ts-glitter 16.2.4 → 16.2.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.
- package/lowcode/Entry.js +1 -1
- package/lowcode/Entry.ts +1 -1
- package/lowcode/glitter-base/global/currency.d.ts +19 -0
- package/lowcode/glitter-base/global/currency.js.map +1 -0
- package/lowcode/glitter-base/global/global-user.d.ts +5 -0
- package/lowcode/glitter-base/global/global-user.js.map +1 -1
- package/lowcode/glitter-base/global/language.d.ts +22 -0
- package/lowcode/glitter-base/global/language.js.map +1 -0
- package/lowcode/glitter-base/route/shopping.d.ts +28 -2
- package/lowcode/glitter-base/route/shopping.js.map +1 -1
- package/lowcode/glitterBundle/api/base.js.map +1 -1
- package/package.json +5 -2
- package/src/api-public/services/shopping.d.ts +1 -1
- package/src/api-public/services/shopping.js +1 -0
- package/src/api-public/services/shopping.js.map +1 -1
- package/src/api-public/services/shopping.ts +1 -0
- package/src/helper/glitter-util.d.ts +4 -2
- package/src/helper/glitter-util.js +20 -11
- package/src/helper/glitter-util.js.map +1 -1
- package/src/helper/glitter-util.ts +22 -12
- package/src/index.js +255 -433
- package/src/index.js.map +1 -1
- package/src/index.ts +246 -441
- package/src/seo-config.d.ts +40 -0
- package/src/seo-config.js +303 -0
- package/src/seo-config.js.map +1 -0
- package/src/seo-config.ts +357 -0
package/src/index.ts
CHANGED
|
@@ -10,6 +10,7 @@ import contollers = require('./controllers');
|
|
|
10
10
|
import public_contollers = require('./api-public/controllers');
|
|
11
11
|
import database from './modules/database';
|
|
12
12
|
import {SaasScheme} from './services/saas-table-check';
|
|
13
|
+
|
|
13
14
|
import db from './modules/database';
|
|
14
15
|
import {createBucket, listBuckets} from './modules/AWSLib';
|
|
15
16
|
import {Live_source} from './live_source';
|
|
@@ -41,6 +42,7 @@ import {Manager} from "./api-public/services/manager.js";
|
|
|
41
42
|
import {SitemapStream, streamToPromise} from "sitemap";
|
|
42
43
|
import {Readable} from "stream";
|
|
43
44
|
import AWS from "aws-sdk";
|
|
45
|
+
import {extractCols, extractProds, SeoConfig} from "./seo-config.js";
|
|
44
46
|
|
|
45
47
|
export const app = express();
|
|
46
48
|
const logger = new Logger();
|
|
@@ -122,80 +124,10 @@ async function createAppRoute() {
|
|
|
122
124
|
}
|
|
123
125
|
}
|
|
124
126
|
|
|
125
|
-
function extractCols(data: {
|
|
126
|
-
value: {
|
|
127
|
-
code: string;
|
|
128
|
-
array: { code: string }[];
|
|
129
|
-
}[];
|
|
130
|
-
updated_at: Date;
|
|
131
|
-
}) {
|
|
132
|
-
const items: any = [];
|
|
133
|
-
const updated_at = new Date(data.updated_at).toISOString().replace(/\.\d{3}Z$/, '+00:00');
|
|
134
|
-
data.value.map((item: any) => {
|
|
135
|
-
items.push({
|
|
136
|
-
code: item.code,
|
|
137
|
-
updated_at,
|
|
138
|
-
seo_title: item.seo_title,
|
|
139
|
-
seo_image: item.seo_image,
|
|
140
|
-
seo_content: item.seo_content,
|
|
141
|
-
});
|
|
142
|
-
if (item.array && item.array.length > 0) {
|
|
143
|
-
item.array.map((child: any) => {
|
|
144
|
-
items.push({
|
|
145
|
-
code: child.code,
|
|
146
|
-
updated_at,
|
|
147
|
-
seo_title: child.seo_title,
|
|
148
|
-
seo_image: child.seo_image,
|
|
149
|
-
seo_content: child.seo_content,
|
|
150
|
-
});
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
});
|
|
154
|
-
return items;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
function extractProds(data: any) {
|
|
158
|
-
const items: any = [];
|
|
159
|
-
data.map((item: any) => {
|
|
160
|
-
const code = (() => {
|
|
161
|
-
try {
|
|
162
|
-
return item.content.seo.domain;
|
|
163
|
-
} catch (error) {
|
|
164
|
-
return '';
|
|
165
|
-
}
|
|
166
|
-
})();
|
|
167
|
-
const updated_at = new Date(item.updated_time).toISOString().replace(/\.\d{3}Z$/, '+00:00');
|
|
168
|
-
items.push({code, updated_at});
|
|
169
|
-
});
|
|
170
|
-
return items;
|
|
171
|
-
}
|
|
172
127
|
|
|
173
128
|
// 信任代理
|
|
174
129
|
app.set('trust proxy', true);
|
|
175
130
|
|
|
176
|
-
// 判斷現在時間是否在 start 和 end 之間的函數
|
|
177
|
-
function isCurrentTimeWithinRange(data: {
|
|
178
|
-
startDate: string;
|
|
179
|
-
startTime: string;
|
|
180
|
-
endDate?: string;
|
|
181
|
-
endTime?: string
|
|
182
|
-
}): boolean {
|
|
183
|
-
const now = new Date();
|
|
184
|
-
now.setTime(now.getTime() + 8 * 3600 * 1000);
|
|
185
|
-
// 組合 start 的完整日期時間
|
|
186
|
-
const startDateTime = new Date(`${data.startDate}T${data.startTime}`);
|
|
187
|
-
|
|
188
|
-
// 若 endDate 或 endTime 為 undefined,視為無期限
|
|
189
|
-
const hasEnd = data.endDate && data.endTime;
|
|
190
|
-
const endDateTime = hasEnd ? new Date(`${data.endDate}T${data.endTime}`) : null;
|
|
191
|
-
|
|
192
|
-
// 判斷現在時間是否在範圍內
|
|
193
|
-
if (hasEnd) {
|
|
194
|
-
return now >= startDateTime && now <= endDateTime!;
|
|
195
|
-
} else {
|
|
196
|
-
return now >= startDateTime;
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
131
|
|
|
200
132
|
export async function createAPP(dd: any) {
|
|
201
133
|
const html = String.raw;
|
|
@@ -222,8 +154,18 @@ export async function createAPP(dd: any) {
|
|
|
222
154
|
req.headers['g-app'] = appName;
|
|
223
155
|
const start = new Date().getTime();
|
|
224
156
|
console.log(`getPageInfo==>`, (new Date().getTime() - start) / 1000);
|
|
225
|
-
|
|
226
|
-
let [
|
|
157
|
+
//SEO內容
|
|
158
|
+
let seo_content: string[] = []
|
|
159
|
+
let [
|
|
160
|
+
customCode,
|
|
161
|
+
FBCode,
|
|
162
|
+
store_info,
|
|
163
|
+
language_label,
|
|
164
|
+
check_schema,
|
|
165
|
+
brandAndMemberType,
|
|
166
|
+
login_config,
|
|
167
|
+
ip_country
|
|
168
|
+
] = await Promise.all([new User(appName).getConfigV2({
|
|
227
169
|
key: 'ga4_config',
|
|
228
170
|
user_id: 'manager',
|
|
229
171
|
}), new User(appName).getConfigV2({
|
|
@@ -235,57 +177,20 @@ export async function createAPP(dd: any) {
|
|
|
235
177
|
}), new User(appName).getConfigV2({
|
|
236
178
|
key: 'language-label',
|
|
237
179
|
user_id: 'manager',
|
|
238
|
-
})
|
|
180
|
+
}), ApiPublic.createScheme(appName),
|
|
181
|
+
App.checkBrandAndMemberType(appName), new User(req.get('g-app') as string, req.body.token).getConfigV2({
|
|
182
|
+
key: 'login_config',
|
|
183
|
+
user_id: 'manager',
|
|
184
|
+
}), User.ipInfo((req.query.ip || req.headers['x-real-ip'] || req.ip) as string)])
|
|
239
185
|
//取得多國語言
|
|
240
|
-
const language = (
|
|
241
|
-
function checkIncludes(lan: string) {
|
|
242
|
-
return store_info.language_setting.support.includes(lan);
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
function checkEqual(lan: string) {
|
|
246
|
-
return `${req.query.page}`.startsWith(`${lan}/`) || req.query.page === lan;
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
function replace(lan: string) {
|
|
250
|
-
if (req.query.page === lan) {
|
|
251
|
-
req.query.page = '';
|
|
252
|
-
} else {
|
|
253
|
-
req.query.page = `${req.query.page}`.replace(lan + '/', '');
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
if (checkEqual('en') && checkIncludes('en-US')) {
|
|
258
|
-
replace('en');
|
|
259
|
-
return `en-US`;
|
|
260
|
-
} else if (checkEqual('cn') && checkIncludes('zh-CN')) {
|
|
261
|
-
replace('cn');
|
|
262
|
-
return `zh-CN`;
|
|
263
|
-
} else if (checkEqual('tw') && checkIncludes('zh-TW')) {
|
|
264
|
-
replace('tw');
|
|
265
|
-
return `zh-TW`;
|
|
266
|
-
} else {
|
|
267
|
-
return store_info.language_setting.def;
|
|
268
|
-
}
|
|
269
|
-
})();
|
|
270
|
-
console.log(`req.query.page===>`, req.query.page);
|
|
186
|
+
const language: any = await SeoConfig.language(store_info, req)
|
|
271
187
|
//插入瀏覽紀錄
|
|
272
188
|
Monitor.insertHistory({
|
|
273
189
|
req_type: 'file',
|
|
274
190
|
req: req,
|
|
275
191
|
});
|
|
276
|
-
console.log(`
|
|
277
|
-
|
|
278
|
-
await ApiPublic.createScheme(appName);
|
|
279
|
-
console.log(`createScheme==>`, (new Date().getTime() - start) / 1000);
|
|
280
|
-
//確認SAAS用戶資訊
|
|
281
|
-
const brandAndMemberType = await App.checkBrandAndMemberType(appName);
|
|
282
|
-
console.log(`brandAndMemberType==>`, (new Date().getTime() - start) / 1000);
|
|
283
|
-
//取得Login config
|
|
284
|
-
const login_config = await new User(req.get('g-app') as string, req.body.token).getConfigV2({
|
|
285
|
-
key: 'login_config',
|
|
286
|
-
user_id: 'manager',
|
|
287
|
-
});
|
|
288
|
-
//取得頁面資訊
|
|
192
|
+
console.log(`req.query.page==>`, req.query.page)
|
|
193
|
+
//取得SEO頁面資訊
|
|
289
194
|
let data = await Seo.getPageInfo(appName, req.query.page as string, language);
|
|
290
195
|
//首頁SEO
|
|
291
196
|
let home_page_data = await (async () => {
|
|
@@ -295,61 +200,34 @@ export async function createAPP(dd: any) {
|
|
|
295
200
|
return await Seo.getPageInfo(appName, 'index', language);
|
|
296
201
|
}
|
|
297
202
|
})();
|
|
203
|
+
console.log(`req.query.page==>`, req.query.page)
|
|
298
204
|
if (data && data.page_config) {
|
|
299
205
|
data.page_config = data.page_config ?? {};
|
|
300
206
|
const d = data.page_config.seo ?? {};
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
)
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
data.page_config.seo.title = productSeo.title;
|
|
326
|
-
data.page_config.seo.image = pd.data.content.preview_image[0];
|
|
327
|
-
data.page_config.seo.content = productSeo.content;
|
|
328
|
-
} else {
|
|
329
|
-
data = await Seo.getPageInfo(appName, data.config.homePage, language);
|
|
330
|
-
}
|
|
331
|
-
} else if (data.page_type === 'article' && data.page_config.template_type === 'blog') {
|
|
332
|
-
req.query.article = req.query.article || (req.query.page as any).split('/')[1];
|
|
333
|
-
let query = [`(content->>'$.type'='article')`, `(content->>'$.tag'='${req.query.article}')`];
|
|
334
|
-
const article: any = await new UtDatabase(appName, `t_manager_post`).querySql(query, {
|
|
335
|
-
page: 0,
|
|
336
|
-
limit: 1,
|
|
337
|
-
});
|
|
338
|
-
data = await Seo.getPageInfo(appName, data.config.homePage, language);
|
|
339
|
-
data.page_config = data.page_config ?? {};
|
|
340
|
-
data.page_config.seo = data.page_config.seo ?? {};
|
|
341
|
-
if (article.data[0]) {
|
|
342
|
-
if (article.data[0].content.language_data && article.data[0].content.language_data[language]) {
|
|
343
|
-
data.page_config.seo.title = article.data[0].content.language_data[language].seo.title;
|
|
344
|
-
data.page_config.seo.content = article.data[0].content.language_data[language].seo.content;
|
|
345
|
-
data.page_config.seo.keywords = article.data[0].content.language_data[language].seo.keywords;
|
|
346
|
-
} else {
|
|
347
|
-
data.page_config.seo.title = article.data[0].content.seo.title;
|
|
348
|
-
data.page_config.seo.content = article.data[0].content.seo.content;
|
|
349
|
-
data.page_config.seo.keywords = article.data[0].content.seo.keywords;
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
}
|
|
207
|
+
console.log(`req.query.page`)
|
|
208
|
+
//商品搜索
|
|
209
|
+
if (`${req.query.page}`.startsWith('products/')) {
|
|
210
|
+
await SeoConfig.productSEO({
|
|
211
|
+
data,
|
|
212
|
+
language,
|
|
213
|
+
appName,
|
|
214
|
+
product_id: req.query.product_id as any,
|
|
215
|
+
page: (req.query.page) as any
|
|
216
|
+
})
|
|
217
|
+
} else if (`${req.query.page}`.startsWith('blogs/')) {
|
|
218
|
+
//網誌搜索
|
|
219
|
+
await SeoConfig.articleSeo({
|
|
220
|
+
article: req.query.article as any,
|
|
221
|
+
page: req.query.page as any,
|
|
222
|
+
language, appName, data
|
|
223
|
+
})
|
|
224
|
+
} else if (`${req.query.page}`.startsWith('pages/')) {
|
|
225
|
+
//頁面搜索
|
|
226
|
+
await SeoConfig.articleSeo({
|
|
227
|
+
article: req.query.article as any,
|
|
228
|
+
page: req.query.page as any,
|
|
229
|
+
language, appName, data
|
|
230
|
+
})
|
|
353
231
|
} else if (d.type !== 'custom') {
|
|
354
232
|
data = home_page_data;
|
|
355
233
|
}
|
|
@@ -380,183 +258,119 @@ export async function createAPP(dd: any) {
|
|
|
380
258
|
localStorage.setItem('distributionCode','');
|
|
381
259
|
`;
|
|
382
260
|
}
|
|
261
|
+
//分銷連結頁面SEO
|
|
383
262
|
if ((req.query.page as string).split('/')[0] === 'distribution' && (req.query.page as string).split('/')[1]) {
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
);
|
|
393
|
-
const page = rec[0] && rec[0].content ? rec[0].content : {status: false};
|
|
394
|
-
|
|
395
|
-
if (page.status && isCurrentTimeWithinRange(page)) {
|
|
396
|
-
let query = [`(content->>'$.type'='article')`, `(content->>'$.tag'='${page.redirect.split('/')[2]}')`];
|
|
397
|
-
const article: any = await new UtDatabase(appName, `t_manager_post`).querySql(query, {
|
|
398
|
-
page: 0,
|
|
399
|
-
limit: 1,
|
|
400
|
-
});
|
|
401
|
-
data = await Seo.getPageInfo(appName, data.config.homePage, language);
|
|
402
|
-
data.page_config = data.page_config ?? {};
|
|
403
|
-
data.page_config.seo = data.page_config.seo ?? {};
|
|
404
|
-
if (article.data[0]) {
|
|
405
|
-
if (article.data[0].content.language_data[language]) {
|
|
406
|
-
data.page_config.seo.title = article.data[0].content.language_data[language].seo.title;
|
|
407
|
-
data.page_config.seo.content = article.data[0].content.language_data[language].seo.content;
|
|
408
|
-
data.page_config.seo.keywords = article.data[0].content.language_data[language].seo.keywords;
|
|
409
|
-
} else {
|
|
410
|
-
data.page_config.seo.title = article.data[0].content.seo.title;
|
|
411
|
-
data.page_config.seo.content = article.data[0].content.seo.content;
|
|
412
|
-
data.page_config.seo.keywords = article.data[0].content.seo.keywords;
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
}
|
|
416
|
-
distribution_code = `
|
|
417
|
-
localStorage.setItem('distributionCode','${page.code}');
|
|
418
|
-
location.href = '${link_prefix ? `/` : ``}${link_prefix}${page.redirect}${redURL.search}';
|
|
419
|
-
`;
|
|
420
|
-
} else {
|
|
421
|
-
distribution_code = `
|
|
422
|
-
location.href = '/';
|
|
423
|
-
`;
|
|
424
|
-
}
|
|
263
|
+
distribution_code = await SeoConfig.distributionSEO({
|
|
264
|
+
appName: appName,
|
|
265
|
+
url: req.url,
|
|
266
|
+
page: req.query.page as string,
|
|
267
|
+
link_prefix: link_prefix,
|
|
268
|
+
data,
|
|
269
|
+
language
|
|
270
|
+
})
|
|
425
271
|
}
|
|
272
|
+
//分類頁面SEO
|
|
426
273
|
if ((req.query.page as string).split('/')[0] === 'collections' && (req.query.page as string).split('/')[1]) {
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
language: language,
|
|
433
|
-
})
|
|
434
|
-
)[0] ?? {};
|
|
435
|
-
const colJson = extractCols(cols);
|
|
436
|
-
const urlCode = decodeURI((req.query.page as string).split('/')[1]);
|
|
437
|
-
const colData = colJson.find((item: { code: string }) => item.code === urlCode);
|
|
438
|
-
if (colData) {
|
|
439
|
-
data.page_config.seo.title = colData.seo_title;
|
|
440
|
-
data.page_config.seo.content = colData.seo_content;
|
|
441
|
-
data.page_config.seo.keywords = colData.seo_keywords;
|
|
442
|
-
}
|
|
274
|
+
await SeoConfig.collectionSeo({appName, language, data, page: req.query.page as string})
|
|
275
|
+
}
|
|
276
|
+
//FB像素
|
|
277
|
+
if (FBCode) {
|
|
278
|
+
seo_content.push(SeoConfig.fbCode(FBCode))
|
|
443
279
|
}
|
|
444
|
-
return
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
${d.code ?? ''}
|
|
506
|
-
${(() => {
|
|
507
|
-
if (req.query.type === 'editor') {
|
|
508
|
-
return ``;
|
|
509
|
-
} else {
|
|
510
|
-
return `${(data.config.globalStyle ?? [])
|
|
511
|
-
.map((dd: any) => {
|
|
512
|
-
try {
|
|
513
|
-
if (dd.data.elem === 'link') {
|
|
514
|
-
return html`
|
|
515
|
-
<link
|
|
516
|
-
type="text/css"
|
|
517
|
-
rel="stylesheet"
|
|
518
|
-
href="${dd.data.attr.find((dd: any) => {
|
|
519
|
-
return dd.attr === 'href';
|
|
520
|
-
}).value}"
|
|
521
|
-
/>`;
|
|
522
|
-
}
|
|
523
|
-
} catch (e) {
|
|
524
|
-
return ``;
|
|
525
|
-
}
|
|
526
|
-
})
|
|
527
|
-
.join('')}`;
|
|
528
|
-
}
|
|
529
|
-
})()}
|
|
530
|
-
</head>
|
|
280
|
+
return {
|
|
281
|
+
head: (() => {
|
|
282
|
+
const d = data.page_config.seo;
|
|
283
|
+
const home_seo = home_page_data.page_config.seo;
|
|
284
|
+
return html`
|
|
285
|
+
${(() => {
|
|
286
|
+
if (req.query.type === 'editor') {
|
|
287
|
+
return SeoConfig.editorSeo;
|
|
288
|
+
} else {
|
|
289
|
+
return html`<title>${d.title || '尚未設定標題'}</title>
|
|
290
|
+
<link
|
|
291
|
+
rel="canonical"
|
|
292
|
+
href="${(() => {
|
|
293
|
+
if (data.tag === 'index') {
|
|
294
|
+
return `https://${brandAndMemberType.domain}`;
|
|
295
|
+
} else {
|
|
296
|
+
return `https://${brandAndMemberType.domain}/${data.tag}`;
|
|
297
|
+
}
|
|
298
|
+
})()}"
|
|
299
|
+
/>
|
|
300
|
+
${data.tag !== req.query.page ? `<meta name="robots" content="noindex">` : `<meta name="robots" content="index, follow"/>`}
|
|
301
|
+
<meta name="keywords"
|
|
302
|
+
content="${(d.keywords || '尚未設定關鍵字').replace(/"/g, '"')}"/>
|
|
303
|
+
<link id="appImage" rel="shortcut icon"
|
|
304
|
+
href="${d.logo || home_seo.logo || ''}" type="image/x-icon"/>
|
|
305
|
+
<link rel="icon" href="${d.logo || home_seo.logo || ''}"
|
|
306
|
+
type="image/png" sizes="128x128"/>
|
|
307
|
+
<meta property="og:image" content="${d.image || home_seo.image || ''}"/>
|
|
308
|
+
<meta property="og:title"
|
|
309
|
+
content="${(d.title ?? '').replace(/\n/g, '').replace(/"/g, '"')}"/>
|
|
310
|
+
<meta name="description"
|
|
311
|
+
content="${(d.content ?? '').replace(/\n/g, '').replace(/"/g, '"')}"/>
|
|
312
|
+
<meta name="og:description"
|
|
313
|
+
content="${(d.content ?? '').replace(/\n/g, '').replace(/"/g, '"')}"/>`;
|
|
314
|
+
}
|
|
315
|
+
})()}
|
|
316
|
+
${d.code ?? ''}
|
|
317
|
+
${(() => {
|
|
318
|
+
if (req.query.type === 'editor') {
|
|
319
|
+
return ``;
|
|
320
|
+
} else {
|
|
321
|
+
return `${(data.config.globalStyle ?? [])
|
|
322
|
+
.map((dd: any) => {
|
|
323
|
+
try {
|
|
324
|
+
if (dd.data.elem === 'link') {
|
|
325
|
+
return html`
|
|
326
|
+
<link
|
|
327
|
+
type="text/css"
|
|
328
|
+
rel="stylesheet"
|
|
329
|
+
href="${dd.data.attr.find((dd: any) => {
|
|
330
|
+
return dd.attr === 'href';
|
|
331
|
+
}).value}"
|
|
332
|
+
/>`;
|
|
333
|
+
}
|
|
334
|
+
} catch (e) {
|
|
335
|
+
return ``;
|
|
336
|
+
}
|
|
337
|
+
})
|
|
338
|
+
.join('')}`;
|
|
339
|
+
}
|
|
340
|
+
})()}
|
|
531
341
|
`;
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
342
|
+
})()+`<script>
|
|
343
|
+
${[
|
|
344
|
+
d.custom_script ?? '',
|
|
345
|
+
`window.login_config = ${JSON.stringify(login_config)};`,
|
|
346
|
+
`window.appName = '${appName}';`,
|
|
347
|
+
`window.glitterBase = '${brandAndMemberType.brand}';`,
|
|
348
|
+
`window.memberType = '${brandAndMemberType.memberType}';`,
|
|
349
|
+
`window.glitterBackend = '${config.domain}';`,
|
|
350
|
+
`window.preloadData = ${JSON.stringify(preload)
|
|
541
351
|
.replace(/<\/script>/g, 'sdjuescript_prepand')
|
|
542
|
-
.replace(/<script>/g, 'sdjuescript_prefix')}
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
352
|
+
.replace(/<script>/g, 'sdjuescript_prefix')};`,
|
|
353
|
+
`window.glitter_page = '${req.query.page}';`,
|
|
354
|
+
`window.store_info = ${JSON.stringify(store_info)};`,
|
|
355
|
+
`window.server_execute_time = ${(new Date().getTime() - start) / 1000};`,
|
|
356
|
+
`window.language = '${language}';`,
|
|
357
|
+
`${distribution_code}`,
|
|
358
|
+
`window.ip_country = '${(ip_country).country || 'TW'}';`,
|
|
359
|
+
`window.currency_covert = ${JSON.stringify(await Shopping.currencyCovert((req.query.base || 'TWD') as string))};`,
|
|
360
|
+
`window.language_list = ${JSON.stringify(language_label.label)};`
|
|
361
|
+
].map((dd) => {
|
|
362
|
+
return dd.trim()
|
|
363
|
+
}).filter((dd) => {
|
|
364
|
+
return dd
|
|
365
|
+
}).join(';\n')}
|
|
552
366
|
</script>
|
|
553
367
|
${[
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
368
|
+
{src: 'glitterBundle/GlitterInitial.js', type: 'module'},
|
|
369
|
+
{src: 'glitterBundle/module/html-generate.js', type: 'module'},
|
|
370
|
+
{src: 'glitterBundle/html-component/widget.js', type: 'module'},
|
|
371
|
+
{src: 'glitterBundle/plugins/trigger-event.js', type: 'module'},
|
|
372
|
+
{src: 'api/pageConfig.js', type: 'module'},
|
|
373
|
+
]
|
|
560
374
|
.map((dd) => {
|
|
561
375
|
return html`
|
|
562
376
|
<script src="/${link_prefix && `${link_prefix}/`}${dd.src}"
|
|
@@ -571,96 +385,39 @@ export async function createAPP(dd: any) {
|
|
|
571
385
|
const link = dd.fun.replace(`TriggerEvent.setEventRouter(import.meta.url, '.`, 'official_event');
|
|
572
386
|
return link.substring(0, link.length - 2);
|
|
573
387
|
})
|
|
574
|
-
.map((dd: any) =>
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
})
|
|
388
|
+
.map((dd: any) =>
|
|
389
|
+
html`
|
|
390
|
+
<script src="/${link_prefix && `${link_prefix}/`}${dd}"
|
|
391
|
+
type="module"></script>`)
|
|
579
392
|
.join('')}
|
|
580
|
-
</head>
|
|
581
393
|
${(() => {
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
${(customCode.ga4
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
<script>
|
|
592
|
-
window.dataLayer = window.dataLayer || [];
|
|
593
|
-
|
|
594
|
-
function gtag() {
|
|
595
|
-
dataLayer.push(arguments);
|
|
596
|
-
}
|
|
597
|
-
|
|
598
|
-
gtag('js', new Date());
|
|
599
|
-
|
|
600
|
-
gtag('config', '${dd.code}');
|
|
601
|
-
</script>`;
|
|
602
|
-
})
|
|
603
|
-
.join('')}
|
|
604
|
-
${(customCode.g_tag || [])
|
|
605
|
-
.map((dd: any) => {
|
|
606
|
-
return html`<!-- Google tag (gtag.js) -->
|
|
607
|
-
<!-- Google Tag Manager -->
|
|
608
|
-
<script>
|
|
609
|
-
(function (w, d, s, l, i) {
|
|
610
|
-
w[l] = w[l] || [];
|
|
611
|
-
w[l].push({
|
|
612
|
-
'gtm.start': new Date().getTime(),
|
|
613
|
-
event: 'gtm.js',
|
|
614
|
-
});
|
|
615
|
-
var f = d.getElementsByTagName(s)[0],
|
|
616
|
-
j = d.createElement(s),
|
|
617
|
-
dl = l != 'dataLayer' ? '&l=' + l : '';
|
|
618
|
-
j.async = true;
|
|
619
|
-
j.src = 'https://www.googletagmanager.com/gtm.js?id=' + i + dl;
|
|
620
|
-
f.parentNode.insertBefore(j, f);
|
|
621
|
-
})(window, document, 'script', 'dataLayer', '${dd.code}');
|
|
622
|
-
</script>
|
|
623
|
-
<!-- End Google Tag Manager -->`;
|
|
624
|
-
})
|
|
625
|
-
.join('')}
|
|
626
|
-
${FBCode && FBCode.pixel
|
|
627
|
-
? html`<!-- Meta Pixel Code -->
|
|
628
|
-
<script>
|
|
629
|
-
!(function (f, b, e, v, n, t, s) {
|
|
630
|
-
if (f.fbq) return;
|
|
631
|
-
n = f.fbq = function () {
|
|
632
|
-
n.callMethod ? n.callMethod.apply(n, arguments) : n.queue.push(arguments);
|
|
633
|
-
};
|
|
634
|
-
if (!f._fbq) f._fbq = n;
|
|
635
|
-
n.push = n;
|
|
636
|
-
n.loaded = !0;
|
|
637
|
-
n.version = '2.0';
|
|
638
|
-
n.queue = [];
|
|
639
|
-
t = b.createElement(e);
|
|
640
|
-
t.async = !0;
|
|
641
|
-
t.src = v;
|
|
642
|
-
s = b.getElementsByTagName(e)[0];
|
|
643
|
-
s.parentNode.insertBefore(t, s);
|
|
644
|
-
})(window, document, 'script', 'https://connect.facebook.net/en_US/fbevents.js');
|
|
645
|
-
fbq('init', '${FBCode.pixel}');
|
|
646
|
-
fbq('track', 'PageView');
|
|
647
|
-
</script>
|
|
648
|
-
<noscript><img height="1" width="1" style="display:none"
|
|
649
|
-
src="https://www.facebook.com/tr?id=617830100580621&ev=PageView&noscript=1"/>
|
|
650
|
-
</noscript>
|
|
651
|
-
<!-- End Meta Pixel Code -->`
|
|
652
|
-
: ''}
|
|
394
|
+
if (req.query.type === 'editor') {
|
|
395
|
+
return ``;
|
|
396
|
+
} else {
|
|
397
|
+
return html`
|
|
398
|
+
${SeoConfig.gA4(customCode.ga4)}
|
|
399
|
+
${SeoConfig.gTag(customCode.g_tag)}
|
|
400
|
+
${seo_content.map((dd) => {
|
|
401
|
+
return dd.trim()
|
|
402
|
+
}).join('\n')}
|
|
653
403
|
`;
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
404
|
+
}
|
|
405
|
+
})()}`,
|
|
406
|
+
body:``
|
|
407
|
+
}
|
|
408
|
+
|
|
657
409
|
} else {
|
|
658
|
-
|
|
659
|
-
|
|
410
|
+
return {
|
|
411
|
+
head:await Seo.redirectToHomePage(appName, req),
|
|
412
|
+
body:``
|
|
413
|
+
}
|
|
660
414
|
}
|
|
661
415
|
} catch (e: any) {
|
|
662
416
|
console.error(e);
|
|
663
|
-
return
|
|
417
|
+
return {
|
|
418
|
+
head:``,
|
|
419
|
+
body:`${e}`
|
|
420
|
+
}
|
|
664
421
|
}
|
|
665
422
|
},
|
|
666
423
|
sitemap: async (req, resp) => {
|
|
@@ -694,13 +451,30 @@ export async function createAPP(dd: any) {
|
|
|
694
451
|
)
|
|
695
452
|
)[0] ?? {};
|
|
696
453
|
|
|
697
|
-
const
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
454
|
+
const language_setting=(await new User(appName).getConfigV2({
|
|
455
|
+
key: 'store-information',
|
|
456
|
+
user_id: 'manager',
|
|
457
|
+
})).language_setting;
|
|
458
|
+
|
|
459
|
+
const product=(await new Shopping(appName).getProduct( {
|
|
460
|
+
page: 0,
|
|
461
|
+
limit: 100000,
|
|
462
|
+
collection: '',
|
|
463
|
+
accurate_search_text: false,
|
|
464
|
+
accurate_search_collection: true,
|
|
465
|
+
min_price: undefined,
|
|
466
|
+
max_price: undefined,
|
|
467
|
+
status: undefined,
|
|
468
|
+
channel: undefined,
|
|
469
|
+
id_list: undefined,
|
|
470
|
+
order_by: 'order by id desc',
|
|
471
|
+
with_hide_index: undefined,
|
|
472
|
+
is_manger: true,
|
|
473
|
+
productType: 'product',
|
|
474
|
+
filter_visible: 'true',
|
|
475
|
+
language: 'zh-TW',
|
|
476
|
+
currency_code: 'TWD'
|
|
477
|
+
})).data
|
|
704
478
|
// 創建 SitemapStream
|
|
705
479
|
const stream = new SitemapStream({hostname: `https://${domain}`});
|
|
706
480
|
|
|
@@ -730,20 +504,51 @@ export async function createAPP(dd: any) {
|
|
|
730
504
|
.map((d2: any) => {
|
|
731
505
|
return {url: `https://${domain}/${d2.url}`, changefreq: 'weekly'}
|
|
732
506
|
}),
|
|
733
|
-
...
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
507
|
+
...(()=>{
|
|
508
|
+
let array:string[]=[];
|
|
509
|
+
extractCols(cols)
|
|
510
|
+
.map((item:any) => {
|
|
511
|
+
array=array.concat((language_setting.support).map((d1:any)=>{
|
|
512
|
+
const seo=(item.language_data && item.language_data[d1] && item.language_data[d1].seo && item.language_data[d1].seo.domain) || item.code || item.title
|
|
513
|
+
if(d1===language_setting.def){
|
|
514
|
+
return {url: `https://${domain}/collections/${seo}`, changefreq: 'weekly'}
|
|
515
|
+
}else if(d1==='zh-TW'){
|
|
516
|
+
return {url: `https://${domain}/tw/collections/${seo}`, changefreq: 'weekly'}
|
|
517
|
+
}else if(d1==='zh-CN'){
|
|
518
|
+
return {url: `https://${domain}/cn/collections/${seo}`, changefreq: 'weekly'}
|
|
519
|
+
}else if(d1==='en-US'){
|
|
520
|
+
return {url: `https://${domain}/en/collections/${seo}`, changefreq: 'weekly'}
|
|
521
|
+
}else{
|
|
522
|
+
return {url: `https://${domain}/${d1}/collections/${seo}`, changefreq: 'weekly'}
|
|
523
|
+
}
|
|
524
|
+
}))
|
|
525
|
+
})
|
|
526
|
+
console.log(array)
|
|
527
|
+
return array
|
|
528
|
+
})(),
|
|
529
|
+
...(()=>{
|
|
530
|
+
let array:string[]=[];
|
|
531
|
+
product.map((dd:any)=>{
|
|
532
|
+
dd=dd.content;
|
|
533
|
+
array=array.concat((language_setting.support).map((d1:any)=>{
|
|
534
|
+
// console.log(`products=>`,dd)
|
|
535
|
+
const seo=(dd.language_data && dd.language_data[d1] && dd.language_data[d1].seo && dd.language_data[d1].seo.domain) || dd.seo.domain
|
|
536
|
+
if(d1===language_setting.def){
|
|
537
|
+
return {url: `https://${domain}/products/${seo}`, changefreq: 'weekly'}
|
|
538
|
+
}else if(d1==='zh-TW'){
|
|
539
|
+
return {url: `https://${domain}/tw/products/${seo}`, changefreq: 'weekly'}
|
|
540
|
+
}else if(d1==='zh-CN'){
|
|
541
|
+
return {url: `https://${domain}/cn/products/${seo}`, changefreq: 'weekly'}
|
|
542
|
+
}else if(d1==='en-US'){
|
|
543
|
+
return {url: `https://${domain}/en/products/${seo}`, changefreq: 'weekly'}
|
|
544
|
+
}else{
|
|
545
|
+
return {url: `https://${domain}/${d1}/products/${seo}`, changefreq: 'weekly'}
|
|
546
|
+
}
|
|
547
|
+
}))
|
|
746
548
|
})
|
|
549
|
+
|
|
550
|
+
return array
|
|
551
|
+
})()
|
|
747
552
|
]).pipe(stream)).then((data: any) =>
|
|
748
553
|
data.toString()
|
|
749
554
|
);
|