ts-glitter 20.4.6 → 20.4.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/lowcode/Entry.js +1 -1
  2. package/lowcode/Entry.ts +1 -1
  3. package/lowcode/backend-manager/bg-widget.js +19 -17
  4. package/lowcode/backend-manager/bg-widget.ts +19 -17
  5. package/lowcode/cms-plugin/stock-history.js +1 -0
  6. package/lowcode/cms-plugin/stock-history.ts +10 -0
  7. package/lowcode/cms-plugin/user/user-module.js +28 -28
  8. package/lowcode/cms-plugin/user/user-module.ts +29 -31
  9. package/lowcode/cms-plugin/user-list.js +55 -42
  10. package/lowcode/cms-plugin/user-list.ts +71 -47
  11. package/lowcode/glitter-base/route/progress.js +32 -0
  12. package/lowcode/glitter-base/route/progress.ts +36 -0
  13. package/lowcode/glitter-base/route/user.js +37 -1
  14. package/lowcode/glitter-base/route/user.ts +40 -1
  15. package/lowcode/glitterBundle/dialog/ShareDialog.ts +0 -1
  16. package/package.json +3 -1
  17. package/src/api-public/controllers/ai-chat.js.map +1 -1
  18. package/src/api-public/controllers/app-release.js.map +1 -1
  19. package/src/api-public/controllers/delivery.js.map +1 -1
  20. package/src/api-public/controllers/graph-api.js.map +1 -1
  21. package/src/api-public/controllers/index.js +9 -8
  22. package/src/api-public/controllers/index.js.map +1 -1
  23. package/src/api-public/controllers/index.ts +171 -169
  24. package/src/api-public/controllers/lambda.js.map +1 -1
  25. package/src/api-public/controllers/manager.js.map +1 -1
  26. package/src/api-public/controllers/post.js.map +1 -1
  27. package/src/api-public/controllers/progress.d.ts +3 -0
  28. package/src/api-public/controllers/progress.js +29 -0
  29. package/src/api-public/controllers/progress.js.map +1 -0
  30. package/src/api-public/controllers/progress.ts +25 -0
  31. package/src/api-public/controllers/sql_api.js.map +1 -1
  32. package/src/api-public/controllers/track.js.map +1 -1
  33. package/src/api-public/controllers/user.js +47 -1
  34. package/src/api-public/controllers/user.js.map +1 -1
  35. package/src/api-public/controllers/user.ts +44 -3
  36. package/src/api-public/services/checkout.d.ts +1 -0
  37. package/src/api-public/services/checkout.js +16 -6
  38. package/src/api-public/services/checkout.js.map +1 -1
  39. package/src/api-public/services/checkout.ts +28 -18
  40. package/src/api-public/services/customer-sessions.js.map +1 -1
  41. package/src/api-public/services/fake-data-model/fake-order.d.ts +6 -1
  42. package/src/api-public/services/fake-data-model/fake-order.js +159 -155
  43. package/src/api-public/services/fake-data-model/fake-order.js.map +1 -1
  44. package/src/api-public/services/fake-data-model/fake-order.ts +186 -179
  45. package/src/api-public/services/fake-data-model/fake-product.js +94 -94
  46. package/src/api-public/services/fake-data-model/fake-product.js.map +1 -1
  47. package/src/api-public/services/fake-data-model/fake-product.ts +109 -114
  48. package/src/api-public/services/fake-data-model/fake-user.d.ts +17 -1
  49. package/src/api-public/services/fake-data-model/fake-user.js +70 -384
  50. package/src/api-public/services/fake-data-model/fake-user.js.map +1 -1
  51. package/src/api-public/services/fake-data-model/fake-user.ts +111 -394
  52. package/src/api-public/services/initial-fake-data.js +50 -10
  53. package/src/api-public/services/initial-fake-data.js.map +1 -1
  54. package/src/api-public/services/initial-fake-data.ts +92 -22
  55. package/src/api-public/services/invoice.js.map +1 -1
  56. package/src/api-public/services/manager.js.map +1 -1
  57. package/src/api-public/services/notify.js +234 -213
  58. package/src/api-public/services/notify.js.map +1 -1
  59. package/src/api-public/services/notify.ts +520 -494
  60. package/src/api-public/services/phone-verify.js +1 -1
  61. package/src/api-public/services/phone-verify.js.map +1 -1
  62. package/src/api-public/services/phone-verify.ts +1 -1
  63. package/src/api-public/services/pos.js.map +1 -1
  64. package/src/api-public/services/post.js.map +1 -1
  65. package/src/api-public/services/rebate.d.ts +1 -0
  66. package/src/api-public/services/rebate.js +15 -8
  67. package/src/api-public/services/rebate.js.map +1 -1
  68. package/src/api-public/services/rebate.ts +24 -15
  69. package/src/api-public/services/recommend.js.map +1 -1
  70. package/src/api-public/services/schedule.js +7 -4
  71. package/src/api-public/services/schedule.js.map +1 -1
  72. package/src/api-public/services/schedule.ts +344 -335
  73. package/src/api-public/services/shopee.js.map +1 -1
  74. package/src/api-public/services/shopping.d.ts +1 -1
  75. package/src/api-public/services/shopping.js +28 -25
  76. package/src/api-public/services/shopping.js.map +1 -1
  77. package/src/api-public/services/shopping.ts +89 -76
  78. package/src/api-public/services/stock.js.map +1 -1
  79. package/src/api-public/services/user.d.ts +10 -1
  80. package/src/api-public/services/user.js +245 -42
  81. package/src/api-public/services/user.js.map +1 -1
  82. package/src/api-public/services/user.ts +325 -45
  83. package/src/api-public/services/voucher.js.map +1 -1
  84. package/src/api-public/services/workers.js.map +1 -1
  85. package/src/api-public/utils/ut-permission.d.ts +0 -1
  86. package/src/api-public/utils/ut-permission.js.map +1 -1
  87. package/src/config.d.ts +2 -1
  88. package/src/config.js +2 -1
  89. package/src/config.js.map +1 -1
  90. package/src/config.ts +142 -142
  91. package/src/controllers/app.js.map +1 -1
  92. package/src/controllers/backend-server.js.map +1 -1
  93. package/src/controllers/filemanager.js.map +1 -1
  94. package/src/controllers/index.js.map +1 -1
  95. package/src/controllers/user.js.map +1 -1
  96. package/src/domain-check.js.map +1 -1
  97. package/src/index.js.map +1 -1
  98. package/src/index.ts +3 -12
  99. package/src/modules/AWSLib.js +2 -3
  100. package/src/modules/AWSLib.js.map +1 -1
  101. package/src/modules/database.d.ts +1 -2
  102. package/src/modules/database.js.map +1 -1
  103. package/src/modules/firebase.js.map +1 -1
  104. package/src/modules/logger.js.map +1 -1
  105. package/src/modules/redis.d.ts +1 -1
  106. package/src/modules/redis.js.map +1 -1
  107. package/src/run.js +1 -2
  108. package/src/run.js.map +1 -1
  109. package/src/services/backend-service.js.map +1 -1
  110. package/src/services/create-instance.js +3 -4
  111. package/src/services/create-instance.js.map +1 -1
  112. package/src/services/global-event.js.map +1 -1
  113. package/src/services/ios-release.js.map +1 -1
  114. package/src/services/page.js.map +1 -1
  115. package/src/services/private_config.js.map +1 -1
  116. package/src/services/release.js.map +1 -1
  117. package/src/services/seo.js.map +1 -1
  118. package/src/services/tool.js +2 -3
  119. package/src/services/tool.js.map +1 -1
  120. package/src/services/user.js.map +1 -1
  121. package/src/services/web-socket.js.map +1 -1
  122. package/src/update-progress-track.d.ts +14 -0
  123. package/src/update-progress-track.js +28 -0
  124. package/src/update-progress-track.js.map +1 -0
  125. package/src/update-progress-track.ts +34 -0
  126. package/j4enepo67p.json +0 -1
@@ -15,69 +15,68 @@ import { App } from '../../services/app.js';
15
15
  import { UserUpdate } from './user-update.js';
16
16
 
17
17
  type ScheduleItem = {
18
- second: number;
19
- status: boolean;
20
- func: keyof Schedule;
21
- desc: string;
18
+ second: number;
19
+ status: boolean;
20
+ func: keyof Schedule;
21
+ desc: string;
22
22
  };
23
23
 
24
24
  export class Schedule {
25
- static app: string[] = [];
26
-
27
- async perload(app: string) {
28
- const brand_type=await App.checkBrandAndMemberType(app)
29
- if(brand_type.brand==='shopnex' && brand_type.domain){
30
- if (!(await this.isDatabasePass(app))) return false;
31
- await ApiPublic.createScheme(app);
32
- return true;
33
- }else{
34
- return false
35
- }
36
-
25
+ static app: string[] = [];
26
+
27
+ async perload(app: string) {
28
+ const brand_type = await App.checkBrandAndMemberType(app);
29
+ if (brand_type.brand === 'shopnex' && brand_type.domain) {
30
+ if (!(await this.isDatabasePass(app))) return false;
31
+ await ApiPublic.createScheme(app);
32
+ return true;
33
+ } else {
34
+ return false;
37
35
  }
36
+ }
38
37
 
39
- async isDatabaseExists(app: string) {
40
- return (await db.query(`SHOW DATABASES LIKE \'${app}\';`, [])).length > 0;
41
- }
38
+ async isDatabaseExists(app: string) {
39
+ return (await db.query(`SHOW DATABASES LIKE \'${app}\';`, [])).length > 0;
40
+ }
42
41
 
43
- async isDatabasePass(app: string) {
44
- const SQL = `
42
+ async isDatabasePass(app: string) {
43
+ const SQL = `
45
44
  SELECT *
46
45
  FROM ${saasConfig.SAAS_NAME}.app_config
47
46
  WHERE appName = \'${app}\'
48
47
  AND (refer_app is null OR refer_app = appName);
49
48
  `;
50
- return (await db.query(SQL, [])).length > 0;
51
- }
52
-
53
- async isTableExists(table: string, app: string) {
54
- return (await db.query(`SHOW TABLES IN \`${app}\` LIKE \'${table}\';`, [])).length > 0;
55
- }
56
-
57
- async example(sec: number) {
58
- try {
59
- for (const app of Schedule.app) {
60
- if (await this.perload(app)) {
61
- // 排程範例
62
- // await
63
- }
64
- }
65
- } catch (e) {
66
- throw exception.BadRequestError('BAD_REQUEST', 'Example Error: ' + e, null);
49
+ return (await db.query(SQL, [])).length > 0;
50
+ }
51
+
52
+ async isTableExists(table: string, app: string) {
53
+ return (await db.query(`SHOW TABLES IN \`${app}\` LIKE \'${table}\';`, [])).length > 0;
54
+ }
55
+
56
+ async example(sec: number) {
57
+ try {
58
+ for (const app of Schedule.app) {
59
+ if (await this.perload(app)) {
60
+ // 排程範例
61
+ // await
67
62
  }
68
- setTimeout(() => this.example(sec), sec * 1000);
63
+ }
64
+ } catch (e) {
65
+ throw exception.BadRequestError('BAD_REQUEST', 'Example Error: ' + e, null);
69
66
  }
70
-
71
- async autoCancelOrder(sec: number) {
72
- let clock=new Date()
73
- console.log(`autoCancelOrder`)
74
- for (const app of Schedule.app) {
75
- try {
76
- if (await this.perload(app)) {
77
- const config = await new User(app).getConfigV2({ key: 'login_config', user_id: 'manager' });
78
- if (config?.auto_cancel_order_timer && config.auto_cancel_order_timer > 0) {
79
- const orders = await db.query(
80
- `SELECT * FROM \`${app}\`.t_checkout
67
+ setTimeout(() => this.example(sec), sec * 1000);
68
+ }
69
+
70
+ async autoCancelOrder(sec: number) {
71
+ let clock = new Date();
72
+ console.log(`autoCancelOrder`);
73
+ for (const app of Schedule.app) {
74
+ try {
75
+ if (await this.perload(app)) {
76
+ const config = await new User(app).getConfigV2({ key: 'login_config', user_id: 'manager' });
77
+ if (config?.auto_cancel_order_timer && config.auto_cancel_order_timer > 0) {
78
+ const orders = await db.query(
79
+ `SELECT * FROM \`${app}\`.t_checkout
81
80
  WHERE
82
81
  status = 0
83
82
  AND created_time < NOW() - INTERVAL ${config.auto_cancel_order_timer} HOUR
@@ -86,332 +85,342 @@ export class Schedule {
86
85
  AND progress='wait'
87
86
  AND payment_method != 'cash_on_delivery'
88
87
  ORDER BY id DESC;`,
89
- []
90
- );
91
- await Promise.all(
92
- orders.map(async (order: any) => {
93
- order.orderData.orderStatus = '-1';
94
- order.orderData.archived = 'true';
95
- return new Shopping(app).putOrder({
96
- id: order.id,
97
- orderData: order.orderData,
98
- status: '0',
99
- });
100
- })
101
- );
102
- }
103
- }
104
- } catch (e) {
105
- console.error(`autoCancelOrder-Error`,e)
106
- }
88
+ []
89
+ );
90
+ await Promise.all(
91
+ orders.map(async (order: any) => {
92
+ order.orderData.orderStatus = '-1';
93
+ order.orderData.archived = 'true';
94
+ return new Shopping(app).putOrder({
95
+ id: order.id,
96
+ orderData: order.orderData,
97
+ status: '0',
98
+ });
99
+ })
100
+ );
101
+ }
107
102
  }
108
- setTimeout(() => this.autoCancelOrder(sec), sec * 1000);
109
- console.log(`autoCancelOrder-Stop`,(new Date().getTime() - clock.getTime())/1000)
103
+ } catch (e) {
104
+ console.error(`autoCancelOrder-Error`, e);
105
+ }
110
106
  }
111
-
112
- async renewMemberLevel(sec: number) {
113
- let clock=new Date()
114
- console.log(`renewMemberLevel`)
107
+ setTimeout(() => this.autoCancelOrder(sec), sec * 1000);
108
+ console.log(`autoCancelOrder-Stop`, (new Date().getTime() - clock.getTime()) / 1000);
109
+ }
110
+
111
+ async renewMemberLevel(sec: number) {
112
+ let clock = new Date();
113
+ console.log(`renewMemberLevel`);
114
+ try {
115
+ for (const app of Schedule.app) {
115
116
  try {
116
- for (const app of Schedule.app) {
117
- try {
118
- if (await this.perload(app)) {
119
- const users = await db.query(`select * from \`${app}\`.t_user `, []);
120
- for (const user of users) {
121
- await new User(app).checkMember(user, true);
122
- await UserUpdate.update(app,user.userID)
123
- //限制速率每秒最多100筆更新
124
- await new Promise((resolve, reject)=>{
125
- setTimeout(()=>{
126
- resolve(true)
127
- },50)
128
- })
129
- }
130
- }
131
- console.log(`renewMemberLevel-finish->`,app)
132
- }catch (e) {
133
- console.log(`renewMemberLevel-error-continue`)
134
- }
117
+ if (await this.perload(app)) {
118
+ const users = await db.query(`select * from \`${app}\`.t_user `, []);
119
+ for (const user of users) {
120
+ await new User(app).checkMember(user, true);
121
+ await UserUpdate.update(app, user.userID);
122
+ //限制速率每秒最多100筆更新
123
+ await new Promise((resolve, reject) => {
124
+ setTimeout(() => {
125
+ resolve(true);
126
+ }, 50);
127
+ });
135
128
  }
129
+ }
130
+ console.log(`renewMemberLevel-finish->`, app);
136
131
  } catch (e) {
137
- console.error('BAD_REQUEST', 'renewMemberLevel Error: ' + e, null);
132
+ console.log(`renewMemberLevel-error-continue`);
138
133
  }
139
- setTimeout(() => this.renewMemberLevel(sec), sec * 1000);
140
- console.log(`renewMemberLevel-Stop`,(new Date().getTime() - clock.getTime())/1000)
134
+ }
135
+ } catch (e) {
136
+ console.error('BAD_REQUEST', 'renewMemberLevel Error: ' + e, null);
141
137
  }
138
+ setTimeout(() => this.renewMemberLevel(sec), sec * 1000);
139
+ console.log(`renewMemberLevel-Stop`, (new Date().getTime() - clock.getTime()) / 1000);
140
+ }
141
+
142
+ async birthRebate(sec: number) {
143
+ let clock = new Date();
144
+ console.log(`resetVoucherHistory`);
145
+ for (const app of Schedule.app) {
146
+ try {
147
+ if (await this.perload(app)) {
148
+ const rebateClass = new Rebate(app);
149
+ const userClass = new User(app);
150
+
151
+ if (await rebateClass.mainStatus()) {
152
+ const getRS = await userClass.getConfig({ key: 'rebate_setting', user_id: 'manager' });
153
+ const rgs = getRS[0] && getRS[0].value.birth ? getRS[0].value.birth : {};
154
+ if (rgs && rgs.switch) {
155
+ async function postUserRebate(id: number, value: number) {
156
+ const used = await rebateClass.canUseRebate(id, 'birth');
157
+ if (used?.result) {
158
+ if (value !== 0) {
159
+ await rebateClass.insertRebate(id, value, '生日禮', {
160
+ type: 'birth',
161
+ deadTime: rgs.unlimited ? undefined : moment().add(rgs.date, 'd').format('YYYY-MM-DD HH:mm:ss'),
162
+ });
163
+ }
164
+ }
165
+ }
142
166
 
143
- async birthRebate(sec: number) {
144
- let clock=new Date()
145
- console.log(`resetVoucherHistory`)
146
- for (const app of Schedule.app) {
147
- try {
148
- if (await this.perload(app)) {
149
- const rebateClass = new Rebate(app);
150
- const userClass = new User(app);
151
-
152
- if (await rebateClass.mainStatus()) {
153
- const getRS = await userClass.getConfig({ key: 'rebate_setting', user_id: 'manager' });
154
- const rgs = getRS[0] && getRS[0].value.birth ? getRS[0].value.birth : {};
155
- if (rgs && rgs.switch) {
156
- async function postUserRebate(id: number, value: number) {
157
- const used = await rebateClass.canUseRebate(id, 'birth');
158
- if (used?.result) {
159
- if (value !== 0) {
160
- await rebateClass.insertRebate(id, value, '生日禮', {
161
- type: 'birth',
162
- deadTime: rgs.unlimited ? undefined : moment().add(rgs.date, 'd').format('YYYY-MM-DD HH:mm:ss'),
163
- });
164
- }
165
- }
166
- }
167
-
168
- const users = await db.query(
169
- `SELECT *
167
+ const users = await db.query(
168
+ `SELECT *
170
169
  FROM \`${app}\`.t_user
171
170
  WHERE MONTH (JSON_EXTRACT(userData, '$.birth')) = MONTH (CURDATE());`,
172
- []
173
- );
174
-
175
- if (rgs.type === 'base') {
176
- for (const user of users) {
177
- await postUserRebate(user.userID, rgs.value);
178
- }
179
- }
180
-
181
- const levelData = await userClass.getConfigV2({ key: 'member_level_config', user_id: 'manager' });
182
- levelData.levels = levelData.levels || [];
171
+ []
172
+ );
183
173
 
184
- if (rgs.type === 'levels') {
185
- const usersLevel = await userClass.getUserLevel(
186
- users.map((item: { userID: number }) => {
187
- return { userId: item.userID };
188
- })
189
- );
190
- for (const user of users) {
191
- const member = usersLevel.find((item) => item.id == user.userID);
192
- if (member && member.data.id === '') {
193
- continue;
194
- }
195
- const data = rgs.level.find((item: { id: string }) => item.id == member?.data.id);
196
- if (!data) {
197
- continue;
198
- }
199
- await postUserRebate(user.userID, data.value);
200
- }
201
- }
202
- }
203
- }
174
+ if (rgs.type === 'base') {
175
+ for (const user of users) {
176
+ await postUserRebate(user.userID, rgs.value);
204
177
  }
205
- } catch (e) {
206
- console.error('BAD_REQUEST', 'birthRebate Error: ' + e, null);
178
+ }
179
+
180
+ const levelData = await userClass.getConfigV2({ key: 'member_level_config', user_id: 'manager' });
181
+ levelData.levels = levelData.levels || [];
182
+
183
+ if (rgs.type === 'levels') {
184
+ const usersLevel = await userClass.getUserLevel(
185
+ users.map((item: { userID: number }) => {
186
+ return { userId: item.userID };
187
+ })
188
+ );
189
+ for (const user of users) {
190
+ const member = usersLevel.find(item => item.id == user.userID);
191
+ if (member && member.data.id === '') {
192
+ continue;
193
+ }
194
+ const data = rgs.level.find((item: { id: string }) => item.id == member?.data.id);
195
+ if (!data) {
196
+ continue;
197
+ }
198
+ await postUserRebate(user.userID, data.value);
199
+ }
200
+ }
207
201
  }
202
+ }
208
203
  }
209
-
210
- setTimeout(() => this.birthRebate(sec), sec * 1000);
211
- console.log(`birthRebate-Stop`,(new Date().getTime() - clock.getTime())/1000)
204
+ } catch (e) {
205
+ console.error('BAD_REQUEST', 'birthRebate Error: ' + e, null);
206
+ }
212
207
  }
213
208
 
214
- async birthBlessMail(sec: number) {
215
- let clock=new Date()
216
- console.log(`resetVoucherHistory`)
217
- for (const app of Schedule.app) {
218
- try {
219
- if (await this.perload(app)) {
220
- const mailType = 'auto-email-birthday';
221
- const customerMail = await AutoSendEmail.getDefCompare(app, mailType, 'zh-TW');
222
- if (customerMail.toggle) {
223
- // 歷史生日祝福寄件紀錄
224
- const mailClass = new Mail(app);
225
- const sendRecords = await mailClass.getMail({
226
- type: 'download',
227
- page: 0,
228
- limit: 0,
229
- mailType: mailType,
230
- });
209
+ setTimeout(() => this.birthRebate(sec), sec * 1000);
210
+ console.log(`birthRebate-Stop`, (new Date().getTime() - clock.getTime()) / 1000);
211
+ }
212
+
213
+ async birthBlessMail(sec: number) {
214
+ let clock = new Date();
215
+ console.log(`resetVoucherHistory`);
216
+ for (const app of Schedule.app) {
217
+ try {
218
+ if (await this.perload(app)) {
219
+ const mailType = 'auto-email-birthday';
220
+ const customerMail = await AutoSendEmail.getDefCompare(app, mailType, 'zh-TW');
221
+ if (customerMail.toggle) {
222
+ // 歷史生日祝福寄件紀錄
223
+ const mailClass = new Mail(app);
224
+ const sendRecords = await mailClass.getMail({
225
+ type: 'download',
226
+ page: 0,
227
+ limit: 0,
228
+ mailType: mailType,
229
+ });
231
230
 
232
- // 當月生日之顧客
233
- const users = await db.query(
234
- `SELECT *
231
+ // 當月生日之顧客
232
+ const users = await db.query(
233
+ `SELECT *
235
234
  FROM \`${app}\`.t_user
236
235
  WHERE MONTH (JSON_EXTRACT(userData, '$.birth')) = MONTH (CURDATE());`,
237
- []
238
- );
239
-
240
- // 篩選出一年內曾寄信過的顧客
241
- const now = new Date();
242
- const oneYearAgo = new Date(now);
243
- oneYearAgo.setFullYear(now.getFullYear() - 1);
244
- const filteredData = sendRecords.data.filter((item: { trigger_time: string }) => {
245
- const triggerTime = new Date(item.trigger_time);
246
- return triggerTime > oneYearAgo;
247
- });
248
-
249
- // 一年內曾寄信過的顧客信箱陣列
250
- let hasBless: string[] = [];
251
- filteredData.map((item: { content: { email: string } }) => {
252
- hasBless = hasBless.concat(item.content.email);
253
- });
254
- hasBless = [...new Set(hasBless)];
236
+ []
237
+ );
238
+
239
+ // 篩選出一年內曾寄信過的顧客
240
+ const now = new Date();
241
+ const oneYearAgo = new Date(now);
242
+ oneYearAgo.setFullYear(now.getFullYear() - 1);
243
+ const filteredData = sendRecords.data.filter((item: { trigger_time: string }) => {
244
+ const triggerTime = new Date(item.trigger_time);
245
+ return triggerTime > oneYearAgo;
246
+ });
255
247
 
256
- // 進入寄信程序
257
- for (const user of users) {
258
- if (!hasBless.includes(user.userData.email)) {
259
- await mailClass.postMail({
260
- name: customerMail.name,
261
- title: customerMail.title.replace(/@\{\{user_name\}\}/g, user.userData.name),
262
- content: customerMail.content.replace(/@\{\{user_name\}\}/g, user.userData.name),
263
- email: [user.userData.email],
264
- type: mailType,
265
- });
266
- }
267
- }
268
- }
269
- }
270
- } catch (e) {
271
- console.error('BAD_REQUEST', 'birthBlessMail Error: ' + e, null);
248
+ // 一年內曾寄信過的顧客信箱陣列
249
+ let hasBless: string[] = [];
250
+ filteredData.map((item: { content: { email: string } }) => {
251
+ hasBless = hasBless.concat(item.content.email);
252
+ });
253
+ hasBless = [...new Set(hasBless)];
254
+
255
+ // 進入寄信程序
256
+ for (const user of users) {
257
+ if (!hasBless.includes(user.userData.email)) {
258
+ await mailClass.postMail({
259
+ name: customerMail.name,
260
+ title: customerMail.title.replace(/@\{\{user_name\}\}/g, user.userData.name),
261
+ content: customerMail.content.replace(/@\{\{user_name\}\}/g, user.userData.name),
262
+ email: [user.userData.email],
263
+ type: mailType,
264
+ });
265
+ }
272
266
  }
267
+ }
273
268
  }
274
-
275
- setTimeout(() => this.birthBlessMail(sec), sec * 1000);
276
- console.log(`birthBlessMail-Stop`,(new Date().getTime() - clock.getTime())/1000)
269
+ } catch (e) {
270
+ console.error('BAD_REQUEST', 'birthBlessMail Error: ' + e, null);
271
+ }
277
272
  }
278
273
 
279
- async resetVoucherHistory(sec: number) {
280
- let clock=new Date()
281
- console.log(`resetVoucherHistory`)
282
- for (const app of Schedule.app) {
283
- try {
284
- if (await this.perload(app)) {
285
- await new Shopping(app).resetVoucherHistory();
286
- }
287
- } catch (e) {
288
- console.error('BAD_REQUEST', 'resetVoucherHistory Error: ' + e, null);
289
- }
274
+ setTimeout(() => this.birthBlessMail(sec), sec * 1000);
275
+ console.log(`birthBlessMail-Stop`, (new Date().getTime() - clock.getTime()) / 1000);
276
+ }
277
+
278
+ async resetVoucherHistory(sec: number) {
279
+ let clock = new Date();
280
+ console.log(`resetVoucherHistory`);
281
+ for (const app of Schedule.app) {
282
+ try {
283
+ if (await this.perload(app)) {
284
+ await new Shopping(app).resetVoucherHistory();
290
285
  }
291
- setTimeout(() => this.resetVoucherHistory(sec), sec * 1000);
292
- console.log(`resetVoucherHistory-Stop`,(new Date().getTime() - clock.getTime())/1000)
286
+ } catch (e) {
287
+ console.error('BAD_REQUEST', 'resetVoucherHistory Error: ' + e, null);
288
+ }
293
289
  }
294
-
295
- async autoSendMail(sec: number) {
296
- let clock=new Date()
297
- console.log(`autoSendLine`)
298
- for (const app of Schedule.app) {
299
- try {
300
- if (await this.perload(app)) {
301
- const emails = await db.query(
302
- `SELECT * FROM \`${app}\`.t_triggers
290
+ setTimeout(() => this.resetVoucherHistory(sec), sec * 1000);
291
+ console.log(`resetVoucherHistory-Stop`, (new Date().getTime() - clock.getTime()) / 1000);
292
+ }
293
+
294
+ async autoSendMail(sec: number) {
295
+ let clock = new Date();
296
+ console.log(`autoSendLine`);
297
+ for (const app of Schedule.app) {
298
+ try {
299
+ if (await this.perload(app)) {
300
+ const emails = await db.query(
301
+ `SELECT * FROM \`${app}\`.t_triggers
303
302
  WHERE
304
303
  tag = 'sendMailBySchedule' AND
305
304
  status = 0 AND
306
305
  DATE_FORMAT(trigger_time, '%Y-%m-%d %H:%i') = DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i');`,
307
- []
308
- );
309
- for (const email of emails) {
310
- if (email.status === 0) {
311
- new Mail(app).chunkSendMail(email.content, email.id);
312
- }
313
- }
314
- }
315
- } catch (e) {
316
- console.error('BAD_REQUEST', 'autoSendMail Error: ' + e, null);
306
+ []
307
+ );
308
+ for (const email of emails) {
309
+ if (email.status === 0) {
310
+ new Mail(app).chunkSendMail(email.content, email.id);
317
311
  }
312
+ }
318
313
  }
319
- setTimeout(() => this.autoSendMail(sec), sec * 1000);
320
- console.log(`autoSendMail-Stop`,(new Date().getTime() - clock.getTime())/1000)
314
+ } catch (e) {
315
+ console.error('BAD_REQUEST', 'autoSendMail Error: ' + e, null);
316
+ }
321
317
  }
322
-
323
- async autoSendLine(sec: number) {
324
- let clock=new Date()
325
- console.log(`autoSendLine`)
326
- for (const app of Schedule.app) {
327
- try {
328
- if (await this.perload(app)) {
329
- const emails = await db.query(
330
- `SELECT * FROM \`${app}\`.t_triggers
318
+ setTimeout(() => this.autoSendMail(sec), sec * 1000);
319
+ console.log(`autoSendMail-Stop`, (new Date().getTime() - clock.getTime()) / 1000);
320
+ }
321
+
322
+ async autoSendLine(sec: number) {
323
+ let clock = new Date();
324
+ console.log(`autoSendLine`);
325
+ for (const app of Schedule.app) {
326
+ try {
327
+ if (await this.perload(app)) {
328
+ const emails = await db.query(
329
+ `SELECT * FROM \`${app}\`.t_triggers
331
330
  WHERE
332
331
  tag = 'sendLineBySchedule' AND
333
332
  DATE_FORMAT(trigger_time, '%Y-%m-%d %H:%i') = DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i');`,
334
- []
335
- );
336
-
337
- for (const email of emails) {
338
- if (email.status === 0) {
339
- new LineMessage(app).chunkSendLine(
340
- email.userList,
341
- {
342
- data: {
343
- text: email.content,
344
- },
345
- },
346
- email.id
347
- );
348
- }
349
- }
350
- }
351
- } catch (e) {
352
- console.error('BAD_REQUEST', 'autoSendLine Error: ' + e, null);
333
+ []
334
+ );
335
+
336
+ for (const email of emails) {
337
+ if (email.status === 0) {
338
+ new LineMessage(app).chunkSendLine(
339
+ email.userList,
340
+ {
341
+ data: {
342
+ text: email.content,
343
+ },
344
+ },
345
+ email.id
346
+ );
353
347
  }
348
+ }
354
349
  }
355
-
356
- setTimeout(() => this.autoSendLine(sec), sec * 1000);
357
- console.log(`autoSendLine-Stop`,(new Date().getTime() - clock.getTime())/1000)
358
- }
359
-
360
- async initialSampleApp(sec: number) {
361
- await new InitialFakeData(`t_1725992531001`).run();
362
- setTimeout(() => this.initialSampleApp(sec), sec * 1000);
350
+ } catch (e) {
351
+ console.error('BAD_REQUEST', 'autoSendLine Error: ' + e, null);
352
+ }
363
353
  }
364
354
 
365
- async currenciesUpdate(sec: number) {
366
- const date = new Date();
367
- const date_index = `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`;
368
- let clock=new Date()
369
- console.log(`currenciesUpdate-Start`)
370
- if ((await db.query(`select count(1) from \`${saasConfig.SAAS_NAME}\`.currency_config where updated='${date_index}'`, []))[0]['count(1)'] === 0) {
371
- let config = {
372
- method: 'get',
373
- maxBodyLength: Infinity,
374
- url: 'https://data.fixer.io/api/latest?access_key=0ced797dd1cc136b22d6cfee7e2d6476',
375
- headers: {},
376
- };
377
-
378
- axios
379
- .request(config)
380
- .then(async (response: any) => {
381
- await db.query(`insert into \`${saasConfig.SAAS_NAME}\`.currency_config (\`json\`,updated) values (?,?)`, [JSON.stringify(response.data), date_index]);
382
- setTimeout(() => this.currenciesUpdate(sec), sec * 1000);
383
- })
384
- .catch((error: any) => {
385
- console.error(error);
386
- setTimeout(() => this.currenciesUpdate(sec), sec * 1000);
387
- });
388
- } else {
389
- setTimeout(() => this.currenciesUpdate(sec), sec * 1000);
390
- console.log(`currenciesUpdate-Stop`,(new Date().getTime() - clock.getTime())/1000)
391
- }
355
+ setTimeout(() => this.autoSendLine(sec), sec * 1000);
356
+ console.log(`autoSendLine-Stop`, (new Date().getTime() - clock.getTime()) / 1000);
357
+ }
358
+
359
+ async initialSampleApp(sec: number) {
360
+ await new InitialFakeData('t_1725992531001').run();
361
+ setTimeout(() => this.initialSampleApp(sec), sec * 1000);
362
+ }
363
+
364
+ async currenciesUpdate(sec: number) {
365
+ const date = new Date();
366
+ const date_index = `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`;
367
+ let clock = new Date();
368
+ console.log(`currenciesUpdate-Start`);
369
+ if (
370
+ (
371
+ await db.query(
372
+ `select count(1) from \`${saasConfig.SAAS_NAME}\`.currency_config where updated='${date_index}'`,
373
+ []
374
+ )
375
+ )[0]['count(1)'] === 0
376
+ ) {
377
+ let config = {
378
+ method: 'get',
379
+ maxBodyLength: Infinity,
380
+ url: 'https://data.fixer.io/api/latest?access_key=0ced797dd1cc136b22d6cfee7e2d6476',
381
+ headers: {},
382
+ };
383
+
384
+ axios
385
+ .request(config)
386
+ .then(async (response: any) => {
387
+ await db.query(`insert into \`${saasConfig.SAAS_NAME}\`.currency_config (\`json\`,updated) values (?,?)`, [
388
+ JSON.stringify(response.data),
389
+ date_index,
390
+ ]);
391
+ setTimeout(() => this.currenciesUpdate(sec), sec * 1000);
392
+ })
393
+ .catch((error: any) => {
394
+ console.error(error);
395
+ setTimeout(() => this.currenciesUpdate(sec), sec * 1000);
396
+ });
397
+ } else {
398
+ setTimeout(() => this.currenciesUpdate(sec), sec * 1000);
399
+ console.log(`currenciesUpdate-Stop`, (new Date().getTime() - clock.getTime()) / 1000);
392
400
  }
393
-
394
- main() {
395
- const scheduleList: ScheduleItem[] = [
396
- // { second: 10, status: false, func: 'example', desc: '排程啟用範例' },
397
- { second: 3600, status: true, func: 'birthRebate', desc: '生日禮發放購物金' },
398
- { second: 3600, status: true, func: 'birthBlessMail', desc: '生日祝福信件' },
399
- { second: 600, status: true, func: 'renewMemberLevel', desc: '更新會員分級' },
400
- { second: 30, status: true, func: 'resetVoucherHistory', desc: '未付款歷史優惠券重設' },
401
- { second: 30, status: true, func: 'autoSendMail', desc: '自動排程寄送信件' },
402
- { second: 30, status: true, func: 'autoSendLine', desc: '自動排程寄送line訊息' },
403
- { second: 3600 * 24, status: true, func: 'currenciesUpdate', desc: '多國貨幣的更新排程' },
404
- // { second: 3600 * 24, status: false, func: 'initialSampleApp', desc: '重新刷新示範商店' },
405
- { second: 30, status: true, func: 'autoCancelOrder', desc: '自動取消未付款未出貨訂單' },
406
- ];
407
- try {
408
- scheduleList.forEach((schedule) => {
409
- if (schedule.status && typeof this[schedule.func] === 'function') {
410
- (this[schedule.func] as (sec: number) => void)(schedule.second);
411
- }
412
- });
413
- } catch (e) {
414
- throw exception.BadRequestError('BAD_REQUEST', 'Init Schedule Error: ' + e, null);
401
+ }
402
+
403
+ main() {
404
+ const scheduleList: ScheduleItem[] = [
405
+ // { second: 10, status: false, func: 'example', desc: '排程啟用範例' },
406
+ { second: 3600, status: true, func: 'birthRebate', desc: '生日禮發放購物金' },
407
+ { second: 3600, status: true, func: 'birthBlessMail', desc: '生日祝福信件' },
408
+ { second: 600, status: true, func: 'renewMemberLevel', desc: '更新會員分級' },
409
+ { second: 30, status: true, func: 'resetVoucherHistory', desc: '未付款歷史優惠券重設' },
410
+ { second: 30, status: true, func: 'autoSendMail', desc: '自動排程寄送信件' },
411
+ { second: 30, status: true, func: 'autoSendLine', desc: '自動排程寄送line訊息' },
412
+ { second: 3600 * 24, status: true, func: 'currenciesUpdate', desc: '多國貨幣的更新排程' },
413
+ // { second: 3600 * 24, status: false, func: 'initialSampleApp', desc: '重新刷新示範商店' },
414
+ { second: 30, status: true, func: 'autoCancelOrder', desc: '自動取消未付款未出貨訂單' },
415
+ ];
416
+ try {
417
+ scheduleList.forEach(schedule => {
418
+ if (schedule.status && typeof this[schedule.func] === 'function') {
419
+ (this[schedule.func] as (sec: number) => void)(schedule.second);
415
420
  }
421
+ });
422
+ } catch (e) {
423
+ throw exception.BadRequestError('BAD_REQUEST', 'Init Schedule Error: ' + e, null);
416
424
  }
425
+ }
417
426
  }