yf-system-cli 1.0.0

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.
@@ -0,0 +1,1723 @@
1
+ const express = require('express');
2
+ const https = require('https');
3
+ const path = require('path');
4
+ const fs = require('fs');
5
+
6
+ const app = express();
7
+
8
+ // 入口参数
9
+ const args = process.argv.slice(2); // 忽略前两个
10
+
11
+ //全局处理
12
+ app.use((req, res, next) => {
13
+ // 禁止缓存
14
+ res.set('Cache-Control', 'no-store, no-cache, must-revalidate, private');
15
+ res.set('Pragma', 'no-cache');
16
+ res.set('Expires', '0');
17
+
18
+ // 允许跨域
19
+ res.set('Access-Control-Allow-Origin', '*');
20
+ res.set('Access-Control-Allow-Methods', '*');
21
+ res.set('Access-Control-Allow-Headers', '*');
22
+
23
+ // 处理预检请求(OPTIONS)
24
+ if (req.method === 'OPTIONS') {
25
+ return res.status(200).end();
26
+ }
27
+
28
+ // 继续处理后续路由
29
+ next();
30
+ });
31
+
32
+ // 静态文件服务
33
+ const staticItems = [
34
+ { path: '/', dir: './html', theme: false },
35
+ { path: '/components', dir: './components', theme: false },
36
+ { path: '/plugins', dir: './plugins', theme: false },
37
+ { path: '/assets', dir: './assets', theme: true },
38
+ { path: '/css', dir: './css', theme: true },
39
+ { path: '/js', dir: './js', theme: true },
40
+ { path: '/font', dir: './font', theme: true },
41
+ ];
42
+ staticItems.forEach(({ path, dir, theme }) => {
43
+ app.use(path, express.static(dir));
44
+ if (theme && args.length > 1) {
45
+ app.use(`/${args[1]}${path}`, express.static(dir));
46
+ }
47
+ });
48
+
49
+ // 配置接口
50
+ app.use(express.json({ strict: false })); // `strict: false` 允许解析任何 JSON 值
51
+ app.get('/products/:id/variants', (req, res, next) => {
52
+ //获取商品变体
53
+ const acceptHeader = req.headers['accept'];
54
+ if (acceptHeader.includes('application/json')) {
55
+ res.set('Content-Type', 'application/json');
56
+ res.status(200).json({
57
+ status: 200,
58
+ message: "<status description>",
59
+ data: {
60
+ currency: {
61
+ code: "USD",
62
+ symbol: "$",
63
+ separatorDecimal: ".",
64
+ separatorGroup: ",",
65
+ },
66
+ info: {
67
+ id: req.params.id,
68
+ route: 'iphone-16-pro-max',
69
+ title: 'iPhone16 Pro Max',
70
+ priceSaleMin: 588.66,
71
+ priceSaleMax: 588.66,
72
+ priceOriginMin: null,
73
+ priceOriginMax: null,
74
+ priceSaveMin: null,
75
+ priceSaveMax: null,
76
+ discountSaveMin: null,
77
+ discountSaveMax: null,
78
+ weightMin: null,
79
+ weightMax: null,
80
+ volumeMin: null,
81
+ volumeMax: null,
82
+ salesCount: 0,
83
+ commentCount: 0,
84
+ commentStar: 0,
85
+ availableStart: null,
86
+ availableEnd: null,
87
+ quantityMin: 1,
88
+ quantityMax: null,
89
+ isTaxable: true,
90
+ isShipping: true,
91
+ },
92
+ medias: [{
93
+ size: 123,
94
+ width: 1024,
95
+ height: null,
96
+ type: 1,
97
+ mime: "image/jpeg",
98
+ host: "picsum.photos",
99
+ key: `/seed/${req.params.id}/1000/1000`,
100
+ version: 1020304050,
101
+ }],
102
+ variants: [
103
+ {
104
+ id: 123123456456,
105
+ media: {
106
+ size: 123,
107
+ width: 1024,
108
+ height: null,
109
+ type: 1,
110
+ mime: "image/jpeg",
111
+ host: "picsum.photos",
112
+ key: `/seed/${req.params.id}/1000/1000`,
113
+ version: 1020304050,
114
+ },
115
+ priceSale: 588.66,
116
+ priceOrigin: null,
117
+ priceSave: null,
118
+ discountSave: null,
119
+ salesCount: 123,
120
+ stockCount: 1,
121
+ weight: 275,
122
+ length: 8,
123
+ width: 6,
124
+ height: 3,
125
+ options: [
126
+ 100101,
127
+ 100202,
128
+ ],
129
+ },
130
+ ],
131
+ options: [
132
+ {
133
+ id: 1001,
134
+ name: "Color",
135
+ values: [
136
+ {
137
+ id: 100101,
138
+ name: "Black",
139
+ tip: "高级典雅镀金黑",
140
+ sort: 0,
141
+ },
142
+ {
143
+ id: 100102,
144
+ name: "Red",
145
+ tip: null,
146
+ sort: 1,
147
+ },
148
+ ],
149
+ sort: 0,
150
+ },
151
+ {
152
+ id: 1002,
153
+ name: "Size",
154
+ values: [
155
+ {
156
+ id: 100201,
157
+ name: "XXL",
158
+ tip: null,
159
+ sort: 0,
160
+ },
161
+ {
162
+ id: 100202,
163
+ name: "XXXL",
164
+ tip: "适合身高185cm以上",
165
+ sort: 1,
166
+ },
167
+ ],
168
+ sort: 0,
169
+ },
170
+ ],
171
+ },
172
+ timestamp: new Date().getTime()
173
+ });
174
+ }
175
+ else {
176
+ res.status(200).sendFile(path.join(__dirname, 'mock', 'productModal.html'));
177
+ }
178
+ });
179
+ app.get('/products/_/compares', (req, res, next) => {
180
+ //获取商品变体
181
+ const format = {
182
+ status: null,
183
+ message: "<status description>",
184
+ data: null,
185
+ timestamp: new Date().getTime()
186
+ };
187
+ const acceptHeader = req.headers['accept'];
188
+ if (acceptHeader.includes('application/json')) {
189
+ if (req.query.id === undefined || req.query.id === null || req.query.id.length <= 0 || req.query.id.length > 5) {
190
+ format.status = 204;
191
+ }
192
+ else {
193
+ format.status = 200;
194
+ format.data = {
195
+ "currency": {
196
+ "code": "USD",
197
+ "symbol": "$",
198
+ "digitDecimal": 2,
199
+ "separatorDecimal": ".",
200
+ "separatorGroup": ","
201
+ },
202
+ "products": [{
203
+ "info": {
204
+ "id": 2030405060,
205
+ "titme": "Balloon (Round and Heart-shaped), 11\"",
206
+ "route": "balloon-round-and-heart-shaped-11",
207
+ "priceSaleMin": 11.56,
208
+ "priceSaleMax": 11.56,
209
+ "priceOriginMin": null,
210
+ "priceOriginMax": null,
211
+ "priceSaveMin": null,
212
+ "priceSaveMax": null,
213
+ "discountSaveMin": null,
214
+ "discountSaveMax": null,
215
+ "weightMin": null,
216
+ "weightMax": null,
217
+ "volumeMin": null,
218
+ "volumeMax": null,
219
+ "salesCount": 0,
220
+ "commentCount": 0,
221
+ "commentStar": 0.00,
222
+ "availableStart": null,
223
+ "availableEnd": null,
224
+ "quantityMin": 1,
225
+ "quantityMax": 99,
226
+ "isTaxable": false,
227
+ "isShipping": true
228
+ },
229
+ "medias": [{
230
+ "alt": "HEI",
231
+ "sort": 1,
232
+ "size": 1024,
233
+ "width": null,
234
+ "height": null,
235
+ "type": 1,
236
+ "mime": "image/png",
237
+ "host": null,
238
+ "key": "/_/placeholder/colorful-1_1.png",
239
+ "version": 638918165480698999
240
+ },
241
+ {
242
+ "alt": "HA",
243
+ "sort": 2,
244
+ "size": 1024,
245
+ "width": null,
246
+ "height": null,
247
+ "type": 1,
248
+ "mime": "image/png",
249
+ "host": null,
250
+ "key": "/_/placeholder/gray-1_1.png",
251
+ "version": 638918165480697999
252
+ }
253
+ ],
254
+ "comparison": null
255
+ },
256
+ {
257
+ "info": {
258
+ "id": 1324354657,
259
+ "titme": "Toddler Jersey T-Shirt",
260
+ "route": "toddler-jersey-t-shirt",
261
+ "priceSaleMin": 18.00,
262
+ "priceSaleMax": 18.00,
263
+ "priceOriginMin": 20.00,
264
+ "priceOriginMax": 30.00,
265
+ "priceSaveMin": 2.00,
266
+ "priceSaveMax": 2.00,
267
+ "discountSaveMin": 10.00,
268
+ "discountSaveMax": 10.00,
269
+ "weightMin": null,
270
+ "weightMax": null,
271
+ "volumeMin": null,
272
+ "volumeMax": null,
273
+ "salesCount": 0,
274
+ "commentCount": 0,
275
+ "commentStar": 0.00,
276
+ "availableStart": "2025-07-26T17:52:44+08:00",
277
+ "availableEnd": "2025-08-26T17:52:44+08:00",
278
+ "quantityMin": 1,
279
+ "quantityMax": 99,
280
+ "isTaxable": false,
281
+ "isShipping": true
282
+ },
283
+ "medias": [{
284
+ "alt": "HEI",
285
+ "sort": 1,
286
+ "size": 1024,
287
+ "width": null,
288
+ "height": null,
289
+ "type": 1,
290
+ "mime": "image/png",
291
+ "host": null,
292
+ "key": "/_/placeholder/colorful-1_1.png",
293
+ "version": 638918165480698999
294
+ },
295
+ {
296
+ "alt": "HA",
297
+ "sort": 2,
298
+ "size": 1024,
299
+ "width": null,
300
+ "height": null,
301
+ "type": 1,
302
+ "mime": "image/png",
303
+ "host": null,
304
+ "key": "/_/placeholder/gray-4_3.png",
305
+ "version": 638918165480697998
306
+ },
307
+ {
308
+ "alt": "HEI",
309
+ "sort": 3,
310
+ "size": 1024,
311
+ "width": null,
312
+ "height": null,
313
+ "type": 1,
314
+ "mime": "image/png",
315
+ "host": null,
316
+ "key": "/_/placeholder/colorful-9_6.png",
317
+ "version": 638918165480698997
318
+ }
319
+ ],
320
+ "comparison": null
321
+ },
322
+ {
323
+ "info": {
324
+ "id": 1020304050,
325
+ "titme": "Accent Coffee Mug (11, 15oz)",
326
+ "route": "accent-coffee-mug-11-15oz",
327
+ "priceSaleMin": 2.52,
328
+ "priceSaleMax": 5.31,
329
+ "priceOriginMin": null,
330
+ "priceOriginMax": null,
331
+ "priceSaveMin": null,
332
+ "priceSaveMax": null,
333
+ "discountSaveMin": null,
334
+ "discountSaveMax": null,
335
+ "weightMin": null,
336
+ "weightMax": null,
337
+ "volumeMin": null,
338
+ "volumeMax": null,
339
+ "salesCount": 0,
340
+ "commentCount": 3,
341
+ "commentStar": 5.00,
342
+ "availableStart": null,
343
+ "availableEnd": null,
344
+ "quantityMin": 2,
345
+ "quantityMax": 5,
346
+ "isTaxable": false,
347
+ "isShipping": true
348
+ },
349
+ "medias": [{
350
+ "alt": "HEI",
351
+ "sort": 1,
352
+ "size": 1024,
353
+ "width": null,
354
+ "height": null,
355
+ "type": 1,
356
+ "mime": "image/png",
357
+ "host": null,
358
+ "key": "/_/placeholder/gray-1_1.png",
359
+ "version": 638918165480697999
360
+ },
361
+ {
362
+ "alt": "HA",
363
+ "sort": 2,
364
+ "size": 1024,
365
+ "width": null,
366
+ "height": null,
367
+ "type": 1,
368
+ "mime": "image/png",
369
+ "host": null,
370
+ "key": "/_/placeholder/colorful-1_1.png",
371
+ "version": 638918165480698999
372
+ },
373
+ {
374
+ "alt": "HE",
375
+ "sort": 3,
376
+ "size": 1024,
377
+ "width": null,
378
+ "height": null,
379
+ "type": 1,
380
+ "mime": "image/png",
381
+ "host": null,
382
+ "key": "/_/placeholder/gray-4_3.png",
383
+ "version": 638918165480697998
384
+ }
385
+ ],
386
+ "comparison": {
387
+ "color": [
388
+ "Red",
389
+ "Black",
390
+ "Blue"
391
+ ],
392
+ "size": [
393
+ "S",
394
+ "M",
395
+ "L"
396
+ ],
397
+ "package": [
398
+ "General",
399
+ "VIP"
400
+ ]
401
+ }
402
+ }
403
+ ],
404
+ "groups": [
405
+ "Color",
406
+ "Size",
407
+ "Package"
408
+ ]
409
+ };
410
+ }
411
+
412
+ //返回
413
+ res.set('Content-Type', 'application/json');
414
+ res.status(format.status).json(format);
415
+ }
416
+ else {
417
+ res.status(200).sendFile(path.join(__dirname, 'mock', 'compareResult.html'));
418
+ }
419
+ });
420
+ app.post('/cart/append', (req, res, next) => {
421
+ //追加购物车
422
+ const format = {
423
+ status: null,
424
+ message: "<status description>",
425
+ data: null,
426
+ timestamp: new Date().getTime()
427
+ };
428
+
429
+ //正常
430
+ format.status = 200;
431
+ if (req.body.mode === 3) {
432
+ format.data = '/checkout/one-page/123qwe098mnb';
433
+ }
434
+ else if (req.body.mode === 2) {
435
+ format.data = 1234321;
436
+ }
437
+ else {
438
+ format.data = true;
439
+ }
440
+ // //商品当前不可售
441
+ // format.status = 401;
442
+ // format.data = '商品当前不可售';
443
+ // //超过店铺设置的购物车最大容量
444
+ // format.status = 403;
445
+ // format.data = '超过店铺设置的购物车最大容量';
446
+ // //商品或变体不存在
447
+ // format.status = 404;
448
+ // format.data = '商品或变体不存在';
449
+ // //超过限购设置
450
+ // format.status = 413;
451
+ // format.data = '超过限购设置';
452
+
453
+ //返回
454
+ res.set('Content-Type', 'application/json');
455
+ res.status(format.status).json(format);
456
+ });
457
+ app.get('/cart/item/:id', (req, res, next) => {
458
+ //购物车条目
459
+ const acceptHeader = req.headers['accept'];
460
+ if (acceptHeader.includes('application/json')) {
461
+ res.set('Content-Type', 'application/json');
462
+ res.status(200).json({
463
+ status: 200,
464
+ message: "<status description>",
465
+ data: {
466
+ currency: {
467
+ code: "USD",
468
+ symbol: "$",
469
+ separatorDecimal: ".",
470
+ separatorGroup: ","
471
+ },
472
+ product: {
473
+ id: 123123456456,
474
+ productId: 321321321321,
475
+ variantId: 321321321321,
476
+ productRoute: "iphone-16-pro-max",
477
+ productTitle: "Apple iPhone 16 Pro Max",
478
+ productMedia: {
479
+ size: 123,
480
+ width: 1024,
481
+ height: null,
482
+ type: 1,
483
+ mime: "image/jpeg",
484
+ host: "picsum.photos",
485
+ key: `/seed/${new Date().getTime()}/1000/1000`,
486
+ version: 1020304050
487
+ },
488
+ priceSale: 588.66,
489
+ priceOrigin: null,
490
+ quantityMin: 1,
491
+ quantityMax: 3,
492
+ quantity: 1,
493
+ subTotal: 588.66,
494
+ options: [
495
+ {
496
+ groupName: "Color",
497
+ ValueName: "Black",
498
+ displayType: null
499
+ },
500
+ {
501
+ groupName: "Size",
502
+ ValueName: "XXL",
503
+ displayType: null
504
+ }
505
+ ],
506
+ stockCount: null,
507
+ isTaxable: true,
508
+ isShipping: true,
509
+ isValid: true
510
+ }
511
+ },
512
+ timestamp: new Date().getTime()
513
+ });
514
+ }
515
+ else {
516
+ res.status(200).sendFile(path.join(__dirname, 'mock', 'addCartSuccess.html'));
517
+ }
518
+ });
519
+ app.put('/cart/change/:id', (req, res, next) => {
520
+ //变更购物车数量
521
+ const format = {
522
+ status: null,
523
+ message: "<status description>",
524
+ data: null,
525
+ timestamp: new Date().getTime()
526
+ };
527
+
528
+ //正常
529
+ format.status = 200;
530
+ format.data = true;
531
+ // //商品当前不可售
532
+ // format.status = 401;
533
+ // format.data = '商品当前不可售';
534
+ // //超过店铺设置的购物车最大容量
535
+ // format.status = 403;
536
+ // format.data = '超过店铺设置的购物车最大容量';
537
+ // //商品或变体不存在
538
+ // format.status = 404;
539
+ // format.data = '商品或变体不存在';
540
+ // //超过限购设置
541
+ // format.status = 413;
542
+ // format.data = '超过限购设置';
543
+
544
+ //返回
545
+ res.set('Content-Type', 'application/json');
546
+ res.status(format.status).json(format);
547
+ });
548
+ app.delete('/cart/remove/:id', (req, res, next) => {
549
+ //移除购物车条目
550
+ const format = {
551
+ status: null,
552
+ message: "<status description>",
553
+ data: null,
554
+ timestamp: new Date().getTime()
555
+ };
556
+
557
+ //正常
558
+ format.status = 200;
559
+ format.data = true;
560
+
561
+ //返回
562
+ res.set('Content-Type', 'application/json');
563
+ res.status(format.status).json(format);
564
+ });
565
+ app.delete('/cart/clean', (req, res, next) => {
566
+ //清空购物车
567
+ const format = {
568
+ status: null,
569
+ message: "<status description>",
570
+ data: null,
571
+ timestamp: new Date().getTime()
572
+ };
573
+
574
+ //正常
575
+ format.status = 200;
576
+ format.data = true;
577
+
578
+ //返回
579
+ res.set('Content-Type', 'application/json');
580
+ res.status(format.status).json(format);
581
+ });
582
+ app.get('/cart/count', (req, res, next) => {
583
+ //购物车数量
584
+ const format = {
585
+ status: null,
586
+ message: "<status description>",
587
+ data: null,
588
+ timestamp: new Date().getTime()
589
+ };
590
+
591
+ //正常
592
+ format.status = 200;
593
+ format.data = new Date().getTime() % 10;
594
+
595
+ //返回
596
+ res.set('Content-Type', 'application/json');
597
+ res.status(format.status).json(format);
598
+ });
599
+ app.get('/cart/list', (req, res, next) => {
600
+ //购物车列表
601
+ const acceptHeader = req.headers['accept'];
602
+ if (acceptHeader.includes('application/json')) {
603
+ res.set('Content-Type', 'application/json');
604
+ res.status(200).json({
605
+ status: 200,
606
+ message: "<status description>",
607
+ data: {
608
+ currency: {
609
+ code: "USD",
610
+ symbol: "$",
611
+ separatorDecimal: ".",
612
+ separatorGroup: ","
613
+ },
614
+ items: [
615
+ {
616
+ id: 123123456456,
617
+ productId: 321321321321,
618
+ productRoute: "iphone-16-pro-max",
619
+ productTitle: "Apple iPhone 16 Pro Max",
620
+ productMedia: {
621
+ size: 123,
622
+ width: 1024,
623
+ height: null,
624
+ type: 1,
625
+ mime: "image/jpeg",
626
+ host: "picsum.photos",
627
+ key: `/seed/${new Date().getTime()}/1000/1000`,
628
+ version: 1020304050
629
+ },
630
+ priceSale: 588.66,
631
+ priceOrigin: null,
632
+ quantityMin: 1,
633
+ quantityMax: 3,
634
+ quantity: 1,
635
+ subTotal: 588.66,
636
+ options: [
637
+ {
638
+ groupName: "Color",
639
+ ValueName: "Black",
640
+ displayType: null
641
+ },
642
+ {
643
+ groupName: "Size",
644
+ ValueName: "XXL",
645
+ displayType: null
646
+ }
647
+ ],
648
+ stockCount: null,
649
+ isTaxable: true,
650
+ isShipping: true,
651
+ isValid: true
652
+ }
653
+ ],
654
+ subTotal: 588.66,
655
+ coupon: -9.99,
656
+ promotion: -0.12,
657
+ total: 578.55
658
+ },
659
+ timestamp: new Date().getTime()
660
+ });
661
+ }
662
+ else {
663
+ res.status(200).sendFile(path.join(__dirname, 'mock', 'cart.html'));
664
+ }
665
+ });
666
+ app.post('/cart/coupon', (req, res, next) => {
667
+ //兑换优惠券
668
+ const format = {
669
+ status: null,
670
+ message: "<status description>",
671
+ data: null,
672
+ timestamp: new Date().getTime()
673
+ };
674
+
675
+ //正常
676
+ format.status = 200;
677
+ format.data = {
678
+ "title": "-$ 1.90 , Buy 20+ items",
679
+ "amount": -1.90,
680
+ };
681
+ // //不符合兑换条件
682
+ // format.status = 403;
683
+ // format.data = '不符合兑换条件';
684
+ // //券码无效
685
+ // format.status = 404;
686
+ // format.data = '券码无效';
687
+
688
+ //返回
689
+ res.set('Content-Type', 'application/json');
690
+ res.status(format.status).json(format);
691
+ });
692
+ app.delete('/cart/coupon', (req, res, next) => {
693
+ //移除优惠券
694
+ const format = {
695
+ status: null,
696
+ message: "<status description>",
697
+ data: null,
698
+ timestamp: new Date().getTime()
699
+ };
700
+
701
+ //正常
702
+ format.status = 200;
703
+ format.data = true;
704
+
705
+ //返回
706
+ res.set('Content-Type', 'application/json');
707
+ res.status(format.status).json(format);
708
+ });
709
+ app.get('/account/address/:id', (req, res, next) => {
710
+ //获取地址
711
+ const format = {
712
+ status: 200,
713
+ message: "<status description>",
714
+ data: {
715
+ firstName: "Zhang",
716
+ lastName: "san feng",
717
+ address1: "Wudang Avenue",
718
+ address2: null,
719
+ countryId: "156",
720
+ stateId: null,
721
+ stateName: "Hubei",
722
+ cityId: null,
723
+ cityName: "Shiyan",
724
+ zipcode: "442799",
725
+ phoneArea: "+86",
726
+ phoneNumber: "07195665396",
727
+ isDefault: parseInt(req.params.id) % 2 === 0,
728
+ },
729
+ timestamp: new Date().getTime()
730
+ };
731
+
732
+ //返回
733
+ res.set('Content-Type', 'application/json');
734
+ res.status(format.status).json(format);
735
+ });
736
+ app.delete('/account/address/:id', (req, res, next) => {
737
+ //删除地址
738
+ const format = {
739
+ status: null,
740
+ message: "<status description>",
741
+ data: null,
742
+ timestamp: new Date().getTime()
743
+ };
744
+
745
+ //正常
746
+ format.status = 200;
747
+ format.data = true;
748
+
749
+ //返回
750
+ res.set('Content-Type', 'application/json');
751
+ res.status(format.status).json(format);
752
+ });
753
+ app.post('/wishlist/product', (req, res, next) => {
754
+ //心愿添加-商品
755
+ const format = {
756
+ status: null,
757
+ message: "<status description>",
758
+ data: null,
759
+ timestamp: new Date().getTime()
760
+ };
761
+
762
+ //正常
763
+ format.status = 200;
764
+ format.data = true;
765
+
766
+ //返回
767
+ res.set('Content-Type', 'application/json');
768
+ res.status(format.status).json(format);
769
+ });
770
+ app.post('/wishlist/blog', (req, res, next) => {
771
+ //心愿添加-博客
772
+ const format = {
773
+ status: null,
774
+ message: "<status description>",
775
+ data: null,
776
+ timestamp: new Date().getTime()
777
+ };
778
+
779
+ //正常
780
+ format.status = 200;
781
+ format.data = true;
782
+
783
+ //返回
784
+ res.set('Content-Type', 'application/json');
785
+ res.status(format.status).json(format);
786
+ });
787
+ app.delete('/wishlist/product', (req, res, next) => {
788
+ //心愿移除-商品
789
+ const format = {
790
+ status: null,
791
+ message: "<status description>",
792
+ data: null,
793
+ timestamp: new Date().getTime()
794
+ };
795
+
796
+ //正常
797
+ format.status = 200;
798
+ format.data = true;
799
+
800
+ //返回
801
+ res.set('Content-Type', 'application/json');
802
+ res.status(format.status).json(format);
803
+ });
804
+ app.delete('/wishlist/blog', (req, res, next) => {
805
+ //心愿移除-博客
806
+ const format = {
807
+ status: null,
808
+ message: "<status description>",
809
+ data: null,
810
+ timestamp: new Date().getTime()
811
+ };
812
+
813
+ //正常
814
+ format.status = 200;
815
+ format.data = true;
816
+
817
+ //返回
818
+ res.set('Content-Type', 'application/json');
819
+ res.status(format.status).json(format);
820
+ });
821
+ app.get('/localization/countries', (req, res, next) => {
822
+ //国家列表
823
+ const format = {
824
+ status: 200,
825
+ message: "<status description>",
826
+ data: [
827
+ {
828
+ "id": 45,
829
+ "name": "China",
830
+ "code2": "CN",
831
+ "code3": "CHN",
832
+ "number3": "156",
833
+ "phone": ["+86"],
834
+ "language": ["zh"],
835
+ "currency": ["CNY"],
836
+ "domain": "cn",
837
+ "capital": "Beijing",
838
+ "continent": "Asia"
839
+ },
840
+ {
841
+ "id": 75,
842
+ "name": "France",
843
+ "code2": "FR",
844
+ "code3": "FRA",
845
+ "number3": "250",
846
+ "phone": ["+33"],
847
+ "language": ["fr"],
848
+ "currency": ["EUR"],
849
+ "domain": "fr",
850
+ "capital": "Paris",
851
+ "continent": "Europe"
852
+ },
853
+ {
854
+ "id": 233,
855
+ "name": "United States of America (the)",
856
+ "code2": "US",
857
+ "code3": "USA",
858
+ "number3": "840",
859
+ "phone": ["+1"],
860
+ "language": ["us"],
861
+ "currency": ["USD"],
862
+ "domain": "us",
863
+ "capital": "Washington",
864
+ "continent": "North America"
865
+ }
866
+ ],
867
+ timestamp: new Date().getTime()
868
+ };
869
+
870
+ //返回
871
+ res.set('Content-Type', 'application/json');
872
+ res.status(format.status).json(format);
873
+ });
874
+ app.get('/localization/states/:id', (req, res, next) => {
875
+ //州省列表
876
+ const format = {
877
+ status: 200,
878
+ message: "<status description>",
879
+ data: [],
880
+ timestamp: new Date().getTime()
881
+ };
882
+
883
+ if (req.params.id == '45') {
884
+ format.data.push({
885
+ "id": 10001,
886
+ "countryId": 45,
887
+ "name": "Zhejiang",
888
+ "code": null
889
+ });
890
+ format.data.push({
891
+ "id": 10002,
892
+ "countryId": 45,
893
+ "name": "Hainan",
894
+ "code": null
895
+ });
896
+ }
897
+ else if (req.params.id == '233') {
898
+ format.data.push({
899
+ "id": 20001,
900
+ "countryId": 233,
901
+ "name": "Alaska",
902
+ "code": 'AK'
903
+ });
904
+ format.data.push({
905
+ "id": 20002,
906
+ "countryId": 233,
907
+ "name": "Maryland",
908
+ "code": 'MD'
909
+ });
910
+ format.data.push({
911
+ "id": 20003,
912
+ "countryId": 233,
913
+ "name": "Texas",
914
+ "code": 'TX'
915
+ });
916
+ }
917
+
918
+ //返回
919
+ res.set('Content-Type', 'application/json');
920
+ res.status(format.status).json(format);
921
+ });
922
+ app.get('/localization/cities/:id1/:id2', (req, res, next) => {
923
+ //城市列表
924
+ const format = {
925
+ status: 200,
926
+ message: "<status description>",
927
+ data: [],
928
+ timestamp: new Date().getTime()
929
+ };
930
+
931
+ if (req.params.id1 == '45') {
932
+ if (req.params.id2 == '10001') {
933
+ format.data.push({
934
+ "id": 30001,
935
+ "countryId": 45,
936
+ "stateId": 10001,
937
+ "name": "Hangzhou",
938
+ "code": null
939
+ });
940
+ format.data.push({
941
+ "id": 30002,
942
+ "countryId": 45,
943
+ "stateId": 10001,
944
+ "name": "Ningbo",
945
+ "code": null
946
+ });
947
+ format.data.push({
948
+ "id": 30003,
949
+ "countryId": 45,
950
+ "stateId": 10001,
951
+ "name": "Wenzhou",
952
+ "code": null
953
+ });
954
+ }
955
+ }
956
+
957
+ if (req.params.id1 == '45') {
958
+ if (req.params.id2 == '10002') {
959
+ format.data = []
960
+ }
961
+ }
962
+
963
+ //返回
964
+ res.set('Content-Type', 'application/json');
965
+ res.status(format.status).json(format);
966
+ });
967
+
968
+ // 默认的表单模板路由(不带国家ID)
969
+ app.get('/pay/form', (req, res, next) => {
970
+ const format = {
971
+ status: 200,
972
+ message: "<status description>",
973
+ data: [
974
+ [
975
+ {
976
+ "name": "countryCode",
977
+ "id": "countryCode",
978
+ "label": "Country/Region",
979
+ "required": true,
980
+ "type": "select",
981
+ "error": "Please select your country/region"
982
+ }
983
+ ],
984
+ [
985
+ {
986
+ "name": "firstName",
987
+ "id": "firstName",
988
+ "label": "First name",
989
+ "required": true,
990
+ "type": "input",
991
+ "error": "Please enter your first name",
992
+ "minLength": 1,
993
+ "maxLength": 20
994
+ },
995
+ {
996
+ "name": "lastName",
997
+ "id": "lastName",
998
+ "label": "Last name",
999
+ "required": true,
1000
+ "type": "input",
1001
+ "error": "Please enter your last name",
1002
+ "minLength": 1,
1003
+ "maxLength": 20
1004
+ }
1005
+ ],
1006
+ [
1007
+ {
1008
+ "name": "address1",
1009
+ "id": "address1",
1010
+ "label": "Address",
1011
+ "required": true,
1012
+ "type": "input",
1013
+ "error": "Please enter your address",
1014
+ "maxLength": 150
1015
+ }
1016
+ ],
1017
+ [
1018
+ {
1019
+ "name": "address2",
1020
+ "id": "address2",
1021
+ "label": "Apartment",
1022
+ "required": false,
1023
+ "type": "input",
1024
+ "error": "Please enter your apartment",
1025
+ "maxLength": 150,
1026
+ }
1027
+ ],
1028
+ [
1029
+ {
1030
+ "name": "city",
1031
+ "id": "city",
1032
+ "label": "City",
1033
+ "required": true,
1034
+ "type": "input",
1035
+ "error": "Please enter your city",
1036
+ "minLength": 1,
1037
+ "maxLength": 100
1038
+ },
1039
+ {
1040
+ "name": "province",
1041
+ "id": "province",
1042
+ "label": "Province",
1043
+ "required": true,
1044
+ "type": "select",
1045
+ "error": "Please select your state/province",
1046
+ "minLength": 1,
1047
+ "maxLength": 100
1048
+ },
1049
+ {
1050
+ "name": "postalCode",
1051
+ "id": "postalCode",
1052
+ "label": "PostalCode",
1053
+ "required": true,
1054
+ "type": "input",
1055
+ "error": "Please enter your postal code",
1056
+ "maxLength": 10
1057
+ }
1058
+ ],
1059
+ [
1060
+ {
1061
+ "name": "phone",
1062
+ "id": "phone",
1063
+ "label": "Phone",
1064
+ "required": true,
1065
+ "type": "input",
1066
+ "error": "Please enter your phone",
1067
+ "minLength": 3,
1068
+ "maxLength": 20
1069
+ }
1070
+ ]
1071
+ ],
1072
+ timestamp: new Date().getTime()
1073
+ };
1074
+
1075
+ res.set('Content-Type', 'application/json');
1076
+ res.status(format.status).json(format);
1077
+ });
1078
+
1079
+ app.get('/pay/form/:id', (req, res, next) => {
1080
+ const format = {
1081
+ status: 200,
1082
+ message: "<status description>",
1083
+ data: [],
1084
+ timestamp: new Date().getTime()
1085
+ };
1086
+
1087
+ if (req.params.id == '45') {
1088
+ format.data = [[
1089
+ {
1090
+ "name": "countryCode",
1091
+ "id": "countryCode",
1092
+ "label": "Country/Region",
1093
+ "required": true,
1094
+ "type": "select",
1095
+ "error": "Please select your country/region"
1096
+ }
1097
+ ],
1098
+ [
1099
+ {
1100
+ "name": "firstName",
1101
+ "id": "firstName",
1102
+ "label": "First name",
1103
+ "required": true,
1104
+ "type": "input",
1105
+ "error": "Please enter your first name",
1106
+ "minLength": 1,
1107
+ "maxLength": 20
1108
+ },
1109
+ {
1110
+ "name": "lastName",
1111
+ "id": "lastName",
1112
+ "label": "Last name",
1113
+ "required": false,
1114
+ "type": "input",
1115
+ "error": "Please enter your last name",
1116
+ "minLength": 1,
1117
+ "maxLength": 20
1118
+ }
1119
+ ],
1120
+ [
1121
+ {
1122
+ "name": "address1",
1123
+ "id": "address1",
1124
+ "label": "Address",
1125
+ "required": true,
1126
+ "type": "input",
1127
+ "error": "Please enter your address",
1128
+ "maxLength": 150
1129
+ }
1130
+ ],
1131
+ [
1132
+ {
1133
+ "name": "city",
1134
+ "id": "city",
1135
+ "label": "City",
1136
+ "required": true,
1137
+ "type": "input",
1138
+ "error": "Please enter your city",
1139
+ "minLength": 1,
1140
+ "maxLength": 100
1141
+ },
1142
+ {
1143
+ "name": "province",
1144
+ "id": "province",
1145
+ "label": "Province",
1146
+ "required": true,
1147
+ "type": "select",
1148
+ "error": "Please select your state/province",
1149
+ "minLength": 1,
1150
+ "maxLength": 100
1151
+ },
1152
+ {
1153
+ "name": "postalCode",
1154
+ "id": "postalCode",
1155
+ "label": "PostalCode",
1156
+ "required": true,
1157
+ "type": "input",
1158
+ "error": "Please enter your postal code",
1159
+ "maxLength": 10
1160
+ }
1161
+ ],
1162
+ [
1163
+ {
1164
+ "name": "phone",
1165
+ "id": "phone",
1166
+ "label": "Phone",
1167
+ "required": true,
1168
+ "type": "input",
1169
+ "error": "Please enter your phone",
1170
+ "minLength": 3,
1171
+ "maxLength": 20
1172
+ }
1173
+ ]];
1174
+ }
1175
+ if (req.params.id == '75') {
1176
+ format.data = [
1177
+ [
1178
+ {
1179
+ "name": "countryCode",
1180
+ "id": "countryCode",
1181
+ "label": "Country/Region",
1182
+ "required": true,
1183
+ "type": "select",
1184
+ "error": "Please select your country/region"
1185
+ }
1186
+ ],
1187
+ [
1188
+ {
1189
+ "name": "firstName",
1190
+ "id": "firstName",
1191
+ "label": "First name (optional)",
1192
+ "required": false,
1193
+ "type": "input",
1194
+ "error": "Please enter your first name",
1195
+ "minLength": 1,
1196
+ "maxLength": 20
1197
+ },
1198
+ {
1199
+ "name": "lastName",
1200
+ "id": "lastName",
1201
+ "label": "Last name",
1202
+ "required": true,
1203
+ "type": "input",
1204
+ "error": "Please enter your last name",
1205
+ "minLength": 1,
1206
+ "maxLength": 20
1207
+ }
1208
+ ],
1209
+ [
1210
+ {
1211
+ "name": "address1",
1212
+ "id": "address1",
1213
+ "label": "Address",
1214
+ "required": true,
1215
+ "type": "input",
1216
+ "error": "Please enter your address",
1217
+ "maxLength": 150
1218
+ }
1219
+ ],
1220
+ [
1221
+ {
1222
+ "name": "address2",
1223
+ "id": "address2",
1224
+ "label": "Apartment",
1225
+ "required": true,
1226
+ "type": "input",
1227
+ "error": "Please enter your apartment",
1228
+ "maxLength": 150
1229
+ }
1230
+ ],
1231
+ [
1232
+ {
1233
+ "name": "postalCode",
1234
+ "id": "postalCode",
1235
+ "label": "PostalCode",
1236
+ "required": true,
1237
+ "type": "input",
1238
+ "error": "Please enter your postal code",
1239
+ "maxLength": 10
1240
+ },
1241
+ {
1242
+ "name": "city",
1243
+ "id": "city",
1244
+ "label": "City",
1245
+ "required": true,
1246
+ "type": "input",
1247
+ "error": "Please enter your city",
1248
+ "minLength": 1,
1249
+ "maxLength": 100
1250
+ }
1251
+ ],
1252
+ [
1253
+ {
1254
+ "name": "phone",
1255
+ "id": "phone",
1256
+ "label": "Phone",
1257
+ "required": true,
1258
+ "type": "input",
1259
+ "error": "Please enter your phone",
1260
+ "minLength": 3,
1261
+ "maxLength": 20
1262
+ }
1263
+ ]
1264
+ ]
1265
+ }
1266
+ if (req.params.id == '233') {
1267
+ format.data = [
1268
+ [
1269
+ {
1270
+ "name": "countryCode",
1271
+ "id": "countryCode",
1272
+ "label": "Country/Region",
1273
+ "required": true,
1274
+ "type": "select",
1275
+ "error": "Please select your country/region"
1276
+ }
1277
+ ],
1278
+ [
1279
+ {
1280
+ "name": "firstName",
1281
+ "id": "firstName",
1282
+ "label": "First name (optional)",
1283
+ "required": true,
1284
+ "type": "input",
1285
+ "error": "Please enter your first name",
1286
+ "minLength": 1,
1287
+ "maxLength": 20
1288
+ },
1289
+ {
1290
+ "name": "lastName",
1291
+ "id": "lastName",
1292
+ "label": "Last name",
1293
+ "required": true,
1294
+ "type": "input",
1295
+ "error": "Please enter your last name",
1296
+ "minLength": 1,
1297
+ "maxLength": 20
1298
+ }
1299
+ ],
1300
+ [
1301
+ {
1302
+ "name": "address1",
1303
+ "id": "address1",
1304
+ "label": "街道地址",
1305
+ "required": true,
1306
+ "type": "input",
1307
+ "error": "Please enter your address",
1308
+ "maxLength": 150
1309
+ }
1310
+ ],
1311
+ [
1312
+ {
1313
+ "name": "address2",
1314
+ "id": "address2",
1315
+ "label": "Apartment/单元号",
1316
+ "required": true,
1317
+ "type": "input",
1318
+ "error": "Please enter your apartment",
1319
+ "maxLength": 150
1320
+ }
1321
+ ],
1322
+ [
1323
+ {
1324
+ "name": "city",
1325
+ "id": "city",
1326
+ "label": "City",
1327
+ "required": true,
1328
+ "type": "select",
1329
+ "error": "Please select your city",
1330
+ "minLength": 1,
1331
+ "maxLength": 100
1332
+ },
1333
+ {
1334
+ "name": "state",
1335
+ "id": "state",
1336
+ "label": "State",
1337
+ "required": true,
1338
+ "type": "select",
1339
+ "error": "Please select your state",
1340
+ "minLength": 1,
1341
+ "maxLength": 100
1342
+ }
1343
+ ],
1344
+ [
1345
+ {
1346
+ "name": "zipCode",
1347
+ "id": "zipCode",
1348
+ "label": "ZIP code",
1349
+ "required": true,
1350
+ "type": "input",
1351
+ "error": "Please enter your zip code",
1352
+ "maxLength": 10
1353
+ }
1354
+ ],
1355
+ [
1356
+ {
1357
+ "name": "phone",
1358
+ "id": "phone",
1359
+ "label": "Phone",
1360
+ "required": true,
1361
+ "type": "input",
1362
+ "error": "Please enter your phone",
1363
+ "minLength": 3,
1364
+ "maxLength": 20
1365
+ }
1366
+ ]
1367
+ ]
1368
+ }
1369
+
1370
+ //返回
1371
+ res.set('Content-Type', 'application/json');
1372
+ res.status(format.status).json(format);
1373
+ });
1374
+
1375
+ app.get('/pay/shipping/:id', (req, res, next) => {
1376
+ const format = {
1377
+ status: 200,
1378
+ message: "<status description>",
1379
+ data: [],
1380
+ timestamp: new Date().getTime()
1381
+ };
1382
+ if (req.params.id == '45') {
1383
+ format.data.push({
1384
+ "id": "SF_EXPRESS",
1385
+ "name": "顺丰特快",
1386
+ "name_en": "SF Express Premium",
1387
+ "type": "express",
1388
+ "baseCost": 25.00,
1389
+ "finalCost": 18.00,
1390
+ "discount": {
1391
+ "type": "coupon",
1392
+ "code": "SF2023Q4",
1393
+ "value": 7.00,
1394
+ "description": "季度促销直减7元",
1395
+ "validUntil": "2023-12-31"
1396
+ },
1397
+ "tax": {
1398
+ "rate": 0.06,
1399
+ "amount": 1.08,
1400
+ "type": "VAT",
1401
+ "includedInPrice": false
1402
+ },
1403
+ "deliveryTime": "1-2个工作日",
1404
+ "weightLimit": 20.0,
1405
+ "extras": [
1406
+ {
1407
+ "name": "保价服务",
1408
+ "fee": 2.00,
1409
+ "per": 1000,
1410
+ "optional": true
1411
+ }
1412
+ ]
1413
+ },
1414
+ {
1415
+ "id": "JD_ECONOMY",
1416
+ "name": "京东经济",
1417
+ "name_en": "JD Economy",
1418
+ "type": "standard",
1419
+ "baseCost": 15.00,
1420
+ "finalCost": 0.00,
1421
+ "discount": {
1422
+ "type": "free_shipping",
1423
+ "condition": "order_amount >= 99",
1424
+ "description": "满99元包邮"
1425
+ },
1426
+ "tax": {
1427
+ "rate": 0.06,
1428
+ "amount": 0.00,
1429
+ "type": "VAT"
1430
+ },
1431
+ "deliveryTime": "3-5个工作日"
1432
+ })
1433
+ }
1434
+ if (req.params.id == '75') {
1435
+ format.data.push(
1436
+ {
1437
+ "id": "JD_ECONOMY",
1438
+ "name": "京东经济",
1439
+ "name_en": "JD Economy",
1440
+ "type": "standard",
1441
+ "baseCost": 15.00,
1442
+ "finalCost": 0.00,
1443
+ "discount": {
1444
+ "type": "free_shipping",
1445
+ "condition": "order_amount >= 99",
1446
+ "description": "满99元包邮"
1447
+ },
1448
+ "tax": {
1449
+ "rate": 0.06,
1450
+ "amount": 0.00,
1451
+ "type": "VAT"
1452
+ },
1453
+ "deliveryTime": "3-5个工作日"
1454
+ })
1455
+ }
1456
+ if (req.params.id == '233') {
1457
+ format.data = []
1458
+ }
1459
+
1460
+ //返回
1461
+ res.set('Content-Type', 'application/json');
1462
+ res.status(format.status).json(format);
1463
+ });
1464
+
1465
+ app.get('/pay/methods/:id', (req, res, next) => {
1466
+ const format = {
1467
+ status: 200,
1468
+ message: "<status description>",
1469
+ data: [],
1470
+ timestamp: new Date().getTime()
1471
+ };
1472
+ if (req.params.id == 'SF_EXPRESS') {
1473
+ format.data.push(
1474
+ {
1475
+ "id": "credit_card",
1476
+ "name": "信用卡支付",
1477
+ "type": "card",
1478
+ "description": "支持国际信用卡和国内银联卡",
1479
+ "cards": [
1480
+ {
1481
+ "type": "visa",
1482
+ "logo": "/image/visa.png",
1483
+ "binRanges": [
1484
+ "4"
1485
+ ]
1486
+ },
1487
+ {
1488
+ "type": "mastercard",
1489
+ "logo": "/image/bank.png",
1490
+ "binRanges": [
1491
+ "51",
1492
+ "52",
1493
+ "53",
1494
+ "54",
1495
+ "55"
1496
+ ]
1497
+ }
1498
+ ]
1499
+ },
1500
+ {
1501
+ "id": "wechat_pay",
1502
+ "name": "微信支付",
1503
+ "type": "mobile_wallet",
1504
+ "logo": "/image/weichat_logo.png",
1505
+ "qrcode": "/image/weichat_qr.png",
1506
+ "supportedCurrencies": [
1507
+ "CNY"
1508
+ ]
1509
+ },
1510
+ {
1511
+ "id": "alipay",
1512
+ "name": "支付宝",
1513
+ "type": "mobile_wallet",
1514
+ "logo": "/image/zhifubao_logo.png",
1515
+ "qrcode": "/image/zhifubao_qr.png"
1516
+ }
1517
+ )
1518
+ }
1519
+ if (req.params.id == 'JD_ECONOMY') {
1520
+ format.data.push(
1521
+ {
1522
+ "id": "apple_pay",
1523
+ "name": "Apple Pay",
1524
+ "type": "mobile_wallet",
1525
+ "logo": "/image/apple_logo.png",
1526
+ "qrcode": "/image/qr.png",
1527
+ "supportedDevices": [
1528
+ "iPhone",
1529
+ "iPad",
1530
+ "Mac"
1531
+ ]
1532
+ }
1533
+ )
1534
+ }
1535
+
1536
+ //返回
1537
+ res.set('Content-Type', 'application/json');
1538
+ res.status(format.status).json(format);
1539
+ });
1540
+
1541
+ app.post('/pay/confirm', (req, res, next) => {
1542
+ const format = {
1543
+ status: 200,
1544
+ message: "<status description>",
1545
+ data: null,
1546
+ timestamp: new Date().getTime()
1547
+ };
1548
+
1549
+ // 随机返回45、75、233中的一个数
1550
+ const randomNumbers = [45, 75, 233];
1551
+ const randomIndex = Math.floor(Math.random() * randomNumbers.length);
1552
+
1553
+ format.data = {
1554
+ "payId": randomNumbers[randomIndex],
1555
+ }
1556
+
1557
+ // format.status = 400
1558
+ // format.message = 'error'
1559
+ res.set('Content-Type', 'application/json');
1560
+ res.status(format.status).json(format);
1561
+ });
1562
+
1563
+ app.get('/pay/template', (req, res, next) => {
1564
+ const format = {
1565
+ status: 200,
1566
+ message: "<status description>",
1567
+ data: [],
1568
+ timestamp: new Date().getTime()
1569
+ };
1570
+
1571
+ if (req.query.countryId == '45' || req.query.countryId == '75') {
1572
+ format.data.push(
1573
+ {
1574
+ "id": "1",
1575
+ "name": "Plan 1",
1576
+ "tip": "Order with a value above $100 will receive a 10% discount",
1577
+ "list": [
1578
+ {
1579
+ "id": "1-1",
1580
+ "label": "Tax",
1581
+ "tagName": "input",
1582
+ "type": "text",
1583
+ "minLength": 1,
1584
+ "maxLength": 100,
1585
+ "required": true,
1586
+ "errorMessage": "Vax Id is required"
1587
+ },
1588
+ {
1589
+ "id": "1-2",
1590
+ "label": "Vax Id",
1591
+ "tagName": "input",
1592
+ "type": "number",
1593
+ "min": 1,
1594
+ "max": 100,
1595
+ "required": true,
1596
+ "errorMessage": "Tax must be between 1 and 100"
1597
+ }
1598
+ ]
1599
+ },
1600
+ {
1601
+ "id": "2",
1602
+ "name": "Plan 2",
1603
+ "list": [
1604
+ {
1605
+ "id": "2-1",
1606
+ "label": "Tax",
1607
+ "tagName": "select",
1608
+ "required": true,
1609
+ "errorMessage": "Please enter a valid Tax",
1610
+ "defaultChoice": true,
1611
+ "options": [
1612
+ {
1613
+ "id": "2-1-1",
1614
+ "label": "Option 1",
1615
+ "value": "1"
1616
+ },
1617
+ {
1618
+ "id": "2-1-2",
1619
+ "label": "Option 2",
1620
+ "value": "2"
1621
+ }
1622
+ ]
1623
+ },
1624
+ {
1625
+ "id": "2-1",
1626
+ "label": "Tax",
1627
+ "tagName": "select",
1628
+ "required": true,
1629
+ "errorMessage": "Please enter a valid Tax",
1630
+ "defaultChoice": false,
1631
+ "options": [
1632
+ {
1633
+ "id": "2-1-0",
1634
+ "label": "Please select",
1635
+ "value": ""
1636
+ },
1637
+ {
1638
+ "id": "2-1-1",
1639
+ "label": "Option 1",
1640
+ "value": "1"
1641
+ },
1642
+ {
1643
+ "id": "2-1-2",
1644
+ "label": "Option 2",
1645
+ "value": "2"
1646
+ }
1647
+ ]
1648
+ }
1649
+ ]
1650
+ }
1651
+ )
1652
+ }
1653
+ res.set('Content-Type', 'application/json');
1654
+ res.status(format.status).json(format);
1655
+ });
1656
+
1657
+ app.post('/assets/upload-token', (req, res, next) => {
1658
+ //上传令牌
1659
+ const format = {
1660
+ status: null,
1661
+ message: "<status description>",
1662
+ data: null,
1663
+ timestamp: new Date().getTime()
1664
+ };
1665
+
1666
+ //空间容量不足
1667
+ // format.status = 403;
1668
+ // format.data = "空间容量不足";
1669
+
1670
+ //正常
1671
+ format.status = 200;
1672
+ format.data = {
1673
+ code: format.timestamp.toString(16),
1674
+ link: `https://picsum.photos/seed/${format.timestamp}/1000/1000`,
1675
+ style: null,
1676
+ action: "/assets/upload-file",
1677
+ headers: {},
1678
+ forms: {
1679
+ by: "sandbox",
1680
+ file: "${file}"
1681
+ }
1682
+ };
1683
+
1684
+ //返回
1685
+ res.set('Content-Type', 'application/json');
1686
+ res.status(format.status).json(format);
1687
+ });
1688
+ app.post('/assets/upload-file', (req, res, next) => {
1689
+ //上传文件
1690
+ res.set('Content-Type', 'application/json');
1691
+ res.status(201).json(null);
1692
+ });
1693
+ app.post('/assets/upload-confirm', (req, res, next) => {
1694
+ //上传确认
1695
+ const format = {
1696
+ status: 200,
1697
+ message: "<status description>",
1698
+ data: new Date().getTime() % 10000,
1699
+ timestamp: new Date().getTime()
1700
+ };
1701
+
1702
+ //返回
1703
+ res.set('Content-Type', 'application/json');
1704
+ res.status(format.status).json(format);
1705
+ });
1706
+ app.use((err, req, res, next) => {
1707
+ // 500 错误处理(放在路由之后,404 之前)
1708
+ console.error(err.stack); // 打印错误日志
1709
+ res.status(404).sendFile(path.join(__dirname, 'html', '500.html'));
1710
+ });
1711
+ app.use((req, res, next) => {
1712
+ // 404 处理(必须放在所有路由之后)
1713
+ res.status(404).sendFile(path.join(__dirname, 'html', '404.html'));
1714
+ });
1715
+
1716
+ // 启动服务器
1717
+ const port = args.length > 0 ? parseInt(args[0]) : new Date().getTime() % 50000 + 10000;
1718
+ https.createServer({
1719
+ key: fs.readFileSync('localhost.key', 'utf8'),
1720
+ cert: fs.readFileSync('localhost.crt', 'utf8'),
1721
+ }, app).listen(port, () => {
1722
+ console.log(`HTTPS server running at https://localhost:${port}`);
1723
+ });