ts-glitter 21.2.3 → 21.2.4
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.
- package/lowcode/Entry.js +1 -1
- package/lowcode/Entry.ts +1 -1
- package/lowcode/glitter-base/global/global-user.js +7 -5
- package/lowcode/glitter-base/global/global-user.ts +6 -4
- package/package.json +1 -1
- package/src/api-public/services/data-analyze.d.ts +1 -1
- package/src/api-public/services/financial-service.d.ts +1 -0
- package/src/api-public/services/financial-service.js +52 -29
- package/src/api-public/services/financial-service.js.map +1 -1
- package/src/api-public/services/financial-service.ts +70 -33
- package/src/api-public/services/financial-serviceV2.js +7 -17
- package/src/api-public/services/financial-serviceV2.js.map +1 -1
- package/src/modules/firebase.js +83 -69
- package/src/modules/firebase.js.map +1 -1
- package/src/modules/firebase.ts +334 -292
package/src/modules/firebase.ts
CHANGED
|
@@ -1,334 +1,376 @@
|
|
|
1
|
-
import path from
|
|
2
|
-
import admin from
|
|
3
|
-
import {ConfigSetting} from
|
|
4
|
-
import db from
|
|
5
|
-
import {WebSocket} from
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import admin from 'firebase-admin';
|
|
3
|
+
import { ConfigSetting } from '../config';
|
|
4
|
+
import db from '../modules/database';
|
|
5
|
+
import { WebSocket } from '../services/web-socket.js';
|
|
6
6
|
import { CaughtError } from './caught-error.js';
|
|
7
7
|
import exception from './exception.js';
|
|
8
8
|
import { AutoSendEmail } from '../api-public/services/auto-send-email.js';
|
|
9
9
|
|
|
10
10
|
export class Firebase {
|
|
11
|
-
|
|
11
|
+
public app: string = '';
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
constructor(app: string) {
|
|
14
|
+
this.app = app;
|
|
15
|
+
}
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
17
|
+
public static async initial() {
|
|
18
|
+
console.log(
|
|
19
|
+
`fireBaseInitial:${admin.credential.cert(path.resolve(ConfigSetting.config_path, `../${process.env.firebase}`))}`
|
|
20
|
+
);
|
|
21
|
+
admin.initializeApp(
|
|
22
|
+
{
|
|
23
|
+
credential: admin.credential.cert(path.resolve(ConfigSetting.config_path, `../${process.env.firebase}`)),
|
|
24
|
+
},
|
|
25
|
+
'glitter'
|
|
26
|
+
);
|
|
27
|
+
admin.initializeApp({
|
|
28
|
+
credential: admin.credential.cert(path.resolve(ConfigSetting.config_path, `../${process.env.firebase}`)),
|
|
29
|
+
});
|
|
30
|
+
}
|
|
26
31
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
// 註冊 Android 應用
|
|
39
|
-
await admin
|
|
40
|
-
.projectManagement().createAndroidApp(cf.appID, cf.appName)
|
|
41
|
-
}
|
|
42
|
-
} catch (e) {
|
|
32
|
+
public static async appRegister(cf: { appID: string; appName: string; type: 'android' | 'ios' }) {
|
|
33
|
+
try {
|
|
34
|
+
if (cf.type === 'ios') {
|
|
35
|
+
// 註冊 iOS 應用
|
|
36
|
+
await admin.projectManagement().createIosApp(cf.appID, cf.appName);
|
|
37
|
+
} else {
|
|
38
|
+
// 註冊 Android 應用
|
|
39
|
+
await admin.projectManagement().createAndroidApp(cf.appID, cf.appName);
|
|
40
|
+
}
|
|
41
|
+
} catch (e) {}
|
|
42
|
+
}
|
|
43
43
|
|
|
44
|
+
public static async getConfig(cf: { appID: string; type: 'android' | 'ios'; appDomain: string }) {
|
|
45
|
+
try {
|
|
46
|
+
if (cf.type === 'ios') {
|
|
47
|
+
for (const b of await admin.projectManagement().listIosApps()) {
|
|
48
|
+
if ((await b.getMetadata()).bundleId === cf.appID) {
|
|
49
|
+
await b.setDisplayName(cf.appDomain);
|
|
50
|
+
return await b.getConfig();
|
|
51
|
+
}
|
|
44
52
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}) {
|
|
52
|
-
try {
|
|
53
|
-
if (cf.type === 'ios') {
|
|
54
|
-
for (const b of (await (admin
|
|
55
|
-
.projectManagement().listIosApps()))) {
|
|
56
|
-
if ((await b.getMetadata()).bundleId === cf.appID) {
|
|
57
|
-
await b.setDisplayName(cf.appDomain)
|
|
58
|
-
return (await b.getConfig())
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
} else {
|
|
62
|
-
for (const b of (await (admin
|
|
63
|
-
.projectManagement().listAndroidApps()))) {
|
|
64
|
-
if ((await b.getMetadata()).packageName === cf.appID) {
|
|
65
|
-
await b.setDisplayName(cf.appDomain)
|
|
66
|
-
return (await b.getConfig())
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
} catch (e) {
|
|
71
|
-
console.log(e)
|
|
72
|
-
return ''
|
|
53
|
+
} else {
|
|
54
|
+
for (const b of await admin.projectManagement().listAndroidApps()) {
|
|
55
|
+
if ((await b.getMetadata()).packageName === cf.appID) {
|
|
56
|
+
await b.setDisplayName(cf.appDomain);
|
|
57
|
+
return await b.getConfig();
|
|
58
|
+
}
|
|
73
59
|
}
|
|
60
|
+
}
|
|
61
|
+
} catch (e) {
|
|
62
|
+
console.log(e);
|
|
63
|
+
return '';
|
|
74
64
|
}
|
|
65
|
+
}
|
|
75
66
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
}
|
|
95
|
-
return new Promise(async (resolve, reject) => {
|
|
96
|
-
if (cf.userID) {
|
|
97
|
-
cf.token = (await db.query(`SELECT deviceToken
|
|
98
|
-
FROM \`${cf.app || this.app}\`.t_fcm
|
|
99
|
-
where userID = ?;`, [cf.userID])).map((dd: any) => {
|
|
100
|
-
return dd.deviceToken
|
|
101
|
-
});
|
|
102
|
-
const user_cf = (((await db.query(`select \`value\`
|
|
103
|
-
from \`${cf.app || this.app}\`.t_user_public_config
|
|
104
|
-
where \`key\` ='notify_setting' and user_id=?`, [cf.userID]))[0]) ?? {value: {}}).value;
|
|
105
|
-
if (`${user_cf[cf.tag]}` !== 'false') {
|
|
106
|
-
if (cf.userID && cf.tag && cf.title && cf.body && cf.link && !cf.pass_store) {
|
|
107
|
-
await db.query(`insert into \`${cf.app || this.app}\`.t_notice (user_id, tag, title, content, link)
|
|
108
|
-
values (?, ?, ?, ?, ?)`, [
|
|
109
|
-
cf.userID,
|
|
110
|
-
cf.tag,
|
|
111
|
-
cf.title,
|
|
112
|
-
cf.body,
|
|
113
|
-
cf.link
|
|
114
|
-
])
|
|
115
|
-
}
|
|
116
|
-
} else {
|
|
117
|
-
resolve(true)
|
|
118
|
-
return
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
}
|
|
122
|
-
if (typeof cf.token === 'string') {
|
|
123
|
-
cf.token = [cf.token]
|
|
124
|
-
}
|
|
125
|
-
if (Array.isArray(cf.token)) {
|
|
126
|
-
for (const token of cf.token) {
|
|
127
|
-
try {
|
|
128
|
-
admin.apps.find((dd) => {
|
|
129
|
-
return dd?.name === 'glitter'
|
|
130
|
-
})!.messaging().send({
|
|
131
|
-
notification: {
|
|
132
|
-
title: cf.title,
|
|
133
|
-
body: cf.body.replace(/<br>/g,''),
|
|
134
|
-
},
|
|
135
|
-
android: {
|
|
136
|
-
notification: {
|
|
137
|
-
sound: 'default'
|
|
138
|
-
},
|
|
139
|
-
},
|
|
140
|
-
apns: {
|
|
141
|
-
payload: {
|
|
142
|
-
aps: {
|
|
143
|
-
sound: 'default'
|
|
144
|
-
},
|
|
145
|
-
},
|
|
146
|
-
},
|
|
147
|
-
data: {
|
|
148
|
-
link: `${cf.link || ''}`
|
|
149
|
-
},
|
|
150
|
-
"token": token!
|
|
151
|
-
}).then((response: any) => {
|
|
152
|
-
|
|
153
|
-
console.log('成功發送推播:', response);
|
|
154
|
-
}).catch((error: any) => {
|
|
155
|
-
console.error('發送推播時發生錯誤:', error);
|
|
156
|
-
})
|
|
157
|
-
}catch (e:any) {
|
|
158
|
-
CaughtError.warning('fcm',`firebase->74`,`${e}`)
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
resolve(true)
|
|
164
|
-
})
|
|
165
|
-
|
|
67
|
+
public async sendMessage(cf: {
|
|
68
|
+
token?: string | string[];
|
|
69
|
+
userID?: string;
|
|
70
|
+
title: string;
|
|
71
|
+
tag: string;
|
|
72
|
+
link: string;
|
|
73
|
+
body: string;
|
|
74
|
+
app?: string;
|
|
75
|
+
pass_store?: boolean;
|
|
76
|
+
}) {
|
|
77
|
+
console.log('sendMessage', cf);
|
|
78
|
+
cf.body = cf.body.replace(/<br\s*\/?>/gi, '\n');
|
|
79
|
+
if (cf.userID) {
|
|
80
|
+
WebSocket.noticeChangeMem[cf.userID] &&
|
|
81
|
+
WebSocket.noticeChangeMem[cf.userID].map(d2 => {
|
|
82
|
+
d2.callback({
|
|
83
|
+
type: 'notice_count_change',
|
|
84
|
+
});
|
|
85
|
+
});
|
|
166
86
|
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
87
|
+
return new Promise(async (resolve, reject) => {
|
|
88
|
+
if (cf.userID) {
|
|
89
|
+
cf.token = (
|
|
90
|
+
await db.query(
|
|
91
|
+
`SELECT deviceToken
|
|
92
|
+
FROM \`${cf.app || this.app}\`.t_fcm
|
|
93
|
+
where userID = ?;`,
|
|
94
|
+
[cf.userID]
|
|
95
|
+
)
|
|
96
|
+
).map((dd: any) => {
|
|
97
|
+
return dd.deviceToken;
|
|
98
|
+
});
|
|
99
|
+
console.log(
|
|
100
|
+
`sendMessage:${cf.userID}`,
|
|
101
|
+
`SELECT deviceToken
|
|
102
|
+
FROM \`${cf.app || this.app}\`.t_fcm
|
|
103
|
+
where userID = ${db.escape(cf.userID)};`
|
|
104
|
+
);
|
|
105
|
+
const user_cf = (
|
|
106
|
+
(
|
|
107
|
+
await db.query(
|
|
108
|
+
`select \`value\`
|
|
109
|
+
from \`${cf.app || this.app}\`.t_user_public_config
|
|
110
|
+
where \`key\` = 'notify_setting'
|
|
111
|
+
and user_id = ?`,
|
|
112
|
+
[cf.userID]
|
|
113
|
+
)
|
|
114
|
+
)[0] ?? { value: {} }
|
|
115
|
+
).value;
|
|
116
|
+
if (`${user_cf[cf.tag]}` !== 'false') {
|
|
117
|
+
if (cf.userID && cf.tag && cf.title && cf.body && cf.link && !cf.pass_store) {
|
|
118
|
+
await db.query(
|
|
119
|
+
`insert into \`${cf.app || this.app}\`.t_notice (user_id, tag, title, content, link)
|
|
120
|
+
values (?, ?, ?, ?, ?)`,
|
|
121
|
+
[cf.userID, cf.tag, cf.title, cf.body, cf.link]
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
} else {
|
|
125
|
+
resolve(true);
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
if (typeof cf.token === 'string') {
|
|
130
|
+
cf.token = [cf.token];
|
|
131
|
+
}
|
|
132
|
+
if (Array.isArray(cf.token)) {
|
|
133
|
+
let error_token:string[]=[]
|
|
134
|
+
await Promise.all(
|
|
135
|
+
cf.token.map(token => {
|
|
136
|
+
return new Promise(async (resolve, reject) => {
|
|
137
|
+
try {
|
|
138
|
+
admin.apps
|
|
139
|
+
.find(dd => {
|
|
140
|
+
return dd?.name === 'glitter';
|
|
141
|
+
})!
|
|
142
|
+
.messaging()
|
|
143
|
+
.send({
|
|
144
|
+
notification: {
|
|
145
|
+
title: cf.title,
|
|
146
|
+
body: cf.body.replace(/<br>/g, ''),
|
|
147
|
+
},
|
|
148
|
+
android: {
|
|
149
|
+
notification: {
|
|
150
|
+
sound: 'default',
|
|
185
151
|
},
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
`INSERT INTO \`${this.app}\`.\`t_triggers\`
|
|
193
|
-
SET ?;`,
|
|
194
|
-
[
|
|
195
|
-
{
|
|
196
|
-
tag: 'sendFCM',
|
|
197
|
-
content: JSON.stringify(data),
|
|
198
|
-
trigger_time: formatDateTime(),
|
|
199
|
-
status: 1,
|
|
152
|
+
},
|
|
153
|
+
apns: {
|
|
154
|
+
payload: {
|
|
155
|
+
aps: {
|
|
156
|
+
sound: 'default',
|
|
157
|
+
},
|
|
200
158
|
},
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
159
|
+
},
|
|
160
|
+
data: {
|
|
161
|
+
link: `${cf.link || ''}`,
|
|
162
|
+
},
|
|
163
|
+
token: token!,
|
|
164
|
+
})
|
|
165
|
+
.then((response: any) => {
|
|
166
|
+
console.log(`成功發送推播:${token}`, response);
|
|
167
|
+
resolve(true);
|
|
168
|
+
})
|
|
169
|
+
.catch((error: any) => {
|
|
170
|
+
if (error.errorInfo.code === 'messaging/registration-token-not-registered') {
|
|
171
|
+
error_token.push(token)
|
|
172
|
+
}
|
|
173
|
+
resolve(true);
|
|
174
|
+
});
|
|
175
|
+
} catch (e: any) {
|
|
176
|
+
CaughtError.warning('fcm', `firebase->74`, `${e}`);
|
|
177
|
+
resolve(true);
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
})
|
|
181
|
+
);
|
|
182
|
+
if(error_token.length>0){
|
|
183
|
+
await db.query(
|
|
184
|
+
`delete
|
|
185
|
+
FROM \`${cf.app || this.app}\`.t_fcm
|
|
186
|
+
where userID = ? and deviceToken in (${error_token.map(d=>db.escape(d)).join(',')});`,
|
|
187
|
+
[cf.userID]
|
|
188
|
+
);
|
|
208
189
|
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
let msgid = '';
|
|
214
|
-
for (const b of chunkArray(Array.from(new Set(data.userList.map((dd:any)=>{
|
|
215
|
-
return dd.id
|
|
216
|
-
}))), 10)) {
|
|
217
|
-
let check = b.length;
|
|
190
|
+
}
|
|
191
|
+
resolve(true);
|
|
192
|
+
});
|
|
193
|
+
}
|
|
218
194
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
tag:'promote',
|
|
226
|
-
link:data.link,
|
|
227
|
-
})
|
|
228
|
-
// this.sendMessage({ data: data.content, phone: d, date: date }, res => {
|
|
229
|
-
// check--;
|
|
230
|
-
// console.log(' res -- ', res);
|
|
231
|
-
// if (check === 0) {
|
|
232
|
-
// db.query(
|
|
233
|
-
// `UPDATE \`${this.app}\`.t_triggers
|
|
234
|
-
// SET status = ${date ? 0 : 1},
|
|
235
|
-
// content = JSON_SET(content, '$.name', '${res.msgid}')
|
|
236
|
-
// WHERE id = ?;`,
|
|
237
|
-
// [id]
|
|
238
|
-
// );
|
|
239
|
-
// resolve(true);
|
|
240
|
-
// }
|
|
241
|
-
// });
|
|
242
|
-
}
|
|
243
|
-
});
|
|
244
|
-
}
|
|
245
|
-
// await db.query(`UPDATE \`${this.app}\`.t_triggers SET status = ${date?0:1} , content = JSON_SET(content, '$.name', '變數A') WHERE id = ?;`, [ id]);
|
|
246
|
-
// await db.query(`-- UPDATE \`${this.app}\`.t_triggers SET ? WHERE id = ?;`, [{ status: 1 , content : `JSON_SET(content, '$.name', '變數A')`}, id]);
|
|
247
|
-
} catch (e) {
|
|
248
|
-
throw exception.BadRequestError('BAD_REQUEST', 'chunkSendSns Error:' + e, null);
|
|
195
|
+
async postFCM(data: any): Promise<{ result: boolean; message: string }> {
|
|
196
|
+
data.msgid = '';
|
|
197
|
+
try {
|
|
198
|
+
if (Boolean(data.sendTime)) {
|
|
199
|
+
if (isLater(data.sendTime)) {
|
|
200
|
+
return { result: false, message: '排定發送的時間需大於現在時間' };
|
|
249
201
|
}
|
|
202
|
+
const insertData = await db.query(
|
|
203
|
+
`INSERT INTO \`${this.app}\`.\`t_triggers\`
|
|
204
|
+
SET ?;`,
|
|
205
|
+
[
|
|
206
|
+
{
|
|
207
|
+
tag: 'sendFCM',
|
|
208
|
+
content: JSON.stringify(data),
|
|
209
|
+
trigger_time: formatDateTime(data.sendTime),
|
|
210
|
+
status: 0,
|
|
211
|
+
},
|
|
212
|
+
]
|
|
213
|
+
);
|
|
214
|
+
|
|
215
|
+
this.chunkSendFcm(data, insertData.insertId, formatDateTime(data.sendTime));
|
|
216
|
+
} else {
|
|
217
|
+
const insertData = await db.query(
|
|
218
|
+
`INSERT INTO \`${this.app}\`.\`t_triggers\`
|
|
219
|
+
SET ?;`,
|
|
220
|
+
[
|
|
221
|
+
{
|
|
222
|
+
tag: 'sendFCM',
|
|
223
|
+
content: JSON.stringify(data),
|
|
224
|
+
trigger_time: formatDateTime(),
|
|
225
|
+
status: 1,
|
|
226
|
+
},
|
|
227
|
+
]
|
|
228
|
+
);
|
|
229
|
+
this.chunkSendFcm(data, insertData.insertId);
|
|
230
|
+
}
|
|
231
|
+
return { result: true, message: '寄送成功' };
|
|
232
|
+
} catch (e) {
|
|
233
|
+
throw exception.BadRequestError('BAD_REQUEST', 'postMail Error:' + e, null);
|
|
250
234
|
}
|
|
235
|
+
}
|
|
251
236
|
|
|
237
|
+
async chunkSendFcm(data: any, id: number, date?: string) {
|
|
238
|
+
try {
|
|
239
|
+
let msgid = '';
|
|
240
|
+
for (const b of chunkArray(
|
|
241
|
+
Array.from(
|
|
242
|
+
new Set(
|
|
243
|
+
data.userList.map((dd: any) => {
|
|
244
|
+
return dd.id;
|
|
245
|
+
})
|
|
246
|
+
)
|
|
247
|
+
),
|
|
248
|
+
10
|
|
249
|
+
)) {
|
|
250
|
+
let check = b.length;
|
|
252
251
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
252
|
+
await new Promise(resolve => {
|
|
253
|
+
for (const d of b) {
|
|
254
|
+
this.sendMessage({
|
|
255
|
+
userID: d as string,
|
|
256
|
+
title: data.title,
|
|
257
|
+
body: data.content,
|
|
258
|
+
tag: 'promote',
|
|
259
|
+
link: data.link,
|
|
260
|
+
});
|
|
261
|
+
// this.sendMessage({ data: data.content, phone: d, date: date }, res => {
|
|
262
|
+
// check--;
|
|
263
|
+
// console.log(' res -- ', res);
|
|
264
|
+
// if (check === 0) {
|
|
265
|
+
// db.query(
|
|
266
|
+
// `UPDATE \`${this.app}\`.t_triggers
|
|
267
|
+
// SET status = ${date ? 0 : 1},
|
|
268
|
+
// content = JSON_SET(content, '$.name', '${res.msgid}')
|
|
269
|
+
// WHERE id = ?;`,
|
|
270
|
+
// [id]
|
|
271
|
+
// );
|
|
272
|
+
// resolve(true);
|
|
273
|
+
// }
|
|
274
|
+
// });
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
// await db.query(`UPDATE \`${this.app}\`.t_triggers SET status = ${date?0:1} , content = JSON_SET(content, '$.name', '變數A') WHERE id = ?;`, [ id]);
|
|
279
|
+
// await db.query(`-- UPDATE \`${this.app}\`.t_triggers SET ? WHERE id = ?;`, [{ status: 1 , content : `JSON_SET(content, '$.name', '變數A')`}, id]);
|
|
280
|
+
} catch (e) {
|
|
281
|
+
throw exception.BadRequestError('BAD_REQUEST', 'chunkSendSns Error:' + e, null);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
267
284
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
285
|
+
async getFCM(query: {
|
|
286
|
+
type: string;
|
|
287
|
+
page: number;
|
|
288
|
+
limit: number;
|
|
289
|
+
search?: string;
|
|
290
|
+
searchType?: string;
|
|
291
|
+
mailType?: string;
|
|
292
|
+
status?: string;
|
|
293
|
+
}) {
|
|
294
|
+
try {
|
|
295
|
+
const whereList: string[] = ['1 = 1'];
|
|
296
|
+
switch (query.searchType) {
|
|
297
|
+
case 'email':
|
|
298
|
+
// whereList.push(`(JSON_SEARCH(content->'$.email', 'one', '%${query.search ?? ''}%', NULL, '$[*]') IS NOT NULL)`);
|
|
299
|
+
break;
|
|
300
|
+
case 'name':
|
|
301
|
+
whereList.push(`(UPPER(JSON_EXTRACT(content, '$.name')) LIKE UPPER('%${query.search ?? ''}%'))`);
|
|
302
|
+
break;
|
|
303
|
+
case 'title':
|
|
304
|
+
whereList.push(`(UPPER(JSON_EXTRACT(content, '$.title')) LIKE UPPER('%${query.search ?? ''}%'))`);
|
|
305
|
+
break;
|
|
306
|
+
}
|
|
271
307
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
}
|
|
308
|
+
if (query.status) {
|
|
309
|
+
whereList.push(`(status in (${query.status}))`);
|
|
310
|
+
}
|
|
276
311
|
|
|
277
|
-
|
|
312
|
+
if (query.mailType) {
|
|
313
|
+
const maiTypeString = query.mailType.replace(/[^,]+/g, "'$&'");
|
|
314
|
+
whereList.push(`(JSON_EXTRACT(content, '$.type') in (${maiTypeString}))`);
|
|
315
|
+
}
|
|
278
316
|
|
|
317
|
+
const whereSQL = `(tag = 'sendFCM') AND ${whereList.join(' AND ')}`;
|
|
279
318
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
319
|
+
const emails = await db.query(
|
|
320
|
+
`SELECT *
|
|
321
|
+
FROM \`${this.app}\`.t_triggers
|
|
322
|
+
WHERE ${whereSQL}
|
|
323
|
+
ORDER BY id DESC
|
|
324
|
+
${query.type === 'download' ? '' : `LIMIT ${query.page * query.limit}, ${query.limit}`};`,
|
|
325
|
+
[]
|
|
326
|
+
);
|
|
287
327
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
328
|
+
const total = await db.query(
|
|
329
|
+
`SELECT count(id) as c
|
|
330
|
+
FROM \`${this.app}\`.t_triggers
|
|
331
|
+
WHERE ${whereSQL};`,
|
|
332
|
+
[]
|
|
333
|
+
);
|
|
293
334
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
}
|
|
335
|
+
for (const email of emails) {
|
|
336
|
+
email.content.typeName = '手動發送';
|
|
337
|
+
}
|
|
338
|
+
return { data: emails, total: total[0].c };
|
|
339
|
+
} catch (e) {
|
|
340
|
+
throw exception.BadRequestError('BAD_REQUEST', 'getMail Error:' + e, null);
|
|
301
341
|
}
|
|
342
|
+
}
|
|
302
343
|
}
|
|
303
344
|
|
|
304
345
|
function isLater(dateTimeObj: { date: string; time: string }) {
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
346
|
+
const currentDateTime = new Date();
|
|
347
|
+
const { date, time } = dateTimeObj;
|
|
348
|
+
const dateTimeString = `${date}T${time}:00`;
|
|
349
|
+
const providedDateTime = new Date(dateTimeString);
|
|
350
|
+
return currentDateTime > providedDateTime;
|
|
310
351
|
}
|
|
311
352
|
|
|
312
353
|
function chunkArray(array: any, groupSize: number) {
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
354
|
+
const result = [];
|
|
355
|
+
for (let i = 0; i < array.length; i += groupSize) {
|
|
356
|
+
result.push(array.slice(i, i + groupSize));
|
|
357
|
+
}
|
|
358
|
+
return result;
|
|
318
359
|
}
|
|
360
|
+
|
|
319
361
|
function formatDate(date: any) {
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
362
|
+
const year = date.getFullYear();
|
|
363
|
+
const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
364
|
+
const day = String(date.getDate()).padStart(2, '0');
|
|
365
|
+
const hours = String(date.getHours()).padStart(2, '0');
|
|
366
|
+
const minutes = String(date.getMinutes()).padStart(2, '0');
|
|
367
|
+
const seconds = String(date.getSeconds()).padStart(2, '0');
|
|
326
368
|
|
|
327
|
-
|
|
369
|
+
return `${year}${month}${day}${hours}${minutes}${seconds}`;
|
|
328
370
|
}
|
|
329
371
|
|
|
330
372
|
function formatDateTime(sendTime?: { date: string; time: string }) {
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
}
|
|
373
|
+
const dateTimeString = sendTime ? sendTime.date + ' ' + sendTime.time : undefined;
|
|
374
|
+
const dateObject = dateTimeString ? new Date(dateTimeString) : new Date();
|
|
375
|
+
return formatDate(dateObject);
|
|
376
|
+
}
|