-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathsketch_jun9b.ino
2337 lines (2089 loc) · 114 KB
/
sketch_jun9b.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
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
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
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
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/**********************************************************************
项目名称/Project : 仅使用ESP32-C3实现支付宝当面付解决方案
程序名称/Program name : Alipayf2f
团队/Team : 青岛迷之科技有限公司 / (www.mizhikeji.com)
作者/Author : 迷之科技点灯开发组(李工)
日期/Date(YYYYMMDD) : 2023/06/09
程序目的/Purpose : 仅使用ESP32C3实现客户访问设备IP实现当面付,付款成功后驱动LED闪烁模拟开门
***********************************************************************/
#include <WiFi.h>
#include <ESPAsyncWebServer.h>
#include "FS.h"
#include <LittleFS.h>
// #include <esp_task_wdt.h>
#include <Arduino.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#define FORMAT_LITTLEFS_IF_FAILED true
//加密算法库
#include <mbedtls/pk.h>
#include <mbedtls/rsa.h>
#include <mbedtls/pem.h> //https://blog.csdn.net/qdlyd/article/details/131084726?spm=1001.2014.3001.5501
#include <mbedtls/sha256.h> //https://blog.csdn.net/imba_wolf/article/details/122417540
#include <mbedtls/ctr_drbg.h> //https://www.trustedfirmware.org/projects/mbed-tls/
#include <mbedtls/entropy.h> //https://johanneskinzig.de/index.php/files/26/Arduino-mbedtls/9/gettingstartedmbedtlsarduino.7z
#include <arduino_base64.hpp> //https://github.com/dojyorin/arduino_base64 随便拉的库 库管理搜base64_encode作者dojyorin
//URL处理
#include <UrlEncode.h>
//UDPz底层库
#include <AsyncUDP.h> //https://github.com/me-no-dev/ESPAsyncUDP
//HTTP客户端
#include <HTTPClient.h>
#include <WiFiClientSecure.h>
//JSON编解码
#include <Arduino_JSON.h>
//时间函数
#define SECS_PER_MIN ((time_t)(60UL))
#define SECS_PER_HOUR ((time_t)(3600UL))
#define SECS_PER_DAY ((time_t)(SECS_PER_HOUR * 24UL))
#define LEAP_YEAR(Y) (((1970 + (Y)) > 0) && !((1970 + (Y)) % 4) && (((1970 + (Y)) % 100) || !((1970 + (Y)) % 400)))
static const uint8_t monthDays[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; // API starts months from 1, this array starts from 0
AsyncUDP udp;
char *ntpServer = "pool.ntp.org"; //time.nist.gov只有协议3 pool.ntp.org CN.NTP.ORG.CN
const unsigned int localPort = 23511;
unsigned long long ntpTime = 0; //最后一次对时距离1900年的秒数
unsigned long timesendudp;
unsigned long timegetudp;
bool needupadte = 1;
//定义了一种传统格里高利时间的结构体
typedef struct {
uint8_t Second;
uint8_t Minute;
uint8_t Hour;
uint8_t Wday; // day of week, Sunday is day 1
uint8_t Day;
uint8_t Month;
uint32_t Year; // offset from 1970;END AY 4294967295YEAR
} tmElement64s_t;
//定义WIFI配置
const char *ssid = "S23"; //
const char *password = "12345678";
const char *dataFile = "/data.txt"; // 存储键值对的文件路径
String websetpassword = "123"; //网页配置密码 1821行
const int LED_PIN = 13;
const int ERROE_PIN = 12;
int i = 1;
int webpassworderrortime = 0; //设置密码测试计时器
int alipayneedasktime = 0; //支付宝轮询剩余秒数
int tresttime = 0; //支付宝轮询剩余秒数
int ORDERNUM = 0; //支付宝轮询剩余秒数
String price[19]; //定义存储价格的价格内存 全局变量 因为浮点数据存在小数分辨率问题
int doorio[19]; //定义一个储存门对应IO的全局数组
String Alipaysign[19]; //定义一个签名字符串数组
uint64_t Alipaysingtime[19]; //定义一个支付宝签名时间数组,用于复原原有签出请求URL
String Alipaylastorder; //最后轮询的订单号
int alipaylastdoor; //使用支付宝渠道的最后提交支付的门号
uint64_t alipaydealtime = 0; //订单生成器种子
uint64_t alipaysigntime[19]; //已签名的订单号
String alipayrootcertsn;
String alipayappcertsn;
String alipayappid;
String alipayprivatekey; //私钥 在内存不足时应使用局部变量
int alipyneedsigndoor = 1; //轮询生成请求字符串
String alipayneedcloseorder; //由于支付宝存在先天BUG,无法关闭未创建的订单,也就是预创建订单,所以轮询关单
//再多的防备,也做不出没有漏洞的系统,如果有人同时生成多笔订单并关闭机器导致线程关闭,再开机也只会关闭最后一笔订单。因此产生的跳单需要商户自行处理
uint64_t alipayneedclosetrytime = 0; //关闭订单轮询结束时间戳
uint64_t alipayneedquerytrytime = 0; //查询订单轮询结束时间戳
String alipayneedqueryorder; //当前需要轮询的订单号
String lastsuccessalipayorder; //最后成交订单号用于误关门重开
TaskHandle_t task1Handle;
AsyncWebServer server(80);
const char *rootCACertificate =
"-----BEGIN CERTIFICATE-----\n"
"MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh\n"
"MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n"
"d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD\n"
"QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT\n"
"MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j\n"
"b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG\n"
"9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB\n"
"CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97\n"
"nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt\n"
"43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P\n"
"T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4\n"
"gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO\n"
"BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR\n"
"TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw\n"
"DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr\n"
"hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg\n"
"06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF\n"
"PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls\n"
"YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk\n"
"CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=\n"
"-----END CERTIFICATE-----\n";
const char *index_html = R"html(
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>售货机-青岛迷之科技提供软件支持</title>
<style>
button {
padding: 10px 20px;
font-size: 16px;
margin-bottom: 10px;
}
</style>
</head>
<body>
<h1>点击按钮支付宝购买<br>注意设备序列号为<br>
)html";
const char *index_html2 = R"html(
<button onclick="sendControlRequest('on')">开启</button>
<button onclick="sendControlRequest('off')">关闭</button><br>
<a href="set">设备后台设置</a>
<script>
function sendControlRequest(state) {
var xhr = new XMLHttpRequest();
xhr.open("GET", "/control?state=" + state, true);
xhr.send();
}
</script>
</body>
</html>)html";
//alipayprivatekey
const char *setwebpassword_html = R"html(<!DOCTYPE html><html><head><meta charset="utf-8"><title>设置密码页</title></head><body><h1>设备密码设置</h1><form action="setwebpassword2"id="f1">原密码<input type="text"id="input1"name="oldpassword"><br>新密码<input type="text"id="input2"name="newpassword"><br></form><button onclick="t()">提交更改</button><!--<input value="提交">-->忘记密码,联系厂家<br><br><br><a href="/"><button>返回主页</button></a><script>function t(){document.getElementById("input1").value=document.getElementById("input1").value.trim();document.getElementById("input2").value=document.getElementById("input2").value.trim();if(/\s/g.test(document.getElementById("input2").value)){alert("不能有空格!!");return true}if(document.getElementById("input2").value.length<=16){document.getElementById('f1').submit()}else{alert("密码过长(需要小于16位)")}}</script></body></html><!--)html";
const char *set_html = R"html(<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>本地设置页</title>
<style>
button {
padding: 10px 20px;
font-size: 16px;
margin-bottom: 10px;
}
</style>
</head>
<body>
<h1>设备设置</h1>
<a href="setwebpassword"><button>设置设备管理密码</button></a><br>
<a href="setalipayprivatekey"><button>设置支付宝参数</button></a><br>
<a href="setalipaypublickey"><button>设置支付宝HTTPS公钥</button></a><br>
<a href="setprice"><button>设置价格</button></a><br>
<a href="time"><button>设置时间</button></a><br>
<a href="setdoorpin"><button>设置门与物理IO管脚对应关系</button></a><br>
<a href="/"><button>返回主页</button></a>
</body>
</html><!--
)html";
const char *setprice_html = R"html(<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta HTTP-EQUIV="pragma" CONTENT="no-cache">
<title>设置价格页</title>
</head>
<body>
<h1>设置价格页</h1>
<h1>价格0元代表关闭购买按钮</h1>
<h1>负价格如-1代表直接按按钮就能开</h1>
<form action="setprice2" id="f1">
配置密码
<input type="text" id="testwebpassword" name="testwebpassword"><br>
商品1价格<input type="text" id="price1" name="price1" value="0.00">元<br>
商品2价格<input type="text" id="price2" name="price2" value="0.00">元<br>
商品3价格<input type="text" id="price3" name="price3" value="0.00">元<br>
商品4价格<input type="text" id="price4" name="price4" value="0.00">元<br>
商品5价格<input type="text" id="price5" name="price5" value="0.00">元<br>
商品6价格<input type="text" id="price6" name="price6" value="0.00">元<br>
商品7价格<input type="text" id="price6" name="price7" value="0.00">元<br>
商品8价格<input type="text" id="price6" name="price8" value="0.00">元<br>
商品9价格<input type="text" id="price6" name="price9" value="0.00">元<br>
商品10价格<input type="text" id="price6" name="price10" value="0.00">元<br>
商品11价格<input type="text" id="price6" name="price11" value="0.00">元<br>
商品12价格<input type="text" id="price6" name="price12" value="0.00">元<br>
商品13价格<input type="text" id="price6" name="price13" value="0.00">元<br>
商品14价格<input type="text" id="price6" name="price14" value="0.00">元<br>
商品15价格<input type="text" id="price6" name="price15" value="0.00">元<br>
商品16价格<input type="text" id="price6" name="price16" value="0.00">元<br>
商品17价格<input type="text" id="price6" name="price17" value="0.00">元<br>
商品18价格<input type="text" id="price6" name="price18" value="0.00">元<br>
</form><button onclick="t()">提交更改</button>
<!--<input value="提交">-->忘记密码,联系厂家<br><br><br><a href="/"><button>返回主页</button></a>
<script>
function t(){document.getElementById('f1').submit()}
</script>
</body>
</html><!--)html";
const char *setdoorpin_html = R"html(<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta HTTP-EQUIV="pragma" CONTENT="no-cache">
<title>设置价格页</title>
</head>
<body>
<h1>门与电器引脚IO对应关系</h1>
<form action="setdoorpin2" id="f1">
配置密码
<input type="text" id="testwebpassword" name="testwebpassword"><br>
门1对应<input type="text" name="doorio1" value="1">号引脚IO<br>
门2对应<input type="text" name="doorio2" value="2">号引脚IO<br>
门3对应<input type="text" name="doorio3" value="3">号引脚IO<br>
门4对应<input type="text" name="doorio4" value="4">号引脚IO<br>
门5对应<input type="text" name="doorio5" value="5">号引脚IO<br>
门6对应<input type="text" name="doorio6" value="6">号引脚IO<br>
门7对应<input type="text" name="doorio7" value="7">号引脚IO<br>
门8对应<input type="text" name="doorio8" value="8">号引脚IO<br>
门9对应<input type="text" name="doorio9" value="9">号引脚IO<br>
门10对应<input type="text" name="doorio10" value="10">号引脚IO<br>
门11对应<input type="text" name="doorio11" value="11">号引脚IO<br>
门12对应<input type="text" name="doorio12" value="12">号引脚IO<br>
门13对应<input type="text" name="doorio13" value="13">号引脚IO<br>
门14对应<input type="text" name="doorio14" value="18">号引脚IO<br>
门15对应<input type="text" name="doorio15" value="19">号引脚IO<br>
门16对应<input type="text" name="doorio16" value="20">号引脚IO<br>
门17对应<input type="text" name="doorio17" value="21">号引脚IO<br>
门18对应<input type="text" name="doorio18" value="0">号引脚IO<br>
门开启时间<input type="text" name="dooropenms" value="2000">毫秒<br>
</form><button onclick="t()">提交更改</button>
<!--<input value="提交">-->忘记密码,联系厂家<br><br>
ESP32-C3 9.9元开发板引脚非常用引脚对应关系
RX0-----IO20影响串口调试<br>
TX0-----IO21影响串口调试<br>
IO12影响正面LED4<br>
IO13影响正面LED5<br>
IO18影响USB调试<br>
IO19影响USB调试<br>
IO9-----IO9-BOOT按钮影响信号<br>
严禁使用IO14-IO15-IO16-IO17会影响程序运行<br>
<br><a href="/"><button>返回主页</button></a>
<script>
function t(){document.getElementById('f1').submit()}
</script>
</body>
</html><!--)html";
// const char* newpasswordhadchange = R"html(<!DOCTYPE html><html><head><meta charset="utf-8"></head><body>已成功更改为新密码,New password have changed</body></html><!--)html";
const char *alipayprivatekey_html = R"html(<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>设置支付宝私钥</title>
</head>
<body>
<h1>设置支付宝私钥</h1>
<form action="setalipayprivatekey2" method="GET" id="f1">支付宝PKCS#1格式私钥64个字符一个回车文件后缀常为pem<br><textarea name="newalipayprivatekey"
rows="25" cols="38" placeholder="-----BEGIN RSA PRIVATE KEY-----
MIIB……PKCS#1私钥64个字符一个回车
-----END RSA PRIVATE KEY-----"></textarea>
<br>支付宝根证书序列号alipay_root_cert_sn<input type="text" name="alipayrootcertsn" value="687b59193f3f462dd5336e5abf83c5d8_02941eef3187dddf3d3b83462e1dfcf6" placeholder="687b59193f3f462dd5336e5abf83c5d8_02941eef3187dddf3d3b83462e1dfcf6">
<br>支付宝应用证书序列号app_cert_sn<input type="text" name="appcertsn">
<br>支付宝项目号app_id<input type="text" name="appid">
<br>各序列号需要用其他语言程序然后抓包获取,也可从官网获得SDK及DEMO
<br>php 应用证书用 getCertSN()根证书用getRootCertSN()方法
<br>密码<input type="text" name="testwebpassword">
<br></form><button
onclick="t()">提交更改</button><!--<input value="提交">-->忘记密码,联系厂家<br><br><br><a href="/"><button>返回主页</button></a>
<script>function t() { document.getElementById('f1').submit() }</script>
</body>
</html><!--)html";
const char *alipaypublickey_html = R"html(<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>设置支付宝私钥</title>
</head>
<body>
<h1>设置支付宝HTTPS公钥</h1><br>
<h1>如果支付宝更换证书提供商需设置</h1>
<form action="setalipaypublickeykey2" method="GET" id="f1">支付宝HTTPS公钥根证书,一般为DigiCert根证书2031年后需要更换平时切误设置<br>更换方法浏览器访问https://openapi.alipay.com/gateway.do点左上角小锁选更多选证书选最上面的根证书选导出仅根证书base64导出后用记事本打开并复制过来<BR><textarea name="newalipaypublickeykey"
rows="25" cols="38">-----BEGIN CERTIFICATE-----
MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
-----END CERTIFICATE-----</textarea>
<br>密码<input type="text" name="testwebpassword">
<br></form><button
onclick="t()">提交更改</button><!--<input value="提交">-->忘记密码,联系厂家<br><br><br><a href="/"><button>返回主页</button></a>
<script>function t() { document.getElementById('f1').submit() }</script>
</body>
</html><!--)html";
//b页面为直接调用页
const char *b_html = R"html(
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>青岛迷之科技智能售货机</title>
<script type="text/javascript" src="/qrcode.min.js"></script>
</head>
<body onload="buy()">
<noscript>
<p>
<h1 style="color:red">
使用本网站必须支持并启用JavaScript<br>如果您不启用将无法使用本网站<br>
</h1>
</p>
</noscript>
<h1 id="tip" style="font-size:3em;word-wrap: break-word;overflow: hidden;" >正在跳转支付,预计5秒</h1><br>
<div id="demo"></div>
<div id="qrcode" style="margin:1em;"></div>
</body>
<script>
function buy() {
var qrwidth;
if(window.screen.height>=window.screen.width){qrwidth=window.screen.width*0.5;}
if(window.screen.height<=window.screen.width){qrwidth=window.screen.height*0.5;}
var qrcode = new QRCode(document.getElementById("qrcode"), {
width : qrwidth,
height : qrwidth
});
// qrcode.makeCode("214");
var xhttpa = new XMLHttpRequest();
var xhttpb = new XMLHttpRequest();
var ask;
var json;
// var qrvalue;
// var obj;
xhttpa.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
ask= this.responseText;
var firstTwoChars = ask.substring(0, 4);
if(firstTwoChars=="http"){
xhttpb.open("GET", ask, true);//第二遍请求支付宝的网关
xhttpb.send();
}else{
document.getElementById("tip").innerHTML ="出现问题"+ask;
}
}
};
xhttpb.onreadystatechange = function () {
json= this.responseText;//支付宝返回的JSON字符串
const obj = JSON.parse(json);
if(obj.alipay_trade_precreate_response.code!=10000){document.getElementById("demo").innerHTML ="未请求成功:"+obj.alipay_trade_precreate_response.sub_msg+this.responseText;}
else if(/AlipayClient/.test(window.navigator.userAgent)){
window.location.replace(obj.alipay_trade_precreate_response.qr_code);
}else{qrcode.makeCode(obj.alipay_trade_precreate_response.qr_code);
document.getElementById("tip").innerHTML ="支付宝扫码完成支付";
}
}
xhttpa.open("GET", "/buy?door="+GetQueryString("d"), true);//第一遍请求本地服务器索取请求Alipay的地址
xhttpa.send();
}
function GetQueryString(name)
{
var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)");
var r = window.location.search.substr(1).match(reg);
if(r!=null)return unescape(r[2]); return null;
}
</script>
</html>
<!--
)html";
String rethtml(String str) {
String ret;
const char *head_html = R"html(<!DOCTYPE html><html><head><meta charset="utf-8"></head><body>)html";
const char *feet_html = R"html(</body></html><!--)html";
// char charMAX[str.length()+1]; // 做一个获取MAC地址的输出缓冲区
// str.toCharArray(charMAX, sizeof(charMAX)); // 将MAC地址输出到char类型中
ret = head_html;
ret += str;
ret += feet_html;
// Serial.println(ret);
return ret;
}
const char *qrcodeminjs = R"html(var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,this.data=a,this.parsedData=[];for(var b=[],d=0,e=this.data.length;e>d;d++){var f=this.data.charCodeAt(d);f>65536?(b[0]=240|(1835008&f)>>>18,b[1]=128|(258048&f)>>>12,b[2]=128|(4032&f)>>>6,b[3]=128|63&f):f>2048?(b[0]=224|(61440&f)>>>12,b[1]=128|(4032&f)>>>6,b[2]=128|63&f):f>128?(b[0]=192|(1984&f)>>>6,b[1]=128|63&f):b[0]=f,this.parsedData=this.parsedData.concat(b)}this.parsedData.length!=this.data.length&&(this.parsedData.unshift(191),this.parsedData.unshift(187),this.parsedData.unshift(239))}function b(a,b){this.typeNumber=a,this.errorCorrectLevel=b,this.modules=null,this.moduleCount=0,this.dataCache=null,this.dataList=[]}function i(a,b){if(void 0==a.length)throw new Error(a.length+"/"+b);for(var c=0;c<a.length&&0==a[c];)c++;this.num=new Array(a.length-c+b);for(var d=0;d<a.length-c;d++)this.num[d]=a[d+c]}function j(a,b){this.totalCount=a,this.dataCount=b}function k(){this.buffer=[],this.length=0}function m(){return"undefined"!=typeof CanvasRenderingContext2D}function n(){var a=!1,b=navigator.userAgent;return/android/i.test(b)&&(a=!0,aMat=b.toString().match(/android ([0-9]\.[0-9])/i),aMat&&aMat[1]&&(a=parseFloat(aMat[1]))),a}function r(a,b){for(var c=1,e=s(a),f=0,g=l.length;g>=f;f++){var h=0;switch(b){case d.L:h=l[f][0];break;case d.M:h=l[f][1];break;case d.Q:h=l[f][2];break;case d.H:h=l[f][3]}if(h>=e)break;c++}if(c>l.length)throw new Error("Too long data");return c}function s(a){var b=encodeURI(a).toString().replace(/\%[0-9a-fA-F]{2}/g,"a");return b.length+(b.length!=a?3:0)}a.prototype={getLength:function(){return this.parsedData.length},write:function(a){for(var b=0,c=this.parsedData.length;c>b;b++)a.put(this.parsedData[b],8)}},b.prototype={addData:function(b){var c=new a(b);this.dataList.push(c),this.dataCache=null},isDark:function(a,b){if(0>a||this.moduleCount<=a||0>b||this.moduleCount<=b)throw new Error(a+","+b);return this.modules[a][b]},getModuleCount:function(){return this.moduleCount},make:function(){this.makeImpl(!1,this.getBestMaskPattern())},makeImpl:function(a,c){this.moduleCount=4*this.typeNumber+17,this.modules=new Array(this.moduleCount);for(var d=0;d<this.moduleCount;d++){this.modules[d]=new Array(this.moduleCount);for(var e=0;e<this.moduleCount;e++)this.modules[d][e]=null}this.setupPositionProbePattern(0,0),this.setupPositionProbePattern(this.moduleCount-7,0),this.setupPositionProbePattern(0,this.moduleCount-7),this.setupPositionAdjustPattern(),this.setupTimingPattern(),this.setupTypeInfo(a,c),this.typeNumber>=7&&this.setupTypeNumber(a),null==this.dataCache&&(this.dataCache=b.createData(this.typeNumber,this.errorCorrectLevel,this.dataList)),this.mapData(this.dataCache,c)},setupPositionProbePattern:function(a,b){for(var c=-1;7>=c;c++)if(!(-1>=a+c||this.moduleCount<=a+c))for(var d=-1;7>=d;d++)-1>=b+d||this.moduleCount<=b+d||(this.modules[a+c][b+d]=c>=0&&6>=c&&(0==d||6==d)||d>=0&&6>=d&&(0==c||6==c)||c>=2&&4>=c&&d>=2&&4>=d?!0:!1)},getBestMaskPattern:function(){for(var a=0,b=0,c=0;8>c;c++){this.makeImpl(!0,c);var d=f.getLostPoint(this);(0==c||a>d)&&(a=d,b=c)}return b},createMovieClip:function(a,b,c){var d=a.createEmptyMovieClip(b,c),e=1;this.make();for(var f=0;f<this.modules.length;f++)for(var g=f*e,h=0;h<this.modules[f].length;h++){var i=h*e,j=this.modules[f][h];j&&(d.beginFill(0,100),d.moveTo(i,g),d.lineTo(i+e,g),d.lineTo(i+e,g+e),d.lineTo(i,g+e),d.endFill())}return d},setupTimingPattern:function(){for(var a=8;a<this.moduleCount-8;a++)null==this.modules[a][6]&&(this.modules[a][6]=0==a%2);for(var b=8;b<this.moduleCount-8;b++)null==this.modules[6][b]&&(this.modules[6][b]=0==b%2)},setupPositionAdjustPattern:function(){for(var a=f.getPatternPosition(this.typeNumber),b=0;b<a.length;b++)for(var c=0;c<a.length;c++){var d=a[b],e=a[c];if(null==this.modules[d][e])for(var g=-2;2>=g;g++)for(var h=-2;2>=h;h++)this.modules[d+g][e+h]=-2==g||2==g||-2==h||2==h||0==g&&0==h?!0:!1}},setupTypeNumber:function(a){for(var b=f.getBCHTypeNumber(this.typeNumber),c=0;18>c;c++){var d=!a&&1==(1&b>>c);this.modules[Math.floor(c/3)][c%3+this.moduleCount-8-3]=d}for(var c=0;18>c;c++){var d=!a&&1==(1&b>>c);this.modules[c%3+this.moduleCount-8-3][Math.floor(c/3)]=d}},setupTypeInfo:function(a,b){for(var c=this.errorCorrectLevel<<3|b,d=f.getBCHTypeInfo(c),e=0;15>e;e++){var g=!a&&1==(1&d>>e);6>e?this.modules[e][8]=g:8>e?this.modules[e+1][8]=g:this.modules[this.moduleCount-15+e][8]=g}for(var e=0;15>e;e++){var g=!a&&1==(1&d>>e);8>e?this.modules[8][this.moduleCount-e-1]=g:9>e?this.modules[8][15-e-1+1]=g:this.modules[8][15-e-1]=g}this.modules[this.moduleCount-8][8]=!a},mapData:function(a,b){for(var c=-1,d=this.moduleCount-1,e=7,g=0,h=this.moduleCount-1;h>0;h-=2)for(6==h&&h--;;){for(var i=0;2>i;i++)if(null==this.modules[d][h-i]){var j=!1;g<a.length&&(j=1==(1&a[g]>>>e));var k=f.getMask(b,d,h-i);k&&(j=!j),this.modules[d][h-i]=j,e--,-1==e&&(g++,e=7)}if(d+=c,0>d||this.moduleCount<=d){d-=c,c=-c;break}}}},b.PAD0=236,b.PAD1=17,b.createData=function(a,c,d){for(var e=j.getRSBlocks(a,c),g=new k,h=0;h<d.length;h++){var i=d[h];g.put(i.mode,4),g.put(i.getLength(),f.getLengthInBits(i.mode,a)),i.write(g)}for(var l=0,h=0;h<e.length;h++)l+=e[h].dataCount;if(g.getLengthInBits()>8*l)throw new Error("code length overflow. ("+g.getLengthInBits()+">"+8*l+")");for(g.getLengthInBits()+4<=8*l&&g.put(0,4);0!=g.getLengthInBits()%8;)g.putBit(!1);for(;;){if(g.getLengthInBits()>=8*l)break;if(g.put(b.PAD0,8),g.getLengthInBits()>=8*l)break;g.put(b.PAD1,8)}return b.createBytes(g,e)},b.createBytes=function(a,b){for(var c=0,d=0,e=0,g=new Array(b.length),h=new Array(b.length),j=0;j<b.length;j++){var k=b[j].dataCount,l=b[j].totalCount-k;d=Math.max(d,k),e=Math.max(e,l),g[j]=new Array(k);for(var m=0;m<g[j].length;m++)g[j][m]=255&a.buffer[m+c];c+=k;var n=f.getErrorCorrectPolynomial(l),o=new i(g[j],n.getLength()-1),p=o.mod(n);h[j]=new Array(n.getLength()-1);for(var m=0;m<h[j].length;m++){var q=m+p.getLength()-h[j].length;h[j][m]=q>=0?p.get(q):0}}for(var r=0,m=0;m<b.length;m++)r+=b[m].totalCount;for(var s=new Array(r),t=0,m=0;d>m;m++)for(var j=0;j<b.length;j++)m<g[j].length&&(s[t++]=g[j][m]);for(var m=0;e>m;m++)for(var j=0;j<b.length;j++)m<h[j].length&&(s[t++]=h[j][m]);return s};for(var c={MODE_NUMBER:1,MODE_ALPHA_NUM:2,MODE_8BIT_BYTE:4,MODE_KANJI:8},d={L:1,M:0,Q:3,H:2},e={PATTERN000:0,PATTERN001:1,PATTERN010:2,PATTERN011:3,PATTERN100:4,PATTERN101:5,PATTERN110:6,PATTERN111:7},f={PATTERN_POSITION_TABLE:[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]],G15:1335,G18:7973,G15_MASK:21522,getBCHTypeInfo:function(a){for(var b=a<<10;f.getBCHDigit(b)-f.getBCHDigit(f.G15)>=0;)b^=f.G15<<f.getBCHDigit(b)-f.getBCHDigit(f.G15);return(a<<10|b)^f.G15_MASK},getBCHTypeNumber:function(a){for(var b=a<<12;f.getBCHDigit(b)-f.getBCHDigit(f.G18)>=0;)b^=f.G18<<f.getBCHDigit(b)-f.getBCHDigit(f.G18);return a<<12|b},getBCHDigit:function(a){for(var b=0;0!=a;)b++,a>>>=1;return b},getPatternPosition:function(a){return f.PATTERN_POSITION_TABLE[a-1]},getMask:function(a,b,c){switch(a){case e.PATTERN000:return 0==(b+c)%2;case e.PATTERN001:return 0==b%2;case e.PATTERN010:return 0==c%3;case e.PATTERN011:return 0==(b+c)%3;case e.PATTERN100:return 0==(Math.floor(b/2)+Math.floor(c/3))%2;case e.PATTERN101:return 0==b*c%2+b*c%3;case e.PATTERN110:return 0==(b*c%2+b*c%3)%2;case e.PATTERN111:return 0==(b*c%3+(b+c)%2)%2;default:throw new Error("bad maskPattern:"+a)}},getErrorCorrectPolynomial:function(a){for(var b=new i([1],0),c=0;a>c;c++)b=b.multiply(new i([1,g.gexp(c)],0));return b},getLengthInBits:function(a,b){if(b>=1&&10>b)switch(a){case c.MODE_NUMBER:return 10;case c.MODE_ALPHA_NUM:return 9;case c.MODE_8BIT_BYTE:return 8;case c.MODE_KANJI:return 8;default:throw new Error("mode:"+a)}else if(27>b)switch(a){case c.MODE_NUMBER:return 12;case c.MODE_ALPHA_NUM:return 11;case c.MODE_8BIT_BYTE:return 16;case c.MODE_KANJI:return 10;default:throw new Error("mode:"+a)}else{if(!(41>b))throw new Error("type:"+b);switch(a){case c.MODE_NUMBER:return 14;case c.MODE_ALPHA_NUM:return 13;case c.MODE_8BIT_BYTE:return 16;case c.MODE_KANJI:return 12;default:throw new Error("mode:"+a)}}},getLostPoint:function(a){for(var b=a.getModuleCount(),c=0,d=0;b>d;d++)for(var e=0;b>e;e++){for(var f=0,g=a.isDark(d,e),h=-1;1>=h;h++)if(!(0>d+h||d+h>=b))for(var i=-1;1>=i;i++)0>e+i||e+i>=b||(0!=h||0!=i)&&g==a.isDark(d+h,e+i)&&f++;f>5&&(c+=3+f-5)}for(var d=0;b-1>d;d++)for(var e=0;b-1>e;e++){var j=0;a.isDark(d,e)&&j++,a.isDark(d+1,e)&&j++,a.isDark(d,e+1)&&j++,a.isDark(d+1,e+1)&&j++,(0==j||4==j)&&(c+=3)}for(var d=0;b>d;d++)for(var e=0;b-6>e;e++)a.isDark(d,e)&&!a.isDark(d,e+1)&&a.isDark(d,e+2)&&a.isDark(d,e+3)&&a.isDark(d,e+4)&&!a.isDark(d,e+5)&&a.isDark(d,e+6)&&(c+=40);for(var e=0;b>e;e++)for(var d=0;b-6>d;d++)a.isDark(d,e)&&!a.isDark(d+1,e)&&a.isDark(d+2,e)&&a.isDark(d+3,e)&&a.isDark(d+4,e)&&!a.isDark(d+5,e)&&a.isDark(d+6,e)&&(c+=40);for(var k=0,e=0;b>e;e++)for(var d=0;b>d;d++)a.isDark(d,e)&&k++;var l=Math.abs(100*k/b/b-50)/5;return c+=10*l}},g={glog:function(a){if(1>a)throw new Error("glog("+a+")");return g.LOG_TABLE[a]},gexp:function(a){for(;0>a;)a+=255;for(;a>=256;)a-=255;return g.EXP_TABLE[a]},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)},h=0;8>h;h++)g.EXP_TABLE[h]=1<<h;for(var h=8;256>h;h++)g.EXP_TABLE[h]=g.EXP_TABLE[h-4]^g.EXP_TABLE[h-5]^g.EXP_TABLE[h-6]^g.EXP_TABLE[h-8];for(var h=0;255>h;h++)g.LOG_TABLE[g.EXP_TABLE[h]]=h;i.prototype={get:function(a){return this.num[a]},getLength:function(){return this.num.length},multiply:function(a){for(var b=new Array(this.getLength()+a.getLength()-1),c=0;c<this.getLength();c++)for(var d=0;d<a.getLength();d++)b[c+d]^=g.gexp(g.glog(this.get(c))+g.glog(a.get(d)));return new i(b,0)},mod:function(a){if(this.getLength()-a.getLength()<0)return this;for(var b=g.glog(this.get(0))-g.glog(a.get(0)),c=new Array(this.getLength()),d=0;d<this.getLength();d++)c[d]=this.get(d);for(var d=0;d<a.getLength();d++)c[d]^=g.gexp(g.glog(a.get(d))+b);return new i(c,0).mod(a)}},j.RS_BLOCK_TABLE=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16],[4,101,81],[1,80,50,4,81,51],[4,50,22,4,51,23],[3,36,12,8,37,13],[2,116,92,2,117,93],[6,58,36,2,59,37],[4,46,20,6,47,21],[7,42,14,4,43,15],[4,133,107],[8,59,37,1,60,38],[8,44,20,4,45,21],[12,33,11,4,34,12],[3,145,115,1,146,116],[4,64,40,5,65,41],[11,36,16,5,37,17],[11,36,12,5,37,13],[5,109,87,1,110,88],[5,65,41,5,66,42],[5,54,24,7,55,25],[11,36,12],[5,122,98,1,123,99],[7,73,45,3,74,46],[15,43,19,2,44,20],[3,45,15,13,46,16],[1,135,107,5,136,108],[10,74,46,1,75,47],[1,50,22,15,51,23],[2,42,14,17,43,15],[5,150,120,1,151,121],[9,69,43,4,70,44],[17,50,22,1,51,23],[2,42,14,19,43,15],[3,141,113,4,142,114],[3,70,44,11,71,45],[17,47,21,4,48,22],[9,39,13,16,40,14],[3,135,107,5,136,108],[3,67,41,13,68,42],[15,54,24,5,55,25],[15,43,15,10,44,16],[4,144,116,4,145,117],[17,68,42],[17,50,22,6,51,23],[19,46,16,6,47,17],[2,139,111,7,140,112],[17,74,46],[7,54,24,16,55,25],[34,37,13],[4,151,121,5,152,122],[4,75,47,14,76,48],[11,54,24,14,55,25],[16,45,15,14,46,16],[6,147,117,4,148,118],[6,73,45,14,74,46],[11,54,24,16,55,25],[30,46,16,2,47,17],[8,132,106,4,133,107],[8,75,47,13,76,48],[7,54,24,22,55,25],[22,45,15,13,46,16],[10,142,114,2,143,115],[19,74,46,4,75,47],[28,50,22,6,51,23],[33,46,16,4,47,17],[8,152,122,4,153,123],[22,73,45,3,74,46],[8,53,23,26,54,24],[12,45,15,28,46,16],[3,147,117,10,148,118],[3,73,45,23,74,46],[4,54,24,31,55,25],[11,45,15,31,46,16],[7,146,116,7,147,117],[21,73,45,7,74,46],[1,53,23,37,54,24],[19,45,15,26,46,16],[5,145,115,10,146,116],[19,75,47,10,76,48],[15,54,24,25,55,25],[23,45,15,25,46,16],[13,145,115,3,146,116],[2,74,46,29,75,47],[42,54,24,1,55,25],[23,45,15,28,46,16],[17,145,115],[10,74,46,23,75,47],[10,54,24,35,55,25],[19,45,15,35,46,16],[17,145,115,1,146,116],[14,74,46,21,75,47],[29,54,24,19,55,25],[11,45,15,46,46,16],[13,145,115,6,146,116],[14,74,46,23,75,47],[44,54,24,7,55,25],[59,46,16,1,47,17],[12,151,121,7,152,122],[12,75,47,26,76,48],[39,54,24,14,55,25],[22,45,15,41,46,16],[6,151,121,14,152,122],[6,75,47,34,76,48],[46,54,24,10,55,25],[2,45,15,64,46,16],[17,152,122,4,153,123],[29,74,46,14,75,47],[49,54,24,10,55,25],[24,45,15,46,46,16],[4,152,122,18,153,123],[13,74,46,32,75,47],[48,54,24,14,55,25],[42,45,15,32,46,16],[20,147,117,4,148,118],[40,75,47,7,76,48],[43,54,24,22,55,25],[10,45,15,67,46,16],[19,148,118,6,149,119],[18,75,47,31,76,48],[34,54,24,34,55,25],[20,45,15,61,46,16]],j.getRSBlocks=function(a,b){var c=j.getRsBlockTable(a,b);if(void 0==c)throw new Error("bad rs block @ typeNumber:"+a+"/errorCorrectLevel:"+b);for(var d=c.length/3,e=[],f=0;d>f;f++)for(var g=c[3*f+0],h=c[3*f+1],i=c[3*f+2],k=0;g>k;k++)e.push(new j(h,i));return e},j.getRsBlockTable=function(a,b){switch(b){case d.L:return j.RS_BLOCK_TABLE[4*(a-1)+0];case d.M:return j.RS_BLOCK_TABLE[4*(a-1)+1];case d.Q:return j.RS_BLOCK_TABLE[4*(a-1)+2];case d.H:return j.RS_BLOCK_TABLE[4*(a-1)+3];default:return void 0}},k.prototype={get:function(a){var b=Math.floor(a/8);return 1==(1&this.buffer[b]>>>7-a%8)},put:function(a,b){for(var c=0;b>c;c++)this.putBit(1==(1&a>>>b-c-1))},getLengthInBits:function(){return this.length},putBit:function(a){var b=Math.floor(this.length/8);this.buffer.length<=b&&this.buffer.push(0),a&&(this.buffer[b]|=128>>>this.length%8),this.length++}};var l=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]],o=function(){var a=function(a,b){this._el=a,this._htOption=b};return a.prototype.draw=function(a){function g(a,b){var c=document.createElementNS("http://www.w3.org/2000/svg",a);for(var d in b)b.hasOwnProperty(d)&&c.setAttribute(d,b[d]);return c}var b=this._htOption,c=this._el,d=a.getModuleCount();Math.floor(b.width/d),Math.floor(b.height/d),this.clear();var h=g("svg",{viewBox:"0 0 "+String(d)+" "+String(d),width:"100%",height:"100%",fill:b.colorLight});h.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:xlink","http://www.w3.org/1999/xlink"),c.appendChild(h),h.appendChild(g("rect",{fill:b.colorDark,width:"1",height:"1",id:"template"}));for(var i=0;d>i;i++)for(var j=0;d>j;j++)if(a.isDark(i,j)){var k=g("use",{x:String(i),y:String(j)});k.setAttributeNS("http://www.w3.org/1999/xlink","href","#template"),h.appendChild(k)}},a.prototype.clear=function(){for(;this._el.hasChildNodes();)this._el.removeChild(this._el.lastChild)},a}(),p="svg"===document.documentElement.tagName.toLowerCase(),q=p?o:m()?function(){function a(){this._elImage.src=this._elCanvas.toDataURL("image/png"),this._elImage.style.display="block",this._elCanvas.style.display="none"}function d(a,b){var c=this;if(c._fFail=b,c._fSuccess=a,null===c._bSupportDataURI){var d=document.createElement("img"),e=function(){c._bSupportDataURI=!1,c._fFail&&_fFail.call(c)},f=function(){c._bSupportDataURI=!0,c._fSuccess&&c._fSuccess.call(c)};return d.onabort=e,d.onerror=e,d.onload=f,d.src="data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==",void 0}c._bSupportDataURI===!0&&c._fSuccess?c._fSuccess.call(c):c._bSupportDataURI===!1&&c._fFail&&c._fFail.call(c)}if(this._android&&this._android<=2.1){var b=1/window.devicePixelRatio,c=CanvasRenderingContext2D.prototype.drawImage;CanvasRenderingContext2D.prototype.drawImage=function(a,d,e,f,g,h,i,j){if("nodeName"in a&&/img/i.test(a.nodeName))for(var l=arguments.length-1;l>=1;l--)arguments[l]=arguments[l]*b;else"undefined"==typeof j&&(arguments[1]*=b,arguments[2]*=b,arguments[3]*=b,arguments[4]*=b);c.apply(this,arguments)}}var e=function(a,b){this._bIsPainted=!1,this._android=n(),this._htOption=b,this._elCanvas=document.createElement("canvas"),this._elCanvas.width=b.width,this._elCanvas.height=b.height,a.appendChild(this._elCanvas),this._el=a,this._oContext=this._elCanvas.getContext("2d"),this._bIsPainted=!1,this._elImage=document.createElement("img"),this._elImage.style.display="none",this._el.appendChild(this._elImage),this._bSupportDataURI=null};return e.prototype.draw=function(a){var b=this._elImage,c=this._oContext,d=this._htOption,e=a.getModuleCount(),f=d.width/e,g=d.height/e,h=Math.round(f),i=Math.round(g);b.style.display="none",this.clear();for(var j=0;e>j;j++)for(var k=0;e>k;k++){var l=a.isDark(j,k),m=k*f,n=j*g;c.strokeStyle=l?d.colorDark:d.colorLight,c.lineWidth=1,c.fillStyle=l?d.colorDark:d.colorLight,c.fillRect(m,n,f,g),c.strokeRect(Math.floor(m)+.5,Math.floor(n)+.5,h,i),c.strokeRect(Math.ceil(m)-.5,Math.ceil(n)-.5,h,i)}this._bIsPainted=!0},e.prototype.makeImage=function(){this._bIsPainted&&d.call(this,a)},e.prototype.isPainted=function(){return this._bIsPainted},e.prototype.clear=function(){this._oContext.clearRect(0,0,this._elCanvas.width,this._elCanvas.height),this._bIsPainted=!1},e.prototype.round=function(a){return a?Math.floor(1e3*a)/1e3:a},e}():function(){var a=function(a,b){this._el=a,this._htOption=b};return a.prototype.draw=function(a){for(var b=this._htOption,c=this._el,d=a.getModuleCount(),e=Math.floor(b.width/d),f=Math.floor(b.height/d),g=['<table style="border:0;border-collapse:collapse;">'],h=0;d>h;h++){g.push("<tr>");for(var i=0;d>i;i++)g.push('<td style="border:0;border-collapse:collapse;padding:0;margin:0;width:'+e+"px;height:"+f+"px;background-color:"+(a.isDark(h,i)?b.colorDark:b.colorLight)+';"></td>');g.push("</tr>")}g.push("</table>"),c.innerHTML=g.join("");var j=c.childNodes[0],k=(b.width-j.offsetWidth)/2,l=(b.height-j.offsetHeight)/2;k>0&&l>0&&(j.style.margin=l+"px "+k+"px")},a.prototype.clear=function(){this._el.innerHTML=""},a}();QRCode=function(a,b){if(this._htOption={width:256,height:256,typeNumber:4,colorDark:"#000000",colorLight:"#ffffff",correctLevel:d.H},"string"==typeof b&&(b={text:b}),b)for(var c in b)this._htOption[c]=b[c];"string"==typeof a&&(a=document.getElementById(a)),this._android=n(),this._el=a,this._oQRCode=null,this._oDrawing=new q(this._el,this._htOption),this._htOption.text&&this.makeCode(this._htOption.text)},QRCode.prototype.makeCode=function(a){this._oQRCode=new b(r(a,this._htOption.correctLevel),this._htOption.correctLevel),this._oQRCode.addData(a),this._oQRCode.make(),this._el.title=a,this._oDrawing.draw(this._oQRCode),this.makeImage()},QRCode.prototype.makeImage=function(){"function"==typeof this._oDrawing.makeImage&&(!this._android||this._android>=3)&&this._oDrawing.makeImage()},QRCode.prototype.clear=function(){this._oDrawing.clear()},QRCode.CorrectLevel=d}();)html";
//清零重置密码计数器
void taskcleanwebpassworderrortime(void *pvParameters) {
// pinMode(12, OUTPUT);
while (1) {
// digitalWrite(12, HIGH);
// vTaskDelay(1000 / portTICK_PERIOD_MS); // 闪烁频率1Hz
// digitalWrite(12, LOW);
// vTaskDelay(1000 / portTICK_PERIOD_MS); // 闪烁频率1Hz
if (webpassworderrortime > 0) { webpassworderrortime--; }
if (alipayneedasktime > 0) {
if (alipayneedasktime % 6 == 0) {
// checkalipayorder();
}
if (alipayneedasktime == 1) {
saveKeyValue("alipayneedasktime", String("0"));
}
alipayneedasktime--;
}
//反复轮询不停的预生产二维码请求字符串
// prealipayf2fpay(needsigndoor);
// Serial.println("测试预生产URL");
// Serial.println("预生产URL");
// Serial.println(needsigndoor);
// needsigndoor++;
// if(needsigndoor>=19){needsigndoor=1;}
vTaskDelay(1000 / portTICK_PERIOD_MS); // 闪烁频率1Hz
}
}
// 保存键值对到文件
void saveKeyValue(const String &key, const String &value) {
String filePath = "/" + key + ".txt";
File file = LittleFS.open(filePath, "w");
if (file) {
file.print(value);
file.close();
} else {
Serial.println("Failed to open file for writing");
}
}
String getValueByKey(const String &key) {
String filePath = "/" + key + ".txt";
String value = "";
File file = LittleFS.open(filePath, "r");
if (file) {
value = file.readString();
file.close();
} else {
Serial.println("Failed to open file for reading");
}
return value;
}
void handleRoot(AsyncWebServerRequest *request) { //主页代码拼接出注意事项然后写死
String result; //做一个2k的输出缓冲区
String strMAC = WiFi.macAddress(); //获取MAC地址
// char charMAC[18]; //做一个获取MAC地址的输出缓冲区
// strMAC.toCharArray(charMAC, sizeof(charMAC)); //将MAC地址输出到CHAR类型中
result = String(index_html);
result += strMAC;
result += "</h1>";
// <button>购买1号商品元</button>
int i = 1;
for (i; i < 19; i++) {
String str = "price";
str += String(i);
if (getValueByKey(str).toDouble() != 0.00) {
result += "<a href=\"b?d=";
result += i;
// result+= "&mac=";
// result+=strMAC;
result += "\"><button>购买";
result += String(i);
result += "号商品";
if (getValueByKey(str).toDouble() >= 0.01) {
result += getValueByKey(str);
} else {
result += String("0.00");
}
result += "元</button><br></a>";
}
}
result += String(index_html2);
request->send(200, "text/html", result);
}
void handleset(AsyncWebServerRequest *request) {
// request->send(200, "text/plain", "LED state: " + state);
request->send(200, "text/html", set_html);
}
void handlesetwebpassword(AsyncWebServerRequest *request) {
// request->send(200, "text/plain", "LED state: " + state);
request->send(200, "text/html", setwebpassword_html);
}
void handlesetwebpassword2(AsyncWebServerRequest *request) {
Serial.println(websetpassword);
if (webpassworderrortime) {
//如果重试计时器未归零让客户等计时器
char result[20];
itoa(webpassworderrortime, result, 10);
strcat(result, "sWait");
request->send(200, "text/html", result);
return;
}
String oldpassword = request->arg("oldpassword");
String newpassword = request->arg("newpassword");
if (newpassword.equals("")) {
request->send(200, "text/html", rethtml("新密码不能为空"));
return;
}
if (oldpassword.equals(websetpassword)) {
//如果旧密码和储存的密码一致
//则更新内存和硬盘中的密码
saveKeyValue("websetpassword", newpassword);
websetpassword = newpassword;
request->send(200, "text/html", rethtml("已成功更改为新密码")); //
return;
} else {
webpassworderrortime = 15;
Serial.println("输入的旧密码");
Serial.println(oldpassword);
Serial.println("设备内部的密码");
Serial.println(websetpassword);
request->send(200, "text/html", rethtml("旧密码核验不通过"));
}
}
void handleControl(AsyncWebServerRequest *request) {
String state = request->arg("state");
if (state == "on") {
digitalWrite(LED_PIN, HIGH);
} else if (state == "off") {
digitalWrite(LED_PIN, LOW);
}
// Serial.println(Sendalipay(getalipaytradeclosestr("202108230101010017b")));
request->send(200, "text/plain", "LED state: " + state);
}
void handlesetalipayprivatekey(AsyncWebServerRequest *request) {
request->send(200, "text/html", alipayprivatekey_html);
}
void handlesetalipayprivatekey2(AsyncWebServerRequest *request) {
String newalipayprivatekey = request->arg("newalipayprivatekey");
String testwebpassword = request->arg("testwebpassword");
String alipayrootcertsnweb = request->arg("alipayrootcertsn");
String appcertsnweb = request->arg("appcertsn");
String appidweb = request->arg("appid");
if (newalipayprivatekey.length() < 1) { request->send(400, "text/html", rethtml("私钥不能为空")); }
if (testwebpassword.length() < 1) { request->send(400, "text/html", rethtml("密码不能为空")); }
if (alipayrootcertsnweb.length() < 1) { request->send(400, "text/html", rethtml("支付宝根证书序列号不能为空")); }
if (appcertsnweb.length() < 1) { request->send(400, "text/html", rethtml("应用证书序列号不能为空")); }
if (appidweb.length() < 1) { request->send(400, "text/html", rethtml("APPID不能为空")); }
//如果重试计时器未归零让客户等计时器
if (webpassworderrortime) {
char result[20];
itoa(webpassworderrortime, result, 10);
strcat(result, "sWait");
request->send(200, "text/html", result);
return;
}
//如果设备密码错误
if (!testwebpassword.equals(websetpassword)) {
webpassworderrortime = 15;
request->send(200, "text/html", rethtml("旧密码核验不通过,Old password not right"));
return;
}
//如果密码正确验证私钥合规性
mbedtls_pk_context privatekey; //建立一个结构体 privatekey 函数执行结束后该结构体会删除
mbedtls_pk_init(&privatekey);
// const char* charnewalipayprivatekey =newalipayprivatekey.c_str();//临时常量字符数组指针=创建一个char类型数据缓存为下一步填充密钥做准备
char charArray[newalipayprivatekey.length() + 1];
newalipayprivatekey.toCharArray(charArray, sizeof(charArray));
int ret = mbedtls_pk_parse_key(&privatekey, (const unsigned char *)charArray, strlen(charArray) + 1, NULL, 0);
if (ret != 0) {
request->send(200, "text/html", rethtml("支付宝私钥不合格alipayprivatekey not right"));
return;
}
saveKeyValue("alipayprivatekey", newalipayprivatekey);
alipayprivatekey = newalipayprivatekey;
saveKeyValue("alipayrootcertsn", alipayrootcertsnweb);
alipayrootcertsn = alipayrootcertsnweb;
saveKeyValue("appcertsn", appcertsnweb);
alipayappcertsn = appcertsnweb;
saveKeyValue("appid", appidweb);
alipayappid = appidweb;
request->send(200, "text/html", rethtml("支付宝参数已存储 alipay parameter saved"));
return;
}
//设置支付宝HTTPS公钥
void handlesetalipaypublickey(AsyncWebServerRequest *request) {
request->send(200, "text/html", alipaypublickey_html);
}
void handlesetalipaypublickey2(AsyncWebServerRequest *request) {
String newalipaypublickeykey = request->arg("newalipaypublickeykey");
String testwebpassword = request->arg("testwebpassword");
if (newalipaypublickeykey.length() < 1) { request->send(400, "text/html", rethtml("私钥不能为空")); }
if (testwebpassword.length() < 1) { request->send(400, "text/html", rethtml("密码不能为空")); }
//如果重试计时器未归零让客户等计时器
if (webpassworderrortime) {
char result[20];
itoa(webpassworderrortime, result, 10);
strcat(result, "sWait");
request->send(200, "text/html", result);
return;
}
//如果设备密码错误
if (!testwebpassword.equals(websetpassword)) {
webpassworderrortime = 15;
request->send(200, "text/html", rethtml("旧密码核验不通过,Old password not right"));
return;
}
//如果密码正确验证私钥合规性
// mbedtls_pk_context privatekey; //建立一个结构体 privatekey 函数执行结束后该结构体会删除
// mbedtls_pk_init(&privatekey);
// // const char* charnewalipayprivatekey =newalipayprivatekey.c_str();//临时常量字符数组指针=创建一个char类型数据缓存为下一步填充密钥做准备
// char charArray[newalipayprivatekey.length() + 1];
// newalipayprivatekey.toCharArray(charArray, sizeof(charArray));
// int ret = mbedtls_pk_parse_key(&privatekey, (const unsigned char *)charArray, strlen(charArray) + 1, NULL, 0);
// if (ret != 0) {
// request->send(200, "text/html", rethtml("支付宝私钥不合格alipayprivatekey not right"));
// return;
// }
saveKeyValue("alipayhttpspublickeykey", newalipaypublickeykey);
request->send(200, "text/html", rethtml("支付宝https公钥已存储 alipay https publickeykey saved"));
return;
}
//直调跳转 一个门上一个码扫了付钱就走
void handleb(AsyncWebServerRequest *request) {
request->send(200, "text/html", b_html);
}
void handlesetqrcodeminjs(AsyncWebServerRequest *request) {
request->send(200, "text/js", qrcodeminjs);
}
void handlesetprice(AsyncWebServerRequest *request) {
request->send(200, "text/html", setprice_html);
}
void handlesetprice2(AsyncWebServerRequest *request) {
String testwebpassword = request->arg("testwebpassword");
String price1 = String(request->arg("price1").toDouble(), 2);
String price2 = String(request->arg("price2").toDouble(), 2);
String price3 = String(request->arg("price3").toDouble(), 2);
String price4 = String(request->arg("price4").toDouble(), 2);
String price5 = String(request->arg("price5").toDouble(), 2);
String price6 = String(request->arg("price6").toDouble(), 2);
String price7 = String(request->arg("price7").toDouble(), 2);
String price8 = String(request->arg("price8").toDouble(), 2);
String price9 = String(request->arg("price9").toDouble(), 2);
String price10 = String(request->arg("price10").toDouble(), 2);
String price11 = String(request->arg("price11").toDouble(), 2);
String price12 = String(request->arg("price12").toDouble(), 2);
String price13 = String(request->arg("price13").toDouble(), 2);
String price14 = String(request->arg("price14").toDouble(), 2);
String price15 = String(request->arg("price15").toDouble(), 2);
String price16 = String(request->arg("price16").toDouble(), 2);
String price17 = String(request->arg("price17").toDouble(), 2);
String price18 = String(request->arg("price18").toDouble(), 2);
//如果重试计时器未归零让客户等计时器
if (webpassworderrortime) {
char result[20];
itoa(webpassworderrortime, result, 10);
strcat(result, "sWait");
request->send(200, "text/html", result);
return;
}
//如果设备密码错误
if (!testwebpassword.equals(websetpassword)) {
webpassworderrortime = 15;
request->send(200, "text/html", rethtml("旧密码核验不通过,Old password not right"));
return;
}
//如果密码正确直接存库
price[1] = price1;
price[2] = price2;
price[3] = price3;
price[4] = price4;
price[5] = price5;
price[6] = price6;
price[7] = price7;
price[8] = price8;
price[9] = price9;
price[10] = price10;
price[11] = price11;
price[12] = price12;
price[13] = price13;
price[14] = price14;
price[15] = price15;
price[16] = price16;
price[17] = price17;
price[18] = price18;
saveKeyValue("price1", price1);
saveKeyValue("price2", price2);
saveKeyValue("price3", price3);
saveKeyValue("price4", price4);
saveKeyValue("price5", price5);
saveKeyValue("price6", price6);
saveKeyValue("price7", price7);
saveKeyValue("price8", price8);
saveKeyValue("price9", price9);
saveKeyValue("price10", price10);
saveKeyValue("price11", price11);
saveKeyValue("price12", price12);
saveKeyValue("price13", price13);
saveKeyValue("price14", price14);
saveKeyValue("price15", price15);
saveKeyValue("price16", price16);
saveKeyValue("price17", price17);
saveKeyValue("price18", price18);
request->send(200, "text/html", rethtml("价格已存储 price saved"));
return;
}
//通过HTTPS获得时间
bool HTTPS_GETTIME(String host, String postRequest, int Port = 443, int Receive_cache = 1024) {
WiFiClientSecure HTTPS; //建立WiFiClientSecure对象
HTTPS.setCACert(rootCACertificate);
postRequest = (String)("GET ") + postRequest + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "User-Agent: ESP32WiFiClientSecure" + "\r\n\r\n";
HTTPS.setInsecure(); //不进行服务器身份认证
int cache = sizeof(postRequest) + 10;
// Serial.print("原始URLB");
// Serial.println(postRequest);
// Serial.print("发送缓存:");
// Serial.println(postRequest);
// Serial.print("发送缓存大小:");
// Serial.println(cache);
// HTTPS.setBufferSizes(Receive_cache, cache); //接收和发送缓存大小
HTTPS.setTimeout(15000); //设置等待的最大毫秒数
// Serial.println("初始化参数完毕!\n开始连接服务器==>>>>>");
if (!HTTPS.connect(host.c_str(), Port)) {
// delay(100);
// Serial.println();
Serial.println("服务器连接失败!");
return false;
} else {
Serial.println("服务器连接成功!\r");
// Serial.println("发送请求:\n" + postRequest);
}
HTTPS.print(postRequest.c_str()); // 发送HTTP请求
// 检查服务器响应信息。通过串口监视器输出服务器状态码和响应头信息
// 从而确定ESP8266已经成功连接服务器
Serial.println("获取响应信息========>:\r");
Serial.println("响应头:");
String inputString; //用一个字符串接收时间变量
int i = 0;
while (HTTPS.connected()) {
inputString = HTTPS.readStringUntil('\n');
if (inputString.startsWith("Date: ")) {
Serial.println(inputString); //如果是Date开头的字符串就截取
break;
}
if (inputString == "\r") {
Serial.println("响应头输出完毕!"); // Serial.println("响应头屏蔽完毕!\r");
break;
}
if (i >= 20) {
break; //防while(1)
}
i++;
}
char *tokens[6]; // 用于存储分割后的子字符串
int tokenCount = 0;
char *str = strdup(inputString.c_str()); // 复制输入字符串,并将其转换为字符数组
char *token = strtok(str, " "); // 使用空格作为分隔符
while (token != NULL && tokenCount < 6) {
tokens[tokenCount] = token; // 存储子字符串
tokenCount++;
token = strtok(NULL, " "); // 继续分割下一个子字符串
}
// 检查是否成功分割字符串
if (tokenCount != 6) { return false; }
// 分隔后的子字符串数组
String year = String(tokens[4]);
String month = String(tokens[3]);
String day = String(tokens[2]);
String time = String(tokens[5]);
// 进一步处理截取到的子字符串
Serial.println("Year: " + year);
Serial.println("Month: " + month);
Serial.println("Day: " + day);
// 分割时间部分,使用冒号作为分隔符
char *timeTokens[3]; // 用于存储分割后的时间子字符串
int timeTokenCount = 0;
char *timeStr = strdup(time.c_str()); // 复制时间字符串,并将其转换为字符数组
char *timeToken = strtok(timeStr, ":"); // 使用冒号作为分隔符
while (timeToken != NULL && timeTokenCount < 3) {
timeTokens[timeTokenCount] = timeToken; // 存储时间子字符串
timeTokenCount++;
timeToken = strtok(NULL, ":"); // 继续分割下一个时间子字符串
}
if (timeTokenCount != 3) { return false; }
String hour = String(timeTokens[0]);
String minute = String(timeTokens[1]);
String second = String(timeTokens[2]);
Serial.println("Hour: " + hour);
Serial.println("Minute: " + minute);
Serial.println("Second: " + second);
free(timeStr); // 释放分配的内存
free(str); // 释放分配的内存
//此时已分割好所有字符串
//对月份进行转换 先做一个对象数组
// String monthAbbreviation = String(month);
String monthAbbreviations[] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
int monthNumbers[] = {
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
};
int monthNumber = -1; // 初始化月份数字
// 在数组中查找月份缩写,并获取对应的月份数字
for (int i = 0; i < sizeof(monthAbbreviations) / sizeof(monthAbbreviations[0]); i++) {
if (month == monthAbbreviations[i]) {
monthNumber = monthNumbers[i];
break;
}
}
if (monthNumber == -1) { return false; } //如果月份不存在则返回报错
// 输出转换后的结果
// if (monthNumber != -1) {
// Serial.println("Month number: " + String(monthNumber));
// } else {
// Serial.println("Invalid input");
// }
// monthNumber = monthMap[month];
//此时可以使用Arduino自带的setTime(int hr,int min,int sec,int dy, int mnth, int yr) 但该函数存在32位年溢出问题
tmElement64s_t tm;
tm.Year = strtoul(year.c_str(), nullptr, 10) - 1970;
tm.Month = monthNumber;
tm.Day = strtoul(day.c_str(), nullptr, 10);
tm.Hour = strtoul(hour.c_str(), nullptr, 10);
tm.Minute = strtoul(minute.c_str(), nullptr, 10);
tm.Second = strtoul(second.c_str(), nullptr, 10);
ntpTime = makeTime(tm); //将时间戳赋值给全局变量ntpTime;
Serial.println("授时时间戳901");
Serial.println(ntpTime);
struct timeval tv; //ESP32核心库定义此结构体用于赋值ESP32内置RTC
tv.tv_sec = 0;
tv.tv_usec = 0;
settimeofday(&tv, NULL);
Serial.println("执行授时908");
Serial.println(ntpTime);
needupadte = 0;
return true;
}
//购买处理页句柄
//先根据价格判断是否需要调用支付宝
//如果价格<0 直接开门,如果价格大于0则调用支付宝,拿到返回的跳转地址后交由前端,并启动后端轮询进行轮询5小时
void handlebuy(AsyncWebServerRequest *request) {
int door = request->arg("door").toInt(); //过滤非正常输入
if (door >= 19) { request->send(200, "text/html", rethtml("没有那么多门")); }
if (door <= 0) { request->send(200, "text/html", rethtml("门号错误,门号小于0")); }
String str = "price";
str += String(door);
String pricestr = price[door];
double price = pricestr.toDouble(); //读取全局变量提速
if (price <= -0.01) {
request->send(200, "text/html", rethtml("门已开"));
pinMode(13, OUTPUT);
digitalWrite(13, HIGH);
delay(2000);
digitalWrite(13, LOW);
}
//授时
if (needupadte) {
HTTPS_GETTIME("openapi.alipay.com", "/gateway.do?method=alipay.trade.query", 443, 1024);
// Serial.println("尝试HTTP授时");
}
// if (needupadte) {
// getNtpTimeAsync();
// delay(3000);
// Serial.println("等待授时");
// }
//如果无法连接支付宝服务器获得授时
// if (HTTPS_GETTIME("openapi.alipay.com", "/gateway.do?method=alipay.trade.query", 443, 1024)) {
// } else {
// request->send(200, "text/html", rethtml("无法得到授时"));
// }
// Serial.println("999");