Compare commits
801 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
99eef8fb28 | ||
![]() |
47e7685d39 | ||
![]() |
b6ea596ade | ||
![]() |
44d60b469b | ||
![]() |
51087408df | ||
![]() |
96226d9e6e | ||
![]() |
28f0f62424 | ||
![]() |
2e772a8cd4 | ||
![]() |
3fd192f0cf | ||
![]() |
d16ae81961 | ||
![]() |
211a8e093e | ||
![]() |
84010a51d6 | ||
![]() |
e9700ea19b | ||
![]() |
e81ec68072 | ||
![]() |
6096e97708 | ||
![]() |
6f302b66b4 | ||
![]() |
b6e41890f7 | ||
![]() |
be5332a048 | ||
![]() |
4d72aeb0cd | ||
![]() |
c7c3c35100 | ||
![]() |
2f0df3c552 | ||
![]() |
e6effcd921 | ||
![]() |
cd462b9523 | ||
![]() |
7e2e17d38b | ||
![]() |
665d616a06 | ||
![]() |
ced90f5bb9 | ||
![]() |
ca0ddb6cb4 | ||
![]() |
3d733813e1 | ||
![]() |
45ddc0b154 | ||
![]() |
87294497f3 | ||
![]() |
5f45f9c0d0 | ||
![]() |
7f78c06793 | ||
![]() |
8ea5b7eebc | ||
![]() |
e49cd511af | ||
![]() |
15c88646df | ||
![]() |
f47919543d | ||
![]() |
a95291d9cd | ||
![]() |
033deb3d29 | ||
![]() |
923994c1f4 | ||
![]() |
3d45b839b4 | ||
![]() |
55d1efa212 | ||
![]() |
21d794a0e5 | ||
![]() |
614022a78c | ||
![]() |
c00688e23a | ||
![]() |
5c69917d19 | ||
![]() |
6a5eb75b6c | ||
![]() |
727c55eaa2 | ||
![]() |
9b03173ec5 | ||
![]() |
ab95855d6d | ||
![]() |
bb84594c6b | ||
![]() |
97392c76b1 | ||
![]() |
53aec2b306 | ||
![]() |
a0a381dc63 | ||
![]() |
4fa95edeec | ||
![]() |
b944f1d70e | ||
![]() |
0f1a5d0085 | ||
![]() |
e7e10222e7 | ||
![]() |
87c4fda588 | ||
![]() |
0ff820de6f | ||
![]() |
0dcf55e6d9 | ||
![]() |
a69842c910 | ||
![]() |
318f635e4d | ||
![]() |
abf0d72316 | ||
![]() |
5cd89c8844 | ||
![]() |
501c1af38c | ||
![]() |
8526e130d9 | ||
![]() |
76fd08eade | ||
![]() |
bfe48ae9d2 | ||
![]() |
8547cdba7c | ||
![]() |
00d0cd631d | ||
![]() |
04460d13cd | ||
![]() |
a17a15e5d7 | ||
![]() |
bfe2465658 | ||
![]() |
4568987785 | ||
![]() |
c0e5a1419d | ||
![]() |
23ac7ab748 | ||
![]() |
5622dc74a8 | ||
![]() |
528986f4f0 | ||
![]() |
e6b8ff3f91 | ||
![]() |
3fc3c5296f | ||
![]() |
f4f2a14a31 | ||
![]() |
fa3f464cb6 | ||
![]() |
bed20538ae | ||
![]() |
3da461c6e6 | ||
![]() |
9c73e8452a | ||
![]() |
750dab69d3 | ||
![]() |
702d0da47c | ||
![]() |
3a955b1e53 | ||
![]() |
d408bd93e8 | ||
![]() |
63fd9eb1de | ||
![]() |
4718ab6ddf | ||
![]() |
affd4b3a26 | ||
![]() |
6a660dbcda | ||
![]() |
5ff3af8b48 | ||
![]() |
9d49070f93 | ||
![]() |
5b3994a1dd | ||
![]() |
bb1e62c580 | ||
![]() |
29cc776908 | ||
![]() |
d2ef60b2ec | ||
![]() |
41ea496d41 | ||
![]() |
c69bb38929 | ||
![]() |
23b3f8494e | ||
![]() |
0ff94eec1b | ||
![]() |
f67a638565 | ||
![]() |
778cf71c61 | ||
![]() |
e2da083b48 | ||
![]() |
dcc48c0d4b | ||
![]() |
2446b4a591 | ||
![]() |
a973d633c8 | ||
![]() |
c3b11e6e0f | ||
![]() |
44bec2d99e | ||
![]() |
0d59d0a3f6 | ||
![]() |
ddc8372b09 | ||
![]() |
ea7325f4e0 | ||
![]() |
6048f95415 | ||
![]() |
5682705b8d | ||
![]() |
6c3b82607d | ||
![]() |
486c9f4ebf | ||
![]() |
7c8adebf2d | ||
![]() |
ce98bb0dc1 | ||
![]() |
60b49a4296 | ||
![]() |
5d0a2ffae0 | ||
![]() |
bbcf7c722a | ||
![]() |
66574eec6d | ||
![]() |
305df3a42c | ||
![]() |
323c6f4270 | ||
![]() |
c056b2b14c | ||
![]() |
02ebb07fd8 | ||
![]() |
59db0890c3 | ||
![]() |
3ea0d9ed3a | ||
![]() |
0371d11dd5 | ||
![]() |
12f1ebaee9 | ||
![]() |
5202cc22d1 | ||
![]() |
07a34bdcbf | ||
![]() |
27806da4be | ||
![]() |
a15dd1a3ce | ||
![]() |
6cc7451c7c | ||
![]() |
652aeee782 | ||
![]() |
8e1e887b8f | ||
![]() |
6601a2de64 | ||
![]() |
75a42ffc32 | ||
![]() |
8a80a52f5f | ||
![]() |
b373a434ba | ||
![]() |
cd78fdafe6 | ||
![]() |
7a1b4c6db7 | ||
![]() |
f2c7664033 | ||
![]() |
12b295f067 | ||
![]() |
3ee46da40f | ||
![]() |
beadaa7212 | ||
![]() |
16ef09426f | ||
![]() |
b8c1f1f5a9 | ||
![]() |
e027b5cbd6 | ||
![]() |
bf1bd73ad1 | ||
![]() |
86fc95119a | ||
![]() |
b3a76ea17b | ||
![]() |
bababd9d53 | ||
![]() |
8cd5180531 | ||
![]() |
f1ccbade8c | ||
![]() |
a66f4b0417 | ||
![]() |
ff495b2261 | ||
![]() |
90e5824212 | ||
![]() |
3d64021062 | ||
![]() |
fb8ed7428d | ||
![]() |
bdc273c10a | ||
![]() |
2d96cffdc7 | ||
![]() |
4356fccbcd | ||
![]() |
a169fd4ce7 | ||
![]() |
dcd418139e | ||
![]() |
0cac2062d3 | ||
![]() |
854c5d4ade | ||
![]() |
0f96c6ec84 | ||
![]() |
b219bd66c1 | ||
![]() |
cb52f2c0b3 | ||
![]() |
d3273e03ef | ||
![]() |
afbfd963f3 | ||
![]() |
2cd101c5f3 | ||
![]() |
b10bc24dee | ||
![]() |
51a23df861 | ||
![]() |
03a0a9dad9 | ||
![]() |
362c0affbe | ||
![]() |
d5b523479f | ||
![]() |
7719b8f6d7 | ||
![]() |
3656c0d524 | ||
![]() |
8b9e0dd6ea | ||
![]() |
b3921b1037 | ||
![]() |
d7d96e5dbf | ||
![]() |
3934395b7b | ||
![]() |
04fbe9a529 | ||
![]() |
badd6dd9a2 | ||
![]() |
059082456d | ||
![]() |
405b68e22f | ||
![]() |
c90bf6692c | ||
![]() |
b5ea5d0cc5 | ||
![]() |
243617a1e1 | ||
![]() |
9e703edd59 | ||
![]() |
d6c2cf2810 | ||
![]() |
ae7811acfa | ||
![]() |
e55731c099 | ||
![]() |
9df5c74da4 | ||
![]() |
8b75f9f785 | ||
![]() |
bf12428cf4 | ||
![]() |
b551df978b | ||
![]() |
c91d85d2f0 | ||
![]() |
965237fa1f | ||
![]() |
24cd9afc06 | ||
![]() |
602fdefebd | ||
![]() |
7e7818aa17 | ||
![]() |
27a6023a6a | ||
![]() |
3861879900 | ||
![]() |
807eeb8351 | ||
![]() |
045fa53d58 | ||
![]() |
69d405ece7 | ||
![]() |
d3dc4d0c5b | ||
![]() |
7beba1188e | ||
![]() |
9779ebe12c | ||
![]() |
f72cfaa093 | ||
![]() |
cf8ccafb4a | ||
![]() |
7fe281b0b8 | ||
![]() |
5f70e9574f | ||
![]() |
4be51923ba | ||
![]() |
a72c78f4a4 | ||
![]() |
b4d32a6de1 | ||
![]() |
8a6b2d5daa | ||
![]() |
bebadeef14 | ||
![]() |
3551be67f0 | ||
![]() |
1103950b25 | ||
![]() |
9d06e01cec | ||
![]() |
24be946b7e | ||
![]() |
f56d2fc60f | ||
![]() |
9f8356f409 | ||
![]() |
8e6345d938 | ||
![]() |
0eac78bd1c | ||
![]() |
21db2502d0 | ||
![]() |
38c3492123 | ||
![]() |
6376bff476 | ||
![]() |
38495a3ebc | ||
![]() |
cf00897be2 | ||
![]() |
da640f24ec | ||
![]() |
ed6a777c42 | ||
![]() |
81af4485d3 | ||
![]() |
94d8f0237d | ||
![]() |
c5e579dd38 | ||
![]() |
7865e76ee2 | ||
![]() |
4d37212cc0 | ||
![]() |
9ca43f0bb4 | ||
![]() |
fe8d262175 | ||
![]() |
493d6e7165 | ||
![]() |
17b630bcd8 | ||
![]() |
018c5ad3b4 | ||
![]() |
a14b4da977 | ||
![]() |
01b4597cc7 | ||
![]() |
0b083ccc1c | ||
![]() |
ca22cb0eae | ||
![]() |
bcbb8e5f8c | ||
![]() |
bea286cdd4 | ||
![]() |
892d2ee8d2 | ||
![]() |
7440608c14 | ||
![]() |
6246f0295b | ||
![]() |
53c39d9b43 | ||
![]() |
9a50b60031 | ||
![]() |
fd74527320 | ||
![]() |
f91fb522ac | ||
![]() |
7019c02b18 | ||
![]() |
94f8422b9b | ||
![]() |
b25c01567a | ||
![]() |
b9329885de | ||
![]() |
ac88c4cff9 | ||
![]() |
9674f2d238 | ||
![]() |
38c9ecb6f1 | ||
![]() |
be9e9cdd5a | ||
![]() |
afdaf07446 | ||
![]() |
5caaf10225 | ||
![]() |
daffc3a776 | ||
![]() |
34c9748ce5 | ||
![]() |
f17acbf4d1 | ||
![]() |
229f56ce2f | ||
![]() |
0847bedc51 | ||
![]() |
9e4546c305 | ||
![]() |
97b01bf26a | ||
![]() |
e7011628d0 | ||
![]() |
044ffdecbd | ||
![]() |
1a06a3543b | ||
![]() |
5fedc0bf1e | ||
![]() |
7a881f867e | ||
![]() |
dfe73a6cfb | ||
![]() |
45d0fb27ad | ||
![]() |
31890af61d | ||
![]() |
a54b3ecc15 | ||
![]() |
c37cd1bd51 | ||
![]() |
0e3ee89cbf | ||
![]() |
a049176c14 | ||
![]() |
5ef2b0089e | ||
![]() |
1cc4899593 | ||
![]() |
26d1390be9 | ||
![]() |
dc65584fb3 | ||
![]() |
b3d5a708d5 | ||
![]() |
904a5d296b | ||
![]() |
cc82e6a47a | ||
![]() |
a9d02ec854 | ||
![]() |
6b5a2d3767 | ||
![]() |
10d9060b94 | ||
![]() |
8441839c01 | ||
![]() |
b669f5838f | ||
![]() |
1a942f9ce1 | ||
![]() |
ae840758f7 | ||
![]() |
082c08e5f9 | ||
![]() |
74a43557ab | ||
![]() |
184271789d | ||
![]() |
fa61b0cad8 | ||
![]() |
7b197a90d1 | ||
![]() |
62384af2f6 | ||
![]() |
b466202a1a | ||
![]() |
7ab38c18d8 | ||
![]() |
39841ee43e | ||
![]() |
e419800d98 | ||
![]() |
63c99ab69a | ||
![]() |
e2a8fd2279 | ||
![]() |
bbde520471 | ||
![]() |
45fb12f98e | ||
![]() |
4be3dcce50 | ||
![]() |
d12a41c769 | ||
![]() |
ed9a58c9ed | ||
![]() |
4389cea5a1 | ||
![]() |
d24854920b | ||
![]() |
9902443bee | ||
![]() |
8040b2ef16 | ||
![]() |
4533680b10 | ||
![]() |
3b28175135 | ||
![]() |
8e22812265 | ||
![]() |
409bc91b9e | ||
![]() |
61fe543a2a | ||
![]() |
8a949a7e64 | ||
![]() |
b0dc9fb97a | ||
![]() |
83114d1002 | ||
![]() |
94a25a903f | ||
![]() |
4f402f9e55 | ||
![]() |
27bb2e3dcc | ||
![]() |
66cc52f6ec | ||
![]() |
ed1367b116 | ||
![]() |
5c055352e4 | ||
![]() |
8dcff5ada1 | ||
![]() |
4b8b23d7d5 | ||
![]() |
e576f6aed3 | ||
![]() |
97ab04da91 | ||
![]() |
c6361bb36e | ||
![]() |
b0b3dc225d | ||
![]() |
9cbaba192a | ||
![]() |
f511598e13 | ||
![]() |
5ffff3b7aa | ||
![]() |
24c4fa1c4f | ||
![]() |
7f312c1273 | ||
![]() |
ef5c226c81 | ||
![]() |
3f029cf799 | ||
![]() |
5bf64a8bec | ||
![]() |
89f9c537f8 | ||
![]() |
e8d7f57818 | ||
![]() |
9b42fa78e7 | ||
![]() |
96d98e8f39 | ||
![]() |
1f3a281e78 | ||
![]() |
dab4b66ee0 | ||
![]() |
64dd192ddb | ||
![]() |
b0a5c383d0 | ||
![]() |
4836cc99eb | ||
![]() |
ba33873354 | ||
![]() |
12c838cab0 | ||
![]() |
a83a1c83a7 | ||
![]() |
2234f47170 | ||
![]() |
4bae1b17fc | ||
![]() |
6a7a0e0fa6 | ||
![]() |
bff987c55f | ||
![]() |
e467006913 | ||
![]() |
1d646d4a6d | ||
![]() |
70bd4936a1 | ||
![]() |
5ae7add6d2 | ||
![]() |
02b206ce7c | ||
![]() |
2ea626a567 | ||
![]() |
653909ec11 | ||
![]() |
1d7c148eaf | ||
![]() |
94a7e130ca | ||
![]() |
609abacdf0 | ||
![]() |
033ff2e49a | ||
![]() |
00a9bf0641 | ||
![]() |
100f322456 | ||
![]() |
2251e08d30 | ||
![]() |
14e9beef53 | ||
![]() |
c7cce23d54 | ||
![]() |
7becf32352 | ||
![]() |
741eda9f4e | ||
![]() |
473f51481c | ||
![]() |
684f9bd11b | ||
![]() |
b4b7f0c360 | ||
![]() |
cf42d02628 | ||
![]() |
cc9a9eab7b | ||
![]() |
784d6abc9b | ||
![]() |
0eafc07184 | ||
![]() |
7e9499bd2e | ||
![]() |
d01a52aa95 | ||
![]() |
6bcd492980 | ||
![]() |
96b15da04b | ||
![]() |
e0f1801693 | ||
![]() |
d195ad85c5 | ||
![]() |
773f7b6c1b | ||
![]() |
40f29fe399 | ||
![]() |
b19eb117c1 | ||
![]() |
f930ba5eff | ||
![]() |
fbbda6c230 | ||
![]() |
47db4968e5 | ||
![]() |
1aff2e518c | ||
![]() |
24134ca49e | ||
![]() |
aadbe05a5e | ||
![]() |
18eddf4700 | ||
![]() |
0869ba7e70 | ||
![]() |
cba5db1c53 | ||
![]() |
0aa5430e23 | ||
![]() |
88a91828cb | ||
![]() |
27af89f5fe | ||
![]() |
6f6d483bfe | ||
![]() |
915072c191 | ||
![]() |
76077b92ae | ||
![]() |
f0d1a527a5 | ||
![]() |
fdb2a96d1c | ||
![]() |
849e3ac187 | ||
![]() |
5c4cf21c59 | ||
![]() |
40ee3e5d9b | ||
![]() |
77a7cc034e | ||
![]() |
82b7881765 | ||
![]() |
3515775267 | ||
![]() |
10e12aa1c1 | ||
![]() |
7fb4e62aa3 | ||
![]() |
2605eaa614 | ||
![]() |
8e97b4820d | ||
![]() |
89af4cdb68 | ||
![]() |
6099c1a25a | ||
![]() |
fd23758aea | ||
![]() |
8ad0b89db1 | ||
![]() |
e7dffa3ff4 | ||
![]() |
2772b5d2e2 | ||
![]() |
df6d9b5f70 | ||
![]() |
c9622d6d57 | ||
![]() |
1f0b7c3c7e | ||
![]() |
c12245037e | ||
![]() |
fe6d2a50a5 | ||
![]() |
7be84950f8 | ||
![]() |
ba212da222 | ||
![]() |
122b833256 | ||
![]() |
7c73479041 | ||
![]() |
151f2e99ae | ||
![]() |
da367e813f | ||
![]() |
9143dfe336 | ||
![]() |
29914d6a72 | ||
![]() |
0dbef72a97 | ||
![]() |
3bb118bfe1 | ||
![]() |
85ce3be077 | ||
![]() |
064c2bf0a8 | ||
![]() |
c96d06ccc5 | ||
![]() |
a658dbb753 | ||
![]() |
bf5d5b629e | ||
![]() |
241d576519 | ||
![]() |
7807e9bdd0 | ||
![]() |
fcbf15fed6 | ||
![]() |
cd90a11209 | ||
![]() |
ff65707ea2 | ||
![]() |
b16026070c | ||
![]() |
1b5fbf86d8 | ||
![]() |
5eb1be8101 | ||
![]() |
6a863cd26a | ||
![]() |
87ebb7b6c7 | ||
![]() |
1233a74307 | ||
![]() |
221890acfb | ||
![]() |
687c7e766e | ||
![]() |
ba22c407d3 | ||
![]() |
a8b9ed56b5 | ||
![]() |
3004869e19 | ||
![]() |
1145853fe1 | ||
![]() |
f1617a25b1 | ||
![]() |
932be558d9 | ||
![]() |
ee3a37d3b9 | ||
![]() |
5ac412a582 | ||
![]() |
1625290bc3 | ||
![]() |
1ec169ad49 | ||
![]() |
53be552e44 | ||
![]() |
d3a75d46b9 | ||
![]() |
256512c961 | ||
![]() |
5c12ac5bcc | ||
![]() |
02a2bcb113 | ||
![]() |
1f0a01c725 | ||
![]() |
6ea164ede1 | ||
![]() |
65bae85ecc | ||
![]() |
2fd7dcf4d0 | ||
![]() |
aa3bbbe038 | ||
![]() |
6cb09a6f95 | ||
![]() |
45868f05d3 | ||
![]() |
aac7401e20 | ||
![]() |
c2fc290edd | ||
![]() |
330357fc36 | ||
![]() |
f4a3d6a64e | ||
![]() |
2e0963ec81 | ||
![]() |
897cb6e62a | ||
![]() |
80868bd48e | ||
![]() |
b3df78c56f | ||
![]() |
783a4259e3 | ||
![]() |
fcf19b8dc8 | ||
![]() |
1f9f89817d | ||
![]() |
7b94da7d85 | ||
![]() |
164406f6c2 | ||
![]() |
90ef2adc6b | ||
![]() |
d65f10f88b | ||
![]() |
dca0ece9e0 | ||
![]() |
baabc155c8 | ||
![]() |
7eb94412d6 | ||
![]() |
0fc8b24f85 | ||
![]() |
88f6ef5b96 | ||
![]() |
7442483419 | ||
![]() |
9c61933c04 | ||
![]() |
2b36a99720 | ||
![]() |
c2cfc42ba4 | ||
![]() |
4f32704e08 | ||
![]() |
fccf43685f | ||
![]() |
39135d81ad | ||
![]() |
ff4b10681e | ||
![]() |
10b7908fc2 | ||
![]() |
31790da8c6 | ||
![]() |
4621201c47 | ||
![]() |
692ac31dbf | ||
![]() |
ed1d163d55 | ||
![]() |
e931c9040c | ||
![]() |
f23cb48ea4 | ||
![]() |
c3b2b6b07b | ||
![]() |
f89bf590ba | ||
![]() |
fea17dc00b | ||
![]() |
dbb1069920 | ||
![]() |
afc4ccfaa9 | ||
![]() |
38d55a1c07 | ||
![]() |
5fca29f103 | ||
![]() |
78f34b2ca4 | ||
![]() |
8e8028e809 | ||
![]() |
8dc70687f8 | ||
![]() |
fa22f9ee64 | ||
![]() |
b33c0d3f81 | ||
![]() |
339009add4 | ||
![]() |
798c823c4b | ||
![]() |
14ad86f2a3 | ||
![]() |
a3a714dc17 | ||
![]() |
e8d8b0d41d | ||
![]() |
17daad8f89 | ||
![]() |
e178263b3b | ||
![]() |
4febbc261e | ||
![]() |
ef3a6942fd | ||
![]() |
f8ac2be62b | ||
![]() |
25447c34e5 | ||
![]() |
37cdf8fd48 | ||
![]() |
ac8e7dc959 | ||
![]() |
8293382840 | ||
![]() |
d85a3e7743 | ||
![]() |
f3f5ffb5c8 | ||
![]() |
99e6702c62 | ||
![]() |
e143c25078 | ||
![]() |
3fb67972be | ||
![]() |
61c04d4e09 | ||
![]() |
b22f728958 | ||
![]() |
112be7e383 | ||
![]() |
6a7f83fed5 | ||
![]() |
4b9698a735 | ||
![]() |
ec3d203a6d | ||
![]() |
e77b8f5475 | ||
![]() |
da8bbd321f | ||
![]() |
98fd011def | ||
![]() |
9dccbc5316 | ||
![]() |
03fa26daf9 | ||
![]() |
fbc41e3895 | ||
![]() |
f1a6d0c02c | ||
![]() |
67f6bb7155 | ||
![]() |
86282f596c | ||
![]() |
e0f24c795c | ||
![]() |
7d44ed860c | ||
![]() |
091094a24c | ||
![]() |
ba18ee518c | ||
![]() |
513a031691 | ||
![]() |
cc79de1106 | ||
![]() |
bd90e8efb2 | ||
![]() |
4bd88ff11d | ||
![]() |
d27ee61292 | ||
![]() |
0c20b3345f | ||
![]() |
0f3c8c7193 | ||
![]() |
16761ec605 | ||
![]() |
1069440cda | ||
![]() |
60f5702f17 | ||
![]() |
ee70133e47 | ||
![]() |
06a9fdeb2e | ||
![]() |
f14bd62004 | ||
![]() |
67cbaf22b7 | ||
![]() |
60b166dba2 | ||
![]() |
66e1647ede | ||
![]() |
a1a35c00a5 | ||
![]() |
b02e3361c4 | ||
![]() |
2b9ceaa25a | ||
![]() |
109b5a9755 | ||
![]() |
cc4df86c10 | ||
![]() |
e93532c395 | ||
![]() |
6ff688326a | ||
![]() |
eda5d2872f | ||
![]() |
dc88394f5f | ||
![]() |
ec85c9a2c6 | ||
![]() |
1341638556 | ||
![]() |
4875dfee11 | ||
![]() |
d834ba8bd4 | ||
![]() |
6191067771 | ||
![]() |
6c3a571163 | ||
![]() |
5efb07e10e | ||
![]() |
b25ec18ce6 | ||
![]() |
f3cd281241 | ||
![]() |
58b93cbf4c | ||
![]() |
57fc0349ff | ||
![]() |
d0a2cea772 | ||
![]() |
58d5801fb5 | ||
![]() |
e5f2e59798 | ||
![]() |
1166921057 | ||
![]() |
aeb49576f2 | ||
![]() |
7ef1fecef8 | ||
![]() |
fd630373b5 | ||
![]() |
d365d8f170 | ||
![]() |
dfa5e1172f | ||
![]() |
daf195898a | ||
![]() |
c61c0a39cf | ||
![]() |
6137e6baa5 | ||
![]() |
fd16fd9ffe | ||
![]() |
2b8bd5f2cc | ||
![]() |
d312c2e9e7 | ||
![]() |
578b0d2268 | ||
![]() |
ffb41b0109 | ||
![]() |
c63fb5d796 | ||
![]() |
8caee732e8 | ||
![]() |
df5381adce | ||
![]() |
f34836b7fa | ||
![]() |
44b459883a | ||
![]() |
14a8592ae3 | ||
![]() |
787d0dce4a | ||
![]() |
8be05ff93d | ||
![]() |
3014af565c | ||
![]() |
315252bdc4 | ||
![]() |
c36c3b4607 | ||
![]() |
7d5e939bab | ||
![]() |
f75c9d1eed | ||
![]() |
38cb9855ea | ||
![]() |
ed8b56d624 | ||
![]() |
bca48b13ae | ||
![]() |
29426edb05 | ||
![]() |
33a2dc687f | ||
![]() |
e2398a21b2 | ||
![]() |
f19530276e | ||
![]() |
2b9b92a78c | ||
![]() |
99c55dac10 | ||
![]() |
25667e46f9 | ||
![]() |
2f4e8f2399 | ||
![]() |
9169183769 | ||
![]() |
c420f50831 | ||
![]() |
c6c9279ef4 | ||
![]() |
c125e2991d | ||
![]() |
5348b19d6a | ||
![]() |
afd426daac | ||
![]() |
202c511cfa | ||
![]() |
651eb295a4 | ||
![]() |
d798aaed33 | ||
![]() |
63ef347cc9 | ||
![]() |
3139b2d5a0 | ||
![]() |
2c80bbb244 | ||
![]() |
af06755ada | ||
![]() |
97d6dbaa6c | ||
![]() |
74cf82a1c7 | ||
![]() |
74634889ab | ||
![]() |
dbe30fcd77 | ||
![]() |
24a7f3a320 | ||
![]() |
d3650f1145 | ||
![]() |
4801db9050 | ||
![]() |
6445281658 | ||
![]() |
87719f5938 | ||
![]() |
5ba1ec433b | ||
![]() |
7c5b382458 | ||
![]() |
8960426128 | ||
![]() |
e1d47d5a92 | ||
![]() |
9407c272aa | ||
![]() |
bccbd7b400 | ||
![]() |
a24dc010ec | ||
![]() |
c5e5d50fb8 | ||
![]() |
be1c520320 | ||
![]() |
3d18d0f893 | ||
![]() |
c3351a38a6 | ||
![]() |
0b86340a8d | ||
![]() |
829371b032 | ||
![]() |
b342207bc7 | ||
![]() |
58f4fdced3 | ||
![]() |
253844cbcf | ||
![]() |
e2e2b9ffb4 | ||
![]() |
2568042f5f | ||
![]() |
722edf4b9a | ||
![]() |
e406d364e4 | ||
![]() |
31c37f41b2 | ||
![]() |
6cd879bbc5 | ||
![]() |
b7974050fe | ||
![]() |
e9c9d0816e | ||
![]() |
a437692e1a | ||
![]() |
2a14d2f3c8 | ||
![]() |
559e2d1889 | ||
![]() |
a1aa919f80 | ||
![]() |
cbccb27a5a | ||
![]() |
bbad36d576 | ||
![]() |
df6c9d55b5 | ||
![]() |
36a1d9c364 | ||
![]() |
1f3681d5ac | ||
![]() |
0159f8e53f | ||
![]() |
0432be64fc | ||
![]() |
481e062961 | ||
![]() |
72b8abdeb6 | ||
![]() |
7ec3ee41d1 | ||
![]() |
b765fa4769 | ||
![]() |
06685b162e | ||
![]() |
7bcad7c424 | ||
![]() |
6e054b3cc6 | ||
![]() |
e643f6b0f8 | ||
![]() |
e44c0f85c2 | ||
![]() |
ea66e968eb | ||
![]() |
f7e73d804e | ||
![]() |
2ff4df56a1 | ||
![]() |
346c45fe0c | ||
![]() |
f98b42a36e | ||
![]() |
f77a0a266c | ||
![]() |
0be672788f | ||
![]() |
e2e3d11d42 | ||
![]() |
bb127bb567 | ||
![]() |
8eb4f89db8 | ||
![]() |
4a87ea3e70 | ||
![]() |
61115fce99 | ||
![]() |
4f31120394 | ||
![]() |
b085cd65ce | ||
![]() |
f76ec0721a | ||
![]() |
ef3944fbbf | ||
![]() |
b158fbc0d8 | ||
![]() |
68f2d66e97 | ||
![]() |
0cdd1735bd | ||
![]() |
70f5ead20b | ||
![]() |
574e5616f8 | ||
![]() |
94fa810590 | ||
![]() |
37f69da701 | ||
![]() |
f2f8448ade | ||
![]() |
b357d3fff2 | ||
![]() |
b417194905 | ||
![]() |
d8741da20a | ||
![]() |
c469be9a62 | ||
![]() |
ff4eb339ef | ||
![]() |
78489383c0 | ||
![]() |
f67c1b415f | ||
![]() |
570c16d921 | ||
![]() |
c8bc60568a | ||
![]() |
73de3ba856 | ||
![]() |
6a69be8537 | ||
![]() |
3ee381d505 | ||
![]() |
7ce744e2e4 | ||
![]() |
b81d21c991 | ||
![]() |
e9fe0992c6 | ||
![]() |
d5ef9018fa | ||
![]() |
c2737a7c51 | ||
![]() |
4b6d8733c6 | ||
![]() |
f22a3e0955 | ||
![]() |
4b8144a2f7 | ||
![]() |
abac52e23c | ||
![]() |
9aa089313e | ||
![]() |
b18f2c481a | ||
![]() |
ec83b9f77b | ||
![]() |
fad5495e02 | ||
![]() |
70dec1171e | ||
![]() |
0673a6fce3 | ||
![]() |
8f525b1407 | ||
![]() |
e83a991a4b | ||
![]() |
c000432a52 | ||
![]() |
c06d2d6927 | ||
![]() |
aa29653a8f | ||
![]() |
3f7e4ad486 | ||
![]() |
0eab546b2f | ||
![]() |
8830d216d1 | ||
![]() |
9fa1e3d449 | ||
![]() |
fe5dce7159 | ||
![]() |
952fa31548 | ||
![]() |
cc058ccc61 | ||
![]() |
bc26ed9701 | ||
![]() |
26135fc1a0 | ||
![]() |
0bd14672ff | ||
![]() |
7c7150cde8 | ||
![]() |
b08282b0c1 | ||
![]() |
3bf6e1befc | ||
![]() |
52692371ac | ||
![]() |
159ac1d8bb | ||
![]() |
7f1ffdbc79 | ||
![]() |
5fe64931dc | ||
![]() |
ee67855b48 | ||
![]() |
594a97f43f | ||
![]() |
7fb435a8b4 | ||
![]() |
01e74d6116 | ||
![]() |
b321d75b39 | ||
![]() |
1e47a45723 | ||
![]() |
88c609e5ef | ||
![]() |
775d1a424e |
20
framework/Directory.Build.props
Normal file
20
framework/Directory.Build.props
Normal file
@@ -0,0 +1,20 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<TargetFrameworks>net6.0;net8.0;</TargetFrameworks>
|
||||
<Version>4.0.0.8</Version>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Authors>Diego</Authors>
|
||||
<Product>ThingsGateway</Product>
|
||||
<Copyright>© 2023-present Diego</Copyright>
|
||||
<RepositoryUrl>https://gitee.com/diego2098/ThingsGateway</RepositoryUrl>
|
||||
<SignAssembly>True</SignAssembly>
|
||||
<DelaySign>False</DelaySign>
|
||||
<SatelliteResourceLanguages>zh-Hans</SatelliteResourceLanguages>
|
||||
<GenerateDocumentationFile>False</GenerateDocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
|
||||
</Project>
|
@@ -82,6 +82,7 @@ EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "解决方案项", "解决方案项", "{97B23D8B-C6C0-4746-A21F-C7B49354B284}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
..\.gitignore = ..\.gitignore
|
||||
Directory.Build.props = Directory.Build.props
|
||||
..\README.md = ..\README.md
|
||||
EndProjectSection
|
||||
EndProject
|
||||
|
@@ -1,17 +1,7 @@
|
||||
<Project>
|
||||
<Import Project="$(SolutionDir)\Directory.Build.props" />
|
||||
<PropertyGroup>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<TargetFrameworks>net6.0;net8.0;</TargetFrameworks>
|
||||
<Version>4.0.0.3</Version>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Authors>Diego</Authors>
|
||||
<Product>ThingsGateway</Product>
|
||||
<Copyright>© 2023-present Diego</Copyright>
|
||||
<RepositoryUrl>https://gitee.com/diego2098/ThingsGateway</RepositoryUrl>
|
||||
<SignAssembly>True</SignAssembly>
|
||||
<DelaySign>False</DelaySign>
|
||||
<SatelliteResourceLanguages>zh-Hans</SatelliteResourceLanguages>
|
||||
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
|
@@ -27,12 +27,12 @@ namespace ThingsGateway.Admin.ApiController;
|
||||
[Route("Swagger")]
|
||||
public class SwaggerController : IDynamicApiController, IScoped
|
||||
{
|
||||
private readonly ConfigService _configService;
|
||||
private readonly IConfigService _configService;
|
||||
/// <summary>
|
||||
/// <inheritdoc cref="SwaggerController"/>
|
||||
/// </summary>
|
||||
/// <param name="sysConfigService"></param>
|
||||
public SwaggerController(ConfigService sysConfigService)
|
||||
public SwaggerController(IConfigService sysConfigService)
|
||||
{
|
||||
_configService = sysConfigService;
|
||||
}
|
||||
|
@@ -79,7 +79,7 @@
|
||||
Swagger登录授权服务
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Admin.ApiController.SwaggerController.#ctor(ThingsGateway.Admin.Application.ConfigService)">
|
||||
<member name="M:ThingsGateway.Admin.ApiController.SwaggerController.#ctor(ThingsGateway.Admin.Application.IConfigService)">
|
||||
<summary>
|
||||
<inheritdoc cref="T:ThingsGateway.Admin.ApiController.SwaggerController"/>
|
||||
</summary>
|
||||
|
@@ -96,7 +96,7 @@ public class OperDispatchProxy : AspectDispatchProxy, IDispatchProxy
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public override async Task InvokeAsync(MethodInfo method, object[] args)
|
||||
{
|
||||
var desc = method.GetActualCustomAttribute<OperDescAttribute>(Target);
|
||||
var desc = method.GetActualCustomAttribute<OperDescAttribute>(Target, true);
|
||||
if (desc == null)
|
||||
{
|
||||
var task = method.Invoke(Target, args) as Task;
|
||||
@@ -134,7 +134,7 @@ public class OperDispatchProxy : AspectDispatchProxy, IDispatchProxy
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public override async Task<T> InvokeAsyncT<T>(MethodInfo method, object[] args)
|
||||
{
|
||||
var desc = method.GetActualCustomAttribute<OperDescAttribute>(Target);
|
||||
var desc = method.GetActualCustomAttribute<OperDescAttribute>(Target, true);
|
||||
if (desc == null)
|
||||
{
|
||||
var taskT = method.Invoke(Target, args) as Task<T>;
|
||||
|
@@ -83,7 +83,7 @@ public class OpenApiSessionService : DbRepository<OpenApiUser>, IOpenApiSessionS
|
||||
var verificatInfos = await _verificatService.GetVerificatIdAsync(it.Id);
|
||||
if (verificatInfos != null)
|
||||
{
|
||||
OpenApiSessionService.GetVerificatInfos(ref verificatInfos);//获取剩余时间
|
||||
GetVerificatInfos(ref verificatInfos);//获取剩余时间
|
||||
it.VerificatCount = verificatInfos.Count;//令牌数量
|
||||
it.VerificatSignList = verificatInfos;//令牌列表
|
||||
}
|
||||
|
@@ -73,7 +73,7 @@ public class SessionService : DbRepository<SysUser>, ISessionService
|
||||
var verificatInfos = await _verificatService.GetVerificatIdAsync(it.Id);
|
||||
if (verificatInfos != null)
|
||||
{
|
||||
SessionService.GetVerificatInfos(ref verificatInfos);//获取剩余时间
|
||||
GetVerificatInfos(ref verificatInfos);//获取剩余时间
|
||||
it.VerificatCount = verificatInfos.Count;//令牌数量
|
||||
it.VerificatSignList = verificatInfos;//令牌列表
|
||||
|
||||
|
@@ -12,7 +12,7 @@
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ThingsGateway.Admin.Core\ThingsGateway.Admin.Core.csproj" />
|
||||
<PackageReference Include="MiniExcel" Version="1.31.2" />
|
||||
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.3.6" />
|
||||
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.3.7" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@@ -10,6 +10,8 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
using ThingsGateway.Foundation.Extension.String;
|
||||
|
||||
namespace ThingsGateway.Admin.Application;
|
||||
@@ -34,7 +36,8 @@ public class SeedDataUtil
|
||||
if (!string.IsNullOrEmpty(dataString))//如果有内容
|
||||
{
|
||||
//字段没有数据的替换成null
|
||||
dataString = dataString.Replace("\"\"", "null");
|
||||
dataString = Regex.Replace(dataString, "\\\"[^\"]+?\\\": \\\"\\\"", match => match.Value.Replace("\"\"", "null"));
|
||||
//dataString = dataString.Replace("\"\"", "null");
|
||||
//将json字符串转为实体,这里extjson可以正常转换为字符串
|
||||
var seedDataRecord = Newtonsoft.Json.JsonConvert.DeserializeObject<SeedDataRecords<T>>(dataString);
|
||||
|
||||
|
@@ -37,7 +37,7 @@ namespace ThingsGateway.Admin.Blazor
|
||||
{
|
||||
try
|
||||
{
|
||||
var data = await _serviceScope.ServiceProvider.GetService<UserCenterService>().GetLoginDefaultRazorAsync(UserManager.UserId);
|
||||
var data = await _serviceScope.ServiceProvider.GetService<IUserCenterService>().GetLoginDefaultRazorAsync(UserManager.UserId);
|
||||
var sameLevelMenus = await _serviceScope.ServiceProvider.GetService<IResourceService>().GetaMenuAndSpaListAsync();
|
||||
if (NavigationManager.ToAbsoluteUri(NavigationManager.Uri).AbsolutePath == "/Login" || NavigationManager.ToAbsoluteUri(NavigationManager.Uri).AbsolutePath == "/")
|
||||
NavigationManager.NavigateTo(sameLevelMenus.FirstOrDefault(a => a.Id == data)?.Component ?? "index", true);
|
||||
|
@@ -39,26 +39,26 @@ public partial class Config
|
||||
}
|
||||
private async Task AddCallAsync(ConfigAddInput input)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<ConfigService>().AddAsync(input);
|
||||
await _serviceScope.ServiceProvider.GetService<IConfigService>().AddAsync(input);
|
||||
}
|
||||
|
||||
private async Task DeleteCallAsync(IEnumerable<SysConfig> sysConfigs)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<ConfigService>().DeleteAsync(sysConfigs.Select(a => a.Id).ToArray());
|
||||
await _serviceScope.ServiceProvider.GetService<IConfigService>().DeleteAsync(sysConfigs.Select(a => a.Id).ToArray());
|
||||
}
|
||||
private async Task EditCallAsync(ConfigEditInput sysConfigs)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<ConfigService>().EditAsync(sysConfigs);
|
||||
await _serviceScope.ServiceProvider.GetService<IConfigService>().EditAsync(sysConfigs);
|
||||
}
|
||||
|
||||
private async Task OnSaveAsync()
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<ConfigService>().EditBatchAsync(_sysConfig);
|
||||
await _serviceScope.ServiceProvider.GetService<IConfigService>().EditBatchAsync(_sysConfig);
|
||||
await _mainLayout.StateHasChangedAsync();
|
||||
await PopupService.EnqueueSnackbarAsync("成功", AlertTypes.Success);
|
||||
}
|
||||
private async Task<ISqlSugarPagedList<SysConfig>> QueryCallAsync(ConfigPageInput input)
|
||||
{
|
||||
return await _serviceScope.ServiceProvider.GetService<ConfigService>().PageAsync(input);
|
||||
return await _serviceScope.ServiceProvider.GetService<IConfigService>().PageAsync(input);
|
||||
}
|
||||
}
|
@@ -45,23 +45,23 @@ public partial class Menu
|
||||
private async Task AddCallAsync(MenuAddInput input)
|
||||
{
|
||||
input.ParentId = _search.ParentId;
|
||||
await _serviceScope.ServiceProvider.GetService<MenuService>().AddAsync(input);
|
||||
await _serviceScope.ServiceProvider.GetService<IMenuService>().AddAsync(input);
|
||||
await NavChangeAsync();
|
||||
}
|
||||
private async Task ButtonAddCallAsync(ButtonAddInput input)
|
||||
{
|
||||
input.ParentId = _buttonParentId;
|
||||
await _serviceScope.ServiceProvider.GetService<ButtonService>().AddAsync(input);
|
||||
await _serviceScope.ServiceProvider.GetService<IButtonService>().AddAsync(input);
|
||||
}
|
||||
|
||||
private async Task ButtonDeleteCallAsync(IEnumerable<SysResource> input)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<ButtonService>().DeleteAsync(input.Select(a => a.Id).ToArray());
|
||||
await _serviceScope.ServiceProvider.GetService<IButtonService>().DeleteAsync(input.Select(a => a.Id).ToArray());
|
||||
}
|
||||
|
||||
private async Task ButtonEditCallAsync(ButtonEditInput input)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<ButtonService>().EditAsync(input);
|
||||
await _serviceScope.ServiceProvider.GetService<IButtonService>().EditAsync(input);
|
||||
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ public partial class Menu
|
||||
private async Task<ISqlSugarPagedList<SysResource>> ButtonQueryCallAsync(ButtonPageInput input)
|
||||
{
|
||||
input.ParentId = _buttonParentId;
|
||||
var data = await _serviceScope.ServiceProvider.GetService<ButtonService>().PageAsync(input);
|
||||
var data = await _serviceScope.ServiceProvider.GetService<IButtonService>().PageAsync(input);
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -96,13 +96,13 @@ public partial class Menu
|
||||
|
||||
private async Task DeleteCallAsync(IEnumerable<SysResource> input)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<MenuService>().DeleteAsync(input.Select(a => a.Id).ToArray());
|
||||
await _serviceScope.ServiceProvider.GetService<IMenuService>().DeleteAsync(input.Select(a => a.Id).ToArray());
|
||||
await NavChangeAsync();
|
||||
|
||||
}
|
||||
private async Task EditCallAsync(MenuEditInput input)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<MenuService>().EditAsync(input);
|
||||
await _serviceScope.ServiceProvider.GetService<IMenuService>().EditAsync(input);
|
||||
await NavChangeAsync();
|
||||
|
||||
}
|
||||
@@ -123,7 +123,7 @@ public partial class Menu
|
||||
}
|
||||
private async Task<ISqlSugarPagedList<SysResource>> QueryCallAsync(MenuPageInput input)
|
||||
{
|
||||
var data = await _serviceScope.ServiceProvider.GetService<MenuService>().TreeAsync(input);
|
||||
var data = await _serviceScope.ServiceProvider.GetService<IMenuService>().TreeAsync(input);
|
||||
return data.ToPagedList(input);
|
||||
}
|
||||
|
||||
|
@@ -32,13 +32,13 @@ public partial class OpenApiSession
|
||||
var confirm = await PopupService.OpenConfirmDialogAsync("警告", "确定 ?");
|
||||
if (confirm)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<OpenApiSessionService>().ExitSessionAsync(id);
|
||||
await _serviceScope.ServiceProvider.GetService<IOpenApiSessionService>().ExitSessionAsync(id);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<ISqlSugarPagedList<OpenApiSessionOutput>> SessionQueryCallAsync(OpenApiSessionPageInput input)
|
||||
{
|
||||
return await _serviceScope.ServiceProvider.GetService<OpenApiSessionService>().PageAsync(input);
|
||||
return await _serviceScope.ServiceProvider.GetService<IOpenApiSessionService>().PageAsync(input);
|
||||
}
|
||||
|
||||
private async Task ShowVerificatListAsync(List<VerificatInfo> verificatInfos)
|
||||
@@ -56,7 +56,7 @@ public partial class OpenApiSession
|
||||
VerificatIds = verificats.Select(it => it.Id).ToList(),
|
||||
Id = verificats.First().UserId
|
||||
};
|
||||
await _serviceScope.ServiceProvider.GetService<OpenApiSessionService>().ExitVerificatAsync(send);
|
||||
await _serviceScope.ServiceProvider.GetService<IOpenApiSessionService>().ExitVerificatAsync(send);
|
||||
_verificatInfos.RemoveWhere(it => send.VerificatIds.Contains(it.Id));
|
||||
}
|
||||
|
||||
|
@@ -32,17 +32,17 @@ public partial class OpenApiUserR
|
||||
|
||||
private async Task AddCallAsync(OpenApiUserAddInput input)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<OpenApiUserService>().AddAsync(input);
|
||||
await _serviceScope.ServiceProvider.GetService<IOpenApiUserService>().AddAsync(input);
|
||||
}
|
||||
|
||||
private async Task DeleteCallAsync(IEnumerable<OpenApiUser> users)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<OpenApiUserService>().DeleteAsync(users.Select(a => a.Id).ToArray());
|
||||
await _serviceScope.ServiceProvider.GetService<IOpenApiUserService>().DeleteAsync(users.Select(a => a.Id).ToArray());
|
||||
}
|
||||
|
||||
private async Task EditCallAsync(OpenApiUserEditInput users)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<OpenApiUserService>().EditAsync(users);
|
||||
await _serviceScope.ServiceProvider.GetService<IOpenApiUserService>().EditAsync(users);
|
||||
}
|
||||
|
||||
private List<OpenApiPermissionTreeSelector> GetRouters()
|
||||
@@ -58,7 +58,7 @@ public partial class OpenApiUserR
|
||||
OpenApiUserGrantPermissionInput userGrantRoleInput = new();
|
||||
userGrantRoleInput.Id = _choiceUserId;
|
||||
userGrantRoleInput.PermissionList = _rolesChoice.Select(it => it.ApiRoute).ToList();
|
||||
await _serviceScope.ServiceProvider.GetService<OpenApiUserService>().GrantRoleAsync(userGrantRoleInput);
|
||||
await _serviceScope.ServiceProvider.GetService<IOpenApiUserService>().GrantRoleAsync(userGrantRoleInput);
|
||||
_isShowRoles = false;
|
||||
await _datatable?.QueryClickAsync();
|
||||
}
|
||||
@@ -70,7 +70,7 @@ public partial class OpenApiUserR
|
||||
}
|
||||
private async Task<ISqlSugarPagedList<OpenApiUser>> QueryCallAsync(OpenApiUserPageInput input)
|
||||
{
|
||||
return await _serviceScope.ServiceProvider.GetService<OpenApiUserService>().PageAsync(input);
|
||||
return await _serviceScope.ServiceProvider.GetService<IOpenApiUserService>().PageAsync(input);
|
||||
}
|
||||
|
||||
private async Task UserStatusChangeAsync(OpenApiUser context, bool enable)
|
||||
@@ -78,9 +78,9 @@ public partial class OpenApiUserR
|
||||
try
|
||||
{
|
||||
if (enable)
|
||||
await _serviceScope.ServiceProvider.GetService<OpenApiUserService>().EnableUserAsync(context.Id);
|
||||
await _serviceScope.ServiceProvider.GetService<IOpenApiUserService>().EnableUserAsync(context.Id);
|
||||
else
|
||||
await _serviceScope.ServiceProvider.GetService<OpenApiUserService>().DisableUserAsync(context.Id);
|
||||
await _serviceScope.ServiceProvider.GetService<IOpenApiUserService>().DisableUserAsync(context.Id);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@@ -47,7 +47,7 @@ public partial class Oplog
|
||||
var confirm = await PopupService.OpenConfirmDialogAsync("删除", "确定 ?");
|
||||
if (confirm)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<OperateLogService>().DeleteAsync(_categoryFilters.Select(it => it.Value).ToArray());
|
||||
await _serviceScope.ServiceProvider.GetService<IOperateLogService>().DeleteAsync(_categoryFilters.Select(it => it.Value).ToArray());
|
||||
await _datatable?.QueryClickAsync();
|
||||
}
|
||||
}
|
||||
@@ -68,6 +68,6 @@ public partial class Oplog
|
||||
input.Account = _search.Account;
|
||||
input.Category = _search.Category;
|
||||
input.ExeStatus = _search.ExeStatus;
|
||||
return await _serviceScope.ServiceProvider.GetService<OperateLogService>().PageAsync(input);
|
||||
return await _serviceScope.ServiceProvider.GetService<IOperateLogService>().PageAsync(input);
|
||||
}
|
||||
}
|
@@ -41,17 +41,17 @@ public partial class Role
|
||||
|
||||
private async Task AddCallAsync(RoleAddInput input)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<RoleService>().AddAsync(input);
|
||||
await _serviceScope.ServiceProvider.GetService<IRoleService>().AddAsync(input);
|
||||
}
|
||||
private async Task DeleteCallAsync(IEnumerable<SysRole> sysRoles)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<RoleService>().DeleteAsync(sysRoles.Select(a => a.Id).ToArray());
|
||||
await _serviceScope.ServiceProvider.GetService<IRoleService>().DeleteAsync(sysRoles.Select(a => a.Id).ToArray());
|
||||
await _mainLayout.StateHasChangedAsync();
|
||||
}
|
||||
|
||||
private async Task EditCallAsync(RoleEditInput input)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<RoleService>().EditAsync(input);
|
||||
await _serviceScope.ServiceProvider.GetService<IRoleService>().EditAsync(input);
|
||||
await _mainLayout.StateHasChangedAsync();
|
||||
}
|
||||
private async Task OnRoleHasResuorcesSaveAsync(ModalActionEventArgs args)
|
||||
@@ -62,7 +62,7 @@ public partial class Role
|
||||
var data = new List<SysResource>();
|
||||
userGrantRoleInput.Id = _choiceRoleId;
|
||||
userGrantRoleInput.GrantInfoList = _roleHasResuorces;
|
||||
await _serviceScope.ServiceProvider.GetService<RoleService>().GrantResourceAsync(userGrantRoleInput);
|
||||
await _serviceScope.ServiceProvider.GetService<IRoleService>().GrantResourceAsync(userGrantRoleInput);
|
||||
_isShowResuorces = false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -79,7 +79,7 @@ public partial class Role
|
||||
GrantUserInput userGrantRoleInput = new();
|
||||
userGrantRoleInput.Id = _choiceRoleId;
|
||||
userGrantRoleInput.GrantInfoList = _usersChoice.Select(it => it.Id).ToList();
|
||||
await _serviceScope.ServiceProvider.GetService<RoleService>().GrantUserAsync(userGrantRoleInput);
|
||||
await _serviceScope.ServiceProvider.GetService<IRoleService>().GrantUserAsync(userGrantRoleInput);
|
||||
_isShowUsers = false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -92,19 +92,19 @@ public partial class Role
|
||||
|
||||
private async Task<ISqlSugarPagedList<SysRole>> QueryCallAsync(RolePageInput input)
|
||||
{
|
||||
return await _serviceScope.ServiceProvider.GetService<RoleService>().PageAsync(input);
|
||||
return await _serviceScope.ServiceProvider.GetService<IRoleService>().PageAsync(input);
|
||||
}
|
||||
|
||||
private async Task ResuorceInitAsync()
|
||||
{
|
||||
_resTreeSelectors = (await _serviceScope.ServiceProvider.GetService<ResourceService>().GetRoleGrantResourceMenusAsync());
|
||||
_roleHasResuorces = (await _serviceScope.ServiceProvider.GetService<RoleService>().OwnResourceAsync(_choiceRoleId))?.GrantInfoList;
|
||||
_roleHasResuorces = (await _serviceScope.ServiceProvider.GetService<IRoleService>().OwnResourceAsync(_choiceRoleId))?.GrantInfoList;
|
||||
}
|
||||
|
||||
private async Task<List<UserSelectorOutput>> UserInitAsync()
|
||||
{
|
||||
_allUsers = await _serviceScope.ServiceProvider.GetService<SysUserService>().UserSelectorAsync(_searchKey);
|
||||
var data = await _serviceScope.ServiceProvider.GetService<RoleService>().OwnUserAsync(_choiceRoleId);
|
||||
_allUsers = await _serviceScope.ServiceProvider.GetService<ISysUserService>().UserSelectorAsync(_searchKey);
|
||||
var data = await _serviceScope.ServiceProvider.GetService<IRoleService>().OwnUserAsync(_choiceRoleId);
|
||||
_usersChoice = _allUsers.Where(a => data.Contains(a.Id)).ToList();
|
||||
return _allUsers;
|
||||
}
|
||||
|
@@ -37,14 +37,14 @@ public partial class Session
|
||||
var confirm = await PopupService.OpenConfirmDialogAsync("警告", "确定 ?");
|
||||
if (confirm)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<SessionService>().ExitSessionAsync(id);
|
||||
await _serviceScope.ServiceProvider.GetService<ISessionService>().ExitSessionAsync(id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private async Task<ISqlSugarPagedList<SessionOutput>> SessionQueryCallAsync(SessionPageInput input)
|
||||
{
|
||||
return await _serviceScope.ServiceProvider.GetService<SessionService>().PageAsync(input);
|
||||
return await _serviceScope.ServiceProvider.GetService<ISessionService>().PageAsync(input);
|
||||
}
|
||||
|
||||
private async Task ShowVerificatListAsync(List<VerificatInfo> verificatInfos)
|
||||
@@ -62,7 +62,7 @@ public partial class Session
|
||||
VerificatIds = verificats.Select(it => it.Id).ToList(),
|
||||
Id = verificats.First().UserId
|
||||
};
|
||||
await _serviceScope.ServiceProvider.GetService<SessionService>().ExitVerificatAsync(send);
|
||||
await _serviceScope.ServiceProvider.GetService<ISessionService>().ExitVerificatAsync(send);
|
||||
_verificatInfos.RemoveWhere(it => send.VerificatIds.Contains(it.Id));
|
||||
}
|
||||
|
||||
|
@@ -28,23 +28,23 @@ public partial class Spa
|
||||
|
||||
private async Task AddCallAsync(SpaAddInput input)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<SpaService>().AddAsync(input);
|
||||
await _serviceScope.ServiceProvider.GetService<ISpaService>().AddAsync(input);
|
||||
await _mainLayout.StateHasChangedAsync();
|
||||
}
|
||||
private async Task DeleteCallAsync(IEnumerable<SysResource> input)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<SpaService>().DeleteAsync(input.Select(a => a.Id).ToArray());
|
||||
await _serviceScope.ServiceProvider.GetService<ISpaService>().DeleteAsync(input.Select(a => a.Id).ToArray());
|
||||
await _mainLayout.StateHasChangedAsync();
|
||||
}
|
||||
|
||||
private async Task EditCallAsync(SpaEditInput input)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<SpaService>().EditAsync(input);
|
||||
await _serviceScope.ServiceProvider.GetService<ISpaService>().EditAsync(input);
|
||||
await _mainLayout.StateHasChangedAsync();
|
||||
}
|
||||
|
||||
private async Task<ISqlSugarPagedList<SysResource>> QueryCallAsync(SpaPageInput input)
|
||||
{
|
||||
return await _serviceScope.ServiceProvider.GetService<SpaService>().PageAsync(input);
|
||||
return await _serviceScope.ServiceProvider.GetService<ISpaService>().PageAsync(input);
|
||||
}
|
||||
}
|
@@ -35,17 +35,17 @@ public partial class User
|
||||
|
||||
private async Task AddCallAsync(UserAddInput input)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<SysUserService>().AddAsync(input);
|
||||
await _serviceScope.ServiceProvider.GetService<ISysUserService>().AddAsync(input);
|
||||
}
|
||||
private async Task DeleteCallAsync(IEnumerable<SysUser> users)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<SysUserService>().DeleteAsync(users.Select(a => a.Id).ToArray());
|
||||
await _serviceScope.ServiceProvider.GetService<ISysUserService>().DeleteAsync(users.Select(a => a.Id).ToArray());
|
||||
await _mainLayout.StateHasChangedAsync();
|
||||
}
|
||||
|
||||
private async Task EditCallAsync(UserEditInput users)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<SysUserService>().EditAsync(users);
|
||||
await _serviceScope.ServiceProvider.GetService<ISysUserService>().EditAsync(users);
|
||||
await _mainLayout.StateHasChangedAsync();
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ public partial class User
|
||||
UserGrantRoleInput userGrantRoleInput = new();
|
||||
userGrantRoleInput.Id = _choiceUserId;
|
||||
userGrantRoleInput.RoleIdList = _rolesChoice.Select(it => it.Id).ToList();
|
||||
await _serviceScope.ServiceProvider.GetService<SysUserService>().GrantRoleAsync(userGrantRoleInput);
|
||||
await _serviceScope.ServiceProvider.GetService<ISysUserService>().GrantRoleAsync(userGrantRoleInput);
|
||||
_isShowRoles = false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -68,20 +68,20 @@ public partial class User
|
||||
}
|
||||
private async Task<ISqlSugarPagedList<SysUser>> QueryCallAsync(UserPageInput input)
|
||||
{
|
||||
return await _serviceScope.ServiceProvider.GetService<SysUserService>().PageAsync(input);
|
||||
return await _serviceScope.ServiceProvider.GetService<ISysUserService>().PageAsync(input);
|
||||
}
|
||||
|
||||
private async Task ResetPasswordAsync(SysUser sysUser)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<SysUserService>().ResetPasswordAsync(sysUser.Id);
|
||||
await _serviceScope.ServiceProvider.GetService<ISysUserService>().ResetPasswordAsync(sysUser.Id);
|
||||
await PopupService.EnqueueSnackbarAsync(new("成功", AlertTypes.Success));
|
||||
await _mainLayout.StateHasChangedAsync();
|
||||
}
|
||||
|
||||
private async Task RoleInitAsync()
|
||||
{
|
||||
_allRoles = await _serviceScope.ServiceProvider.GetService<RoleService>().RoleSelectorAsync();
|
||||
var data = await _serviceScope.ServiceProvider.GetService<RoleService>().GetRoleIdListByUserIdAsync(_choiceUserId);
|
||||
_allRoles = await _serviceScope.ServiceProvider.GetService<IRoleService>().RoleSelectorAsync();
|
||||
var data = await _serviceScope.ServiceProvider.GetService<IRoleService>().GetRoleIdListByUserIdAsync(_choiceUserId);
|
||||
_rolesChoice = _allRoles.Where(a => data.Contains(a.Id)).ToList();
|
||||
}
|
||||
private async Task UserStatusChangeAsync(SysUser context, bool enable)
|
||||
@@ -89,9 +89,9 @@ public partial class User
|
||||
try
|
||||
{
|
||||
if (enable)
|
||||
await _serviceScope.ServiceProvider.GetService<SysUserService>().EnableUserAsync(context.Id);
|
||||
await _serviceScope.ServiceProvider.GetService<ISysUserService>().EnableUserAsync(context.Id);
|
||||
else
|
||||
await _serviceScope.ServiceProvider.GetService<SysUserService>().DisableUserAsync(context.Id);
|
||||
await _serviceScope.ServiceProvider.GetService<ISysUserService>().DisableUserAsync(context.Id);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@@ -44,14 +44,14 @@ public partial class UserCenter
|
||||
|
||||
async Task OnDefaultRazorSaveAsync()
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<UserCenterService>().UpdateUserDefaultRazorAsync(UserManager.UserId, _defaultMenuId);
|
||||
await _serviceScope.ServiceProvider.GetService<IUserCenterService>().UpdateUserDefaultRazorAsync(UserManager.UserId, _defaultMenuId);
|
||||
await _mainLayout.StateHasChangedAsync();
|
||||
await PopupService.EnqueueSnackbarAsync("成功", AlertTypes.Success);
|
||||
}
|
||||
|
||||
async Task OnShortcutSaveAsync()
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<UserCenterService>().UpdateWorkbenchAsync(_menusChoice);
|
||||
await _serviceScope.ServiceProvider.GetService<IUserCenterService>().UpdateWorkbenchAsync(_menusChoice);
|
||||
await _mainLayout.StateHasChangedAsync();
|
||||
await PopupService.EnqueueSnackbarAsync("成功", AlertTypes.Success);
|
||||
}
|
||||
@@ -62,7 +62,7 @@ public partial class UserCenter
|
||||
{
|
||||
//验证成功,操作业务
|
||||
_passwordInfoInput.Id = UserResoures.CurrentUser.Id;
|
||||
await _serviceScope.ServiceProvider.GetService<UserCenterService>().EditPasswordAsync(_passwordInfoInput);
|
||||
await _serviceScope.ServiceProvider.GetService<IUserCenterService>().EditPasswordAsync(_passwordInfoInput);
|
||||
await _mainLayout.StateHasChangedAsync();
|
||||
await PopupService.EnqueueSnackbarAsync("成功,将重新登录", AlertTypes.Success);
|
||||
await Task.Delay(2000);
|
||||
@@ -72,7 +72,7 @@ public partial class UserCenter
|
||||
|
||||
async Task OnUpdateUserInfoAsync()
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<UserCenterService>().UpdateUserInfoAsync(_updateInfoInput);
|
||||
await _serviceScope.ServiceProvider.GetService<IUserCenterService>().UpdateUserInfoAsync(_updateInfoInput);
|
||||
await _mainLayout.StateHasChangedAsync();
|
||||
await PopupService.EnqueueSnackbarAsync("成功", AlertTypes.Success);
|
||||
}
|
||||
|
@@ -56,7 +56,7 @@ public partial class Vislog
|
||||
var confirm = await PopupService.OpenConfirmDialogAsync("删除", "确定 ?");
|
||||
if (confirm)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<VisitLogService>().DeleteAsync(_categoryFilters.Select(it => it.Value).ToArray());
|
||||
await _serviceScope.ServiceProvider.GetService<IVisitLogService>().DeleteAsync(_categoryFilters.Select(it => it.Value).ToArray());
|
||||
await _datatable?.QueryClickAsync();
|
||||
}
|
||||
}
|
||||
@@ -74,7 +74,7 @@ public partial class Vislog
|
||||
|
||||
private async Task<ISqlSugarPagedList<SysVisitLog>> QueryCallAsync(VisitLogPageInput input)
|
||||
{
|
||||
var data = await _serviceScope.ServiceProvider.GetService<VisitLogService>().PageAsync(input);
|
||||
var data = await _serviceScope.ServiceProvider.GetService<IVisitLogService>().PageAsync(input);
|
||||
return data;
|
||||
}
|
||||
}
|
@@ -1,12 +1,12 @@
|
||||
#region copyright
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>
|
||||
// GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway
|
||||
// GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway
|
||||
// ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQȺ<EFBFBD><EFBFBD>605534569
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
@@ -16,8 +16,7 @@ using Masa.Blazor.Presets;
|
||||
|
||||
using Microsoft.AspNetCore.Components.Web;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
using System.Diagnostics;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
using ThingsGateway.Foundation.Extension.String;
|
||||
|
||||
@@ -44,7 +43,7 @@ public partial class Login
|
||||
/// <inheritdoc/>
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
if (Debugger.IsAttached)
|
||||
if (App.WebHostEnvironment.IsDevelopment())
|
||||
{
|
||||
_loginModel.Account = "superAdmin";
|
||||
_password = "111111";
|
||||
@@ -54,7 +53,7 @@ public partial class Login
|
||||
_configTitle = (await _serviceScope.ServiceProvider.GetService<IConfigService>().GetByConfigKeyAsync(ConfigConst.SYS_CONFIGBASEDEFAULT, ConfigConst.CONFIG_TITLE))?.ConfigValue;
|
||||
_configRemark = (await _serviceScope.ServiceProvider.GetService<IConfigService>().GetByConfigKeyAsync(ConfigConst.SYS_CONFIGBASEDEFAULT, ConfigConst.CONFIG_REMARK))?.ConfigValue;
|
||||
_showCaptcha = (await _serviceScope.ServiceProvider.GetService<IConfigService>().GetByConfigKeyAsync(ConfigConst.SYS_CONFIGBASEDEFAULT, ConfigConst.CONFIG_CAPTCHA_OPEN))?.ConfigValue?.ToBool(false) == true;
|
||||
_welcome = "<EFBFBD><EFBFBD>ӭʹ<EFBFBD><EFBFBD>" + _configTitle + "!";
|
||||
_welcome = "欢迎使用" + _configTitle + "!";
|
||||
await base.OnParametersSetAsync();
|
||||
}
|
||||
|
||||
@@ -102,14 +101,14 @@ public partial class Login
|
||||
await _captcha.RefreshCode();
|
||||
}
|
||||
|
||||
await PopupService.EnqueueSnackbarAsync(new("<EFBFBD><EFBFBD>¼<EFBFBD><EFBFBD><EFBFBD><EFBFBD>" + ": " + ret.Msg.ToString(), AlertTypes.Error));
|
||||
await PopupService.EnqueueSnackbarAsync(new("登录错误" + ": " + ret.Msg.ToString(), AlertTypes.Error));
|
||||
}
|
||||
else
|
||||
{
|
||||
await PopupService.EnqueueSnackbarAsync(new("<EFBFBD><EFBFBD>¼<EFBFBD>ɹ<EFBFBD>", AlertTypes.Success));
|
||||
await PopupService.EnqueueSnackbarAsync(new("登录成功", AlertTypes.Success));
|
||||
await Task.Delay(500);
|
||||
var userId = await _serviceScope.ServiceProvider.GetService<SysUserService>().GetIdByAccountAsync(_loginModel.Account);
|
||||
var data = await _serviceScope.ServiceProvider.GetService<UserCenterService>().GetLoginDefaultRazorAsync(userId);
|
||||
var userId = await _serviceScope.ServiceProvider.GetService<ISysUserService>().GetIdByAccountAsync(_loginModel.Account);
|
||||
var data = await _serviceScope.ServiceProvider.GetService<IUserCenterService>().GetLoginDefaultRazorAsync(userId);
|
||||
var sameLevelMenus = await _serviceScope.ServiceProvider.GetService<ResourceService>().GetaMenuAndSpaListAsync();
|
||||
if (_NavigationManager.ToAbsoluteUri(_NavigationManager.Uri).AbsolutePath == "/Login" || _NavigationManager.ToAbsoluteUri(_NavigationManager.Uri).AbsolutePath == "/")
|
||||
await _ajaxService.GotoAsync(sameLevelMenus.FirstOrDefault(a => a.Id == data)?.Component ?? "index");
|
||||
@@ -124,7 +123,7 @@ public partial class Login
|
||||
await _captcha.RefreshCode();
|
||||
}
|
||||
|
||||
await PopupService.EnqueueSnackbarAsync(new("<EFBFBD><EFBFBD>¼<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", AlertTypes.Error));
|
||||
await PopupService.EnqueueSnackbarAsync(new("登录错误", AlertTypes.Error));
|
||||
}
|
||||
}
|
||||
private async Task<string> RefreshCode()
|
||||
|
@@ -1,12 +1,12 @@
|
||||
#region copyright
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>
|
||||
// GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway
|
||||
// GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway
|
||||
// ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQȺ<EFBFBD><EFBFBD>605534569
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
@@ -16,7 +16,7 @@ using ThingsGateway.Foundation.Extension.String;
|
||||
|
||||
namespace ThingsGateway.Admin.Blazor;
|
||||
|
||||
public partial class MainLayout
|
||||
public partial class MainLayout : IDisposable
|
||||
{
|
||||
private List<SysResource> _breadcrumbSysResources = new();
|
||||
private string _configCopyRight = "";
|
||||
@@ -43,16 +43,23 @@ public partial class MainLayout
|
||||
private IServiceScopeFactory _serviceScopeFactory { get; set; }
|
||||
[Inject]
|
||||
private UserResoures _userResoures { get; set; }
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_serviceScope.Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ҳ<EFBFBD><EFBFBD>ˢ<EFBFBD><EFBFBD>
|
||||
/// 页面刷新
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task StateHasChangedAsync()
|
||||
{
|
||||
_configCopyRight = (await _serviceScope.ServiceProvider.GetService<IConfigService>().GetByConfigKeyAsync(ConfigConst.SYS_CONFIGBASEDEFAULT, ConfigConst.CONFIG_COPYRIGHT)).ConfigValue;
|
||||
_configTitle = (await _serviceScope.ServiceProvider.GetService<IConfigService>().GetByConfigKeyAsync(ConfigConst.SYS_CONFIGBASEDEFAULT, ConfigConst.CONFIG_TITLE)).ConfigValue;
|
||||
_configCopyRightUrl = (await _serviceScope.ServiceProvider.GetService<IConfigService>().GetByConfigKeyAsync(ConfigConst.SYS_CONFIGBASEDEFAULT, ConfigConst.CONFIG_COPYRIGHT_URL)).ConfigValue;
|
||||
_configPageTab = (await _serviceScope.ServiceProvider.GetService<IConfigService>().GetByConfigKeyAsync(ConfigConst.SYS_CONFIGBASEDEFAULT, ConfigConst.CONFIG_PAGETAB)).ConfigValue.ToBool(true);
|
||||
var configService = _serviceScope.ServiceProvider.GetService<IConfigService>();
|
||||
_configCopyRight = (await configService.GetByConfigKeyAsync(ConfigConst.SYS_CONFIGBASEDEFAULT, ConfigConst.CONFIG_COPYRIGHT)).ConfigValue;
|
||||
_configTitle = (await configService.GetByConfigKeyAsync(ConfigConst.SYS_CONFIGBASEDEFAULT, ConfigConst.CONFIG_TITLE)).ConfigValue;
|
||||
_configCopyRightUrl = (await configService.GetByConfigKeyAsync(ConfigConst.SYS_CONFIGBASEDEFAULT, ConfigConst.CONFIG_COPYRIGHT_URL)).ConfigValue;
|
||||
_configPageTab = (await configService.GetByConfigKeyAsync(ConfigConst.SYS_CONFIGBASEDEFAULT, ConfigConst.CONFIG_PAGETAB)).ConfigValue.ToBool(true);
|
||||
|
||||
await _userResoures.InitUserAsync();
|
||||
await _userResoures.InitMenuAsync();
|
||||
|
@@ -24,7 +24,6 @@ public class Startup : AppStartup
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.ThingsGatewayComponentsConfigureServices();
|
||||
|
||||
services.AddScoped<UserResoures>();
|
||||
|
||||
}
|
||||
|
@@ -3,6 +3,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="8.0.0" />
|
||||
<PackageReference Include="Masa.Blazor.SomethingSkia" Version="1.2.2" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
|
@@ -35,6 +35,7 @@ public class Startup : AppStartup
|
||||
{
|
||||
WorkerId = 4// 取值范围0~63
|
||||
});
|
||||
services.ThingsGatewayCoreConfigureServices();
|
||||
|
||||
services.AddComponent<LoggingConsoleComponent>();//启动控制台日志格式化组件
|
||||
ThingsGateway.Core.TypeExtensions.DefaultFuncs.Add(a => a.GetCustomAttribute<SqlSugar.SugarColumn>()?.ColumnDescription);
|
||||
|
@@ -5,8 +5,10 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.9.1.5" />
|
||||
<PackageReference Include="SqlSugarCore" Version="5.1.4.122" />
|
||||
<PackageReference Include="Furion.Pure" Version="4.9.1.11" />
|
||||
<PackageReference Include="Furion.Extras.ObjectMapper.Mapster" Version="4.9.1.11" />
|
||||
<PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.9.1.11" />
|
||||
<PackageReference Include="SqlSugarCore" Version="5.1.4.126" />
|
||||
<PackageReference Include="UAParser" Version="3.1.47" />
|
||||
<PackageReference Include="Yitter.IdGenerator" Version="1.0.14" />
|
||||
</ItemGroup>
|
||||
|
@@ -56,6 +56,7 @@ public abstract class BaseComponentBase : ComponentBase, IDisposable
|
||||
/// </summary>
|
||||
public virtual void Dispose()
|
||||
{
|
||||
_serviceScope.Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@@ -19,7 +19,7 @@ using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace ThingsGateway.Components;
|
||||
|
||||
public static class ConfigureService
|
||||
public static class ServiceExtensions
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public static void ThingsGatewayComponentsConfigureServices(this IServiceCollection services)
|
||||
@@ -65,9 +65,7 @@ public static class ConfigureService
|
||||
{ nameof(MTimeline), new Dictionary<string, object>() { { nameof(MTimeline.Dense), true } } },
|
||||
{ nameof(MToolbar), new Dictionary<string, object>() { { nameof(MToolbar.Dense), true } } },
|
||||
{ "MTreeview", new Dictionary<string, object>() { { "Dense", true } } },
|
||||
{ nameof(PImageCaptcha), new Dictionary<string, object>() { { nameof(PImageCaptcha.Dense), true } } }
|
||||
|
||||
|
||||
{ "PImageCaptcha", new Dictionary<string, object>() { { "Dense", true } } }
|
||||
|
||||
};
|
||||
options.ConfigureTheme(theme =>
|
||||
@@ -98,6 +96,7 @@ public static class ConfigureService
|
||||
services.AddScoped<InitTimezone>();
|
||||
services.AddScoped<AjaxService>();
|
||||
services.AddScoped<CookieStorage>();
|
||||
services.AddScoped<IDefaultTimezoneOffsetAccessor, DefaultTimezoneOffsetAccessor>();
|
||||
|
||||
}
|
||||
}
|
@@ -1,4 +1,4 @@
|
||||
#region copyright
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
@@ -10,15 +10,12 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
namespace ThingsGateway.Foundation.Serial;
|
||||
namespace ThingsGateway.Components;
|
||||
|
||||
/// <summary>
|
||||
/// 字节事件
|
||||
/// </summary>
|
||||
public class SerialReceivedEventArgs : TouchSocketEventArgs
|
||||
public class DefaultTimezoneOffsetAccessor : IDefaultTimezoneOffsetAccessor
|
||||
{
|
||||
/// <summary>
|
||||
/// 数据块
|
||||
/// </summary>
|
||||
public ByteBlock UserToken { get; set; }
|
||||
}
|
||||
public TimeSpan GetTimezoneOffsetResult()
|
||||
{
|
||||
return TimeSpan.FromHours(8);
|
||||
}
|
||||
}
|
@@ -0,0 +1,8 @@
|
||||
|
||||
namespace ThingsGateway.Components
|
||||
{
|
||||
public interface IDefaultTimezoneOffsetAccessor
|
||||
{
|
||||
TimeSpan GetTimezoneOffsetResult();
|
||||
}
|
||||
}
|
@@ -10,9 +10,6 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace ThingsGateway.Components;
|
||||
|
||||
/// <summary>
|
||||
@@ -43,17 +40,11 @@ public class InitTimezone : IDisposable
|
||||
/// <param name="jsRuntime"></param>
|
||||
/// <param name="storage"></param>
|
||||
/// <param name="serviceProvider"></param>
|
||||
public InitTimezone(IJSRuntime jsRuntime, CookieStorage storage, IServiceProvider serviceProvider)
|
||||
public InitTimezone(IJSRuntime jsRuntime, CookieStorage storage, IDefaultTimezoneOffsetAccessor defaultTimezoneOffsetAccessor)
|
||||
{
|
||||
IHttpContextAccessor httpContextAccessor = serviceProvider.GetService<IHttpContextAccessor>();
|
||||
_jsRuntime = jsRuntime;
|
||||
_storage = storage;
|
||||
var httpContext = httpContextAccessor?.HttpContext;
|
||||
if (httpContext is not null)
|
||||
{
|
||||
var timezoneOffsetResult = httpContext.Request.Cookies[_timezoneOffsetKey];
|
||||
_timezoneOffset = TimeSpan.FromMinutes(Convert.ToDouble(timezoneOffsetResult));
|
||||
}
|
||||
_timezoneOffset = defaultTimezoneOffsetAccessor.GetTimezoneOffsetResult();
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取Web客户端时差
|
||||
|
@@ -3,7 +3,6 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Masa.Blazor" Version="1.2.2" />
|
||||
<PackageReference Include="Masa.Blazor.SomethingSkia" Version="1.2.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@@ -10,8 +10,6 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using Furion.DependencyInjection;
|
||||
|
||||
using Mapster;
|
||||
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
@@ -23,8 +21,9 @@ namespace ThingsGateway.Core;
|
||||
/// <summary>
|
||||
/// 系统内存缓存
|
||||
/// </summary>
|
||||
public class MemoryCache : ISingleton
|
||||
public class MemoryCache
|
||||
{
|
||||
public static MemoryCache Instance { get; private set; } = new();
|
||||
private const string intervalStr = "---___---";
|
||||
private readonly Microsoft.Extensions.Caching.Memory.MemoryCache _memoryCache = new(new MemoryCacheOptions());
|
||||
private readonly Microsoft.Extensions.Caching.Memory.MemoryCache _prefixmemoryCache = new(new MemoryCacheOptions());
|
||||
|
@@ -10,20 +10,15 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using Furion;
|
||||
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace ThingsGateway.Core;
|
||||
|
||||
/// <summary>
|
||||
/// Startup
|
||||
/// </summary>
|
||||
[AppStartup(9999)]
|
||||
public class Startup : AppStartup
|
||||
public static class ServiceExtensions
|
||||
{
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
/// <inheritdoc/>
|
||||
public static void ThingsGatewayCoreConfigureServices(this IServiceCollection services)
|
||||
{
|
||||
|
||||
services.AddSingleton(a => MemoryCache.Instance);
|
||||
}
|
||||
}
|
@@ -10,8 +10,6 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using Furion;
|
||||
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Globalization;
|
||||
@@ -90,7 +88,7 @@ public static class TypeExtensions
|
||||
public static string GetDescription(this Type modelType, string name, Func<MemberInfo, string> func = null)
|
||||
{
|
||||
var cacheKey = $"{nameof(GetDescription)}-{CultureInfo.CurrentUICulture.Name}-{modelType.FullName}-{name}-{modelType.TypeHandle.Value}";
|
||||
var str = App.GetService<MemoryCache>().GetOrCreate(cacheKey, entry =>
|
||||
var str = MemoryCache.Instance.GetOrCreate(cacheKey, entry =>
|
||||
{
|
||||
string dn = default;
|
||||
{
|
||||
|
@@ -1,8 +1,11 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Furion.Pure" Version="4.9.1.5" />
|
||||
<PackageReference Include="Furion.Extras.ObjectMapper.Mapster" Version="4.9.1.5" />
|
||||
|
||||
<PackageReference Include="Mapster" Version="7.4.0" />
|
||||
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="8.0.0" />
|
||||
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
|
@@ -1,14 +1,7 @@
|
||||
<Project>
|
||||
<Import Project="$(SolutionDir)\Directory.Build.props" />
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net6.0;net8.0;</TargetFrameworks>
|
||||
<Version>4.0.0.3</Version>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Authors>Diego</Authors>
|
||||
<Product>ThingsGateway</Product>
|
||||
<Copyright>© 2023-present Diego</Copyright>
|
||||
<RepositoryUrl>https://gitee.com/diego2098/ThingsGateway</RepositoryUrl>
|
||||
<SatelliteResourceLanguages>zh-Hans</SatelliteResourceLanguages>
|
||||
<GenerateDocumentationFile>False</GenerateDocumentationFile>
|
||||
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
|
@@ -12,6 +12,8 @@
|
||||
|
||||
using Photino.Blazor;
|
||||
|
||||
using ThingsGateway.Core;
|
||||
|
||||
namespace ThingsGateway.Foundation.Demo;
|
||||
|
||||
internal class Program
|
||||
@@ -23,11 +25,10 @@ internal class Program
|
||||
|
||||
var appBuilder = PhotinoBlazorAppBuilder.CreateDefault(args);
|
||||
|
||||
Serve.RunNative();
|
||||
|
||||
appBuilder.RootComponents.Add<App>("#app");
|
||||
|
||||
appBuilder.Services.ThingsGatewayComponentsConfigureServices();
|
||||
appBuilder.Services.ThingsGatewayCoreConfigureServices();
|
||||
var app = appBuilder.Build();
|
||||
app.MainWindow.SetTitle("ThingsGateway.Foundation.Demo");
|
||||
app.MainWindow.SetIconFile("wwwroot/favicon.ico");
|
||||
|
@@ -12,6 +12,9 @@
|
||||
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
using ThingsGateway.Components;
|
||||
|
||||
|
||||
namespace ThingsGateway.Foundation.Demo;
|
||||
using LogLevel = Microsoft.Extensions.Logging.LogLevel;
|
||||
/// <summary>
|
||||
|
@@ -18,10 +18,10 @@
|
||||
<MCard Flat Class="pa-2 my-1" Style="width:100%">
|
||||
<div class="mb-4">通道配置</div>
|
||||
<MRow Justify="JustifyTypes.Start" Align="AlignTypes.Center">
|
||||
<MTextField Style="max-width:100px" Class="ma-1" Outlined Label=@(_serialProperty.Description(x => x.PortName)) Dense HideDetails="@("auto")" @bind-Value=@_serialProperty.PortName />
|
||||
<MTextField Style="max-width:100px" Class="ma-1" Outlined Label=@(_serialProperty.Description(x => x.BaudRate)) Dense HideDetails="@("auto")" @bind-Value=@_serialProperty.BaudRate />
|
||||
<MTextField Style="max-width:100px" Class="ma-1" Outlined Label=@(_serialProperty.Description(x => x.DataBits)) Dense HideDetails="@("auto")" @bind-Value=@_serialProperty.DataBits />
|
||||
<MSelect Class="ma-1 " Style="max-width:200px" Outlined @bind-Value="_serialProperty.Parity" Label="@(_serialProperty.Description(x => x.Parity))"
|
||||
<MTextField Style="max-width:100px" Class="ma-1" Outlined Label=@(_serialPortOption.Description(x => x.PortName)) Dense HideDetails="@("auto")" @bind-Value=@_serialPortOption.PortName />
|
||||
<MTextField Style="max-width:100px" Class="ma-1" Outlined Label=@(_serialPortOption.Description(x => x.BaudRate)) Dense HideDetails="@("auto")" @bind-Value=@_serialPortOption.BaudRate />
|
||||
<MTextField Style="max-width:100px" Class="ma-1" Outlined Label=@(_serialPortOption.Description(x => x.DataBits)) Dense HideDetails="@("auto")" @bind-Value=@_serialPortOption.DataBits />
|
||||
<MSelect Class="ma-1 " Style="max-width:200px" Outlined @bind-Value="_serialPortOption.Parity" Label="@(_serialPortOption.Description(x => x.Parity))"
|
||||
Items=@(typeof(Parity).GetEnumList())
|
||||
MenuProps="@(props => { props.Auto = true; props.OffsetY = true; })"
|
||||
ItemText=@((u) =>u.Description)
|
||||
@@ -29,7 +29,7 @@
|
||||
HideDetails=@("auto") Height="30"
|
||||
Dense>
|
||||
</MSelect>
|
||||
<MSelect Class="ma-1 " Style="max-width:200px" Outlined @bind-Value="_serialProperty.StopBits" Label="@(_serialProperty.Description(x => x.StopBits))"
|
||||
<MSelect Class="ma-1 " Style="max-width:200px" Outlined @bind-Value="_serialPortOption.StopBits" Label="@(_serialPortOption.Description(x => x.StopBits))"
|
||||
Items=@(typeof(StopBits).GetEnumList())
|
||||
MenuProps="@(props => { props.Auto = true; props.OffsetY = true; })"
|
||||
ItemText=@((u) =>u.Description)
|
@@ -13,39 +13,39 @@
|
||||
namespace ThingsGateway.Foundation.Demo;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public partial class SerialSessionPage : IDisposable
|
||||
public partial class SerialPortClientPage : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// 日志输出
|
||||
/// </summary>
|
||||
public Action<LogLevel, object, string, Exception> LogAction;
|
||||
|
||||
private readonly SerialProperty _serialProperty = new();
|
||||
private readonly SerialPortOption _serialPortOption = new();
|
||||
private TouchSocketConfig _config;
|
||||
private SerialSession _serialSession { get; set; } = new();
|
||||
private SerialPortClient _serialPortClient { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
_serialSession.SafeDispose();
|
||||
_serialPortClient.SafeDispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public SerialSession GetSerialSession()
|
||||
public SerialPortClient GetSerialPortClient()
|
||||
{
|
||||
_config ??= new TouchSocketConfig();
|
||||
var LogMessage = new LoggerGroup() { LogLevel = LogLevel.Trace };
|
||||
LogMessage.AddLogger(new EasyLogger(LogOut) { LogLevel = LogLevel.Trace });
|
||||
_config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage));
|
||||
_config.SetSerialProperty(_serialProperty);
|
||||
_config.SetSerialPortOption(_serialPortOption);
|
||||
//载入配置
|
||||
_serialSession.Setup(_config);
|
||||
return _serialSession;
|
||||
_serialPortClient.Setup(_config);
|
||||
return _serialPortClient;
|
||||
}
|
||||
internal void StateHasChangedAsync()
|
||||
{
|
||||
@@ -63,7 +63,7 @@ public partial class SerialSessionPage : IDisposable
|
||||
var LogMessage = new LoggerGroup() { LogLevel = LogLevel.Trace };
|
||||
LogMessage.AddLogger(new EasyLogger(LogOut) { LogLevel = LogLevel.Trace });
|
||||
_config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage));
|
||||
_serialSession.Setup(_config);
|
||||
_serialPortClient.Setup(_config);
|
||||
}
|
||||
base.OnAfterRender(firstRender);
|
||||
}
|
||||
@@ -80,8 +80,8 @@ public partial class SerialSessionPage : IDisposable
|
||||
{
|
||||
try
|
||||
{
|
||||
_serialSession.Close();
|
||||
await GetSerialSession().ConnectAsync();
|
||||
_serialPortClient.Close();
|
||||
await GetSerialPortClient().ConnectAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -93,7 +93,7 @@ public partial class SerialSessionPage : IDisposable
|
||||
{
|
||||
try
|
||||
{
|
||||
_serialSession.Close();
|
||||
_serialPortClient.Close();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
@@ -16,6 +16,6 @@ global using System.Threading.Tasks;
|
||||
|
||||
global using ThingsGateway.Components;
|
||||
global using ThingsGateway.Foundation.Core;
|
||||
global using ThingsGateway.Foundation.Serial;
|
||||
global using ThingsGateway.Foundation.SerialPorts;
|
||||
global using ThingsGateway.Foundation.Sockets;
|
||||
|
||||
|
@@ -19,7 +19,7 @@
|
||||
@using Masa.Blazor;
|
||||
@namespace ThingsGateway.Foundation.Demo
|
||||
|
||||
<SerialSessionPage @ref=_serialSessionPage></SerialSessionPage>
|
||||
<SerialPortClientPage @ref=_serialPortClientPage></SerialPortClientPage>
|
||||
|
||||
<MCard Flat Class="pa-2 my-1" Style="width:100%">
|
||||
<div class="mb-4">驱动配置</div>
|
||||
|
@@ -17,9 +17,9 @@ namespace ThingsGateway.Foundation.Demo;
|
||||
public partial class DLT645_2007DebugPage
|
||||
{
|
||||
/// <summary>
|
||||
/// SerialSessionPage
|
||||
/// SerialPortClientPage
|
||||
/// </summary>
|
||||
private SerialSessionPage _serialSessionPage;
|
||||
private SerialPortClientPage _serialPortClientPage;
|
||||
private DriverDebugUIPage _driverDebugUIPage;
|
||||
private ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007 _plc;
|
||||
/// <summary>
|
||||
@@ -37,15 +37,15 @@ public partial class DLT645_2007DebugPage
|
||||
//链路基础配置项
|
||||
var config = new TouchSocketConfig();
|
||||
config
|
||||
.SetSerialProperty(new SerialProperty() //串口链路才需要
|
||||
.SetSerialPortOption(new SerialPortOption() //串口链路才需要
|
||||
{
|
||||
PortName = "COM1"
|
||||
});
|
||||
var serialSession = new SerialSession();//链路对象
|
||||
serialSession.Setup(config);
|
||||
var serialPortClient = new SerialPortClient();//链路对象
|
||||
serialPortClient.Setup(config);
|
||||
|
||||
//创建协议对象,构造函数需要传入对应链路对象
|
||||
DLT645_2007 plc = new(serialSession)//传入链路
|
||||
DLT645_2007 plc = new(serialPortClient)//传入链路
|
||||
{
|
||||
//协议配置
|
||||
DataFormat = DataFormat.ABCD,
|
||||
@@ -69,9 +69,9 @@ public partial class DLT645_2007DebugPage
|
||||
""", "csharp"));
|
||||
|
||||
|
||||
if (_serialSessionPage != null)
|
||||
_serialSessionPage.LogAction = _driverDebugUIPage.LogOut;
|
||||
_plc = new ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007(_serialSessionPage.GetSerialSession());
|
||||
if (_serialPortClientPage != null)
|
||||
_serialPortClientPage.LogAction = _driverDebugUIPage.LogOut;
|
||||
_plc = new ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007(_serialPortClientPage.GetSerialPortClient());
|
||||
_driverDebugUIPage.Plc = _plc;
|
||||
|
||||
//初始化
|
||||
|
@@ -17,7 +17,7 @@ namespace ThingsGateway.Foundation.Demo;
|
||||
public partial class DLT645_2007OverTcpDebugPage
|
||||
{
|
||||
/// <summary>
|
||||
/// SerialSessionPage
|
||||
/// SerialPortClientPage
|
||||
/// </summary>
|
||||
private TcpClientPage _tcpClientPage;
|
||||
private DriverDebugUIPage _driverDebugUIPage;
|
||||
|
@@ -40,7 +40,9 @@
|
||||
Dense>
|
||||
</MSelect>
|
||||
|
||||
<MCheckbox Class="ma-1" Style="max-width:200px" Label=@(_plc.Description(x => x.IsRtu)) Dense HideDetails="@("auto")" @bind-Value=@_plc.IsRtu></MCheckbox>
|
||||
<MCheckbox Class="ma-1" Style="max-width:200px" Label=@(_plc.Description(x => x.IsCheckMessageId)) Dense HideDetails="@("auto")" @bind-Value=@_plc.IsCheckMessageId></MCheckbox>
|
||||
<MCheckbox Class="ma-1" Style="max-width:200px" Label=@(_plc.Description(x => x.Crc16CheckEnable)) Dense HideDetails="@("auto")" @bind-Value=@_plc.Crc16CheckEnable></MCheckbox>
|
||||
|
||||
}
|
||||
</MRow>
|
@@ -13,9 +13,9 @@
|
||||
namespace ThingsGateway.Foundation.Demo;
|
||||
|
||||
/// <summary>
|
||||
/// ModbusTcpDtuDebugPage
|
||||
/// ModbusDtuDebugPage
|
||||
/// </summary>
|
||||
public partial class ModbusTcpDtuDebugPage
|
||||
public partial class ModbusDtuDebugPage
|
||||
{
|
||||
/// <summary>
|
||||
/// TcpServerPage
|
||||
@@ -23,7 +23,7 @@ public partial class ModbusTcpDtuDebugPage
|
||||
private TcpServerPage _tcpServerPage;
|
||||
private DriverDebugUIPage _driverDebugUIPage;
|
||||
|
||||
private ThingsGateway.Foundation.Adapter.Modbus.ModbusTcpDtu _plc;
|
||||
private ThingsGateway.Foundation.Adapter.Modbus.ModbusDtu _plc;
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
@@ -70,7 +70,7 @@ public partial class ModbusTcpDtuDebugPage
|
||||
|
||||
if (_tcpServerPage != null)
|
||||
_tcpServerPage.LogAction = _driverDebugUIPage.LogOut;
|
||||
_plc = new ThingsGateway.Foundation.Adapter.Modbus.ModbusTcpDtu(_tcpServerPage.GetTcpServer());
|
||||
_plc = new ThingsGateway.Foundation.Adapter.Modbus.ModbusDtu(_tcpServerPage.GetTcpServer());
|
||||
_driverDebugUIPage.Plc = _plc;
|
||||
//载入配置
|
||||
StateHasChanged();
|
@@ -19,7 +19,7 @@
|
||||
@using Masa.Blazor;
|
||||
@namespace ThingsGateway.Foundation.Demo
|
||||
|
||||
<SerialSessionPage @ref=_serialSessionPage></SerialSessionPage>
|
||||
<SerialPortClientPage @ref=_serialPortClientPage></SerialPortClientPage>
|
||||
|
||||
<MCard Flat Class="pa-2 my-1" Style="width:100%">
|
||||
<div class="mb-4">驱动配置</div>
|
||||
|
@@ -19,9 +19,9 @@ namespace ThingsGateway.Foundation.Demo;
|
||||
public partial class ModbusRtuDebugPage
|
||||
{
|
||||
/// <summary>
|
||||
/// SerialSessionPage
|
||||
/// SerialPortClientPage
|
||||
/// </summary>
|
||||
private SerialSessionPage _serialSessionPage;
|
||||
private SerialPortClientPage _serialPortClientPage;
|
||||
private readonly List<(string Code, string Language)> _sections = new();
|
||||
private DriverDebugUIPage _driverDebugUIPage;
|
||||
|
||||
@@ -41,15 +41,15 @@ public partial class ModbusRtuDebugPage
|
||||
//链路基础配置项
|
||||
var config = new TouchSocketConfig();
|
||||
config
|
||||
.SetSerialProperty(new SerialProperty() //串口链路才需要
|
||||
.SetSerialPortOption(new SerialPortOption() //串口链路才需要
|
||||
{
|
||||
PortName = "COM1"
|
||||
});
|
||||
var serialSession = new SerialSession();//链路对象
|
||||
serialSession.Setup(config);
|
||||
var serialPortClient = new SerialPortClient();//链路对象
|
||||
serialPortClient.Setup(config);
|
||||
|
||||
//创建协议对象,构造函数需要传入对应链路对象
|
||||
ModbusRtu plc = new(serialSession)//传入链路
|
||||
ModbusRtu plc = new(serialPortClient)//传入链路
|
||||
{
|
||||
//协议配置
|
||||
DataFormat = DataFormat.ABCD,
|
||||
@@ -72,9 +72,9 @@ public partial class ModbusRtuDebugPage
|
||||
""", "csharp"));
|
||||
|
||||
|
||||
if (_serialSessionPage != null)
|
||||
_serialSessionPage.LogAction = _driverDebugUIPage.LogOut;
|
||||
_plc = new ThingsGateway.Foundation.Adapter.Modbus.ModbusRtu(_serialSessionPage.GetSerialSession());
|
||||
if (_serialPortClientPage != null)
|
||||
_serialPortClientPage.LogAction = _driverDebugUIPage.LogOut;
|
||||
_plc = new ThingsGateway.Foundation.Adapter.Modbus.ModbusRtu(_serialPortClientPage.GetSerialPortClient());
|
||||
_driverDebugUIPage.Plc = _plc;
|
||||
//载入配置
|
||||
StateHasChanged();
|
||||
|
@@ -19,7 +19,7 @@ namespace ThingsGateway.Foundation.Demo;
|
||||
public partial class ModbusRtuOverTcpDebugPage
|
||||
{
|
||||
/// <summary>
|
||||
/// SerialSessionPage
|
||||
/// SerialPortClientPage
|
||||
/// </summary>
|
||||
private TcpClientPage _tcpClientPage;
|
||||
private DriverDebugUIPage _driverDebugUIPage;
|
||||
|
@@ -17,7 +17,7 @@ namespace ThingsGateway.Foundation.Demo;
|
||||
public partial class ModbusRtuOverUdpDebugPage
|
||||
{
|
||||
/// <summary>
|
||||
/// SerialSessionPage
|
||||
/// SerialPortClientPage
|
||||
/// </summary>
|
||||
private UdpSessionPage _udpSessionPage;
|
||||
private DriverDebugUIPage _driverDebugUIPage;
|
||||
|
@@ -19,7 +19,7 @@
|
||||
@using Masa.Blazor;
|
||||
@namespace ThingsGateway.Foundation.Demo
|
||||
|
||||
<SerialSessionPage @ref=_serialSessionPage></SerialSessionPage>
|
||||
<SerialPortClientPage @ref=_serialPortClientPage></SerialPortClientPage>
|
||||
|
||||
<MCard Flat Class="pa-2 my-1" Style="width:100%">
|
||||
<div class="mb-4">驱动配置</div>
|
||||
|
@@ -17,9 +17,9 @@ namespace ThingsGateway.Foundation.Demo;
|
||||
public partial class ModbusSerialServerDebugPage
|
||||
{
|
||||
/// <summary>
|
||||
/// SerialSessionPage
|
||||
/// SerialPortClientPage
|
||||
/// </summary>
|
||||
private SerialSessionPage _serialSessionPage;
|
||||
private SerialPortClientPage _serialPortClientPage;
|
||||
private DriverDebugUIPage _driverDebugUIPage;
|
||||
|
||||
private ThingsGateway.Foundation.Adapter.Modbus.ModbusSerialServer _plc;
|
||||
@@ -39,15 +39,15 @@ public partial class ModbusSerialServerDebugPage
|
||||
//链路基础配置项
|
||||
var config = new TouchSocketConfig();
|
||||
config
|
||||
.SetSerialProperty(new SerialProperty() //串口链路才需要
|
||||
.SetSerialPortOption(new SerialPortOption() //串口链路才需要
|
||||
{
|
||||
PortName = "COM1"
|
||||
});
|
||||
var serialSession = new SerialSession();//链路对象
|
||||
serialSession.Setup(config);
|
||||
var serialPortClient = new SerialPortClient();//链路对象
|
||||
serialPortClient.Setup(config);
|
||||
|
||||
//创建协议对象,构造函数需要传入对应链路对象
|
||||
ModbusSerialServer plc = new(serialSession)//传入链路
|
||||
ModbusSerialServer plc = new(serialPortClient)//传入链路
|
||||
{
|
||||
//协议配置
|
||||
DataFormat = DataFormat.ABCD,
|
||||
@@ -70,9 +70,9 @@ public partial class ModbusSerialServerDebugPage
|
||||
""", "csharp"));
|
||||
|
||||
|
||||
if (_serialSessionPage != null)
|
||||
_serialSessionPage.LogAction = _driverDebugUIPage.LogOut;
|
||||
_plc = new ThingsGateway.Foundation.Adapter.Modbus.ModbusSerialServer(_serialSessionPage.GetSerialSession());
|
||||
if (_serialPortClientPage != null)
|
||||
_serialPortClientPage.LogAction = _driverDebugUIPage.LogOut;
|
||||
_plc = new ThingsGateway.Foundation.Adapter.Modbus.ModbusSerialServer(_serialPortClientPage.GetSerialPortClient());
|
||||
_driverDebugUIPage.Plc = _plc;
|
||||
//载入配置
|
||||
StateHasChanged();
|
||||
|
@@ -21,7 +21,7 @@ public partial class ModbusTcpDebugPage
|
||||
private ThingsGateway.Foundation.Adapter.Modbus.ModbusTcp _plc;
|
||||
|
||||
/// <summary>
|
||||
/// SerialSessionPage
|
||||
/// SerialPortClientPage
|
||||
/// </summary>
|
||||
private TcpClientPage _tcpClientPage;
|
||||
/// <summary>
|
||||
|
@@ -17,7 +17,7 @@ namespace ThingsGateway.Foundation.Demo;
|
||||
public partial class ModbusUdpDebugPage
|
||||
{
|
||||
/// <summary>
|
||||
/// SerialSessionPage
|
||||
/// SerialPortClientPage
|
||||
/// </summary>
|
||||
private UdpSessionPage _udpSessionPage;
|
||||
private DriverDebugUIPage _driverDebugUIPage;
|
||||
|
@@ -23,7 +23,7 @@
|
||||
@using ThingsGateway.Foundation.Core;
|
||||
@using ThingsGateway.Foundation.Adapter.OPCDA.Da;
|
||||
@using ThingsGateway.Foundation.Extension;
|
||||
@using ThingsGateway.Foundation.Serial;
|
||||
@using ThingsGateway.Foundation.SerialPorts;
|
||||
@using Masa.Blazor
|
||||
|
||||
|
||||
|
@@ -20,8 +20,6 @@ using Microsoft.JSInterop;
|
||||
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
using ThingsGateway.Foundation.Adapter.OPCDA;
|
||||
using ThingsGateway.Foundation.Adapter.OPCDA.Da;
|
||||
|
||||
@@ -45,6 +43,7 @@ public partial class OPCDAClientDebugPage : IDisposable
|
||||
{
|
||||
_plc.SafeDispose();
|
||||
opcDAClientPage.SafeDispose();
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -105,7 +104,7 @@ public partial class OPCDAClientDebugPage : IDisposable
|
||||
await PopupService.EnqueueSnackbarAsync("无可用变量", AlertTypes.Warning);
|
||||
return;
|
||||
}
|
||||
await _serviceScope.ServiceProvider.GetService<CollectDeviceService>().AddAsync(data?.Item1);
|
||||
await _serviceScope.ServiceProvider.GetService<ICollectDeviceService>().AddAsync(data?.Item1);
|
||||
await _serviceScope.ServiceProvider.GetService<VariableService>().AddBatchAsync(data?.Item2);
|
||||
await PopupService.EnqueueSnackbarAsync("成功", AlertTypes.Success);
|
||||
}
|
||||
@@ -151,7 +150,7 @@ public partial class OPCDAClientDebugPage : IDisposable
|
||||
/// <returns></returns>
|
||||
public async Task DownDeviceExportAsync(CollectDevice data)
|
||||
{
|
||||
using var memoryStream = await _serviceScope.ServiceProvider.GetService<CollectDeviceService>().ExportFileAsync(new List<CollectDevice>() { data });
|
||||
using var memoryStream = await _serviceScope.ServiceProvider.GetService<ICollectDeviceService>().ExportFileAsync(new List<CollectDevice>() { data });
|
||||
using var streamRef = new DotNetStreamReference(stream: memoryStream);
|
||||
JSObjectReference ??= await JSRuntime.LoadModuleAsync("js/downloadFileFromStream");
|
||||
await JSObjectReference.InvokeVoidAsync("downloadFileFromStream", $"设备导出{DateTimeExtensions.CurrentDateTime.ToFileDateTimeFormat()}.xlsx", streamRef);
|
||||
|
@@ -25,7 +25,7 @@
|
||||
@using ThingsGateway.Foundation.Core;
|
||||
@using ThingsGateway.Foundation.Adapter.OPCUA;
|
||||
@using ThingsGateway.Foundation.Extension;
|
||||
@using ThingsGateway.Foundation.Serial;
|
||||
@using ThingsGateway.Foundation.SerialPorts;
|
||||
@using Masa.Blazor
|
||||
|
||||
|
||||
|
@@ -96,7 +96,7 @@ public partial class OPCUAClientDebugPage
|
||||
await PopupService.EnqueueSnackbarAsync("无可用变量", AlertTypes.Warning);
|
||||
return;
|
||||
}
|
||||
await _serviceScope.ServiceProvider.GetService<CollectDeviceService>().AddAsync(data.Item1);
|
||||
await _serviceScope.ServiceProvider.GetService<ICollectDeviceService>().AddAsync(data.Item1);
|
||||
await _serviceScope.ServiceProvider.GetService<VariableService>().AddBatchAsync(data.Item2);
|
||||
await PopupService.EnqueueSnackbarAsync("成功", AlertTypes.Success);
|
||||
}
|
||||
@@ -141,7 +141,7 @@ public partial class OPCUAClientDebugPage
|
||||
/// <returns></returns>
|
||||
public async Task DownDeviceExportAsync(CollectDevice data)
|
||||
{
|
||||
using var memoryStream = await _serviceScope.ServiceProvider.GetService<CollectDeviceService>().ExportFileAsync(new List<CollectDevice>() { data });
|
||||
using var memoryStream = await _serviceScope.ServiceProvider.GetService<ICollectDeviceService>().ExportFileAsync(new List<CollectDevice>() { data });
|
||||
using var streamRef = new DotNetStreamReference(stream: memoryStream);
|
||||
JSObjectReference ??= await JSRuntime.LoadModuleAsync("js/downloadFileFromStream");
|
||||
await JSObjectReference.InvokeVoidAsync("downloadFileFromStream", $"设备导出{DateTimeExtensions.CurrentDateTime.ToFileDateTimeFormat()}.xlsx", streamRef);
|
||||
|
@@ -20,7 +20,7 @@
|
||||
@using ThingsGateway.Foundation.Adapter.Siemens;
|
||||
@using ThingsGateway.Foundation.Core;
|
||||
@using ThingsGateway.Foundation.Extension;
|
||||
@using ThingsGateway.Foundation.Serial;
|
||||
@using ThingsGateway.Foundation.SerialPorts;
|
||||
|
||||
@using Masa.Blazor
|
||||
|
||||
|
@@ -21,7 +21,7 @@ public partial class SiemensDebugPage
|
||||
private ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC _plc;
|
||||
|
||||
/// <summary>
|
||||
/// SerialSessionPage
|
||||
/// SerialPortClientPage
|
||||
/// </summary>
|
||||
private TcpClientPage _tcpClientPage;
|
||||
/// <summary>
|
||||
|
@@ -10,8 +10,6 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ThingsGateway.Foundation.Demo;
|
||||
|
||||
public partial class MainLayout
|
||||
@@ -105,16 +103,16 @@ public partial class MainLayout
|
||||
"Title": "OPCUAClient"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Title": "Mqtt",
|
||||
"Children": [
|
||||
{
|
||||
"Href": "/MqttClient",
|
||||
"Title": "MqttClient"
|
||||
}
|
||||
]
|
||||
}
|
||||
//{
|
||||
// "Title": "Mqtt",
|
||||
// "Children": [
|
||||
// {
|
||||
// "Href": "/MqttClient",
|
||||
// "Title": "MqttClient"
|
||||
// }
|
||||
// ]
|
||||
//}
|
||||
]
|
||||
|
||||
|
||||
|
@@ -25,5 +25,5 @@
|
||||
@using System.Net.Http.Json
|
||||
@using System.IO;
|
||||
@using System.Text.Json;
|
||||
@using ThingsGateway.Foundation.Serial;
|
||||
@using ThingsGateway.Foundation.SerialPorts;
|
||||
@using ThingsGateway.Foundation.Sockets;
|
@@ -14,9 +14,9 @@ using Microsoft.AspNetCore.Components.WebView.WindowsForms;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using ThingsGateway.Components;
|
||||
using ThingsGateway.Core;
|
||||
|
||||
namespace ThingsGateway.Foundation.Demo.Winform
|
||||
{
|
||||
@@ -26,14 +26,12 @@ namespace ThingsGateway.Foundation.Demo.Winform
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
IServiceCollection services = null;
|
||||
IServiceCollection services = new ServiceCollection();
|
||||
|
||||
Serve.RunNative(a =>
|
||||
{
|
||||
services = a;
|
||||
services.AddWindowsFormsBlazorWebView();
|
||||
services.ThingsGatewayComponentsConfigureServices();
|
||||
});
|
||||
|
||||
services.AddWindowsFormsBlazorWebView();
|
||||
services.ThingsGatewayComponentsConfigureServices();
|
||||
services.ThingsGatewayCoreConfigureServices();
|
||||
|
||||
blazorWebView1.HostPage = "wwwroot/index.html";
|
||||
blazorWebView1.Services = services.BuildServiceProvider();
|
||||
|
@@ -7,6 +7,7 @@
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="favicon.ico" />
|
||||
</ItemGroup>
|
||||
|
@@ -1,16 +1,14 @@
|
||||
<Project>
|
||||
<Import Project="$(SolutionDir)\Directory.Build.props" />
|
||||
<!--如果编译net45报错无支持,用一下方法添加net45包-->
|
||||
<!--VS顶部菜单栏 -> 视图 -> 其他 -> 程序包控制台
|
||||
Install-Package Microsoft.NETFramework.ReferenceAssemblies.net45
|
||||
-->
|
||||
<PropertyGroup>
|
||||
<Version>4.0.0.3</Version>
|
||||
<GenerateDocumentationFile>True</GenerateDocumentationFile>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<TargetFrameworks>net45;netstandard2.0;net6.0;net8.0;</TargetFrameworks>
|
||||
<Description>
|
||||
ThingsGateway.Foundation是工业设备通讯类库,归属于ThingsGateway边缘网关项目,说明文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
</Description>
|
||||
<Authors>Diego</Authors>
|
||||
<Product>ThingsGateway</Product>
|
||||
<Copyright>© 2023-present Diego</Copyright>
|
||||
<RepositoryUrl>https://gitee.com/diego2098/ThingsGateway</RepositoryUrl>
|
||||
<PublishRepositoryUrl>true</PublishRepositoryUrl>
|
||||
<EmbedUntrackedSource>true</EmbedUntrackedSource>
|
||||
<EmbedAllSources>true</EmbedAllSources>
|
||||
@@ -22,17 +20,11 @@
|
||||
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
|
||||
<PackageProjectUrl>https://diego2098.gitee.io/thingsgateway-docs/</PackageProjectUrl>
|
||||
<PackageTags>ThingsGateway;Diego;dotNET China;Blazor;设备采集;边缘网关</PackageTags>
|
||||
<SignAssembly>True</SignAssembly>
|
||||
<DelaySign>False</DelaySign>
|
||||
<SatelliteResourceLanguages>zh-Hans</SatelliteResourceLanguages>
|
||||
<PackageOutputPath>..\..\nupkgs</PackageOutputPath>
|
||||
<AssemblyOriginatorKeyFile>..\..\..\snks/ThingsGateway.snk</AssemblyOriginatorKeyFile>
|
||||
<GenerateDocumentationFile>True</GenerateDocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="..\..\..\README.md" Pack="true" PackagePath="\" />
|
||||
</ItemGroup>
|
||||
|
@@ -16,13 +16,13 @@ namespace ThingsGateway.Foundation.Adapter.DLT645;
|
||||
/// <summary>
|
||||
/// DLT645_2007
|
||||
/// </summary>
|
||||
public class DLT645_2007 : ReadWriteDevicesSerialSessionBase, IDLT645_2007
|
||||
public class DLT645_2007 : ReadWriteDevicesSerialPortClientBase, IDLT645_2007
|
||||
{
|
||||
/// <summary>
|
||||
/// DLT645_2007
|
||||
/// </summary>
|
||||
/// <param name="serialSession"></param>
|
||||
public DLT645_2007(SerialSession serialSession) : base(serialSession)
|
||||
/// <param name="serialPortClient"></param>
|
||||
public DLT645_2007(SerialPortClient serialPortClient) : base(serialPortClient)
|
||||
{
|
||||
ThingsGatewayBitConverter = new DLT645_2007BitConverter(EndianType.Big);
|
||||
RegisterByteLength = 2;
|
||||
@@ -62,7 +62,7 @@ public class DLT645_2007 : ReadWriteDevicesSerialSessionBase, IDLT645_2007
|
||||
{
|
||||
EnableFEHead = EnableFEHead
|
||||
};
|
||||
SerialSession.SetDataHandlingAdapter(dataHandleAdapter);
|
||||
SerialPortClient.SetDataHandlingAdapter(dataHandleAdapter);
|
||||
}
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@ public class DLT645_2007 : ReadWriteDevicesSerialSessionBase, IDLT645_2007
|
||||
public override OperResult Write(string address, bool[] value, CancellationToken cancellationToken = default) => Write(address, value.ToString(), cancellationToken);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, byte[] value, CancellationToken cancellationToken = default) => throw new NotImplementedException();
|
||||
public override Task<OperResult> WriteAsync(string address, byte[] value, CancellationToken cancellationToken = default) => Task.FromResult(new OperResult());
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, uint value, CancellationToken cancellationToken = default) => WriteAsync(address, value.ToString(), cancellationToken);
|
||||
/// <inheritdoc/>
|
||||
@@ -125,7 +125,7 @@ public class DLT645_2007 : ReadWriteDevicesSerialSessionBase, IDLT645_2007
|
||||
public override Task<OperResult> WriteAsync(string address, int value, CancellationToken cancellationToken = default) => WriteAsync(address, value.ToString(), cancellationToken);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, bool[] value, CancellationToken cancellationToken = default) => throw new NotImplementedException();
|
||||
public override Task<OperResult> WriteAsync(string address, bool[] value, CancellationToken cancellationToken = default) => Task.FromResult(new OperResult());
|
||||
|
||||
|
||||
#region 其他方法
|
||||
|
@@ -106,7 +106,7 @@ public class DLT645_2007OverTcp : ReadWriteDevicesTcpClientBase, IDLT645_2007
|
||||
public override OperResult Write(string address, bool[] value, CancellationToken cancellationToken = default) => Write(address, value.ToString(), cancellationToken);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, byte[] value, CancellationToken cancellationToken = default) => throw new NotImplementedException();
|
||||
public override Task<OperResult> WriteAsync(string address, byte[] value, CancellationToken cancellationToken = default) => Task.FromResult(new OperResult());
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, uint value, CancellationToken cancellationToken = default) => WriteAsync(address, value.ToString(), cancellationToken);
|
||||
/// <inheritdoc/>
|
||||
@@ -125,7 +125,7 @@ public class DLT645_2007OverTcp : ReadWriteDevicesTcpClientBase, IDLT645_2007
|
||||
public override Task<OperResult> WriteAsync(string address, int value, CancellationToken cancellationToken = default) => WriteAsync(address, value.ToString(), cancellationToken);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, bool[] value, CancellationToken cancellationToken = default) => throw new NotImplementedException();
|
||||
public override Task<OperResult> WriteAsync(string address, bool[] value, CancellationToken cancellationToken = default) => Task.FromResult(new OperResult());
|
||||
|
||||
|
||||
#region 其他方法
|
||||
|
@@ -17,5 +17,5 @@ global using System.Threading;
|
||||
global using System.Threading.Tasks;
|
||||
|
||||
global using ThingsGateway.Foundation.Core;
|
||||
global using ThingsGateway.Foundation.Serial;
|
||||
global using ThingsGateway.Foundation.SerialPorts;
|
||||
global using ThingsGateway.Foundation.Sockets;
|
||||
|
@@ -17,5 +17,5 @@ global using System.Threading;
|
||||
global using System.Threading.Tasks;
|
||||
|
||||
global using ThingsGateway.Foundation.Core;
|
||||
global using ThingsGateway.Foundation.Serial;
|
||||
global using ThingsGateway.Foundation.SerialPorts;
|
||||
global using ThingsGateway.Foundation.Sockets;
|
||||
|
@@ -14,14 +14,14 @@ using System.ComponentModel;
|
||||
|
||||
namespace ThingsGateway.Foundation.Adapter.Modbus;
|
||||
/// <inheritdoc/>
|
||||
public class ModbusTcpDtu : ReadWriteDevicesTcpServerBase
|
||||
public class ModbusDtu : ReadWriteDevicesTcpServerBase
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public ModbusTcpDtu(TcpService tcpService) : base(tcpService)
|
||||
public ModbusDtu(TcpService tcpService) : base(tcpService)
|
||||
{
|
||||
ThingsGatewayBitConverter = new ThingsGatewayBitConverter(EndianType.Big);
|
||||
RegisterByteLength = 2;
|
||||
ModbusTcpDtuPlugin modbusTcpSalvePlugin = new ModbusTcpDtuPlugin();
|
||||
ModbusDtuPlugin modbusTcpSalvePlugin = new ModbusDtuPlugin();
|
||||
tcpService.Config.ConfigurePlugins(a =>
|
||||
{
|
||||
a.Add(modbusTcpSalvePlugin);
|
||||
@@ -35,6 +35,18 @@ public class ModbusTcpDtu : ReadWriteDevicesTcpServerBase
|
||||
[Description("检测事务标识符")]
|
||||
public bool IsCheckMessageId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否Rtu格式
|
||||
/// </summary>
|
||||
[Description("是否Rtu格式")]
|
||||
public bool IsRtu { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Crc校验
|
||||
/// </summary>
|
||||
[Description("Crc校验")]
|
||||
public bool Crc16CheckEnable { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// 站号
|
||||
/// </summary>
|
||||
@@ -92,23 +104,49 @@ public class ModbusTcpDtu : ReadWriteDevicesTcpServerBase
|
||||
{
|
||||
if (socketClient != default)
|
||||
{
|
||||
ModbusTcpDataHandleAdapter dataHandleAdapter = new()
|
||||
{
|
||||
IsCheckMessageId = IsCheckMessageId,
|
||||
CacheTimeout = TimeSpan.FromMilliseconds(CacheTimeout)
|
||||
};
|
||||
socketClient.SetDataHandlingAdapter(dataHandleAdapter);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var item in TcpService.GetClients())
|
||||
if (!IsRtu)
|
||||
{
|
||||
ModbusTcpDataHandleAdapter dataHandleAdapter = new()
|
||||
{
|
||||
IsCheckMessageId = IsCheckMessageId,
|
||||
CacheTimeout = TimeSpan.FromMilliseconds(CacheTimeout)
|
||||
};
|
||||
item.SetDataHandlingAdapter(dataHandleAdapter);
|
||||
socketClient.SetDataHandlingAdapter(dataHandleAdapter);
|
||||
}
|
||||
else
|
||||
{
|
||||
ModbusRtuDataHandleAdapter dataHandleAdapter = new()
|
||||
{
|
||||
Crc16CheckEnable = Crc16CheckEnable,
|
||||
CacheTimeout = TimeSpan.FromMilliseconds(CacheTimeout)
|
||||
};
|
||||
socketClient.SetDataHandlingAdapter(dataHandleAdapter);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//只适配第一个
|
||||
var item = TcpService.GetClients().FirstOrDefault();
|
||||
if (item != null)
|
||||
{
|
||||
if (!IsRtu)
|
||||
{
|
||||
ModbusTcpDataHandleAdapter dataHandleAdapter = new()
|
||||
{
|
||||
IsCheckMessageId = IsCheckMessageId,
|
||||
CacheTimeout = TimeSpan.FromMilliseconds(CacheTimeout)
|
||||
};
|
||||
item.SetDataHandlingAdapter(dataHandleAdapter);
|
||||
}
|
||||
else
|
||||
{
|
||||
ModbusRtuDataHandleAdapter dataHandleAdapter = new()
|
||||
{
|
||||
Crc16CheckEnable = Crc16CheckEnable,
|
||||
CacheTimeout = TimeSpan.FromMilliseconds(CacheTimeout)
|
||||
};
|
||||
item.SetDataHandlingAdapter(dataHandleAdapter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -187,7 +225,7 @@ public class ModbusTcpDtu : ReadWriteDevicesTcpServerBase
|
||||
if (TcpService.TryGetSocketClient($"ID={id}", out var client))
|
||||
{
|
||||
SetDataAdapter(client);
|
||||
return SendThenReturn<ModbusTcpMessage>(command, cancellationToken, client);
|
||||
return SendThenReturn<MessageBase>(command, cancellationToken, client);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -200,7 +238,7 @@ public class ModbusTcpDtu : ReadWriteDevicesTcpServerBase
|
||||
if (TcpService.TryGetSocketClient($"ID={id}", out var client))
|
||||
{
|
||||
SetDataAdapter(client);
|
||||
return await SendThenReturnAsync<ModbusTcpMessage>(command, cancellationToken, client);
|
||||
return await SendThenReturnAsync<MessageBase>(command, cancellationToken, client);
|
||||
}
|
||||
else if (TcpService.SocketClients.Count == 1)
|
||||
{
|
||||
@@ -208,13 +246,13 @@ public class ModbusTcpDtu : ReadWriteDevicesTcpServerBase
|
||||
if (client1 != null)
|
||||
{
|
||||
SetDataAdapter(client1);
|
||||
return await SendThenReturnAsync<ModbusTcpMessage>(command, cancellationToken, client1);
|
||||
return await SendThenReturnAsync<MessageBase>(command, cancellationToken, client1);
|
||||
}
|
||||
}
|
||||
return new OperResult<byte[]>("客户端未连接");
|
||||
}
|
||||
|
||||
internal class ModbusTcpDtuPlugin : PluginBase, ITcpReceivingPlugin
|
||||
internal class ModbusDtuPlugin : PluginBase, ITcpReceivingPlugin
|
||||
{
|
||||
public async Task OnTcpReceiving(ITcpClientBase client, ByteBlockEventArgs e)
|
||||
{
|
@@ -134,21 +134,19 @@ internal class ModbusHelper
|
||||
|
||||
if (response[1] >= 0x80)//错误码
|
||||
return new OperResult<byte[], FilterResult>(GetDescriptionByErrorCode(response[2])) { Content2 = FilterResult.Success };
|
||||
if (response[1] <= 0x05)
|
||||
if (response[1] <= 0x04)
|
||||
{
|
||||
if ((response.Length < response[2] + 5))
|
||||
return new OperResult<byte[], FilterResult>("数据长度不足" + response.ToHexString()) { Content2 = FilterResult.Cache };
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((response.Length < 8))
|
||||
return new OperResult<byte[], FilterResult>("数据长度不足" + response.ToHexString()) { Content2 = FilterResult.Cache };
|
||||
|
||||
}
|
||||
|
||||
|
||||
var data = response.SelectMiddle(0, response[2] != 0 ? response[2] + 5 : 8);
|
||||
var data = response.SelectMiddle(0, response[1] <= 0x04 ? response[2] != 0 ? response[2] + 5 : 8 : 8);
|
||||
if (crcCheck && !CRC16Utils.CheckCRC16(data))
|
||||
return new OperResult<byte[], FilterResult>("Crc校验失败" + DataTransUtil.ByteToHexString(data, ' ')) { Content2 = FilterResult.Success };
|
||||
return GetModbusData(send, data.RemoveLast(2));
|
||||
|
@@ -16,13 +16,13 @@ namespace ThingsGateway.Foundation.Adapter.Modbus;
|
||||
/// <summary>
|
||||
/// ModbusRtu
|
||||
/// </summary>
|
||||
public class ModbusRtu : ReadWriteDevicesSerialSessionBase
|
||||
public class ModbusRtu : ReadWriteDevicesSerialPortClientBase
|
||||
{
|
||||
/// <summary>
|
||||
/// ModbusRtu
|
||||
/// </summary>
|
||||
/// <param name="serialSession"></param>
|
||||
public ModbusRtu(SerialSession serialSession) : base(serialSession)
|
||||
/// <param name="serialPortClient"></param>
|
||||
public ModbusRtu(SerialPortClient serialPortClient) : base(serialPortClient)
|
||||
{
|
||||
ThingsGatewayBitConverter = new ThingsGatewayBitConverter(EndianType.Big);
|
||||
RegisterByteLength = 2;
|
||||
@@ -93,7 +93,7 @@ public class ModbusRtu : ReadWriteDevicesSerialSessionBase
|
||||
Crc16CheckEnable = Crc16CheckEnable,
|
||||
CacheTimeout = TimeSpan.FromMilliseconds(CacheTimeout)
|
||||
};
|
||||
SerialSession.SetDataHandlingAdapter(dataHandleAdapter);
|
||||
SerialPortClient.SetDataHandlingAdapter(dataHandleAdapter);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
@@ -19,7 +19,7 @@ namespace ThingsGateway.Foundation.Adapter.Modbus;
|
||||
/// </summary>
|
||||
internal class ModbusTcpDataHandleAdapter : ReadWriteDevicesSingleStreamDataHandleAdapter<ModbusTcpMessage>
|
||||
{
|
||||
private readonly IncrementCount easyIncrementCount = new(ushort.MaxValue);
|
||||
private readonly IncrementCount _incrementCount = new(ushort.MaxValue);
|
||||
|
||||
/// <summary>
|
||||
/// 检测事务标识符
|
||||
@@ -39,7 +39,7 @@ internal class ModbusTcpDataHandleAdapter : ReadWriteDevicesSingleStreamDataHand
|
||||
/// <inheritdoc/>
|
||||
public override byte[] PackCommand(byte[] command)
|
||||
{
|
||||
return ModbusHelper.AddModbusTcpHead(command, (ushort)easyIncrementCount.GetCurrentValue());
|
||||
return ModbusHelper.AddModbusTcpHead(command, (ushort)_incrementCount.GetCurrentValue());
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
@@ -18,7 +18,7 @@ namespace ThingsGateway.Foundation.Adapter.Modbus;
|
||||
/// </summary>
|
||||
internal class ModbusUdpDataHandleAdapter : ReadWriteDevicesUdpDataHandleAdapter<ModbusTcpMessage>
|
||||
{
|
||||
private readonly IncrementCount easyIncrementCount = new(ushort.MaxValue);
|
||||
private readonly IncrementCount _incrementCount = new(ushort.MaxValue);
|
||||
|
||||
/// <summary>
|
||||
/// 检测事务标识符
|
||||
@@ -38,7 +38,7 @@ internal class ModbusUdpDataHandleAdapter : ReadWriteDevicesUdpDataHandleAdapter
|
||||
/// <inheritdoc/>
|
||||
public override byte[] PackCommand(byte[] command)
|
||||
{
|
||||
return ModbusHelper.AddModbusTcpHead(command, (ushort)easyIncrementCount.GetCurrentValue());
|
||||
return ModbusHelper.AddModbusTcpHead(command, (ushort)_incrementCount.GetCurrentValue());
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
@@ -16,10 +16,10 @@ namespace ThingsGateway.Foundation.Adapter.Modbus;
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
public class ModbusSerialServer : ReadWriteDevicesSerialSessionBase, IModbusServer
|
||||
public class ModbusSerialServer : ReadWriteDevicesSerialPortClientBase, IModbusServer
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public ModbusSerialServer(SerialSession serialSession) : base(serialSession)
|
||||
public ModbusSerialServer(SerialPortClient serialPortClient) : base(serialPortClient)
|
||||
{
|
||||
ThingsGatewayBitConverter = new ThingsGatewayBitConverter(EndianType.Big);
|
||||
RegisterByteLength = 2;
|
||||
@@ -130,7 +130,7 @@ public class ModbusSerialServer : ReadWriteDevicesSerialSessionBase, IModbusServ
|
||||
{
|
||||
ModbusSerialServerDataHandleAdapter dataHandleAdapter = new();
|
||||
dataHandleAdapter.CacheTimeout = TimeSpan.FromMilliseconds(CacheTimeout);
|
||||
SerialSession.SetDataHandlingAdapter(dataHandleAdapter);
|
||||
SerialPortClient.SetDataHandlingAdapter(dataHandleAdapter);
|
||||
}
|
||||
|
||||
|
||||
@@ -165,7 +165,7 @@ public class ModbusSerialServer : ReadWriteDevicesSerialSessionBase, IModbusServ
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override async Task Received(SerialSession client, ReceivedDataEventArgs e)
|
||||
protected override async Task Received(SerialPortClient client, ReceivedDataEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@@ -253,11 +253,11 @@
|
||||
ModbusRtu
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtu.#ctor(ThingsGateway.Foundation.Serial.SerialSession)">
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtu.#ctor(ThingsGateway.Foundation.SerialPorts.SerialPortClient)">
|
||||
<summary>
|
||||
ModbusRtu
|
||||
</summary>
|
||||
<param name="serialSession"></param>
|
||||
<param name="serialPortClient"></param>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtu.Crc16CheckEnable">
|
||||
<summary>
|
||||
|
@@ -143,7 +143,7 @@ public interface IReadWrite : IDisposable
|
||||
/// <param name="cancellationToken">取消令箭</param>
|
||||
/// <param name="senderClient">传入改参数时,将新建等待线程</param>
|
||||
/// <returns></returns>
|
||||
T SendThenReturn<T>(byte[] command, CancellationToken cancellationToken, ISenderClient senderClient = default) where T : OperResult<byte[]>, new();
|
||||
T SendThenReturn<T>(byte[] command, CancellationToken cancellationToken, ISenderClient senderClient = default) where T : OperResult<byte[]>;
|
||||
|
||||
/// <summary>
|
||||
/// 异步发送并返回结果
|
||||
@@ -153,7 +153,7 @@ public interface IReadWrite : IDisposable
|
||||
/// <param name="cancellationToken">取消令箭</param>
|
||||
/// <param name="senderClient">传入改参数时,将新建等待线程</param>
|
||||
/// <returns></returns>
|
||||
Task<T> SendThenReturnAsync<T>(byte[] command, CancellationToken cancellationToken, ISenderClient senderClient = default) where T : OperResult<byte[]>, new();
|
||||
Task<T> SendThenReturnAsync<T>(byte[] command, CancellationToken cancellationToken, ISenderClient senderClient = default) where T : OperResult<byte[]>;
|
||||
|
||||
/// <summary>
|
||||
/// 发送获取数据
|
||||
|
@@ -148,7 +148,7 @@ public abstract class ReadWriteDevicesBase : IReadWrite
|
||||
public abstract void Send(byte[] command, string id = default);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual T SendThenReturn<T>(byte[] command, CancellationToken cancellationToken, ISenderClient senderClient = default) where T : OperResult<byte[]>, new()
|
||||
public virtual T SendThenReturn<T>(byte[] command, CancellationToken cancellationToken, ISenderClient senderClient = default) where T : OperResult<byte[]>
|
||||
{
|
||||
var item = command;
|
||||
if (FrameTime != 0)
|
||||
@@ -157,7 +157,7 @@ public abstract class ReadWriteDevicesBase : IReadWrite
|
||||
return (T)result.RequestInfo;
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public virtual async Task<T> SendThenReturnAsync<T>(byte[] command, CancellationToken cancellationToken, ISenderClient senderClient = default) where T : OperResult<byte[]>, new()
|
||||
public virtual async Task<T> SendThenReturnAsync<T>(byte[] command, CancellationToken cancellationToken, ISenderClient senderClient = default) where T : OperResult<byte[]>
|
||||
{
|
||||
var item = command;
|
||||
await Task.Delay(FrameTime, cancellationToken);
|
||||
|
@@ -10,33 +10,34 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
|
||||
namespace ThingsGateway.Foundation.Core;
|
||||
|
||||
/// <summary>
|
||||
/// 串口读写设备
|
||||
/// </summary>
|
||||
public abstract class ReadWriteDevicesSerialSessionBase : ReadWriteDevicesBase
|
||||
public abstract class ReadWriteDevicesSerialPortClientBase : ReadWriteDevicesBase
|
||||
{
|
||||
/// <summary>
|
||||
/// <inheritdoc cref="ReadWriteDevicesSerialSessionBase"/>
|
||||
/// <inheritdoc cref="ReadWriteDevicesSerialPortClientBase"/>
|
||||
/// </summary>
|
||||
/// <param name="serialSession"></param>
|
||||
public ReadWriteDevicesSerialSessionBase(SerialSession serialSession)
|
||||
/// <param name="serialPortClient"></param>
|
||||
public ReadWriteDevicesSerialPortClientBase(SerialPortClient serialPortClient)
|
||||
{
|
||||
SerialSession = serialSession;
|
||||
WaitingClientEx = SerialSession.CreateWaitingClient(new() { });
|
||||
SerialSession.Received -= Received;
|
||||
SerialSession.Connecting -= Connecting;
|
||||
SerialSession.Connected -= Connected;
|
||||
SerialSession.Disconnecting -= Disconnecting;
|
||||
SerialSession.Disconnected -= Disconnected;
|
||||
SerialSession.Connecting += Connecting;
|
||||
SerialSession.Connected += Connected;
|
||||
SerialSession.Disconnecting += Disconnecting;
|
||||
SerialSession.Disconnected += Disconnected;
|
||||
SerialSession.Received += Received;
|
||||
SerialPortClient = serialPortClient;
|
||||
WaitingClientEx = SerialPortClient.CreateWaitingClient(new() { });
|
||||
SerialPortClient.Received -= Received;
|
||||
SerialPortClient.Connecting -= Connecting;
|
||||
SerialPortClient.Connected -= Connected;
|
||||
SerialPortClient.Disconnecting -= Disconnecting;
|
||||
SerialPortClient.Disconnected -= Disconnected;
|
||||
SerialPortClient.Connecting += Connecting;
|
||||
SerialPortClient.Connected += Connected;
|
||||
SerialPortClient.Disconnecting += Disconnecting;
|
||||
SerialPortClient.Disconnected += Disconnected;
|
||||
SerialPortClient.Received += Received;
|
||||
|
||||
Logger = SerialSession.Logger;
|
||||
Logger = SerialPortClient.Logger;
|
||||
}
|
||||
/// <summary>
|
||||
/// 接收解析
|
||||
@@ -44,88 +45,88 @@ public abstract class ReadWriteDevicesSerialSessionBase : ReadWriteDevicesBase
|
||||
/// <param name="client"></param>
|
||||
/// <param name="e"></param>
|
||||
/// <returns></returns>
|
||||
protected virtual Task Received(SerialSession client, ReceivedDataEventArgs e)
|
||||
protected virtual Task Received(SerialPortClient client, ReceivedDataEventArgs e)
|
||||
{
|
||||
return EasyTask.CompletedTask;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override ChannelEnum ChannelEnum => ChannelEnum.SerialSession;
|
||||
public override ChannelEnum ChannelEnum => ChannelEnum.SerialPortClient;
|
||||
|
||||
/// <summary>
|
||||
/// 串口管理对象
|
||||
/// </summary>
|
||||
public SerialSession SerialSession { get; }
|
||||
public SerialPortClient SerialPortClient { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 默认WaitingClientEx
|
||||
/// </summary>
|
||||
public virtual IWaitingClient<SerialSession> WaitingClientEx { get; }
|
||||
public virtual IWaitingClient<SerialPortClient> WaitingClientEx { get; }
|
||||
/// <inheritdoc/>
|
||||
public override bool IsConnected()
|
||||
{
|
||||
return SerialSession?.CanSend == true;
|
||||
return SerialPortClient?.CanSend == true;
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public override void Connect(CancellationToken cancellationToken)
|
||||
{
|
||||
SerialSession.Connect();
|
||||
SerialPortClient.Connect();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task ConnectAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
return SerialSession.ConnectAsync();
|
||||
return SerialPortClient.ConnectAsync();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Disconnect()
|
||||
{
|
||||
if (CascadeDisposal && IsConnected())
|
||||
SerialSession.Close();
|
||||
SerialPortClient.Close();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Dispose()
|
||||
{
|
||||
Disconnect();
|
||||
SerialSession.Received -= Received;
|
||||
SerialSession.Connecting -= Connecting;
|
||||
SerialSession.Connected -= Connected;
|
||||
SerialSession.Disconnecting -= Disconnecting;
|
||||
SerialSession.Disconnected -= Disconnected;
|
||||
if (CascadeDisposal && !SerialSession.DisposedValue)
|
||||
SerialSession.SafeDispose();
|
||||
SerialPortClient.Received -= Received;
|
||||
SerialPortClient.Connecting -= Connecting;
|
||||
SerialPortClient.Connected -= Connected;
|
||||
SerialPortClient.Disconnecting -= Disconnecting;
|
||||
SerialPortClient.Disconnected -= Disconnected;
|
||||
if (CascadeDisposal && !SerialPortClient.DisposedValue)
|
||||
SerialPortClient.SafeDispose();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
return SerialSession.SerialProperty.ToString();
|
||||
return SerialPortClient.ToString();
|
||||
}
|
||||
|
||||
private async Task Connected(ISerialSession client, ConnectedEventArgs e)
|
||||
private async Task Connected(ISerialPortClient client, ConnectedEventArgs e)
|
||||
{
|
||||
Logger?.Debug(client.SerialProperty.ToString() + "连接成功");
|
||||
Logger?.Debug(client.ToString() + "连接成功");
|
||||
SetDataAdapter();
|
||||
await EasyTask.CompletedTask;
|
||||
}
|
||||
|
||||
private async Task Connecting(ISerialSession client, SerialConnectingEventArgs e)
|
||||
private async Task Connecting(ISerialPortClient client, SerialConnectingEventArgs e)
|
||||
{
|
||||
Logger?.Debug(client.SerialProperty.ToString() + "正在连接");
|
||||
Logger?.Debug(client.ToString() + "正在连接");
|
||||
await EasyTask.CompletedTask;
|
||||
}
|
||||
|
||||
private async Task Disconnected(ISerialSessionBase client, DisconnectEventArgs e)
|
||||
private async Task Disconnected(ISerialPortClient client, DisconnectEventArgs e)
|
||||
{
|
||||
Logger?.Debug(client.SerialProperty.ToString() + "断开连接-" + e.Message);
|
||||
Logger?.Debug(client.ToString() + "断开连接-" + e.Message);
|
||||
await EasyTask.CompletedTask;
|
||||
}
|
||||
|
||||
private async Task Disconnecting(ISerialSessionBase client, DisconnectEventArgs e)
|
||||
private async Task Disconnecting(ISerialPortClient client, DisconnectEventArgs e)
|
||||
{
|
||||
Logger?.Debug(client.SerialProperty.ToString() + "正在主动断开连接-" + e.Message);
|
||||
Logger?.Debug(client.ToString() + "正在主动断开连接-" + e.Message);
|
||||
await EasyTask.CompletedTask;
|
||||
}
|
||||
|
||||
@@ -150,6 +151,6 @@ public abstract class ReadWriteDevicesSerialSessionBase : ReadWriteDevicesBase
|
||||
/// <inheritdoc/>
|
||||
public override void Send(byte[] command, string id = default)
|
||||
{
|
||||
SerialSession.Send(command);
|
||||
SerialPortClient.Send(command);
|
||||
}
|
||||
}
|
@@ -53,8 +53,7 @@ public abstract class ReadWriteDevicesTcpServerBase : ReadWriteDevicesBase
|
||||
/// <inheritdoc/>
|
||||
public override Task ConnectAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
Connect(cancellationToken);
|
||||
return EasyTask.CompletedTask;
|
||||
return TcpService.StartAsync();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
@@ -48,7 +48,7 @@ public abstract class ReadWriteDevicesUdpSessionBase : ReadWriteDevicesBase
|
||||
/// <inheritdoc/>
|
||||
public override Task ConnectAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.FromResult(UdpSession.Start());
|
||||
return UdpSession.StartAsync();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -69,7 +69,7 @@ public abstract class ReadWriteDevicesUdpSessionBase : ReadWriteDevicesBase
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
return UdpSession.RemoteIPHost.ToString();
|
||||
return UdpSession.RemoteIPHost?.ToString();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
@@ -29,6 +29,7 @@ public abstract class ReadWriteDevicesSingleStreamDataHandleAdapter<TRequest> :
|
||||
public ReadWriteDevicesSingleStreamDataHandleAdapter()
|
||||
{
|
||||
Request = GetInstance();
|
||||
CacheTimeoutEnable = true;
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public override bool CanSendRequestInfo => false;
|
||||
|
@@ -53,7 +53,7 @@ public abstract class ReadWriteDevicesUdpDataHandleAdapter<TRequest> : UdpDataHa
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
return (Owner as UdpSession)?.RemoteIPHost.ToString();
|
||||
return (Owner as UdpSession)?.RemoteIPHost?.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -83,11 +83,11 @@ public abstract class ReadWriteDevicesUdpDataHandleAdapter<TRequest> : UdpDataHa
|
||||
var allBytes = byteBlock.ToArray(0, byteBlock.Len);
|
||||
Logger?.Trace($"{FoundationConst.LogMessageHeader}{ToString()}- 接收:{(IsHexData ? allBytes.ToHexString(' ') : Encoding.UTF8.GetString(allBytes))}");
|
||||
|
||||
if (Request?.SendBytes == null)
|
||||
{
|
||||
GoReceived(remoteEndPoint, byteBlock, null);
|
||||
return;
|
||||
}
|
||||
//if (Request?.SendBytes == null)
|
||||
//{
|
||||
// GoReceived(remoteEndPoint, byteBlock, null);
|
||||
// return;
|
||||
//}
|
||||
byte[] header = new byte[] { };
|
||||
if (Request.HeadBytesLength > 0)
|
||||
{
|
||||
|
@@ -22,7 +22,7 @@ public enum ChannelEnum
|
||||
/// <inheritdoc/>
|
||||
TcpClient = 1,
|
||||
/// <inheritdoc/>
|
||||
SerialSession = 2,
|
||||
SerialPortClient = 2,
|
||||
/// <inheritdoc/>
|
||||
UdpSession = 4,
|
||||
/// <inheritdoc/>
|
||||
|
@@ -421,6 +421,74 @@ public static class StringExtensions
|
||||
{
|
||||
return value.IsNullOrEmpty() ? defaultValue : ushort.TryParse(value, out var n) ? n : defaultValue;
|
||||
}
|
||||
/// <summary>
|
||||
/// ToDouble
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static double ToDouble(this object value, double defaultValue = 0)
|
||||
{
|
||||
if (value is Double d)
|
||||
{
|
||||
return Double.IsNaN(d) ? defaultValue : (Double)d;
|
||||
}
|
||||
var str = value?.ToString();
|
||||
if (str.IsNullOrEmpty())
|
||||
{
|
||||
return (double)defaultValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (value is bool boolValue)
|
||||
{
|
||||
return boolValue ? 1 : 0;
|
||||
}
|
||||
return (double)(double.TryParse(str, out var n) ? n : defaultValue);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ToDecimal
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static decimal ToDecimal(this object value, int defaultValue = 0)
|
||||
{
|
||||
if (value is Double d)
|
||||
{
|
||||
return Double.IsNaN(d) ? defaultValue : (Decimal)d;
|
||||
}
|
||||
var str = value?.ToString();
|
||||
if (str.IsNullOrEmpty())
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (value is bool boolValue)
|
||||
{
|
||||
return boolValue ? 1 : 0;
|
||||
}
|
||||
return Decimal.TryParse(str, out var n) ? n : defaultValue;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// ToInt
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static int ToInt(this object value, int defaultValue = 0)
|
||||
{
|
||||
if (value == null || value.ToString().IsNullOrEmpty())
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (value is bool boolValue)
|
||||
{
|
||||
return boolValue ? 1 : 0;
|
||||
}
|
||||
return int.TryParse(value.ToString(), out int n) ? n : defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 用 正则表达式 判断字符是不是汉字
|
||||
|
@@ -1,48 +0,0 @@
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.IO.Ports;
|
||||
|
||||
namespace ThingsGateway.Foundation.Serial;
|
||||
/// <summary>
|
||||
/// Connecting
|
||||
/// </summary>
|
||||
/// <typeparam name="TClient"></typeparam>
|
||||
/// <param name="client"></param>
|
||||
/// <param name="e"></param>
|
||||
public delegate Task SerialConnectingEventHandler<TClient>(TClient client, SerialConnectingEventArgs e);
|
||||
|
||||
/// <summary>
|
||||
/// 客户端连接事件。
|
||||
/// </summary>
|
||||
public class SerialConnectingEventArgs : MsgPermitEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="serialPort"></param>
|
||||
public SerialConnectingEventArgs(SerialPort serialPort)
|
||||
{
|
||||
this.SerialPort = serialPort;
|
||||
this.IsPermitOperation = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 客户端Id。该Id的赋值,仅在服务器适用。
|
||||
/// </summary>
|
||||
public string Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 新初始化的通信器
|
||||
/// </summary>
|
||||
public SerialPort SerialPort { get; private set; }
|
||||
}
|
@@ -1,38 +0,0 @@
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
namespace ThingsGateway.Foundation.Serial;
|
||||
|
||||
/// <summary>
|
||||
/// 串口附加属性
|
||||
/// </summary>
|
||||
public static class SerialConfigExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// 串口属性
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty<SerialProperty> SerialProperty =
|
||||
DependencyProperty<SerialProperty>.Register("SerialProperty", new());
|
||||
|
||||
/// <summary>
|
||||
/// 设置串口
|
||||
/// </summary>
|
||||
/// <param name="config"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public static TouchSocketConfig SetSerialProperty(this TouchSocketConfig config, SerialProperty value)
|
||||
{
|
||||
config.SetValue(SerialProperty, value);
|
||||
return config;
|
||||
}
|
||||
|
||||
}
|
@@ -1,58 +0,0 @@
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.IO.Ports;
|
||||
|
||||
namespace ThingsGateway.Foundation.Serial;
|
||||
|
||||
/// <summary>
|
||||
/// SocketExtension
|
||||
/// </summary>
|
||||
public static class SerialPortExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 会使用同步锁,保证所有数据上缓存区。
|
||||
/// </summary>
|
||||
/// <param name="serialPort"></param>
|
||||
/// <param name="buffer"></param>
|
||||
/// <param name="offset"></param>
|
||||
/// <param name="length"></param>
|
||||
public static void AbsoluteSend(this SerialPort serialPort, byte[] buffer, int offset, int length)
|
||||
{
|
||||
lock (serialPort)
|
||||
{
|
||||
serialPort.Write(buffer, offset, length);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 尝试关闭<see cref="SerialPort"/>。不会抛出异常。
|
||||
/// </summary>
|
||||
/// <param name="serialPort"></param>
|
||||
public static void TryClose(this SerialPort serialPort)
|
||||
{
|
||||
lock (serialPort)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (serialPort.IsOpen)
|
||||
{
|
||||
serialPort.Close();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,36 +0,0 @@
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
namespace ThingsGateway.Foundation.Serial;
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc cref="ISerialSessionBase"/>
|
||||
/// </summary>
|
||||
public interface ISerialSession : ISerialSessionBase, IClientSender, IPluginObject, ISetupConfigObject
|
||||
{
|
||||
/// <summary>
|
||||
/// 成功打开串口
|
||||
/// </summary>
|
||||
ConnectedEventHandler<ISerialSession> Connected { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 准备连接串口的时候
|
||||
/// </summary>
|
||||
SerialConnectingEventHandler<ISerialSession> Connecting { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 连接串口
|
||||
/// </summary>
|
||||
/// <exception cref="Exception"></exception>
|
||||
ISerialSession Connect();
|
||||
|
||||
}
|
@@ -1,66 +0,0 @@
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.IO.Ports;
|
||||
|
||||
namespace ThingsGateway.Foundation.Serial;
|
||||
|
||||
/// <summary>
|
||||
/// 串口连接接口。
|
||||
/// </summary>
|
||||
public interface ISerialSessionBase : ISenderClient, IClient, ISender, IDefaultSender, IPluginObject, IRequsetInfoSender, IConfigObject, IOnlineClient
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否允许自由调用<see cref="SetDataHandlingAdapter"/>进行赋值。
|
||||
/// </summary>
|
||||
bool CanSetDataHandlingAdapter { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 数据处理适配器
|
||||
/// </summary>
|
||||
SingleStreamDataHandlingAdapter DataHandlingAdapter { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 断开连接
|
||||
/// </summary>
|
||||
DisconnectEventHandler<ISerialSessionBase> Disconnected { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 即将断开连接(仅主动断开时有效)。
|
||||
/// <para>
|
||||
/// </para>
|
||||
/// </summary>
|
||||
DisconnectEventHandler<ISerialSessionBase> Disconnecting { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 主通信器
|
||||
/// </summary>
|
||||
SerialPort MainSerialPort { get; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 串口描述
|
||||
/// </summary>
|
||||
SerialProperty SerialProperty { get; }
|
||||
/// <summary>
|
||||
/// 关闭客户端。
|
||||
/// </summary>
|
||||
/// <param name="msg"></param>
|
||||
/// <exception cref="Exception"></exception>
|
||||
void Close(string msg = TouchSocketCoreUtility.Empty);
|
||||
|
||||
/// <summary>
|
||||
/// 设置数据处理适配器
|
||||
/// </summary>
|
||||
/// <param name="adapter"></param>
|
||||
void SetDataHandlingAdapter(SingleStreamDataHandlingAdapter adapter);
|
||||
}
|
@@ -1,388 +0,0 @@
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.IO.Ports;
|
||||
|
||||
namespace ThingsGateway.Foundation.Serial;
|
||||
internal sealed class InternalSerialCore : SerialCore
|
||||
{
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// Serial核心
|
||||
/// </summary>
|
||||
public class SerialCore : IDisposable, ISender
|
||||
{
|
||||
/// <summary>
|
||||
/// 最小缓存尺寸
|
||||
/// </summary>
|
||||
public int MinBufferSize { get; set; } = 1024 * 10;
|
||||
|
||||
/// <summary>
|
||||
/// 最大缓存尺寸
|
||||
/// </summary>
|
||||
public int MaxBufferSize { get; set; } = 1024 * 1024 * 10;
|
||||
#region 字段
|
||||
|
||||
/// <summary>
|
||||
/// 同步根
|
||||
/// </summary>
|
||||
public readonly object SyncRoot = new object();
|
||||
|
||||
private long m_bufferRate;
|
||||
private bool m_online => m_serialPort?.IsOpen == true;
|
||||
private int m_receiveBufferSize = 1024 * 10;
|
||||
private ValueCounter m_receiveCounter;
|
||||
private int m_sendBufferSize = 1024 * 10;
|
||||
private ValueCounter m_sendCounter;
|
||||
private readonly EasyLock m_semaphoreForSend = new EasyLock();
|
||||
private SerialPort m_serialPort;
|
||||
|
||||
#endregion 字段
|
||||
|
||||
/// <summary>
|
||||
/// Tcp核心
|
||||
/// </summary>
|
||||
public SerialCore()
|
||||
{
|
||||
this.m_receiveCounter = new ValueCounter
|
||||
{
|
||||
Period = TimeSpan.FromSeconds(1),
|
||||
OnPeriod = this.OnReceivePeriod
|
||||
};
|
||||
|
||||
this.m_sendCounter = new ValueCounter
|
||||
{
|
||||
Period = TimeSpan.FromSeconds(1),
|
||||
OnPeriod = this.OnSendPeriod
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 析构函数
|
||||
/// </summary>
|
||||
~SerialCore()
|
||||
{
|
||||
this.SafeDispose();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool CanSend => this.m_online;
|
||||
|
||||
/// <summary>
|
||||
/// 当中断Tcp的时候。当为<see langword="true"/>时,意味着是调用<see cref="Close(string)"/>。当为<see langword="false"/>时,则是其他中断。
|
||||
/// </summary>
|
||||
public Action<SerialCore, bool, string> OnBreakOut { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当发生异常的时候
|
||||
/// </summary>
|
||||
public Action<SerialCore, Exception> OnException { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 在线状态
|
||||
/// </summary>
|
||||
public bool Online { get => this.m_online; }
|
||||
/// <summary>
|
||||
/// UserToken
|
||||
/// </summary>
|
||||
public ByteBlock UserToken { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当收到数据的时候
|
||||
/// </summary>
|
||||
public Action<SerialCore, ByteBlock> OnReceived { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 接收缓存池,运行时的值会根据流速自动调整
|
||||
/// </summary>
|
||||
public int ReceiveBufferSize
|
||||
{
|
||||
get => this.m_receiveBufferSize;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 接收计数器
|
||||
/// </summary>
|
||||
public ValueCounter ReceiveCounter { get => this.m_receiveCounter; }
|
||||
|
||||
/// <summary>
|
||||
/// 发送缓存池,运行时的值会根据流速自动调整
|
||||
/// </summary>
|
||||
public int SendBufferSize
|
||||
{
|
||||
get => this.m_sendBufferSize;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送计数器
|
||||
/// </summary>
|
||||
public ValueCounter SendCounter { get => this.m_sendCounter; }
|
||||
|
||||
/// <summary>
|
||||
/// SerialPort
|
||||
/// </summary>
|
||||
public SerialPort MainSerialPort { get => this.m_serialPort; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 开始以Iocp方式接收
|
||||
/// </summary>
|
||||
public virtual void BeginIocpReceive()
|
||||
{
|
||||
var byteBlock = BytePool.Default.GetByteBlock(this.ReceiveBufferSize);
|
||||
this.UserToken = byteBlock;
|
||||
byteBlock.SetLength(0);
|
||||
if (this.m_serialPort.BytesToRead > 0)
|
||||
{
|
||||
this.m_bufferRate += 2;
|
||||
this.ProcessReceived();
|
||||
}
|
||||
m_serialPort.DataReceived += MainSerialPort_DataReceived;
|
||||
}
|
||||
|
||||
private void MainSerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.m_bufferRate = 1;
|
||||
this.ProcessReceived();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.PrivateBreakOut(false, ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 请求关闭
|
||||
/// </summary>
|
||||
/// <param name="msg"></param>
|
||||
public virtual void Close(string msg)
|
||||
{
|
||||
this.PrivateBreakOut(true, msg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 释放对象
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
GC.SuppressFinalize(this);
|
||||
UserToken.SafeDispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重置环境,并设置新的<see cref="m_serialPort"/>。
|
||||
/// </summary>
|
||||
/// <param name="socket"></param>
|
||||
public virtual void Reset(SerialPort socket)
|
||||
{
|
||||
if (socket is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(socket));
|
||||
}
|
||||
|
||||
if (!socket.IsOpen)
|
||||
{
|
||||
throw new Exception("新的SerialPort必须在连接状态。");
|
||||
}
|
||||
this.Reset();
|
||||
this.m_serialPort = socket;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重置环境。
|
||||
/// </summary>
|
||||
public virtual void Reset()
|
||||
{
|
||||
this.m_receiveCounter.Reset();
|
||||
this.m_sendCounter.Reset();
|
||||
this.m_serialPort = null;
|
||||
this.OnReceived = null;
|
||||
this.OnBreakOut = null;
|
||||
this.UserToken = null;
|
||||
this.m_bufferRate = 1;
|
||||
this.m_receiveBufferSize = this.MinBufferSize;
|
||||
this.m_sendBufferSize = this.MinBufferSize;
|
||||
}
|
||||
/// <summary>
|
||||
/// 判断,当不在连接状态时触发异常。
|
||||
/// </summary>
|
||||
/// <exception cref="NotConnectedException"></exception>
|
||||
protected void ThrowIfNotConnected()
|
||||
{
|
||||
if (!this.m_online)
|
||||
{
|
||||
throw new NotConnectedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送数据。
|
||||
/// <para>
|
||||
/// 内部会根据是否启用Ssl,进行直接发送,还是Ssl发送。
|
||||
/// </para>
|
||||
/// </summary>
|
||||
/// <param name="buffer"></param>
|
||||
/// <param name="offset"></param>
|
||||
/// <param name="length"></param>
|
||||
public virtual void Send(byte[] buffer, int offset, int length)
|
||||
{
|
||||
this.ThrowIfNotConnected();
|
||||
try
|
||||
{
|
||||
this.m_semaphoreForSend.Wait();
|
||||
this.m_serialPort.Write(buffer, offset, length);
|
||||
this.m_sendCounter.Increment(length);
|
||||
}
|
||||
finally
|
||||
{
|
||||
this.m_semaphoreForSend.Release();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步发送数据。
|
||||
/// </summary>
|
||||
/// <param name="buffer"></param>
|
||||
/// <param name="offset"></param>
|
||||
/// <param name="length"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="Exception"></exception>
|
||||
public virtual async Task SendAsync(byte[] buffer, int offset, int length)
|
||||
{
|
||||
this.ThrowIfNotConnected();
|
||||
try
|
||||
{
|
||||
await this.m_semaphoreForSend.WaitAsync();
|
||||
|
||||
this.m_serialPort.Write(buffer, offset, length);
|
||||
this.m_sendCounter.Increment(length);
|
||||
}
|
||||
finally
|
||||
{
|
||||
this.m_semaphoreForSend.Release();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当中断Tcp时。
|
||||
/// </summary>
|
||||
/// <param name="manual">当为<see langword="true"/>时,意味着是调用<see cref="Close(string)"/>。当为<see langword="false"/>时,则是其他中断。</param>
|
||||
/// <param name="msg"></param>
|
||||
protected virtual void BreakOut(bool manual, string msg)
|
||||
{
|
||||
this.OnBreakOut?.Invoke(this, manual, msg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 当发生异常的时候
|
||||
/// </summary>
|
||||
/// <param name="ex"></param>
|
||||
protected virtual void Exception(Exception ex)
|
||||
{
|
||||
this.OnException?.Invoke(this, ex);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当收到数据的时候
|
||||
/// </summary>
|
||||
/// <param name="byteBlock"></param>
|
||||
protected virtual void Received(ByteBlock byteBlock)
|
||||
{
|
||||
this.OnReceived?.Invoke(this, byteBlock);
|
||||
}
|
||||
|
||||
private void HandleBuffer(ByteBlock byteBlock)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.m_receiveCounter.Increment(byteBlock.Length);
|
||||
this.Received(byteBlock);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Exception(ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
byteBlock.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnReceivePeriod(long value)
|
||||
{
|
||||
this.m_receiveBufferSize = Math.Max(TouchSocketUtility.HitBufferLength(value), this.MinBufferSize);
|
||||
if (this.MainSerialPort != null && !MainSerialPort.IsOpen)
|
||||
{
|
||||
this.MainSerialPort.ReadBufferSize = this.m_receiveBufferSize;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSendPeriod(long value)
|
||||
{
|
||||
this.m_sendBufferSize = Math.Max(TouchSocketUtility.HitBufferLength(value), this.MinBufferSize);
|
||||
if (this.MainSerialPort != null && !MainSerialPort.IsOpen)
|
||||
{
|
||||
this.MainSerialPort.WriteBufferSize = this.m_sendBufferSize;
|
||||
}
|
||||
}
|
||||
|
||||
private void PrivateBreakOut(bool manual, string msg)
|
||||
{
|
||||
lock (this.SyncRoot)
|
||||
{
|
||||
if (this.m_online)
|
||||
{
|
||||
this.BreakOut(manual, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessReceived()
|
||||
{
|
||||
if (!this.m_online)
|
||||
{
|
||||
UserToken?.SafeDispose();
|
||||
return;
|
||||
}
|
||||
if (m_serialPort.BytesToRead > 0)
|
||||
{
|
||||
var byteBlock = UserToken;
|
||||
byte[] buffer = BytePool.Default.Rent(m_serialPort.BytesToRead);
|
||||
int num = m_serialPort.Read(buffer, 0, m_serialPort.BytesToRead);
|
||||
byteBlock.Write(buffer, 0, num);
|
||||
byteBlock.SetLength(num);
|
||||
this.HandleBuffer(byteBlock);
|
||||
try
|
||||
{
|
||||
var newByteBlock = BytePool.Default.GetByteBlock((int)Math.Min(this.ReceiveBufferSize * this.m_bufferRate, this.MaxBufferSize));
|
||||
newByteBlock.SetLength(0);
|
||||
UserToken = newByteBlock;
|
||||
|
||||
if (m_serialPort.BytesToRead > 0)
|
||||
{
|
||||
this.m_bufferRate += 2;
|
||||
this.ProcessReceived();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.PrivateBreakOut(false, ex.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,53 +0,0 @@
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.ComponentModel;
|
||||
using System.IO.Ports;
|
||||
|
||||
namespace ThingsGateway.Foundation.Serial;
|
||||
|
||||
/// <summary>
|
||||
/// 串口属性
|
||||
/// </summary>
|
||||
public class SerialProperty
|
||||
{
|
||||
/// <summary>
|
||||
/// COM
|
||||
/// </summary>
|
||||
[Description("COM口")]
|
||||
public string PortName { get; set; } = "COM1";
|
||||
/// <summary>
|
||||
/// 波特率
|
||||
/// </summary>
|
||||
[Description("波特率")]
|
||||
public int BaudRate { get; set; } = 9600;
|
||||
/// <summary>
|
||||
/// 数据位
|
||||
/// </summary>
|
||||
[Description("数据位")]
|
||||
public int DataBits { get; set; } = 8;
|
||||
/// <summary>
|
||||
/// 校验位
|
||||
/// </summary>
|
||||
[Description("校验位")]
|
||||
public Parity Parity { get; set; } = Parity.None;
|
||||
/// <summary>
|
||||
/// 停止位
|
||||
/// </summary>
|
||||
[Description("停止位")]
|
||||
public StopBits StopBits { get; set; } = StopBits.One;
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{PortName}[{BaudRate},{DataBits},{StopBits},{Parity}]";
|
||||
}
|
||||
}
|
@@ -1,749 +0,0 @@
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.IO.Ports;
|
||||
|
||||
namespace ThingsGateway.Foundation.Serial;
|
||||
|
||||
|
||||
/// <inheritdoc cref="SerialSessionBase"/>
|
||||
public class SerialSession : SerialSessionBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 接收到数据
|
||||
/// </summary>
|
||||
public ReceivedEventHandler<SerialSession> Received { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override Task ReceivedData(ReceivedDataEventArgs e)
|
||||
{
|
||||
if (this.Received != null)
|
||||
{
|
||||
return this.Received.Invoke(this, e);
|
||||
}
|
||||
return base.ReceivedData(e);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 串口管理
|
||||
/// </summary>
|
||||
public class SerialSessionBase : SetupConfigObject, ISerialSession
|
||||
{
|
||||
static readonly Protocol SerialPort = new("SerialSession");
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
public SerialSessionBase()
|
||||
{
|
||||
this.Protocol = SerialPort;
|
||||
}
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return SerialProperty?.ToString();
|
||||
}
|
||||
#region 变量
|
||||
|
||||
private DelaySender m_delaySender;
|
||||
private bool m_online => MainSerialPort?.IsOpen == true;
|
||||
private readonly EasyLock m_semaphore = new();
|
||||
private readonly InternalSerialCore m_serialCore = new();
|
||||
#endregion 变量
|
||||
|
||||
#region 事件
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ConnectedEventHandler<ISerialSession> Connected { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public SerialConnectingEventHandler<ISerialSession> Connecting { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public DisconnectEventHandler<ISerialSessionBase> Disconnected { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public DisconnectEventHandler<ISerialSessionBase> Disconnecting { get; set; }
|
||||
|
||||
private async Task PrivateOnConnected(ConnectedEventArgs o)
|
||||
{
|
||||
await this.OnConnected(o);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 已经建立连接
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
protected virtual async Task OnConnected(ConnectedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.Connected != null)
|
||||
{
|
||||
await this.Connected.Invoke(this, e);
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
await this.PluginsManager.RaiseAsync(nameof(ITcpConnectedPlugin.OnTcpConnected), this, e);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.Log(LogLevel.Error, this, $"在事件{nameof(this.Connected)}中发生错误。", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task PrivateOnConnecting(SerialConnectingEventArgs e)
|
||||
{
|
||||
if (this.CanSetDataHandlingAdapter)
|
||||
{
|
||||
this.SetDataHandlingAdapter(this.Config.GetValue(TouchSocketConfigExtension.TcpDataHandlingAdapterProperty).Invoke());
|
||||
}
|
||||
|
||||
await this.OnConnecting(e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 准备连接的时候,此时并未建立连接
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
protected virtual async Task OnConnecting(SerialConnectingEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.Connecting != null)
|
||||
{
|
||||
await this.Connecting.Invoke(this, e);
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
await this.PluginsManager.RaiseAsync(nameof(ITcpConnectingPlugin.OnTcpConnecting), this, e);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.Log(LogLevel.Error, this, $"在事件{nameof(this.OnConnecting)}中发生错误。", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task PrivateOnDisconnected(object obj)
|
||||
{
|
||||
this.m_receiver?.TryInputReceive(default, default);
|
||||
await this.OnDisconnected((DisconnectEventArgs)obj);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 断开连接。在客户端未设置连接状态时,不会触发
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
protected virtual async Task OnDisconnected(DisconnectEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.Disconnected != null)
|
||||
{
|
||||
await this.Disconnected.Invoke(this, e).ConfigureAwait(false);
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
await this.PluginsManager.RaiseAsync(nameof(ITcpDisconnectedPlugin.OnTcpDisconnected), this, e).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.Log(LogLevel.Error, this, $"在事件{nameof(this.Disconnected)}中发生错误。", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task PrivateOnDisconnecting(object obj)
|
||||
{
|
||||
await this.OnDisconnecting((DisconnectEventArgs)obj);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 即将断开连接(仅主动断开时有效)。
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
protected virtual async Task OnDisconnecting(DisconnectEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.Disconnecting != null)
|
||||
{
|
||||
await this.Disconnecting.Invoke(this, e).ConfigureAwait(false);
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
await this.PluginsManager.RaiseAsync(nameof(ITcpDisconnectingPlugin.OnTcpDisconnecting), this, e).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.Log(LogLevel.Error, this, $"在事件{nameof(this.Disconnecting)}中发生错误。", ex);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion 事件
|
||||
|
||||
#region 属性
|
||||
|
||||
/// <inheritdoc/>
|
||||
public DateTime LastReceivedTime => this.GetSerialCore().ReceiveCounter.LastIncrement;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public DateTime LastSendTime => this.GetSerialCore().SendCounter.LastIncrement;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual bool CanSetDataHandlingAdapter => true;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public SingleStreamDataHandlingAdapter DataHandlingAdapter { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public SerialProperty SerialProperty { get; private set; }
|
||||
/// <inheritdoc/>
|
||||
public SerialPort MainSerialPort { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Online { get => this.m_online; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool CanSend => this.m_online;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Protocol Protocol { get; set; }
|
||||
|
||||
|
||||
|
||||
#endregion 属性
|
||||
|
||||
#region 断开操作
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual void Close(string msg = TouchSocketCoreUtility.Empty)
|
||||
{
|
||||
lock (this.GetSerialCore())
|
||||
{
|
||||
if (this.m_online)
|
||||
{
|
||||
Task.Factory.StartNew(this.PrivateOnDisconnecting, new DisconnectEventArgs(true, msg));
|
||||
this.MainSerialPort.TryClose();
|
||||
this.BreakOut(true, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
/// <param name="disposing"></param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
lock (this.GetSerialCore())
|
||||
{
|
||||
if (this.m_online)
|
||||
{
|
||||
Task.Factory.StartNew(this.PrivateOnDisconnecting, new DisconnectEventArgs(true, $"{nameof(Dispose)}主动断开"));
|
||||
this.BreakOut(true, $"{nameof(Dispose)}主动断开");
|
||||
}
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#endregion 断开操作
|
||||
|
||||
#region Connect
|
||||
|
||||
/// <summary>
|
||||
/// 打开串口
|
||||
/// </summary>
|
||||
protected void Open()
|
||||
{
|
||||
try
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
this.m_semaphore.Wait();
|
||||
if (this.m_online)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (this.DisposedValue)
|
||||
{
|
||||
throw new ObjectDisposedException(this.GetType().FullName);
|
||||
}
|
||||
if (this.Config == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(this.Config), "配置文件不能为空。");
|
||||
}
|
||||
var serialProperty = this.Config.GetValue(SerialConfigExtension.SerialProperty) ?? throw new ArgumentNullException("串口配置不能为空。");
|
||||
this.MainSerialPort.SafeDispose();
|
||||
var serialPort = CreateSerial(serialProperty);
|
||||
this.PrivateOnConnecting(new(serialPort)).ConfigureAwait(false).GetAwaiter().GetResult();
|
||||
|
||||
serialPort.Open();
|
||||
|
||||
this.SetSerialPort(serialPort);
|
||||
this.BeginReceive();
|
||||
|
||||
this.PrivateOnConnected(new()).ConfigureAwait(false).GetAwaiter().GetResult();
|
||||
}
|
||||
finally
|
||||
{
|
||||
this.m_semaphore.Release();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void BeginReceive()
|
||||
{
|
||||
this.GetSerialCore().BeginIocpReceive();
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual ISerialSession Connect()
|
||||
{
|
||||
this.Open();
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<ISerialSession> ConnectAsync()
|
||||
{
|
||||
return await Task.Run(() =>
|
||||
{
|
||||
return this.Connect();
|
||||
});
|
||||
}
|
||||
|
||||
#endregion Connect
|
||||
|
||||
#region Receiver
|
||||
|
||||
private Receiver m_receiver;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IReceiver CreateReceiver()
|
||||
{
|
||||
return this.m_receiver ??= new Receiver(this);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void ClearReceiver()
|
||||
{
|
||||
this.m_receiver = null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void SerialCoreBreakOut(SerialCore core, bool manual, string msg)
|
||||
{
|
||||
this.BreakOut(manual, msg);
|
||||
}
|
||||
/// <summary>
|
||||
/// BreakOut。
|
||||
/// </summary>
|
||||
/// <param name="manual"></param>
|
||||
/// <param name="msg"></param>
|
||||
protected void BreakOut(bool manual, string msg)
|
||||
{
|
||||
lock (this.GetSerialCore())
|
||||
{
|
||||
if (this.m_online)
|
||||
{
|
||||
this.MainSerialPort.SafeDispose();
|
||||
this.m_delaySender.SafeDispose();
|
||||
this.DataHandlingAdapter.SafeDispose();
|
||||
Task.Factory.StartNew(this.PrivateOnDisconnected, new DisconnectEventArgs(manual, msg));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private SerialCore GetSerialCore()
|
||||
{
|
||||
this.ThrowIfDisposed();
|
||||
return this.m_serialCore ?? throw new ObjectDisposedException(this.GetType().Name);
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual void SetDataHandlingAdapter(SingleStreamDataHandlingAdapter adapter)
|
||||
{
|
||||
if (!this.CanSetDataHandlingAdapter)
|
||||
{
|
||||
throw new Exception($"不允许自由调用{nameof(SetDataHandlingAdapter)}进行赋值。");
|
||||
}
|
||||
|
||||
this.SetAdapter(adapter);
|
||||
}
|
||||
|
||||
|
||||
private void PrivateHandleReceivedData(ByteBlock byteBlock, IRequestInfo requestInfo)
|
||||
{
|
||||
if (this.m_receiver != null)
|
||||
{
|
||||
if (this.m_receiver.TryInputReceive(byteBlock, requestInfo))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.ReceivedData(new ReceivedDataEventArgs(byteBlock, requestInfo)).GetFalseAwaitResult();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当收到适配器处理的数据时。
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
/// <returns>如果返回<see langword="true"/>则表示数据已被处理,且不会再向下传递。</returns>
|
||||
protected virtual Task ReceivedData(ReceivedDataEventArgs e)
|
||||
{
|
||||
return this.PluginsManager.RaiseAsync(nameof(ITcpReceivedPlugin.OnTcpReceived), this, e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当即将发送时,如果覆盖父类方法,则不会触发插件。
|
||||
/// </summary>
|
||||
/// <param name="buffer">数据缓存区</param>
|
||||
/// <param name="offset">偏移</param>
|
||||
/// <param name="length">长度</param>
|
||||
/// <returns>返回值表示是否允许发送</returns>
|
||||
protected virtual async Task<bool> SendingData(byte[] buffer, int offset, int length)
|
||||
{
|
||||
if (this.PluginsManager.GetPluginCount(nameof(ITcpSendingPlugin.OnTcpSending)) > 0)
|
||||
{
|
||||
var args = new SendingEventArgs(buffer, offset, length);
|
||||
await this.PluginsManager.RaiseAsync(nameof(ITcpSendingPlugin.OnTcpSending), this, args).ConfigureAwait(false);
|
||||
return args.IsPermitOperation;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void LoadConfig(TouchSocketConfig config)
|
||||
{
|
||||
this.SerialProperty = config.GetValue(SerialConfigExtension.SerialProperty);
|
||||
this.Logger ??= this.Container.Resolve<ILog>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置适配器,该方法不会检验<see cref="CanSetDataHandlingAdapter"/>的值。
|
||||
/// </summary>
|
||||
/// <param name="adapter"></param>
|
||||
protected void SetAdapter(SingleStreamDataHandlingAdapter adapter)
|
||||
{
|
||||
this.ThrowIfDisposed();
|
||||
if (adapter is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(adapter));
|
||||
}
|
||||
|
||||
if (this.Config != null)
|
||||
{
|
||||
adapter.Config(this.Config);
|
||||
}
|
||||
|
||||
adapter.Logger = this.Logger;
|
||||
adapter.OnLoaded(this);
|
||||
adapter.ReceivedCallBack = this.PrivateHandleReceivedData;
|
||||
adapter.SendCallBack = this.DefaultSend;
|
||||
adapter.SendAsyncCallBack = this.DefaultSendAsync;
|
||||
this.DataHandlingAdapter = adapter;
|
||||
}
|
||||
|
||||
private static SerialPort CreateSerial(SerialProperty serialProperty)
|
||||
{
|
||||
SerialPort serialPort = new(serialProperty.PortName, serialProperty.BaudRate, serialProperty.Parity, serialProperty.DataBits, serialProperty.StopBits)
|
||||
{
|
||||
DtrEnable = true,
|
||||
RtsEnable = true
|
||||
};
|
||||
return serialPort;
|
||||
}
|
||||
|
||||
#region 发送
|
||||
|
||||
#region 同步发送
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
/// <param name="requestInfo"></param>
|
||||
/// <exception cref="NotConnectedException"></exception>
|
||||
/// <exception cref="OverlengthException"></exception>
|
||||
/// <exception cref="Exception"></exception>
|
||||
public void Send(IRequestInfo requestInfo)
|
||||
{
|
||||
if (this.DisposedValue)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (this.DataHandlingAdapter == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(this.DataHandlingAdapter), TouchSocketResource.NullDataAdapter.GetDescription());
|
||||
}
|
||||
if (!this.DataHandlingAdapter.CanSendRequestInfo)
|
||||
{
|
||||
throw new NotSupportedException($"当前适配器不支持对象发送。");
|
||||
}
|
||||
this.DataHandlingAdapter.SendInput(requestInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
/// <param name="buffer"><inheritdoc/></param>
|
||||
/// <param name="offset"><inheritdoc/></param>
|
||||
/// <param name="length"><inheritdoc/></param>
|
||||
/// <exception cref="NotConnectedException"><inheritdoc/></exception>
|
||||
/// <exception cref="OverlengthException"><inheritdoc/></exception>
|
||||
/// <exception cref="Exception"><inheritdoc/></exception>
|
||||
public virtual void Send(byte[] buffer, int offset, int length)
|
||||
{
|
||||
if (this.DataHandlingAdapter == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(this.DataHandlingAdapter), TouchSocketResource.NullDataAdapter.GetDescription());
|
||||
}
|
||||
this.DataHandlingAdapter.SendInput(buffer, offset, length);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
/// <param name="transferBytes"><inheritdoc/></param>
|
||||
/// <exception cref="NotConnectedException"><inheritdoc/></exception>
|
||||
/// <exception cref="OverlengthException"><inheritdoc/></exception>
|
||||
/// <exception cref="Exception"><inheritdoc/></exception>
|
||||
public virtual void Send(IList<ArraySegment<byte>> transferBytes)
|
||||
{
|
||||
if (this.DataHandlingAdapter == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(this.DataHandlingAdapter), TouchSocketResource.NullDataAdapter.GetDescription());
|
||||
}
|
||||
|
||||
if (this.DataHandlingAdapter.CanSplicingSend)
|
||||
{
|
||||
this.DataHandlingAdapter.SendInput(transferBytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
var length = 0;
|
||||
foreach (var item in transferBytes)
|
||||
{
|
||||
length += item.Count;
|
||||
}
|
||||
using (var byteBlock = new ByteBlock(length))
|
||||
{
|
||||
foreach (var item in transferBytes)
|
||||
{
|
||||
byteBlock.Write(item.Array, item.Offset, item.Count);
|
||||
}
|
||||
this.DataHandlingAdapter.SendInput(byteBlock.Buffer, 0, byteBlock.Len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion 同步发送
|
||||
|
||||
#region 异步发送
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
/// <param name="buffer"></param>
|
||||
/// <param name="offset"></param>
|
||||
/// <param name="length"></param>
|
||||
/// <exception cref="NotConnectedException"></exception>
|
||||
/// <exception cref="OverlengthException"></exception>
|
||||
/// <exception cref="Exception"></exception>
|
||||
public virtual Task SendAsync(byte[] buffer, int offset, int length)
|
||||
{
|
||||
this.ThrowIfDisposed();
|
||||
if (this.DataHandlingAdapter == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(this.DataHandlingAdapter), TouchSocketResource.NullDataAdapter.GetDescription());
|
||||
}
|
||||
return this.DataHandlingAdapter.SendInputAsync(buffer, offset, length);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
/// <param name="requestInfo"></param>
|
||||
/// <exception cref="NotConnectedException"></exception>
|
||||
/// <exception cref="OverlengthException"></exception>
|
||||
/// <exception cref="Exception"></exception>
|
||||
public virtual Task SendAsync(IRequestInfo requestInfo)
|
||||
{
|
||||
this.ThrowIfDisposed();
|
||||
if (this.DataHandlingAdapter == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(this.DataHandlingAdapter), TouchSocketResource.NullDataAdapter.GetDescription());
|
||||
}
|
||||
if (!this.DataHandlingAdapter.CanSendRequestInfo)
|
||||
{
|
||||
throw new NotSupportedException($"当前适配器不支持对象发送。");
|
||||
}
|
||||
return this.DataHandlingAdapter.SendInputAsync(requestInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
/// <param name="transferBytes"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
public virtual Task SendAsync(IList<ArraySegment<byte>> transferBytes)
|
||||
{
|
||||
this.ThrowIfDisposed();
|
||||
if (this.DataHandlingAdapter == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(this.DataHandlingAdapter), TouchSocketResource.NullDataAdapter.GetDescription());
|
||||
}
|
||||
if (this.DataHandlingAdapter.CanSplicingSend)
|
||||
{
|
||||
return this.DataHandlingAdapter.SendInputAsync(transferBytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
var length = 0;
|
||||
foreach (var item in transferBytes)
|
||||
{
|
||||
length += item.Count;
|
||||
}
|
||||
using (var byteBlock = new ByteBlock(length))
|
||||
{
|
||||
foreach (var item in transferBytes)
|
||||
{
|
||||
byteBlock.Write(item.Array, item.Offset, item.Count);
|
||||
}
|
||||
return this.DataHandlingAdapter.SendInputAsync(byteBlock.Buffer, 0, byteBlock.Len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion 异步发送
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void DefaultSend(byte[] buffer, int offset, int length)
|
||||
{
|
||||
if (this.SendingData(buffer, offset, length).GetFalseAwaitResult())
|
||||
{
|
||||
if (this.m_delaySender != null)
|
||||
{
|
||||
this.m_delaySender.Send(new QueueDataBytes(buffer, offset, length));
|
||||
return;
|
||||
}
|
||||
this.GetSerialCore().Send(buffer, offset, length);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task DefaultSendAsync(byte[] buffer, int offset, int length)
|
||||
{
|
||||
if (await this.SendingData(buffer, offset, length))
|
||||
{
|
||||
await this.GetSerialCore().SendAsync(buffer, offset, length);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion 发送
|
||||
|
||||
|
||||
#region 自定义
|
||||
|
||||
|
||||
private void SetSerialPort(SerialPort serialPort)
|
||||
{
|
||||
if (serialPort == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.MainSerialPort = serialPort;
|
||||
this.SerialProperty ??= new();
|
||||
this.SerialProperty.Parity = serialPort.Parity;
|
||||
this.SerialProperty.PortName = serialPort.PortName;
|
||||
this.SerialProperty.StopBits = serialPort.StopBits;
|
||||
this.SerialProperty.DataBits = serialPort.DataBits;
|
||||
this.SerialProperty.BaudRate = serialPort.BaudRate;
|
||||
|
||||
var delaySenderOption = this.Config.GetValue(TouchSocketConfigExtension.DelaySenderProperty);
|
||||
if (delaySenderOption != null)
|
||||
{
|
||||
this.m_delaySender = new DelaySender(delaySenderOption, this.MainSerialPort.AbsoluteSend);
|
||||
}
|
||||
this.m_serialCore.Reset(serialPort);
|
||||
this.m_serialCore.OnReceived = this.HandleReceived;
|
||||
this.m_serialCore.OnBreakOut = this.SerialCoreBreakOut;
|
||||
if (this.Config.GetValue(TouchSocketConfigExtension.MinBufferSizeProperty) is int minValue)
|
||||
{
|
||||
this.m_serialCore.MinBufferSize = minValue;
|
||||
}
|
||||
|
||||
if (this.Config.GetValue(TouchSocketConfigExtension.MaxBufferSizeProperty) is int maxValue)
|
||||
{
|
||||
this.m_serialCore.MaxBufferSize = maxValue;
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleReceived(SerialCore core, ByteBlock byteBlock)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.DisposedValue)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (this.ReceivingData(byteBlock).GetFalseAwaitResult())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.DataHandlingAdapter == null)
|
||||
{
|
||||
this.Logger.Error(this, TouchSocketResource.NullDataAdapter.GetDescription());
|
||||
return;
|
||||
}
|
||||
this.DataHandlingAdapter.ReceivedInput(byteBlock);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.Log(LogLevel.Error, this, "在处理数据时发生错误", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当收到原始数据
|
||||
/// </summary>
|
||||
/// <param name="byteBlock"></param>
|
||||
/// <returns>如果返回<see langword="true"/>则表示数据已被处理,且不会再向下传递。</returns>
|
||||
protected virtual Task<bool> ReceivingData(ByteBlock byteBlock)
|
||||
{
|
||||
if (this.PluginsManager.GetPluginCount(nameof(ITcpReceivingPlugin.OnTcpReceiving)) > 0)
|
||||
{
|
||||
return this.PluginsManager.RaiseAsync(nameof(ITcpReceivingPlugin.OnTcpReceiving), this, new ByteBlockEventArgs(byteBlock));
|
||||
}
|
||||
return Task.FromResult(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
@@ -20,6 +20,5 @@ global using System.Threading.Tasks;
|
||||
global using ThingsGateway.Foundation.Core;
|
||||
global using ThingsGateway.Foundation.Http;
|
||||
global using ThingsGateway.Foundation.Rpc;
|
||||
global using ThingsGateway.Foundation.Serial;
|
||||
global using ThingsGateway.Foundation.SerialPorts;
|
||||
global using ThingsGateway.Foundation.Sockets;
|
||||
|
||||
|
@@ -1,10 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net45;netstandard2.0;net6.0;net8.0;</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)'=='net45'">
|
||||
|
@@ -15,7 +15,7 @@ namespace ThingsGateway.Foundation.Core
|
||||
/// <summary>
|
||||
/// 具有设置配置的对象接口
|
||||
/// </summary>
|
||||
public interface ISetupConfigObject : IConfigObject, IPluginObject
|
||||
public interface ISetupConfigObject : IConfigObject, IPluginObject, IResolverObject
|
||||
{
|
||||
/// <summary>
|
||||
/// 配置设置项
|
||||
@@ -23,5 +23,12 @@ namespace ThingsGateway.Foundation.Core
|
||||
/// <param name="config"></param>
|
||||
/// <exception cref="Exception"></exception>
|
||||
void Setup(TouchSocketConfig config);
|
||||
|
||||
/// <summary>
|
||||
/// 异步配置设置项
|
||||
/// </summary>
|
||||
/// <param name="config"></param>
|
||||
/// <returns></returns>
|
||||
Task SetupAsync(TouchSocketConfig config);
|
||||
}
|
||||
}
|
||||
|
@@ -23,10 +23,10 @@ namespace ThingsGateway.Foundation.Core
|
||||
public override TouchSocketConfig Config => this.m_config;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IContainer Container { get; private set; }
|
||||
public IResolver Resolver { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IPluginsManager PluginsManager { get; private set; }
|
||||
public IPluginManager PluginManager { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Setup(TouchSocketConfig config)
|
||||
@@ -40,11 +40,27 @@ namespace ThingsGateway.Foundation.Core
|
||||
|
||||
this.BuildConfig(config);
|
||||
|
||||
this.PluginsManager?.Raise(nameof(ILoadingConfigPlugin.OnLoadingConfig), this, new ConfigEventArgs(config));
|
||||
this.PluginManager?.Raise(nameof(ILoadingConfigPlugin.OnLoadingConfig), this, new ConfigEventArgs(config));
|
||||
this.LoadConfig(this.Config);
|
||||
this.PluginsManager?.Raise(nameof(ILoadedConfigPlugin.OnLoadedConfig), this, new ConfigEventArgs(config));
|
||||
this.PluginManager?.Raise(nameof(ILoadedConfigPlugin.OnLoadedConfig), this, new ConfigEventArgs(config));
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public async Task SetupAsync(TouchSocketConfig config)
|
||||
{
|
||||
if (config == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(config));
|
||||
}
|
||||
|
||||
this.ThrowIfDisposed();
|
||||
|
||||
this.BuildConfig(config);
|
||||
|
||||
await this.PluginManager.RaiseAsync(nameof(ILoadingConfigPlugin.OnLoadingConfig), this, new ConfigEventArgs(config)).ConfigureFalseAwait();
|
||||
this.LoadConfig(config);
|
||||
//return EasyTask.CompletedTask;
|
||||
await this.PluginManager.RaiseAsync(nameof(ILoadedConfigPlugin.OnLoadedConfig), this, new ConfigEventArgs(config)).ConfigureFalseAwait();
|
||||
}
|
||||
/// <summary>
|
||||
/// 加载配置
|
||||
/// </summary>
|
||||
@@ -56,47 +72,48 @@ namespace ThingsGateway.Foundation.Core
|
||||
|
||||
private void BuildConfig(TouchSocketConfig config)
|
||||
{
|
||||
this.m_config = config;
|
||||
this.m_config = config ?? throw new ArgumentNullException(nameof(config));
|
||||
|
||||
if (!config.TryGetValue(TouchSocketCoreConfigExtension.ContainerProperty, out var container))
|
||||
if (!config.TryGetValue(TouchSocketCoreConfigExtension.ResolverProperty, out var resolver))
|
||||
{
|
||||
container = new Container();
|
||||
if (!config.TryGetValue(TouchSocketCoreConfigExtension.RegistratorProperty, out var registrator))
|
||||
{
|
||||
registrator = new Container();
|
||||
}
|
||||
|
||||
if (!registrator.IsRegistered(typeof(ILog)))
|
||||
{
|
||||
registrator.RegisterSingleton<ILog>(new LoggerGroup());
|
||||
}
|
||||
|
||||
if (config.GetValue(TouchSocketCoreConfigExtension.ConfigureContainerProperty) is Action<IRegistrator> actionContainer)
|
||||
{
|
||||
actionContainer.Invoke(registrator);
|
||||
}
|
||||
|
||||
resolver = registrator.BuildResolver();
|
||||
}
|
||||
|
||||
if (!container.IsRegistered(typeof(ILog)))
|
||||
IPluginManager pluginManager;
|
||||
if ((!this.Config.GetValue(TouchSocketCoreConfigExtension.NewPluginManagerProperty)) && resolver.IsRegistered<IPluginManager>())
|
||||
{
|
||||
container.RegisterSingleton<ILog, LoggerGroup>();
|
||||
}
|
||||
|
||||
if (!(config.GetValue(TouchSocketCoreConfigExtension.PluginsManagerProperty) is IPluginsManager pluginsManager))
|
||||
{
|
||||
pluginsManager = new PluginsManager(container);
|
||||
}
|
||||
|
||||
if (container.IsRegistered(typeof(IPluginsManager)))
|
||||
{
|
||||
pluginsManager = container.Resolve<IPluginsManager>();
|
||||
pluginManager = resolver.Resolve<IPluginManager>();
|
||||
}
|
||||
else
|
||||
{
|
||||
container.RegisterSingleton<IPluginsManager>(pluginsManager);
|
||||
pluginManager = new PluginManager(resolver);
|
||||
}
|
||||
|
||||
if (config.GetValue(TouchSocketCoreConfigExtension.ConfigureContainerProperty) is Action<IContainer> actionContainer)
|
||||
if (this.Config.GetValue(TouchSocketCoreConfigExtension.ConfigurePluginsProperty) is Action<IPluginManager> actionPluginManager)
|
||||
{
|
||||
actionContainer.Invoke(container);
|
||||
pluginManager.Enable = true;
|
||||
actionPluginManager.Invoke(pluginManager);
|
||||
}
|
||||
|
||||
if (config.GetValue(TouchSocketCoreConfigExtension.ConfigurePluginsProperty) is Action<IPluginsManager> actionPluginsManager)
|
||||
{
|
||||
pluginsManager.Enable = true;
|
||||
actionPluginsManager.Invoke(pluginsManager);
|
||||
}
|
||||
this.Logger ??= resolver.Resolve<ILog>();
|
||||
|
||||
this.Logger ??= container.Resolve<ILog>();
|
||||
|
||||
this.Container = container;
|
||||
this.PluginsManager = pluginsManager;
|
||||
this.PluginManager = pluginManager;
|
||||
this.Resolver = resolver;
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user