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.

2234 lines
96 KiB

  1. using CounsellorBL.BLStructure;
  2. using CounsellorBL.Common;
  3. using CounsellorBL.Helper;
  4. using CounsellorBL.ORD;
  5. using MonumentDefine;
  6. using Newtonsoft.Json;
  7. using Newtonsoft.Json.Linq;
  8. using OT.COM.ArsenalDB;
  9. using OT.COM.LogisticsUtil;
  10. using OT.COM.SignalerMessage;
  11. using SoldierData.EnterprizeV4;
  12. using System;
  13. using System.Collections.Generic;
  14. using System.Linq;
  15. using System.Net.Http;
  16. using static CounsellorBL.Helper.FbRestHelper;
  17. namespace CounsellorBL.MEB
  18. {
  19. public class MemberListService : SingleDataTableTemplate<tb_meb_member>
  20. {
  21. protected class MemberModel : tb_meb_member
  22. {
  23. public string age { get; set; }
  24. public int return_count { get; set; }
  25. public int amount { get; set; }
  26. }
  27. public class FbToken
  28. {
  29. public string access_token { get; set; }
  30. public string token_type { get; set; }
  31. public bool is_valid { get; set; }
  32. }
  33. public class FbGetGroups
  34. {
  35. public List<Groups> data { get; set; }
  36. public JObject paging { get; set; }
  37. }
  38. public class Groups
  39. {
  40. public string name { get; set; }
  41. public string id { get; set; }
  42. public string privacy { get; set; }
  43. }
  44. private class CusMemberModel
  45. {
  46. public string uid { get; set; }
  47. public string group_user_id { get; set; }
  48. public string group_id { get; set; }
  49. public string fb_pic { get; set; }
  50. public string user_token { get; set; }
  51. }
  52. private class BatchModel
  53. {
  54. public int code { get; set; }
  55. public string body { get; set; }
  56. }
  57. public class PictureModel
  58. {
  59. public Picture picture { get; set; }
  60. public string id { get; set; }
  61. public class Picture
  62. {
  63. public PictureData data { get; set; }
  64. public class PictureData
  65. {
  66. public string url { get; set; }
  67. }
  68. }
  69. }
  70. public MemberListService()
  71. {
  72. dgReadCommandGenerator = readCommandGenerator;
  73. dgReadCommandPostDataHandler = readCommandPostDataHandler;
  74. }
  75. public bool CheckUserIsInGroup(string group_id,string access_token)
  76. {
  77. var IsInGroup = false;
  78. do
  79. {
  80. try
  81. {
  82. // 送出資料
  83. string uri = "https://graph.facebook.com/v8.0/me/groups?limit=10000?";
  84. var dicData = new Dictionary<string, string>()
  85. {
  86. { "limit", "10000" },
  87. { "access_token",access_token}
  88. };
  89. APIHelper.BaseGet(uri, null, dicData, out HttpResponseMessage responseMessage);
  90. if (responseMessage.IsSuccessStatusCode)
  91. {
  92. var fb_error = GetFbApiError(responseMessage);
  93. if (!string.IsNullOrWhiteSpace(fb_error))
  94. {
  95. Logger.Error($"{nameof(CheckUserIsInGroup)} FB API response error message: {fb_error} ");
  96. break;
  97. }
  98. var responseData = JsonConvert.DeserializeObject<FbGetGroups>(responseMessage.Content.ReadAsStringAsync().Result);
  99. IsInGroup = responseData.data.Any(x => x.id == group_id);
  100. }
  101. }
  102. catch (Exception ex)
  103. {
  104. throw ex;
  105. }
  106. } while (false);
  107. return IsInGroup;
  108. }
  109. [Auth(false)]
  110. public new CResponseMessage ReadMemberInfo(CRequestMessage i_crmInput)
  111. {
  112. string sMsg;
  113. Command cRes = null;
  114. CResponseMessage crmRes = null;
  115. do
  116. {
  117. try
  118. {
  119. Dictionary<string, string> dicObjCondition = GetQueryMasterFirstWhereData(i_crmInput).ToDictionary(x => x.Key, x => x.Value.ToString());
  120. List<string> lsMainColumns = EntityBase.GetAllColumnName(typeof(tb_meb_member)); // 取得所有欄位名稱
  121. QueryJsonElementCollection lBlocks = new QueryJsonElementCollection();
  122. QueryJsonElement qjeMember = lBlocks.GetInst();
  123. qjeMember.table = tb_meb_member.TABLENAME;
  124. qjeMember.displaycols = lsMainColumns;
  125. if (dicObjCondition != null && dicObjCondition.Any())
  126. {
  127. qjeMember.dicwherecols = dicObjCondition;
  128. }
  129. lBlocks.Add(qjeMember);
  130. QueryJsonElement qjeBranch = lBlocks.GetInst();
  131. qjeBranch.table = tb_grp_branch.TABLENAME;
  132. qjeBranch.displaycols = new List<string> { tb_grp_branch .CN_BRANCH_NAME};
  133. qjeBranch.jointable = qjeMember;
  134. qjeBranch.joincols = new Dictionary<string, string> { { tb_grp_branch.CN_UID, tb_meb_member.CN_DEFAULT_BRANCH } };
  135. lBlocks.Add(qjeBranch);
  136. sMsg = MakeSelectJoinByBlocks(lBlocks, out cRes);
  137. if (sMsg != null)
  138. {
  139. break;
  140. }
  141. ArsenalInterface ai = ArsenalDBMgr.GetInst(cRes);
  142. var qdsMember = ai.RunQueryDataSet(cRes);
  143. crmRes = new CSuccessResponseMessage(null, i_crmInput);
  144. // 多傳一些參數到前端
  145. crmRes.param.Add("member", new QueryResponse(qdsMember));
  146. }
  147. catch (Exception ex)
  148. {
  149. sMsg = $"{nameof(ReadMemberInfo)} unknwon exception. i_crmInput={JsonConvert.SerializeObject(i_crmInput)}. ex={ex.Message}";
  150. #if DEBUG
  151. System.Diagnostics.Debug.WriteLine(sMsg);
  152. #endif
  153. }
  154. } while (false);
  155. if (!string.IsNullOrEmpty(sMsg))
  156. {
  157. crmRes = new CErrorResponseMessage(sMsg, i_crmInput);
  158. Logger.Error(JsonConvert.SerializeObject(i_crmInput));
  159. Logger.Error(JsonConvert.SerializeObject(crmRes));
  160. }
  161. return crmRes;
  162. }
  163. [Auth(false)]
  164. public new CResponseMessage Read(CRequestMessage i_crmInput) => base.Read(i_crmInput);
  165. protected string readCommandGenerator(CRequestMessage i_crmInput, JArray i_jaData, tb_sys_session i_sSessionUser, out Command o_c,
  166. [System.Runtime.CompilerServices.CallerLineNumber] int i_nCodeLine = 0,
  167. [System.Runtime.CompilerServices.CallerMemberName] string i_sMemberName = "",
  168. [System.Runtime.CompilerServices.CallerFilePath] string i_sSourcePath = "")
  169. {
  170. string sMsg;
  171. Command cRes = null;
  172. try
  173. {
  174. do
  175. {
  176. Dictionary<string, object> dicObjCondition = GetQueryMasterFirstWhereData(i_crmInput);
  177. List<string> lsMainColumns = EntityBase.GetAllColumnName(typeof(tb_meb_member)); // 取得所有欄位名稱
  178. var lsBranch = ProjectHelper.GetUserGroup(i_crmInput); // 取得可讀取社團資料的社團uid清單
  179. var lsMember = new List<string>();
  180. if (dicObjCondition.ContainsKey(tb_meb_member.CN_UID))
  181. {
  182. var aMember = dicObjCondition[tb_meb_member.CN_UID] as JArray;
  183. foreach (var member in aMember)
  184. {
  185. lsMember.Add(member.ToString());
  186. }
  187. dicObjCondition.Remove(tb_meb_member.CN_UID);
  188. }
  189. Dictionary<string, string> dicCondition = new Dictionary<string, string>();
  190. foreach (var condition in dicObjCondition)
  191. {
  192. dicCondition.Add(condition.Key, condition.Value.ToString());
  193. }
  194. QueryJsonElementCollection lBlocks = new QueryJsonElementCollection();
  195. QueryJsonElement qjeMember = lBlocks.GetInst();
  196. qjeMember.table = tb_meb_member.TABLENAME;
  197. qjeMember.displaycols = lsMainColumns;
  198. qjeMember.aliascols = new Dictionary<string, List<string>>
  199. {
  200. { "'0'", new List<string>() { "return_count" } }
  201. };
  202. if (lsMember.Any())
  203. {
  204. qjeMember.wherecols = new WhereNode(tb_meb_member.CN_UID, WhereNode.EColumnOperation.EOT_IN, typeof(tb_meb_member), lsMember.ToArray());
  205. }
  206. if (dicCondition != null && dicCondition.Any())
  207. {
  208. qjeMember.dicwherecols = dicCondition;
  209. }
  210. lBlocks.Add(qjeMember);
  211. QueryJsonElement qjeGroup = lBlocks.GetInst();
  212. qjeGroup.table = tb_grp_group.TABLENAME;
  213. qjeGroup.jointable = qjeMember;
  214. qjeGroup.jointype = QueryJsonElement.LEFT_JOIN;
  215. qjeGroup.joincols = new Dictionary<string, string>() {
  216. { tb_grp_group.CN_FB_GROUP_ID,tb_meb_member.CN_GROUP_ID }};
  217. if (!dicCondition.ContainsKey(tb_meb_member.CN_GROUP_USER_ID))
  218. {
  219. qjeGroup.wherecols = new WhereNode(tb_grp_group.CN_UID, WhereNode.EColumnOperation.EOT_IN, typeof(tb_grp_group), lsBranch.ToArray());
  220. }
  221. lBlocks.Add(qjeGroup);
  222. QueryJsonElement qjePurchase = lBlocks.GetInst();
  223. qjePurchase.table = tb_ord_purchase.TABLENAME;
  224. qjePurchase.jointype = QueryJsonElement.LEFT_JOIN;
  225. qjePurchase.jointable = qjeMember;
  226. qjePurchase.joincols = new Dictionary<string, string>() {
  227. { tb_ord_purchase.CN_MEMBER_UID,tb_meb_member.CN_UID }};
  228. qjePurchase.aliascols = new Dictionary<string, List<string>>
  229. {
  230. { QueryJsonElement.SUM(tb_ord_purchase.CN_AMOUNT), new List<string>() { "amount" } },
  231. };
  232. lBlocks.Add(qjePurchase);
  233. qjeMember.groupcols = new List<Tuple<QueryJsonElement, string>>
  234. {
  235. Tuple.Create(qjeMember, tb_meb_member.CN_UID),
  236. Tuple.Create(qjeMember, tb_meb_member.CN_GROUP_ID),
  237. Tuple.Create(qjeMember, tb_meb_member.CN_GROUP_USER_ID),
  238. Tuple.Create(qjeMember, tb_meb_member.CN_MESSAGE_USER_ID),
  239. Tuple.Create(qjeMember, tb_meb_member.CN_EMAIL),
  240. Tuple.Create(qjeMember, tb_meb_member.CN_RANK),
  241. Tuple.Create(qjeMember, tb_meb_member.CN_FB_PIC),
  242. Tuple.Create(qjeMember, tb_meb_member.CN_NAME),
  243. Tuple.Create(qjeMember, tb_meb_member.CN_NICKNAME),
  244. Tuple.Create(qjeMember, tb_meb_member.CN_GENDER),
  245. Tuple.Create(qjeMember, tb_meb_member.CN_JOB),
  246. Tuple.Create(qjeMember, tb_meb_member.CN_BIRTHDAY),
  247. Tuple.Create(qjeMember, tb_meb_member.CN_CELLPHONE),
  248. Tuple.Create(qjeMember, tb_meb_member.CN_PHONE),
  249. Tuple.Create(qjeMember, tb_meb_member.CN_LAST_CALL_MESSAGE),
  250. Tuple.Create(qjeMember, tb_meb_member.CN_LINE_ID),
  251. Tuple.Create(qjeMember, tb_meb_member.CN_AREA),
  252. Tuple.Create(qjeMember, tb_meb_member.CN_ADDRESS),
  253. Tuple.Create(qjeMember, tb_meb_member.CN_LINK),
  254. Tuple.Create(qjeMember, tb_meb_member.CN_SHOPPING_ACCOUNT),
  255. Tuple.Create(qjeMember, tb_meb_member.CN_STATUS_FLAG),
  256. Tuple.Create(qjeMember, tb_meb_member.CN_DEFAULT_BRANCH),
  257. Tuple.Create(qjeMember, tb_meb_member.CN_DELETE_FLAG),
  258. Tuple.Create(qjeMember, tb_meb_member.CN_WPRICE_PAYMENT),
  259. Tuple.Create(qjeMember, tb_meb_member.CN_CREATE_DATE),
  260. Tuple.Create(qjeMember, tb_meb_member.CN_UPDATE_DATE),
  261. Tuple.Create(qjeMember, tb_meb_member.CN_CREATE_USER_UID),
  262. Tuple.Create(qjeMember, tb_meb_member.CN_UPDATE_USER_UID),
  263. Tuple.Create(qjeMember, tb_meb_member.CN_RETURN_COUNT),
  264. Tuple.Create(qjeMember, tb_meb_member.CN_FIREBASE_TOKEN),
  265. };
  266. sMsg = MakeSelectJoinByBlocks(lBlocks, out cRes);
  267. if (sMsg != null)
  268. {
  269. break;
  270. }
  271. }
  272. while (false);
  273. }
  274. catch (Exception ex)
  275. {
  276. LogHelper.DBLog(Util.GetLastExceptionMsg(ex), i_nCodeLine, i_sMemberName, i_sSourcePath);
  277. sMsg = $"{nameof(readCommandGenerator)} unknwon exception. i_crmInput={JsonConvert.SerializeObject(i_crmInput)}. Call from {i_sMemberName} {i_sSourcePath}({i_nCodeLine}).";
  278. #if DEBUG
  279. System.Diagnostics.Debug.WriteLine(sMsg);
  280. #endif
  281. }
  282. o_c = cRes;
  283. return sMsg;
  284. }
  285. protected string readCommandPostDataHandler(CRequestMessage i_crmInput, ArsenalInterface i_aiArsenal, Command i_cCmd, JArray i_jaData, tb_sys_session i_sSessionUser, out object o_oReault,
  286. [System.Runtime.CompilerServices.CallerLineNumber] int i_nCodeLine = 0,
  287. [System.Runtime.CompilerServices.CallerMemberName] string i_sMemberName = "",
  288. [System.Runtime.CompilerServices.CallerFilePath] string i_sSourcePath = "")
  289. {
  290. string sMsg = null;
  291. List<MemberModel> oResultData = null;
  292. try
  293. {
  294. do
  295. {
  296. Dictionary<string, object> dicCondition = GetQueryMasterFirstWhereData(i_crmInput); // 取得condition
  297. List<MemberModel> qds = i_aiArsenal.RunQueryList<MemberModel>(i_cCmd);
  298. if (!i_cCmd.IsSuccess)
  299. {
  300. sMsg = i_cCmd.LastErrorCode;
  301. break;
  302. }
  303. if (dicCondition.ContainsKey("birthdayMonth"))
  304. {
  305. qds = qds.Where(x => x.birthday.HasValue && x.birthday.Value.Month == Convert.ToInt32(dicCondition["birthdayMonth"])).ToList();
  306. }
  307. // 不顯示現貨銷售
  308. if (dicCondition.ContainsKey("hideSpotSale"))
  309. {
  310. qds = qds.Where(x => x.name != "現貨銷售").ToList();
  311. }
  312. foreach (var data in qds)
  313. {
  314. if (data.birthday.HasValue)
  315. {
  316. var age = CalculateAgeCorrect(data.birthday.Value, DateTime.Now);
  317. data.age = age == 0 ? "" : age.ToString();
  318. }
  319. }
  320. oResultData = qds.OrderByDescending(x => x.create_date).ToList();
  321. }
  322. while (false);
  323. }
  324. catch (Exception ex)
  325. {
  326. LogHelper.DBLog(Util.GetLastExceptionMsg(ex), i_nCodeLine, i_sMemberName, i_sSourcePath);
  327. sMsg = $"{nameof(readCommandPostDataHandler)} unknwon exception. i_crmInput={JsonConvert.SerializeObject(i_crmInput)}. Call from {i_sMemberName} {i_sSourcePath}({i_nCodeLine}).";
  328. #if DEBUG
  329. System.Diagnostics.Debug.WriteLine(sMsg);
  330. #endif
  331. }
  332. o_oReault = oResultData;
  333. return sMsg;
  334. }
  335. public int CalculateAgeCorrect(DateTime birthDate, DateTime now)
  336. {
  337. int age = now.Year - birthDate.Year;
  338. if (now.Month < birthDate.Month || (now.Month == birthDate.Month && now.Day < birthDate.Day)) age--;
  339. return age;
  340. }
  341. /// <summary>
  342. /// 取得應用程式權杖
  343. /// </summary>
  344. /// <param name="authorizationToken"></param>
  345. /// <param name="client_id"></param>
  346. /// <param name="client_secret"></param>
  347. /// <returns></returns>
  348. public bool GetAppToken(string APP_ID, string CLIENT_SECRET, out FbToken responseData)
  349. {
  350. responseData = new FbToken();
  351. string uri = string.Format("https://graph.facebook.com/oauth/access_token?client_id={0}&client_secret={1}&grant_type=client_credentials", APP_ID, CLIENT_SECRET);
  352. APIHelper.BaseGet(uri, null, new Dictionary<string, string>(), out HttpResponseMessage responseMessage);
  353. if (responseMessage.IsSuccessStatusCode)
  354. {
  355. responseData = JsonConvert.DeserializeObject<FbToken>(responseMessage.Content.ReadAsStringAsync().Result);
  356. }
  357. return responseMessage.IsSuccessStatusCode;
  358. }
  359. public bool GetFBPagesID(string i_sASID, string PAGE_ID, string i_sToken, out string o_sPSID)
  360. {
  361. o_sPSID = null;
  362. string uri = string.Format("https://graph.facebook.com/{0}/ids_for_pages?page={1}&access_token={2}", i_sASID, PAGE_ID, i_sToken);
  363. APIHelper.BaseGet(uri, null, new Dictionary<string, string>(), out HttpResponseMessage responseMessage);
  364. if (responseMessage.IsSuccessStatusCode)
  365. {
  366. var sResponse = responseMessage.Content.ReadAsStringAsync().Result;
  367. Logger.Info(uri + " && " + sResponse);
  368. var joResult = JsonConvert.DeserializeObject(sResponse) as JObject;
  369. var oResult = joResult.ToObject<Dictionary<string, object>>();
  370. var jaData = oResult["data"] as JArray;
  371. if (jaData.Any())
  372. {
  373. var joData = jaData.First() as JObject;
  374. if (joData != null)
  375. {
  376. var objData = joData.ToObject<Dictionary<string, object>>();
  377. o_sPSID = objData["id"].ToString();
  378. }
  379. }
  380. }
  381. return responseMessage.IsSuccessStatusCode;
  382. }
  383. [Auth(false)]
  384. public CResponseMessage GetQrCode(CRequestMessage i_crmInput)
  385. {
  386. string sMsg = null;
  387. CResponseMessage crmRes = null;
  388. do
  389. {
  390. try
  391. {
  392. Dictionary<string, object> dicCondition = GetQueryMasterFirstWhereData(i_crmInput); // 取得condition
  393. if (!string.IsNullOrEmpty(sMsg))
  394. {
  395. break;
  396. }
  397. var group_id = dicCondition[tb_meb_member.CN_GROUP_ID].ToString();
  398. // 先查詢資料是否存在
  399. tb_meb_member cMember = new tb_meb_member();
  400. cMember.SetDirty(tb_meb_member.CN_UID, tb_meb_member.CN_GROUP_USER_ID);
  401. tb_meb_member cMemberCon = new tb_meb_member() { group_user_id = dicCondition[tb_meb_member.CN_GROUP_USER_ID].ToString(), group_id = group_id };
  402. Command cMemberSelect = Command.SetupSelectCmd(cMember, cMemberCon);
  403. ArsenalInterface ai = ArsenalDBMgr.GetInst(cMemberSelect);
  404. tb_meb_member qdsMember = ai.RunQuerySingleORM<tb_meb_member>(cMemberSelect);
  405. crmRes = new CSuccessResponseMessage(null, i_crmInput);
  406. // 多傳一些參數到前端
  407. crmRes.param.Add("member", qdsMember);
  408. }
  409. catch (Exception ex)
  410. {
  411. sMsg = $"{nameof(PatchMemberInfo)} unknwon exception. i_crmInput={JsonConvert.SerializeObject(i_crmInput)}. ex={ex.Message}";
  412. #if DEBUG
  413. System.Diagnostics.Debug.WriteLine(sMsg);
  414. #endif
  415. }
  416. } while (false);
  417. if (!string.IsNullOrEmpty(sMsg))
  418. {
  419. crmRes = new CErrorResponseMessage(sMsg, i_crmInput);
  420. Logger.Error(JsonConvert.SerializeObject(i_crmInput));
  421. Logger.Error(JsonConvert.SerializeObject(crmRes));
  422. }
  423. return crmRes;
  424. }
  425. [Auth(false)]
  426. public CResponseMessage CheckTokenValid(CRequestMessage i_crmInput)
  427. {
  428. string sMsg = null;
  429. CResponseMessage crmRes = null;
  430. do
  431. {
  432. try
  433. {
  434. Dictionary<string, object> dicCondition = GetQueryMasterFirstWhereData(i_crmInput); // 取得condition
  435. var fbHelper = new FbRestHelper();
  436. sMsg = fbHelper.CallFbGetInformation(dicCondition["token"].ToString(), out UserInfo userInfo);
  437. if (!string.IsNullOrEmpty(sMsg))
  438. {
  439. break;
  440. }
  441. var group_id = dicCondition[tb_meb_member.CN_GROUP_ID].ToString();
  442. var groupData = GetGroupSettings(group_id);
  443. string sPSID = null;
  444. if (groupData == null)
  445. {
  446. sMsg = "社團資訊錯誤";
  447. break;
  448. }
  449. #region 取得 pages_user_id <PSID> 到貨通知需要
  450. var result = GetAppToken(groupData.app_id, groupData.client_secret, out FbToken resData);
  451. if (result)
  452. {
  453. GetFBPagesID(userInfo.id, groupData.page_id, resData.access_token, out sPSID);
  454. }
  455. string privacy = null;
  456. bool isSuccess = getPrivacy(group_id, out privacy);
  457. var IsOpen = false;
  458. if (privacy == "OPEN")
  459. {
  460. IsOpen = true;
  461. }
  462. #endregion
  463. var IsInGroups = CheckUserIsInGroup(group_id, dicCondition["token"].ToString());
  464. // 更新會員資料
  465. List<Command> lCmdUpdate = new List<Command>();
  466. // 先查詢資料是否存在
  467. tb_meb_member cMember = new tb_meb_member();
  468. cMember.SetFullDirty();
  469. tb_meb_member cMemberCon = new tb_meb_member() { group_user_id = userInfo.id, group_id = group_id };
  470. Command cMemberSelect = Command.SetupSelectCmd(cMember, cMemberCon);
  471. ArsenalInterface ai = ArsenalDBMgr.GetInst(cMemberSelect);
  472. tb_meb_member qdsMember = ai.RunQuerySingleORM<tb_meb_member>(cMemberSelect);
  473. string asid = userInfo.id;
  474. if (qdsMember == null)
  475. {
  476. // 新增
  477. tb_meb_member mNew = new tb_meb_member() { };
  478. mNew.message_user_id = sPSID;
  479. mNew.group_user_id = asid;
  480. mNew.last_call_message = DateTime.Now;
  481. mNew.gender = userInfo.gender;
  482. mNew.email = userInfo.email;
  483. mNew.fb_pic = userInfo.picture.data.url;
  484. if (DateTime.TryParse(userInfo.birthday, out DateTime birthday))
  485. {
  486. mNew.birthday = birthday;
  487. }
  488. mNew.group_user_id = userInfo.id;
  489. mNew.group_id = dicCondition["group_id"].ToString();
  490. lCmdUpdate.Add(Command.SetupInsertCmd(mNew));
  491. }
  492. else
  493. {
  494. // 更新
  495. tb_meb_member mUpd = new tb_meb_member();
  496. mUpd.message_user_id = sPSID;
  497. if (qdsMember.last_call_message == null) // 紀錄最後傳送時間
  498. {
  499. mUpd.last_call_message = DateTime.Now;
  500. }
  501. mUpd.message_user_id = sPSID;
  502. mUpd.group_user_id = asid;
  503. mUpd.last_call_message = DateTime.Now;
  504. mUpd.gender = userInfo.gender;
  505. mUpd.email = userInfo.email;
  506. mUpd.fb_pic = userInfo.picture.data.url;
  507. if (DateTime.TryParse(userInfo.birthday, out DateTime birthday))
  508. {
  509. mUpd.birthday = birthday;
  510. }
  511. mUpd.group_user_id = userInfo.id;
  512. List<WhereNode> lswnMain = new List<WhereNode>();
  513. lswnMain.Add(new WhereNode(tb_meb_member.CN_GROUP_USER_ID, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_meb_member), asid));
  514. lswnMain.Add(new WhereNode(tb_meb_member.CN_GROUP_ID, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_meb_member), group_id));
  515. lCmdUpdate.Add(Command.SetupUpdateCmd(mUpd, new WhereNode(WhereNode.ENodeOperation.ENO_AND, lswnMain.ToArray())));
  516. }
  517. ai = ArsenalDBMgr.GetInst(lCmdUpdate[0], GetDefaultSystemColumnInfo());
  518. ai.RunEditCmds(lCmdUpdate);
  519. sMsg = GetLastErrorCode(lCmdUpdate);
  520. if (sMsg != null)
  521. {
  522. if (sMsg == "msg.sqlserver_2627") // 此錯誤為重複 Insert 相同 group_user_id and group_id 改為更新
  523. {
  524. List<Command> lCmdUpdateWhenErr = new List<Command>();
  525. // 更新
  526. tb_meb_member mUpdErr = new tb_meb_member();
  527. mUpdErr.message_user_id = sPSID;
  528. mUpdErr.message_user_id = sPSID;
  529. mUpdErr.group_user_id = asid;
  530. mUpdErr.last_call_message = DateTime.Now;
  531. mUpdErr.gender = userInfo.gender;
  532. mUpdErr.email = userInfo.email;
  533. mUpdErr.fb_pic = userInfo.picture.data.url;
  534. if (DateTime.TryParse(userInfo.birthday, out DateTime birthday))
  535. {
  536. mUpdErr.birthday = birthday;
  537. }
  538. mUpdErr.group_user_id = userInfo.id;
  539. List<WhereNode> lswnMainErr = new List<WhereNode>();
  540. lswnMainErr.Add(new WhereNode(tb_meb_member.CN_GROUP_USER_ID, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_meb_member), asid));
  541. lswnMainErr.Add(new WhereNode(tb_meb_member.CN_GROUP_ID, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_meb_member), group_id));
  542. lCmdUpdateWhenErr.Add(Command.SetupUpdateCmd(mUpdErr, new WhereNode(WhereNode.ENodeOperation.ENO_AND, lswnMainErr.ToArray())));
  543. ArsenalInterface ai2 = ArsenalDBMgr.GetInst(lCmdUpdateWhenErr[0], GetDefaultSystemColumnInfo());
  544. ai2.RunEditCmds(lCmdUpdateWhenErr);
  545. sMsg = GetLastErrorCode(lCmdUpdateWhenErr);
  546. // 傳必要參數至前端
  547. crmRes.param.Add("psid", sPSID);
  548. crmRes.param.Add("branch_status", 1);
  549. break;
  550. }
  551. else
  552. {
  553. break;
  554. }
  555. }
  556. crmRes = new CSuccessResponseMessage(null, i_crmInput);
  557. // 多傳一些參數到前端
  558. crmRes.param.Add("psid", sPSID);
  559. if (IsOpen == true)
  560. {
  561. crmRes.param.Add("joinGroups", "Y");
  562. }
  563. else
  564. {
  565. crmRes.param.Add("joinGroups", IsInGroups == true ? "Y" : "N");
  566. }
  567. crmRes.param.Add("fbid", userInfo.id);
  568. // 只顯示公開的分店
  569. List<tb_grp_branch> branches = GetBranches(group_id);
  570. var enabledBranches = branches.Where(x => x.public_status == (int)Enums.Flag.Enable).Select(x => new { value = x.uid, display = x.branch_name });
  571. // 沒有預設分店
  572. string default_branch = qdsMember?.default_branch;
  573. int branch_status = 0; // 0:未填寫 1:已填寫 -1:已填寫但分店消失
  574. if (!string.IsNullOrEmpty(default_branch))
  575. {
  576. branch_status = enabledBranches.Any(x => x.value == default_branch) ? 1 : -1;
  577. crmRes.param.Add("default_branch", enabledBranches.Where(x => x.value == default_branch).FirstOrDefault().display);
  578. }
  579. if (branch_status != 1)
  580. {
  581. crmRes.param.Add("branch_data", enabledBranches);
  582. }
  583. crmRes.param.Add("branch_status", branch_status);
  584. Logger.Info($"group_id: {group_id} group_user_id: {asid} branch_status: {branch_status} enabledBranches: {enabledBranches.Count()}");
  585. // 紀錄是否第一次登入
  586. if (qdsMember == null)
  587. {
  588. crmRes.param.Add("first_login", true);
  589. }
  590. //在查一次傳uid
  591. cMember = new tb_meb_member();
  592. cMember.SetFullDirty();
  593. cMemberCon = new tb_meb_member() { group_user_id = userInfo.id, group_id = group_id };
  594. cMemberSelect = Command.SetupSelectCmd(cMember, cMemberCon);
  595. ai = ArsenalDBMgr.GetInst(cMemberSelect);
  596. qdsMember = ai.RunQuerySingleORM<tb_meb_member>(cMemberSelect);
  597. if (qdsMember == null)
  598. {
  599. crmRes.param.Add("uid", tb_meb_member.CN_UID);
  600. }
  601. crmRes.param.Add("token", Guid.NewGuid().ToString());
  602. // 如果超過指定天數沒有按,提醒使用者
  603. bool sendMessageAgain = qdsMember?.message_user_id != null && qdsMember?.last_call_message <= DateTime.Now.AddMonths(-1);
  604. crmRes.param.Add("send_msg_again", sendMessageAgain);
  605. }
  606. catch (Exception ex)
  607. {
  608. sMsg = $"{nameof(PatchMemberInfo)} unknwon exception. i_crmInput={JsonConvert.SerializeObject(i_crmInput)}. ex={ex.Message}";
  609. #if DEBUG
  610. System.Diagnostics.Debug.WriteLine(sMsg);
  611. #endif
  612. }
  613. } while (false);
  614. if (!string.IsNullOrEmpty(sMsg))
  615. {
  616. crmRes = new CErrorResponseMessage(sMsg, i_crmInput);
  617. Logger.Error(JsonConvert.SerializeObject(i_crmInput));
  618. Logger.Error(JsonConvert.SerializeObject(crmRes));
  619. }
  620. return crmRes;
  621. }
  622. [Auth(false)]
  623. public CResponseMessage PatchMemberInfo(CRequestMessage i_crmInput)
  624. {
  625. string sMsg = null;
  626. CResponseMessage crmRes = null;
  627. try
  628. {
  629. do
  630. {
  631. sMsg = getCommonParameter(i_crmInput, BLWording.ADD_MASTER, out JArray jaDataArray, out tb_sys_session sUserSession);
  632. if (sMsg != null)
  633. {
  634. break;
  635. }
  636. if (jaDataArray.Count != 1 || jaDataArray[0] == null)
  637. {
  638. sMsg = MessageWording.PARAM_NOT_EXPECTED;
  639. break;
  640. }
  641. JObject joData = jaDataArray[0] as JObject;
  642. Dictionary<string, object> dicData = new Dictionary<string, object>();
  643. if (joData != null)
  644. {
  645. dicData = joData.ToObject<Dictionary<string, object>>();
  646. }
  647. string sPSID = null;
  648. var group_id = dicData[tb_meb_member.CN_GROUP_ID].ToString();
  649. var groupData = GetGroupSettings(group_id);
  650. if (groupData == null)
  651. {
  652. sMsg = "社團資訊錯誤";
  653. break;
  654. }
  655. #region 取得 pages_user_id <PSID> 到貨通知需要
  656. var result = GetAppToken(groupData.app_id, groupData.client_secret, out FbToken resData);
  657. if (result)
  658. {
  659. GetFBPagesID(dicData[BLWording.ASID].ToString(), groupData.page_id, resData.access_token, out sPSID);
  660. }
  661. #endregion
  662. // 更新會員資料
  663. List<Command> lCmdUpdate = new List<Command>();
  664. // 先查詢資料是否存在
  665. tb_meb_member cMember = new tb_meb_member();
  666. cMember.SetFullDirty();
  667. tb_meb_member cMemberCon = new tb_meb_member() { group_user_id = dicData[BLWording.ASID].ToString(), group_id = group_id };
  668. Command cMemberSelect = Command.SetupSelectCmd(cMember, cMemberCon);
  669. ArsenalInterface ai = ArsenalDBMgr.GetInst(cMemberSelect);
  670. tb_meb_member qdsMember = ai.RunQuerySingleORM<tb_meb_member>(cMemberSelect);
  671. string asid = dicData[BLWording.ASID].ToString();
  672. if (qdsMember == null)
  673. {
  674. // 新增
  675. tb_meb_member mNew = new tb_meb_member() { };
  676. mNew.message_user_id = sPSID;
  677. mNew.group_user_id = asid;
  678. mNew.last_call_message = DateTime.Now;
  679. mNew.FillData(dicData);
  680. lCmdUpdate.Add(Command.SetupInsertCmd(mNew));
  681. }
  682. else
  683. {
  684. // 更新
  685. dicData.Remove("group_id");
  686. tb_meb_member mUpd = new tb_meb_member();
  687. mUpd.message_user_id = sPSID;
  688. if (qdsMember.last_call_message == null) // 紀錄最後傳送時間
  689. {
  690. mUpd.last_call_message = DateTime.Now;
  691. }
  692. mUpd.FillData(dicData);
  693. List<WhereNode> lswnMain = new List<WhereNode>();
  694. lswnMain.Add(new WhereNode(tb_meb_member.CN_GROUP_USER_ID, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_meb_member), asid));
  695. lswnMain.Add(new WhereNode(tb_meb_member.CN_GROUP_ID, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_meb_member), group_id));
  696. lCmdUpdate.Add(Command.SetupUpdateCmd(mUpd, new WhereNode(WhereNode.ENodeOperation.ENO_AND, lswnMain.ToArray())));
  697. }
  698. ai = ArsenalDBMgr.GetInst(lCmdUpdate[0], GetDefaultSystemColumnInfo());
  699. ai.RunEditCmds(lCmdUpdate);
  700. sMsg = GetLastErrorCode(lCmdUpdate);
  701. if (sMsg != null)
  702. {
  703. if (sMsg == "msg.sqlserver_2627") // 此錯誤為重複 Insert 相同 group_user_id and group_id 改為更新
  704. {
  705. List<Command> lCmdUpdateWhenErr = new List<Command>();
  706. // 更新
  707. dicData.Remove("group_id");
  708. tb_meb_member mUpdErr = new tb_meb_member();
  709. mUpdErr.message_user_id = sPSID;
  710. mUpdErr.FillData(dicData);
  711. List<WhereNode> lswnMainErr = new List<WhereNode>();
  712. lswnMainErr.Add(new WhereNode(tb_meb_member.CN_GROUP_USER_ID, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_meb_member), asid));
  713. lswnMainErr.Add(new WhereNode(tb_meb_member.CN_GROUP_ID, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_meb_member), group_id));
  714. lCmdUpdateWhenErr.Add(Command.SetupUpdateCmd(mUpdErr, new WhereNode(WhereNode.ENodeOperation.ENO_AND, lswnMainErr.ToArray())));
  715. ArsenalInterface ai2 = ArsenalDBMgr.GetInst(lCmdUpdateWhenErr[0], GetDefaultSystemColumnInfo());
  716. ai2.RunEditCmds(lCmdUpdateWhenErr);
  717. sMsg = GetLastErrorCode(lCmdUpdateWhenErr);
  718. // 傳必要參數至前端
  719. crmRes.param.Add("psid", sPSID);
  720. crmRes.param.Add("branch_status", 1);
  721. break;
  722. }
  723. else
  724. {
  725. break;
  726. }
  727. }
  728. crmRes = new CSuccessResponseMessage(null, i_crmInput);
  729. // 多傳一些參數到前端
  730. crmRes.param.Add("psid", sPSID);
  731. // 只顯示公開的分店
  732. List<tb_grp_branch> branches = GetBranches(group_id);
  733. var enabledBranches = branches.Where(x => x.public_status == (int)Enums.Flag.Enable).Select(x => new { value = x.uid, display = $"{x.branch_name} - {x.address = x.address }" });
  734. // 沒有預設分店
  735. string default_branch = qdsMember?.default_branch;
  736. int branch_status = 0; // 0:未填寫 1:已填寫 -1:已填寫但分店消失
  737. if (!string.IsNullOrEmpty(default_branch))
  738. {
  739. branch_status = enabledBranches.Any(x => x.value == default_branch) ? 1 : -1;
  740. crmRes.param.Add("default_branch", enabledBranches.Where(x => x.value == default_branch).FirstOrDefault().display);
  741. }
  742. if (branch_status != 1)
  743. {
  744. crmRes.param.Add("branch_data", enabledBranches);
  745. }
  746. crmRes.param.Add("branch_status", branch_status);
  747. Logger.Info($"group_id: {group_id} group_user_id: {asid} branch_status: {branch_status} enabledBranches: {enabledBranches.Count()}");
  748. // 紀錄是否第一次登入
  749. if (qdsMember == null)
  750. {
  751. crmRes.param.Add("first_login", true);
  752. }
  753. // 如果超過指定天數沒有按,提醒使用者
  754. bool sendMessageAgain = qdsMember?.message_user_id != null && qdsMember?.last_call_message <= DateTime.Now.AddMonths(-1);
  755. crmRes.param.Add("send_msg_again", sendMessageAgain);
  756. }
  757. while (false);
  758. }
  759. catch (Exception ex)
  760. {
  761. sMsg = $"{nameof(PatchMemberInfo)} unknwon exception. i_crmInput={JsonConvert.SerializeObject(i_crmInput)}. ex={ex.Message}";
  762. #if DEBUG
  763. System.Diagnostics.Debug.WriteLine(sMsg);
  764. #endif
  765. }
  766. if (string.IsNullOrEmpty(sMsg))
  767. {
  768. //Logger.Info(JsonConvert.SerializeObject(i_crmInput));
  769. //Logger.Info(JsonConvert.SerializeObject(crmRes));
  770. }
  771. else
  772. {
  773. crmRes = new CErrorResponseMessage(sMsg, i_crmInput);
  774. Logger.Error(JsonConvert.SerializeObject(i_crmInput));
  775. Logger.Error(JsonConvert.SerializeObject(crmRes));
  776. }
  777. return crmRes;
  778. }
  779. private List<tb_grp_branch> GetBranches(string group_id)
  780. {
  781. // 從group_id找到uid,再用uid去撈分店名稱跟分店uid
  782. QueryJsonElementCollection lBlocks = new QueryJsonElementCollection();
  783. QueryJsonElement qjeOrigin = lBlocks.GetInst();
  784. qjeOrigin.table = tb_grp_group.TABLENAME;
  785. qjeOrigin.displaycols = new List<string>() { tb_grp_group.CN_UID };
  786. qjeOrigin.wherecols = new WhereNode(tb_grp_group.CN_FB_GROUP_ID, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_grp_group), group_id);
  787. lBlocks.Add(qjeOrigin);
  788. string sMsg = MakeSelectJoinByBlocks(lBlocks, out Command cRes);
  789. var ai = ArsenalDBMgr.GetInst(cRes);
  790. var group = ai.RunQuerySingleORM<tb_grp_group>(cRes);
  791. if (group == null)
  792. {
  793. return null;
  794. }
  795. lBlocks = new QueryJsonElementCollection();
  796. qjeOrigin = lBlocks.GetInst();
  797. qjeOrigin.table = tb_grp_branch.TABLENAME;
  798. qjeOrigin.displaycols = new List<string>() { tb_grp_branch.CN_UID, tb_grp_branch.CN_BRANCH_NAME, tb_grp_branch.CN_PUBLIC_STATUS, tb_grp_branch.CN_ADDRESS };
  799. qjeOrigin.wherecols = new WhereNode(tb_grp_branch.CN_GROUP_UID, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_grp_branch), group.uid);
  800. lBlocks.Add(qjeOrigin);
  801. sMsg = MakeSelectJoinByBlocks(lBlocks, out cRes);
  802. ai = ArsenalDBMgr.GetInst(cRes);
  803. var data = ai.RunQueryList<tb_grp_branch>(cRes);
  804. return data;
  805. }
  806. public CResponseMessage GetMatchedMember(CRequestMessage i_crmInput)
  807. {
  808. CResponseMessage crmRes = null;
  809. string sMsg = null;
  810. try
  811. {
  812. do
  813. {
  814. tb_meb_member sDisplay = new tb_meb_member();
  815. sDisplay.SetFullDirtyEx(EntityBaseExtension.EColumnFilter.ES_NO_SYSTEMCOLUMN);
  816. Command cAllSetting = Command.SetupSelectCmd(sDisplay);
  817. crmRes = this.simpleQuery(i_crmInput, BLWording.QRY_MASTER, null, cAllSetting);
  818. }
  819. while (false);
  820. }
  821. catch (Exception ex)
  822. {
  823. LogHelper.DBLog(Util.GetLastExceptionMsg(ex));
  824. sMsg = $"{nameof(GetMatchedMember)} unknwon exception. Call from).";
  825. #if DEBUG
  826. System.Diagnostics.Debug.WriteLine(sMsg);
  827. #endif
  828. }
  829. if (sMsg != null)
  830. {
  831. crmRes = new CErrorResponseMessage(sMsg);
  832. Logger.Error(JsonConvert.SerializeObject(i_crmInput));
  833. Logger.Error(JsonConvert.SerializeObject(crmRes));
  834. }
  835. else
  836. {
  837. //Logger.Info(JsonConvert.SerializeObject(i_crmInput));
  838. //Logger.Info(JsonConvert.SerializeObject(crmRes));
  839. }
  840. return crmRes;
  841. }
  842. public CResponseMessage GetMemberProfile(CRequestMessage i_crmInput)
  843. {
  844. CResponseMessage crmRes = null;
  845. string sMsg = null;
  846. Command cRes = null;
  847. try
  848. {
  849. do
  850. {
  851. Dictionary<string, string> dicCondition = GetQueryMasterFirstQJEDicwherecols(i_crmInput);
  852. var lsBranch = ProjectHelper.GetUserGroup(i_crmInput);
  853. QueryJsonElementCollection lBlocks = new QueryJsonElementCollection();
  854. QueryJsonElement qjeMember = lBlocks.GetInst();
  855. qjeMember.table = tb_meb_member.TABLENAME;
  856. qjeMember.dicwherecols = dicCondition;
  857. lBlocks.Add(qjeMember);
  858. QueryJsonElement qjeGroup = lBlocks.GetInst();
  859. qjeGroup.table = tb_grp_group.TABLENAME;
  860. qjeGroup.jointable = qjeMember;
  861. qjeGroup.jointype = QueryJsonElement.LEFT_JOIN;
  862. qjeGroup.joincols = new Dictionary<string, string>() {
  863. { tb_grp_group.CN_FB_GROUP_ID,tb_meb_member.CN_GROUP_ID }};
  864. if (!dicCondition.ContainsKey(tb_meb_member.CN_GROUP_USER_ID))
  865. {
  866. qjeGroup.wherecols = new WhereNode(tb_grp_group.CN_UID, WhereNode.EColumnOperation.EOT_IN, typeof(tb_grp_group), lsBranch.ToArray());
  867. }
  868. lBlocks.Add(qjeGroup);
  869. QueryJsonElement qjeGroupUser = lBlocks.GetInst();
  870. qjeGroupUser.table = tb_grp_group2user.TABLENAME;
  871. qjeGroupUser.jointable = qjeGroup;
  872. qjeGroupUser.jointype = QueryJsonElement.LEFT_JOIN;
  873. qjeGroupUser.joincols = new Dictionary<string, string> { { tb_grp_group2user.CN_GROUP_UID, tb_grp_group.CN_UID } };
  874. qjeGroupUser.displaycols = new List<string>()
  875. {
  876. tb_grp_group2user.CN_USER_TOKEN
  877. };
  878. lBlocks.Add(qjeGroupUser);
  879. sMsg = MakeSelectJoinByBlocks(lBlocks, out cRes);
  880. ArsenalInterface ai = ArsenalDBMgr.GetInst(cRes);
  881. List<tb_grp_group> qds = ai.RunQueryList<tb_grp_group>(cRes);
  882. var user_token = "";
  883. foreach (var data in qds)
  884. {
  885. user_token = data.GetValue("user_token").ToString();
  886. }
  887. string uri = "";
  888. if (dicCondition.ContainsKey(tb_meb_member.CN_GROUP_USER_ID))
  889. {
  890. uri = string.Format("https://graph.facebook.com/{0}?fields={1}&access_token={2}", dicCondition[tb_meb_member.CN_GROUP_USER_ID], "picture.type(normal)", user_token);
  891. }
  892. APIHelper.BaseGet(uri, null, new Dictionary<string, string>(), out HttpResponseMessage responseMessage);
  893. if (responseMessage.IsSuccessStatusCode)
  894. {
  895. var joResult = JsonConvert.DeserializeObject(responseMessage.Content.ReadAsStringAsync().Result) as JObject;
  896. var oResult = joResult.ToObject<Dictionary<string, object>>();
  897. if (oResult.Any())
  898. {
  899. crmRes = new CSuccessResponseMessage(null, i_crmInput);
  900. crmRes.param.Add("data", oResult);
  901. }
  902. }
  903. else
  904. {
  905. LogHelper.DBLog("url獲取picture失敗:" + uri);
  906. crmRes = new CErrorResponseMessage("獲取picture失敗");
  907. }
  908. }
  909. while (false);
  910. }
  911. catch (Exception ex)
  912. {
  913. LogHelper.DBLog(Util.GetLastExceptionMsg(ex));
  914. sMsg = $"{nameof(GetMemberProfile)} unknwon exception. Call from).";
  915. #if DEBUG
  916. System.Diagnostics.Debug.WriteLine(sMsg);
  917. #endif
  918. }
  919. if (sMsg != null)
  920. {
  921. crmRes = new CErrorResponseMessage(sMsg);
  922. Logger.Error(JsonConvert.SerializeObject(i_crmInput));
  923. Logger.Error(JsonConvert.SerializeObject(crmRes));
  924. }
  925. else
  926. {
  927. //Logger.Info(JsonConvert.SerializeObject(i_crmInput));
  928. //Logger.Info(JsonConvert.SerializeObject(crmRes));
  929. }
  930. return crmRes;
  931. }
  932. public CResponseMessage RefreshAllMemberInfo(CRequestMessage i_crmInput)
  933. {
  934. CResponseMessage crmRes = null;
  935. string sMsg = null;
  936. Command cRes = null;
  937. try
  938. {
  939. do
  940. {
  941. Dictionary<string, object> dicCondition = GetQueryMasterFirstWhereData(i_crmInput);
  942. string[] aMemberUID = new string[0];
  943. if (dicCondition.ContainsKey(tb_meb_member.CN_UID))
  944. {
  945. if (dicCondition[tb_meb_member.CN_UID] != null)
  946. {
  947. var jaMemberUID = dicCondition[tb_meb_member.CN_UID] as JArray;
  948. aMemberUID = jaMemberUID.Select(x => x.ToString()).ToArray();
  949. }
  950. }
  951. QueryJsonElementCollection lBlocks = new QueryJsonElementCollection();
  952. QueryJsonElement qjeMember = lBlocks.GetInst();
  953. qjeMember.table = tb_meb_member.TABLENAME;
  954. qjeMember.displaycols = new List<string>()
  955. { tb_meb_member.CN_UID,
  956. tb_meb_member.CN_GROUP_USER_ID,
  957. tb_meb_member.CN_GROUP_ID,
  958. tb_meb_member.CN_FB_PIC
  959. };
  960. qjeMember.wherecols = new WhereNode(tb_meb_member.CN_UID, WhereNode.EColumnOperation.EOT_IN, typeof(tb_meb_member), aMemberUID.ToArray());
  961. lBlocks.Add(qjeMember);
  962. QueryJsonElement qjeGroup = lBlocks.GetInst();
  963. qjeGroup.table = tb_grp_group.TABLENAME;
  964. qjeGroup.jointable = qjeMember;
  965. qjeGroup.jointype = QueryJsonElement.LEFT_JOIN;
  966. qjeGroup.joincols = new Dictionary<string, string>() {
  967. { tb_grp_group.CN_FB_GROUP_ID,tb_meb_member.CN_GROUP_ID }};
  968. lBlocks.Add(qjeGroup);
  969. QueryJsonElement qjeGroupUser = lBlocks.GetInst();
  970. qjeGroupUser.table = tb_grp_group2user.TABLENAME;
  971. qjeGroupUser.jointable = qjeGroup;
  972. qjeGroupUser.jointype = QueryJsonElement.LEFT_JOIN;
  973. qjeGroupUser.joincols = new Dictionary<string, string> { { tb_grp_group2user.CN_GROUP_UID, tb_grp_group.CN_UID } };
  974. qjeGroupUser.displaycols = new List<string>()
  975. {
  976. tb_grp_group2user.CN_USER_TOKEN
  977. };
  978. lBlocks.Add(qjeGroupUser);
  979. sMsg = MakeSelectJoinByBlocks(lBlocks, out cRes);
  980. ArsenalInterface ai = ArsenalDBMgr.GetInst(cRes);
  981. List<CusMemberModel> qds = ai.RunQueryList<CusMemberModel>(cRes);
  982. List<Command> lCmdUpdate = new List<Command>();
  983. List<WhereNode> lswnMain = new List<WhereNode>();
  984. var user_token = "";
  985. if(qds.Count()>0)
  986. {
  987. user_token = qds[0].user_token.ToString();
  988. }
  989. string strPostUrl = "https://graph.facebook.com/me";
  990. var lsData = new List<APIHelper.DataContent>()
  991. {
  992. new APIHelper.DataContent { Key = "access_token" , Type = typeof(StringContent) , Content = user_token },
  993. new APIHelper.DataContent { Key = "include_headers", Type = typeof(StringContent), Content = "false" }
  994. };
  995. var listBacth = new List<Dictionary<string, string>>();
  996. var dicBacth = new Dictionary<string, string>();
  997. var iRowNO = 0;
  998. foreach (CusMemberModel MemberData in qds)
  999. {
  1000. iRowNO++;
  1001. dicBacth = new Dictionary<string, string>();
  1002. dicBacth.Add("method", "GET");
  1003. dicBacth.Add("relative_url", string.Format("{0}?fields={1}", MemberData.group_user_id, "picture.type(normal)"));
  1004. listBacth.Add(dicBacth);
  1005. try
  1006. {
  1007. //每50執行一次批次
  1008. if (iRowNO % 50 == 0 || iRowNO == qds.Count())
  1009. {
  1010. lsData.Add(new APIHelper.DataContent { Key = "batch", Type = typeof(StringContent), Content = JsonConvert.SerializeObject(listBacth) });
  1011. listBacth = new List<Dictionary<string, string>>();
  1012. APIHelper.BasePost(strPostUrl, null, lsData, out HttpResponseMessage responseMessage);
  1013. if (responseMessage.IsSuccessStatusCode)
  1014. {
  1015. string sContent = responseMessage.Content.ReadAsStringAsync().Result;
  1016. var lstReturn = JsonConvert.DeserializeObject<List<BatchModel>>(sContent);
  1017. foreach (BatchModel BatchModel in lstReturn)
  1018. {
  1019. if (BatchModel.code == 200)
  1020. {
  1021. var PictureModel = JsonConvert.DeserializeObject<PictureModel>(BatchModel.body);
  1022. var strPicurl = PictureModel.picture.data.url;
  1023. if (!string.IsNullOrEmpty(strPicurl))
  1024. {
  1025. //更新
  1026. tb_meb_member mUpd = new tb_meb_member();
  1027. mUpd.fb_pic = strPicurl;
  1028. mUpd.update_date = DateTime.Now;
  1029. lswnMain = new List<WhereNode>();
  1030. lswnMain.Add(new WhereNode(tb_meb_member.CN_GROUP_USER_ID, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_meb_member), PictureModel.id));
  1031. lCmdUpdate.Add(Command.SetupUpdateCmd(mUpd, new WhereNode(WhereNode.ENodeOperation.ENO_AND, lswnMain.ToArray())));
  1032. }
  1033. }
  1034. }
  1035. }
  1036. else
  1037. {
  1038. Logger.Error($"CallFbPostPushAPI f7");
  1039. sMsg = JsonConvert.SerializeObject(responseMessage);
  1040. Logger.Error($"CallFbPostPushAPI sMsg={sMsg}");
  1041. break;
  1042. }
  1043. }
  1044. }
  1045. catch (Exception ex)
  1046. {
  1047. LogHelper.DBLog(Util.GetLastExceptionMsg(ex));
  1048. Logger.Error(MemberData.uid + "error");
  1049. sMsg = MemberData.uid + "error";
  1050. #if DEBUG
  1051. System.Diagnostics.Debug.WriteLine(sMsg);
  1052. #endif
  1053. }
  1054. }
  1055. // 更新fb_pic資料
  1056. if (lCmdUpdate.Count() > 0)
  1057. {
  1058. ai = ArsenalDBMgr.GetInst(lCmdUpdate[0], GetDefaultSystemColumnInfo());
  1059. ai.RunEditCmds(lCmdUpdate);
  1060. sMsg = GetLastErrorCode(lCmdUpdate);
  1061. if (sMsg != null)
  1062. {
  1063. break;
  1064. }
  1065. }
  1066. //查詢最新的fb_pic
  1067. lBlocks = new QueryJsonElementCollection();
  1068. qjeMember = lBlocks.GetInst();
  1069. qjeMember.table = tb_meb_member.TABLENAME;
  1070. qjeMember.displaycols = new List<string>()
  1071. { tb_meb_member.CN_UID,
  1072. tb_meb_member.CN_GROUP_USER_ID,
  1073. tb_meb_member.CN_GROUP_ID,
  1074. tb_meb_member.CN_FB_PIC
  1075. };
  1076. qjeMember.wherecols = new WhereNode(tb_meb_member.CN_UID, WhereNode.EColumnOperation.EOT_IN, typeof(tb_meb_member), aMemberUID.ToArray());
  1077. lBlocks.Add(qjeMember);
  1078. sMsg = MakeSelectJoinByBlocks(lBlocks, out cRes);
  1079. ai = ArsenalDBMgr.GetInst(cRes);
  1080. qds = ai.RunQueryList<CusMemberModel>(cRes);
  1081. crmRes = new CSuccessResponseMessage(null, i_crmInput);
  1082. crmRes.param.Add(BLWording.DATA, qds);
  1083. }
  1084. while (false);
  1085. }
  1086. catch (Exception ex)
  1087. {
  1088. LogHelper.DBLog(Util.GetLastExceptionMsg(ex));
  1089. sMsg = $"{nameof(GetMemberProfile)} unknwon exception. Call from).";
  1090. #if DEBUG
  1091. System.Diagnostics.Debug.WriteLine(sMsg);
  1092. #endif
  1093. }
  1094. if (sMsg != null)
  1095. {
  1096. crmRes = new CErrorResponseMessage(sMsg);
  1097. Logger.Error(JsonConvert.SerializeObject(i_crmInput));
  1098. Logger.Error(JsonConvert.SerializeObject(crmRes));
  1099. }
  1100. return crmRes;
  1101. }
  1102. [Auth(false)]
  1103. public CResponseMessage SetDefaultBranch(CRequestMessage i_crmInput)
  1104. {
  1105. return UpdateCommand(i_crmInput, (dicData) =>
  1106. {
  1107. var defaultBranch = dicData[tb_meb_member.CN_DEFAULT_BRANCH] as string;
  1108. var group_user_id = dicData[tb_meb_member.CN_GROUP_USER_ID] as string;
  1109. var group_id = dicData[tb_meb_member.CN_GROUP_ID] as string;
  1110. // 更新預設分店
  1111. tb_meb_member updateEntity = new tb_meb_member { default_branch = defaultBranch };
  1112. tb_meb_member updateEntityCond = new tb_meb_member { group_user_id = group_user_id, group_id = group_id };
  1113. return Command.SetupUpdateCmd(updateEntity, updateEntityCond);
  1114. });
  1115. }
  1116. [Auth(false)]
  1117. public CResponseMessage CallSendMessage(CRequestMessage i_crmInput)
  1118. {
  1119. return UpdateCommand(i_crmInput, (dicData) =>
  1120. {
  1121. var group_user_id = dicData[tb_meb_member.CN_GROUP_USER_ID] as string;
  1122. var group_id = dicData[tb_meb_member.CN_GROUP_ID] as string;
  1123. // 更新最後傳遞訊息時間
  1124. tb_meb_member updateEntity = new tb_meb_member { last_call_message = DateTime.Now };
  1125. tb_meb_member updateEntityCond = new tb_meb_member { group_user_id = group_user_id, group_id = group_id };
  1126. return Command.SetupUpdateCmd(updateEntity, updateEntityCond);
  1127. });
  1128. }
  1129. private CResponseMessage UpdateCommand(CRequestMessage i_crmInput, Func<Dictionary<string, object>, Command> func)
  1130. {
  1131. CResponseMessage crmRes = null;
  1132. string sMsg = null;
  1133. Dictionary<string, object> dicData = (i_crmInput.param[BLWording.UPD_MASTER] as JObject).ToObject<Dictionary<string, object>>();
  1134. try
  1135. {
  1136. do
  1137. {
  1138. Command cmd = func(dicData);
  1139. var ai = ArsenalDBMgr.GetInst(cmd, GetDefaultSystemColumnInfo());
  1140. ai.RunEditSingleCmd(cmd);
  1141. sMsg = GetLastErrorCode(cmd);
  1142. }
  1143. while (false);
  1144. }
  1145. catch (Exception ex)
  1146. {
  1147. LogHelper.DBLog(Util.GetLastExceptionMsg(ex));
  1148. sMsg = $"{nameof(UpdateCommand)} unknwon exception. Call from).";
  1149. #if DEBUG
  1150. System.Diagnostics.Debug.WriteLine(sMsg);
  1151. #endif
  1152. }
  1153. if (sMsg != null)
  1154. {
  1155. crmRes = new CErrorResponseMessage(sMsg);
  1156. Logger.Error(JsonConvert.SerializeObject(i_crmInput));
  1157. Logger.Error(JsonConvert.SerializeObject(crmRes));
  1158. }
  1159. else
  1160. {
  1161. crmRes = new CSuccessResponseMessage(null, i_crmInput);
  1162. //Logger.Info(JsonConvert.SerializeObject(i_crmInput));
  1163. //Logger.Info(JsonConvert.SerializeObject(crmRes));
  1164. }
  1165. return crmRes;
  1166. }
  1167. public CResponseMessage RefreshMemberInfo(CRequestMessage i_crmInput)
  1168. {
  1169. string sMsg = null;
  1170. CResponseMessage crmRes = null;
  1171. try
  1172. {
  1173. do
  1174. {
  1175. sMsg = getCommonParameter(i_crmInput, BLWording.ADD_MASTER, out JArray jaDataArray, out tb_sys_session sUserSession);
  1176. if (sMsg != null)
  1177. {
  1178. break;
  1179. }
  1180. if (jaDataArray.Count != 1 || jaDataArray[0] == null)
  1181. {
  1182. sMsg = MessageWording.PARAM_NOT_EXPECTED;
  1183. break;
  1184. }
  1185. JObject joData = jaDataArray[0] as JObject;
  1186. Dictionary<string, object> dicData = new Dictionary<string, object>();
  1187. if (joData != null)
  1188. {
  1189. dicData = joData.ToObject<Dictionary<string, object>>();
  1190. }
  1191. string sPSID = null;
  1192. string fbGroupId = null;
  1193. if (dicData.ContainsKey(tb_meb_member.CN_GROUP_ID))
  1194. {
  1195. fbGroupId = dicData[tb_meb_member.CN_GROUP_ID].ToString();
  1196. }
  1197. var groupData = GetGroupSettings(fbGroupId);
  1198. var result = GetAppToken(groupData.app_id, groupData.client_secret, out FbToken resData);
  1199. if (result)
  1200. {
  1201. GetFBPagesID(dicData[BLWording.ASID].ToString(), groupData.page_id, resData.access_token, out sPSID);
  1202. }
  1203. // 更新會員資料
  1204. List<Command> lCmdUpdate = new List<Command>();
  1205. // 先查詢資料是否存在
  1206. tb_meb_member cMember = new tb_meb_member();
  1207. cMember.SetFullDirty();
  1208. tb_meb_member cMemberCon = new tb_meb_member() { group_user_id = dicData[BLWording.ASID].ToString(), group_id = fbGroupId };
  1209. Command cMemberSelect = Command.SetupSelectCmd(cMember, cMemberCon);
  1210. ArsenalInterface ai = ArsenalDBMgr.GetInst(cMemberSelect);
  1211. tb_meb_member qdsMember = ai.RunQuerySingleORM<tb_meb_member>(cMemberSelect);
  1212. string asid = dicData[BLWording.ASID].ToString();
  1213. var group_id = fbGroupId;
  1214. // 更新
  1215. dicData.Remove(tb_grp_article.CN_GROUP_UID);
  1216. tb_meb_member mUpd = new tb_meb_member();
  1217. mUpd.message_user_id = sPSID;
  1218. mUpd.fb_pic = dicData[tb_meb_member.CN_FB_PIC].ToString();
  1219. List<WhereNode> lswnMain = new List<WhereNode>();
  1220. lswnMain.Add(new WhereNode(tb_meb_member.CN_GROUP_USER_ID, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_meb_member), asid));
  1221. lswnMain.Add(new WhereNode(tb_meb_member.CN_GROUP_ID, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_meb_member), group_id));
  1222. lCmdUpdate.Add(Command.SetupUpdateCmd(mUpd, new WhereNode(WhereNode.ENodeOperation.ENO_AND, lswnMain.ToArray())));
  1223. ai = ArsenalDBMgr.GetInst(lCmdUpdate[0], GetDefaultSystemColumnInfo());
  1224. ai.RunEditCmds(lCmdUpdate);
  1225. sMsg = GetLastErrorCode(lCmdUpdate);
  1226. if (sMsg != null)
  1227. {
  1228. break;
  1229. }
  1230. crmRes = new CSuccessResponseMessage(null, i_crmInput);
  1231. crmRes.param.Add("psid", sPSID);
  1232. }
  1233. while (false);
  1234. }
  1235. catch (Exception ex)
  1236. {
  1237. sMsg = $"{nameof(RefreshMemberInfo)} unknwon exception. i_crmInput={JsonConvert.SerializeObject(i_crmInput)}. ex={ex.Message}";
  1238. #if DEBUG
  1239. System.Diagnostics.Debug.WriteLine(sMsg);
  1240. #endif
  1241. }
  1242. if (string.IsNullOrEmpty(sMsg))
  1243. {
  1244. //Logger.Info(JsonConvert.SerializeObject(i_crmInput));
  1245. //Logger.Info(JsonConvert.SerializeObject(crmRes));
  1246. }
  1247. else
  1248. {
  1249. crmRes = new CErrorResponseMessage(sMsg, i_crmInput);
  1250. Logger.Error(JsonConvert.SerializeObject(i_crmInput));
  1251. Logger.Error(JsonConvert.SerializeObject(crmRes));
  1252. }
  1253. return crmRes;
  1254. }
  1255. public CResponseMessage GetAllMembers(CRequestMessage i_crmInput)
  1256. {
  1257. string sMsg;
  1258. Command cRes = null;
  1259. CResponseMessage crmRes = null;
  1260. try
  1261. {
  1262. do
  1263. {
  1264. Dictionary<string, object> dicObjCondition = GetQueryMasterFirstWhereData(i_crmInput);
  1265. List<string> lsMainColumns = EntityBase.GetAllColumnName(typeof(tb_meb_member)); // 取得所有欄位名稱
  1266. var lsBranch = ProjectHelper.GetUserGroup(i_crmInput); // 取得可讀取社團資料的社團uid清單
  1267. var lsMember = new List<string>();
  1268. if (dicObjCondition.ContainsKey(tb_meb_member.CN_UID))
  1269. {
  1270. var aMember = dicObjCondition[tb_meb_member.CN_UID] as JArray;
  1271. foreach (var member in aMember)
  1272. {
  1273. lsMember.Add(member.ToString());
  1274. }
  1275. dicObjCondition.Remove(tb_meb_member.CN_UID);
  1276. }
  1277. Dictionary<string, string> dicCondition = new Dictionary<string, string>();
  1278. foreach (var condition in dicObjCondition)
  1279. {
  1280. dicCondition.Add(condition.Key, condition.Value.ToString());
  1281. }
  1282. QueryJsonElementCollection lBlocks = new QueryJsonElementCollection();
  1283. QueryJsonElement qjeMember = lBlocks.GetInst();
  1284. qjeMember.table = tb_meb_member.TABLENAME;
  1285. qjeMember.displaycols = lsMainColumns;
  1286. List<WhereNode> lswnMain = new List<WhereNode>();
  1287. if (lsMember.Any())
  1288. {
  1289. qjeMember.wherecols = new WhereNode(tb_meb_member.CN_UID, WhereNode.EColumnOperation.EOT_IN, typeof(tb_meb_member), lsMember.ToArray());
  1290. }
  1291. lBlocks.Add(qjeMember);
  1292. QueryJsonElement qjeGroup = lBlocks.GetInst();
  1293. qjeGroup.table = tb_grp_group.TABLENAME;
  1294. qjeGroup.jointable = qjeMember;
  1295. qjeGroup.jointype = QueryJsonElement.LEFT_JOIN;
  1296. qjeGroup.joincols = new Dictionary<string, string>() {
  1297. { tb_grp_group.CN_FB_GROUP_ID,tb_meb_member.CN_GROUP_ID }};
  1298. if (dicObjCondition.ContainsKey(tb_meb_member.CN_GROUP_ID))
  1299. {
  1300. qjeGroup.wherecols = new WhereNode(tb_grp_group.CN_UID, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_grp_group), dicObjCondition[tb_meb_member.CN_GROUP_ID].ToString());
  1301. }
  1302. else
  1303. {
  1304. qjeGroup.wherecols = new WhereNode(tb_grp_group.CN_UID, WhereNode.EColumnOperation.EOT_IN, typeof(tb_grp_group), lsBranch.ToArray());
  1305. }
  1306. lBlocks.Add(qjeGroup);
  1307. sMsg = MakeSelectJoinByBlocks(lBlocks, out cRes);
  1308. ArsenalInterface ai = ArsenalDBMgr.GetInst(cRes, GetDefaultSystemColumnInfo());
  1309. List<tb_meb_member> qds = ai.RunQueryList<tb_meb_member>(cRes);
  1310. sMsg = GetLastErrorCode(cRes);
  1311. if (sMsg != null)
  1312. {
  1313. break;
  1314. }
  1315. crmRes = new CSuccessResponseMessage(null, i_crmInput);
  1316. crmRes.param.Add("data", qds);
  1317. }
  1318. while (false);
  1319. }
  1320. catch (Exception ex)
  1321. {
  1322. sMsg = $"{nameof(GetAllMembers)} unknwon exception. i_crmInput={JsonConvert.SerializeObject(i_crmInput)}. ex={ex.Message}";
  1323. #if DEBUG
  1324. System.Diagnostics.Debug.WriteLine(sMsg);
  1325. #endif
  1326. }
  1327. return crmRes;
  1328. }
  1329. [Auth(false)]
  1330. public CResponseMessage SetShoppingPoints(CRequestMessage i_crmInput)
  1331. {
  1332. CResponseMessage crmRes = null;
  1333. string sMsg = null;
  1334. Command cRes = null;
  1335. try
  1336. {
  1337. do
  1338. {
  1339. sMsg = getCommonParameter(i_crmInput, BLWording.UPD_MASTER, out JArray jaDataArray, out tb_sys_session sUserSession);
  1340. if (sMsg != null)
  1341. {
  1342. break;
  1343. }
  1344. if (jaDataArray.Count != 1 || jaDataArray[0] == null)
  1345. {
  1346. sMsg = MessageWording.PARAM_NOT_EXPECTED;
  1347. break;
  1348. }
  1349. JObject joData = jaDataArray[0] as JObject;
  1350. Dictionary<string, object> dicData = joData[BLWording.WHEREDATA].ToObject<Dictionary<string, object>>();
  1351. tb_meb_member cMember = new tb_meb_member();
  1352. cMember.SetDirty(tb_meb_member.CN_UID);
  1353. tb_meb_member cCon = new tb_meb_member()
  1354. {
  1355. group_user_id = dicData[tb_meb_member.CN_GROUP_USER_ID].ToString(),
  1356. group_id = dicData[tb_meb_member.CN_GROUP_ID].ToString()
  1357. };
  1358. Command cSelect = Command.SetupSelectCmd(cMember, cCon);
  1359. ArsenalInterface ai = ArsenalDBMgr.GetInst(cSelect);
  1360. List<tb_meb_member> qdsMember = ai.RunQueryList<tb_meb_member>(cSelect);
  1361. List<Command> lCmdUpdate = new List<Command>();
  1362. string sNewArticleUid = Guid.NewGuid().ToString();
  1363. tb_meb_shopping_points_record mNew = new tb_meb_shopping_points_record() { };
  1364. mNew.uid = sNewArticleUid;
  1365. mNew.member_uid = qdsMember[0].uid;
  1366. mNew.amount = 30;
  1367. mNew.memo = "首登";
  1368. lCmdUpdate.Add(Command.SetupInsertCmd(mNew));
  1369. lCmdUpdate.Add(Command.SetupUpdateCmd(new tb_meb_member()
  1370. {
  1371. shopping_account = 30
  1372. }
  1373. , new tb_meb_member() { uid = qdsMember[0].uid }));
  1374. ai = ArsenalDBMgr.GetInst(lCmdUpdate[0], GetDefaultSystemColumnInfo());
  1375. ai.RunEditCmds(lCmdUpdate);
  1376. sMsg = GetLastErrorCode(lCmdUpdate);
  1377. if (sMsg != null)
  1378. {
  1379. break;
  1380. }
  1381. crmRes = new CSuccessResponseMessage(null, i_crmInput);
  1382. }
  1383. while (false);
  1384. }
  1385. catch (Exception ex)
  1386. {
  1387. LogHelper.DBLog(Util.GetLastExceptionMsg(ex));
  1388. sMsg = $"{nameof(SetShoppingPoints)} unknwon exception. Call from).";
  1389. #if DEBUG
  1390. System.Diagnostics.Debug.WriteLine(sMsg);
  1391. #endif
  1392. }
  1393. if (sMsg != null)
  1394. {
  1395. crmRes = new CErrorResponseMessage(sMsg);
  1396. Logger.Error(JsonConvert.SerializeObject(i_crmInput));
  1397. Logger.Error(JsonConvert.SerializeObject(crmRes));
  1398. }
  1399. else
  1400. {
  1401. //Logger.Info(JsonConvert.SerializeObject(i_crmInput));
  1402. //Logger.Info(JsonConvert.SerializeObject(crmRes));
  1403. }
  1404. return crmRes;
  1405. }
  1406. class ShoppingPointsModel : tb_meb_shopping_points_record
  1407. {
  1408. public string name { get; set; }
  1409. }
  1410. [Auth(false)]
  1411. public CResponseMessage GetShoppingPoints(CRequestMessage i_crmInput)
  1412. {
  1413. CResponseMessage crmRes = null;
  1414. string sMsg = null;
  1415. Command cRes = null;
  1416. try
  1417. {
  1418. do
  1419. {
  1420. Dictionary<string, object> dicObjCondition = GetQueryMasterFirstWhereData(i_crmInput);
  1421. string[] aMember = null;
  1422. string group_user_id = null;
  1423. string group_id = null;
  1424. if (dicObjCondition.ContainsKey(tb_meb_shopping_points_record.CN_MEMBER_UID))
  1425. {
  1426. var jaMember = dicObjCondition[tb_meb_shopping_points_record.CN_MEMBER_UID] as JArray;
  1427. aMember = jaMember.Select(x => x.ToString()).ToArray();
  1428. }
  1429. else if (dicObjCondition.ContainsKey(tb_meb_member.CN_GROUP_USER_ID))
  1430. {
  1431. group_user_id = dicObjCondition[tb_meb_member.CN_GROUP_USER_ID].ToString();
  1432. group_id = dicObjCondition[tb_meb_member.CN_GROUP_ID].ToString();
  1433. }
  1434. else
  1435. {
  1436. sMsg = "參數錯誤";
  1437. break;
  1438. }
  1439. QueryJsonElementCollection lBlocks = new QueryJsonElementCollection();
  1440. QueryJsonElement qjeMember = lBlocks.GetInst();
  1441. qjeMember.table = tb_meb_member.TABLENAME;
  1442. qjeMember.displaycols = new List<string>() {
  1443. tb_meb_member.CN_UID,
  1444. tb_meb_member.CN_NAME,
  1445. tb_meb_member.CN_SHOPPING_ACCOUNT,
  1446. };
  1447. if (aMember != null)
  1448. {
  1449. qjeMember.wherecols = new WhereNode(tb_meb_member.CN_UID, WhereNode.EColumnOperation.EOT_IN, typeof(tb_meb_member), aMember);
  1450. }
  1451. else if (group_user_id != null && group_id != null)
  1452. {
  1453. List<WhereNode> lswnMember = new List<WhereNode>();
  1454. lswnMember.Add(new WhereNode(tb_meb_member.CN_GROUP_USER_ID, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_meb_member), group_user_id));
  1455. lswnMember.Add(new WhereNode(tb_meb_member.CN_GROUP_ID, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_meb_member), group_id));
  1456. qjeMember.wherecols = new WhereNode(WhereNode.ENodeOperation.ENO_AND, lswnMember.ToArray());
  1457. }
  1458. lBlocks.Add(qjeMember);
  1459. sMsg = MakeSelectJoinByBlocks(lBlocks, out cRes);
  1460. ArsenalInterface ai = ArsenalDBMgr.GetInst(cRes, GetDefaultSystemColumnInfo());
  1461. List<tb_meb_member> qds = ai.RunQueryList<tb_meb_member>(cRes);
  1462. sMsg = GetLastErrorCode(cRes);
  1463. if (sMsg != null)
  1464. {
  1465. break;
  1466. }
  1467. crmRes = new CSuccessResponseMessage(null, i_crmInput);
  1468. crmRes.param.Add("data", qds);
  1469. }
  1470. while (false);
  1471. }
  1472. catch (Exception ex)
  1473. {
  1474. LogHelper.DBLog(Util.GetLastExceptionMsg(ex));
  1475. sMsg = $"{nameof(GetShoppingPoints)} unknwon exception. Call from).";
  1476. #if DEBUG
  1477. System.Diagnostics.Debug.WriteLine(sMsg);
  1478. #endif
  1479. }
  1480. if (sMsg != null)
  1481. {
  1482. crmRes = new CErrorResponseMessage(sMsg);
  1483. Logger.Error(JsonConvert.SerializeObject(i_crmInput));
  1484. Logger.Error(JsonConvert.SerializeObject(crmRes));
  1485. }
  1486. else
  1487. {
  1488. //Logger.Info(JsonConvert.SerializeObject(i_crmInput));
  1489. //Logger.Info(JsonConvert.SerializeObject(crmRes));
  1490. }
  1491. return crmRes;
  1492. }
  1493. public CResponseMessage UpdateShoppingPoints(CRequestMessage i_crmInput)
  1494. {
  1495. CResponseMessage crmRes = null;
  1496. string sMsg = null;
  1497. Command cRes = null;
  1498. try
  1499. {
  1500. do
  1501. {
  1502. sMsg = getCommonParameter(i_crmInput, BLWording.UPD_MASTER, out JArray jaDataArray, out tb_sys_session sUserSession);
  1503. if (sMsg != null)
  1504. {
  1505. break;
  1506. }
  1507. if (jaDataArray.Count != 1 || jaDataArray[0] == null)
  1508. {
  1509. sMsg = MessageWording.PARAM_NOT_EXPECTED;
  1510. break;
  1511. }
  1512. JObject joData = jaDataArray[0] as JObject;
  1513. Dictionary<string, object> dicData = joData[BLWording.WHEREDATA].ToObject<Dictionary<string, object>>();
  1514. string memberUid = dicData[tb_meb_member.CN_UID].ToString();
  1515. int type = Convert.ToInt32(dicData["type"]);
  1516. int amount = type == 0 ? Convert.ToInt32(dicData[tb_meb_shopping_points_record.CN_AMOUNT]) : -Convert.ToInt32(dicData[tb_meb_shopping_points_record.CN_AMOUNT]);
  1517. string memo = dicData[tb_meb_shopping_points_record.CN_MEMO].ToString();
  1518. tb_meb_member cMember = new tb_meb_member();
  1519. cMember.SetDirty(tb_meb_member.CN_SHOPPING_ACCOUNT);
  1520. tb_meb_member cCon = new tb_meb_member()
  1521. {
  1522. uid = memberUid
  1523. };
  1524. Command cSelect = Command.SetupSelectCmd(cMember, cCon);
  1525. ArsenalInterface ai = ArsenalDBMgr.GetInst(cSelect);
  1526. List<tb_meb_member> qdsMember = ai.RunQueryList<tb_meb_member>(cSelect);
  1527. List<Command> lCmdUpdate = new List<Command>();
  1528. string sNewArticleUid = Guid.NewGuid().ToString();
  1529. tb_meb_shopping_points_record mNew = new tb_meb_shopping_points_record() { };
  1530. mNew.uid = sNewArticleUid;
  1531. mNew.member_uid = memberUid;
  1532. mNew.amount = amount;
  1533. mNew.memo = string.IsNullOrEmpty(memo) ? null : memo;
  1534. lCmdUpdate.Add(Command.SetupInsertCmd(mNew));
  1535. // 更新member shopping_account
  1536. if (qdsMember[0].shopping_account + amount < 0)
  1537. {
  1538. sMsg = "購物金不得小於0";
  1539. break;
  1540. }
  1541. lCmdUpdate.Add(Command.SetupUpdateCmd(new tb_meb_member()
  1542. {
  1543. shopping_account = qdsMember[0].shopping_account + amount
  1544. }
  1545. , new tb_meb_member() { uid = memberUid }));
  1546. ai = ArsenalDBMgr.GetInst(lCmdUpdate[0], GetDefaultSystemColumnInfo());
  1547. ai.RunEditCmds(lCmdUpdate);
  1548. sMsg = GetLastErrorCode(lCmdUpdate);
  1549. if (sMsg != null)
  1550. {
  1551. break;
  1552. }
  1553. crmRes = new CSuccessResponseMessage(null, i_crmInput);
  1554. }
  1555. while (false);
  1556. }
  1557. catch (Exception ex)
  1558. {
  1559. LogHelper.DBLog(Util.GetLastExceptionMsg(ex));
  1560. sMsg = $"{nameof(UpdateShoppingPoints)} unknwon exception. Call from).";
  1561. #if DEBUG
  1562. System.Diagnostics.Debug.WriteLine(sMsg);
  1563. #endif
  1564. }
  1565. if (sMsg != null)
  1566. {
  1567. crmRes = new CErrorResponseMessage(sMsg);
  1568. Logger.Error(JsonConvert.SerializeObject(i_crmInput));
  1569. Logger.Error(JsonConvert.SerializeObject(crmRes));
  1570. }
  1571. else
  1572. {
  1573. //Logger.Info(JsonConvert.SerializeObject(i_crmInput));
  1574. //Logger.Info(JsonConvert.SerializeObject(crmRes));
  1575. }
  1576. return crmRes;
  1577. }
  1578. public CResponseMessage ResetReturnCount(CRequestMessage i_crmInput)
  1579. {
  1580. CResponseMessage crmRes = null;
  1581. string sMsg = null;
  1582. try
  1583. {
  1584. do
  1585. {
  1586. tb_meb_member dicData = new tb_meb_member();
  1587. if (i_crmInput != null && i_crmInput.param != null && i_crmInput.param.ContainsKey(BLWording.UPD_MASTER))
  1588. {
  1589. JArray joData = i_crmInput.param[BLWording.UPD_MASTER] as JArray;
  1590. if (joData.Any())
  1591. {
  1592. dicData = joData[0][BLWording.WHEREDATA].ToObject<tb_meb_member>();
  1593. }
  1594. }
  1595. Command cCmd = Command.SetupUpdateCmd(new tb_meb_member()
  1596. {
  1597. return_count = 0
  1598. }
  1599. , new tb_meb_member() { uid = dicData.uid });
  1600. ArsenalInterface ai = ArsenalDBMgr.GetInst(cCmd, GetDefaultSystemColumnInfo());
  1601. ai.RunEditSingleCmd(cCmd);
  1602. string sErrorCode = GetLastErrorCode(cCmd);
  1603. if (sErrorCode != null)
  1604. {
  1605. sMsg = sErrorCode;
  1606. }
  1607. if (sMsg != null)
  1608. {
  1609. break;
  1610. }
  1611. crmRes = new CSuccessResponseMessage(null, i_crmInput);
  1612. }
  1613. while (false);
  1614. }
  1615. catch (Exception ex)
  1616. {
  1617. LogHelper.DBLog(Util.GetLastExceptionMsg(ex));
  1618. sMsg = $"{nameof(ResetReturnCount)} unknwon exception. Call from).";
  1619. #if DEBUG
  1620. System.Diagnostics.Debug.WriteLine(sMsg);
  1621. #endif
  1622. }
  1623. if (sMsg != null)
  1624. {
  1625. crmRes = new CErrorResponseMessage(sMsg);
  1626. Logger.Error(JsonConvert.SerializeObject(i_crmInput));
  1627. Logger.Error(JsonConvert.SerializeObject(crmRes));
  1628. }
  1629. else
  1630. {
  1631. //Logger.Info(JsonConvert.SerializeObject(i_crmInput));
  1632. //Logger.Info(JsonConvert.SerializeObject(crmRes));
  1633. }
  1634. return crmRes;
  1635. }
  1636. [Auth(false)]
  1637. public CResponseMessage VerifyFirebaseToken(CRequestMessage i_crmInput)
  1638. {
  1639. string sMsg = null;
  1640. CResponseMessage crmRes = null;
  1641. try
  1642. {
  1643. do
  1644. {
  1645. sMsg = getCommonParameter(i_crmInput, BLWording.QRY_MASTER, out JArray jaDataArray, out tb_sys_session sUserSession);
  1646. if (sMsg != null)
  1647. {
  1648. break;
  1649. }
  1650. if (jaDataArray.Count != 1 || jaDataArray[0] == null)
  1651. {
  1652. sMsg = MessageWording.PARAM_NOT_EXPECTED;
  1653. break;
  1654. }
  1655. JObject joData = jaDataArray[0][BLWording.WHEREDATA] as JObject;
  1656. Dictionary<string, object> dicData = new Dictionary<string, object>();
  1657. if (joData != null)
  1658. {
  1659. dicData = joData.ToObject<Dictionary<string, object>>();
  1660. }
  1661. string firebaseToken = dicData[tb_meb_member.CN_FIREBASE_TOKEN].ToString();
  1662. string group_id = dicData[tb_meb_member.CN_GROUP_ID].ToString();
  1663. string asid = dicData[tb_meb_member.CN_GROUP_USER_ID].ToString();
  1664. // 查詢Token
  1665. tb_meb_member cMember = new tb_meb_member();
  1666. cMember.SetFullDirty();
  1667. tb_meb_member cMemberCon = new tb_meb_member() { group_user_id = asid, group_id = group_id };
  1668. Command cMemberSelect = Command.SetupSelectCmd(cMember, cMemberCon);
  1669. ArsenalInterface ai = ArsenalDBMgr.GetInst(cMemberSelect);
  1670. tb_meb_member qdsMember = ai.RunQuerySingleORM<tb_meb_member>(cMemberSelect);
  1671. // 更新會員資料
  1672. List<Command> lCmdUpdate = new List<Command>();
  1673. if (qdsMember.firebase_token == null || firebaseToken != qdsMember.firebase_token)
  1674. {
  1675. // 更新
  1676. tb_meb_member mUpd = new tb_meb_member();
  1677. mUpd.firebase_token = firebaseToken;
  1678. List<WhereNode> lswnMain = new List<WhereNode>();
  1679. lswnMain.Add(new WhereNode(tb_meb_member.CN_GROUP_USER_ID, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_meb_member), asid));
  1680. lswnMain.Add(new WhereNode(tb_meb_member.CN_GROUP_ID, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_meb_member), group_id));
  1681. lCmdUpdate.Add(Command.SetupUpdateCmd(mUpd, new WhereNode(WhereNode.ENodeOperation.ENO_AND, lswnMain.ToArray())));
  1682. ai = ArsenalDBMgr.GetInst(lCmdUpdate[0], GetDefaultSystemColumnInfo());
  1683. ai.RunEditCmds(lCmdUpdate);
  1684. string sErrorCode = GetLastErrorCode(lCmdUpdate);
  1685. if (sErrorCode != null)
  1686. {
  1687. sMsg = sErrorCode;
  1688. }
  1689. if (sMsg != null)
  1690. {
  1691. sMsg = "已偵測裝置變更";
  1692. }
  1693. }
  1694. crmRes = new CSuccessResponseMessage(sMsg, i_crmInput);
  1695. }
  1696. while (false);
  1697. }
  1698. catch (Exception ex)
  1699. {
  1700. sMsg = $"{nameof(VerifyFirebaseToken)} unknwon exception. i_crmInput={JsonConvert.SerializeObject(i_crmInput)}. ex={ex.Message}";
  1701. #if DEBUG
  1702. System.Diagnostics.Debug.WriteLine(sMsg);
  1703. #endif
  1704. }
  1705. if (string.IsNullOrEmpty(sMsg))
  1706. {
  1707. //Logger.Info(JsonConvert.SerializeObject(i_crmInput));
  1708. //Logger.Info(JsonConvert.SerializeObject(crmRes));
  1709. }
  1710. else
  1711. {
  1712. crmRes = new CErrorResponseMessage(sMsg, i_crmInput);
  1713. Logger.Error(JsonConvert.SerializeObject(i_crmInput));
  1714. Logger.Error(JsonConvert.SerializeObject(crmRes));
  1715. }
  1716. return crmRes;
  1717. }
  1718. protected class tokenModel
  1719. {
  1720. public string group_id { get; set; }
  1721. public string code { get; set; }
  1722. public string redirect_uri { get; set; }
  1723. public string access_token { get; set; }
  1724. }
  1725. [Auth(false)]
  1726. public CResponseMessage GetAccessToken(CRequestMessage i_crmInput)
  1727. {
  1728. CResponseMessage crmRes = null;
  1729. string sMsg = null;
  1730. try
  1731. {
  1732. do
  1733. {
  1734. tokenModel dicData = new tokenModel();
  1735. tokenModel rawResult = null;
  1736. if (i_crmInput != null && i_crmInput.param != null && i_crmInput.param.ContainsKey(BLWording.UPD_MASTER))
  1737. {
  1738. JArray joData = i_crmInput.param[BLWording.UPD_MASTER] as JArray;
  1739. if (joData.Any())
  1740. {
  1741. dicData = joData[0][BLWording.WHEREDATA].ToObject<tokenModel>();
  1742. }
  1743. }
  1744. var groupData = GetGroupSettings(dicData.group_id);
  1745. string uri = string.Format("https://graph.facebook.com/v3.2/oauth/access_token?client_id={0}&redirect_uri={1}&code={2}&client_secret={3}", groupData.app_id, dicData.redirect_uri, dicData.code, groupData.client_secret);
  1746. APIHelper.BaseGet(uri, null, new Dictionary<string, string>(), out HttpResponseMessage responseMessage);
  1747. if (responseMessage.IsSuccessStatusCode)
  1748. {
  1749. rawResult = JsonConvert.DeserializeObject<tokenModel>(responseMessage.Content.ReadAsStringAsync().Result);
  1750. if (string.IsNullOrEmpty(rawResult.access_token))
  1751. {
  1752. sMsg = "獲取token失敗";
  1753. }
  1754. }
  1755. if (sMsg != null)
  1756. {
  1757. break;
  1758. }
  1759. crmRes = new CSuccessResponseMessage(null, i_crmInput);
  1760. crmRes.param.Add("access_token", rawResult.access_token);
  1761. }
  1762. while (false);
  1763. }
  1764. catch (Exception ex)
  1765. {
  1766. LogHelper.DBLog(Util.GetLastExceptionMsg(ex));
  1767. sMsg = $"{nameof(GetAccessToken)} unknwon exception. Call from).";
  1768. #if DEBUG
  1769. System.Diagnostics.Debug.WriteLine(sMsg);
  1770. #endif
  1771. }
  1772. if (sMsg != null)
  1773. {
  1774. crmRes = new CErrorResponseMessage(sMsg);
  1775. Logger.Error(JsonConvert.SerializeObject(i_crmInput));
  1776. Logger.Error(JsonConvert.SerializeObject(crmRes));
  1777. }
  1778. else
  1779. {
  1780. //Logger.Info(JsonConvert.SerializeObject(i_crmInput));
  1781. //Logger.Info(JsonConvert.SerializeObject(crmRes));
  1782. }
  1783. return crmRes;
  1784. }
  1785. protected class checkedTokenModel
  1786. {
  1787. public Data data { get; set; }
  1788. public class Data
  1789. {
  1790. public string user_id { get; set; }
  1791. public string app_id { get; set; }
  1792. public bool is_valid { get; set; }
  1793. }
  1794. }
  1795. [Auth(false)]
  1796. public CResponseMessage CheckAccessToken(CRequestMessage i_crmInput)
  1797. {
  1798. CResponseMessage crmRes = null;
  1799. string sMsg = null;
  1800. try
  1801. {
  1802. do
  1803. {
  1804. tokenModel dicData = new tokenModel();
  1805. checkedTokenModel rawResult = null;
  1806. if (i_crmInput != null && i_crmInput.param != null && i_crmInput.param.ContainsKey(BLWording.UPD_MASTER))
  1807. {
  1808. JArray joData = i_crmInput.param[BLWording.UPD_MASTER] as JArray;
  1809. if (joData.Any())
  1810. {
  1811. dicData = joData[0][BLWording.WHEREDATA].ToObject<tokenModel>();
  1812. }
  1813. }
  1814. var groupData = GetGroupSettings(dicData.group_id);
  1815. var result = GetAppToken(groupData.app_id, groupData.client_secret, out FbToken responseData);
  1816. string uri = string.Format("https://graph.facebook.com/debug_token?input_token={0}&access_token={1}", dicData.access_token, responseData.access_token);
  1817. APIHelper.BaseGet(uri, null, new Dictionary<string, string>(), out HttpResponseMessage responseMessage);
  1818. if (responseMessage.IsSuccessStatusCode)
  1819. {
  1820. rawResult = JsonConvert.DeserializeObject<checkedTokenModel>(responseMessage.Content.ReadAsStringAsync().Result);
  1821. if (!rawResult.data.is_valid)
  1822. {
  1823. sMsg = "驗證token失敗";
  1824. break;
  1825. }
  1826. }
  1827. else
  1828. {
  1829. sMsg = "驗證token失敗";
  1830. break;
  1831. }
  1832. if (sMsg != null)
  1833. {
  1834. break;
  1835. }
  1836. crmRes = new CSuccessResponseMessage(null, i_crmInput);
  1837. }
  1838. while (false);
  1839. }
  1840. catch (Exception ex)
  1841. {
  1842. LogHelper.DBLog(Util.GetLastExceptionMsg(ex));
  1843. sMsg = $"{nameof(GetAccessToken)} unknwon exception. Call from).";
  1844. #if DEBUG
  1845. System.Diagnostics.Debug.WriteLine(sMsg);
  1846. #endif
  1847. }
  1848. if (sMsg != null)
  1849. {
  1850. crmRes = new CErrorResponseMessage(sMsg);
  1851. Logger.Error(JsonConvert.SerializeObject(i_crmInput));
  1852. Logger.Error(JsonConvert.SerializeObject(crmRes));
  1853. }
  1854. else
  1855. {
  1856. //Logger.Info(JsonConvert.SerializeObject(i_crmInput));
  1857. //Logger.Info(JsonConvert.SerializeObject(crmRes));
  1858. }
  1859. return crmRes;
  1860. }
  1861. public bool getPrivacy(string group_id,out string privacy)
  1862. {
  1863. var result = false;
  1864. privacy = null;
  1865. string sMsg = null;
  1866. QueryJsonElementCollection lBlocks = new QueryJsonElementCollection();
  1867. QueryJsonElement qjeGroups = lBlocks.GetInst();
  1868. qjeGroups.table = tb_grp_group.TABLENAME;
  1869. qjeGroups.wherecols = new WhereNode(tb_grp_group.CN_FB_GROUP_ID, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_grp_group2user), group_id);
  1870. lBlocks.Add(qjeGroups);
  1871. QueryJsonElement qjeGroupUser = lBlocks.GetInst();
  1872. qjeGroupUser.table = tb_grp_group2user.TABLENAME;
  1873. qjeGroupUser.jointable = qjeGroups;
  1874. qjeGroupUser.displaycols = new List<string>() { tb_grp_group2user.CN_USER_TOKEN };
  1875. qjeGroupUser.jointype = QueryJsonElement.LEFT_JOIN;
  1876. qjeGroupUser.joincols = new Dictionary<string, string>() {
  1877. { tb_grp_group2user.CN_GROUP_UID,tb_grp_group.CN_UID }};
  1878. lBlocks.Add(qjeGroupUser);
  1879. Command cRes = null;
  1880. sMsg = MakeSelectJoinByBlocks(lBlocks, out cRes);
  1881. ArsenalInterface ai = ArsenalDBMgr.GetInst(cRes);
  1882. tb_grp_group2user qdsGroups = ai.RunQuerySingleORM<tb_grp_group2user>(cRes);
  1883. if (qdsGroups != null)
  1884. {
  1885. var groupsInfo = GetPrivacy(group_id, qdsGroups.user_token);
  1886. privacy = groupsInfo.privacy;
  1887. result = true;
  1888. }
  1889. return result;
  1890. }
  1891. public Groups GetPrivacy(string group_id, string access_token)
  1892. {
  1893. Groups GroupInfo = null;
  1894. do
  1895. {
  1896. try
  1897. {
  1898. // 送出資料
  1899. string uri = $"https://graph.facebook.com/v8.0/{group_id}?";
  1900. var dicData = new Dictionary<string, string>()
  1901. {
  1902. { "access_token",access_token},
  1903. { "fields","privacy"}
  1904. };
  1905. APIHelper.BaseGet(uri, null, dicData, out HttpResponseMessage responseMessage);
  1906. if (responseMessage.IsSuccessStatusCode)
  1907. {
  1908. var fb_error = GetFbApiError(responseMessage);
  1909. if (!string.IsNullOrWhiteSpace(fb_error))
  1910. {
  1911. Logger.Error($"{nameof(GetPrivacy)} FB API response error message: {fb_error} ");
  1912. break;
  1913. }
  1914. GroupInfo = JsonConvert.DeserializeObject<Groups>(responseMessage.Content.ReadAsStringAsync().Result);
  1915. }
  1916. }
  1917. catch (Exception ex)
  1918. {
  1919. throw ex;
  1920. }
  1921. } while (false);
  1922. return GroupInfo;
  1923. }
  1924. private tb_grp_group GetGroupSettings(string group_id)
  1925. {
  1926. // 獲得該社團的token, app id, client secret
  1927. tb_grp_group cGroup = new tb_grp_group();
  1928. cGroup.SetDirty(tb_grp_group.CN_APP_ID, tb_grp_group.CN_PAGE_ID, tb_grp_group.CN_CLIENT_SECRET);
  1929. tb_grp_group cCon = new tb_grp_group() { fb_group_id = group_id };
  1930. Command cSelect = Command.SetupSelectCmd(cGroup, cCon);
  1931. ArsenalInterface ai2 = ArsenalDBMgr.GetInst(cSelect);
  1932. tb_grp_group qds2 = ai2.RunQuerySingleORM<tb_grp_group>(cSelect);
  1933. return qds2;
  1934. }
  1935. }
  1936. }