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.

2394 lines
111 KiB

  1. namespace CounsellorBL.GROUP
  2. {
  3. using CounsellorBL.BLStructure;
  4. using CounsellorBL.Common;
  5. using CounsellorBL.GROUP.ConstDefinition;
  6. using CounsellorBL.GROUP.Helper;
  7. using CounsellorBL.Helper;
  8. using ICSharpCode.SharpZipLib.Zip;
  9. using MonumentDefine;
  10. using Newtonsoft.Json;
  11. using Newtonsoft.Json.Linq;
  12. using NPOI.SS.Formula.Functions;
  13. using OT.COM.ArsenalDB;
  14. using OT.COM.ArsenalDB.SQL;
  15. using OT.COM.LogisticsUtil;
  16. using OT.COM.SignalerMessage;
  17. using SoldierData.EnterprizeV4;
  18. using System;
  19. using System.Collections.Generic;
  20. using System.Data;
  21. using System.Globalization;
  22. using System.IO;
  23. using System.Linq;
  24. using System.Net;
  25. using static CounsellorBL.GROUP.ConstDefinition.GrpBLWording;
  26. using static CounsellorBL.GROUP.Helper.FbHelper;
  27. using static MonumentDefine.Enums;
  28. class ArticleManage2Service : SingleDataTableTemplate<tb_grp_article>
  29. {
  30. private class GroupViewModel
  31. {
  32. public string message { get; set; }
  33. public string fb_group_id { get; set; }
  34. public string user_token { get; set; }
  35. public string announcement { get; set; }
  36. public string group_user_uid { get; set; }
  37. public int status_flag { get; set; }
  38. }
  39. private class GroupArticleModel : GroupViewModel
  40. {
  41. public string uid { get; set; }
  42. public string group_uid { get; set; }
  43. public DateTime release_date { get; set; }
  44. public string name { get; set; }
  45. public string user_tokne { get; set; }
  46. }
  47. class MediaInfo
  48. {
  49. public string uid { get; set; }
  50. public string display { get; set; }
  51. public string mediatype { get; set; }
  52. }
  53. class ArticleMediaInfo : tb_grp_article
  54. {
  55. public string media_type { get; set; }
  56. public string media_id { get; set; }
  57. public string media_uid { get; set; }
  58. public int seq { get; set; }
  59. public int cost_price { get; set; }
  60. }
  61. public ArticleManage2Service()
  62. {
  63. dgReadCommandGenerator = readCommandGenerator;
  64. dgCreateCommandGenerator = createCommandGenerator;
  65. dgUpdateCommandGenerator = updateCommandGenerator;
  66. dgDeleteCommandGenerator = deleteCommandGenerator;
  67. }
  68. [Auth(false)]
  69. public CResponseMessage UpdateStatus(CRequestMessage i_crmInput)
  70. {
  71. return commonEditor(i_crmInput, BLWording.UPD_MASTER, updateSingleCommandGeneratorDefault);
  72. }
  73. [Auth(false)]
  74. public new CResponseMessage Read(CRequestMessage i_crmInput) => base.Read(i_crmInput);
  75. protected string readCommandGenerator(CRequestMessage i_crmInput, JArray i_jaData, tb_sys_session i_sSessionUser, out Command o_c,
  76. [System.Runtime.CompilerServices.CallerLineNumber] int i_nCodeLine = 0,
  77. [System.Runtime.CompilerServices.CallerMemberName] string i_sMemberName = "",
  78. [System.Runtime.CompilerServices.CallerFilePath] string i_sSourcePath = "")
  79. {
  80. string sMsg;
  81. Command cRes = null;
  82. try
  83. {
  84. do
  85. {
  86. List<string> lsEmpColumns = EntityBase.GetAllColumnName(typeof(tb_grp_article));
  87. // 取得condition
  88. Dictionary<string, string> dicCondition = GetQueryMasterFirstQJEDicwherecols(i_crmInput);
  89. var lsBranch = ProjectHelper.GetUserGroup(i_crmInput);
  90. QueryJsonElementCollection lBlocks = new QueryJsonElementCollection();
  91. QueryJsonElement qjeArticle = lBlocks.GetInst();
  92. qjeArticle.table = tb_grp_article.TABLENAME;
  93. qjeArticle.displaycols = lsEmpColumns;
  94. qjeArticle.wherecols = new WhereNode(tb_grp_article.CN_GROUP_UID, WhereNode.EColumnOperation.EOT_IN, typeof(tb_grp_article), lsBranch.ToArray());
  95. if (dicCondition.Any())
  96. {
  97. qjeArticle.dicwherecols = dicCondition;
  98. }
  99. qjeArticle.ordercols = new List<Tuple<QueryJsonElement, string, string>>()
  100. {
  101. new Tuple<QueryJsonElement, string, string>(qjeArticle, tb_grp_article.CN_CREATE_DATE, BLWording.ORDER_DESC)
  102. };
  103. QueryJsonElement qjeMain = lBlocks.GetInst();
  104. qjeMain.table = tb_ord_order_master.TABLENAME;
  105. qjeMain.jointype = QueryJsonElement.LEFT_JOIN;
  106. qjeMain.jointable = qjeArticle;
  107. qjeMain.joincols = new Dictionary<string, string>() {
  108. { tb_ord_order_master.CN_ARTICLE_UID,tb_grp_article.CN_UID }};
  109. qjeMain.displaycols = new List<string>()
  110. {
  111. tb_ord_order_master.CN_ORDER_CODE
  112. };
  113. lBlocks.Add(qjeArticle);
  114. lBlocks.Add(qjeMain);
  115. sMsg = MakeSelectJoinByBlocks(lBlocks, out Command cRead);
  116. if (sMsg != null)
  117. {
  118. break;
  119. }
  120. cRes = cRead;
  121. }
  122. while (false);
  123. }
  124. catch (Exception ex)
  125. {
  126. LogHelper.DBLog(Util.GetLastExceptionMsg(ex), i_nCodeLine, i_sMemberName, i_sSourcePath);
  127. sMsg = $"{nameof(readCommandGenerator)} unknwon exception. i_crmInput={JsonConvert.SerializeObject(i_crmInput)}. Call from {i_sMemberName} {i_sSourcePath}({i_nCodeLine}).";
  128. #if DEBUG
  129. System.Diagnostics.Debug.WriteLine(sMsg);
  130. #endif
  131. }
  132. o_c = cRes;
  133. return sMsg;
  134. }
  135. [Auth(false)]
  136. public new CResponseMessage Update(CRequestMessage i_crmInput) => base.Update(i_crmInput);
  137. [Auth(false)]
  138. public CResponseMessage GetArticleInRange(CRequestMessage i_crmInput)
  139. {
  140. return simpleRead(i_crmInput, new SQLLib(new MSSQLDirectSQLHelper()).GetArticleInRange(out Command cRes), cRes);
  141. }
  142. [Auth(false)]
  143. public CResponseMessage GetScheduleWaitingArticleInRange(CRequestMessage i_crmInput)
  144. {
  145. return simpleRead(i_crmInput, new SQLLib(new MSSQLDirectSQLHelper()).GetScheduleWaitingArticleInRange(out Command cRes), cRes);
  146. }
  147. [Auth(false)]
  148. public CResponseMessage GetMediadWaitingArticleInRange(CRequestMessage i_crmInput)
  149. {
  150. return simpleRead(i_crmInput, new SQLLib(new MSSQLDirectSQLHelper()).GetMediadWaitingArticleInRange(out Command cRes), cRes);
  151. }
  152. [Auth(false)]
  153. public CResponseMessage GetFailWaitingArticleInRange(CRequestMessage i_crmInput)
  154. {
  155. return simpleRead(i_crmInput, new SQLLib(new MSSQLDirectSQLHelper()).GetFailWaitingArticleInRange(out Command cRes), cRes);
  156. }
  157. [Auth(false)]
  158. public CResponseMessage GetArticleInRangeTest(CRequestMessage i_crmInput)
  159. {
  160. return simpleRead(i_crmInput, new SQLLib(new MSSQLDirectSQLHelper()).GetArticleInRangeTest(out Command cRes), cRes);
  161. }
  162. protected string deleteCommandGenerator(CRequestMessage i_crmInput, JArray i_jaItems, tb_sys_session i_sSessionUser, out List<Command> o_lcResult, List<string> i_saQryContainKeys,
  163. [System.Runtime.CompilerServices.CallerLineNumber] int i_nCodeLine = 0,
  164. [System.Runtime.CompilerServices.CallerMemberName] string i_sMemberName = "",
  165. [System.Runtime.CompilerServices.CallerFilePath] string i_sSourcePath = "")
  166. {
  167. string sMsg = null;
  168. Command cRes = null;
  169. List<Command> lcCmds = new List<Command>();
  170. try
  171. {
  172. do
  173. {
  174. foreach (JToken jtkItem in i_jaItems)
  175. {
  176. Dictionary<string, object> dicItem = jtkItem.ToObject<Dictionary<string, object>>();
  177. sMsg = getManualLog(i_crmInput, dicItem, BLWording.LOG_ACTION_NAME_DELETESQL, out Command cLog);
  178. if (sMsg != null)
  179. {
  180. break;
  181. }
  182. if (cLog != null)
  183. {
  184. lcCmds.Add(cLog);
  185. }
  186. string sMstUID = null;
  187. if (dicItem.ContainsKey(BLWording.WHEREDATA) && dicItem[BLWording.WHEREDATA] is JObject wheredata)
  188. {
  189. Dictionary<string, object> wheredataDic = wheredata.ToObject<Dictionary<string, object>>();
  190. // Get all MsterID
  191. if (wheredataDic.ContainsKey("action") && wheredataDic.ContainsKey(BLWording.UID)) // For article-scheduler 因為此段刪除須要將文章轉草稿
  192. {
  193. if (wheredataDic["action"].ToString() == "update")
  194. {
  195. sMstUID = wheredataDic[BLWording.UID].ToString();
  196. var oData = new tb_grp_article();
  197. oData.post_status = 0;
  198. oData.release_date = null;
  199. Command c = Command.SetupUpdateCmd(oData,
  200. new WhereNode(tb_grp_article.CN_UID, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_grp_article), sMstUID));
  201. lcCmds.Add(c);
  202. }
  203. }
  204. else if (wheredataDic.ContainsKey(BLWording.UID))
  205. {
  206. sMstUID = wheredataDic[BLWording.UID].ToString();
  207. QueryJsonElementCollection lBlocks = new QueryJsonElementCollection();
  208. QueryJsonElement qjeA = lBlocks.GetInst();
  209. qjeA.table = tb_grp_article.TABLENAME;
  210. qjeA.displaycols = new List<string>()
  211. {
  212. tb_grp_article.CN_DRAFT_UID
  213. };
  214. qjeA.wherecols = new WhereNode(tb_grp_article.CN_UID, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_grp_article), sMstUID);
  215. lBlocks.Add(qjeA);
  216. sMsg = MakeSelectJoinByBlocks(lBlocks, out cRes);
  217. if (sMsg != null)
  218. {
  219. break;
  220. }
  221. ArsenalInterface ai = ArsenalDBMgr.GetInst(cRes);
  222. var qds = ai.RunQueryList<tb_grp_article>(cRes);
  223. var draft_uid = qds[0].draft_uid;
  224. lBlocks = new QueryJsonElementCollection();
  225. QueryJsonElement qjeAll = lBlocks.GetInst();
  226. qjeAll.table = tb_grp_article.TABLENAME;
  227. qjeAll.displaycols = new List<string>()
  228. {
  229. tb_grp_article.CN_UID
  230. };
  231. qjeAll.wherecols = new WhereNode(tb_grp_article.CN_DRAFT_UID, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_grp_article), draft_uid);
  232. lBlocks.Add(qjeAll);
  233. sMsg = MakeSelectJoinByBlocks(lBlocks, out cRes);
  234. if (sMsg != null)
  235. {
  236. break;
  237. }
  238. ArsenalInterface aiAll = ArsenalDBMgr.GetInst(cRes);
  239. var qdsAll = aiAll.RunQueryList<tb_grp_article>(cRes);
  240. List<string> detailColumnUID = new List<string>();
  241. foreach (var data in qdsAll)
  242. {
  243. detailColumnUID.Add(data.uid.ToString());
  244. }
  245. tb_grp_article u = new tb_grp_article()
  246. {
  247. status_flag = BLWording.STATUS_FLAG_OFF
  248. };
  249. tb_grp_article_media m = new tb_grp_article_media()
  250. {
  251. status_flag = BLWording.STATUS_FLAG_OFF
  252. };
  253. tb_prd_article2product p = new tb_prd_article2product()
  254. {
  255. status_flag = BLWording.STATUS_FLAG_OFF
  256. };
  257. Command c = Command.SetupUpdateCmd(u, new WhereNode(tb_grp_article.CN_UID, WhereNode.EColumnOperation.EOT_IN, typeof(tb_grp_article), detailColumnUID.ToArray()));
  258. Command c1 = Command.SetupUpdateCmd(m, new WhereNode(tb_grp_article_media.CN_ARTICLE_UID, WhereNode.EColumnOperation.EOT_IN, typeof(tb_grp_article_media), detailColumnUID.ToArray()));
  259. Command c2 = Command.SetupUpdateCmd(p, new WhereNode(tb_prd_article2product.CN_ARTICLE_UID, WhereNode.EColumnOperation.EOT_IN, typeof(tb_prd_article2product), detailColumnUID.ToArray()));
  260. lcCmds.Add(c);
  261. lcCmds.Add(c1);
  262. lcCmds.Add(c2);
  263. // Get all action in this program
  264. //lcCmds.Add(Command.SetupDeleteCmd(new tb_prd_article2product() { article_uid = sMstUID }));
  265. //lcCmds.Add(Command.SetupDeleteCmd(new tb_grp_article_media() { article_uid = sMstUID }));
  266. //lcCmds.Add(Command.SetupDeleteCmd(new tb_grp_article() { uid = sMstUID }));
  267. }
  268. }
  269. }
  270. }
  271. while (false);
  272. }
  273. catch (Exception ex)
  274. {
  275. LogHelper.DBLog(Util.GetLastExceptionMsg(ex), i_crmInput);
  276. sMsg = $"{nameof(deleteCommandGenerator)} unknwon exception. i_crmInput={JsonConvert.SerializeObject(i_crmInput)}. Call from {i_sMemberName} {i_sSourcePath}({i_nCodeLine}).";
  277. #if DEBUG
  278. System.Diagnostics.Debug.WriteLine(sMsg);
  279. #endif
  280. }
  281. o_lcResult = lcCmds;
  282. return sMsg;
  283. }
  284. private string updateCommandGenerator(CRequestMessage i_crmInput, JArray i_jaData, tb_sys_session i_sSessionUser, out List<Command> o_lcCmds, List<string> i_saQryContainKeys,
  285. [System.Runtime.CompilerServices.CallerLineNumber] int i_nCodeLine = 0,
  286. [System.Runtime.CompilerServices.CallerMemberName] string i_sMemberName = "",
  287. [System.Runtime.CompilerServices.CallerFilePath] string i_sSourcePath = "")
  288. {
  289. string sMsg = null;
  290. List<Command> lCmds = new List<Command>();
  291. try
  292. {
  293. do
  294. {
  295. foreach (JToken joData in i_jaData)
  296. {
  297. Dictionary<string, object> dicData = joData.ToObject<Dictionary<string, object>>();
  298. JObject jwheredata = dicData[BLWording.WHEREDATA] as JObject;
  299. JObject allData = dicData[BLWording.DATA] as JObject;
  300. string uid = jwheredata[tb_grp_article.CN_UID].ToString();
  301. tb_grp_article upData = new tb_grp_article()
  302. {
  303. message = allData[tb_grp_article.CN_MESSAGE].ToString(),
  304. release_date = Convert.ToDateTime(allData[tb_grp_article.CN_POST_DATE].ToString()),
  305. name = allData[tb_grp_article.CN_NAME].ToString(),
  306. group_uid = allData[tb_grp_article.CN_GROUP_UID].ToString(),
  307. };
  308. tb_grp_article upCon = new tb_grp_article() { uid = uid };
  309. lCmds.Add(Command.SetupUpdateCmd(upData, upCon));
  310. }
  311. }
  312. while (false);
  313. }
  314. catch (Exception ex)
  315. {
  316. LogHelper.DBLog(Util.GetLastExceptionMsg(ex), i_nCodeLine, i_sMemberName, i_sSourcePath);
  317. sMsg = $"{nameof(updateCommandGenerator)} unknwon exception. i_crmInput={JsonConvert.SerializeObject(i_crmInput)}. Call from {i_sMemberName} {i_sSourcePath}({i_nCodeLine}).";
  318. #if DEBUG
  319. System.Diagnostics.Debug.WriteLine(sMsg);
  320. #endif
  321. }
  322. o_lcCmds = lCmds;
  323. return sMsg;
  324. }
  325. protected string createCommandGenerator(CRequestMessage i_crmInput, JArray i_jaData, tb_sys_session i_sSessionUser, out List<Command> o_lResult, List<string> i_saQryContainKeys,
  326. [System.Runtime.CompilerServices.CallerLineNumber] int i_nCodeLine = 0,
  327. [System.Runtime.CompilerServices.CallerMemberName] string i_sMemberName = "",
  328. [System.Runtime.CompilerServices.CallerFilePath] string i_sSourcePath = "")
  329. {
  330. string sMsg = null;
  331. List<Command> lCmds = new List<Command>();
  332. try
  333. {
  334. do
  335. {
  336. foreach (JToken joData in i_jaData)
  337. {
  338. Dictionary<string, object> dicData = joData.ToObject<Dictionary<string, object>>();
  339. JObject jdata = dicData[BLWording.DATA] as JObject;
  340. Dictionary<string, object> dicInput = jdata.ToObject<Dictionary<string, object>>();
  341. string sNewArticleUid = Guid.NewGuid().ToString();
  342. if (dicInput.ContainsKey("isProductValid"))
  343. {
  344. if (Convert.ToBoolean(dicInput["isProductValid"]) == false)
  345. {
  346. sMsg = "商品價格錯誤";
  347. break;
  348. }
  349. }
  350. tb_grp_article cInsert = new tb_grp_article()
  351. {
  352. uid = sNewArticleUid,
  353. name = (dicInput[tb_grp_article.CN_NAME] ?? "").ToString(),
  354. group_uid = (dicInput[tb_grp_article.CN_GROUP_UID] ?? "").ToString(),
  355. // fb_article_id = (dicInput[tb_grp_article.CN_FB_ARTICLE_ID] ?? "").ToString(),
  356. message = dicInput[tb_grp_article.CN_MESSAGE].ToString(),
  357. post_status = Convert.ToInt32(dicInput[tb_grp_article.CN_POST_STATUS]),
  358. draft = 1,
  359. draft_uid = sNewArticleUid,
  360. dutyfree = (dicInput[tb_grp_article.CN_DUTYFREE] ?? "").ToString().ToLower() == "true" ? "1" : "0"
  361. };
  362. // 發布時間可能為空
  363. if (dicInput.ContainsKey(tb_grp_article.CN_RELEASE_DATE) && dicInput[tb_grp_article.CN_RELEASE_DATE] != null)
  364. {
  365. cInsert.release_date = Convert.ToDateTime(dicInput[tb_grp_article.CN_RELEASE_DATE].ToString());
  366. }
  367. // 截團時間可能為空
  368. if (dicInput.ContainsKey(tb_grp_article.CN_CLOSE_DATE) && dicInput[tb_grp_article.CN_CLOSE_DATE] != null)
  369. {
  370. cInsert.close_date = Convert.ToDateTime(dicInput[tb_grp_article.CN_CLOSE_DATE].ToString());
  371. }
  372. Command c = Command.SetupInsertCmd(cInsert);
  373. lCmds.Add(c);
  374. // Log
  375. sMsg = getManualLog(i_crmInput, dicData, BLWording.LOG_ACTION_NAME_INSERTSQL, out Command cLog);
  376. if (sMsg != null)
  377. {
  378. break;
  379. }
  380. if (cLog != null)
  381. {
  382. lCmds.Add(cLog);
  383. }
  384. string sMediaKey = nameof(tb_grp_article_media);
  385. if (!jdata.ContainsKey(sMediaKey))
  386. {
  387. sMsg = "common.no_media_fle";
  388. break;
  389. }
  390. List<MediaInfo> lmi = jdata[sMediaKey].ToObject<List<MediaInfo>>();
  391. var seq = 1;
  392. lmi.ForEach(f =>
  393. {
  394. lCmds.Add(Command.SetupInsertCmd(new tb_grp_article_media()
  395. {
  396. article_uid = sNewArticleUid,
  397. media_id = f.uid,
  398. type = f.mediatype,
  399. seq = seq++
  400. }));
  401. });
  402. string sProductKey = nameof(tb_prd_article2product);
  403. if (!jdata.ContainsKey(sProductKey))
  404. {
  405. sMsg = "grp.no_product";
  406. break;
  407. }
  408. List<tb_prd_article2product> la2pProducts = jdata[sProductKey].ToObject<List<tb_prd_article2product>>();
  409. if (!la2pProducts.Any())
  410. {
  411. sMsg = "grp.no_product";
  412. break;
  413. }
  414. new Article2ProductService().CreateProduct(sNewArticleUid, la2pProducts, cInsert.group_uid, ref lCmds);
  415. }
  416. }
  417. while (false);
  418. }
  419. catch (Exception ex)
  420. {
  421. LogHelper.DBLog(Util.GetLastExceptionMsg(ex), i_nCodeLine, i_sMemberName, i_sSourcePath);
  422. sMsg = $"{nameof(createCommandGenerator)} unknwon exception. i_crmInput={JsonConvert.SerializeObject(i_crmInput)}. Call from {i_sMemberName} {i_sSourcePath}({i_nCodeLine}).";
  423. #if DEBUG
  424. System.Diagnostics.Debug.WriteLine(sMsg);
  425. #endif
  426. }
  427. o_lResult = lCmds;
  428. return sMsg;
  429. }
  430. [Auth(false)]
  431. public CResponseMessage PushPost(CRequestMessage i_crmInput)
  432. {
  433. string sMsg = null;
  434. CResponseMessage crmRes = null;
  435. try
  436. {
  437. do
  438. {
  439. sMsg = getCommonParameter(i_crmInput, BLWording.QRY_MASTER, out JArray jaDataArray, out tb_sys_session sUserSession);
  440. if (sMsg != null)
  441. {
  442. break;
  443. }
  444. if (jaDataArray.Count != 1 || jaDataArray[0] == null)
  445. {
  446. sMsg = MessageWording.PARAM_NOT_EXPECTED;
  447. break;
  448. }
  449. sMsg = _PushPostDetail(jaDataArray[0][BLWording.WHEREDATA][BLWording.UID].ToString(), jaDataArray[0][GrpBLWording.GRP_DOWNLOADURL].ToString(), true, out _);
  450. if (sMsg != null)
  451. {
  452. break;
  453. }
  454. crmRes = new CSuccessResponseMessage(null, i_crmInput);
  455. // 填寫回傳
  456. }
  457. while (false);
  458. }
  459. catch (Exception ex)
  460. {
  461. sMsg = $"{nameof(PushPost)} exception. i_crmInput={JsonConvert.SerializeObject(i_crmInput)}. ex={ex.Message}";
  462. Logger.Error(sMsg);
  463. #if DEBUG
  464. System.Diagnostics.Debug.WriteLine(sMsg);
  465. #endif
  466. }
  467. if (string.IsNullOrEmpty(sMsg))
  468. {
  469. //Logger.Info(JsonConvert.SerializeObject(i_crmInput));
  470. //Logger.Info(JsonConvert.SerializeObject(crmRes));
  471. }
  472. else
  473. {
  474. crmRes = new CErrorResponseMessage(sMsg, i_crmInput);
  475. Logger.Error(JsonConvert.SerializeObject(i_crmInput));
  476. Logger.Error(JsonConvert.SerializeObject(crmRes));
  477. }
  478. return crmRes;
  479. }
  480. private string _PushPostDetail(string i_sUID, string i_sURL, bool i_bHandlePhoto, out string o_sResult)
  481. {
  482. string sMsg = null;
  483. string sResult = null;
  484. Logger.Info($"_PushPostDetail 處理 Uid:{i_sUID} i_sURL={i_sURL}");
  485. try
  486. {
  487. do
  488. {
  489. /**開始組指令**/
  490. QueryJsonElementCollection lBlocks = new QueryJsonElementCollection();
  491. QueryJsonElement qjeArticle = lBlocks.GetInst();
  492. qjeArticle.table = tb_grp_article.TABLENAME;
  493. qjeArticle.displaycols = new List<string>()
  494. {
  495. tb_grp_article.CN_MESSAGE
  496. };
  497. qjeArticle.wherecols = new WhereNode(tb_grp_article.CN_UID, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_grp_article), i_sUID);
  498. lBlocks.Add(qjeArticle);
  499. QueryJsonElement qjeGroup = lBlocks.GetInst();
  500. qjeGroup.table = tb_grp_group.TABLENAME;
  501. qjeGroup.jointable = qjeArticle;
  502. qjeGroup.jointype = QueryJsonElement.LEFT_JOIN;
  503. qjeGroup.joincols = new Dictionary<string, string> { { tb_grp_group.CN_UID, tb_grp_article.CN_GROUP_UID } };
  504. qjeGroup.displaycols = new List<string>()
  505. {
  506. tb_grp_group.CN_FB_GROUP_ID,tb_grp_group.CN_ANNOUNCEMENT
  507. };
  508. lBlocks.Add(qjeGroup);
  509. QueryJsonElement qjeGroupUser = lBlocks.GetInst();
  510. qjeGroupUser.table = tb_grp_group2user.TABLENAME;
  511. qjeGroupUser.jointable = qjeGroup;
  512. qjeGroupUser.jointype = QueryJsonElement.LEFT_JOIN;
  513. qjeGroupUser.joincols = new Dictionary<string, string> { { tb_grp_group2user.CN_UID, tb_grp_group.CN_POST_USER_UID } };
  514. qjeGroupUser.displaycols = new List<string>()
  515. {
  516. tb_grp_group2user.CN_USER_TOKEN
  517. };
  518. qjeGroupUser.aliascols = new Dictionary<string, List<string>>() {
  519. { tb_grp_group2user.CN_UID, new List<string>() { "group_user_uid" } },
  520. };
  521. lBlocks.Add(qjeGroupUser);
  522. sMsg = MakeSelectJoinByBlocks(lBlocks, out Command cRes);
  523. if (sMsg != null)
  524. {
  525. break;
  526. }
  527. ArsenalInterface ai = ArsenalDBMgr.GetInst(cRes);
  528. List<GroupViewModel> qdArticle = ai.RunQueryList<GroupViewModel>(cRes);
  529. GroupViewModel data = qdArticle.FirstOrDefault();
  530. var mailHelper = new MailHelper();
  531. // 取得當發文錯誤要發送的名單
  532. string sMsgMailList = SystemSettingHelper.GetSetting(BLWording.ERROR_MAILLIST, out var mailList);
  533. if (sMsg != null)
  534. {
  535. Logger.Error(sMsgMailList);
  536. }
  537. List<MailAccountInfo> lsMailList = new List<MailAccountInfo>();
  538. if (mailList != null && !string.IsNullOrEmpty(mailList.key_value))
  539. {
  540. var lsMail = mailList.key_value.Split(new String[] { ",", ";" }, StringSplitOptions.RemoveEmptyEntries).ToList();
  541. foreach (var mail in lsMail)
  542. {
  543. lsMailList.Add(new MailAccountInfo() { EMail = mail });
  544. }
  545. }
  546. lBlocks.Clear();
  547. List<string> lsPhotoId = new List<string>();
  548. bool bNeedRPA = false;
  549. bool bHasPicError = false;
  550. int nPhotoCountOrigin = 0;
  551. if (i_bHandlePhoto)
  552. {
  553. List<string> lsFailURIs = new List<string>();
  554. Logger.Info($"_PushPostDetail HandlePhoto Start Uid:{i_sUID}");
  555. QueryJsonElement qjeMedia = lBlocks.GetInst();
  556. qjeMedia.table = tb_grp_article_media.TABLENAME;
  557. qjeMedia.displaycols = new List<string>()
  558. {
  559. tb_grp_article_media.CN_MEDIA_ID,
  560. tb_grp_article_media.CN_URI,
  561. tb_grp_article_media.CN_TYPE
  562. };
  563. qjeMedia.wherecols = WhereNode.GenNode<tb_grp_article_media>(f => f.article_uid == i_sUID);
  564. lBlocks.Add(qjeMedia);
  565. sMsg = MakeSelectJoinByBlocks(lBlocks, out Command cResom);
  566. if (sMsg != null)
  567. {
  568. break;
  569. }
  570. ai = ArsenalDBMgr.GetInst(cResom);
  571. List<tb_grp_article_media> qdMedia = ai.RunQueryList<tb_grp_article_media>(cResom);
  572. nPhotoCountOrigin = qdMedia.Count;
  573. Logger.Info($"_PushPostDetail CallFbPostPushAPI nPhotoCountOrigin = {nPhotoCountOrigin}");
  574. // 如果是上傳的圖片則組uri(圖片需要分次上傳)
  575. foreach (tb_grp_article_media x in qdMedia.Where(x => x.type == BLWording.MediaType.Photo))
  576. {
  577. string uri = string.Format("{0}{1}", i_sURL, x.media_id);
  578. Logger.Info($"_PushPostDetail CallFbPicturePushAPI uri = {uri}");
  579. // TODO: 可以考慮Retry
  580. string sMsgPic = new FbHelper().CallFbPicturePushAPI(data.user_token, data.fb_group_id, uri, out string sID);
  581. if (sMsgPic != null)
  582. {
  583. bHasPicError = true;
  584. lsFailURIs.Add(uri);
  585. Logger.Error($"_PushPostDetail 發文錯誤:{sMsgPic}, GroupViewModel:{JsonConvert.SerializeObject(data)}");
  586. var mailMsg = mailHelper.Send("發文錯誤", string.Format("圖片上傳錯誤:{0}", sMsg), lsMailList);
  587. if (string.IsNullOrEmpty(mailMsg))
  588. {
  589. Logger.Info(string.Format("信件發送成功:{0} => {1}", sMsg, lsMailList));
  590. }
  591. else
  592. {
  593. Logger.Error(string.Format("信件發送失敗:{0} => {1}", mailMsg, lsMailList));
  594. }
  595. continue;
  596. }
  597. else
  598. {
  599. lsPhotoId.Add(sID);
  600. }
  601. Logger.Info($"_PushPostDetail CallFbPicturePushAPI end uri = {uri} ");
  602. }
  603. Logger.Info($"_PushPostDetail HandlePhoto:F1 bHasPicError={bHasPicError} ({lsFailURIs.Count}/{nPhotoCountOrigin})");
  604. // 判斷是否有影片決定更新RPA狀況
  605. bNeedRPA = bHasPicError || (qdMedia != null && qdMedia.Any(x => x.type == BLWording.MediaType.Video));
  606. Logger.Info($"_PushPostDetail HandlePhoto End Uid:{i_sUID} bHasPicError={bHasPicError} bNeedRPA={bNeedRPA}");
  607. }
  608. if (bHasPicError)
  609. {
  610. // 只要有圖錯就不要發文
  611. sMsg = "有一張以上圖失敗就放棄上傳";
  612. Logger.Error($"_PushPostDetail {sMsg}");
  613. break;
  614. }
  615. Logger.Info($"_PushPostDetail CallFbPostPushAPI before lsPhotoId.Count= {nPhotoCountOrigin}");
  616. sMsg = new FbHelper().CallFbPostPushAPI(data.user_token, data.message + "\n" + data.announcement, data.fb_group_id, lsPhotoId, out string sPostID);
  617. Logger.Info($"_PushPostDetail CallFbPostPushAPI after sMsg={sMsg}");
  618. if (sMsg != null)
  619. {
  620. Logger.Error($"F5 _PushPostDetail {sMsg}");
  621. mailHelper.Send("發文錯誤", string.Format("貼文上傳錯誤:{0}", sMsg), lsMailList);
  622. // break; <= 2021/06/17 CallFbPostPushAPI 理論上網路正常的狀況FB已經上了
  623. break;
  624. }
  625. Logger.Info($"_PushPostDetail before Update");
  626. tb_grp_article u = new tb_grp_article()
  627. {
  628. post_status = (int)EPostStatus.EPS_COMPLETE,
  629. fb_article_id = sPostID,
  630. group_user_uid = data.group_user_uid,
  631. post_date = DateTime.Now
  632. };
  633. if (!bNeedRPA)
  634. {
  635. u.rpa_status = (int)Enums.Flag.Enable;
  636. }
  637. Command c = Command.SetupUpdateCmd(u, new WhereNode(tb_grp_article.CN_UID, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_grp_article), i_sUID));
  638. ai = ArsenalDBMgr.GetInst(c, GetDefaultSystemColumnInfo());
  639. ai.RunEditSingleCmd(c);
  640. Logger.Info($"_PushPostDetail after Update");
  641. if (!c.IsSuccess)
  642. {
  643. sMsg = c.LastErrorCode;
  644. Logger.Error($"_PushPostDetail c.LastErrorCode={c.LastErrorCode}");
  645. break;
  646. }
  647. sResult = sPostID;
  648. }
  649. while (false);
  650. }
  651. catch (Exception ex)
  652. {
  653. sMsg = ex.Message;
  654. Logger.Error($"Exception:{sMsg}");
  655. #if DEBUG
  656. System.Diagnostics.Debug.WriteLine(sMsg);
  657. #endif
  658. }
  659. o_sResult = sResult;
  660. Logger.Info($"_PushPostDetail 處理 Uid :{i_sUID} i_sURL={i_sURL} 結束 sMsg={sMsg} o_sResult = {o_sResult} ");
  661. return sMsg;
  662. }
  663. public CResponseMessage TransferOrder(CRequestMessage i_crmInput)
  664. {
  665. string sMsg = null;
  666. CResponseMessage crmRes = null;
  667. try
  668. {
  669. do
  670. {
  671. sMsg = getCommonParameter(i_crmInput, BLWording.UPD_MASTER, out JArray jaDataArray, out tb_sys_session sUserSession);
  672. if (sMsg != null)
  673. {
  674. break;
  675. }
  676. if (jaDataArray.Count != 1 || jaDataArray[0] == null)
  677. {
  678. sMsg = MessageWording.PARAM_NOT_EXPECTED;
  679. break;
  680. }
  681. var article_uid = jaDataArray[0][BLWording.WHEREDATA][BLWording.UID].ToString();
  682. var data = jaDataArray[0][BLWording.WHEREDATA][BLWording.DATA] as JArray;
  683. sMsg = new FbHelper().CheckOrder(article_uid, data);
  684. if (sMsg != null)
  685. {
  686. break;
  687. }
  688. }
  689. while (false);
  690. }
  691. catch (Exception ex)
  692. {
  693. LogHelper.DBLog(Util.GetLastExceptionMsg(ex));
  694. Logger.Error(ex);
  695. sMsg = $"{nameof(TransferOrder)} unknwon exception.).";
  696. #if DEBUG
  697. System.Diagnostics.Debug.WriteLine(sMsg);
  698. #endif
  699. }
  700. if (sMsg != null)
  701. {
  702. crmRes = new CErrorResponseMessage(sMsg);
  703. Logger.Error(JsonConvert.SerializeObject(i_crmInput));
  704. Logger.Error(JsonConvert.SerializeObject(crmRes));
  705. }
  706. else
  707. {
  708. crmRes = new CSuccessResponseMessage(null, i_crmInput);
  709. //Logger.Info(JsonConvert.SerializeObject(i_crmInput));
  710. //Logger.Info(JsonConvert.SerializeObject(crmRes));
  711. }
  712. return crmRes;
  713. }
  714. private string GetMemberPSID(string i_sArticleUID, out List<string> lsPSID)
  715. {
  716. string sMsg = null;
  717. lsPSID = null;
  718. try
  719. {
  720. do
  721. {
  722. QueryJsonElementCollection lBlocks = new QueryJsonElementCollection();
  723. QueryJsonElement qjeOrder = lBlocks.GetInst();
  724. qjeOrder.table = tb_ord_order_detail.TABLENAME;
  725. lBlocks.Add(qjeOrder);
  726. QueryJsonElement qjeMain = lBlocks.GetInst();
  727. qjeMain.table = tb_ord_order_master.TABLENAME;
  728. qjeMain.jointable = qjeOrder;
  729. qjeMain.jointype = QueryJsonElement.LEFT_JOIN;
  730. qjeMain.joincols = new Dictionary<string, string> { { tb_ord_order_master.CN_UID, tb_ord_order_detail.CN_ORDER_UID } };
  731. qjeMain.wherecols = new WhereNode(tb_ord_order_master.CN_ARTICLE_UID, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_ord_order_master), i_sArticleUID);
  732. lBlocks.Add(qjeMain);
  733. QueryJsonElement qjeMember = lBlocks.GetInst();
  734. qjeMember.table = tb_meb_member.TABLENAME;
  735. qjeMember.jointable = qjeOrder;
  736. qjeMember.jointype = QueryJsonElement.LEFT_JOIN;
  737. qjeMember.joincols = new Dictionary<string, string> { { tb_meb_member.CN_UID, tb_ord_order_detail.CN_MEMBER_UID } };
  738. qjeMember.displaycols = new List<string>()
  739. {
  740. tb_meb_member.CN_MESSAGE_USER_ID
  741. };
  742. lBlocks.Add(qjeMember);
  743. sMsg = MakeSelectJoinByBlocks(lBlocks, out Command cRes);
  744. if (sMsg != null)
  745. {
  746. break;
  747. }
  748. ArsenalInterface ai = ArsenalDBMgr.GetInst(cRes);
  749. List<tb_meb_member> qds = ai.RunQueryList<tb_meb_member>(cRes);
  750. lsPSID = qds.Select(x => x.message_user_id).ToList();
  751. }
  752. while (false);
  753. }
  754. catch (Exception ex)
  755. {
  756. LogHelper.DBLog(Util.GetLastExceptionMsg(ex));
  757. sMsg = $"{nameof(TransferOrder)} unknwon exception.).";
  758. #if DEBUG
  759. System.Diagnostics.Debug.WriteLine(sMsg);
  760. #endif
  761. }
  762. return sMsg;
  763. }
  764. public CResponseMessage GetArticleMedia(CRequestMessage i_crmInput)
  765. {
  766. string sMsg;
  767. Command cRes = null;
  768. CResponseMessage crmRes = null;
  769. try
  770. {
  771. do
  772. {
  773. // 分頁
  774. int nPageIdx = -1;
  775. int nPageNum = -1;
  776. if (i_crmInput != null)
  777. {
  778. if (i_crmInput.param.ContainsKey(BLWording.QRY_PAGE_IDX)
  779. && Int32.TryParse(i_crmInput.param[BLWording.QRY_PAGE_IDX].ToString(), out int nPageIdxFromUI)
  780. && nPageIdxFromUI >= 0)
  781. {
  782. nPageIdx = nPageIdxFromUI;
  783. }
  784. if (i_crmInput.param.ContainsKey(BLWording.QRY_PAGE_NUM)
  785. && Int32.TryParse(i_crmInput.param[BLWording.QRY_PAGE_NUM].ToString(), out int nPageNumFromUI)
  786. && nPageNumFromUI >= 0)
  787. {
  788. nPageNum = nPageNumFromUI;
  789. }
  790. }
  791. List<string> lsEmpColumns = EntityBase.GetAllColumnName(typeof(tb_grp_article));
  792. // 取得condition
  793. Dictionary<string, string> dicCondition = GetQueryMasterFirstQJEDicwherecols(i_crmInput);
  794. var lsBranch = ProjectHelper.GetUserGroup(i_crmInput);
  795. // Filter& Sort
  796. Dictionary<string, string> mainOrderData = null;
  797. string mainFullTextPattern = null;
  798. if (i_crmInput != null && i_crmInput.param != null && i_crmInput.param.ContainsKey(BLWording.QRY_MASTER))
  799. {
  800. JArray joData = i_crmInput.param[BLWording.QRY_MASTER] as JArray;
  801. if (joData.Any() && joData[0][BLWording.ORDERDATA] != null)
  802. {
  803. JArray jaData = joData[0][BLWording.ORDERDATA] as JArray;
  804. mainOrderData = jaData[0].ToObject<Dictionary<string, string>>();
  805. }
  806. if (joData.Any() && joData[0][BLWording.FULLTEXT_PATTERN] != null)
  807. {
  808. mainFullTextPattern = joData[0][BLWording.FULLTEXT_PATTERN].ToString();
  809. }
  810. }
  811. QueryJsonElementCollection lBlocks = new QueryJsonElementCollection();
  812. List<WhereNode> lswnArticle = new List<WhereNode>();
  813. lswnArticle.Add(new WhereNode(tb_grp_article.CN_GROUP_UID, WhereNode.EColumnOperation.EOT_IN, typeof(tb_grp_article), lsBranch.ToArray()));
  814. QueryJsonElement qjeArticle = lBlocks.GetInst();
  815. qjeArticle.table = tb_grp_article.TABLENAME;
  816. qjeArticle.displaycols = lsEmpColumns;
  817. if (dicCondition.Any())
  818. {
  819. qjeArticle.dicwherecols = dicCondition;
  820. }
  821. if (!string.IsNullOrEmpty(mainFullTextPattern))
  822. {
  823. lswnArticle.Add(new WhereNode(tb_grp_article.CN_NAME, WhereNode.EColumnOperation.EOT_LIKE, typeof(tb_grp_article), mainFullTextPattern));
  824. }
  825. qjeArticle.wherecols = new WhereNode(WhereNode.ENodeOperation.ENO_AND, lswnArticle.ToArray());
  826. QueryJsonElement qjeGroup = lBlocks.GetInst();
  827. qjeGroup.table = tb_grp_group.TABLENAME;
  828. qjeGroup.jointable = qjeArticle;
  829. qjeGroup.jointype = QueryJsonElement.LEFT_JOIN;
  830. qjeGroup.joincols = new Dictionary<string, string> { { tb_grp_group.CN_UID, tb_grp_article.CN_GROUP_UID } };
  831. if (!string.IsNullOrEmpty(mainFullTextPattern))
  832. {
  833. qjeGroup.wherecols = new WhereNode(tb_grp_group.CN_NAME, WhereNode.EColumnOperation.EOT_LIKE, typeof(tb_grp_group), mainFullTextPattern);
  834. }
  835. // Sort
  836. List<Tuple<QueryJsonElement, string, string>> mainOrder = new List<Tuple<QueryJsonElement, string, string>>();
  837. if (mainOrderData != null)
  838. {
  839. mainOrder.Add(Tuple.Create(qjeArticle, mainOrderData.First().Key, mainOrderData.First().Value));
  840. }
  841. else
  842. {
  843. mainOrder.Add(Tuple.Create(qjeArticle, tb_grp_article.CN_RELEASE_DATE, BLWording.ORDER_DESC));
  844. }
  845. qjeArticle.ordercols = mainOrder;
  846. // 先依照分頁條件查出資料
  847. lBlocks.Add(qjeArticle);
  848. _ = MakeSelectJoinByBlocks(lBlocks, out Command cResOrderMst);
  849. cResOrderMst.NeedCount = true;
  850. ArsenalInterface ai = ArsenalDBMgr.GetInst(cResOrderMst);
  851. var qdsOrderMst = ai.RunQueryDataSet(cResOrderMst, i_nPageIdx: nPageIdx, i_nNumOfPage: nPageNum);
  852. List<string> orderMstArray = new List<string>();
  853. foreach (DataRow data in qdsOrderMst.DATA.Tables[0].Rows)
  854. {
  855. orderMstArray.Add(data[tb_grp_article.CN_UID].ToString());
  856. }
  857. lBlocks = new QueryJsonElementCollection();
  858. qjeArticle = lBlocks.GetInst();
  859. qjeArticle.table = tb_grp_article.TABLENAME;
  860. qjeArticle.displaycols = lsEmpColumns;
  861. qjeArticle.wherecols = new WhereNode(tb_grp_article.CN_UID, WhereNode.EColumnOperation.EOT_IN, typeof(tb_grp_article), orderMstArray.ToArray());
  862. qjeGroup = lBlocks.GetInst();
  863. qjeGroup.table = tb_grp_group.TABLENAME;
  864. qjeGroup.jointable = qjeArticle;
  865. qjeGroup.jointype = QueryJsonElement.LEFT_JOIN;
  866. qjeGroup.joincols = new Dictionary<string, string> { { tb_grp_group.CN_UID, tb_grp_article.CN_GROUP_UID } };
  867. QueryJsonElement qjeMedia = lBlocks.GetInst();
  868. qjeMedia.table = tb_grp_article_media.TABLENAME;
  869. qjeMedia.jointable = qjeArticle;
  870. qjeMedia.jointype = QueryJsonElement.LEFT_JOIN;
  871. qjeMedia.joincols = new Dictionary<string, string> { { tb_grp_article_media.CN_ARTICLE_UID, tb_grp_article.CN_UID } };
  872. qjeMedia.aliascols = new Dictionary<string, List<string>>
  873. {
  874. { tb_grp_article_media.CN_TYPE, new List<string>() { "media_type" } },
  875. { tb_grp_article_media.CN_UID, new List<string>() { "media_uid" } },
  876. { tb_grp_article_media.CN_MEDIA_ID, new List<string>() { "media_id" } }
  877. };
  878. qjeMedia.wherecols = new WhereNode(tb_grp_article_media.CN_TYPE, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_grp_article_media), "photo");
  879. qjeMedia.displaycols = new List<string>() { tb_grp_article_media.CN_SEQ };
  880. QueryJsonElement qjeProduct = lBlocks.GetInst();
  881. qjeProduct.table = tb_prd_article2product.TABLENAME;
  882. qjeProduct.jointable = qjeArticle;
  883. qjeProduct.jointype = QueryJsonElement.LEFT_JOIN;
  884. qjeProduct.joincols = new Dictionary<string, string> { { tb_prd_article2product.CN_ARTICLE_UID, tb_grp_article.CN_UID } };
  885. qjeProduct.displaycols = new List<string>() { tb_prd_article2product.CN_COST_PRICE };
  886. lBlocks.Add(qjeArticle);
  887. lBlocks.Add(qjeGroup);
  888. lBlocks.Add(qjeMedia);
  889. lBlocks.Add(qjeProduct);
  890. sMsg = MakeSelectJoinByBlocks(lBlocks, out Command cRead);
  891. ai = ArsenalDBMgr.GetInst(cRead);
  892. var qds = ai.RunQueryList<ArticleMediaInfo>(cRead);
  893. var groupData = qds.OrderByDescending(x => x.release_date).GroupBy(x => new { x.draft_uid }).ToList();
  894. if (dicCondition.ContainsKey(tb_grp_article.CN_POST_STATUS))
  895. {
  896. if (dicCondition[tb_grp_article.CN_POST_STATUS] == "2")
  897. {
  898. groupData = qds.OrderBy(x => x.release_date).GroupBy(x => new { x.draft_uid }).ToList();
  899. }
  900. }
  901. var lsFirstData = new List<ArticleMediaInfo>();
  902. foreach (var data in groupData.OrderByDescending(x => x.Last().release_date))
  903. {
  904. var firstData = data.OrderBy(x => x.seq).First();
  905. var haveNullCost = data.Where(x => x.uid == firstData.uid).Any(x => x.cost_price <= 0);
  906. firstData.cost_price = haveNullCost ? (int)Enums.Flag.Disable : (int)Enums.Flag.Enable;
  907. lsFirstData.Add(firstData);
  908. }
  909. var res = lsFirstData.Select(x => new
  910. {
  911. x.uid,
  912. x.type,
  913. x.group_uid,
  914. x.name,
  915. x.fb_article_id,
  916. x.message,
  917. close_date = x.close_date.HasValue ? x.close_date.Value.ToString("yyyy-MM-dd HH:mm:ss") : "",
  918. release_date = x.release_date.HasValue ? x.release_date.Value.ToString("yyyy-MM-dd HH:mm:ss") : "",
  919. x.post_status,
  920. x.remark,
  921. x.status_flag,
  922. x.media_id,
  923. x.media_type,
  924. x.media_uid,
  925. x.create_date,
  926. x.draft_uid,
  927. x.draft,
  928. x.cost_price
  929. }).ToList();
  930. crmRes = new CSuccessResponseMessage(null, i_crmInput);
  931. crmRes.param.Add(BLWording.DATA, new { records = res, totalCount = qdsOrderMst.Total });
  932. }
  933. while (false);
  934. }
  935. catch (Exception ex)
  936. {
  937. LogHelper.DBLog(Util.GetLastExceptionMsg(ex));
  938. sMsg = $"{nameof(GetArticleMedia)} unknwon exception. i_crmInput={JsonConvert.SerializeObject(i_crmInput)}. ";
  939. #if DEBUG
  940. System.Diagnostics.Debug.WriteLine(sMsg);
  941. #endif
  942. }
  943. if (null != sMsg)
  944. {
  945. crmRes = new CErrorResponseMessage(sMsg, i_crmInput);
  946. }
  947. return crmRes;
  948. }
  949. public CResponseMessage GetArticleMediaForScheduler(CRequestMessage i_crmInput)
  950. {
  951. string sMsg;
  952. Command cRes = null;
  953. CResponseMessage crmRes = null;
  954. try
  955. {
  956. do
  957. {
  958. List<string> lsEmpColumns = EntityBase.GetAllColumnName(typeof(tb_grp_article));
  959. // 取得condition
  960. Dictionary<string, string> dicCondition = GetQueryMasterFirstQJEDicwherecols(i_crmInput);
  961. var lsBranch = ProjectHelper.GetUserGroup(i_crmInput);
  962. QueryJsonElementCollection lBlocks = new QueryJsonElementCollection();
  963. QueryJsonElement qjeArticle = lBlocks.GetInst();
  964. qjeArticle.table = tb_grp_article.TABLENAME;
  965. qjeArticle.displaycols = lsEmpColumns;
  966. qjeArticle.wherecols = new WhereNode(WhereNode.ENodeOperation.ENO_AND,
  967. new WhereNode(tb_grp_article.CN_GROUP_UID, WhereNode.EColumnOperation.EOT_IN, typeof(tb_grp_article), lsBranch.ToArray()),
  968. new WhereNode(tb_grp_article.CN_STATUS_FLAG, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_grp_article), 1),
  969. new WhereNode(tb_grp_article.CN_RELEASE_DATE, WhereNode.EColumnOperation.EOT_ISNOTNULL, typeof(tb_grp_article))
  970. );
  971. if (dicCondition.Any())
  972. {
  973. qjeArticle.dicwherecols = dicCondition;
  974. }
  975. lBlocks.Add(qjeArticle);
  976. QueryJsonElement qjeMedia = lBlocks.GetInst();
  977. qjeMedia.table = tb_grp_article_media.TABLENAME;
  978. qjeMedia.jointable = qjeArticle;
  979. qjeMedia.jointype = QueryJsonElement.LEFT_JOIN;
  980. qjeMedia.joincols = new Dictionary<string, string> { { tb_grp_article_media.CN_ARTICLE_UID, tb_grp_article.CN_UID } };
  981. qjeMedia.aliascols = new Dictionary<string, List<string>>
  982. {
  983. { tb_grp_article_media.CN_TYPE, new List<string>() { "media_type" } },
  984. { tb_grp_article_media.CN_UID, new List<string>() { "media_uid" } },
  985. { tb_grp_article_media.CN_MEDIA_ID, new List<string>() { "media_id" } }
  986. };
  987. qjeMedia.wherecols = new WhereNode(tb_grp_article_media.CN_TYPE, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_grp_article_media), "photo");
  988. qjeMedia.displaycols = new List<string>() { tb_grp_article_media.CN_SEQ };
  989. lBlocks.Add(qjeMedia);
  990. QueryJsonElement qjeProduct = lBlocks.GetInst();
  991. qjeProduct.table = tb_prd_article2product.TABLENAME;
  992. qjeProduct.jointable = qjeArticle;
  993. qjeProduct.jointype = QueryJsonElement.LEFT_JOIN;
  994. qjeProduct.joincols = new Dictionary<string, string> { { tb_prd_article2product.CN_ARTICLE_UID, tb_grp_article.CN_UID } };
  995. qjeProduct.displaycols = new List<string>() { tb_prd_article2product.CN_COST_PRICE };
  996. lBlocks.Add(qjeProduct);
  997. sMsg = MakeSelectJoinByBlocks(lBlocks, out Command cRead);
  998. ArsenalInterface ai = ArsenalDBMgr.GetInst(cRead);
  999. var qds = ai.RunQueryList<ArticleMediaInfo>(cRead);
  1000. var groupData = qds.OrderByDescending(x => x.create_date).GroupBy(x => new { x.draft_uid }).ToList();
  1001. if (dicCondition.ContainsKey(tb_grp_article.CN_POST_STATUS))
  1002. {
  1003. if (dicCondition[tb_grp_article.CN_POST_STATUS] == "2")
  1004. {
  1005. groupData = qds.OrderBy(x => x.release_date).GroupBy(x => new { x.draft_uid }).ToList();
  1006. }
  1007. }
  1008. var lsFirstData = new List<ArticleMediaInfo>();
  1009. foreach (var data in groupData.OrderByDescending(x => x.Last().create_date))
  1010. {
  1011. var firstData = data.OrderBy(x => x.seq).First();
  1012. var haveNullCost = data.Where(x => x.uid == firstData.uid).Any(x => x.cost_price <= 0);
  1013. firstData.cost_price = haveNullCost ? (int)Enums.Flag.Disable : (int)Enums.Flag.Enable;
  1014. lsFirstData.Add(firstData);
  1015. }
  1016. var res = lsFirstData.Select(x => new
  1017. {
  1018. x.uid,
  1019. x.type,
  1020. x.group_uid,
  1021. x.name,
  1022. x.fb_article_id,
  1023. x.message,
  1024. close_date = x.close_date.HasValue ? x.close_date.Value.ToString("yyyy-MM-dd HH:mm:ss") : "",
  1025. release_date = x.release_date.HasValue ? x.release_date.Value.ToString("yyyy-MM-dd HH:mm:ss") : "",
  1026. x.post_status,
  1027. x.status_flag,
  1028. x.media_id,
  1029. x.media_type,
  1030. x.media_uid,
  1031. x.create_date,
  1032. x.draft_uid,
  1033. x.draft,
  1034. x.cost_price
  1035. }).ToList();
  1036. crmRes = new CSuccessResponseMessage(null, i_crmInput);
  1037. crmRes.param.Add(BLWording.DATA, res);
  1038. }
  1039. while (false);
  1040. }
  1041. catch (Exception ex)
  1042. {
  1043. LogHelper.DBLog(Util.GetLastExceptionMsg(ex));
  1044. sMsg = $"{nameof(GetArticleMedia)} unknwon exception. i_crmInput={JsonConvert.SerializeObject(i_crmInput)}. ";
  1045. #if DEBUG
  1046. System.Diagnostics.Debug.WriteLine(sMsg);
  1047. #endif
  1048. }
  1049. if (null != sMsg)
  1050. {
  1051. crmRes = new CErrorResponseMessage(sMsg, i_crmInput);
  1052. }
  1053. return crmRes;
  1054. }
  1055. private string createCopyArticle(CRequestMessage i_crmInput, JArray i_jaData, int draft, List<string> productUid)
  1056. {
  1057. string sMsg = null;
  1058. List<Command> lCmds = new List<Command>();
  1059. string sNewArticleUid = "";
  1060. try
  1061. {
  1062. do
  1063. {
  1064. foreach (JToken joData in i_jaData)
  1065. {
  1066. List<string> lsEmpColumns = EntityBase.GetAllColumnName(typeof(tb_grp_article));
  1067. var lsBranch = ProjectHelper.GetUserGroup(i_crmInput);
  1068. Dictionary<string, object> dicData = joData.ToObject<Dictionary<string, object>>();
  1069. JObject jdata = dicData[BLWording.DATA] as JObject;
  1070. Dictionary<string, object> dicInput = jdata.ToObject<Dictionary<string, object>>();
  1071. sNewArticleUid = Guid.NewGuid().ToString();
  1072. tb_grp_article cInsert = new tb_grp_article()
  1073. {
  1074. uid = sNewArticleUid,
  1075. name = (dicInput[tb_grp_article.CN_NAME] ?? "").ToString(),
  1076. group_uid = (dicInput[tb_grp_article.CN_GROUP_UID] ?? "").ToString(),
  1077. // fb_article_id = (dicInput[tb_grp_article.CN_FB_ARTICLE_ID] ?? "").ToString(),
  1078. message = dicInput[tb_grp_article.CN_MESSAGE].ToString(),
  1079. post_status = Convert.ToInt32(dicInput[tb_grp_article.CN_POST_STATUS]),
  1080. draft = draft,
  1081. draft_uid = draft == 1 ? sNewArticleUid : (dicInput[tb_grp_article.CN_DRAFT_UID] ?? "").ToString(),
  1082. remark = (dicInput[tb_grp_article.CN_REMARK])?.ToString(),
  1083. dutyfree = (dicInput[tb_grp_article.CN_DUTYFREE] ?? "").ToString().ToLower() == "true" ? "1" : "0"
  1084. };
  1085. // 發布時間可能為空
  1086. if (dicInput.ContainsKey(tb_grp_article.CN_RELEASE_DATE) && dicInput[tb_grp_article.CN_RELEASE_DATE] != null)
  1087. {
  1088. cInsert.release_date = Convert.ToDateTime(dicInput[tb_grp_article.CN_RELEASE_DATE].ToString());
  1089. }
  1090. // 截團時間可能為空
  1091. if (dicInput.ContainsKey(tb_grp_article.CN_CLOSE_DATE) && dicInput[tb_grp_article.CN_CLOSE_DATE] != null)
  1092. {
  1093. cInsert.close_date = Convert.ToDateTime(dicInput[tb_grp_article.CN_CLOSE_DATE].ToString());
  1094. }
  1095. Command c = Command.SetupInsertCmd(cInsert);
  1096. lCmds.Add(c);
  1097. //}
  1098. // Log
  1099. sMsg = getManualLog(i_crmInput, dicData, BLWording.LOG_ACTION_NAME_INSERTSQL, out Command cLog);
  1100. if (sMsg != null)
  1101. {
  1102. break;
  1103. }
  1104. if (cLog != null)
  1105. {
  1106. lCmds.Add(cLog);
  1107. }
  1108. string sMediaKey = nameof(tb_grp_article_media);
  1109. if (!jdata.ContainsKey(sMediaKey))
  1110. {
  1111. sMsg = "common.no_media_fle";
  1112. break;
  1113. }
  1114. List<MediaInfo> lmi = jdata[sMediaKey].ToObject<List<MediaInfo>>();
  1115. lmi.ForEach(f =>
  1116. {
  1117. lCmds.Add(Command.SetupInsertCmd(new tb_grp_article_media()
  1118. {
  1119. uid = Guid.NewGuid().ToString(),
  1120. article_uid = sNewArticleUid,
  1121. media_id = f.display.Substring(f.display.IndexOf('=') + 1),
  1122. type = f.mediatype,
  1123. status_flag = BLWording.STATUS_FLAG_ON
  1124. }));
  1125. });
  1126. string sProductKey = nameof(tb_prd_article2product);
  1127. if (!jdata.ContainsKey(sProductKey))
  1128. {
  1129. sMsg = "grp.no_product";
  1130. break;
  1131. }
  1132. //List<tb_prd_article2product> la2pProducts = jdata[sProductKey].ToObject<List<tb_prd_article2product>>();
  1133. //new Article2ProductService().CreateProduct(sNewArticleUid, la2pProducts, dicInput[tb_grp_article.CN_GROUP_UID].ToString(), ref lCmds);
  1134. if (dicInput.ContainsKey(nameof(tb_prd_article2product)))
  1135. {
  1136. List<tb_prd_article2product> la2pFrontEnd = (dicInput[nameof(tb_prd_article2product)] as JArray).ToObject<List<tb_prd_article2product>>();
  1137. var count = 0;
  1138. // Only in dicInput => Add
  1139. la2pFrontEnd.ForEach((f) =>
  1140. {
  1141. string sProductUid = "";
  1142. if (f.prd_uid == null && productUid.Count != 0)
  1143. {
  1144. sProductUid = productUid[count];
  1145. count++;
  1146. }
  1147. else
  1148. {
  1149. sProductUid = f.prd_uid;
  1150. }
  1151. tb_prd_product pDisplay = new tb_prd_product();
  1152. pDisplay.SetFullDirty();
  1153. tb_prd_product p = new tb_prd_product()
  1154. {
  1155. uid = sProductUid
  1156. };
  1157. Command cSelectP = Command.SetupSelectCmd(pDisplay, p);
  1158. ArsenalInterface ai = ArsenalDBMgr.GetInst(cSelectP, GetDefaultSystemColumnInfo());
  1159. List<tb_prd_article2product> la2pOri = ai.RunQueryList<tb_prd_article2product>(cSelectP);
  1160. if (la2pOri.FirstOrDefault() == null)
  1161. {
  1162. sProductUid = Guid.NewGuid().ToString();
  1163. // Create Product first
  1164. lCmds.Add(Command.SetupInsertCmd(new tb_prd_product()
  1165. {
  1166. uid = sProductUid,
  1167. name = f.name,
  1168. group_id = dicInput[tb_grp_article.CN_GROUP_UID].ToString(),
  1169. price = f.price,
  1170. wholesale_price = f.wholesale_price,
  1171. cost_price = f.cost_price
  1172. }));
  1173. }
  1174. lCmds.Add(Command.SetupInsertCmd(new tb_prd_article2product()
  1175. {
  1176. uid = Guid.NewGuid().ToString(),
  1177. price = f.price,
  1178. wholesale_price = f.wholesale_price,
  1179. name = f.name,
  1180. article_uid = sNewArticleUid,
  1181. prd_uid = sProductUid,
  1182. seq = f.seq,
  1183. specification = f.specification.ToUpper(),
  1184. cost_price = f.cost_price
  1185. }));
  1186. });
  1187. }
  1188. ArsenalInterface ai = ArsenalDBMgr.GetInst(lCmds[0], GetDefaultSystemColumnInfo());
  1189. ai.RunEditCmds(lCmds);
  1190. sMsg = GetLastErrorCode(lCmds);
  1191. if (sMsg != null)
  1192. {
  1193. return sMsg;
  1194. }
  1195. }
  1196. }
  1197. while (false);
  1198. }
  1199. catch (Exception ex)
  1200. {
  1201. LogHelper.DBLog(Util.GetLastExceptionMsg(ex));
  1202. sMsg = $"{nameof(createCopyArticle)} unknwon exception. i_crmInput={JsonConvert.SerializeObject(i_crmInput)}. ";
  1203. #if DEBUG
  1204. System.Diagnostics.Debug.WriteLine(sMsg);
  1205. #endif
  1206. throw new Exception(sMsg);
  1207. }
  1208. return sNewArticleUid;
  1209. }
  1210. public CResponseMessage UpdateArticle(CRequestMessage i_crmInput)
  1211. {
  1212. string sMsg = null;
  1213. List<Command> lCmds = new List<Command>();
  1214. CResponseMessage crmRes = null;
  1215. JArray i_jaData = i_crmInput.param[BLWording.UPD_MASTER] as JArray;
  1216. try
  1217. {
  1218. do
  1219. {
  1220. string post_status = null;
  1221. string opost_status = "0";
  1222. bool isSchedule = false;
  1223. string action = null;
  1224. string oriArticleId = null;
  1225. string downloadurl = null;
  1226. List<string> productUid = new List<string>();
  1227. foreach (JToken joData in i_jaData)
  1228. {
  1229. Dictionary<string, object> dicData = joData.ToObject<Dictionary<string, object>>();
  1230. if (dicData.ContainsKey("isProductValid"))
  1231. {
  1232. if (Convert.ToBoolean(dicData["isProductValid"]) == false)
  1233. {
  1234. sMsg = "商品價格錯誤";
  1235. break;
  1236. }
  1237. }
  1238. JObject jalldata = dicData[BLWording.DATA] as JObject;
  1239. downloadurl = dicData[GrpBLWording.GRP_DOWNLOADURL].ToString();
  1240. oriArticleId = jalldata[tb_grp_article.CN_UID].ToString();
  1241. sMsg = getManualLog(i_crmInput, dicData, BLWording.LOG_ACTION_NAME_INSERTSQL, out Command cLog);
  1242. if (sMsg != null)
  1243. {
  1244. crmRes = new CErrorResponseMessage(sMsg, i_crmInput);
  1245. break;
  1246. }
  1247. if (cLog != null)
  1248. {
  1249. lCmds.Add(cLog);
  1250. }
  1251. if (dicData.ContainsKey("action"))
  1252. {
  1253. action = dicData["action"].ToString();
  1254. }
  1255. // 判斷有無release_date 來決定是否排程與是否發佈
  1256. if (jalldata.ContainsKey(tb_grp_article.CN_RELEASE_DATE))
  1257. {
  1258. bool isDateTime = DateTime.TryParse(jalldata[tb_grp_article.CN_RELEASE_DATE].ToString(), out DateTime release_date);
  1259. if (isDateTime && release_date < DateTime.Now.AddMinutes(-30) && action != "Save")
  1260. {
  1261. sMsg = "datetime wrong";
  1262. break;
  1263. }
  1264. if (isDateTime && action != "Save")
  1265. {
  1266. isSchedule = true;
  1267. }
  1268. else if (isDateTime && action == "Save")
  1269. {
  1270. isSchedule = true;
  1271. }
  1272. }
  1273. // 判斷是否為草稿
  1274. if (jalldata.ContainsKey(tb_grp_article.CN_POST_STATUS))
  1275. {
  1276. post_status = jalldata[tb_grp_article.CN_POST_STATUS].ToString();
  1277. }
  1278. if (jalldata.ContainsKey("opost_status"))
  1279. {
  1280. opost_status = jalldata["opost_status"].ToString();
  1281. }
  1282. //List<Command> lcMst = getUpdListCommand(i_crmInput, i_jaData, typeof(tb_grp_article).GetField("TABLENAME").GetValue(null).ToString(), i_saQryContainKeys, out sMsg);
  1283. //判斷是否為Establish 如果是就不Update
  1284. //if (action == "Establish")
  1285. //{
  1286. // //lCmds.Add(lcMst[0]);
  1287. // continue;
  1288. //}
  1289. var oData = new tb_grp_article();
  1290. if (jalldata[tb_grp_article.CN_CLOSE_DATE].ToString() == "")
  1291. {
  1292. oData.close_date = null;
  1293. }
  1294. else
  1295. {
  1296. oData.close_date = Convert.ToDateTime(jalldata[tb_grp_article.CN_CLOSE_DATE].ToString());
  1297. }
  1298. if (jalldata[tb_grp_article.CN_RELEASE_DATE].ToString() == "")
  1299. {
  1300. oData.release_date = null;
  1301. }
  1302. else
  1303. {
  1304. oData.release_date = Convert.ToDateTime(jalldata[tb_grp_article.CN_RELEASE_DATE].ToString());
  1305. }
  1306. oData.message = jalldata[tb_grp_article.CN_MESSAGE].ToString();
  1307. oData.name = jalldata[tb_grp_article.CN_NAME].ToString();
  1308. oData.group_uid = jalldata[tb_grp_article.CN_GROUP_UID].ToString();
  1309. oData.remark= jalldata[tb_grp_article.CN_REMARK].ToString();
  1310. oData.dutyfree = jalldata[tb_grp_article.CN_DUTYFREE].ToString().ToLower() == "true" ? "1" : "0";
  1311. if (int.Parse(opost_status) > 2)
  1312. {
  1313. if (action == "Post")
  1314. {
  1315. oData.post_status = int.Parse(opost_status);
  1316. post_status = opost_status;
  1317. }
  1318. }
  1319. else
  1320. {
  1321. if (action == "Post")
  1322. {
  1323. oData.post_status = int.Parse(post_status);
  1324. }
  1325. }
  1326. if (action != "Establish" && action != "Post")
  1327. {
  1328. Command c = Command.SetupUpdateCmd(oData,
  1329. new WhereNode(tb_grp_article.CN_UID, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_grp_article), oriArticleId));
  1330. lCmds.Add(c);
  1331. }
  1332. if (sMsg != null)
  1333. {
  1334. break;
  1335. }
  1336. //lCmds.AddRange(lcMst);
  1337. if (!dicData.ContainsKey(BLWording.DATA))
  1338. {
  1339. continue;
  1340. }
  1341. JObject jdata = dicData[BLWording.DATA] as JObject;
  1342. JObject jwheredata = dicData[BLWording.WHEREDATA] as JObject;
  1343. Dictionary<string, object> dicWhere = new Dictionary<string, object>();
  1344. if (null != JProperty2Dic(jwheredata, ref dicWhere))
  1345. {
  1346. sMsg = MessageWording.PARAM_NOT_EXPECTED; //參數錯誤
  1347. break;
  1348. }
  1349. Dictionary<string, object> dicInput = jdata.ToObject<Dictionary<string, object>>();
  1350. string sArticleUid = dicWhere[tb_grp_article.CN_UID].ToString();
  1351. if (dicInput.ContainsKey(nameof(tb_grp_article_media)))
  1352. {
  1353. tb_grp_article_media a2mDisplay = new tb_grp_article_media();
  1354. a2mDisplay.SetFullDirty();
  1355. tb_grp_article_media a2m = new tb_grp_article_media()
  1356. {
  1357. article_uid = sArticleUid
  1358. };
  1359. Command cSelecta2m = Command.SetupSelectCmd(a2mDisplay, a2m);
  1360. ArsenalInterface ai = ArsenalDBMgr.GetInst(cSelecta2m, GetDefaultSystemColumnInfo());
  1361. List<tb_grp_article_media> la2mOri = ai.RunQueryList<tb_grp_article_media>(cSelecta2m);
  1362. if (!cSelecta2m.IsSuccess)
  1363. {
  1364. sMsg = cSelecta2m.LastErrorCode;
  1365. break;
  1366. }
  1367. List<MediaInfo> la2mFrontEnd = (dicInput[nameof(tb_grp_article_media)] as JArray).ToObject<List<MediaInfo>>();
  1368. var seq = 1;
  1369. // Only in dicInput => Add
  1370. la2mFrontEnd.ForEach(f =>
  1371. {
  1372. tb_grp_article_media a2mMatch = la2mOri.FirstOrDefault(g => g.uid == f.uid);
  1373. if (f.uid == BLWording.CREATEUID || a2mMatch == null)
  1374. {
  1375. lCmds.Add(Command.SetupInsertCmd(new tb_grp_article_media()
  1376. {
  1377. uid = Guid.NewGuid().ToString(),
  1378. article_uid = sArticleUid,
  1379. media_id = f.display.Substring(f.display.IndexOf('=') + 1),
  1380. type = f.mediatype,
  1381. status_flag = BLWording.STATUS_FLAG_ON
  1382. }));
  1383. }
  1384. else
  1385. {
  1386. // update seq
  1387. lCmds.Add(Command.SetupUpdateCmd(new tb_grp_article_media()
  1388. {
  1389. seq = seq++
  1390. },
  1391. new tb_grp_article_media()
  1392. {
  1393. uid = f.uid
  1394. }
  1395. ));
  1396. }
  1397. });
  1398. // Only in la2mOri => Delete
  1399. la2mOri.ForEach(f =>
  1400. {
  1401. MediaInfo a2mMatch = la2mFrontEnd.FirstOrDefault(g => g.uid == f.uid);
  1402. if (a2mMatch == null)
  1403. {
  1404. lCmds.Add(Command.SetupDeleteCmd(
  1405. new tb_grp_article_media()
  1406. {
  1407. uid = f.uid
  1408. }
  1409. ));
  1410. }
  1411. });
  1412. }
  1413. if (dicInput.ContainsKey(nameof(tb_prd_article2product)))
  1414. {
  1415. tb_prd_article2product a2pDisplay = new tb_prd_article2product();
  1416. a2pDisplay.SetFullDirty();
  1417. tb_prd_article2product a2p = new tb_prd_article2product()
  1418. {
  1419. article_uid = sArticleUid
  1420. };
  1421. Command cSelectA2P = Command.SetupSelectCmd(a2pDisplay, a2p);
  1422. ArsenalInterface ai = ArsenalDBMgr.GetInst(cSelectA2P, GetDefaultSystemColumnInfo());
  1423. List<tb_prd_article2product> la2pOri = ai.RunQueryList<tb_prd_article2product>(cSelectA2P);
  1424. if (!cSelectA2P.IsSuccess)
  1425. {
  1426. sMsg = cSelectA2P.LastErrorCode;
  1427. break;
  1428. }
  1429. List<tb_prd_article2product> la2pFrontEnd = (dicInput[nameof(tb_prd_article2product)] as JArray).ToObject<List<tb_prd_article2product>>();
  1430. // Only in dicInput => Add
  1431. la2pFrontEnd.ForEach(f =>
  1432. {
  1433. string sProductUid = f.prd_uid;
  1434. if (sProductUid == null)
  1435. {
  1436. sProductUid = Guid.NewGuid().ToString();
  1437. productUid.Add(sProductUid);
  1438. // Create Product first
  1439. lCmds.Add(Command.SetupInsertCmd(new tb_prd_product()
  1440. {
  1441. uid = sProductUid,
  1442. name = f.name,
  1443. group_id = dicInput[tb_grp_article.CN_GROUP_UID].ToString(),
  1444. price = f.price,
  1445. wholesale_price = f.wholesale_price,
  1446. cost_price = f.cost_price
  1447. }));
  1448. }
  1449. tb_prd_article2product a2pMatch = la2pOri.FirstOrDefault(g => g.uid == f.uid);
  1450. if (f.uid == BLWording.CREATEUID || a2pMatch == null)
  1451. {
  1452. lCmds.Add(Command.SetupInsertCmd(new tb_prd_article2product()
  1453. {
  1454. uid = Guid.NewGuid().ToString(),
  1455. price = f.price,
  1456. wholesale_price = f.wholesale_price,
  1457. name = f.name,
  1458. article_uid = sArticleUid,
  1459. prd_uid = sProductUid,
  1460. seq = f.seq,
  1461. specification = f.specification.ToUpper(),
  1462. cost_price = f.cost_price
  1463. }));
  1464. }
  1465. else
  1466. {
  1467. // Update
  1468. lCmds.Add(Command.SetupUpdateCmd(
  1469. new tb_prd_article2product()
  1470. {
  1471. price = f.price,
  1472. wholesale_price = f.wholesale_price,
  1473. name = f.name,
  1474. article_uid = sArticleUid,
  1475. prd_uid = sProductUid,
  1476. seq = f.seq,
  1477. specification = f.specification.ToUpper(),
  1478. cost_price = f.cost_price
  1479. },
  1480. new tb_prd_article2product()
  1481. {
  1482. uid = a2pMatch.uid
  1483. }
  1484. ));
  1485. lCmds.Add(Command.SetupUpdateCmd(
  1486. new tb_prd_product()
  1487. {
  1488. name = f.name
  1489. },
  1490. new tb_prd_product()
  1491. {
  1492. uid = sProductUid
  1493. }
  1494. ));
  1495. }
  1496. });
  1497. // Only in la2pOri => Delete
  1498. la2pOri.ForEach(f =>
  1499. {
  1500. tb_prd_article2product a2pMatch = la2pFrontEnd.FirstOrDefault(g => g.uid == f.uid);
  1501. if (a2pMatch == null)
  1502. {
  1503. if (int.Parse(opost_status) >= (int)Enums.EPostStatus.EPS_ORDER)
  1504. {
  1505. sMsg = "已結單文章不得刪除商品";
  1506. return;
  1507. }
  1508. lCmds.Add(Command.SetupDeleteCmd(
  1509. new tb_prd_article2product()
  1510. {
  1511. uid = f.uid
  1512. }
  1513. ));
  1514. }
  1515. });
  1516. }
  1517. }
  1518. if (sMsg != null)
  1519. {
  1520. break;
  1521. }
  1522. ArsenalInterface ai_upd = ArsenalDBMgr.GetInst(lCmds[0], GetDefaultSystemColumnInfo());
  1523. int iRes = ai_upd.RunEditCmds(lCmds);
  1524. sMsg = GetLastErrorCode(lCmds);
  1525. if (sMsg != null)
  1526. {
  1527. sMsg = GetLastErrorMessage(lCmds);
  1528. break;
  1529. }
  1530. crmRes = new CSuccessResponseMessage(null, i_crmInput);
  1531. crmRes.param.Add(BLWording.AFFECTCOUNT, iRes);
  1532. if (sMsg != null)
  1533. {
  1534. break;
  1535. }
  1536. // 開始判斷各種Action邏輯
  1537. string newArticleId = null;
  1538. if (int.Parse(opost_status) > 2) // status > 2 為已發文
  1539. {
  1540. if (isSchedule)
  1541. {
  1542. if (action == "Establish") // 是Establish就新增為底稿
  1543. {
  1544. createCopyArticle(i_crmInput, i_jaData, 1, productUid);
  1545. }
  1546. else if (action == "Post") // 是Post新增為非底稿
  1547. {
  1548. createCopyArticle(i_crmInput, i_jaData, 0, productUid);
  1549. }
  1550. }
  1551. else
  1552. {
  1553. if (action == "Establish") // 是Establish就新增為底稿
  1554. {
  1555. createCopyArticle(i_crmInput, i_jaData, 1, productUid);
  1556. }
  1557. else if (action == "Post") // 是Post新增為非底稿
  1558. {
  1559. newArticleId = createCopyArticle(i_crmInput, i_jaData, 0, productUid);
  1560. }
  1561. }
  1562. }
  1563. else
  1564. {
  1565. if (action == "Establish") // 非上傳文章之Establish 新增為底稿
  1566. {
  1567. newArticleId = createCopyArticle(i_crmInput, i_jaData, 1, productUid);
  1568. }
  1569. }
  1570. // 非排程且action為Post 就直接上傳
  1571. if (!isSchedule && action == "Post")
  1572. {
  1573. if (newArticleId != null)
  1574. {
  1575. sMsg = _PushPostDetail(newArticleId, downloadurl, true, out _);
  1576. }
  1577. else
  1578. {
  1579. sMsg = _PushPostDetail(oriArticleId, downloadurl, true, out _);
  1580. }
  1581. }
  1582. if (sMsg != null)
  1583. {
  1584. break;
  1585. }
  1586. }
  1587. while (false);
  1588. }
  1589. catch (Exception ex)
  1590. {
  1591. LogHelper.DBLog(Util.GetLastExceptionMsg(ex));
  1592. sMsg = $"{nameof(UpdateArticle)} unknwon exception. i_crmInput={JsonConvert.SerializeObject(i_crmInput)}. ";
  1593. #if DEBUG
  1594. System.Diagnostics.Debug.WriteLine(sMsg);
  1595. #endif
  1596. }
  1597. if (null != sMsg)
  1598. {
  1599. crmRes = new CErrorResponseMessage(sMsg, i_crmInput);
  1600. }
  1601. return crmRes;
  1602. }
  1603. /// <summary>
  1604. /// 與原版的UpdateArticle差別在只更新社團ID進去
  1605. /// </summary>
  1606. /// <param name="i_crmInput"></param>
  1607. /// <returns></returns>
  1608. public CResponseMessage UpdateArticleManual(CRequestMessage i_crmInput)
  1609. {
  1610. string sMsg = null;
  1611. List<Command> lCmds = new List<Command>();
  1612. CResponseMessage crmRes = null;
  1613. JArray i_jaData = i_crmInput.param[BLWording.UPD_MASTER] as JArray;
  1614. try
  1615. {
  1616. do
  1617. {
  1618. lCmds = getUpdListCommand(i_crmInput, i_jaData, typeof(tb_grp_article).GetField("TABLENAME").GetValue(null).ToString(), new List<string>() { "uid" }, out sMsg);
  1619. ArsenalInterface ai_upd = ArsenalDBMgr.GetInst(lCmds[0], GetDefaultSystemColumnInfo());
  1620. int iRes = ai_upd.RunEditCmds(lCmds);
  1621. sMsg = GetLastErrorCode(lCmds);
  1622. if (sMsg != null)
  1623. {
  1624. sMsg = GetLastErrorMessage(lCmds);
  1625. break;
  1626. }
  1627. crmRes = new CSuccessResponseMessage("", i_crmInput);
  1628. }
  1629. while (false);
  1630. }
  1631. catch (Exception ex)
  1632. {
  1633. LogHelper.DBLog(Util.GetLastExceptionMsg(ex));
  1634. sMsg = $"{nameof(UpdateArticle)} unknwon exception. i_crmInput={JsonConvert.SerializeObject(i_crmInput)}. ";
  1635. #if DEBUG
  1636. System.Diagnostics.Debug.WriteLine(sMsg);
  1637. #endif
  1638. }
  1639. if (null != sMsg)
  1640. {
  1641. crmRes = new CErrorResponseMessage(sMsg, i_crmInput);
  1642. }
  1643. return crmRes;
  1644. }
  1645. public CResponseMessage SearchArticle(CRequestMessage i_crmInput)
  1646. {
  1647. string sMsg;
  1648. CResponseMessage crmRes = null;
  1649. try
  1650. {
  1651. do
  1652. {
  1653. List<string> lsEmpColumns = EntityBase.GetAllColumnName(typeof(tb_grp_article));
  1654. // 取得condition
  1655. Dictionary<string, string> dicCondition = GetQueryMasterFirstQJEDicwherecols(i_crmInput);
  1656. var lsBranch = ProjectHelper.GetUserGroup(i_crmInput);
  1657. // 取回文章ID跟UserToken
  1658. sMsg = GetUserToken(dicCondition[tb_grp_article.CN_GROUP_UID].ToString(), out List<GroupViewModel> qdGroup);
  1659. if (sMsg != null)
  1660. {
  1661. break;
  1662. }
  1663. var Articledata = new FbHelper().CallFbPostGetDataAPI(qdGroup.First().user_token, qdGroup.First().fb_group_id);
  1664. //QueryJsonElement qjeArticle = lBlocks.GetInst();
  1665. //qjeArticle.table = tb_grp_article.TABLENAME;
  1666. //qjeArticle.displaycols = lsEmpColumns;
  1667. //List<WhereNode> lwnMainInfo = new List<WhereNode>();
  1668. //lwnMainInfo.Add(new WhereNode(tb_grp_article.CN_GROUP_UID, WhereNode.EColumnOperation.EOT_IN, typeof(tb_grp_article), lsBranch.ToArray()));
  1669. //lwnMainInfo.Add(new WhereNode(tb_grp_article.CN_STATUS_FLAG, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_grp_article), BLWording.STATUS_FLAG_ON));
  1670. //if (dicCondition.ContainsKey(tb_grp_article.CN_NAME))
  1671. //{
  1672. // lwnMainInfo.Add(new WhereNode(tb_grp_article.CN_NAME, WhereNode.EColumnOperation.EOT_LIKE, typeof(tb_grp_article), dicCondition[tb_grp_article.CN_NAME].ToString()));
  1673. //}
  1674. //qjeArticle.wherecols = new WhereNode(WhereNode.ENodeOperation.ENO_AND, lwnMainInfo.ToArray());
  1675. //lBlocks.Add(qjeArticle);
  1676. //sMsg = MakeSelectJoinByBlocks(lBlocks, out Command cRead);
  1677. //ArsenalInterface ai = ArsenalDBMgr.GetInst(cRead);
  1678. //var qds = ai.RunQueryList<ArticleMediaInfo>(cRead);
  1679. //var groupData = qds.OrderByDescending(x => x.create_date).GroupBy(x => new { x.draft_uid }).ToList();
  1680. string filter = dicCondition.ContainsKey(tb_grp_article.CN_NAME) ? dicCondition[tb_grp_article.CN_NAME].ToString() : "";
  1681. var res = Articledata.data.Where(x =>
  1682. {
  1683. if (x.message != null)
  1684. {
  1685. return x.message.Contains(filter);
  1686. }
  1687. return false;
  1688. }).Select(x => new
  1689. {
  1690. x.full_picture,
  1691. x.id,
  1692. x.message,
  1693. x.source,
  1694. x.created_time
  1695. }).ToList();
  1696. crmRes = new CSuccessResponseMessage(null, i_crmInput);
  1697. crmRes.param.Add(BLWording.DATA, res);
  1698. }
  1699. while (false);
  1700. }
  1701. catch (Exception ex)
  1702. {
  1703. LogHelper.DBLog(Util.GetLastExceptionMsg(ex));
  1704. sMsg = $"{nameof(SearchArticle)} unknwon exception. i_crmInput={JsonConvert.SerializeObject(i_crmInput)}. ";
  1705. #if DEBUG
  1706. System.Diagnostics.Debug.WriteLine(sMsg);
  1707. #endif
  1708. }
  1709. if (null != sMsg)
  1710. {
  1711. crmRes = new CErrorResponseMessage(sMsg, i_crmInput);
  1712. }
  1713. return crmRes;
  1714. }
  1715. public CResponseMessage ImportArticle(CRequestMessage i_crmInput)
  1716. {
  1717. string sMsg;
  1718. CResponseMessage crmRes = null;
  1719. List<Command> lCmds = new List<Command>();
  1720. try
  1721. {
  1722. do
  1723. {
  1724. JArray i_jaData = i_crmInput.param[BLWording.ADD_MASTER] as JArray;
  1725. foreach (JToken joData in i_jaData)
  1726. {
  1727. Dictionary<string, object> dicData = joData.ToObject<Dictionary<string, object>>();
  1728. JObject jdata = dicData[BLWording.DATA] as JObject;
  1729. Dictionary<string, object> dicInput = jdata.ToObject<Dictionary<string, object>>();
  1730. if (dicInput.ContainsKey("isProductValid"))
  1731. {
  1732. if (Convert.ToBoolean(dicInput["isProductValid"]) == false)
  1733. {
  1734. sMsg = "商品價格錯誤";
  1735. crmRes = new CErrorResponseMessage(sMsg, i_crmInput);
  1736. break;
  1737. }
  1738. }
  1739. if (!dicInput.ContainsKey("id"))
  1740. {
  1741. sMsg = "文章資料錯誤";
  1742. crmRes = new CErrorResponseMessage(sMsg, i_crmInput);
  1743. break;
  1744. }
  1745. // 先查詢資料是否存在
  1746. tb_grp_article cArticle = new tb_grp_article();
  1747. cArticle.SetFullDirty();
  1748. tb_grp_article cArticleCon = new tb_grp_article() { fb_article_id = dicInput["id"].ToString(), status_flag = BLWording.STATUS_FLAG_ON };
  1749. Command cArticleSelect = Command.SetupSelectCmd(cArticle, cArticleCon);
  1750. ArsenalInterface ai = ArsenalDBMgr.GetInst(cArticleSelect);
  1751. tb_grp_article qdsArticle = ai.RunQuerySingleORM<tb_grp_article>(cArticleSelect);
  1752. if (qdsArticle != null)
  1753. {
  1754. sMsg = "此文章已存在於系統";
  1755. crmRes = new CErrorResponseMessage(sMsg, i_crmInput);
  1756. break;
  1757. }
  1758. string sNewArticleUid = Guid.NewGuid().ToString();
  1759. string newArticleMediaUid = Guid.NewGuid().ToString();
  1760. string newArticleMediaId = Guid.NewGuid().ToString();
  1761. string newArticleMediaName = string.Format(CultureInfo.CurrentCulture, "{0}_{1}", (i_crmInput.customparam[BLWording.SESSION_USER] as tb_sys_session).update_user_uid, DateTime.Now.ToString("yyyyMMddHHMMssfff", CultureInfo.CurrentCulture));
  1762. WebClient webClient = new WebClient();
  1763. string filePath = Path.Combine(RootPath, SystemSettingHelper.FileFolder(SystemSettingHelper.EPath.EP_FILETMP)) + "\\" + newArticleMediaName + ".jpg";
  1764. // if FB Post has full_picture
  1765. if (!dicInput.ContainsKey("full_picture"))
  1766. {
  1767. sMsg = "欲匯入文章沒有圖片";
  1768. crmRes = new CErrorResponseMessage(sMsg, i_crmInput);
  1769. break;
  1770. }
  1771. webClient.DownloadFile(dicInput["full_picture"].ToString(), filePath);
  1772. FileUploadHelper fuh = new FileUploadHelper(GetFileUploadInfo(), i_crmInput);
  1773. sMsg = fuh.UploadLocalFile(filePath, out tb_sys_uploadlog ulRes);
  1774. if (sMsg != null)
  1775. {
  1776. crmRes = new CErrorResponseMessage(sMsg, i_crmInput);
  1777. break;
  1778. }
  1779. lCmds.Add(Command.SetupInsertCmd(new tb_grp_article_media()
  1780. {
  1781. uid = newArticleMediaUid,
  1782. article_uid = sNewArticleUid,
  1783. media_id = ulRes.uid,
  1784. type = "photo",
  1785. seq = 1,
  1786. status_flag = BLWording.STATUS_FLAG_ON
  1787. }));
  1788. tb_grp_article cInsert = new tb_grp_article()
  1789. {
  1790. uid = sNewArticleUid,
  1791. name = (dicInput[tb_grp_article.CN_NAME] ?? "").ToString(),
  1792. group_uid = (dicInput[tb_grp_article.CN_GROUP_UID] ?? "").ToString(),
  1793. fb_article_id = (dicInput["id"] ?? "").ToString(),
  1794. post_date = Convert.ToDateTime(dicInput["created_time"]),
  1795. message = dicInput[tb_grp_article.CN_MESSAGE].ToString(),
  1796. post_status = (int)Enums.EPostStatus.EPS_COMPLETE,
  1797. draft = 1,
  1798. draft_uid = sNewArticleUid
  1799. };
  1800. // 發布時間可能為空
  1801. if (dicInput.ContainsKey(tb_grp_article.CN_RELEASE_DATE) && dicInput[tb_grp_article.CN_RELEASE_DATE] != null)
  1802. {
  1803. cInsert.release_date = Convert.ToDateTime(dicInput[tb_grp_article.CN_RELEASE_DATE].ToString());
  1804. }
  1805. Command c = Command.SetupInsertCmd(cInsert);
  1806. lCmds.Add(c);
  1807. // Log
  1808. sMsg = getManualLog(i_crmInput, dicData, BLWording.LOG_ACTION_NAME_INSERTSQL, out Command cLog);
  1809. if (sMsg != null)
  1810. {
  1811. crmRes = new CErrorResponseMessage(sMsg, i_crmInput);
  1812. break;
  1813. }
  1814. if (cLog != null)
  1815. {
  1816. lCmds.Add(cLog);
  1817. }
  1818. string sProductKey = nameof(tb_prd_article2product);
  1819. if (!jdata.ContainsKey(sProductKey))
  1820. {
  1821. sMsg = "grp.no_product";
  1822. crmRes = new CErrorResponseMessage(sMsg, i_crmInput);
  1823. break;
  1824. }
  1825. List<tb_prd_article2product> la2pProducts = jdata[sProductKey].ToObject<List<tb_prd_article2product>>();
  1826. if (!la2pProducts.Any())
  1827. {
  1828. sMsg = "grp.no_product";
  1829. crmRes = new CErrorResponseMessage(sMsg, i_crmInput);
  1830. break;
  1831. }
  1832. new Article2ProductService().CreateProduct(sNewArticleUid, la2pProducts, cInsert.group_uid, ref lCmds);
  1833. ArsenalInterface ai_upd = ArsenalDBMgr.GetInst(lCmds[0], GetDefaultSystemColumnInfo());
  1834. int iRes = ai_upd.RunEditCmds(lCmds);
  1835. sMsg = GetLastErrorCode(lCmds);
  1836. if (sMsg != null)
  1837. {
  1838. sMsg = GetLastErrorMessage(lCmds);
  1839. crmRes = new CErrorResponseMessage(sMsg, i_crmInput);
  1840. break;
  1841. }
  1842. crmRes = new CSuccessResponseMessage(null, i_crmInput);
  1843. crmRes.param.Add(BLWording.AFFECTCOUNT, iRes);
  1844. }
  1845. }
  1846. while (false);
  1847. }
  1848. catch (Exception ex)
  1849. {
  1850. LogHelper.DBLog(Util.GetLastExceptionMsg(ex));
  1851. sMsg = $"{nameof(ImportArticle)} unknwon exception. i_crmInput={JsonConvert.SerializeObject(i_crmInput)}. ";
  1852. #if DEBUG
  1853. System.Diagnostics.Debug.WriteLine(sMsg);
  1854. crmRes = new CErrorResponseMessage(sMsg, i_crmInput);
  1855. #endif
  1856. }
  1857. return crmRes;
  1858. }
  1859. public CResponseMessage BindFbPostToArticle(CRequestMessage i_crmInput)
  1860. {
  1861. string sMsg;
  1862. CResponseMessage crmRes = null;
  1863. List<Command> lCmds = new List<Command>();
  1864. try
  1865. {
  1866. do
  1867. {
  1868. sMsg = getCommonParameter(i_crmInput, BLWording.UPD_MASTER, out JArray jaDataArray, out tb_sys_session sUserSession);
  1869. if (sMsg != null)
  1870. {
  1871. break;
  1872. }
  1873. if (jaDataArray.Count != 1 || jaDataArray[0] == null)
  1874. {
  1875. sMsg = MessageWording.PARAM_NOT_EXPECTED;
  1876. break;
  1877. }
  1878. JObject joData = jaDataArray[0] as JObject;
  1879. Dictionary<string, object> dicCondition = new Dictionary<string, object>();
  1880. if (joData != null)
  1881. {
  1882. dicCondition = joData[BLWording.DATA].ToObject<Dictionary<string, object>>();
  1883. }
  1884. // 判斷為社團ID還是分店ID
  1885. sMsg = GetUserToken(dicCondition[tb_grp_article.CN_GROUP_UID].ToString(), out List<GroupViewModel> qdGroup);
  1886. if (sMsg != null || qdGroup == null)
  1887. {
  1888. sMsg = "尋找社團資訊時發生了問題";
  1889. break;
  1890. }
  1891. qdGroup = qdGroup.Where(x => x.status_flag == BLWording.STATUS_FLAG_ON).ToList();
  1892. if(qdGroup.Count == 0)
  1893. {
  1894. sMsg = "尋找社團資訊時發生了問題";
  1895. break;
  1896. }
  1897. if (qdGroup.First().fb_group_id != dicCondition[tb_grp_group.CN_FB_GROUP_ID].ToString())
  1898. {
  1899. sMsg = "社團網址錯誤";
  1900. break;
  1901. }
  1902. var Articledata = new FbHelper().CallSingleFbPostGetDataAPI(qdGroup.First().user_token, dicCondition[tb_grp_article.CN_FB_ARTICLE_ID].ToString().Split("_")[1]);
  1903. if (Articledata == null)
  1904. {
  1905. sMsg = "與FB貼文連結失敗";
  1906. break;
  1907. }
  1908. tb_grp_article upData = new tb_grp_article()
  1909. {
  1910. fb_article_id = dicCondition[tb_grp_article.CN_FB_ARTICLE_ID].ToString(),
  1911. post_date = Articledata.created_time,
  1912. post_status = (int)Enums.EPostStatus.EPS_COMPLETE
  1913. };
  1914. tb_grp_article upCon = new tb_grp_article() { uid = dicCondition[tb_grp_article.CN_UID].ToString() };
  1915. lCmds.Add(Command.SetupUpdateCmd(upData, upCon));
  1916. ArsenalInterface ai = ArsenalDBMgr.GetInst(lCmds[0], GetDefaultSystemColumnInfo());
  1917. ai.RunEditCmds(lCmds);
  1918. sMsg = GetLastErrorCode(lCmds);
  1919. if (sMsg != null)
  1920. {
  1921. sMsg = GetLastErrorMessage(lCmds);
  1922. crmRes = new CErrorResponseMessage(sMsg, i_crmInput);
  1923. break;
  1924. }
  1925. crmRes = new CSuccessResponseMessage(null, i_crmInput);
  1926. }
  1927. while (false);
  1928. }
  1929. catch (Exception ex)
  1930. {
  1931. LogHelper.DBLog(Util.GetLastExceptionMsg(ex));
  1932. sMsg = $"{nameof(BindFbPostToArticle)} unknwon exception. i_crmInput={JsonConvert.SerializeObject(i_crmInput)}. ";
  1933. #if DEBUG
  1934. System.Diagnostics.Debug.WriteLine(sMsg);
  1935. crmRes = new CSuccessResponseMessage(sMsg, i_crmInput);
  1936. #endif
  1937. }
  1938. if (null != sMsg)
  1939. {
  1940. crmRes = new CErrorResponseMessage(sMsg, i_crmInput);
  1941. }
  1942. return crmRes;
  1943. }
  1944. private string GetUserToken(string groupUid, out List<GroupViewModel> qdGroup)
  1945. {
  1946. string sMsg = null;
  1947. // 取回文章ID跟UserToken
  1948. QueryJsonElementCollection lBlocks = new QueryJsonElementCollection();
  1949. QueryJsonElement qjeGroup = lBlocks.GetInst();
  1950. qjeGroup.table = tb_grp_group.TABLENAME;
  1951. qjeGroup.displaycols = new List<string>()
  1952. {
  1953. tb_grp_group.CN_FB_GROUP_ID
  1954. };
  1955. qjeGroup.wherecols = new WhereNode(tb_grp_group.CN_UID, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_grp_group), groupUid);
  1956. lBlocks.Add(qjeGroup);
  1957. QueryJsonElement qjeGroupUser = lBlocks.GetInst();
  1958. qjeGroupUser.table = tb_grp_group2user.TABLENAME;
  1959. qjeGroupUser.jointable = qjeGroup;
  1960. qjeGroupUser.jointype = QueryJsonElement.LEFT_JOIN;
  1961. qjeGroupUser.joincols = new Dictionary<string, string> { { tb_grp_group2user.CN_GROUP_UID, tb_grp_group.CN_UID } };
  1962. qjeGroupUser.displaycols = new List<string>()
  1963. {
  1964. tb_grp_group2user.CN_USER_TOKEN,
  1965. tb_grp_group2user.CN_STATUS_FLAG
  1966. };
  1967. lBlocks.Add(qjeGroupUser);
  1968. sMsg = MakeSelectJoinByBlocks(lBlocks, out Command cRes);
  1969. if (sMsg != null)
  1970. {
  1971. qdGroup = null;
  1972. return "error";
  1973. }
  1974. ArsenalInterface ai = ArsenalDBMgr.GetInst(cRes);
  1975. qdGroup = ai.RunQueryList<GroupViewModel>(cRes);
  1976. sMsg = GetLastErrorCode(cRes);
  1977. if (sMsg != null)
  1978. {
  1979. return sMsg;
  1980. }
  1981. return null;
  1982. }
  1983. /// <summary>
  1984. /// 自動匯入FB社團文章ID, 處理使用發文API後FB回傳發文失敗錯誤訊息(Internal Server Error), 但文章還是會發送去社團的狀況
  1985. /// </summary>
  1986. /// <param name="i_crmInput"></param>
  1987. /// <returns></returns>
  1988. //public CResponseMessage AutoImportArticle(CRequestMessage i_crmInput)
  1989. //{
  1990. // var information = "";
  1991. // var grabDate = 10;
  1992. // int groupArticleTotalCount = 0, matchFbPosts = 0, updateSuccessCount = 0;
  1993. // var articleGroup = GetIntradayNoFbPostIdArticle(grabDate).GroupBy(x => x.fb_group_id);
  1994. // foreach (var articles in articleGroup)
  1995. // {
  1996. // FbGetPost getPost = new FbHelper().CallFbPostGetDataAPI(articles.FirstOrDefault().user_token, articles.Key);
  1997. // //FbGetPost getPost = new FbHelper().CallFbPostGetDataAPI(articles.FirstOrDefault().user_token, articles.Key, grabDate);// 找出指定群組內的貼文
  1998. // matchFbPosts = 0;
  1999. // updateSuccessCount = 0;
  2000. // groupArticleTotalCount = articles.Count();
  2001. // foreach (var article in articles)
  2002. // {
  2003. // // 取發布貼文日期正負10分鐘的同名貼文
  2004. // var fbPost = getPost.data.Where(
  2005. // x => x.message != null &&
  2006. // x.message.Contains(article.name) &&
  2007. // x.created_time > article.release_date.AddMinutes(-10) &&
  2008. // x.created_time < article.release_date.AddMinutes(10)
  2009. // ).FirstOrDefault();
  2010. // if (fbPost != null)
  2011. // {
  2012. // matchFbPosts++;
  2013. // if (UpdateArticleFbPostId(article.uid, fbPost.id))
  2014. // {
  2015. // updateSuccessCount++;
  2016. // }
  2017. // }
  2018. // }
  2019. // information += $@"{nameof(AutoImportArticle)} porcess FB group id: {articles.FirstOrDefault()?.fb_group_id} Complete, {nameof(groupArticleTotalCount)} = {groupArticleTotalCount}, {nameof(matchFbPosts)} = {matchFbPosts}, {nameof(updateSuccessCount)} = {updateSuccessCount} .";
  2020. // }
  2021. // Logger.Debug($@"{information}");// 紀錄匹配文章數量與db更新成功數量
  2022. // CResponseMessage crmRes = new CSuccessResponseMessage(
  2023. // $"{information}",
  2024. // i_crmInput
  2025. // );
  2026. // return crmRes;
  2027. //}
  2028. /// <summary>
  2029. /// 取得當天所有已發布貼文卻沒有FB貼文ID的文章
  2030. /// </summary>
  2031. /// <returns></returns>
  2032. private List<GroupArticleModel> GetIntradayNoFbPostIdArticle(int grabDate_)
  2033. {
  2034. string sMsg = null;
  2035. QueryJsonElementCollection lBlocks = new QueryJsonElementCollection();
  2036. QueryJsonElement article = lBlocks.GetInst();
  2037. article.table = tb_grp_article.TABLENAME;
  2038. article.displaycols = new List<string>()
  2039. {
  2040. tb_grp_article.CN_UID,
  2041. tb_grp_article.CN_NAME,
  2042. tb_grp_article.CN_GROUP_UID,
  2043. tb_grp_article.CN_RELEASE_DATE,
  2044. };
  2045. article.wherecols = new WhereNode(WhereNode.ENodeOperation.ENO_AND,
  2046. new WhereNode(tb_grp_article.CN_FB_ARTICLE_ID, WhereNode.EColumnOperation.EOT_ISNULL, typeof(tb_grp_article)),
  2047. //new WhereNode(tb_grp_article.CN_POST_DATE, WhereNode.EColumnOperation.EOT_GT, typeof(tb_grp_article), DateTime.Now.AddDays(-1).ToString("yyyy/MM/dd HH:mm:ss"))
  2048. new WhereNode(tb_grp_article.CN_RELEASE_DATE, WhereNode.EColumnOperation.EOT_GT, typeof(tb_grp_article), DateTime.Now.AddDays(-grabDate_).ToString("yyyy/MM/dd HH:mm:ss"))
  2049. );
  2050. QueryJsonElement group = lBlocks.GetInst();
  2051. group.table = tb_grp_group.TABLENAME;
  2052. group.displaycols = new List<string>()
  2053. {
  2054. tb_grp_group.CN_FB_GROUP_ID
  2055. };
  2056. group.jointable = article;
  2057. group.joincols = new Dictionary<string, string>() {
  2058. { tb_grp_group.CN_UID,tb_grp_article.CN_GROUP_UID }};
  2059. QueryJsonElement group2user = lBlocks.GetInst();
  2060. group2user.table = tb_grp_group2user.TABLENAME;
  2061. group2user.displaycols = new List<string>()
  2062. {
  2063. tb_grp_group2user.CN_USER_TOKEN
  2064. };
  2065. group2user.jointable = article;
  2066. group2user.joincols = new Dictionary<string, string>() {
  2067. { tb_grp_group2user.CN_GROUP_UID,tb_grp_article.CN_GROUP_UID }};
  2068. lBlocks.Add(article);
  2069. lBlocks.Add(group);
  2070. lBlocks.Add(group2user);
  2071. sMsg = MakeSelectJoinByBlocks(lBlocks, out Command cRes);
  2072. if (sMsg != null)
  2073. {
  2074. throw new Exception(sMsg);
  2075. }
  2076. ArsenalInterface ai = ArsenalDBMgr.GetInst(cRes);
  2077. var result = ai.RunQueryList<GroupArticleModel>(cRes);
  2078. sMsg = GetLastErrorCode(cRes);
  2079. if (sMsg != null)
  2080. {
  2081. throw new Exception(sMsg);
  2082. }
  2083. return result;
  2084. }
  2085. /// <summary>
  2086. /// 使用UID更新fb_article_id
  2087. /// </summary>
  2088. /// <param name="article_uid_"></param>
  2089. /// <param name="fb_article_id_"></param>
  2090. /// <returns></returns>
  2091. private bool UpdateArticleFbPostId(string article_uid_, string fb_article_id_)
  2092. {
  2093. var sMsg = "";
  2094. var Commands = new List<Command>();
  2095. var oData = new tb_grp_article();
  2096. oData.fb_article_id = fb_article_id_;// Just update Data
  2097. Command c = Command.SetupUpdateCmd(oData,
  2098. new WhereNode(tb_grp_article.CN_UID, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_grp_article), article_uid_));
  2099. Commands.Add(c);
  2100. ArsenalInterface ai = ArsenalDBMgr.GetInst(Commands[0], GetDefaultSystemColumnInfo());
  2101. ai.RunEditCmds(Commands);
  2102. sMsg = GetLastErrorCode(Commands);
  2103. if (sMsg != null)
  2104. {
  2105. Logger.Error($"{nameof(UpdateArticleFbPostId)} => {sMsg}");
  2106. return false;
  2107. }
  2108. return true;
  2109. }
  2110. }
  2111. }