Compare commits
1422 Commits
5f7f63689c
...
Feature/pr
| Author | SHA1 | Date | |
|---|---|---|---|
| 380ed8f6b1 | |||
| 7423391003 | |||
| 572f66f905 | |||
| 2bea265989 | |||
| ef9b78b924 | |||
| 8ad296fe61 | |||
|
|
823110ea74 | ||
| 061058cbeb | |||
| c6ed46d8b7 | |||
| 3da7453ece | |||
|
|
9a591fabff | ||
| 9d09ef60f8 | |||
| 0757ac7e74 | |||
| a9789023ac | |||
| 16b11a8bb8 | |||
|
|
dd5455d80a | ||
| 9360dcad71 | |||
| 1971252713 | |||
| 02cc099104 | |||
| 209aa5912d | |||
| 340685a06c | |||
| b20a56df26 | |||
| 8d93fa4fc6 | |||
| 8f10f7057c | |||
| 00b5066f6f | |||
| abd221cb55 | |||
| 33833a408c | |||
| c2fca9f9eb | |||
| a16c20440b | |||
| 1f365f3642 | |||
| 0bfcde6a3f | |||
| 4ada29a98a | |||
| 6f64ee1ce4 | |||
| 582da511c6 | |||
| 3340edcc17 | |||
| 385a885c93 | |||
| f99f199a77 | |||
| 287b31e356 | |||
| 5f8232809a | |||
| 3c72311096 | |||
| 250d17eba2 | |||
| 5db8e7d319 | |||
|
|
3300f60845 | ||
|
|
7537cfe5b8 | ||
|
|
3c1bf7dff0 | ||
| 6909fcf715 | |||
| fe66ff5aa3 | |||
| ce305edac4 | |||
| a49b825ce9 | |||
| fb62523a23 | |||
|
|
e171a4749c | ||
| 9b6c0d4cc4 | |||
| f8126b4000 | |||
|
|
cf62d75f0e | ||
|
|
f93e59b77c | ||
|
|
8f37d9f388 | ||
| 8e72b56758 | |||
| a6e1251445 | |||
| 490a1a69d5 | |||
| 7e3ea39d5b | |||
| 66a6c411d6 | |||
|
|
b03a806dfb | ||
| 14ff0a2e59 | |||
| 58f695fe95 | |||
| b4ccacd37e | |||
| 1fef8e355a | |||
| 147621de34 | |||
| d663857de1 | |||
|
|
4d326b1983 | ||
| aa37ca4b28 | |||
| 9bbdff9bc6 | |||
| 45615684ed | |||
| d11fdcf106 | |||
| eb9a3e52fe | |||
| 94955ea1b4 | |||
| 16c1ae04a9 | |||
| 656bb49fab | |||
| cf3f0564f9 | |||
| fb5b98bf25 | |||
| 12318a6a51 | |||
| 1e733f3f20 | |||
| 836e721b6f | |||
| 8fca1f3a91 | |||
| 2feca1f7f8 | |||
| 4e9cecbb74 | |||
| adf297455f | |||
| 1d656a590f | |||
|
|
a33d7c019c | ||
|
|
d62b5ca155 | ||
|
|
18a4334d8a | ||
| 84416fe1f5 | |||
|
|
bd1c1fa814 | ||
| d855684cd7 | |||
| 9e5e8d8e5d | |||
|
|
8496b52013 | ||
| 9eefdd8fd1 | |||
|
|
5c1547dced | ||
|
|
c09321d89d | ||
| 219e64c0f7 | |||
| b42217ed94 | |||
| 8b6786c09a | |||
| 45c5d20323 | |||
| ad6f872145 | |||
| d22805892a | |||
| 4da496cab8 | |||
| aa0eae6c83 | |||
| 2159901614 | |||
|
|
4b40580658 | ||
|
|
8bc9e044ae | ||
|
|
cddaf2f709 | ||
|
|
337cd40a4e | ||
| 7ce7854091 | |||
|
|
a98300cacd | ||
|
|
daded35ab1 | ||
|
|
ba778bb519 | ||
| 4c638cbdae | |||
|
|
27e8d302d9 | ||
|
|
54c67fe8f7 | ||
| 92e1d6de5c | |||
| c488f61a09 | |||
|
|
dc703fad3c | ||
| 54e5904951 | |||
|
|
a638913172 | ||
| a986212834 | |||
| 649242fc76 | |||
|
|
d254da1393 | ||
| ad4b0be033 | |||
| 733f39db9f | |||
| 94237434c5 | |||
| 2da8bc8a20 | |||
| 39a5918a11 | |||
| 8b217f6cd0 | |||
|
|
74bd802a3d | ||
| b58481a36f | |||
|
|
3fd17299f9 | ||
|
|
fc315cc908 | ||
|
|
abe07e1c4b | ||
|
|
6046f55ece | ||
| d80a36ec35 | |||
|
|
7b648b135e | ||
|
|
5998bd212f | ||
|
|
d77bffabdd | ||
| 4f0e5a34a4 | |||
| 5faa2062b9 | |||
|
|
69476f3f2d | ||
|
|
4bc65e500d | ||
| 07587d162f | |||
| 30b4f52896 | |||
| 134466547e | |||
| a191968c15 | |||
|
|
59bbb7aae6 | ||
| d740c36dc6 | |||
|
|
89de3162de | ||
|
|
132c8ac5a4 | ||
| b9e271de1a | |||
| e661bc2dcb | |||
|
|
f00fde4084 | ||
|
|
e8b3700cdf | ||
| 0ca35e3295 | |||
| 1a91743916 | |||
|
|
dd68473150 | ||
|
|
72e3859d2c | ||
| 46d193b45e | |||
| 1bfe41418b | |||
| 6a446d5972 | |||
|
|
acec101c4c | ||
|
|
7d92321d1c | ||
|
|
19f78a230c | ||
| 0e91e6f287 | |||
| 9df56ee19b | |||
| 8750604d96 | |||
| f27ce460fd | |||
|
|
934019c6c6 | ||
|
|
82bf10c2d5 | ||
|
|
19a72ac78d | ||
|
|
9cb42b7cef | ||
| 8e5d4c312e | |||
| 12fab5a9a5 | |||
| 20dd8f64f4 | |||
| b827493306 | |||
| 04c65eae93 | |||
| b4526a4338 | |||
| 2d879ce80a | |||
| 56e79d2099 | |||
| 93891f3837 | |||
|
|
5bdfbc572b | ||
| 4385a65cbc | |||
| 722f8dae7c | |||
|
|
07113353c4 | ||
| 4b39994de6 | |||
| 0dd2dc7c43 | |||
| 8c6336b9bd | |||
| 20c00893b6 | |||
| 20e3d454cf | |||
| b0d174a575 | |||
| 2bf31db6b2 | |||
| 7a4a6de84f | |||
| 293ea0f6f4 | |||
| 3ce4cf3966 | |||
| 4f16d7680c | |||
|
|
7a10d5ce59 | ||
|
|
3d88feeee7 | ||
|
|
f408624463 | ||
|
|
8296292e49 | ||
| be8deef167 | |||
| 84fb29c8c8 | |||
| 0969e8a5fd | |||
| 92e2282381 | |||
|
|
3b71b7d707 | ||
| 6123a53f01 | |||
| ec74db17eb | |||
| dc118cf18b | |||
| a11e54c333 | |||
|
|
2383e7a54f | ||
|
|
2ef1ea3d1a | ||
|
|
ebdc9b1e55 | ||
| 9e5a494881 | |||
| 2972807c9f | |||
| f7351454f3 | |||
| b64d0e5ffd | |||
| 35b7a3a3dd | |||
| fe93ef60c9 | |||
| ef865d9c68 | |||
|
|
61e35100f9 | ||
|
|
01d33ff340 | ||
| cd64e1d24d | |||
| d9da2e97ab | |||
|
|
1c1c8816a5 | ||
| a1e85261a6 | |||
| 000af89fd7 | |||
|
|
a4f3feba1c | ||
|
|
a3d286c040 | ||
|
|
902ef34757 | ||
|
|
e67aca37f9 | ||
| 2a31b27f9b | |||
| e05eb1236b | |||
| a7d3b1e96f | |||
| 73bef104fb | |||
|
|
b31559a29a | ||
|
|
e62270a9b7 | ||
|
|
998759e2dc | ||
|
|
49d401856f | ||
|
|
2faf6c1400 | ||
|
|
a01a927f6f | ||
| bca1e66f0f | |||
|
|
097d5a6e86 | ||
| 83a7bbf5f3 | |||
|
|
24501df615 | ||
| da46d45601 | |||
| 14fda440c1 | |||
| 85ce92af2c | |||
|
|
5777a869cf | ||
| ed6301831c | |||
| 2d0eb52211 | |||
| 05d8b738cc | |||
|
|
5936f02421 | ||
|
|
57116b14cc | ||
| a1e52ca48a | |||
| f75d267ef5 | |||
| 5be44432b1 | |||
|
|
c0d2cae82e | ||
|
|
955a6a3d21 | ||
| a52e313984 | |||
| 58816ca383 | |||
| 370feca81e | |||
|
|
a4bf6c952d | ||
|
|
c9d582877b | ||
| 339cea998a | |||
| 32065aec33 | |||
| f2293934d4 | |||
| b12b3b9eb8 | |||
| 91259046f6 | |||
| c9882f0b59 | |||
|
|
e89aae1cc9 | ||
| 9469a5f76e | |||
| c059066b13 | |||
| ba0669bc55 | |||
| b3f42af77c | |||
| f42db3d21c | |||
| eb49bf771d | |||
| f829b8ddd1 | |||
| 5e6033db95 | |||
| 27e8a26ed8 | |||
|
|
0a2815946c | ||
|
|
7776dedd2a | ||
|
|
5da523e9a8 | ||
| b7a7fb01d7 | |||
| 8d49220532 | |||
|
|
def27929d9 | ||
|
|
ea6fcbc773 | ||
| 788d58b413 | |||
| de8181770d | |||
| 3a32d1ca9d | |||
| 951a194961 | |||
| ea896c4c11 | |||
| 167b2bce09 | |||
|
|
32a05398de | ||
|
|
57853e2d1f | ||
|
|
acd96bcdc7 | ||
| 3c0ec01f77 | |||
| 517f2d06ca | |||
|
|
fb97d3453d | ||
|
|
2320185ade | ||
|
|
80fdd1fece | ||
| 343f830d0d | |||
| 323a46a623 | |||
| 87ff7976fb | |||
| a533850f24 | |||
| b5c1a4c29d | |||
| 28607dec66 | |||
| 4a041ca8e2 | |||
|
|
de0de6fde8 | ||
|
|
70447a74ef | ||
| 90aa6058f0 | |||
| 3df296f205 | |||
| 6a2e4405de | |||
| 88c10ac141 | |||
|
|
8de3939675 | ||
| e78c838cab | |||
|
|
5e4b8a3a80 | ||
|
|
a18984fec1 | ||
| a178fcd202 | |||
| 9e92d2215f | |||
| c63eb23b22 | |||
| 238926118f | |||
| c874164ca2 | |||
| d2f0ed46ae | |||
| 40dd90074b | |||
| 452b0b6277 | |||
| 720e998a54 | |||
| 626722e805 | |||
| 5e5910e0fd | |||
| 5d81731512 | |||
| 511932fa58 | |||
| 95891d5bae | |||
|
|
901a4ebd35 | ||
| f3fa76c292 | |||
|
|
16b04fc75c | ||
| ac6bbc3587 | |||
| 947d7590f4 | |||
| 91403a52a3 | |||
| 7e80342f80 | |||
| 5e92207778 | |||
|
|
29484e9565 | ||
|
|
86ac300e00 | ||
| ba640494d2 | |||
| 6974a505b4 | |||
| 6d3d599449 | |||
| 2d28bd1f98 | |||
| 75ae3efb65 | |||
| eb53fd67ef | |||
| 8ec717916c | |||
| 64bdbcbd2d | |||
| 7e9ba23b97 | |||
|
|
90a420c8c5 | ||
|
|
e6640a1636 | ||
|
|
e9665c190b | ||
|
|
73563b0421 | ||
| ea3baf14e8 | |||
| 36f104f316 | |||
| 42cae1295f | |||
| 95b281c3a4 | |||
|
|
c239b094d7 | ||
| 9e61bd3f55 | |||
| 7025478417 | |||
|
|
b5ee4f01c7 | ||
| 3937cd8a9f | |||
|
|
3ed14bf2bd | ||
| 933dd3d937 | |||
| 90d7de4901 | |||
| 37aa57d773 | |||
| cce903f2ae | |||
| 873ad2f41f | |||
| 2035b6fff8 | |||
|
|
d31cf8470f | ||
|
|
5a34c9a6c9 | ||
|
|
4eb78996d5 | ||
|
|
9d8e40c841 | ||
|
|
4ba21db7c7 | ||
| 164388dac3 | |||
| e81a44dd2f | |||
| f238b5af6b | |||
|
|
f5cb6b276e | ||
| ed746cb60a | |||
| 07b2596a6a | |||
| 7dce7f5bc8 | |||
| 7ac078c631 | |||
| 265d5f8b22 | |||
| cf5c9f29cf | |||
| 7448ddc79c | |||
| 3f1a6f3387 | |||
| 95d4dfe568 | |||
|
|
a481e941c5 | ||
|
|
58637ab038 | ||
|
|
d10eff3dd5 | ||
| 3258deeb2c | |||
| 6d3526fb30 | |||
|
|
ed35067ecc | ||
|
|
488ce6041a | ||
|
|
0f261684e9 | ||
|
|
a2c0cf126a | ||
|
|
09a1d6df38 | ||
|
|
39bacdf8d6 | ||
| ba2b402c04 | |||
| f3470de8b6 | |||
| 783fffa0c2 | |||
| 16c29bc2d0 | |||
|
|
dad334a9bd | ||
|
|
57ef47473b | ||
|
|
193e9f587f | ||
|
|
e00c93b23d | ||
| 8bd248c6a7 | |||
|
|
2164aeb5bc | ||
|
|
7e08b44d4d | ||
|
|
eec53c8024 | ||
|
|
8c37826367 | ||
| 7f9531f07b | |||
| 4a8f76c473 | |||
| 3e5520d8a0 | |||
| 0fbd5c9d3e | |||
| 8436f70aa0 | |||
| 0b439d0268 | |||
|
|
861b214b0c | ||
|
|
690f574240 | ||
|
|
05abc67cdd | ||
| 3282825719 | |||
| 76666b3da7 | |||
| cd1cf93ad1 | |||
| adef1fc15a | |||
| 597f54c062 | |||
| c0ead0a917 | |||
| 59284ffd29 | |||
| 5c7dd76e3f | |||
| dff6bc2541 | |||
| 22b67b344a | |||
|
|
d8b432ca1e | ||
| f4853b6f39 | |||
| 6ab418c4ab | |||
|
|
74dca1d2d2 | ||
|
|
a9b4eb6195 | ||
|
|
2125e15fb9 | ||
| b7f7d3b223 | |||
| 752c7c72ab | |||
| 9cf8447a83 | |||
| e124a4d5d9 | |||
| 7b9e7881c6 | |||
| 18c27d7a9a | |||
| 73da938bc9 | |||
|
|
c080e11fe0 | ||
|
|
0eb9ecc373 | ||
| 470651cb76 | |||
| 2a9d9574e3 | |||
|
|
7b1542d5c6 | ||
|
|
981fd2d4ee | ||
|
|
7f3f785e39 | ||
| ca1ef420af | |||
| d7baf358cc | |||
|
|
676c8d2fa6 | ||
|
|
632ab3631b | ||
| 595b2c8a2d | |||
| c7bace728e | |||
| 08574b5bb5 | |||
| 288e3a8988 | |||
| 8134216a4a | |||
|
|
3d013cfa60 | ||
| 30bfc96cbe | |||
| 5d55118c3c | |||
| 280db87408 | |||
| c5a1e5c274 | |||
| 4c6de6a76f | |||
| 25c7b67eb5 | |||
| 19b390b17d | |||
| 026d8da74a | |||
| 6b6b0767e3 | |||
| 3d86ba401f | |||
| 6a6e2e532a | |||
| ca6638d6a3 | |||
| 608fb824dc | |||
| 4686151bbb | |||
| d7fae42e4f | |||
| 2cfe480733 | |||
|
|
c574ce534d | ||
| 174edbf87d | |||
| a827470831 | |||
| c9b61c3fc6 | |||
| 45002b88c4 | |||
| 0bacb24aa2 | |||
| 7fd8851f71 | |||
| bc6ae854f8 | |||
| 68f1f81b53 | |||
| d4c2ab939e | |||
| 5822005b68 | |||
| 53aeb60861 | |||
| c2a08d9c33 | |||
| 85e2481680 | |||
| b711e803a9 | |||
| 232a834dc9 | |||
| 55f7b4f7c0 | |||
| c5b521bc50 | |||
| acdd7de4f6 | |||
| 78458f24e5 | |||
| fde58a7c75 | |||
|
|
dbddccf011 | ||
| 488454d354 | |||
| 4126a7370f | |||
| 7aff8ba59f | |||
| 7d6b57affd | |||
| 950f2884ac | |||
| 2edf150ef6 | |||
| df9c268959 | |||
| 3c6303e817 | |||
| 23386fda76 | |||
| 119f4496cd | |||
| ce4fc33daa | |||
| f5d95b21b0 | |||
| 6e83904e11 | |||
| 1f7785581c | |||
| 9140f1ea0b | |||
| 81e6094817 | |||
| e5c0a7db58 | |||
| d44a9224be | |||
| c8018948c2 | |||
| a5e68cbd90 | |||
| 37a6920a74 | |||
| db40ab567c | |||
| 5f324a6fa1 | |||
| d1703ad20e | |||
| 2f38470746 | |||
| 23c02abe65 | |||
| 475142744f | |||
| 230cde7c15 | |||
| 13a2cd78cd | |||
| 4aa3c10466 | |||
| 91fc560355 | |||
| 8acb25dd67 | |||
| 9297bdefb5 | |||
| 61b326aed4 | |||
|
|
397280d0a2 | ||
| 5975a92aa1 | |||
| 0cec7c0cce | |||
| be6cb6430f | |||
| f863fb065f | |||
| 76aa1eae88 | |||
| d0b29e7643 | |||
| f1106deff9 | |||
| 94a5741906 | |||
| 221d06a0fc | |||
| 2b993fb746 | |||
| 756e06cc2f | |||
|
|
5b3c7e471e | ||
|
|
330a3ca839 | ||
| 7c4cf1e2ed | |||
| 1d2c4f26f1 | |||
| 761ac352df | |||
| ecfb7af386 | |||
| 92fd8d6b0e | |||
| 4f68d141e8 | |||
| 75ea35596b | |||
| a0e2b969c0 | |||
| 8efffe8b75 | |||
| fdf7fa0d3c | |||
| 5cde26e7f3 | |||
| b448c43bb7 | |||
| 6045153865 | |||
| 5d16020c6a | |||
| 987e5acca4 | |||
| 9ebbe00a95 | |||
| b576a8dd6b | |||
| 69279b320c | |||
| a360a20478 | |||
| aad1645edd | |||
| af1388f0d7 | |||
| 4d0cf13d40 | |||
| 6584558e6a | |||
| 561f742eb5 | |||
| 560ea04f33 | |||
| ed5681256d | |||
| a1a361a09c | |||
| ccd99c5184 | |||
| f29fac2631 | |||
| 4707c389ae | |||
| a403b9f960 | |||
| 6a0abf2545 | |||
| 7a58423eb3 | |||
| 83ef2a1177 | |||
| 3fa05b99dd | |||
| 70164ae498 | |||
| c5d6dcbbc3 | |||
| d70ea10d2d | |||
| db225fea18 | |||
| bd331c8afe | |||
| 9f7d267afb | |||
| 7abbd489bb | |||
| 35811775f3 | |||
| b78a06e743 | |||
| 4ce82679ff | |||
| e1161245cf | |||
| 8e83b32856 | |||
| 8eeec345d1 | |||
| 780a610e91 | |||
| e095f4e07d | |||
| 4a3ac6e096 | |||
| 2bbe616127 | |||
| f64e6ac176 | |||
| 9095ed28e1 | |||
| a1ad139730 | |||
| dbe7aebf37 | |||
| 7eca8226b3 | |||
| 8912215bbc | |||
| 6c5f224fda | |||
| 437f419c2d | |||
| 04ec2ed5a4 | |||
| fc1258e985 | |||
|
|
c7f5310c56 | ||
| 7b3d1f527c | |||
| dbbee73e2a | |||
| 21df40af3b | |||
| 6d0072c8ac | |||
|
|
f50fdd7f91 | ||
| 76013946bd | |||
| 024b8cfaa9 | |||
| b8c738bd14 | |||
| 126cbff54f | |||
| 2e97d3238d | |||
| ea0be6b865 | |||
| 896c891f70 | |||
| 11207a785c | |||
|
|
87cde91ad0 | ||
|
|
55f62da928 | ||
| bfb7f4e38c | |||
|
|
5a7f233568 | ||
|
|
9d83de947f | ||
|
|
f4c3aa1889 | ||
| 8fb10ba5b0 | |||
| b5465f5501 | |||
| bcb42cc05e | |||
| ee9f802486 | |||
| 72d082d5f2 | |||
| 983f629cd6 | |||
| 0e3e783c5c | |||
| 136a9775ea | |||
| a6fdfd13f9 | |||
| 9bf8153d95 | |||
|
|
d0928804ee | ||
|
|
67f199e86f | ||
| 8893b53d9a | |||
| e49f635b4e | |||
| 04d9b84eb6 | |||
| 39d887c4c3 | |||
| 2e0d005ab9 | |||
| f90bb3dfc6 | |||
| 2d0365bc6e | |||
| dba90c9a3f | |||
| 0e360836f7 | |||
| 0753095415 | |||
| 7725384a87 | |||
| 94f16c8a49 | |||
| f5c3e6351c | |||
| 6bfc0a8d67 | |||
| 413bd3aad9 | |||
| 031f05937d | |||
| 84060e83f5 | |||
|
|
85936cad63 | ||
|
|
6f805d9abe | ||
| 0acb691c54 | |||
| 90c6eef199 | |||
| 52f310353f | |||
| 71f7b05490 | |||
| 7681f4e95b | |||
| 681ac6eb1a | |||
| 349b96ba08 | |||
| c38aa29009 | |||
| 914a7def53 | |||
| 2b6864c024 | |||
| cf2849e47e | |||
| c0cbf20450 | |||
| 75cc5a3e5f | |||
| 6603427845 | |||
| 3d12f3b4d2 | |||
| c87d734b5a | |||
| b47759244e | |||
| 7905dff7c6 | |||
| 0ebca7c613 | |||
| 57dae3d8f1 | |||
| 81d78affa0 | |||
| 32e118d6f7 | |||
| 68748ab8a6 | |||
| 7777ad52de | |||
| b8b8d9c3c4 | |||
|
|
04710e321a | ||
|
|
b9ff14757b | ||
| 58152ae2d6 | |||
| f51c42a359 | |||
| 0373a7e6be | |||
| 957284be7f | |||
| c01bc80608 | |||
| f387d0c535 | |||
| 27109b3472 | |||
| d1f64dd1b0 | |||
| ffc6969ee7 | |||
| 9beed6cf45 | |||
| 868bb3f17a | |||
| c3bbd9af98 | |||
| 56cce8c93d | |||
| c13a77e53d | |||
| 523cbc744b | |||
| e53f3a721a | |||
| 79b14ec958 | |||
| 72435f2d47 | |||
| bd72dada76 | |||
| df00f5cbac | |||
| e79dabbb2d | |||
| f527c59603 | |||
| 112369c2a5 | |||
| 518719a6b8 | |||
| 53eab1be67 | |||
| 90ee299b87 | |||
| e6e81cd1c9 | |||
|
|
21aa17d856 | ||
| b8d6911756 | |||
| 2e8f098937 | |||
| c9cae74cd4 | |||
|
|
abe8774d6f | ||
|
|
eab0441f00 | ||
| 13250d9f62 | |||
| e77eb217f7 | |||
| 39200da4b5 | |||
| 49050a8990 | |||
| 9474f3ff1a | |||
| ad4cffffcd | |||
|
|
b3cf56eb1c | ||
|
|
20dbd0121f | ||
|
|
74c7b1ebbd | ||
|
|
b2c6ad2541 | ||
| 8eded713da | |||
|
|
18e559f1ae | ||
|
|
e1dfd8c8e1 | ||
|
|
b1c9b2669d | ||
|
|
116f40d87d | ||
|
|
6a982a80f7 | ||
|
|
c3cb3df3d3 | ||
|
|
604ac76a1a | ||
|
|
f9947dc138 | ||
|
|
3b12be04b5 | ||
|
|
5a1d2640c3 | ||
|
|
de0e21f98b | ||
|
|
80ed1e9469 | ||
|
|
0609c66e0a | ||
|
|
add5b8ef8e | ||
|
|
c5091c53a4 | ||
|
|
3f1664a844 | ||
|
|
fdc5ea950f | ||
|
|
39d62eb02d | ||
|
|
a42ef19470 | ||
|
|
7ae7d8fc07 | ||
|
|
2bc7766ba1 | ||
|
|
d780f24b36 | ||
|
|
d7b49f8fc3 | ||
|
|
82d035b7e1 | ||
|
|
e80621280c | ||
|
|
1c6b0ac292 | ||
|
|
7d3a1dad71 | ||
|
|
b5fc98a47b | ||
|
|
01bc8ef01b | ||
|
|
ca350aa795 | ||
|
|
58c015b151 | ||
|
|
14480eb683 | ||
|
|
882a295413 | ||
|
|
785e364efc | ||
|
|
bd83ed3880 | ||
|
|
fae3c7cbd3 | ||
|
|
052b94a66e | ||
|
|
369757aebe | ||
|
|
38d8e88fd6 | ||
|
|
bcedb0d690 | ||
|
|
3662502db1 | ||
|
|
0701b334e4 | ||
|
|
631bf3a920 | ||
|
|
874bce1113 | ||
|
|
1daaeff194 | ||
|
|
9cd00a1886 | ||
|
|
1f897fa0c9 | ||
|
|
5f7c27e45c | ||
|
|
824a80d1fe | ||
|
|
9e2ec49247 | ||
|
|
f5137d0bab | ||
|
|
881bdfa7ae | ||
|
|
e063870b36 | ||
|
|
fe8335af55 | ||
|
|
179ff95d54 | ||
|
|
5c3119d3d2 | ||
|
|
0c56240158 | ||
|
|
2e703c49f7 | ||
|
|
e9dbfb411a | ||
|
|
40a02dbede | ||
|
|
030ce880f8 | ||
|
|
2b8cc9d05a | ||
|
|
0136e219a1 | ||
|
|
60ed37b965 | ||
|
|
5355e74830 | ||
|
|
87609773e5 | ||
|
|
6112e969b6 | ||
|
|
3e4c57d813 | ||
|
|
efc510a09b | ||
|
|
a6c1ae7971 | ||
|
|
8bf707056e | ||
|
|
ee72c95d55 | ||
|
|
f4f8ab8272 | ||
|
|
1c6def5d70 | ||
|
|
87e0181a8d | ||
|
|
66d566847e | ||
|
|
29fed23805 | ||
|
|
a26f079969 | ||
|
|
dbfffafbee | ||
|
|
b2a70bc5a9 | ||
|
|
5053b69295 | ||
|
|
77458978b5 | ||
|
|
969a707000 | ||
|
|
57b625f3b2 | ||
|
|
62572a9b64 | ||
|
|
6d0b7de149 | ||
|
|
34d8e068df | ||
|
|
3a1dfa7e11 | ||
|
|
866725e3b4 | ||
|
|
2f15c2d54b | ||
|
|
7e3f7d1dcf | ||
|
|
7772bff9f4 | ||
|
|
033461641a | ||
|
|
83a251ad3b | ||
|
|
cdf282a17a | ||
|
|
4bc3fd2fbc | ||
|
|
c826c3614d | ||
|
|
b8ea59b814 | ||
|
|
f82d0d5925 | ||
|
|
701ebaeb96 | ||
|
|
a1d57b291c | ||
|
|
e7d43316ad | ||
|
|
bdc5ccae13 | ||
|
|
d37ad552df | ||
|
|
df39072944 | ||
|
|
9c04fd439d | ||
|
|
2b3067dab2 | ||
|
|
6f8ced3192 | ||
|
|
86682a28e2 | ||
|
|
5720c30f7a | ||
|
|
c90a68a8cc | ||
|
|
a71205aa2b | ||
|
|
641dcc1767 | ||
|
|
b1a15bfa54 | ||
|
|
c40b457d1f | ||
|
|
f7166ca17f | ||
|
|
d4f9c810ea | ||
|
|
09574150b6 | ||
|
|
7ccf600885 | ||
|
|
a7b7bfc745 | ||
|
|
170a0ddba0 | ||
|
|
33a736ab5d | ||
|
|
fa5e079db5 | ||
|
|
ec2defab69 | ||
|
|
a344c3f3a6 | ||
|
|
8f76b8c082 | ||
|
|
e34fef37d7 | ||
|
|
5e7bfe0634 | ||
|
|
23723e4b7a | ||
|
|
859f8ea8ca | ||
|
|
2732ec09b2 | ||
|
|
3744b5f470 | ||
|
|
13d93b3e1d | ||
|
|
db78fb1cd4 | ||
|
|
7ce2142517 | ||
|
|
98146b4aa7 | ||
|
|
5f65c13b45 | ||
|
|
8bde7aa3d1 | ||
|
|
584425b3af | ||
|
|
2f60883ea2 | ||
|
|
da8579d2a6 | ||
|
|
41503101b6 | ||
|
|
1cd4cd4b49 | ||
|
|
7afa112e63 | ||
|
|
3aa5668696 | ||
|
|
df1e6f62b8 | ||
|
|
76e5a93ee5 | ||
|
|
469a8808d1 | ||
|
|
d3157780ea | ||
|
|
2d2dc24280 | ||
|
|
362b306c48 | ||
|
|
b0c02d47c4 | ||
|
|
6869ccb436 | ||
|
|
605fe16ced | ||
|
|
856ed38f08 | ||
|
|
dfb78db2fa | ||
|
|
13ebe2fc2a | ||
|
|
54fbbc964f | ||
|
|
4a3515ad65 | ||
|
|
f0daa0b283 | ||
|
|
82f68d1bbe | ||
|
|
48c2186110 | ||
|
|
72fe632516 | ||
|
|
b92aaaffa0 | ||
|
|
2a315ff7ae | ||
|
|
49b84b50a5 | ||
|
|
204355acd6 | ||
|
|
e1ac481dc3 | ||
|
|
8fd3930393 | ||
|
|
b2694ca281 | ||
|
|
b82456f172 | ||
|
|
c04a8f86a4 | ||
|
|
e0f7ff5ec7 | ||
|
|
7cb3551dc8 | ||
|
|
873a30ecd1 | ||
|
|
c048e89da8 | ||
|
|
c91df337d4 | ||
|
|
b88cda4007 | ||
|
|
5902472b86 | ||
|
|
9aa8855a46 | ||
|
|
9556be42ea | ||
|
|
3ebaeb645c | ||
|
|
366ad25a3a | ||
|
|
463e4bc080 | ||
|
|
785309c731 | ||
|
|
f0126d365d | ||
|
|
b77538218f | ||
|
|
e877aca832 | ||
|
|
f66293a637 | ||
|
|
4aa710b7d6 | ||
|
|
2547fec258 | ||
|
|
acb572d94a | ||
|
|
5ff08ebb2f | ||
|
|
fd122fe582 | ||
|
|
25903856b2 | ||
|
|
d1b7e0c3e1 | ||
|
|
9c0d5b65be | ||
|
|
ac4bd3453a | ||
|
|
77e03f3d7f | ||
|
|
a9008beb24 | ||
|
|
a30d5b68d7 | ||
|
|
93c72e16e7 | ||
|
|
290e1639e8 | ||
|
|
3650b46b8e | ||
|
|
734de19bc2 | ||
|
|
398bb35815 | ||
|
|
697bd9fefe | ||
|
|
9d9f0e14d3 | ||
|
|
2743493a11 | ||
|
|
f9de490c13 | ||
|
|
f374ff3012 | ||
|
|
563fe563c0 | ||
|
|
c75e3464d7 | ||
|
|
e3a5fb578b | ||
|
|
8cb99b2862 | ||
|
|
57b2ad3445 | ||
|
|
3befd6f0d9 | ||
|
|
8f10aa54a8 | ||
|
|
efbd74479b | ||
|
|
8432b2660e | ||
|
|
2f9426bdaf | ||
|
|
5477519464 | ||
|
|
f92257b251 | ||
|
|
5efe58d23d | ||
|
|
648ca44ebb | ||
|
|
3232c979aa | ||
|
|
ce8a0b397d | ||
|
|
c1fcaa1726 | ||
|
|
e1fd94db04 | ||
|
|
882f38d000 | ||
|
|
29560370d8 | ||
|
|
7841e8c336 | ||
|
|
a114cc8242 | ||
|
|
473132d66a | ||
|
|
9124f50577 | ||
|
|
7a13150223 | ||
|
|
f7059bcaeb | ||
|
|
4c4e848f52 | ||
|
|
7984f18516 | ||
|
|
94aa4fda51 | ||
|
|
2d2207565e | ||
|
|
3f8b85906f | ||
|
|
346756c766 | ||
|
|
20f208ac0e | ||
|
|
2b602e4199 | ||
|
|
9557f860bb | ||
|
|
cf0dc95b5c | ||
|
|
c7f7b17866 | ||
|
|
d9259bf7c4 | ||
|
|
55dc4c891f | ||
|
|
daa2a0fdc1 | ||
|
|
6d6ce93f74 | ||
|
|
a71433f751 | ||
|
|
68d1a8d9fe | ||
|
|
a1dfc17ce9 | ||
|
|
99a8cc181d | ||
|
|
05cd8832d5 | ||
|
|
a4bcb1ac55 | ||
|
|
6cec0e39ec | ||
|
|
08bf8395c4 | ||
|
|
bc6378beca | ||
|
|
08adccb2f1 | ||
|
|
5e24071175 | ||
|
|
ebc377603a | ||
|
|
b70dbc8a6b | ||
|
|
a34d81318b | ||
|
|
00357df859 | ||
|
|
ba8e07c63a | ||
|
|
f87b203939 | ||
|
|
79807569dc | ||
|
|
bda666b989 | ||
|
|
9eca54276b | ||
|
|
de64933d06 | ||
|
|
44763da729 | ||
|
|
1f3bf123c4 | ||
|
|
7a33b7da46 | ||
|
|
da6573a147 | ||
|
|
6a6ec2610d | ||
|
|
d9717033cf | ||
|
|
beafd047bf | ||
|
|
7c3abeb463 | ||
|
|
040f40df52 | ||
|
|
ac66df98f5 | ||
|
|
8da9f09663 | ||
|
|
591de9acd8 | ||
|
|
be282fa548 | ||
|
|
1b88cebdf2 | ||
|
|
12356c927b | ||
|
|
b73898f5ea | ||
|
|
51e8686668 | ||
|
|
133b99d5fc | ||
|
|
6c814d5dce | ||
|
|
9879857a97 | ||
|
|
e3f29e5efa | ||
|
|
4d45ee36b6 | ||
|
|
7ae08fe023 | ||
|
|
13278e2c24 | ||
|
|
5ca32bbbaf | ||
|
|
3ea80c1344 | ||
|
|
5ae31b9cea | ||
|
|
117b5df447 | ||
|
|
fee14c65ec | ||
|
|
0d06457e1f | ||
|
|
bdc433b0a3 | ||
|
|
e87733f5cb | ||
|
|
60bd120196 | ||
|
|
0a41751c15 | ||
|
|
41f39fb6fa | ||
|
|
e8fd8bdace | ||
|
|
9f2487f8ef | ||
|
|
32dbd094e0 | ||
|
|
b97039ee15 | ||
|
|
313579cdee | ||
|
|
3bda7116a2 | ||
|
|
8bb29447e2 | ||
|
|
8dc839f561 | ||
|
|
9f9c0d64a9 | ||
|
|
751c1a4131 | ||
|
|
b96ed1c7c3 | ||
|
|
500d7fc8d4 | ||
|
|
b8cfc8eb56 | ||
|
|
4c0f4bb70c | ||
|
|
6317ebb079 | ||
|
|
91d86dbd2e | ||
|
|
aedaf84d57 | ||
|
|
b0c1f216a1 | ||
|
|
bd42a6d5e9 | ||
|
|
e924ca7049 | ||
|
|
482eb8ab0b | ||
|
|
7541abb92c | ||
|
|
91365f5aeb | ||
|
|
0664a71047 | ||
|
|
4ff2596864 | ||
|
|
744078dd6c | ||
|
|
1ebc93a1f8 | ||
|
|
a61c62a2c3 | ||
|
|
0981dc20ec | ||
|
|
e8a65e51db | ||
|
|
fb10d962a6 | ||
|
|
ad2612b60c | ||
|
|
3254db4a62 | ||
|
|
8325752355 | ||
|
|
bb3a50eb18 | ||
|
|
767022d0b8 | ||
|
|
6e7199cf6d | ||
|
|
9ab4670d68 | ||
|
|
d080b093e8 | ||
|
|
f2717de5bf | ||
|
|
e5fa554971 | ||
|
|
6932ba7b79 | ||
|
|
cc3b18bc99 | ||
|
|
194323004b | ||
|
|
5a3b99d07c | ||
|
|
aab65e07dc | ||
|
|
3c6e83a967 | ||
|
|
bfd6632940 | ||
|
|
39a91c269d | ||
|
|
29875f4870 | ||
|
|
0859cd3ba4 | ||
|
|
200f86b270 | ||
|
|
54b3d6ad2c | ||
|
|
e9ab5c40ef | ||
|
|
c7b9f2ae20 | ||
|
|
bf08af0b3d | ||
|
|
314ec82133 | ||
|
|
76448cdca4 | ||
|
|
9f33b481fa | ||
|
|
f6441f916e | ||
|
|
fe20c63baf | ||
|
|
5427782b06 | ||
|
|
0806b55dfb | ||
|
|
7f68e11f9d | ||
|
|
f550aca7f7 | ||
|
|
f1f3ff199a | ||
|
|
60252ab032 | ||
|
|
15e608a1cf | ||
|
|
f3bf66aeb0 | ||
|
|
8ac15191ad | ||
|
|
a177d6063d | ||
|
|
59f063b824 | ||
|
|
be2333cac8 | ||
|
|
f8a1aa596d | ||
|
|
64422755f2 | ||
| 8255e8679e | |||
|
|
62bcd4d6b6 | ||
|
|
af2c71ea09 | ||
|
|
0cb9cfe9b2 | ||
|
|
558021ac6a | ||
|
|
0b59e6af15 | ||
|
|
eecdcc11c0 | ||
|
|
ccbc180c96 | ||
|
|
376d9d1d78 | ||
|
|
7ddd51034a | ||
|
|
a63fed8c4a | ||
|
|
042530b6e3 | ||
|
|
0579692a55 | ||
|
|
e26df8026e | ||
|
|
5ebcbcf774 | ||
|
|
2bdfdb366e | ||
|
|
b1a5333a25 | ||
|
|
31defcde7e | ||
|
|
bf24b3b36d | ||
|
|
e9b115e962 | ||
|
|
6f1e651559 | ||
|
|
143cc4943c | ||
|
|
33ae219fbf | ||
|
|
8f8a971a41 | ||
|
|
94058660b6 | ||
|
|
725559e7c1 | ||
|
|
aab30b3a4b | ||
|
|
a4dbb016d2 | ||
|
|
d0e05df33a | ||
|
|
8eaa739e5e | ||
|
|
358544e56c | ||
|
|
fb52e99c68 | ||
|
|
8eb74fea15 | ||
|
|
00012cef52 | ||
|
|
ba994a5802 | ||
|
|
f4ec4f43c6 | ||
|
|
030a622252 | ||
|
|
3099881416 | ||
|
|
6449776348 | ||
|
|
e8f7f6b778 | ||
|
|
513b093c66 | ||
|
|
b0b8680125 | ||
|
|
2e63c7b80a | ||
|
|
255d13049e | ||
|
|
2714732750 | ||
|
|
2a78a9dc1a | ||
|
|
60b53f6e39 | ||
|
|
87f8517afb | ||
|
|
45a4a735ca | ||
|
|
95b09278aa | ||
|
|
6e5f41ec60 | ||
|
|
f2b3a26471 | ||
|
|
629ae1f0df | ||
|
|
b9db912441 | ||
|
|
b3d339d7fb | ||
|
|
33e3efeef5 | ||
| 38171581d3 | |||
|
|
0d66a79d49 | ||
|
|
35f948484e | ||
|
|
0ed24dff45 | ||
|
|
53061f29b7 | ||
|
|
4ec744a6bd | ||
|
|
c30c460a68 | ||
|
|
861efc48e0 | ||
|
|
eb16bda0ae | ||
|
|
3285be107e | ||
|
|
4818fa32f4 | ||
|
|
79e5d98ac6 | ||
|
|
73732cfe67 | ||
|
|
f2580c8e28 | ||
|
|
6f292ddac6 | ||
|
|
5c5f3eefa6 | ||
|
|
b99c503b58 | ||
|
|
2fd1878126 | ||
|
|
a8c449c101 | ||
|
|
80c0ec28d5 | ||
|
|
b133aa67d2 | ||
|
|
8122c9d841 | ||
|
|
75e2a3c558 | ||
|
|
3fa027dfd1 | ||
|
|
6942e55823 | ||
|
|
2314fd456c | ||
|
|
4415cb8128 | ||
|
|
b9943cf460 | ||
|
|
8d490cd3fe | ||
|
|
1e3780be38 | ||
|
|
92f68d8555 | ||
|
|
f0547828a6 | ||
|
|
b5afc9eef0 | ||
|
|
83a17a7e86 | ||
|
|
8e3a5b46da | ||
|
|
b15c34373b | ||
|
|
8284ec199f | ||
|
|
fcfe7c7e58 | ||
| d27b8484a2 | |||
| 5c637e3626 | |||
|
|
9b28c63317 | ||
|
|
a861f9f21c | ||
|
|
8fd51f4e42 | ||
|
|
146ab74524 | ||
|
|
1d38420ddf | ||
|
|
fcad12d3ef | ||
|
|
285e56ce03 | ||
| b2cb3ae173 | |||
| 8afdf13863 | |||
| 524086129a | |||
| 53d44700b8 | |||
|
|
84ff2bc8f1 | ||
| 3a84c65ce1 | |||
| a6c25ec8e8 | |||
|
|
c69cc41c93 | ||
| 423f14a348 | |||
| 1bb0f1f1b2 | |||
| 7b2eefa954 | |||
|
|
c80a5dbab7 | ||
|
|
256717c6f8 | ||
|
|
0d18d9aa1a | ||
|
|
14fbf309a7 | ||
|
|
e379727606 | ||
| 3303d4b54a | |||
| dba28b4d89 | |||
|
|
41ec3fb9cf | ||
|
|
7f98cf8f12 | ||
|
|
6c8385061e | ||
|
|
a49467ee44 | ||
| e9907650e9 | |||
| fb1db062f3 | |||
|
|
0e66c5e1a0 | ||
|
|
27a92f5796 | ||
| 6e5788074c | |||
| 831b426f9f | |||
| b29b1335d3 | |||
|
|
befcc70d46 | ||
|
|
f249df5b49 | ||
| 24d41ffc68 | |||
|
|
c6d4d7d473 | ||
| c594cbf523 | |||
| 996adec188 | |||
| 6f47948e40 | |||
|
|
d135eb73ea | ||
|
|
86143a044c | ||
| 8a6d4e0af6 | |||
| 3b2fd137e4 | |||
| 52976d8965 | |||
| ec97274d5e | |||
| c9183fb57e | |||
|
|
c4d21be4aa | ||
|
|
e9386708dc | ||
|
|
d70abb60d7 | ||
| 2098e843a5 | |||
| f6b6dfa046 | |||
| 36cdde7e6a | |||
|
|
34358a36c9 | ||
|
|
babecda188 | ||
|
|
98c3e7c821 | ||
|
|
5d91b29f2b | ||
|
|
c948498307 | ||
| 87b0d248a3 | |||
| a410d0c216 | |||
| a640f91703 | |||
|
|
99c8dcb764 | ||
| f35aca8e44 | |||
| 16d45c6dc4 | |||
| 45e746b194 | |||
|
|
d44935329f | ||
|
|
3a7fc7087b | ||
| 925f43214c | |||
|
|
c2fc7dabc1 | ||
|
|
dec5666eb7 | ||
| 9271cb5c66 | |||
| aee7e5ce82 | |||
| 97b4c7dc66 | |||
| e3b6d5f1c9 | |||
| 7c1fe65cf2 | |||
| f26fcba165 | |||
|
|
de2a6203df | ||
|
|
2208834a0e | ||
| de52a0be98 | |||
|
|
5bebec3fde | ||
|
|
cad808d73c | ||
| abef053f56 | |||
| 6469bf5a50 | |||
|
|
4fd5ef52ef | ||
|
|
61e2bdaaf5 | ||
| 8ab22d9948 | |||
|
|
17b5f5fee5 | ||
| 9e7e4ca655 | |||
|
|
100c9367ed | ||
| fdb6799c65 | |||
|
|
c81da3e787 | ||
|
|
d8c0471878 | ||
|
|
8418c2edc4 | ||
|
|
e109a41b90 | ||
|
|
158fc91a67 | ||
|
|
d1fb6e933d | ||
|
|
0811482370 | ||
| 24982e11d3 | |||
| 394d65db31 | |||
| 59deae29c2 | |||
|
|
5576ee5c24 | ||
|
|
46833f93da | ||
|
|
8d78ea548a | ||
|
|
ffbadc5a96 | ||
| e889b61d27 | |||
| b492aa39e8 | |||
| 2201ade168 | |||
|
|
baeeec183b | ||
|
|
3142a80b44 | ||
|
|
7c2354b386 | ||
|
|
175158a3d7 | ||
|
|
b79abcb175 | ||
|
|
7388fd8a81 | ||
|
|
a9c489b43d | ||
|
|
66ada45d29 | ||
|
|
04e51fe3b5 | ||
|
|
e486f20a5a | ||
|
|
2db6a9695c | ||
|
|
cea68fce49 | ||
|
|
3f2c0c5531 | ||
|
|
22f13aea0b | ||
| 0ec62e5e83 | |||
|
|
86a3a21d5b | ||
|
|
e02bc9adc5 | ||
|
|
39bc95731e | ||
|
|
759792b44b | ||
|
|
1409d30dfd | ||
|
|
ad9f747027 | ||
|
|
b021636913 | ||
|
|
3007a87104 | ||
|
|
d7eb8517f7 | ||
|
|
eaaab56421 | ||
|
|
7d763715cd | ||
|
|
7d1eb780a5 | ||
|
|
3e1758d35c | ||
|
|
88a9a62dd3 | ||
|
|
7bcc052ec6 | ||
|
|
6fd9b336a9 | ||
|
|
44d5225ff3 | ||
|
|
03e4f7e8c1 | ||
|
|
2c6512faa2 | ||
|
|
406212a1f0 | ||
|
|
53e93bd410 | ||
|
|
19f109254d | ||
|
|
9311d68a91 | ||
|
|
9e91214941 | ||
|
|
aded6b2839 | ||
|
|
08d40ae299 | ||
|
|
659f647b31 | ||
|
|
0ddcb3653a | ||
|
|
3e3eccf0f0 | ||
|
|
22d7c49379 | ||
|
|
ca7e46907c | ||
|
|
ed7e6a3dee | ||
|
|
40482e167a | ||
|
|
3807b213bb | ||
| 2719639333 | |||
|
|
3aa6c6d1ed | ||
|
|
0112772d3f | ||
|
|
7eb8255215 | ||
|
|
3650caabfa | ||
|
|
faac2bf707 | ||
|
|
f04749043e | ||
|
|
e8a9a674a1 | ||
|
|
d8b6b0f5e8 | ||
|
|
3058f95e0e | ||
|
|
8fa8c33415 | ||
|
|
9393993755 | ||
|
|
4d81de755e | ||
|
|
f02aa4e217 | ||
|
|
6cce3f5321 | ||
|
|
59112d9635 | ||
|
|
987c1b51fa | ||
|
|
5e186a2352 | ||
|
|
f68739cc22 | ||
|
|
db8bb247b3 | ||
|
|
9cc3bb07f1 | ||
|
|
4fd71690d5 | ||
|
|
8078d8bfdd | ||
|
|
3b38b80a28 | ||
|
|
0cd8d5b4cf | ||
|
|
4b23448cc1 | ||
|
|
aeebb983a4 | ||
|
|
2fffa67ff6 | ||
|
|
acb6764271 | ||
|
|
c0f9fb6389 | ||
|
|
e17ca40df6 | ||
|
|
abc8f408a7 | ||
|
|
b8937ef79c | ||
|
|
789b0fbc24 | ||
|
|
65ce181001 | ||
|
|
b8e831ce4d | ||
|
|
56def568b5 | ||
|
|
f4961a46eb | ||
|
|
ffa728d05d | ||
|
|
30c70c83b2 | ||
|
|
ec0996f53c | ||
|
|
541f60d6cd | ||
|
|
0aebb8c498 | ||
|
|
dbb0b2e53a | ||
|
|
7f900755be | ||
|
|
dc39f30c21 | ||
|
|
8dd9ee508a | ||
|
|
9f42af6a23 | ||
|
|
4449195aed |
45
.github/workflows/dotnet-developPublish.yml
vendored
Normal file
45
.github/workflows/dotnet-developPublish.yml
vendored
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
name: Deploy Development ASP.NET Core App to IIS
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- Main
|
||||||
|
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-deploy:
|
||||||
|
runs-on: windows-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup .NET SDK
|
||||||
|
uses: actions/setup-dotnet@v4
|
||||||
|
with:
|
||||||
|
dotnet-version: '8.0.x' # یا نسخه پروژهت
|
||||||
|
|
||||||
|
- name: Restore dependencies
|
||||||
|
run: dotnet restore
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: dotnet build --configuration Release
|
||||||
|
|
||||||
|
- name: Publish
|
||||||
|
run: dotnet publish --configuration Release --output ./publish /p:EnvironmentName=Development --no-build
|
||||||
|
|
||||||
|
- name: Deploy to IIS via Web Deploy
|
||||||
|
shell: powershell
|
||||||
|
run: |
|
||||||
|
$publishFolder = Resolve-Path ./publish
|
||||||
|
& "C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe" `
|
||||||
|
-verb:sync `
|
||||||
|
-source:contentPath="$publishFolder" `
|
||||||
|
-dest:contentPath="dadmehrg",computerName="https://$env:SERVER_HOST:8172/msdeploy.axd?site=gozareshgir",userName="$env:DEPLOY_USER",password="$env:DEPLOY_PASSWORD",authType="Basic" `
|
||||||
|
-allowUntrusted `
|
||||||
|
-enableRule:AppOffline
|
||||||
|
|
||||||
|
env:
|
||||||
|
SERVER_HOST: 171.22.24.15
|
||||||
|
DEPLOY_USER: ${{ secrets.DEPLOY_USER }}
|
||||||
|
DEPLOY_PASSWORD: ${{ secrets.DEPLOY_PASSWORD }}
|
||||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -361,4 +361,6 @@ MigrationBackup/
|
|||||||
|
|
||||||
# # Fody - auto-generated XML schema
|
# # Fody - auto-generated XML schema
|
||||||
# FodyWeavers.xsd
|
# FodyWeavers.xsd
|
||||||
|
.idea
|
||||||
|
/ServiceHost/appsettings.Development.json
|
||||||
|
/ServiceHost/appsettings.json
|
||||||
|
|||||||
@@ -1,22 +1,44 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
<RootNamespace>_0_Framework</RootNamespace>
|
<RootNamespace>_0_Framework</RootNamespace>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="IPE.SmsIR" Version="1.0.5" />
|
<PackageReference Include="FluentValidation" Version="12.1.1" />
|
||||||
<PackageReference Include="EPPlus" Version="7.5.2" />
|
<PackageReference Include="IPE.SmsIR" Version="1.2.7" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="2.1.34" />
|
<PackageReference Include="EPPlus" Version="8.4.0" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.4" />
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="2.3.0" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.3.0" />
|
||||||
<PackageReference Include="Newtonsoft.Json.Bson" Version="1.0.2" />
|
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.3.0" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.1" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="10.0.1" />
|
||||||
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
|
||||||
|
<PackageReference Include="Newtonsoft.Json.Bson" Version="1.0.3" />
|
||||||
<PackageReference Include="PersianTools.Core" Version="2.0.4" />
|
<PackageReference Include="PersianTools.Core" Version="2.0.4" />
|
||||||
<PackageReference Include="System.Drawing.Common" Version="9.0.0" />
|
<PackageReference Include="System.Drawing.Common" Version="10.0.1" />
|
||||||
<PackageReference Include="MD.PersianDateTime.Standard" Version="2.5.0" />
|
<PackageReference Include="MD.PersianDateTime.Standard" Version="2.6.0" />
|
||||||
|
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="10.0.1" />
|
||||||
|
<PackageReference Include="System.Security.Cryptography.Xml" Version="10.0.1" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Remove="Application\UID\UidService.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Remove="Application\AuthorizedPerson\AuthorizedPersonApplication.cs" />
|
||||||
|
<Compile Remove="Application\AuthorizedPerson\IAuthorizedPersonApplication.cs" />
|
||||||
|
<Compile Remove="Domain\AuthorizedPersonAgg\IAuthorizedPersonRepository.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Domain\AuthorizedPersonAgg\" />
|
||||||
|
<Folder Include="InfraStructure\AuthorizedPerson\" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
8
0_Framework/Application/AppSettingConfiguration.cs
Normal file
8
0_Framework/Application/AppSettingConfiguration.cs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
namespace _0_Framework.Application;
|
||||||
|
|
||||||
|
public class AppSettingConfiguration
|
||||||
|
{
|
||||||
|
public string Domain { get; set; }
|
||||||
|
public string ClientDomain =>"client"+Domain;
|
||||||
|
public string AdminDomain =>"admin"+Domain;
|
||||||
|
}
|
||||||
@@ -12,69 +12,77 @@ namespace _0_Framework.Application;
|
|||||||
|
|
||||||
public class AuthHelper : IAuthHelper
|
public class AuthHelper : IAuthHelper
|
||||||
{
|
{
|
||||||
private readonly IHttpContextAccessor _contextAccessor;
|
private readonly IHttpContextAccessor _contextAccessor;
|
||||||
|
|
||||||
public AuthHelper(IHttpContextAccessor contextAccessor)
|
|
||||||
{
|
|
||||||
_contextAccessor = contextAccessor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AuthViewModel CurrentAccountInfo()
|
public AuthHelper(IHttpContextAccessor contextAccessor)
|
||||||
{
|
{
|
||||||
var result = new AuthViewModel();
|
_contextAccessor = contextAccessor;
|
||||||
if (!IsAuthenticated())
|
}
|
||||||
return result;
|
|
||||||
|
|
||||||
var claims = _contextAccessor.HttpContext.User.Claims.ToList();
|
public AuthViewModel CurrentAccountInfo()
|
||||||
result.Id = long.Parse(claims.FirstOrDefault(x => x.Type == "AccountId").Value);
|
{
|
||||||
result.Username = claims.FirstOrDefault(x => x.Type == "Username")?.Value;
|
var result = new AuthViewModel();
|
||||||
result.ProfilePhoto = claims.FirstOrDefault(x => x.Type == "ProfilePhoto")?.Value;
|
if (!IsAuthenticated())
|
||||||
result.RoleId = long.Parse(claims.FirstOrDefault(x => x.Type == ClaimTypes.Role)?.Value);
|
return result;
|
||||||
result.Fullname = claims.FirstOrDefault(x => x.Type == ClaimTypes.Name)?.Value;
|
|
||||||
result.Role = claims.FirstOrDefault(x => x.Type == "RoleName")?.Value;
|
var claims = _contextAccessor.HttpContext.User.Claims.ToList();
|
||||||
result.ClientAriaPermission =claims.FirstOrDefault(x => x.Type == "ClientAriaPermission").Value;
|
result.Id = long.Parse(claims.FirstOrDefault(x => x.Type == "AccountId").Value);
|
||||||
result.AdminAreaPermission = claims.FirstOrDefault(x => x.Type == "AdminAreaPermission").Value;
|
result.Username = claims.FirstOrDefault(x => x.Type == "Username")?.Value;
|
||||||
result.PositionValue = !string.IsNullOrWhiteSpace(claims.FirstOrDefault(x => x.Type == "PositionValue")?.Value) ? int.Parse(claims.FirstOrDefault(x => x.Type == "PositionValue")?.Value) : 0;
|
result.ProfilePhoto = claims.FirstOrDefault(x => x.Type == "ProfilePhoto")?.Value;
|
||||||
result.WorkshopList = Tools.DeserializeFromBsonList<WorkshopClaim>(claims.FirstOrDefault(x => x is { Type: "workshopList" })?.Value);
|
result.RoleId = long.Parse(claims.FirstOrDefault(x => x.Type == ClaimTypes.Role)?.Value);
|
||||||
result.WorkshopSlug = claims.FirstOrDefault(x => x is { Type: "WorkshopSlug" }).Value;
|
result.Fullname = claims.FirstOrDefault(x => x.Type == ClaimTypes.Name)?.Value;
|
||||||
result.Mobile = claims.FirstOrDefault(x => x is { Type: "Mobile" }).Value;
|
result.Role = claims.FirstOrDefault(x => x.Type == "RoleName")?.Value;
|
||||||
|
result.ClientAriaPermission = claims.FirstOrDefault(x => x.Type == "ClientAriaPermission").Value;
|
||||||
|
result.AdminAreaPermission = claims.FirstOrDefault(x => x.Type == "AdminAreaPermission").Value;
|
||||||
|
result.PositionValue = !string.IsNullOrWhiteSpace(claims.FirstOrDefault(x => x.Type == "PositionValue")?.Value) ? int.Parse(claims.FirstOrDefault(x => x.Type == "PositionValue")?.Value) : 0;
|
||||||
|
result.WorkshopList = Tools.DeserializeFromBsonList<WorkshopClaim>(claims.FirstOrDefault(x => x is { Type: "workshopList" })?.Value);
|
||||||
|
result.WorkshopSlug = claims.FirstOrDefault(x => x is { Type: "WorkshopSlug" }).Value;
|
||||||
|
result.Mobile = claims.FirstOrDefault(x => x is { Type: "Mobile" }).Value;
|
||||||
result.SubAccountId = long.Parse(claims.FirstOrDefault(x => x.Type == "SubAccountId").Value);
|
result.SubAccountId = long.Parse(claims.FirstOrDefault(x => x.Type == "SubAccountId").Value);
|
||||||
result.WorkshopName = claims.FirstOrDefault(x => x is { Type: "WorkshopName" })?.Value;
|
result.WorkshopName = claims.FirstOrDefault(x => x is { Type: "WorkshopName" })?.Value;
|
||||||
return result;
|
result.Permissions = Tools.DeserializeFromBsonList<int>(claims.FirstOrDefault(x => x is { Type: "permissions" })?.Value);
|
||||||
}
|
result.RoleName = claims.FirstOrDefault(x => x is { Type: "RoleName" })?.Value;
|
||||||
|
result.WorkshopId = long.Parse(claims.FirstOrDefault(x => x.Type == "WorkshopId")?.Value??"0");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
public List<int> GetPermissions()
|
public List<int> GetPermissions()
|
||||||
{
|
{
|
||||||
if (!IsAuthenticated())
|
if (!IsAuthenticated())
|
||||||
return new List<int>();
|
return new List<int>();
|
||||||
|
|
||||||
var permissions = _contextAccessor.HttpContext.User.Claims.FirstOrDefault(x => x.Type == "permissions")
|
var permissions = _contextAccessor.HttpContext.User.Claims.FirstOrDefault(x => x.Type == "permissions")
|
||||||
?.Value;
|
?.Value;
|
||||||
return Tools.DeserializeFromBsonList<int>(permissions); //Mahan
|
return Tools.DeserializeFromBsonList<int>(permissions); //Mahan
|
||||||
}
|
}
|
||||||
|
|
||||||
public long CurrentAccountId()
|
public bool HasPermission(int permission)
|
||||||
{
|
{
|
||||||
return IsAuthenticated()
|
return GetPermissions().Any(x => x == permission);
|
||||||
? long.Parse(_contextAccessor.HttpContext.User.Claims.First(x => x.Type == "AccountId")?.Value)
|
}
|
||||||
: 0;
|
|
||||||
}
|
public long CurrentAccountId()
|
||||||
public long CurrentSubAccountId()
|
{
|
||||||
{
|
return IsAuthenticated()
|
||||||
return IsAuthenticated()
|
? long.Parse(_contextAccessor.HttpContext.User.Claims.First(x => x.Type == "AccountId")?.Value)
|
||||||
? long.Parse(_contextAccessor.HttpContext.User.Claims.First(x => x.Type == "SubAccountId")?.Value)
|
: 0;
|
||||||
: 0;
|
}
|
||||||
}
|
public long CurrentSubAccountId()
|
||||||
|
{
|
||||||
|
return IsAuthenticated()
|
||||||
|
? long.Parse(_contextAccessor.HttpContext.User.Claims.First(x => x.Type == "SubAccountId")?.Value)
|
||||||
|
: 0;
|
||||||
|
}
|
||||||
public string CurrentAccountMobile()
|
public string CurrentAccountMobile()
|
||||||
{
|
{
|
||||||
return IsAuthenticated()
|
return IsAuthenticated()
|
||||||
? _contextAccessor.HttpContext.User.Claims.First(x => x.Type == "Mobile")?.Value
|
? _contextAccessor.HttpContext.User.Claims.First(x => x.Type == "Mobile")?.Value
|
||||||
: "";
|
: "";
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Vafa
|
#region Vafa
|
||||||
|
|
||||||
public void UpdateWorkshopSlugClaim(string newWorkshopSlug, string newWorkshopName)
|
public void UpdateWorkshopSlugClaim(string newWorkshopSlug, string newWorkshopName,long newWorkshopId)
|
||||||
{
|
{
|
||||||
var user = _contextAccessor.HttpContext.User;
|
var user = _contextAccessor.HttpContext.User;
|
||||||
|
|
||||||
@@ -83,6 +91,7 @@ public class AuthHelper : IAuthHelper
|
|||||||
var claimsIdentity = (ClaimsIdentity)user.Identity;
|
var claimsIdentity = (ClaimsIdentity)user.Identity;
|
||||||
var existingClaimSlug = claimsIdentity.FindFirst("WorkshopSlug");
|
var existingClaimSlug = claimsIdentity.FindFirst("WorkshopSlug");
|
||||||
var existingClaimName = claimsIdentity.FindFirst("WorkshopName");
|
var existingClaimName = claimsIdentity.FindFirst("WorkshopName");
|
||||||
|
var existingWorkshopId = claimsIdentity.FindFirst("WorkshopId");
|
||||||
|
|
||||||
if (existingClaimSlug != null)
|
if (existingClaimSlug != null)
|
||||||
{
|
{
|
||||||
@@ -94,9 +103,14 @@ public class AuthHelper : IAuthHelper
|
|||||||
claimsIdentity.RemoveClaim(existingClaimName);
|
claimsIdentity.RemoveClaim(existingClaimName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (existingWorkshopId != null)
|
||||||
|
{
|
||||||
|
claimsIdentity.RemoveClaim(existingWorkshopId);
|
||||||
|
}
|
||||||
|
|
||||||
claimsIdentity.AddClaim(new Claim("WorkshopSlug", newWorkshopSlug));
|
claimsIdentity.AddClaim(new Claim("WorkshopSlug", newWorkshopSlug));
|
||||||
claimsIdentity.AddClaim(new Claim("WorkshopName", newWorkshopName));
|
claimsIdentity.AddClaim(new Claim("WorkshopName", newWorkshopName));
|
||||||
|
claimsIdentity.AddClaim(new Claim("WorkshopId",newWorkshopId.ToString()));
|
||||||
|
|
||||||
|
|
||||||
var authProperties = new AuthenticationProperties
|
var authProperties = new AuthenticationProperties
|
||||||
@@ -111,160 +125,176 @@ public class AuthHelper : IAuthHelper
|
|||||||
}
|
}
|
||||||
|
|
||||||
public string GetWorkshopSlug()
|
public string GetWorkshopSlug()
|
||||||
{
|
{
|
||||||
return CurrentAccountInfo().ClientAriaPermission == "true"
|
return CurrentAccountInfo().ClientAriaPermission == "true"
|
||||||
? _contextAccessor.HttpContext.User.Claims.First(x => x.Type == "WorkshopSlug")?.Value
|
? _contextAccessor.HttpContext.User.Claims.First(x => x.Type == "WorkshopSlug")?.Value
|
||||||
: "";
|
: "";
|
||||||
}
|
}
|
||||||
public string GetWorkshopName()
|
public string GetWorkshopName()
|
||||||
{
|
{
|
||||||
var workshopName = _contextAccessor.HttpContext.User.Claims.FirstOrDefault(x => x.Type == "ClientAriaPermission")?.Value == "true";
|
var workshopName = _contextAccessor.HttpContext.User.Claims.FirstOrDefault(x => x.Type == "ClientAriaPermission")?.Value == "true";
|
||||||
if (workshopName)
|
if (workshopName)
|
||||||
{
|
{
|
||||||
return _contextAccessor.HttpContext.User.Claims.First(x => x.Type == "WorkshopName")?.Value;
|
return _contextAccessor.HttpContext.User.Claims.First(x => x.Type == "WorkshopName")?.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
public long GetWorkshopId()
|
||||||
|
{
|
||||||
|
return long.Parse(_contextAccessor.HttpContext?.User.Claims.FirstOrDefault(x => x.Type == "WorkshopId")?.Value ?? "0");
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public string CurrentAccountRole()
|
public string CurrentAccountRole()
|
||||||
{
|
{
|
||||||
if (IsAuthenticated())
|
if (IsAuthenticated())
|
||||||
return _contextAccessor.HttpContext.User.Claims.FirstOrDefault(x => x.Type == ClaimTypes.Role)?.Value;
|
return _contextAccessor.HttpContext.User.Claims.FirstOrDefault(x => x.Type == ClaimTypes.Role)?.Value;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsAuthenticated()
|
public bool IsAuthenticated()
|
||||||
{
|
{
|
||||||
return _contextAccessor.HttpContext.User.Identity.IsAuthenticated;
|
return _contextAccessor.HttpContext.User.Identity.IsAuthenticated;
|
||||||
//var claims = _contextAccessor.HttpContext.User.Claims.ToList();
|
//var claims = _contextAccessor.HttpContext.User.Claims.ToList();
|
||||||
//if (claims.Count > 0)
|
//if (claims.Count > 0)
|
||||||
// return true;
|
// return true;
|
||||||
//return false;
|
//return false;
|
||||||
//return claims.Count > 0;
|
//return claims.Count > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Signin(AuthViewModel account)
|
public void Signin(AuthViewModel account)
|
||||||
{
|
{
|
||||||
#region MahanChanges
|
#region MahanChanges
|
||||||
|
|
||||||
var permissions = account.Permissions is { Count: > 0 } ? Tools.SerializeToBson(account.Permissions) : "";
|
if (account.Id == 322)
|
||||||
var workshopBson = account.WorkshopList is { Count: > 0 } ? Tools.SerializeToBson(account.WorkshopList) : "";
|
account.Permissions.AddRange([3060301, 30603, 30604, 30605]);
|
||||||
var slug = account.WorkshopSlug ?? "";
|
|
||||||
|
|
||||||
#endregion
|
var permissions = account.Permissions is { Count: > 0 } ? Tools.SerializeToBson(account.Permissions) : "";
|
||||||
|
|
||||||
var claims = new List<Claim>
|
|
||||||
{
|
|
||||||
new Claim("AccountId", account.Id.ToString()),
|
var workshopBson = account.WorkshopList is { Count: > 0 } ? Tools.SerializeToBson(account.WorkshopList) : "";
|
||||||
new Claim(ClaimTypes.Name, account.Fullname),
|
var slug = account.WorkshopSlug ?? "";
|
||||||
new Claim(ClaimTypes.Role, account.RoleId.ToString()),
|
|
||||||
new Claim("Username", account.Username), // Or Use ClaimTypes.NameIdentifier
|
#endregion
|
||||||
|
|
||||||
|
var claims = new List<Claim>
|
||||||
|
{
|
||||||
|
new Claim("AccountId", account.Id.ToString()),
|
||||||
|
new Claim(ClaimTypes.Name, account.Fullname),
|
||||||
|
new Claim(ClaimTypes.Role, account.RoleId.ToString()),
|
||||||
|
new Claim("Username", account.Username), // Or Use ClaimTypes.NameIdentifier
|
||||||
new Claim("permissions", permissions),
|
new Claim("permissions", permissions),
|
||||||
new Claim("Mobile", account.Mobile),
|
new Claim("Mobile", account.Mobile),
|
||||||
new Claim("ProfilePhoto", account.ProfilePhoto ),
|
new Claim("ProfilePhoto", account.ProfilePhoto ),
|
||||||
new Claim("RoleName", account.RoleName),
|
new Claim("RoleName", account.RoleName),
|
||||||
new Claim("SubAccountId", account.SubAccountId.ToString()),
|
new Claim("SubAccountId", account.SubAccountId.ToString()),
|
||||||
new Claim("AdminAreaPermission", account.AdminAreaPermission.ToString()),
|
new Claim("AdminAreaPermission", account.AdminAreaPermission.ToString()),
|
||||||
new Claim("ClientAriaPermission", account.ClientAriaPermission.ToString()),
|
new Claim("ClientAriaPermission", account.ClientAriaPermission.ToString()),
|
||||||
new Claim("IsCamera", "false"),
|
new Claim("IsCamera", "false"),
|
||||||
new Claim("PositionValue",account.PositionValue.ToString()),
|
new Claim("PositionValue",account.PositionValue.ToString()),
|
||||||
//mahanChanges
|
//mahanChanges
|
||||||
new("workshopList",workshopBson),
|
new("workshopList",workshopBson),
|
||||||
new("WorkshopSlug",slug),
|
new("WorkshopSlug",slug),
|
||||||
new("WorkshopName",account.WorkshopName??"")
|
new("WorkshopId", account.WorkshopId.ToString()),
|
||||||
|
new("WorkshopName",account.WorkshopName??""),
|
||||||
|
new("pm.userId", account.PmUserId.ToString()),
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
|
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
|
||||||
|
|
||||||
var authProperties = new AuthenticationProperties
|
var authProperties = new AuthenticationProperties
|
||||||
{
|
{
|
||||||
ExpiresUtc = DateTimeOffset.UtcNow.AddDays(1)
|
ExpiresUtc = DateTimeOffset.UtcNow.AddDays(1)
|
||||||
};
|
};
|
||||||
|
|
||||||
_contextAccessor.HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,
|
_contextAccessor.HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,
|
||||||
new ClaimsPrincipal(claimsIdentity),
|
new ClaimsPrincipal(claimsIdentity),
|
||||||
authProperties);
|
authProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Camera
|
#region Camera
|
||||||
public void CameraSignIn(CameraAuthViewModel account)
|
public void CameraSignIn(CameraAuthViewModel account)
|
||||||
{
|
{
|
||||||
var claims = new List<Claim>
|
var claims = new List<Claim>
|
||||||
{
|
{
|
||||||
new Claim("AccountId", account.Id.ToString()),
|
new Claim("AccountId", account.Id.ToString()),
|
||||||
new Claim("Username", account.Username), // Or Use ClaimTypes.NameIdentifier
|
new Claim("Username", account.Username), // Or Use ClaimTypes.NameIdentifier
|
||||||
new Claim("WorkshopId", account.WorkshopId.ToString()),
|
new Claim("WorkshopId", account.WorkshopId.ToString()),
|
||||||
new Claim("WorkshopName", account.WorkshopName),
|
new Claim("WorkshopName", account.WorkshopName),
|
||||||
new Claim("Mobile", account.Mobile),
|
new Claim("Mobile", account.Mobile),
|
||||||
new Claim("AccountId", account.AccountId.ToString()),
|
new Claim("AccountId", account.AccountId.ToString()),
|
||||||
new Claim("IsActiveString", account.IsActiveString),
|
new Claim("IsActiveString", account.IsActiveString),
|
||||||
new Claim("IsCamera", "true"),
|
new Claim("IsCamera", "true"),
|
||||||
|
|
||||||
};
|
};
|
||||||
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
|
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
|
||||||
|
|
||||||
var authProperties = new AuthenticationProperties
|
var authProperties = new AuthenticationProperties
|
||||||
{
|
{
|
||||||
|
|
||||||
//ExpiresUtc = DateTimeOffset.UtcNow.AddDays(30)
|
//ExpiresUtc = DateTimeOffset.UtcNow.AddDays(30)
|
||||||
ExpiresUtc = new DateTimeOffset(year: 2100, month: 1, day: 1, hour: 0, minute: 0, second: 0, offset: TimeSpan.Zero)
|
ExpiresUtc = new DateTimeOffset(year: 2100, month: 1, day: 1, hour: 0, minute: 0, second: 0, offset: TimeSpan.Zero)
|
||||||
};
|
};
|
||||||
|
|
||||||
_contextAccessor.HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,
|
_contextAccessor.HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,
|
||||||
new ClaimsPrincipal(claimsIdentity),
|
new ClaimsPrincipal(claimsIdentity),
|
||||||
authProperties);
|
authProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CameraAuthViewModel CameraAccountInfo()
|
public CameraAuthViewModel CameraAccountInfo()
|
||||||
{
|
{
|
||||||
var result = new CameraAuthViewModel();
|
var result = new CameraAuthViewModel();
|
||||||
if (!IsAuthenticated())
|
if (!IsAuthenticated())
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
var claims = _contextAccessor.HttpContext.User.Claims.ToList();
|
var claims = _contextAccessor.HttpContext.User.Claims.ToList();
|
||||||
result.Id = long.Parse(claims.FirstOrDefault(x => x.Type == "AccountId").Value);
|
result.Id = long.Parse(claims.FirstOrDefault(x => x.Type == "AccountId").Value);
|
||||||
result.Username = claims.FirstOrDefault(x => x.Type == "Username")?.Value;
|
result.Username = claims.FirstOrDefault(x => x.Type == "Username")?.Value;
|
||||||
result.WorkshopId = long.Parse(claims.FirstOrDefault(x => x.Type == "WorkshopId")?.Value);
|
result.WorkshopId = long.Parse(claims.FirstOrDefault(x => x.Type == "WorkshopId")?.Value);
|
||||||
result.WorkshopName = claims.FirstOrDefault(x => x.Type == "WorkshopName").Value;
|
result.WorkshopName = claims.FirstOrDefault(x => x.Type == "WorkshopName").Value;
|
||||||
result.Mobile = claims.FirstOrDefault(x => x.Type == "Mobile").Value;
|
result.Mobile = claims.FirstOrDefault(x => x.Type == "Mobile").Value;
|
||||||
result.AccountId = long.Parse(claims.FirstOrDefault(x => x.Type == "AccountId")?.Value);
|
result.AccountId = long.Parse(claims.FirstOrDefault(x => x.Type == "AccountId")?.Value);
|
||||||
result.IsActiveString = claims.FirstOrDefault(x => x.Type == "IsActiveString").Value;
|
result.IsActiveString = claims.FirstOrDefault(x => x.Type == "IsActiveString").Value;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
public void SignOut()
|
public void SignOut()
|
||||||
{
|
{
|
||||||
_contextAccessor.HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
|
_contextAccessor.HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#region Pooya
|
#region Pooya
|
||||||
|
|
||||||
public (long Id, UserType userType, long roleId) GetUserTypeWithId()
|
public (long Id, UserType userType, long roleId) GetUserTypeWithId()
|
||||||
{
|
{
|
||||||
if (!IsAuthenticated())
|
if (!IsAuthenticated())
|
||||||
return (0, UserType.Anonymous, 0);
|
return (0, UserType.Anonymous, 0);
|
||||||
var claims = _contextAccessor.HttpContext.User.Claims.ToList();
|
var claims = _contextAccessor.HttpContext.User.Claims.ToList();
|
||||||
|
|
||||||
var subAccountId = long.Parse(claims.FirstOrDefault(x => x.Type == "SubAccountId")?.Value ?? "0");
|
var subAccountId = long.Parse(claims.FirstOrDefault(x => x.Type == "SubAccountId")?.Value ?? "0");
|
||||||
if (subAccountId > 0)
|
if (subAccountId > 0)
|
||||||
return (subAccountId, UserType.SubAccount, 0);
|
return (subAccountId, UserType.SubAccount, 0);
|
||||||
|
|
||||||
var id = long.Parse(_contextAccessor.HttpContext.User.Claims.First(x => x.Type == "AccountId")?.Value);
|
var id = long.Parse(_contextAccessor.HttpContext.User.Claims.First(x => x.Type == "AccountId")?.Value);
|
||||||
if (claims.FirstOrDefault(x => x.Type == "AdminAreaPermission")?.Value == "true")
|
if (claims.FirstOrDefault(x => x.Type == "AdminAreaPermission")?.Value == "true")
|
||||||
{
|
{
|
||||||
var roleId = long.Parse(claims.FirstOrDefault(x => x.Type == ClaimTypes.Role)?.Value ?? "0");
|
var roleId = long.Parse(claims.FirstOrDefault(x => x.Type == ClaimTypes.Role)?.Value ?? "0");
|
||||||
return (id, UserType.Admin, roleId);
|
return (id, UserType.Admin, roleId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (id, UserType.Client, 0);
|
return (id, UserType.Client, 0);
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -20,16 +20,19 @@ public class AuthViewModel
|
|||||||
|
|
||||||
public int? PositionValue { get; set; }
|
public int? PositionValue { get; set; }
|
||||||
public string WorkshopSlug { get; set; }
|
public string WorkshopSlug { get; set; }
|
||||||
|
public long WorkshopId { get; set; }
|
||||||
public string WorkshopName { get; set; }
|
public string WorkshopName { get; set; }
|
||||||
public List<WorkshopClaim> WorkshopList { get; set; }
|
public List<WorkshopClaim> WorkshopList { get; set; }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
public long SubAccountId { get; set; }
|
public long SubAccountId { get; set; }
|
||||||
|
public long? PmUserId { get; set; }
|
||||||
|
|
||||||
|
|
||||||
public AuthViewModel(long id, long roleId, string fullname, string username, string mobile,string profilePhoto,
|
public AuthViewModel(long id, long roleId, string fullname, string username, string mobile,string profilePhoto,
|
||||||
List<int> permissions, string roleName, string adminAreaPermission, string clientAriaPermission, int? positionValue, long subAccountId = 0)
|
List<int> permissions, string roleName, string adminAreaPermission, string clientAriaPermission, int? positionValue,
|
||||||
|
long subAccountId = 0,long? pmUserId = null)
|
||||||
{
|
{
|
||||||
Id = id;
|
Id = id;
|
||||||
RoleId = roleId;
|
RoleId = roleId;
|
||||||
@@ -43,6 +46,7 @@ public class AuthViewModel
|
|||||||
ClientAriaPermission = clientAriaPermission;
|
ClientAriaPermission = clientAriaPermission;
|
||||||
PositionValue = positionValue;
|
PositionValue = positionValue;
|
||||||
SubAccountId = subAccountId;
|
SubAccountId = subAccountId;
|
||||||
|
PmUserId = pmUserId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AuthViewModel()
|
public AuthViewModel()
|
||||||
|
|||||||
8
0_Framework/Application/Enums/ActivationStatus.cs
Normal file
8
0_Framework/Application/Enums/ActivationStatus.cs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
namespace _0_Framework.Application.Enums;
|
||||||
|
|
||||||
|
public enum ActivationStatus
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Active = 1,
|
||||||
|
DeActive = 2
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
namespace _0_Framework.Application.Enums;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// وضعیت تایید قرادا مالی
|
||||||
|
/// </summary>
|
||||||
|
public enum InstitutionContractVerificationStatus
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// در انتظار تایید
|
||||||
|
/// </summary>
|
||||||
|
PendingForVerify = 0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// در انتظار کارپوشه
|
||||||
|
/// </summary>
|
||||||
|
PendingWorkflow = 1,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// تایید شده
|
||||||
|
/// </summary>
|
||||||
|
Verified = 2
|
||||||
|
}
|
||||||
8
0_Framework/Application/Enums/LegalType.cs
Normal file
8
0_Framework/Application/Enums/LegalType.cs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
namespace _0_Framework.Application.Enums;
|
||||||
|
|
||||||
|
public enum LegalType
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Real = 1,
|
||||||
|
Legal = 2
|
||||||
|
}
|
||||||
15
0_Framework/Application/Enums/TypeOfCheckoutWarning.cs
Normal file
15
0_Framework/Application/Enums/TypeOfCheckoutWarning.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
namespace _0_Framework.Application.Enums;
|
||||||
|
|
||||||
|
public enum TypeOfCheckoutWarning
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// هشدار های متفرقه
|
||||||
|
/// </summary>
|
||||||
|
OthersWarning,
|
||||||
|
/// <summary>
|
||||||
|
/// هشدار سهم بیمه کارگر
|
||||||
|
/// </summary>
|
||||||
|
InsuranceEmployeeShare,
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
41
0_Framework/Application/Enums/TypeOfSmsSetting.cs
Normal file
41
0_Framework/Application/Enums/TypeOfSmsSetting.cs
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
namespace _0_Framework.Application.Enums;
|
||||||
|
|
||||||
|
public enum TypeOfSmsSetting
|
||||||
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// پیامک
|
||||||
|
/// یادآور بدهی ماهیانه قرارداد مالی
|
||||||
|
/// </summary>
|
||||||
|
InstitutionContractDebtReminder,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// پیامک
|
||||||
|
/// صورت حساب ماهانه قرارداد مالی
|
||||||
|
/// </summary>
|
||||||
|
MonthlyInstitutionContract,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// پیامک
|
||||||
|
/// اعلام مسدودی طرف حساب
|
||||||
|
/// </summary>
|
||||||
|
BlockContractingParty,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// پیامک
|
||||||
|
/// هشدار اول
|
||||||
|
/// </summary>
|
||||||
|
Warning,
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///پیامک اقدام قضائی
|
||||||
|
/// </summary>
|
||||||
|
LegalAction,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// پیامک تایید قراداد
|
||||||
|
/// </summary>
|
||||||
|
InstitutionContractConfirm,
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace _0_Framework.Application.FaceEmbedding;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// سرویس اطلاعرسانی تغییرات Face Embedding
|
||||||
|
/// </summary>
|
||||||
|
public interface IFaceEmbeddingNotificationService
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// اطلاعرسانی ایجاد یا بهروزرسانی Embedding
|
||||||
|
/// </summary>
|
||||||
|
Task NotifyEmbeddingCreatedAsync(long workshopId, long employeeId, string employeeFullName);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// اطلاعرسانی حذف Embedding
|
||||||
|
/// </summary>
|
||||||
|
Task NotifyEmbeddingDeletedAsync(long workshopId, long employeeId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// اطلاعرسانی بهبود Embedding
|
||||||
|
/// </summary>
|
||||||
|
Task NotifyEmbeddingRefinedAsync(long workshopId, long employeeId);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace _0_Framework.Application.FaceEmbedding;
|
||||||
|
|
||||||
|
public interface IFaceEmbeddingService
|
||||||
|
{
|
||||||
|
Task<OperationResult> GenerateEmbeddingsAsync(long employeeId, long workshopId, string employeeFullName, string picture1Path, string picture2Path);
|
||||||
|
Task<OperationResult> GenerateEmbeddingsFromStreamAsync(long employeeId, long workshopId, string employeeFullName, Stream picture1Stream, Stream picture2Stream);
|
||||||
|
Task<OperationResult> RefineEmbeddingAsync(long employeeId, long workshopId, float[] embedding, float confidence, Dictionary<string, object> metadata = null);
|
||||||
|
Task<OperationResult> DeleteEmbeddingAsync(long employeeId, long workshopId);
|
||||||
|
Task<OperationResult<FaceEmbeddingResponse>> GetEmbeddingAsync(long employeeId, long workshopId);
|
||||||
|
Task<OperationResult> UpdateEmbeddingFullNameAsync(long employeeId, long workshopId, string newFullName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class FaceEmbeddingResponse
|
||||||
|
{
|
||||||
|
public long EmployeeId { get; set; }
|
||||||
|
public long WorkshopId { get; set; }
|
||||||
|
public string EmployeeFullName { get; set; }
|
||||||
|
public float[] Embedding { get; set; }
|
||||||
|
public float Confidence { get; set; }
|
||||||
|
public Dictionary<string, object> Metadata { get; set; }
|
||||||
|
}
|
||||||
@@ -12,16 +12,18 @@ public interface IAuthHelper
|
|||||||
string CurrentAccountRole();
|
string CurrentAccountRole();
|
||||||
AuthViewModel CurrentAccountInfo();
|
AuthViewModel CurrentAccountInfo();
|
||||||
List<int> GetPermissions();
|
List<int> GetPermissions();
|
||||||
|
bool HasPermission(int permission);
|
||||||
long CurrentAccountId();
|
long CurrentAccountId();
|
||||||
string CurrentAccountMobile();
|
string CurrentAccountMobile();
|
||||||
|
|
||||||
#region Vafa
|
#region Vafa
|
||||||
|
|
||||||
void UpdateWorkshopSlugClaim(string workshopSlug, string workshopName);
|
void UpdateWorkshopSlugClaim(string workshopSlug, string workshopName, long workshopId);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
long CurrentSubAccountId();
|
long CurrentSubAccountId();
|
||||||
string GetWorkshopSlug();
|
string GetWorkshopSlug();
|
||||||
string GetWorkshopName();
|
string GetWorkshopName();
|
||||||
|
long GetWorkshopId();
|
||||||
(long Id, UserType userType, long roleId) GetUserTypeWithId();
|
(long Id, UserType userType, long roleId) GetUserTypeWithId();
|
||||||
}
|
}
|
||||||
@@ -4,5 +4,5 @@ public enum IsActive
|
|||||||
{
|
{
|
||||||
False,
|
False,
|
||||||
True,
|
True,
|
||||||
|
None
|
||||||
}
|
}
|
||||||
@@ -51,4 +51,11 @@ public class OperationResult<T>
|
|||||||
Message = message;
|
Message = message;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
public OperationResult<T> Failed(string message, T data)
|
||||||
|
{
|
||||||
|
IsSuccedded = false;
|
||||||
|
Message = message;
|
||||||
|
Data = data;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
15
0_Framework/Application/PagedResult.cs
Normal file
15
0_Framework/Application/PagedResult.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
|
namespace _0_Framework.Application;
|
||||||
|
|
||||||
|
|
||||||
|
public class PagedResult<T> where T : class
|
||||||
|
{
|
||||||
|
public int TotalCount { get; set; }
|
||||||
|
public List<T> List { get; set; }
|
||||||
|
}
|
||||||
|
public class PagedResult<T,TMeta>:PagedResult<T> where T : class
|
||||||
|
{
|
||||||
|
public TMeta? Meta { get; set; }
|
||||||
|
}
|
||||||
7
0_Framework/Application/PaginationRequest.cs
Normal file
7
0_Framework/Application/PaginationRequest.cs
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
namespace _0_Framework.Application;
|
||||||
|
|
||||||
|
public class PaginationRequest
|
||||||
|
{
|
||||||
|
public int PageIndex { get; set; } = 1;
|
||||||
|
public int PageSize { get; set; } = 30;
|
||||||
|
}
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Net.Http.Json;
|
||||||
|
using System.Security.Policy;
|
||||||
|
using System.Security.Principal;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
|
||||||
|
namespace _0_Framework.Application.PaymentGateway;
|
||||||
|
|
||||||
|
public class AqayePardakhtPaymentGateway:IPaymentGateway
|
||||||
|
{
|
||||||
|
private static string _pin = "86EAF2C4D052F7D8759F";
|
||||||
|
private const string AccountNumber = "AP.1042276242";
|
||||||
|
private const string EncryptedKey = "130D2@D2923";
|
||||||
|
|
||||||
|
private readonly HttpClient _httpClient;
|
||||||
|
|
||||||
|
public AqayePardakhtPaymentGateway(IHttpClientFactory httpClientFactory,IOptions<AppSettingConfiguration> appSetting)
|
||||||
|
{
|
||||||
|
_httpClient = httpClientFactory.CreateClient();
|
||||||
|
|
||||||
|
if (appSetting.Value.Domain == ".dadmehrg.ir")
|
||||||
|
{
|
||||||
|
_pin = "7349F84E81AB584862D9";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<PaymentGatewayResponse> Create(CreatePaymentGatewayRequest command,CancellationToken cancellationToken =default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.PostAsJsonAsync("https://panel.aqayepardakht.ir/api/v2/create", new
|
||||||
|
{
|
||||||
|
pin = _pin,
|
||||||
|
amount = command.Amount,
|
||||||
|
callback = command.CallBackUrl,
|
||||||
|
card_number = command.CardNumber,
|
||||||
|
invoice_id = command.TransactionId,
|
||||||
|
mobile = command.Mobile,
|
||||||
|
email = command.Email??"",
|
||||||
|
description = command.Description,
|
||||||
|
}, cancellationToken: cancellationToken);
|
||||||
|
var resStr = await response.Content.ReadAsStringAsync(cancellationToken);
|
||||||
|
var result = await response.Content.ReadFromJsonAsync<PaymentGatewayResponse>(cancellationToken: cancellationToken);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetStartPayUrl(string transactionId) =>
|
||||||
|
$"https://panel.aqayepardakht.ir/startpay/{transactionId}";
|
||||||
|
|
||||||
|
public async Task<PaymentGatewayResponse> Verify(VerifyPaymentGateWayRequest command, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.PostAsJsonAsync("https://panel.aqayepardakht.ir/api/v2/verify", new
|
||||||
|
{
|
||||||
|
pin = _pin,
|
||||||
|
amount = command.Amount,
|
||||||
|
transid = command.TransactionId,
|
||||||
|
}, cancellationToken: cancellationToken);
|
||||||
|
|
||||||
|
var result = await response.Content.ReadFromJsonAsync<PaymentGatewayResponse>(cancellationToken: cancellationToken);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<PaymentGatewayResponse> CreateSandBox(CreatePaymentGatewayRequest command, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.PostAsJsonAsync("https://panel.aqayepardakht.ir/api/v2/create", new
|
||||||
|
{
|
||||||
|
pin = "sandbox",
|
||||||
|
amount = command.Amount,
|
||||||
|
callback = command.CallBackUrl,
|
||||||
|
card_number = command.Amount,
|
||||||
|
invoice_id = command.TransactionId,
|
||||||
|
mobile = command.Mobile,
|
||||||
|
email = command.Email,
|
||||||
|
description = command.Email,
|
||||||
|
}, cancellationToken: cancellationToken);
|
||||||
|
|
||||||
|
var result = await response.Content.ReadFromJsonAsync<PaymentGatewayResponse>(cancellationToken: cancellationToken);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetStartPaySandBoxUrl(string transactionId) =>
|
||||||
|
$"https://panel.aqayepardakht.ir/startpay/sandbox/{transactionId}";
|
||||||
|
|
||||||
|
public async Task<WalletAmountResponse> GetWalletAmount(CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var response =await _httpClient.PostAsJsonAsync("https://panel.aqayepardakht.ir/api/v2/getmoney", new
|
||||||
|
{
|
||||||
|
account=AccountNumber,
|
||||||
|
code = EncryptedKey
|
||||||
|
}, cancellationToken: cancellationToken);
|
||||||
|
var jsonString = await response.Content.ReadAsStringAsync(cancellationToken);
|
||||||
|
var result = await response.Content.ReadFromJsonAsync<WalletAmountResponse>(cancellationToken);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
67
0_Framework/Application/PaymentGateway/IPaymentGateway.cs
Normal file
67
0_Framework/Application/PaymentGateway/IPaymentGateway.cs
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
using Microsoft.AspNetCore.Server.HttpSys;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace _0_Framework.Application.PaymentGateway;
|
||||||
|
|
||||||
|
public interface IPaymentGateway
|
||||||
|
{
|
||||||
|
Task<PaymentGatewayResponse> Create(CreatePaymentGatewayRequest command, CancellationToken cancellationToken =default);
|
||||||
|
|
||||||
|
string GetStartPayUrl(string transactionId);
|
||||||
|
Task<PaymentGatewayResponse> Verify(VerifyPaymentGateWayRequest command, CancellationToken cancellationToken=default);
|
||||||
|
Task<PaymentGatewayResponse> CreateSandBox(CreatePaymentGatewayRequest command, CancellationToken cancellationToken=default);
|
||||||
|
string GetStartPaySandBoxUrl(string transactionId);
|
||||||
|
Task<WalletAmountResponse> GetWalletAmount(CancellationToken cancellationToken);
|
||||||
|
|
||||||
|
}
|
||||||
|
public class PaymentGatewayResponse
|
||||||
|
{
|
||||||
|
[JsonPropertyName("status")]
|
||||||
|
public string Status { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName("code")]
|
||||||
|
public int? ErrorCode { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName("transid")]
|
||||||
|
public string Token { get; set; }
|
||||||
|
|
||||||
|
public bool IsSuccess { get; set; }
|
||||||
|
|
||||||
|
public string Message { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class WalletAmountResponse
|
||||||
|
{
|
||||||
|
[JsonPropertyName("status")]
|
||||||
|
public string Status { get; set; }
|
||||||
|
[JsonPropertyName("money")]
|
||||||
|
public double Amount { get; set; }
|
||||||
|
[JsonPropertyName("code")]
|
||||||
|
public int Code { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CreatePaymentGatewayRequest
|
||||||
|
{
|
||||||
|
public double Amount { get; set; }
|
||||||
|
public string TransactionId { get; set; }
|
||||||
|
public string CallBackUrl { get; set; }
|
||||||
|
public string CardNumber { get; set; }
|
||||||
|
public string Mobile { get; set; }
|
||||||
|
public string Email { get; set; }
|
||||||
|
public string Description { get; set; }
|
||||||
|
public long FinancialInvoiceId { get; set; }
|
||||||
|
public IDictionary<string, object> ExtraData { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class VerifyPaymentGateWayRequest
|
||||||
|
{
|
||||||
|
public string DigitalReceipt { get; set; }
|
||||||
|
public string TransactionId { get; set; }
|
||||||
|
public double Amount { get; set; }
|
||||||
|
}
|
||||||
112
0_Framework/Application/PaymentGateway/SepehrPaymentGateway.cs
Normal file
112
0_Framework/Application/PaymentGateway/SepehrPaymentGateway.cs
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Net.Http.Json;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace _0_Framework.Application.PaymentGateway;
|
||||||
|
|
||||||
|
public class SepehrPaymentGateway:IPaymentGateway
|
||||||
|
{
|
||||||
|
private readonly HttpClient _httpClient;
|
||||||
|
private const long TerminalId = 99213700;
|
||||||
|
private readonly ILogger<SepehrPaymentGateway> _logger;
|
||||||
|
|
||||||
|
public SepehrPaymentGateway(IHttpClientFactory httpClient, ILogger<SepehrPaymentGateway> logger)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
_httpClient = httpClient.CreateClient();
|
||||||
|
_httpClient.BaseAddress = new Uri("https://sepehr.shaparak.ir/Rest/V1/PeymentApi/");
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<PaymentGatewayResponse> Create(CreatePaymentGatewayRequest command, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Create payment started. TransactionId: {TransactionId}, Amount: {Amount}", command.TransactionId, command.Amount);
|
||||||
|
command.ExtraData ??= new Dictionary<string, object>();
|
||||||
|
_logger.LogInformation("Initializing extra data with FinancialInvoiceId: {FinancialInvoiceId}", command.FinancialInvoiceId);
|
||||||
|
command.ExtraData.Add("financialInvoiceId", command.FinancialInvoiceId);
|
||||||
|
var extraData = JsonConvert.SerializeObject(command.ExtraData);
|
||||||
|
_logger.LogInformation("Serialized extra data payload: {Payload}", extraData);
|
||||||
|
|
||||||
|
var res = await _httpClient.PostAsJsonAsync("GetToken", new
|
||||||
|
{
|
||||||
|
TerminalID = TerminalId,
|
||||||
|
Amount = command.Amount,
|
||||||
|
InvoiceID = command.TransactionId,
|
||||||
|
callbackURL = command.CallBackUrl,
|
||||||
|
payload = extraData
|
||||||
|
}, cancellationToken: cancellationToken);
|
||||||
|
_logger.LogInformation("Create payment request sent. StatusCode: {StatusCode}", res.StatusCode);
|
||||||
|
// خواندن محتوای پاسخ
|
||||||
|
var content = await res.Content.ReadAsStringAsync(cancellationToken);
|
||||||
|
_logger.LogInformation("Create payment response content: {Content}", content);
|
||||||
|
|
||||||
|
// تبدیل پاسخ JSON به آبجکت داتنت
|
||||||
|
var json = System.Text.Json.JsonDocument.Parse(content);
|
||||||
|
_logger.LogInformation("Create payment JSON parsed successfully.");
|
||||||
|
|
||||||
|
// گرفتن مقدار AccessToken
|
||||||
|
var accessToken = json.RootElement.GetProperty("Accesstoken").ToString();
|
||||||
|
var status = json.RootElement.GetProperty("Status").ToString();
|
||||||
|
_logger.LogInformation("Create payment parsed values. Status: {Status}, AccessToken: {AccessToken}", status, accessToken);
|
||||||
|
|
||||||
|
return new PaymentGatewayResponse
|
||||||
|
{
|
||||||
|
Status = status,
|
||||||
|
IsSuccess = status == "0",
|
||||||
|
Token = accessToken,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetStartPayUrl(string token)=>
|
||||||
|
$"https://sepehr.shaparak.ir/Payment/Pay?token={token}&terminalId={TerminalId}";
|
||||||
|
|
||||||
|
public async Task<PaymentGatewayResponse> Verify(VerifyPaymentGateWayRequest command, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Verify payment started. DigitalReceipt: {DigitalReceipt}", command.DigitalReceipt);
|
||||||
|
var res = await _httpClient.PostAsJsonAsync("Advice", new
|
||||||
|
{
|
||||||
|
digitalreceipt = command.DigitalReceipt,
|
||||||
|
Tid = TerminalId,
|
||||||
|
}, cancellationToken: cancellationToken);
|
||||||
|
_logger.LogInformation("Verify payment request sent. StatusCode: {StatusCode}", res.StatusCode);
|
||||||
|
// خواندن محتوای پاسخ
|
||||||
|
var content = await res.Content.ReadAsStringAsync(cancellationToken);
|
||||||
|
_logger.LogInformation("Verify payment response content: {Content}", content);
|
||||||
|
|
||||||
|
// تبدیل پاسخ JSON به آبجکت داتنت
|
||||||
|
var json = System.Text.Json.JsonDocument.Parse(content);
|
||||||
|
_logger.LogInformation("Verify payment JSON parsed successfully.");
|
||||||
|
|
||||||
|
var message = json.RootElement.GetProperty("Message").GetString();
|
||||||
|
var status = json.RootElement.GetProperty("Status").GetString();
|
||||||
|
_logger.LogInformation("Verify payment parsed values. Status: {Status}, Message: {Message}", status, message);
|
||||||
|
return new PaymentGatewayResponse
|
||||||
|
{
|
||||||
|
Status = status,
|
||||||
|
IsSuccess = status.ToLower() == "ok",
|
||||||
|
Message = message
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<PaymentGatewayResponse> CreateSandBox(CreatePaymentGatewayRequest command, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetStartPaySandBoxUrl(string transactionId)
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<WalletAmountResponse> GetWalletAmount(CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
13
0_Framework/Application/SecretKeys.cs
Normal file
13
0_Framework/Application/SecretKeys.cs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace _0_Framework.Application;
|
||||||
|
|
||||||
|
public static class SecretKeys
|
||||||
|
{
|
||||||
|
|
||||||
|
public static string ProgramManagerInternalApi => "JOb09$Ic3NJd0siLCJtYWMiOiI2%dmODJmNDV";
|
||||||
|
}
|
||||||
7
0_Framework/Application/SelectListViewModel.cs
Normal file
7
0_Framework/Application/SelectListViewModel.cs
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
namespace _0_Framework.Application;
|
||||||
|
|
||||||
|
public class SelectListViewModel
|
||||||
|
{
|
||||||
|
public long Id { get; set; }
|
||||||
|
public string Text { get; set; }
|
||||||
|
}
|
||||||
@@ -26,6 +26,79 @@ public interface ISmsService
|
|||||||
#region Mahan
|
#region Mahan
|
||||||
|
|
||||||
Task<double> GetCreditAmount();
|
Task<double> GetCreditAmount();
|
||||||
|
|
||||||
|
public Task<bool> SendInstitutionCreationVerificationLink(string number, string fullName, Guid institutionId, long contractingPartyId, long institutionContractId, string typeOfSms = null);
|
||||||
|
|
||||||
|
public Task<bool> SendInstitutionVerificationCode(string number, string code, string contractingPartyFullName,
|
||||||
|
long contractingPartyId, long institutionContractId);
|
||||||
|
|
||||||
|
SmsResult TaskReminderSms(string number, string taskCount);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region InstitutionContractSMS
|
||||||
|
/// <summary>
|
||||||
|
/// پیامک اهانه جدید
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="number"></param>
|
||||||
|
/// <param name="tamplateId"></param>
|
||||||
|
/// <param name="fullname"></param>
|
||||||
|
/// <param name="amount"></param>
|
||||||
|
/// <param name="code1"></param>
|
||||||
|
/// <param name="code2"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<(byte status, string message, int messaeId, bool isSucceded)> MonthlyBillNew(string number, int tamplateId, string fullname, string amount, string code1,
|
||||||
|
string code2);
|
||||||
|
/// <summary>
|
||||||
|
/// پیامک ماهانه قدیم
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="number"></param>
|
||||||
|
/// <param name="tamplateId"></param>
|
||||||
|
/// <param name="fullname"></param>
|
||||||
|
/// <param name="amount"></param>
|
||||||
|
/// <param name="id"></param>
|
||||||
|
/// <param name="aprove"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<(byte status, string message, int messaeId, bool isSucceded)> MonthlyBill(string number, int tamplateId, string fullname, string amount, string id, string aprove);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// پیامک مسدودی طرف حساب
|
||||||
|
/// قراردادهای قدیم
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="number"></param>
|
||||||
|
/// <param name="fullname"></param>
|
||||||
|
/// <param name="amount"></param>
|
||||||
|
/// <param name="accountType"></param>
|
||||||
|
/// <param name="id"></param>
|
||||||
|
/// <param name="aprove"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<(byte status, string message, int messaeId, bool isSucceded)> BlockMessage(string number, string fullname, string amount, string accountType, string id, string aprove);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// پیامک مسدودی طرف حساب
|
||||||
|
/// قرارداد های جدید
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="number"></param>
|
||||||
|
/// <param name="fullname"></param>
|
||||||
|
/// <param name="amount"></param>
|
||||||
|
/// <param name="code1"></param>
|
||||||
|
/// <param name="code2"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<(byte status, string message, int messaeId, bool isSucceded)> BlockMessageForElectronicContract(string number,
|
||||||
|
string fullname,
|
||||||
|
string amount, string code1, string code2);
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region AlarmMessage
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ارسال پیامک های خطا یا اعمال ارسال
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="number"></param>
|
||||||
|
/// <param name="message"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<bool> Alarm(string number, string message);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|||||||
7
0_Framework/Application/Sms/OtpResultViewModel.cs
Normal file
7
0_Framework/Application/Sms/OtpResultViewModel.cs
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
namespace _0_Framework.Application.Sms;
|
||||||
|
|
||||||
|
public class OtpResultViewModel
|
||||||
|
{
|
||||||
|
public int ExpireTimeSec { get; set; }
|
||||||
|
public int ReSendTimeSec { get; set; }
|
||||||
|
}
|
||||||
32
0_Framework/Application/Sms/SmsResult.cs
Normal file
32
0_Framework/Application/Sms/SmsResult.cs
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
namespace _0_Framework.Application.Sms;
|
||||||
|
|
||||||
|
public class SmsResult
|
||||||
|
{
|
||||||
|
public SmsResult()
|
||||||
|
{
|
||||||
|
IsSuccedded = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsSuccedded { get; set; }
|
||||||
|
public string Message { get; set; }
|
||||||
|
public byte StatusCode { get; set; }
|
||||||
|
public int MessageId { get; set; }
|
||||||
|
|
||||||
|
public SmsResult Succedded(byte statusCode, string message, int messageId)
|
||||||
|
{
|
||||||
|
IsSuccedded = true;
|
||||||
|
Message = message;
|
||||||
|
StatusCode = statusCode;
|
||||||
|
MessageId = messageId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SmsResult Failed(byte statusCode, string message, int messageId)
|
||||||
|
{
|
||||||
|
IsSuccedded = false;
|
||||||
|
Message = message;
|
||||||
|
StatusCode = statusCode;
|
||||||
|
MessageId = messageId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,337 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Runtime.InteropServices.ComTypes;
|
|
||||||
using System.Security.AccessControl;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using IPE.SmsIrClient;
|
|
||||||
using IPE.SmsIrClient.Models.Requests;
|
|
||||||
using IPE.SmsIrClient.Models.Results;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
|
||||||
using static System.Runtime.InteropServices.JavaScript.JSType;
|
|
||||||
|
|
||||||
|
|
||||||
namespace _0_Framework.Application.Sms;
|
|
||||||
|
|
||||||
public class SmsService : ISmsService
|
|
||||||
{
|
|
||||||
private readonly IConfiguration _configuration;
|
|
||||||
public SmsIr SmsIr { get; set; }
|
|
||||||
|
|
||||||
|
|
||||||
public SmsService(IConfiguration configuration)
|
|
||||||
{
|
|
||||||
_configuration = configuration;
|
|
||||||
SmsIr = new SmsIr("Og5M562igmzJRhQPnq0GdtieYdLgtfikjzxOmeQBPxJjZtyge5Klc046Lfw1mxSa");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Send(string number, string message)
|
|
||||||
{
|
|
||||||
//var token = GetToken();
|
|
||||||
//var lines = new SmsLine().GetSmsLines(token);
|
|
||||||
//if (lines == null) return;
|
|
||||||
|
|
||||||
//var line = lines.SMSLines.Last().LineNumber.ToString();
|
|
||||||
//var data = new MessageSendObject
|
|
||||||
//{
|
|
||||||
// Messages = new List<string>
|
|
||||||
// {message}.ToArray(),
|
|
||||||
// MobileNumbers = new List<string> {number}.ToArray(),
|
|
||||||
// LineNumber = line,
|
|
||||||
// SendDateTime = DateTime.Now,
|
|
||||||
// CanContinueInCaseOfError = true
|
|
||||||
//};
|
|
||||||
//var messageSendResponseObject =
|
|
||||||
// new MessageSend().Send(token, data);
|
|
||||||
|
|
||||||
//if (messageSendResponseObject.IsSuccessful) return;
|
|
||||||
|
|
||||||
//line = lines.SMSLines.First().LineNumber.ToString();
|
|
||||||
//data.LineNumber = line;
|
|
||||||
//new MessageSend().Send(token, data);
|
|
||||||
}
|
|
||||||
public bool VerifySend(string number, string message)
|
|
||||||
{
|
|
||||||
|
|
||||||
SmsIr smsIr = new SmsIr("Og5M562igmzJRhQPnq0GdtieYdLgtfikjzxOmeQBPxJjZtyge5Klc046Lfw1mxSa");
|
|
||||||
|
|
||||||
//var bulkSendResult = smsIr.BulkSendAsync(95007079000006, "your text message", new string[] { "9120000000" });
|
|
||||||
|
|
||||||
var verificationSendResult = smsIr.VerifySendAsync(number, 768382, new VerifySendParameter[] { new VerifySendParameter("VerificationCode", message) });
|
|
||||||
Thread.Sleep(2000);
|
|
||||||
if (verificationSendResult.IsCompletedSuccessfully)
|
|
||||||
{
|
|
||||||
|
|
||||||
var resStartStatus = verificationSendResult.Result;
|
|
||||||
var b = resStartStatus.Status;
|
|
||||||
var resResult = verificationSendResult.Status;
|
|
||||||
var a = verificationSendResult.IsCompleted;
|
|
||||||
var reseExceptiont = verificationSendResult.Exception;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
var resStartStatus = verificationSendResult.Status;
|
|
||||||
var resResult = verificationSendResult.Status;
|
|
||||||
var reseExceptiont = verificationSendResult.Exception;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool LoginSend(string number, string message)
|
|
||||||
{
|
|
||||||
SmsIr smsIr = new SmsIr("Og5M562igmzJRhQPnq0GdtieYdLgtfikjzxOmeQBPxJjZtyge5Klc046Lfw1mxSa");
|
|
||||||
|
|
||||||
//var bulkSendResult = smsIr.BulkSendAsync(95007079000006, "your text message", new string[] { "9120000000" });
|
|
||||||
|
|
||||||
var verificationSendResult = smsIr.VerifySendAsync(number, 635330, new VerifySendParameter[] { new VerifySendParameter("LOGINCODE", message) });
|
|
||||||
Thread.Sleep(2000);
|
|
||||||
if (verificationSendResult.IsCompletedSuccessfully)
|
|
||||||
{
|
|
||||||
|
|
||||||
var resStartStatus = verificationSendResult.Result;
|
|
||||||
var b = resStartStatus.Status;
|
|
||||||
var resResult = verificationSendResult.Status;
|
|
||||||
var a = verificationSendResult.IsCompleted;
|
|
||||||
var reseExceptiont = verificationSendResult.Exception;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
var resStartStatus = verificationSendResult.Status;
|
|
||||||
var resResult = verificationSendResult.Status;
|
|
||||||
var reseExceptiont = verificationSendResult.Exception;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<SentSmsViewModel> SendVerifyCodeToClient(string number, string code)
|
|
||||||
{
|
|
||||||
SmsIr smsIr = new SmsIr("Og5M562igmzJRhQPnq0GdtieYdLgtfikjzxOmeQBPxJjZtyge5Klc046Lfw1mxSa");
|
|
||||||
var result = new SentSmsViewModel();
|
|
||||||
//var bulkSendResult = smsIr.BulkSendAsync(95007079000006, "your text message", new string[] { "9120000000" });
|
|
||||||
|
|
||||||
var sendResult = await smsIr.VerifySendAsync(number, 768382, new VerifySendParameter[] { new VerifySendParameter("VerificationCode", code) });
|
|
||||||
Thread.Sleep(2000);
|
|
||||||
|
|
||||||
if (sendResult.Message == "موفق")
|
|
||||||
{
|
|
||||||
var status = sendResult.Status;
|
|
||||||
var message = sendResult.Message;
|
|
||||||
var messaeId = sendResult.Data.MessageId;
|
|
||||||
return result.Succedded(status, message, messaeId);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var status = sendResult.Status;
|
|
||||||
var message = sendResult.Message;
|
|
||||||
var messaeId = sendResult.Data.MessageId;
|
|
||||||
return result.Failed(status, message, messaeId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool SendAccountsInfo(string number, string fullName, string userName)
|
|
||||||
{
|
|
||||||
|
|
||||||
var checkLength = fullName.Length;
|
|
||||||
if (checkLength > 25)
|
|
||||||
fullName = fullName.Substring(0, 24);
|
|
||||||
SmsIr smsIr = new SmsIr("Og5M562igmzJRhQPnq0GdtieYdLgtfikjzxOmeQBPxJjZtyge5Klc046Lfw1mxSa");
|
|
||||||
|
|
||||||
var sendResult = smsIr.VerifySendAsync(number, 725814, new VerifySendParameter[] { new VerifySendParameter("FULLNAME", fullName), new VerifySendParameter("USERNAME", userName), new VerifySendParameter("PASSWORD", userName) });
|
|
||||||
|
|
||||||
|
|
||||||
Console.WriteLine(userName + " - " + sendResult.Result.Status);
|
|
||||||
if (sendResult.IsCompletedSuccessfully)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<ApiResultViewModel> GetByMessageId(int messId)
|
|
||||||
{
|
|
||||||
|
|
||||||
SmsIr smsIr = new SmsIr("Og5M562igmzJRhQPnq0GdtieYdLgtfikjzxOmeQBPxJjZtyge5Klc046Lfw1mxSa");
|
|
||||||
var response = await smsIr.GetReportAsync(messId);
|
|
||||||
MessageReportResult messages = response.Data;
|
|
||||||
|
|
||||||
var appendData = new ApiResultViewModel()
|
|
||||||
{
|
|
||||||
MessageId = messages.MessageId,
|
|
||||||
LineNumber = messages.LineNumber,
|
|
||||||
Mobile = messages.Mobile,
|
|
||||||
MessageText = messages.MessageText,
|
|
||||||
SendUnixTime = UnixTimeStampToDateTime(messages.SendDateTime),
|
|
||||||
DeliveryState = DeliveryStatus(messages.DeliveryState),
|
|
||||||
DeliveryUnixTime = UnixTimeStampToDateTime(messages.DeliveryDateTime),
|
|
||||||
DeliveryColor = DeliveryColorStatus(messages.DeliveryState),
|
|
||||||
};
|
|
||||||
return appendData;
|
|
||||||
}
|
|
||||||
public async Task<List<ApiResultViewModel>> GetApiResult(string startDate, string endDate)
|
|
||||||
{
|
|
||||||
var st = new DateTime(2024, 6, 2);
|
|
||||||
var ed = new DateTime(2024, 7, 1);
|
|
||||||
if (!string.IsNullOrWhiteSpace(startDate) && startDate.Length == 10)
|
|
||||||
{
|
|
||||||
st = startDate.ToGeorgianDateTime();
|
|
||||||
}
|
|
||||||
if (!string.IsNullOrWhiteSpace(endDate) && endDate.Length == 10)
|
|
||||||
{
|
|
||||||
ed = endDate.ToGeorgianDateTime();
|
|
||||||
}
|
|
||||||
var res = new List<ApiResultViewModel>();
|
|
||||||
Int32 unixTimestamp = (int)st.Subtract(new DateTime(1970,1,1)).TotalSeconds;
|
|
||||||
Int32 unixTimestamp2 = (int)ed.Subtract(new DateTime(1970, 1, 1)).TotalSeconds;
|
|
||||||
// int? fromDateUnixTime = null; // unix time - for instance: 1700598600
|
|
||||||
//int? toDateUnixTime = null; // unix time - for instance: 1703190600
|
|
||||||
int pageNumber = 2;
|
|
||||||
int pageSize = 100; // max: 100
|
|
||||||
SmsIr smsIr = new SmsIr("Og5M562igmzJRhQPnq0GdtieYdLgtfikjzxOmeQBPxJjZtyge5Klc046Lfw1mxSa");
|
|
||||||
var response = await smsIr.GetArchivedReportAsync(pageNumber, pageSize, unixTimestamp, unixTimestamp2);
|
|
||||||
|
|
||||||
|
|
||||||
MessageReportResult[] messages = response.Data;
|
|
||||||
foreach (var message in messages)
|
|
||||||
{
|
|
||||||
var appendData = new ApiResultViewModel()
|
|
||||||
{
|
|
||||||
MessageId = message.MessageId,
|
|
||||||
LineNumber = message.LineNumber,
|
|
||||||
Mobile = message.Mobile,
|
|
||||||
MessageText = message.MessageText,
|
|
||||||
SendUnixTime = UnixTimeStampToDateTime(message.SendDateTime),
|
|
||||||
DeliveryState = DeliveryStatus(message.DeliveryState),
|
|
||||||
DeliveryUnixTime = UnixTimeStampToDateTime(message.DeliveryDateTime),
|
|
||||||
DeliveryColor = DeliveryColorStatus(message.DeliveryState),
|
|
||||||
};
|
|
||||||
res.Add(appendData);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string DeliveryStatus(byte? dv)
|
|
||||||
{
|
|
||||||
string mess = "";
|
|
||||||
switch (dv)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
mess = "رسیده به گوشی";
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
mess = "نرسیده به گوشی";
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
mess = "پردازش در مخابرات";
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
mess = "نرسیده به مخابرات";
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
mess = "سیده به مخابرات";
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
mess = "خطا";
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
mess = "لیست سیاه";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
mess="";
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return mess;
|
|
||||||
}
|
|
||||||
public string DeliveryColorStatus(byte? dv)
|
|
||||||
{
|
|
||||||
string mess = "";
|
|
||||||
switch (dv)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
mess = "successSend";
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
mess = "errSend";
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
mess = "pSend";
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
mess = "noSend";
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
mess = "itcSend";
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
mess = "redSend";
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
mess = "blockSend";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
mess = "";
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return mess;
|
|
||||||
}
|
|
||||||
public string UnixTimeStampToDateTime(int? unixTimeStamp)
|
|
||||||
{
|
|
||||||
if (unixTimeStamp != null)
|
|
||||||
{
|
|
||||||
// Unix timestamp is seconds past epoch
|
|
||||||
DateTime dateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
|
|
||||||
dateTime = dateTime.AddSeconds(Convert.ToDouble(unixTimeStamp)).ToLocalTime();
|
|
||||||
var time = dateTime.ToFarsiFull();
|
|
||||||
return time;
|
|
||||||
}
|
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
private string GetToken()
|
|
||||||
{
|
|
||||||
return "";
|
|
||||||
//var smsSecrets = _configuration.GetSection("SmsSecrets");
|
|
||||||
//var tokenService = new Token();
|
|
||||||
//return tokenService.GetToken("x-api-key", "Og5M562igmzJRhQPnq0GdtieYdLgtfikjzxOmeQBPxJjZtyge5Klc046Lfw1mxSa");
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Mahan
|
|
||||||
|
|
||||||
public async Task<double> GetCreditAmount()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var credit = await SmsIr.GetCreditAsync();
|
|
||||||
return (double)credit.Data;
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
@@ -30,12 +30,24 @@ public static class StaticWorkshopAccounts
|
|||||||
/// 380 - افروز نظری
|
/// 380 - افروز نظری
|
||||||
/// 381 - مهدی قربانی
|
/// 381 - مهدی قربانی
|
||||||
/// 392 - عمار حسن دوست
|
/// 392 - عمار حسن دوست
|
||||||
|
/// 20 - سمیرا الهی نیا
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static List<long> StaticAccountIds = [2, 3, 380, 381, 392];
|
public static List<long> StaticAccountIds = [2, 3, 380, 381, 392, 20, 476];
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// این تاریخ در جدول اکانت لفت ورک به این معنیست
|
/// این تاریخ در جدول اکانت لفت ورک به این معنیست
|
||||||
/// که کاربر همچنان به کارگاه دسترسی دارد
|
/// که کاربر همچنان به کارگاه دسترسی دارد
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static DateTime ContinuesWorkingDate = new DateTime(2150, 1, 1);
|
public static DateTime ContinuesWorkingDate = new DateTime(2150, 1, 1);
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// لیستی آی دی نقش هایی که مسئول بیمه کارگاه هستند
|
||||||
|
/// 7 : بیمه ارشد
|
||||||
|
/// 8 : بیمه ساده
|
||||||
|
/// </summary>
|
||||||
|
public static List<long> InsuranceAccountsRoleIds = [7, 8];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -385,11 +385,27 @@
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public const int SetWorkshopWorkingHoursPermissionCode = 10606;
|
public const int SetWorkshopWorkingHoursPermissionCode = 10606;
|
||||||
|
|
||||||
|
#region حساب کاربری دوربین
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// تنظیمات حساب کاربری دوربین
|
/// تنظیمات حساب کاربری دوربین
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const int CameraAccountSettingsPermissionCode = 10607;
|
public const int CameraAccountSettingsPermissionCode = 10607;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// فعال/غیرفعال اکانت دوربین
|
||||||
|
/// </summary>
|
||||||
|
public const int CameraAccountActivationBtnPermissionCode = 1060701;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ویرایش اکانت دوربین
|
||||||
|
/// </summary>
|
||||||
|
public const int CameraAccountEditPermissionCode = 1060702;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region کارپوشه
|
#region کارپوشه
|
||||||
@@ -744,6 +760,22 @@
|
|||||||
Code = CameraAccountSettingsPermissionCode,
|
Code = CameraAccountSettingsPermissionCode,
|
||||||
ParentId = RollCallOperationsPermissionCode
|
ParentId = RollCallOperationsPermissionCode
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public static SubAccountPermissionDto CameraAccountActivationBtn { get; } = new()
|
||||||
|
{
|
||||||
|
Id = CameraAccountActivationBtnPermissionCode,
|
||||||
|
Name = "فعال/غیرفعال حساب کاربری دوربین",
|
||||||
|
Code = CameraAccountActivationBtnPermissionCode,
|
||||||
|
ParentId = CameraAccountSettingsPermissionCode
|
||||||
|
};
|
||||||
|
|
||||||
|
public static SubAccountPermissionDto CameraAccountEdit { get; } = new()
|
||||||
|
{
|
||||||
|
Id = CameraAccountEditPermissionCode,
|
||||||
|
Name = "ویراش حساب کاربری دوربین",
|
||||||
|
Code = CameraAccountEditPermissionCode,
|
||||||
|
ParentId = CameraAccountSettingsPermissionCode
|
||||||
|
};
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region کارپوشه,ParentId = WorkFlowOperationsPermissionCode
|
#region کارپوشه,ParentId = WorkFlowOperationsPermissionCode
|
||||||
|
|||||||
@@ -477,26 +477,42 @@ public static class Tools
|
|||||||
string bb = string.Empty;
|
string bb = string.Empty;
|
||||||
bool isNegative = false;
|
bool isNegative = false;
|
||||||
|
|
||||||
for (int x = 0; x < myMoney.Length; x++)
|
try
|
||||||
{
|
{
|
||||||
if (char.IsDigit(myMoney[x]))
|
if (!string.IsNullOrWhiteSpace(myMoney))
|
||||||
{
|
{
|
||||||
bb += myMoney[x];
|
for (int x = 0; x < myMoney.Length; x++)
|
||||||
}
|
{
|
||||||
else if (myMoney[x] == '-' && bb.Length == 0)
|
if (char.IsDigit(myMoney[x]))
|
||||||
{
|
{
|
||||||
// اگر علامت منفی قبل از اولین عدد آمد، در نظر بگیر
|
bb += myMoney[x];
|
||||||
isNegative = true;
|
}
|
||||||
}
|
else if (myMoney[x] == '-' && bb.Length == 0)
|
||||||
}
|
{
|
||||||
|
// اگر علامت منفی قبل از اولین عدد آمد، در نظر بگیر
|
||||||
|
isNegative = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (bb.Length > 0)
|
if (bb.Length > 0)
|
||||||
{
|
{
|
||||||
double res = double.Parse(bb);
|
double res = double.Parse(bb);
|
||||||
return isNegative ? -res : res;
|
return isNegative ? -res : res;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
catch (Exception)
|
||||||
{
|
{
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -897,7 +913,15 @@ public static class Tools
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
numbers = Convert.ToInt32(num);
|
try
|
||||||
|
{
|
||||||
|
numbers = Convert.ToInt32(num);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return numbers;
|
return numbers;
|
||||||
}
|
}
|
||||||
public static string ToFarsiMonthByNumber(this string value)
|
public static string ToFarsiMonthByNumber(this string value)
|
||||||
@@ -1413,6 +1437,73 @@ public static class Tools
|
|||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// چک میکند که در دو شیفت استاتیک تداخل زمانی وجود دارد یا خیر
|
||||||
|
/// چک میکند که آیا ساعات وارد شده ولید هستند یا خیر
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="start1"></param>
|
||||||
|
/// <param name="end1"></param>
|
||||||
|
/// <param name="start2"></param>
|
||||||
|
/// <param name="end2"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static bool InterferenceTime(string start1, string end1, string start2, string end2)
|
||||||
|
{
|
||||||
|
if (!CheckValidHm(start1))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (!CheckValidHm(end1))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (!CheckValidHm(start2))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (!CheckValidHm(end2))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
//اگه دو شیفت نبود
|
||||||
|
if (string.IsNullOrWhiteSpace(start1) || string.IsNullOrWhiteSpace(start2))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var start1Gr = Convert.ToDateTime(start1);
|
||||||
|
var end1Gr = Convert.ToDateTime(end1);
|
||||||
|
|
||||||
|
if (end1Gr < start1Gr)
|
||||||
|
end1Gr = end1Gr.AddDays(1);
|
||||||
|
|
||||||
|
var start2Gr = Convert.ToDateTime(start2);
|
||||||
|
var end2Gr = Convert.ToDateTime(end2);
|
||||||
|
|
||||||
|
|
||||||
|
start2Gr = new DateTime(end1Gr.Year, end1Gr.Month, end1Gr.Day, start2Gr.Hour, start2Gr.Minute,
|
||||||
|
start2Gr.Second);
|
||||||
|
|
||||||
|
|
||||||
|
end2Gr = new DateTime(end1Gr.Year, end1Gr.Month, end1Gr.Day, end2Gr.Hour, end2Gr.Minute,
|
||||||
|
end2Gr.Second);
|
||||||
|
if (end2Gr < start2Gr)
|
||||||
|
end2Gr = end2Gr.AddDays(1);
|
||||||
|
|
||||||
|
var diff = (end1Gr - start1Gr).Add((end2Gr - start2Gr));
|
||||||
|
if (diff > new TimeSpan(24,0,0))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (start2Gr <= end1Gr)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
public static DateTime FindFirstDayOfMonthGr(this DateTime date)
|
public static DateTime FindFirstDayOfMonthGr(this DateTime date)
|
||||||
{
|
{
|
||||||
var pc = new PersianCalendar();
|
var pc = new PersianCalendar();
|
||||||
@@ -1421,6 +1512,14 @@ public static class Tools
|
|||||||
#region Mahan
|
#region Mahan
|
||||||
|
|
||||||
|
|
||||||
|
public static bool IsvalidIban(this string iban)
|
||||||
|
{
|
||||||
|
return Regex.IsMatch(iban, @"^IR[0-9]{24}$");
|
||||||
|
}
|
||||||
|
public static bool IsValidCardNumber(this string cardNumber)
|
||||||
|
{
|
||||||
|
return Regex.IsMatch(cardNumber, @"^[0-9]{16}$");
|
||||||
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// این متد حروف عربی را به فارسی در میاورد. مثال: علي را به علی تبدیل میکند
|
/// این متد حروف عربی را به فارسی در میاورد. مثال: علي را به علی تبدیل میکند
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ public class UidBasicInformation
|
|||||||
{
|
{
|
||||||
"GENDER_MALE" => Application.Gender.Male,
|
"GENDER_MALE" => Application.Gender.Male,
|
||||||
"GENDER_FEMALE" => Application.Gender.Female,
|
"GENDER_FEMALE" => Application.Gender.Female,
|
||||||
_ => throw new ArgumentOutOfRangeException()
|
_ => Application.Gender.None
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
public record IdentificationInformation(string NationalId, string BirthDate, string ShenasnameSeri, string ShenasnameSerial, string ShenasnamehNumber);
|
public record IdentificationInformation(string NationalId, string BirthDate, string ShenasnameSeri, string ShenasnameSerial, string ShenasnamehNumber);
|
||||||
@@ -110,6 +110,53 @@ public interface IUidService
|
|||||||
{
|
{
|
||||||
Task<PersonalInfoResponse> GetPersonalInfo(string nationalCode , string birthDate);
|
Task<PersonalInfoResponse> GetPersonalInfo(string nationalCode , string birthDate);
|
||||||
Task<MatchMobileWithNationalCodeResponse> IsMachPhoneWithNationalCode(string nationalCode , string phoneNumber);
|
Task<MatchMobileWithNationalCodeResponse> IsMachPhoneWithNationalCode(string nationalCode , string phoneNumber);
|
||||||
|
Task<IbanInquiryResponse> IbanInquiry (string iban);
|
||||||
|
Task<AccountToIbanResponse> AccountToIban(string accountNumber, UidBanks bank);
|
||||||
|
Task<CardToNumberResponse> CardToIban(string cardNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CardToNumberResponse:UidBaseResponse
|
||||||
|
{
|
||||||
|
public string Iban { get; set; }
|
||||||
|
public string CardNumber { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AccountToIbanResponse:UidBaseResponse
|
||||||
|
{
|
||||||
|
public string Iban { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class IbanInquiryResponse:UidBaseResponse
|
||||||
|
{
|
||||||
|
public IbanInquiryAccountBasicInformation AccountBasicInformation { get; set; }
|
||||||
|
[JsonProperty("owners")]
|
||||||
|
public List<IbanInquiryOwner> Owners { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class IbanInquiryAccountBasicInformation
|
||||||
|
{
|
||||||
|
public string Iban { get; set; }
|
||||||
|
public string AccountNumber { get; set; }
|
||||||
|
public IbanInquiryBankInformation BankInformation { get; set; }
|
||||||
|
public string AccountStatus { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class IbanInquiryBankInformation
|
||||||
|
{
|
||||||
|
public string BankName { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class IbanInquiryOwner
|
||||||
|
{
|
||||||
|
[JsonProperty("firstName")]
|
||||||
|
public string FirstName { get; set; }
|
||||||
|
[JsonProperty("lastName")]
|
||||||
|
public string LastName { get; set; }
|
||||||
|
[JsonProperty("nationalIdentifier")]
|
||||||
|
public string NationalIdentifier { get; set; }
|
||||||
|
[JsonProperty("customerType")]
|
||||||
|
public string CustomerType { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class MatchMobileWithNationalCodeResponse
|
public class MatchMobileWithNationalCodeResponse
|
||||||
@@ -118,4 +165,7 @@ public class MatchMobileWithNationalCodeResponse
|
|||||||
|
|
||||||
public ResponseContext ResponseContext { get; set; }
|
public ResponseContext ResponseContext { get; set; }
|
||||||
}
|
}
|
||||||
|
public class UidBaseResponse
|
||||||
|
{
|
||||||
|
public ResponseContext ResponseContext { get; set; }
|
||||||
|
}
|
||||||
|
|||||||
117
0_Framework/Application/UID/UidBanks.cs
Normal file
117
0_Framework/Application/UID/UidBanks.cs
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
using System.ComponentModel;
|
||||||
|
|
||||||
|
namespace _0_Framework.Application.UID;
|
||||||
|
|
||||||
|
public enum UidBanks
|
||||||
|
{
|
||||||
|
[Description("بانک دی")]
|
||||||
|
BANK_DEY = 66,
|
||||||
|
|
||||||
|
[Description("بانک سپه")]
|
||||||
|
BANK_SEPAH = 15,
|
||||||
|
|
||||||
|
[Description("بانک شهر")]
|
||||||
|
BANK_SHAHR = 61,
|
||||||
|
|
||||||
|
[Description("بانک ملت")]
|
||||||
|
BANK_MELAT = 12,
|
||||||
|
|
||||||
|
[Description("بانک ملی")]
|
||||||
|
BANK_MELLI = 17,
|
||||||
|
|
||||||
|
[Description("بانک رفاه کارگران")]
|
||||||
|
BANK_REFAH = 13,
|
||||||
|
|
||||||
|
[Description("بانک سینا")]
|
||||||
|
BANK_SINA = 59,
|
||||||
|
|
||||||
|
[Description("بانک مسکن")]
|
||||||
|
BANK_MASKAN = 14,
|
||||||
|
|
||||||
|
[Description("بانک آینده")]
|
||||||
|
BANK_AYANDEH = 62,
|
||||||
|
|
||||||
|
[Description("بانک انصار")]
|
||||||
|
BANK_ANSAR = 63,
|
||||||
|
|
||||||
|
[Description("بانک تجارت")]
|
||||||
|
BANK_TEJARAT = 18,
|
||||||
|
|
||||||
|
[Description("بانک رسالت")]
|
||||||
|
BANK_RESALAT = 70,
|
||||||
|
|
||||||
|
[Description("بانک سامان")]
|
||||||
|
BANK_SAMAN = 56,
|
||||||
|
|
||||||
|
[Description("بانک مرکزی")]
|
||||||
|
BANK_MARKAZI = 10,
|
||||||
|
|
||||||
|
[Description("بانک سرمایه")]
|
||||||
|
BANK_SARMAYEH = 58,
|
||||||
|
|
||||||
|
[Description("بانک صادرات")]
|
||||||
|
BANK_SADERAT = 19,
|
||||||
|
|
||||||
|
[Description("بانک قوامین")]
|
||||||
|
BANK_GHAVAMIN = 52,
|
||||||
|
|
||||||
|
[Description("بانک پارسیان")]
|
||||||
|
BANK_PARSIAN = 54,
|
||||||
|
|
||||||
|
[Description("بانک کشاورزی")]
|
||||||
|
BANK_KESHAVARZI = 16,
|
||||||
|
|
||||||
|
[Description("بانک گردشگری")]
|
||||||
|
BANK_GARDESHGARI = 64,
|
||||||
|
|
||||||
|
[Description("پست بانک")]
|
||||||
|
BANK_POST_BANK = 21,
|
||||||
|
|
||||||
|
[Description("بانک پاسارگاد")]
|
||||||
|
BANK_PASARGAD = 57,
|
||||||
|
|
||||||
|
[Description("بانک کارآفرین")]
|
||||||
|
BANK_KARAFARIN = 53,
|
||||||
|
|
||||||
|
[Description("بانک خاورمیانه")]
|
||||||
|
BANK_KHAVARMIANEH = 78,
|
||||||
|
|
||||||
|
[Description("بانک ایران زمین")]
|
||||||
|
BANK_IRAN_ZAMIN = 69,
|
||||||
|
|
||||||
|
[Description("بانک مهر اقتصاد")]
|
||||||
|
BANK_MEHR_EQTESAD = 79,
|
||||||
|
|
||||||
|
[Description("بانک صنعت و معدن")]
|
||||||
|
BANK_SANAT_MADAN = 11,
|
||||||
|
|
||||||
|
[Description("بانک اقتصاد نوین")]
|
||||||
|
BANK_EGHTESAD_NOVIN = 55,
|
||||||
|
|
||||||
|
[Description("بانک توسعه تعاون")]
|
||||||
|
BANK_TOSSE_TAAVON = 22,
|
||||||
|
|
||||||
|
[Description("بانک توسعه صادرات")]
|
||||||
|
BANK_TOSSE_SADERAT = 20,
|
||||||
|
|
||||||
|
[Description("بانک ایران و ونزوئلا")]
|
||||||
|
BANK_IRAN_VENEZUELA = 95,
|
||||||
|
|
||||||
|
[Description("بانک حکمت ایرانیان")]
|
||||||
|
BANK_HEKMAT_IRANIAN = 65,
|
||||||
|
|
||||||
|
[Description("بانک قرض الحسنه مهر")]
|
||||||
|
BANK_GHARZOLHASANEH_MEHR = 60,
|
||||||
|
|
||||||
|
[Description("موسسه مالی و اعتباری ملل")]
|
||||||
|
BANK_MOASSASE_MELLAL = 75,
|
||||||
|
|
||||||
|
[Description("موسسه مالی و اعتباری نور")]
|
||||||
|
BANK_MOASSASE_NOOR = 80,
|
||||||
|
|
||||||
|
[Description("موسسه مالی و اعتباری کوثر")]
|
||||||
|
BANK_MOASSASE_KOSAR = 73,
|
||||||
|
|
||||||
|
[Description("موسسه مالی و اعتباری توسعه")]
|
||||||
|
BANK_MOASSASE_TOSSE = 51
|
||||||
|
}
|
||||||
27
0_Framework/Application/UID/UidBanksExtension.cs
Normal file
27
0_Framework/Application/UID/UidBanksExtension.cs
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
using System;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace _0_Framework.Application.UID
|
||||||
|
{
|
||||||
|
public static class UidBanksExtension
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// دریافت نام فارسی بانک
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bank">بانک</param>
|
||||||
|
/// <returns>نام فارسی بانک</returns>
|
||||||
|
public static string GetPersianName(this UidBanks bank)
|
||||||
|
{
|
||||||
|
var fieldInfo = bank.GetType().GetField(bank.ToString());
|
||||||
|
|
||||||
|
if (fieldInfo == null)
|
||||||
|
return string.Empty;
|
||||||
|
|
||||||
|
var attribute = (DescriptionAttribute)Attribute.GetCustomAttribute(
|
||||||
|
fieldInfo, typeof(DescriptionAttribute));
|
||||||
|
|
||||||
|
return attribute?.Description ?? bank.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Net.Http.Json;
|
|
||||||
using System.Text;
|
|
||||||
using System.Text.Json;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace _0_Framework.Application.UID;
|
|
||||||
|
|
||||||
public class UidService : IUidService
|
|
||||||
{
|
|
||||||
private readonly HttpClient _httpClient;
|
|
||||||
private const string BaseUrl= "https://json-api.uid.ir/api/inquiry/";
|
|
||||||
|
|
||||||
public UidService()
|
|
||||||
{
|
|
||||||
_httpClient = new HttpClient()
|
|
||||||
{
|
|
||||||
BaseAddress = new Uri(BaseUrl)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<PersonalInfoResponse> GetPersonalInfo(string nationalCode, string birthDate)
|
|
||||||
{
|
|
||||||
var request = new PersonalInfoRequest
|
|
||||||
{
|
|
||||||
BirthDate = birthDate ,
|
|
||||||
NationalId = nationalCode,
|
|
||||||
RequestContext = new UidRequestContext()
|
|
||||||
};
|
|
||||||
var json = JsonConvert.SerializeObject(request);
|
|
||||||
var contentType = new StringContent(json, Encoding.UTF8, "application/json");
|
|
||||||
|
|
||||||
var requestResult = await _httpClient.PostAsync("person/v2", contentType);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (!requestResult.IsSuccessStatusCode)
|
|
||||||
return null;
|
|
||||||
var responseResult = await requestResult.Content.ReadFromJsonAsync<PersonalInfoResponse>();
|
|
||||||
if (responseResult.BasicInformation != null)
|
|
||||||
{
|
|
||||||
responseResult.BasicInformation.FirstName = responseResult.BasicInformation.FirstName?.ToPersian();
|
|
||||||
responseResult.BasicInformation.LastName = responseResult.BasicInformation.LastName?.ToPersian();
|
|
||||||
responseResult.BasicInformation.FatherName = responseResult.BasicInformation.FatherName?.ToPersian();
|
|
||||||
}
|
|
||||||
|
|
||||||
return responseResult;
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public async Task<MatchMobileWithNationalCodeResponse> IsMachPhoneWithNationalCode(string nationalCode, string phoneNumber)
|
|
||||||
{
|
|
||||||
var request = new PersonalInfoRequest
|
|
||||||
{
|
|
||||||
MobileNumber = phoneNumber,
|
|
||||||
NationalId = nationalCode,
|
|
||||||
RequestContext = new UidRequestContext()
|
|
||||||
};
|
|
||||||
var json = JsonConvert.SerializeObject(request);
|
|
||||||
var contentType = new StringContent(json, Encoding.UTF8, "application/json");
|
|
||||||
|
|
||||||
var requestResult = await _httpClient.PostAsync("mobile/owner/v2", contentType);
|
|
||||||
if (!requestResult.IsSuccessStatusCode)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
var responseResult = await requestResult.Content.ReadFromJsonAsync<MatchMobileWithNationalCodeResponse>();
|
|
||||||
return responseResult;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using _0_Framework.Domain.CustomizeCheckoutShared.Enums;
|
using _0_Framework.Domain.CustomizeCheckoutShared.Enums;
|
||||||
using _0_Framework.Domain.CustomizeCheckoutShared.ValueObjects;
|
using _0_Framework.Domain.CustomizeCheckoutShared.ValueObjects;
|
||||||
using Microsoft.EntityFrameworkCore.Design.Internal;
|
using Microsoft.EntityFrameworkCore.Design.Internal;
|
||||||
@@ -12,8 +14,7 @@ public class BaseCustomizeEntity : EntityBase
|
|||||||
}
|
}
|
||||||
public BaseCustomizeEntity(FridayPay fridayPay, OverTimePay overTimePay,
|
public BaseCustomizeEntity(FridayPay fridayPay, OverTimePay overTimePay,
|
||||||
BaseYearsPay baseYearsPay, BonusesPay bonusesPay, NightWorkPay nightWorkPay, MarriedAllowance marriedAllowance, ShiftPay shiftPay,
|
BaseYearsPay baseYearsPay, BonusesPay bonusesPay, NightWorkPay nightWorkPay, MarriedAllowance marriedAllowance, ShiftPay shiftPay,
|
||||||
FamilyAllowance familyAllowance, LeavePay leavePay, InsuranceDeduction insuranceDeduction, FineAbsenceDeduction fineAbsenceDeduction, LateToWork lateToWork, EarlyExit earlyExit,
|
FamilyAllowance familyAllowance, LeavePay leavePay, InsuranceDeduction insuranceDeduction, FineAbsenceDeduction fineAbsenceDeduction, LateToWork lateToWork, EarlyExit earlyExit, HolidayWork holidayWork, BreakTime breakTime,int leavePermittedDays,List<WeeklyOffDay> weeklyOffDays)
|
||||||
FridayWork fridayWork, HolidayWork holidayWork, BreakTime breakTime,int leavePermittedDays)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
FridayPay = fridayPay;
|
FridayPay = fridayPay;
|
||||||
@@ -29,10 +30,10 @@ public class BaseCustomizeEntity : EntityBase
|
|||||||
FineAbsenceDeduction = fineAbsenceDeduction;
|
FineAbsenceDeduction = fineAbsenceDeduction;
|
||||||
LateToWork = lateToWork;
|
LateToWork = lateToWork;
|
||||||
EarlyExit = earlyExit;
|
EarlyExit = earlyExit;
|
||||||
FridayWork = fridayWork;
|
|
||||||
HolidayWork = holidayWork;
|
HolidayWork = holidayWork;
|
||||||
BreakTime = breakTime;
|
BreakTime = breakTime;
|
||||||
LeavePermittedDays = leavePermittedDays;
|
LeavePermittedDays = leavePermittedDays;
|
||||||
|
WeeklyOffDays = weeklyOffDays.Select(x=> new WeeklyOffDay(x.DayOfWeek)).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -117,4 +118,28 @@ public class BaseCustomizeEntity : EntityBase
|
|||||||
|
|
||||||
|
|
||||||
public BreakTime BreakTime { get; protected set; }
|
public BreakTime BreakTime { get; protected set; }
|
||||||
|
|
||||||
|
public List<WeeklyOffDay> WeeklyOffDays { get; set; } = [];
|
||||||
|
|
||||||
|
public void FridayWorkToWeeklyDayOfWeek()
|
||||||
|
{
|
||||||
|
if (FridayWork == FridayWork.Default && !WeeklyOffDays.Any(x => x.DayOfWeek == DayOfWeek.Friday))
|
||||||
|
{
|
||||||
|
WeeklyOffDays.Add(new WeeklyOffDay(DayOfWeek.Friday));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class WeeklyOffDay
|
||||||
|
{
|
||||||
|
public WeeklyOffDay(DayOfWeek dayOfWeek)
|
||||||
|
{
|
||||||
|
DayOfWeek = dayOfWeek;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long Id { get; set; }
|
||||||
|
public DayOfWeek DayOfWeek { get; set; }
|
||||||
|
public long ParentId { get; set; }
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
namespace _0_Framework.Application.Enums
|
||||||
|
{
|
||||||
|
public class CheckoutDynamicDeductionItem
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
public int Count { get; set; }
|
||||||
|
public string Amount { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ using System.Linq;
|
|||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage;
|
||||||
|
|
||||||
namespace _0_Framework.Domain;
|
namespace _0_Framework.Domain;
|
||||||
|
|
||||||
@@ -17,4 +18,6 @@ public interface IRepository<TKey, T> where T:class
|
|||||||
bool Exists(Expression<Func<T, bool>> expression);
|
bool Exists(Expression<Func<T, bool>> expression);
|
||||||
void SaveChanges();
|
void SaveChanges();
|
||||||
Task SaveChangesAsync();
|
Task SaveChangesAsync();
|
||||||
|
Task<IDbContextTransaction> BeginTransactionAsync();
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -17,7 +17,7 @@ public class ExcelGenerator
|
|||||||
{
|
{
|
||||||
public ExcelGenerator()
|
public ExcelGenerator()
|
||||||
{
|
{
|
||||||
ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
|
OfficeOpenXml.ExcelPackage.License.SetNonCommercialOrganization("Gozareshgir Noncommercial organization");
|
||||||
}
|
}
|
||||||
public static byte[] GenerateExcel<T>(List<T> obj, string date = "") where T : class
|
public static byte[] GenerateExcel<T>(List<T> obj, string date = "") where T : class
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace _0_Framework.Exceptions;
|
namespace _0_Framework.Exceptions;
|
||||||
|
|
||||||
@@ -14,5 +15,13 @@ public class BadRequestException:Exception
|
|||||||
Details = details;
|
Details = details;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BadRequestException(string message, Dictionary<string, object?> extra) :
|
||||||
|
base(message)
|
||||||
|
{
|
||||||
|
Extra = extra;
|
||||||
|
}
|
||||||
|
|
||||||
public string Details { get; }
|
public string Details { get; }
|
||||||
|
public Dictionary<string,object> Extra { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
101
0_Framework/Exceptions/Handler/CustomExceptionHandler.cs
Normal file
101
0_Framework/Exceptions/Handler/CustomExceptionHandler.cs
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
#nullable enable
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using FluentValidation;
|
||||||
|
using Microsoft.AspNetCore.Diagnostics;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
|
||||||
|
namespace _0_Framework.Exceptions.Handler;
|
||||||
|
|
||||||
|
public class CustomExceptionHandler : IExceptionHandler
|
||||||
|
{
|
||||||
|
private readonly ILogger<CustomExceptionHandler> _logger;
|
||||||
|
|
||||||
|
public CustomExceptionHandler(ILogger<CustomExceptionHandler> logger)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async ValueTask<bool> TryHandleAsync(HttpContext context, Exception exception, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
_logger.LogError(exception,
|
||||||
|
"Error Message: {exceptionMessage}, Type: {exceptionType}, Time: {time}, Path: {path}, TraceId: {traceId}",
|
||||||
|
exception.Message,
|
||||||
|
exception.GetType().FullName,
|
||||||
|
DateTime.UtcNow,
|
||||||
|
context.Request.Path,
|
||||||
|
context.TraceIdentifier);
|
||||||
|
|
||||||
|
(string Detail, string Title, int StatusCode, Dictionary<string, object>? Extra) details = exception switch
|
||||||
|
{
|
||||||
|
ValidationException validationException =>
|
||||||
|
(
|
||||||
|
validationException.Errors.FirstOrDefault()?.ErrorMessage ?? "One or more validation errors occurred.",
|
||||||
|
"Validation Error",
|
||||||
|
context.Response.StatusCode = StatusCodes.Status400BadRequest,
|
||||||
|
null
|
||||||
|
),
|
||||||
|
|
||||||
|
InternalServerException =>
|
||||||
|
(
|
||||||
|
exception.Message,
|
||||||
|
exception.GetType().Name,
|
||||||
|
context.Response.StatusCode = StatusCodes.Status500InternalServerError,
|
||||||
|
null
|
||||||
|
),
|
||||||
|
|
||||||
|
BadRequestException bre =>
|
||||||
|
(
|
||||||
|
exception.Message,
|
||||||
|
exception.GetType().Name,
|
||||||
|
context.Response.StatusCode = StatusCodes.Status400BadRequest,
|
||||||
|
bre.Extra
|
||||||
|
),
|
||||||
|
|
||||||
|
NotFoundException =>
|
||||||
|
(
|
||||||
|
exception.Message,
|
||||||
|
exception.GetType().Name,
|
||||||
|
context.Response.StatusCode = StatusCodes.Status404NotFound,
|
||||||
|
null
|
||||||
|
),
|
||||||
|
|
||||||
|
UnAuthorizeException =>
|
||||||
|
(
|
||||||
|
exception.Message,
|
||||||
|
exception.GetType().Name,
|
||||||
|
context.Response.StatusCode = StatusCodes.Status401Unauthorized,
|
||||||
|
null
|
||||||
|
),
|
||||||
|
|
||||||
|
_ =>
|
||||||
|
(
|
||||||
|
exception.Message,
|
||||||
|
exception.GetType().Name,
|
||||||
|
context.Response.StatusCode = StatusCodes.Status500InternalServerError,
|
||||||
|
null
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
var problemDetails = new ProblemDetails
|
||||||
|
{
|
||||||
|
Title = details.Title,
|
||||||
|
Detail = details.Detail,
|
||||||
|
Status = details.StatusCode,
|
||||||
|
Instance = context.Request.Path,
|
||||||
|
Extensions = details.Extra ?? new Dictionary<string, object>()
|
||||||
|
};
|
||||||
|
|
||||||
|
problemDetails.Extensions.Add("traceId", context.TraceIdentifier);
|
||||||
|
|
||||||
|
await context.Response.WriteAsJsonAsync(problemDetails, cancellationToken: cancellationToken);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
10
0_Framework/Exceptions/UnAuthorizeException.cs
Normal file
10
0_Framework/Exceptions/UnAuthorizeException.cs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace _0_Framework.Exceptions;
|
||||||
|
|
||||||
|
public class UnAuthorizeException:Exception
|
||||||
|
{
|
||||||
|
public UnAuthorizeException(string message) : base(message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
404
0_Framework/InfraStructure/FaceEmbeddingService.cs
Normal file
404
0_Framework/InfraStructure/FaceEmbeddingService.cs
Normal file
@@ -0,0 +1,404 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
|
using System.Net.Http.Json;
|
||||||
|
using System.Text.Json;
|
||||||
|
using _0_Framework.Application;
|
||||||
|
using _0_Framework.Application.FaceEmbedding;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Microsoft.Extensions.Http;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace _0_Framework.Infrastructure;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// پیادهسازی سرویس ارتباط با API پایتون برای مدیریت Embeddings چهره
|
||||||
|
/// </summary>
|
||||||
|
public class FaceEmbeddingService : IFaceEmbeddingService
|
||||||
|
{
|
||||||
|
private readonly IHttpClientFactory _httpClientFactory;
|
||||||
|
private readonly ILogger<FaceEmbeddingService> _logger;
|
||||||
|
private readonly IFaceEmbeddingNotificationService _notificationService;
|
||||||
|
private readonly string _apiBaseUrl;
|
||||||
|
|
||||||
|
public FaceEmbeddingService(IHttpClientFactory httpClientFactory, ILogger<FaceEmbeddingService> logger,
|
||||||
|
IFaceEmbeddingNotificationService notificationService = null)
|
||||||
|
{
|
||||||
|
_httpClientFactory = httpClientFactory;
|
||||||
|
_logger = logger;
|
||||||
|
_notificationService = notificationService;
|
||||||
|
_apiBaseUrl = "http://localhost:8000";
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<OperationResult> GenerateEmbeddingsAsync(long employeeId, long workshopId,
|
||||||
|
string employeeFullName, string picture1Path, string picture2Path)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var httpClient = _httpClientFactory.CreateClient();
|
||||||
|
httpClient.BaseAddress = new Uri(_apiBaseUrl);
|
||||||
|
httpClient.Timeout = TimeSpan.FromSeconds(30);
|
||||||
|
|
||||||
|
using var content = new MultipartFormDataContent();
|
||||||
|
|
||||||
|
// Add form fields
|
||||||
|
content.Add(new StringContent(employeeId.ToString()), "employee_id");
|
||||||
|
content.Add(new StringContent(workshopId.ToString()), "workshop_id");
|
||||||
|
content.Add(new StringContent(employeeFullName ?? ""), "employee_full_name");
|
||||||
|
|
||||||
|
// Add picture files
|
||||||
|
if (File.Exists(picture1Path))
|
||||||
|
{
|
||||||
|
var picture1Bytes = await File.ReadAllBytesAsync(picture1Path);
|
||||||
|
var picture1Content = new ByteArrayContent(picture1Bytes);
|
||||||
|
picture1Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
|
||||||
|
content.Add(picture1Content, "picture1", "1.jpg");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger.LogWarning("Picture1 not found at path: {Path}", picture1Path);
|
||||||
|
return new OperationResult { IsSuccedded = false, Message = "تصویر اول یافت نشد" };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (File.Exists(picture2Path))
|
||||||
|
{
|
||||||
|
var picture2Bytes = await File.ReadAllBytesAsync(picture2Path);
|
||||||
|
var picture2Content = new ByteArrayContent(picture2Bytes);
|
||||||
|
picture2Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
|
||||||
|
content.Add(picture2Content, "picture2", "2.jpg");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger.LogWarning("Picture2 not found at path: {Path}", picture2Path);
|
||||||
|
return new OperationResult { IsSuccedded = false, Message = "تصویر دوم یافت نشد" };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send request to Python API
|
||||||
|
var response = await httpClient.PostAsync("embeddings", content);
|
||||||
|
|
||||||
|
if (response.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
var responseContent = await response.Content.ReadAsStringAsync();
|
||||||
|
_logger.LogInformation(
|
||||||
|
"Embeddings generated successfully for Employee {EmployeeId}, Workshop {WorkshopId}",
|
||||||
|
employeeId, workshopId);
|
||||||
|
|
||||||
|
// ارسال اطلاعرسانی به سایر سیستمها
|
||||||
|
if (_notificationService != null)
|
||||||
|
{
|
||||||
|
await _notificationService.NotifyEmbeddingCreatedAsync(workshopId, employeeId, employeeFullName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new OperationResult
|
||||||
|
{
|
||||||
|
IsSuccedded = true,
|
||||||
|
Message = "Embedding با موفقیت ایجاد شد"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var errorContent = await response.Content.ReadAsStringAsync();
|
||||||
|
_logger.LogError("Failed to generate embeddings. Status: {StatusCode}, Error: {Error}",
|
||||||
|
response.StatusCode, errorContent);
|
||||||
|
|
||||||
|
return new OperationResult
|
||||||
|
{
|
||||||
|
IsSuccedded = false,
|
||||||
|
Message = $"خطا در تولید Embedding: {response.StatusCode}"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (HttpRequestException ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "HTTP error while calling embeddings API for Employee {EmployeeId}", employeeId);
|
||||||
|
return new OperationResult
|
||||||
|
{
|
||||||
|
IsSuccedded = false,
|
||||||
|
Message = "خطا در ارتباط با سرور Embedding"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error while calling embeddings API for Employee {EmployeeId}", employeeId);
|
||||||
|
return new OperationResult
|
||||||
|
{
|
||||||
|
IsSuccedded = false,
|
||||||
|
Message = "خطای غیرمنتظره در تولید Embedding"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<OperationResult> GenerateEmbeddingsFromStreamAsync(long employeeId, long workshopId,
|
||||||
|
string employeeFullName, Stream picture1Stream, Stream picture2Stream)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var httpClient = _httpClientFactory.CreateClient();
|
||||||
|
httpClient.BaseAddress = new Uri(_apiBaseUrl);
|
||||||
|
httpClient.Timeout = TimeSpan.FromSeconds(30);
|
||||||
|
|
||||||
|
using var content = new MultipartFormDataContent();
|
||||||
|
|
||||||
|
// Add form fields
|
||||||
|
content.Add(new StringContent(employeeId.ToString()), "employee_id");
|
||||||
|
content.Add(new StringContent(workshopId.ToString()), "workshop_id");
|
||||||
|
content.Add(new StringContent(employeeFullName ?? ""), "employee_full_name");
|
||||||
|
|
||||||
|
// Add picture streams
|
||||||
|
var picture1Content = new StreamContent(picture1Stream);
|
||||||
|
picture1Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
|
||||||
|
content.Add(picture1Content, "picture1", "1.jpg");
|
||||||
|
|
||||||
|
var picture2Content = new StreamContent(picture2Stream);
|
||||||
|
picture2Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
|
||||||
|
content.Add(picture2Content, "picture2", "2.jpg");
|
||||||
|
|
||||||
|
// Send request to Python API
|
||||||
|
var response = await httpClient.PostAsync("embeddings", content);
|
||||||
|
|
||||||
|
if (response.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Embeddings generated successfully from streams for Employee {EmployeeId}",
|
||||||
|
employeeId);
|
||||||
|
|
||||||
|
// ارسال اطلاعرسانی به سایر سیستمها
|
||||||
|
if (_notificationService != null)
|
||||||
|
{
|
||||||
|
await _notificationService.NotifyEmbeddingCreatedAsync(workshopId, employeeId, employeeFullName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new OperationResult { IsSuccedded = true, Message = "Embedding با موفقیت ایجاد شد" };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var errorContent = await response.Content.ReadAsStringAsync();
|
||||||
|
_logger.LogError("Failed to generate embeddings from streams. Status: {StatusCode}, Error: {Error}",
|
||||||
|
response.StatusCode, errorContent);
|
||||||
|
|
||||||
|
return new OperationResult
|
||||||
|
{
|
||||||
|
IsSuccedded = false,
|
||||||
|
Message = $"خطا در تولید Embedding: {response.StatusCode}"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error while generating embeddings from streams for Employee {EmployeeId}",
|
||||||
|
employeeId);
|
||||||
|
return new OperationResult
|
||||||
|
{
|
||||||
|
IsSuccedded = false,
|
||||||
|
Message = "خطا در تولید Embedding"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<OperationResult> RefineEmbeddingAsync(long employeeId, long workshopId, float[] embedding,
|
||||||
|
float confidence, Dictionary<string, object> metadata = null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var httpClient = _httpClientFactory.CreateClient();
|
||||||
|
httpClient.BaseAddress = new Uri(_apiBaseUrl);
|
||||||
|
httpClient.Timeout = TimeSpan.FromSeconds(30);
|
||||||
|
|
||||||
|
var requestBody = new
|
||||||
|
{
|
||||||
|
employeeId,
|
||||||
|
workshopId,
|
||||||
|
embedding,
|
||||||
|
confidence,
|
||||||
|
metadata = metadata ?? new Dictionary<string, object>()
|
||||||
|
};
|
||||||
|
|
||||||
|
var response = await httpClient.PostAsJsonAsync("embeddings/refine", requestBody);
|
||||||
|
|
||||||
|
if (response.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Embedding refined successfully for Employee {EmployeeId}", employeeId);
|
||||||
|
|
||||||
|
// ارسال اطلاعرسانی به سایر سیستمها
|
||||||
|
if (_notificationService != null)
|
||||||
|
{
|
||||||
|
await _notificationService.NotifyEmbeddingRefinedAsync(workshopId, employeeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new OperationResult { IsSuccedded = true, Message = "Embedding بهبود یافت" };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var errorContent = await response.Content.ReadAsStringAsync();
|
||||||
|
_logger.LogError("Failed to refine embedding. Status: {StatusCode}, Error: {Error}",
|
||||||
|
response.StatusCode, errorContent);
|
||||||
|
|
||||||
|
return new OperationResult
|
||||||
|
{
|
||||||
|
IsSuccedded = false,
|
||||||
|
Message = $"خطا در بهبود Embedding: {response.StatusCode}"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error while refining embedding for Employee {EmployeeId}", employeeId);
|
||||||
|
return new OperationResult
|
||||||
|
{
|
||||||
|
IsSuccedded = false,
|
||||||
|
Message = "خطا در بهبود Embedding"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<OperationResult> DeleteEmbeddingAsync(long employeeId, long workshopId)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var httpClient = _httpClientFactory.CreateClient();
|
||||||
|
httpClient.BaseAddress = new Uri(_apiBaseUrl);
|
||||||
|
httpClient.Timeout = TimeSpan.FromSeconds(30);
|
||||||
|
|
||||||
|
var response = await httpClient.DeleteAsync($"embeddings/{workshopId}/{employeeId}");
|
||||||
|
|
||||||
|
if (response.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Embedding deleted successfully for Employee {EmployeeId}", employeeId);
|
||||||
|
|
||||||
|
// ارسال اطلاعرسانی به سایر سیستمها
|
||||||
|
if (_notificationService != null)
|
||||||
|
{
|
||||||
|
await _notificationService.NotifyEmbeddingDeletedAsync(workshopId, employeeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new OperationResult { IsSuccedded = true, Message = "Embedding حذف شد" };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var errorContent = await response.Content.ReadAsStringAsync();
|
||||||
|
_logger.LogError("Failed to delete embedding. Status: {StatusCode}, Error: {Error}",
|
||||||
|
response.StatusCode, errorContent);
|
||||||
|
|
||||||
|
return new OperationResult
|
||||||
|
{
|
||||||
|
IsSuccedded = false,
|
||||||
|
Message = $"خطا در حذف Embedding: {response.StatusCode}"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error while deleting embedding for Employee {EmployeeId}", employeeId);
|
||||||
|
return new OperationResult
|
||||||
|
{
|
||||||
|
IsSuccedded = false,
|
||||||
|
Message = "خطا در حذف Embedding"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<OperationResult<FaceEmbeddingResponse>> GetEmbeddingAsync(long employeeId, long workshopId)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var httpClient = _httpClientFactory.CreateClient();
|
||||||
|
httpClient.BaseAddress = new Uri(_apiBaseUrl);
|
||||||
|
httpClient.Timeout = TimeSpan.FromSeconds(30);
|
||||||
|
|
||||||
|
var response = await httpClient.GetAsync($"embeddings/{workshopId}/{employeeId}");
|
||||||
|
|
||||||
|
if (response.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
var content = await response.Content.ReadAsStringAsync();
|
||||||
|
var embeddingData = JsonSerializer.Deserialize<FaceEmbeddingResponse>(content,
|
||||||
|
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
|
||||||
|
|
||||||
|
_logger.LogInformation("Embedding retrieved successfully for Employee {EmployeeId}", employeeId);
|
||||||
|
|
||||||
|
return new OperationResult<FaceEmbeddingResponse>
|
||||||
|
{
|
||||||
|
IsSuccedded = true,
|
||||||
|
Message = "Embedding دریافت شد",
|
||||||
|
Data = embeddingData
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var errorContent = await response.Content.ReadAsStringAsync();
|
||||||
|
_logger.LogError("Failed to get embedding. Status: {StatusCode}, Error: {Error}",
|
||||||
|
response.StatusCode, errorContent);
|
||||||
|
|
||||||
|
return new OperationResult<FaceEmbeddingResponse>
|
||||||
|
{
|
||||||
|
IsSuccedded = false,
|
||||||
|
Message = $"خطا در دریافت Embedding: {response.StatusCode}"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error while getting embedding for Employee {EmployeeId}", employeeId);
|
||||||
|
return new OperationResult<FaceEmbeddingResponse>
|
||||||
|
{
|
||||||
|
IsSuccedded = false,
|
||||||
|
Message = "خطا در دریافت Embedding"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<OperationResult> UpdateEmbeddingFullNameAsync(long employeeId, long workshopId,
|
||||||
|
string newFullName)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var httpClient = _httpClientFactory.CreateClient();
|
||||||
|
httpClient.BaseAddress = new Uri(_apiBaseUrl);
|
||||||
|
httpClient.Timeout = TimeSpan.FromSeconds(30);
|
||||||
|
|
||||||
|
var requestBody = new
|
||||||
|
{
|
||||||
|
employee_id = employeeId,
|
||||||
|
workshop_id = workshopId,
|
||||||
|
employee_full_name = newFullName
|
||||||
|
};
|
||||||
|
|
||||||
|
var response = await httpClient.PutAsJsonAsync("embeddings/update-name", requestBody);
|
||||||
|
|
||||||
|
if (response.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Employee Name Changed For {EmployeeId} In workshop ={WorkshopId}", employeeId,
|
||||||
|
workshopId);
|
||||||
|
|
||||||
|
// ارسال اطلاعرسانی به سایر سیستمها
|
||||||
|
if (_notificationService != null)
|
||||||
|
{
|
||||||
|
//await _notificationService.NotifyEmbeddingRefinedAsync(workshopId, employeeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new OperationResult { IsSuccedded = true, Message = "عملیات با موفقیت انجام شد" };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var errorContent = await response.Content.ReadAsStringAsync();
|
||||||
|
_logger.LogError("Failed to refine embedding. Status: {StatusCode}, Error: {Error}",
|
||||||
|
response.StatusCode, errorContent);
|
||||||
|
|
||||||
|
return new OperationResult
|
||||||
|
{
|
||||||
|
IsSuccedded = false,
|
||||||
|
Message = $"خطا در بهبود Embedding: {response.StatusCode}"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error while Changing EmployeeFullName for Employee {EmployeeId}", employeeId);
|
||||||
|
return new OperationResult
|
||||||
|
{
|
||||||
|
IsSuccedded = false,
|
||||||
|
Message = "خطا در بهبود Embedding"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
8
0_Framework/InfraStructure/Mongo/MongoDbConfig.cs
Normal file
8
0_Framework/InfraStructure/Mongo/MongoDbConfig.cs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
namespace _0_Framework.InfraStructure.Mongo;
|
||||||
|
|
||||||
|
public class MongoDbConfig
|
||||||
|
{
|
||||||
|
public string ConnectionString { get; set; } = null!;
|
||||||
|
|
||||||
|
public string DatabaseName { get; set; } = null!;
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
using _0_Framework.Application.FaceEmbedding;
|
||||||
|
|
||||||
|
namespace _0_Framework.InfraStructure;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// پیادهسازی پیشفرض (بدون عملیات) برای IFaceEmbeddingNotificationService
|
||||||
|
/// این کلاس زمانی استفاده میشود که SignalR در دسترس نباشد
|
||||||
|
/// </summary>
|
||||||
|
public class NullFaceEmbeddingNotificationService : IFaceEmbeddingNotificationService
|
||||||
|
{
|
||||||
|
public Task NotifyEmbeddingCreatedAsync(long workshopId, long employeeId, string employeeFullName)
|
||||||
|
{
|
||||||
|
// هیچ عملیاتی انجام نمیدهد
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task NotifyEmbeddingDeletedAsync(long workshopId, long employeeId)
|
||||||
|
{
|
||||||
|
// هیچ عملیاتی انجام نمیدهد
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task NotifyEmbeddingRefinedAsync(long workshopId, long employeeId)
|
||||||
|
{
|
||||||
|
// هیچ عملیاتی انجام نمیدهد
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
}
|
||||||
22
0_Framework/InfraStructure/QueryableExtensions.cs
Normal file
22
0_Framework/InfraStructure/QueryableExtensions.cs
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace _0_Framework.InfraStructure;
|
||||||
|
|
||||||
|
public static class QueryableExtensions
|
||||||
|
{
|
||||||
|
public static IQueryable<T> ApplyPagination<T>(this IQueryable<T> query, int page, int pageSize = 30)
|
||||||
|
{
|
||||||
|
if (page <= 0) page = 1;
|
||||||
|
if (pageSize <= 0) pageSize = 10;
|
||||||
|
|
||||||
|
return query.Skip((page - 1) * pageSize).Take(pageSize);
|
||||||
|
}
|
||||||
|
public static IEnumerable<T> ApplyPagination<T>(this IEnumerable<T> source, int page, int pageSize = 30)
|
||||||
|
{
|
||||||
|
if (page <= 0) page = 1;
|
||||||
|
if (pageSize <= 0) pageSize = 10;
|
||||||
|
|
||||||
|
return source.Skip((page - 1) * pageSize).Take(pageSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ using System.Text;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using _0_Framework.Domain;
|
using _0_Framework.Domain;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage;
|
||||||
|
|
||||||
namespace _0_Framework.InfraStructure
|
namespace _0_Framework.InfraStructure
|
||||||
{
|
{
|
||||||
@@ -70,5 +71,10 @@ namespace _0_Framework.InfraStructure
|
|||||||
{
|
{
|
||||||
await _context.SaveChangesAsync();
|
await _context.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<IDbContextTransaction> BeginTransactionAsync()
|
||||||
|
{
|
||||||
|
return await _context.Database.BeginTransactionAsync();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
624
ANDROID_SIGNALR_GUIDE.md
Normal file
624
ANDROID_SIGNALR_GUIDE.md
Normal file
@@ -0,0 +1,624 @@
|
|||||||
|
# راهنمای اتصال اپلیکیشن Android به SignalR برای Face Embedding
|
||||||
|
|
||||||
|
## 1. افزودن کتابخانه SignalR به پروژه Android
|
||||||
|
|
||||||
|
در فایل `build.gradle` (Module: app) خود، dependency زیر را اضافه کنید:
|
||||||
|
|
||||||
|
```gradle
|
||||||
|
dependencies {
|
||||||
|
// SignalR for Android
|
||||||
|
implementation 'com.microsoft.signalr:signalr:7.0.0'
|
||||||
|
|
||||||
|
// اگر از Kotlin استفاده میکنید:
|
||||||
|
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.1'
|
||||||
|
|
||||||
|
// برای JSON پردازش:
|
||||||
|
implementation 'com.google.code.gson:gson:2.10.1'
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2. اضافه کردن Permission در AndroidManifest.xml
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
|
```
|
||||||
|
|
||||||
|
## 3. کد Java/Kotlin برای اتصال به SignalR
|
||||||
|
|
||||||
|
### نسخه Java:
|
||||||
|
|
||||||
|
```java
|
||||||
|
import com.microsoft.signalr.HubConnection;
|
||||||
|
import com.microsoft.signalr.HubConnectionBuilder;
|
||||||
|
import com.microsoft.signalr.HubConnectionState;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
public class FaceEmbeddingSignalRClient {
|
||||||
|
private static final String TAG = "FaceEmbeddingHub";
|
||||||
|
private HubConnection hubConnection;
|
||||||
|
private String serverUrl = "http://YOUR_SERVER_IP:PORT/trackingFaceEmbeddingHub"; // آدرس سرور خود را وارد کنید
|
||||||
|
private long workshopId;
|
||||||
|
|
||||||
|
public FaceEmbeddingSignalRClient(long workshopId) {
|
||||||
|
this.workshopId = workshopId;
|
||||||
|
initializeSignalR();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initializeSignalR() {
|
||||||
|
// ایجاد اتصال SignalR
|
||||||
|
hubConnection = HubConnectionBuilder
|
||||||
|
.create(serverUrl)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// دریافت رویداد ایجاد Embedding
|
||||||
|
hubConnection.on("EmbeddingCreated", (data) -> {
|
||||||
|
JsonObject jsonData = (JsonObject) data;
|
||||||
|
long employeeId = jsonData.get("employeeId").getAsLong();
|
||||||
|
String employeeFullName = jsonData.get("employeeFullName").getAsString();
|
||||||
|
String timestamp = jsonData.get("timestamp").getAsString();
|
||||||
|
|
||||||
|
Log.d(TAG, "Embedding Created - Employee: " + employeeFullName + " (ID: " + employeeId + ")");
|
||||||
|
|
||||||
|
// اینجا میتوانید دادههای جدید را از سرور بگیرید یا UI را بروزرسانی کنید
|
||||||
|
onEmbeddingCreated(employeeId, employeeFullName, timestamp);
|
||||||
|
|
||||||
|
}, JsonObject.class);
|
||||||
|
|
||||||
|
// دریافت رویداد حذف Embedding
|
||||||
|
hubConnection.on("EmbeddingDeleted", (data) -> {
|
||||||
|
JsonObject jsonData = (JsonObject) data;
|
||||||
|
long employeeId = jsonData.get("employeeId").getAsLong();
|
||||||
|
String timestamp = jsonData.get("timestamp").getAsString();
|
||||||
|
|
||||||
|
Log.d(TAG, "Embedding Deleted - Employee ID: " + employeeId);
|
||||||
|
onEmbeddingDeleted(employeeId, timestamp);
|
||||||
|
|
||||||
|
}, JsonObject.class);
|
||||||
|
|
||||||
|
// دریافت رویداد بهبود Embedding
|
||||||
|
hubConnection.on("EmbeddingRefined", (data) -> {
|
||||||
|
JsonObject jsonData = (JsonObject) data;
|
||||||
|
long employeeId = jsonData.get("employeeId").getAsLong();
|
||||||
|
String timestamp = jsonData.get("timestamp").getAsString();
|
||||||
|
|
||||||
|
Log.d(TAG, "Embedding Refined - Employee ID: " + employeeId);
|
||||||
|
onEmbeddingRefined(employeeId, timestamp);
|
||||||
|
|
||||||
|
}, JsonObject.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void connect() {
|
||||||
|
if (hubConnection.getConnectionState() == HubConnectionState.DISCONNECTED) {
|
||||||
|
hubConnection.start()
|
||||||
|
.doOnComplete(() -> {
|
||||||
|
Log.d(TAG, "Connected to SignalR Hub");
|
||||||
|
joinWorkshopGroup();
|
||||||
|
})
|
||||||
|
.doOnError(error -> {
|
||||||
|
Log.e(TAG, "Error connecting to SignalR: " + error.getMessage());
|
||||||
|
})
|
||||||
|
.subscribe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void joinWorkshopGroup() {
|
||||||
|
// عضویت در گروه مخصوص این کارگاه
|
||||||
|
hubConnection.send("JoinWorkshopGroup", workshopId);
|
||||||
|
Log.d(TAG, "Joined workshop group: " + workshopId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void disconnect() {
|
||||||
|
if (hubConnection.getConnectionState() == HubConnectionState.CONNECTED) {
|
||||||
|
// خروج از گروه
|
||||||
|
hubConnection.send("LeaveWorkshopGroup", workshopId);
|
||||||
|
|
||||||
|
hubConnection.stop();
|
||||||
|
Log.d(TAG, "Disconnected from SignalR Hub");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// این متدها را در Activity/Fragment خود override کنید
|
||||||
|
protected void onEmbeddingCreated(long employeeId, String employeeFullName, String timestamp) {
|
||||||
|
// اینجا UI را بروزرسانی کنید یا داده جدید را بگیرید
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void onEmbeddingDeleted(long employeeId, String timestamp) {
|
||||||
|
// اینجا UI را بروزرسانی کنید
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void onEmbeddingRefined(long employeeId, String timestamp) {
|
||||||
|
// اینجا UI را بروزرسانی کنید
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### نسخه Kotlin:
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
import com.microsoft.signalr.HubConnection
|
||||||
|
import com.microsoft.signalr.HubConnectionBuilder
|
||||||
|
import com.microsoft.signalr.HubConnectionState
|
||||||
|
import com.google.gson.JsonObject
|
||||||
|
import android.util.Log
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
class FaceEmbeddingSignalRClient(private val workshopId: Long) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val TAG = "FaceEmbeddingHub"
|
||||||
|
}
|
||||||
|
|
||||||
|
private lateinit var hubConnection: HubConnection
|
||||||
|
private val serverUrl = "http://YOUR_SERVER_IP:PORT/trackingFaceEmbeddingHub" // آدرس سرور خود را وارد کنید
|
||||||
|
|
||||||
|
init {
|
||||||
|
initializeSignalR()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initializeSignalR() {
|
||||||
|
hubConnection = HubConnectionBuilder
|
||||||
|
.create(serverUrl)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
// دریافت رویداد ایجاد Embedding
|
||||||
|
hubConnection.on("EmbeddingCreated", { data: JsonObject ->
|
||||||
|
val employeeId = data.get("employeeId").asLong
|
||||||
|
val employeeFullName = data.get("employeeFullName").asString
|
||||||
|
val timestamp = data.get("timestamp").asString
|
||||||
|
|
||||||
|
Log.d(TAG, "Embedding Created - Employee: $employeeFullName (ID: $employeeId)")
|
||||||
|
onEmbeddingCreated(employeeId, employeeFullName, timestamp)
|
||||||
|
}, JsonObject::class.java)
|
||||||
|
|
||||||
|
// دریافت رویداد حذف Embedding
|
||||||
|
hubConnection.on("EmbeddingDeleted", { data: JsonObject ->
|
||||||
|
val employeeId = data.get("employeeId").asLong
|
||||||
|
val timestamp = data.get("timestamp").asString
|
||||||
|
|
||||||
|
Log.d(TAG, "Embedding Deleted - Employee ID: $employeeId")
|
||||||
|
onEmbeddingDeleted(employeeId, timestamp)
|
||||||
|
}, JsonObject::class.java)
|
||||||
|
|
||||||
|
// دریافت رویداد بهبود Embedding
|
||||||
|
hubConnection.on("EmbeddingRefined", { data: JsonObject ->
|
||||||
|
val employeeId = data.get("employeeId").asLong
|
||||||
|
val timestamp = data.get("timestamp").asString
|
||||||
|
|
||||||
|
Log.d(TAG, "Embedding Refined - Employee ID: $employeeId")
|
||||||
|
onEmbeddingRefined(employeeId, timestamp)
|
||||||
|
}, JsonObject::class.java)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun connect() {
|
||||||
|
if (hubConnection.connectionState == HubConnectionState.DISCONNECTED) {
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
try {
|
||||||
|
hubConnection.start().blockingAwait()
|
||||||
|
Log.d(TAG, "Connected to SignalR Hub")
|
||||||
|
joinWorkshopGroup()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e(TAG, "Error connecting to SignalR: ${e.message}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun joinWorkshopGroup() {
|
||||||
|
hubConnection.send("JoinWorkshopGroup", workshopId)
|
||||||
|
Log.d(TAG, "Joined workshop group: $workshopId")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun disconnect() {
|
||||||
|
if (hubConnection.connectionState == HubConnectionState.CONNECTED) {
|
||||||
|
hubConnection.send("LeaveWorkshopGroup", workshopId)
|
||||||
|
hubConnection.stop()
|
||||||
|
Log.d(TAG, "Disconnected from SignalR Hub")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// این متدها را override کنید
|
||||||
|
open fun onEmbeddingCreated(employeeId: Long, employeeFullName: String, timestamp: String) {
|
||||||
|
// اینجا UI را بروزرسانی کنید یا داده جدید را بگیرید
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun onEmbeddingDeleted(employeeId: Long, timestamp: String) {
|
||||||
|
// اینجا UI را بروزرسانی کنید
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun onEmbeddingRefined(employeeId: Long, timestamp: String) {
|
||||||
|
// اینجا UI را بروزرسانی کنید
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 4. استفاده در Activity یا Fragment
|
||||||
|
|
||||||
|
### مثال با Login و دریافت WorkshopId
|
||||||
|
|
||||||
|
#### Java:
|
||||||
|
```java
|
||||||
|
public class LoginActivity extends AppCompatActivity {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_login);
|
||||||
|
|
||||||
|
Button btnLogin = findViewById(R.id.btnLogin);
|
||||||
|
btnLogin.setOnClickListener(v -> performLogin());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void performLogin() {
|
||||||
|
// فراخوانی API لاگین
|
||||||
|
// فرض کنید response شامل workshopId است
|
||||||
|
|
||||||
|
// مثال ساده (باید از Retrofit یا کتابخانه مشابه استفاده کنید):
|
||||||
|
// LoginResponse response = apiService.login(username, password);
|
||||||
|
// long workshopId = response.getWorkshopId();
|
||||||
|
|
||||||
|
long workshopId = 123; // این را از response دریافت کنید
|
||||||
|
|
||||||
|
// ذخیره workshopId
|
||||||
|
SharedPreferences prefs = getSharedPreferences("AppPrefs", MODE_PRIVATE);
|
||||||
|
prefs.edit().putLong("workshopId", workshopId).apply();
|
||||||
|
|
||||||
|
// رفتن به صفحه اصلی
|
||||||
|
Intent intent = new Intent(this, MainActivity.class);
|
||||||
|
startActivity(intent);
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MainActivity extends AppCompatActivity {
|
||||||
|
private FaceEmbeddingSignalRClient signalRClient;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_main);
|
||||||
|
|
||||||
|
// دریافت workshopId از SharedPreferences
|
||||||
|
SharedPreferences prefs = getSharedPreferences("AppPrefs", MODE_PRIVATE);
|
||||||
|
long workshopId = prefs.getLong("workshopId", 0);
|
||||||
|
|
||||||
|
if (workshopId == 0) {
|
||||||
|
// اگر workshopId وجود نداره، برگرد به صفحه لاگین
|
||||||
|
Intent intent = new Intent(this, LoginActivity.class);
|
||||||
|
startActivity(intent);
|
||||||
|
finish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ایجاد و اتصال SignalR
|
||||||
|
signalRClient = new FaceEmbeddingSignalRClient(workshopId) {
|
||||||
|
@Override
|
||||||
|
protected void onEmbeddingCreated(long employeeId, String employeeFullName, String timestamp) {
|
||||||
|
runOnUiThread(() -> {
|
||||||
|
// بروزرسانی UI
|
||||||
|
Toast.makeText(MainActivity.this,
|
||||||
|
"Embedding ایجاد شد برای: " + employeeFullName,
|
||||||
|
Toast.LENGTH_SHORT).show();
|
||||||
|
|
||||||
|
// دریافت دادههای جدید از API
|
||||||
|
refreshEmployeeList();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onEmbeddingDeleted(long employeeId, String timestamp) {
|
||||||
|
runOnUiThread(() -> {
|
||||||
|
// بروزرسانی UI
|
||||||
|
refreshEmployeeList();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onEmbeddingRefined(long employeeId, String timestamp) {
|
||||||
|
runOnUiThread(() -> {
|
||||||
|
// بروزرسانی UI
|
||||||
|
refreshEmployeeList();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
signalRClient.connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
if (signalRClient != null) {
|
||||||
|
signalRClient.disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void refreshEmployeeList() {
|
||||||
|
// دریافت لیست جدید کارمندان از API
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Kotlin:
|
||||||
|
```kotlin
|
||||||
|
class LoginActivity : AppCompatActivity() {
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setContentView(R.layout.activity_login)
|
||||||
|
|
||||||
|
val btnLogin = findViewById<Button>(R.id.btnLogin)
|
||||||
|
btnLogin.setOnClickListener { performLogin() }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun performLogin() {
|
||||||
|
// فراخوانی API لاگین
|
||||||
|
// فرض کنید response شامل workshopId است
|
||||||
|
|
||||||
|
// مثال ساده (باید از Retrofit یا کتابخانه مشابه استفاده کنید):
|
||||||
|
// val response = apiService.login(username, password)
|
||||||
|
// val workshopId = response.workshopId
|
||||||
|
|
||||||
|
val workshopId = 123L // این را از response دریافت کنید
|
||||||
|
|
||||||
|
// ذخیره workshopId
|
||||||
|
val prefs = getSharedPreferences("AppPrefs", Context.MODE_PRIVATE)
|
||||||
|
prefs.edit().putLong("workshopId", workshopId).apply()
|
||||||
|
|
||||||
|
// رفتن به صفحه اصلی
|
||||||
|
val intent = Intent(this, MainActivity::class.java)
|
||||||
|
startActivity(intent)
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MainActivity : AppCompatActivity() {
|
||||||
|
private lateinit var signalRClient: FaceEmbeddingSignalRClient
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setContentView(R.layout.activity_main)
|
||||||
|
|
||||||
|
// دریافت workshopId از SharedPreferences
|
||||||
|
val prefs = getSharedPreferences("AppPrefs", Context.MODE_PRIVATE)
|
||||||
|
val workshopId = prefs.getLong("workshopId", 0L)
|
||||||
|
|
||||||
|
if (workshopId == 0L) {
|
||||||
|
// اگر workshopId وجود نداره، برگرد به صفحه لاگین
|
||||||
|
val intent = Intent(this, LoginActivity::class.java)
|
||||||
|
startActivity(intent)
|
||||||
|
finish()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// ایجاد و اتصال SignalR
|
||||||
|
signalRClient = object : FaceEmbeddingSignalRClient(workshopId) {
|
||||||
|
override fun onEmbeddingCreated(employeeId: Long, employeeFullName: String, timestamp: String) {
|
||||||
|
runOnUiThread {
|
||||||
|
// بروزرسانی UI
|
||||||
|
Toast.makeText(this@MainActivity,
|
||||||
|
"Embedding ایجاد شد برای: $employeeFullName",
|
||||||
|
Toast.LENGTH_SHORT).show()
|
||||||
|
|
||||||
|
// دریافت دادههای جدید از API
|
||||||
|
refreshEmployeeList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onEmbeddingDeleted(employeeId: Long, timestamp: String) {
|
||||||
|
runOnUiThread {
|
||||||
|
// بروزرسانی UI
|
||||||
|
refreshEmployeeList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onEmbeddingRefined(employeeId: Long, timestamp: String) {
|
||||||
|
runOnUiThread {
|
||||||
|
// بروزرسانی UI
|
||||||
|
refreshEmployeeList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
signalRClient.connect()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroy() {
|
||||||
|
super.onDestroy()
|
||||||
|
signalRClient.disconnect()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun refreshEmployeeList() {
|
||||||
|
// دریافت لیست جدید کارمندان از API
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### مثال ساده بدون Login:
|
||||||
|
اگر workshopId را از قبل میدانید:
|
||||||
|
|
||||||
|
#### Java:
|
||||||
|
```java
|
||||||
|
public class MainActivity extends AppCompatActivity {
|
||||||
|
private FaceEmbeddingSignalRClient signalRClient;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_main);
|
||||||
|
|
||||||
|
long workshopId = 123; // شناسه کارگاه خود را وارد کنید
|
||||||
|
|
||||||
|
signalRClient = new FaceEmbeddingSignalRClient(workshopId) {
|
||||||
|
@Override
|
||||||
|
protected void onEmbeddingCreated(long employeeId, String employeeFullName, String timestamp) {
|
||||||
|
runOnUiThread(() -> {
|
||||||
|
// بروزرسانی UI
|
||||||
|
Toast.makeText(MainActivity.this,
|
||||||
|
"Embedding ایجاد شد برای: " + employeeFullName,
|
||||||
|
Toast.LENGTH_SHORT).show();
|
||||||
|
|
||||||
|
// دریافت دادههای جدید از API
|
||||||
|
refreshEmployeeList();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onEmbeddingDeleted(long employeeId, String timestamp) {
|
||||||
|
runOnUiThread(() -> {
|
||||||
|
// بروزرسانی UI
|
||||||
|
refreshEmployeeList();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
signalRClient.connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
if (signalRClient != null) {
|
||||||
|
signalRClient.disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void refreshEmployeeList() {
|
||||||
|
// دریافت لیست جدید کارمندان از API
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Kotlin:
|
||||||
|
```kotlin
|
||||||
|
class MainActivity : AppCompatActivity() {
|
||||||
|
private lateinit var signalRClient: FaceEmbeddingSignalRClient
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setContentView(R.layout.activity_main)
|
||||||
|
|
||||||
|
val workshopId = 123L // شناسه کارگاه خود را وارد کنید
|
||||||
|
|
||||||
|
signalRClient = object : FaceEmbeddingSignalRClient(workshopId) {
|
||||||
|
override fun onEmbeddingCreated(employeeId: Long, employeeFullName: String, timestamp: String) {
|
||||||
|
runOnUiThread {
|
||||||
|
// بروزرسانی UI
|
||||||
|
Toast.makeText(this@MainActivity,
|
||||||
|
"Embedding ایجاد شد برای: $employeeFullName",
|
||||||
|
Toast.LENGTH_SHORT).show()
|
||||||
|
|
||||||
|
// دریافت دادههای جدید از API
|
||||||
|
refreshEmployeeList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onEmbeddingDeleted(employeeId: Long, timestamp: String) {
|
||||||
|
runOnUiThread {
|
||||||
|
// بروزرسانی UI
|
||||||
|
refreshEmployeeList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
signalRClient.connect()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroy() {
|
||||||
|
super.onDestroy()
|
||||||
|
signalRClient.disconnect()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun refreshEmployeeList() {
|
||||||
|
// دریافت لیست جدید کارمندان از API
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 5. نکات مهم
|
||||||
|
|
||||||
|
### آدرس سرور
|
||||||
|
- اگر روی شبیهساز اندروید تست میکنید و سرور روی localhost اجرا میشود، از آدرس `http://10.0.2.2:PORT` استفاده کنید
|
||||||
|
- اگر روی دستگاه فیزیکی تست میکنید، از آدرس IP شبکه محلی سرور استفاده کنید (مثل `http://192.168.1.100:PORT`)
|
||||||
|
- PORT پیشفرض معمولاً 5000 یا 5001 است (بسته به کانفیگ پروژه شما)
|
||||||
|
|
||||||
|
### دریافت WorkshopId از Login
|
||||||
|
بعد از login موفق، workshopId را از سرور دریافت کنید و در SharedPreferences یا یک Singleton ذخیره کنید:
|
||||||
|
|
||||||
|
```java
|
||||||
|
// بعد از login موفق
|
||||||
|
SharedPreferences prefs = getSharedPreferences("AppPrefs", MODE_PRIVATE);
|
||||||
|
prefs.edit().putLong("workshopId", workshopId).apply();
|
||||||
|
|
||||||
|
// استفاده در Activity
|
||||||
|
long workshopId = prefs.getLong("workshopId", 0);
|
||||||
|
```
|
||||||
|
|
||||||
|
یا در Kotlin:
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
// بعد از login موفق
|
||||||
|
val prefs = getSharedPreferences("AppPrefs", Context.MODE_PRIVATE)
|
||||||
|
prefs.edit().putLong("workshopId", workshopId).apply()
|
||||||
|
|
||||||
|
// استفاده در Activity
|
||||||
|
val workshopId = prefs.getLong("workshopId", 0L)
|
||||||
|
```
|
||||||
|
|
||||||
|
### مدیریت اتصال
|
||||||
|
برای reconnection خودکار:
|
||||||
|
|
||||||
|
```java
|
||||||
|
hubConnection.onClosed(exception -> {
|
||||||
|
Log.e(TAG, "Connection closed. Attempting to reconnect...");
|
||||||
|
new Handler().postDelayed(() -> connect(), 5000); // تلاش مجدد بعد از 5 ثانیه
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Thread Safety
|
||||||
|
همیشه UI updates را در main thread انجام دهید:
|
||||||
|
|
||||||
|
```java
|
||||||
|
runOnUiThread(() -> {
|
||||||
|
// UI updates here
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## 6. تست اتصال
|
||||||
|
|
||||||
|
برای تست میتوانید:
|
||||||
|
1. اپلیکیشن را اجرا کنید
|
||||||
|
2. از طریق Postman یا Swagger یک Embedding ایجاد کنید
|
||||||
|
3. باید در Logcat پیام "Embedding Created" را ببینید
|
||||||
|
|
||||||
|
## 7. خطایابی (Debugging)
|
||||||
|
|
||||||
|
برای دیدن جزئیات بیشتر:
|
||||||
|
|
||||||
|
```java
|
||||||
|
hubConnection = HubConnectionBuilder
|
||||||
|
.create(serverUrl)
|
||||||
|
.withHttpConnectionOptions(options -> {
|
||||||
|
options.setLogging(LogLevel.TRACE);
|
||||||
|
})
|
||||||
|
.build();
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## خلاصه Endpoints
|
||||||
|
|
||||||
|
| نوع رویداد | متد SignalR | پارامترهای دریافتی |
|
||||||
|
|-----------|-------------|---------------------|
|
||||||
|
| ایجاد Embedding | `EmbeddingCreated` | workshopId, employeeId, employeeFullName, timestamp |
|
||||||
|
| حذف Embedding | `EmbeddingDeleted` | workshopId, employeeId, timestamp |
|
||||||
|
| بهبود Embedding | `EmbeddingRefined` | workshopId, employeeId, timestamp |
|
||||||
|
|
||||||
|
| متد ارسالی | پارامتر | توضیحات |
|
||||||
|
|-----------|---------|---------|
|
||||||
|
| `JoinWorkshopGroup` | workshopId | عضویت در گروه کارگاه |
|
||||||
|
| `LeaveWorkshopGroup` | workshopId | خروج از گروه کارگاه |
|
||||||
|
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
namespace AccountManagement.Application.Contracts.Account;
|
||||||
|
|
||||||
|
public class AccountSelectListViewModel
|
||||||
|
{
|
||||||
|
public long Id { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public long RoleId { get; set; }
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ using System.Collections.Generic;
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using AccountManagement.Application.Contracts.Role;
|
using AccountManagement.Application.Contracts.Role;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||||
|
|
||||||
namespace AccountManagement.Application.Contracts.Account;
|
namespace AccountManagement.Application.Contracts.Account;
|
||||||
|
|
||||||
@@ -35,4 +36,20 @@ public class CreateAccount
|
|||||||
public string Email { get; set; }
|
public string Email { get; set; }
|
||||||
public string VerifyCode { get; set; }
|
public string VerifyCode { get; set; }
|
||||||
public string IsActiveString { get; set; }
|
public string IsActiveString { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// آیا کاربر در پروگرام منیجر فعالیت مبکند؟
|
||||||
|
/// </summary>
|
||||||
|
public bool IsProgramManagerUser { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// لیست نقش های پروگرام منیجر
|
||||||
|
/// </summary>
|
||||||
|
public List<long> UserRoles { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// لیست نقشهای موجود در پروگرام منیجر
|
||||||
|
/// </summary>
|
||||||
|
public SelectList RoleList { get; set; }
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -3,4 +3,5 @@
|
|||||||
public class EditAccount : CreateAccount
|
public class EditAccount : CreateAccount
|
||||||
{
|
{
|
||||||
public long Id { get; set; }
|
public long Id { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,4 @@
|
|||||||
using System;
|
namespace AccountManagement.Application.Contracts.Account;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace AccountManagement.Application.Contracts.Account;
|
|
||||||
|
|
||||||
public class EditClientAccount : RegisterAccount
|
public class EditClientAccount : RegisterAccount
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,15 +2,21 @@
|
|||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Shared.Contracts.PmUser.Queries;
|
||||||
|
|
||||||
namespace AccountManagement.Application.Contracts.Account;
|
namespace AccountManagement.Application.Contracts.Account;
|
||||||
|
|
||||||
public interface IAccountApplication
|
public interface IAccountApplication
|
||||||
{
|
{
|
||||||
AccountViewModel GetAccountBy(long id);
|
AccountViewModel GetAccountBy(long id);
|
||||||
OperationResult Create(CreateAccount command);
|
/// <summary>
|
||||||
|
/// ایجاد کاربر گزارشگیر و پروگرام منیجر
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="command"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<OperationResult> Create(CreateAccount command);
|
||||||
OperationResult RegisterClient(RegisterAccount command);
|
OperationResult RegisterClient(RegisterAccount command);
|
||||||
OperationResult Edit(EditAccount command);
|
Task<OperationResult> Edit(EditAccount command);
|
||||||
OperationResult EditClient(EditClientAccount command);
|
OperationResult EditClient(EditClientAccount command);
|
||||||
OperationResult ChangePassword(ChangePassword command);
|
OperationResult ChangePassword(ChangePassword command);
|
||||||
OperationResult Login(Login command);
|
OperationResult Login(Login command);
|
||||||
@@ -28,7 +34,7 @@ public interface IAccountApplication
|
|||||||
OperationResult DeActive(long id);
|
OperationResult DeActive(long id);
|
||||||
OperationResult DirectLogin(long id);
|
OperationResult DirectLogin(long id);
|
||||||
|
|
||||||
AccountLeftWorkViewModel WorkshopList(long accountId);
|
// AccountLeftWorkViewModel WorkshopList(long accountId);
|
||||||
OperationResult SaveWorkshopAccount(
|
OperationResult SaveWorkshopAccount(
|
||||||
List<WorkshopAccountlistViewModel> workshopAccountList,
|
List<WorkshopAccountlistViewModel> workshopAccountList,
|
||||||
string startDate,
|
string startDate,
|
||||||
@@ -41,6 +47,8 @@ public interface IAccountApplication
|
|||||||
List<AccountViewModel> GetAccountsByPositionId(long positionId);
|
List<AccountViewModel> GetAccountsByPositionId(long positionId);
|
||||||
|
|
||||||
List<AccountViewModel> GetAccountEqualToLowerPositionValue();
|
List<AccountViewModel> GetAccountEqualToLowerPositionValue();
|
||||||
|
Task<List<AccountSelectListViewModel>> GetAdminSelectList();
|
||||||
|
|
||||||
OperationResult ReLogin();
|
OperationResult ReLogin();
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@@ -62,4 +70,15 @@ public interface IAccountApplication
|
|||||||
/// <param name="userName"></param>
|
/// <param name="userName"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public bool CheckExistClientAccount(string userName);
|
public bool CheckExistClientAccount(string userName);
|
||||||
|
List<AccountViewModel> GetAdminAccountsNew();
|
||||||
|
|
||||||
|
void CameraLogin(CameraLoginRequest request);
|
||||||
|
|
||||||
|
Task<GetPmUserDto> GetPmUserAsync(long accountId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CameraLoginRequest
|
||||||
|
{
|
||||||
|
public string UserName { get; set; }
|
||||||
|
public string Password { get; set; }
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,4 @@
|
|||||||
using System;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using _0_Framework.Application;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
||||||
namespace AccountManagement.Application.Contracts.Account;
|
namespace AccountManagement.Application.Contracts.Account;
|
||||||
|
|||||||
@@ -1,10 +1,4 @@
|
|||||||
using System;
|
namespace AccountManagement.Application.Contracts.Account;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace AccountManagement.Application.Contracts.Account;
|
|
||||||
|
|
||||||
public class WorkshopSelectList
|
public class WorkshopSelectList
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,15 +1,20 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.ViewFeatures" Version="2.2.0" />
|
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.3.0" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.3.0" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Mvc.ViewFeatures" Version="2.3.0" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="10.0.1" />
|
||||||
|
<PackageReference Include="System.Security.Cryptography.Xml" Version="10.0.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\0_Framework\0_Framework.csproj" />
|
<ProjectReference Include="..\0_Framework\0_Framework.csproj" />
|
||||||
|
<ProjectReference Include="..\Shared.Contracts\Shared.Contracts.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -4,12 +4,13 @@ using System.Collections.Generic;
|
|||||||
|
|
||||||
namespace AccountManagement.Application.Contracts.Media
|
namespace AccountManagement.Application.Contracts.Media
|
||||||
{
|
{
|
||||||
public interface IMediaApplication
|
public interface IMediaApplication
|
||||||
{
|
{
|
||||||
MediaViewModel Get(long id);
|
MediaViewModel Get(long id);
|
||||||
OperationResult UploadFile(IFormFile file, string fileLabel, string relativePath, int maximumFileLength, List<string> allowedExtensions);
|
OperationResult UploadFile(IFormFile file, string fileLabel, string relativePath, int maximumFileLength,
|
||||||
OperationResult MoveFile(long mediaId, string newRelativePath);
|
List<string> allowedExtensions, string category);
|
||||||
OperationResult DeleteFile(long mediaId);
|
OperationResult MoveFile(long mediaId, string newRelativePath);
|
||||||
List<MediaViewModel> GetRange(IEnumerable<long> select);
|
OperationResult DeleteFile(long mediaId);
|
||||||
}
|
List<MediaViewModel> GetRange(IEnumerable<long> select);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
namespace AccountManagement.Application.Contracts.ProgramManagerApiResult;
|
||||||
|
|
||||||
|
public record ApiResponse
|
||||||
|
{
|
||||||
|
public bool isSuccess { get; set; }
|
||||||
|
public string errorMessage { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public ErrorType ErrorType { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace AccountManagement.Application.Contracts.ProgramManagerApiResult;
|
||||||
|
|
||||||
|
|
||||||
|
public record CreateProgramManagerRole
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// نام نقش
|
||||||
|
/// </summary>
|
||||||
|
public string RoleName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// کدهای دسترسی
|
||||||
|
/// </summary>
|
||||||
|
public List<int> Permissions { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// آی دی اکانت گزارشگیر
|
||||||
|
/// </summary>
|
||||||
|
public long? GozareshgirRoleId { get; set; }
|
||||||
|
};
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace AccountManagement.Application.Contracts.ProgramManagerApiResult;
|
||||||
|
|
||||||
|
public record CreateProgramManagerUser(string FullName, string UserName, string Password, string Mobile, string Email, long? AccountId, List<long> Roles);
|
||||||
|
|
||||||
|
public record EditUserCommand(string FullName, string UserName, string Mobile, long AccountId, List<long> Roles, bool IsActive);
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
namespace AccountManagement.Application.Contracts.ProgramManagerApiResult;
|
||||||
|
|
||||||
|
public enum ErrorType
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
BadRequest,
|
||||||
|
NotFound,
|
||||||
|
Unauthorized,
|
||||||
|
Validation,
|
||||||
|
InternalServerError
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace AccountManagement.Application.Contracts.ProgramManagerApiResult;
|
||||||
|
|
||||||
|
public class RoleResponse
|
||||||
|
{
|
||||||
|
public bool isSuccess { get; set; }
|
||||||
|
public RolesData data { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RolesData
|
||||||
|
{
|
||||||
|
public List<RoleList> role { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RoleList
|
||||||
|
{
|
||||||
|
public int id { get; set; }
|
||||||
|
public string roleName { get; set; }
|
||||||
|
public int gozareshgirRoleId { get; set; }
|
||||||
|
public List<int> permissions { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using static System.Runtime.InteropServices.JavaScript.JSType;
|
||||||
|
|
||||||
|
namespace AccountManagement.Application.Contracts.ProgramManagerApiResult;
|
||||||
|
|
||||||
|
public record SingleUserResponseResult
|
||||||
|
{
|
||||||
|
public bool isSuccess { get; set; }
|
||||||
|
public SingleUserData Data { get; set; }
|
||||||
|
};
|
||||||
|
|
||||||
|
public record SingleUserData
|
||||||
|
|
||||||
|
{
|
||||||
|
public long id { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// نام و نام خانوادگی
|
||||||
|
/// </summary>
|
||||||
|
public string fullName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// نام کاربری
|
||||||
|
/// </summary>
|
||||||
|
public string userName { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// مسیر عکس پروفایل
|
||||||
|
/// </summary>
|
||||||
|
public string profilePhotoPath { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// شماره موبایل
|
||||||
|
/// </summary>
|
||||||
|
public string mobile { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// فعال/غیر فعال بودن یوزر
|
||||||
|
/// </summary>
|
||||||
|
public bool isActive { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// گذرواژه
|
||||||
|
/// </summary>
|
||||||
|
public string password { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ای دی اکانت کاربر در گزارشگیر
|
||||||
|
/// </summary>
|
||||||
|
public long? accountId { get; set; }
|
||||||
|
|
||||||
|
public List<long> Roles { get; set; }
|
||||||
|
}
|
||||||
@@ -9,6 +9,10 @@ namespace AccountManagement.Application.Contracts.Role
|
|||||||
[Required(ErrorMessage = ValidationMessages.IsRequired)]
|
[Required(ErrorMessage = ValidationMessages.IsRequired)]
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public List<int> Permissions { get; set; }
|
public List<int> Permissions { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// لیست پرمیشن های پروگرام منیجر
|
||||||
|
/// </summary>
|
||||||
|
public List<int> PmPermissions { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,26 @@
|
|||||||
using _0_Framework.Application;
|
using _0_Framework.Application;
|
||||||
|
|
||||||
|
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Shared.Contracts.PmRole.Queries;
|
||||||
|
|
||||||
namespace AccountManagement.Application.Contracts.Role
|
namespace AccountManagement.Application.Contracts.Role
|
||||||
{
|
{
|
||||||
public interface IRoleApplication
|
public interface IRoleApplication
|
||||||
{
|
{
|
||||||
OperationResult Create(CreateRole command);
|
Task<OperationResult> Create(CreateRole command);
|
||||||
OperationResult Edit(EditRole command);
|
Task<OperationResult> Edit(EditRole command);
|
||||||
List<RoleViewModel> List();
|
List<RoleViewModel> List();
|
||||||
EditRole GetDetails(long id);
|
EditRole GetDetails(long id);
|
||||||
|
|
||||||
|
#region ProgramManager
|
||||||
|
|
||||||
|
Task<SelectList> GetPmRoleList(long? gozareshgirRoleId);
|
||||||
|
Task<List<GetPmRolesDto>> GetPmRoleListToEdit(long? gozareshgirRoleId);
|
||||||
|
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,6 @@ namespace AccountManagement.Application.Contracts.SubAccount
|
|||||||
public string PhoneNumber { get; set; }
|
public string PhoneNumber { get; set; }
|
||||||
public string Username { get; set; }
|
public string Username { get; set; }
|
||||||
public string ProfilePhoto { get; set; }
|
public string ProfilePhoto { get; set; }
|
||||||
public List<long> WorkshopIds { get; set; }
|
//public List<long> WorkshopIds { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,5 +8,6 @@ namespace AccountManagement.Application.Contracts.SubAccount
|
|||||||
public string Title { get; set; }
|
public string Title { get; set; }
|
||||||
public long AccountId { get; set; }
|
public long AccountId { get; set; }
|
||||||
public List<int> Permissions { get; set; }
|
public List<int> Permissions { get; set; }
|
||||||
|
public List<long> WorkshopIds { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ namespace AccountManagement.Application.Contracts.SubAccount
|
|||||||
public string PhoneNumber { get; set; }
|
public string PhoneNumber { get; set; }
|
||||||
public string RePassword { get; set; }
|
public string RePassword { get; set; }
|
||||||
public long SubAccountRoleId { get; set; }
|
public long SubAccountRoleId { get; set; }
|
||||||
public List<long> WorkshopIds { get; set; }
|
//public List<long> WorkshopIds { get; set; }
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,5 +7,6 @@ namespace AccountManagement.Application.Contracts.SubAccount
|
|||||||
public long Id { get; set; }
|
public long Id { get; set; }
|
||||||
public string Title { get; set; }
|
public string Title { get; set; }
|
||||||
public List<int> Permissions { get; set; }
|
public List<int> Permissions { get; set; }
|
||||||
|
public List<long> WorkshopIds { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,4 +21,5 @@ public class EditTask:CreateTask
|
|||||||
public List<AccountViewModel> AssignsLists { get; set; }
|
public List<AccountViewModel> AssignsLists { get; set; }
|
||||||
public bool HasTicket { get; set; }
|
public bool HasTicket { get; set; }
|
||||||
public long TaskScheduleId { get; set; }
|
public long TaskScheduleId { get; set; }
|
||||||
|
public bool HasRequest { get; set; }
|
||||||
}
|
}
|
||||||
@@ -48,6 +48,7 @@ public class TaskViewModel
|
|||||||
public bool CanDelete { get; set; }
|
public bool CanDelete { get; set; }
|
||||||
public bool CanAssign { get; set; }
|
public bool CanAssign { get; set; }
|
||||||
public bool CanCheckRequests { get; set; }
|
public bool CanCheckRequests { get; set; }
|
||||||
|
public bool HasRequest { get; set; }
|
||||||
public AssignViewModel AssignedReceiverViewModel { get; set; }
|
public AssignViewModel AssignedReceiverViewModel { get; set; }
|
||||||
|
|
||||||
public TaskScheduleType ScheduleType { get; set; }
|
public TaskScheduleType ScheduleType { get; set; }
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ public class TaskScheduleDetailsViewModel
|
|||||||
public string ContractingPartyName { get; set; }
|
public string ContractingPartyName { get; set; }
|
||||||
public string Title { get; set; }
|
public string Title { get; set; }
|
||||||
public string Description { get; set; }
|
public string Description { get; set; }
|
||||||
|
public string Count { get; set; }
|
||||||
|
public string FirstEndTaskDate { get; set; }
|
||||||
public List<MediaViewModel> Medias { get; set; }
|
public List<MediaViewModel> Medias { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,28 +1,25 @@
|
|||||||
using System;
|
using _0_Framework.Application;
|
||||||
using System.Collections;
|
using _0_Framework.Application.Sms;
|
||||||
using _0_Framework.Application;
|
using _0_Framework.Exceptions;
|
||||||
using AccountManagement.Application.Contracts.Account;
|
using AccountManagement.Application.Contracts.Account;
|
||||||
using AccountManagement.Domain.AccountAgg;
|
using AccountManagement.Domain.AccountAgg;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using _0_Framework.Application.Sms;
|
|
||||||
using AccountManagement.Domain.AccountLeftWorkAgg;
|
using AccountManagement.Domain.AccountLeftWorkAgg;
|
||||||
using AccountManagement.Domain.CameraAccountAgg;
|
using AccountManagement.Domain.CameraAccountAgg;
|
||||||
using AccountManagement.Domain.RoleAgg;
|
|
||||||
using CompanyManagment.App.Contracts.Workshop;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
|
||||||
using static Microsoft.EntityFrameworkCore.DbLoggerCategory.Database;
|
|
||||||
using Company.Domain.WorkshopAgg;
|
|
||||||
using System.Security.Claims;
|
|
||||||
using AccountManagement.Domain.PositionAgg;
|
using AccountManagement.Domain.PositionAgg;
|
||||||
|
using AccountManagement.Domain.RoleAgg;
|
||||||
using AccountManagement.Domain.SubAccountAgg;
|
using AccountManagement.Domain.SubAccountAgg;
|
||||||
using AccountManagement.Domain.SubAccountPermissionSubtitle1Agg;
|
using AccountManagement.Domain.SubAccountPermissionSubtitle1Agg;
|
||||||
using AccountManagement.Domain.SubAccountRoleAgg;
|
using AccountManagement.Domain.SubAccountRoleAgg;
|
||||||
|
using Company.Domain._common;
|
||||||
|
using Company.Domain.WorkshopAgg;
|
||||||
using Company.Domain.WorkshopSubAccountAgg;
|
using Company.Domain.WorkshopSubAccountAgg;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Shared.Contracts.PmUser.Commands;
|
||||||
|
using Shared.Contracts.PmUser.Queries;
|
||||||
|
|
||||||
//using AccountManagement.Domain.RoleAgg;
|
//using AccountManagement.Domain.RoleAgg;
|
||||||
|
|
||||||
@@ -38,15 +35,25 @@ public class AccountApplication : IAccountApplication
|
|||||||
private readonly ISmsService _smsService;
|
private readonly ISmsService _smsService;
|
||||||
private readonly ICameraAccountRepository _cameraAccountRepository;
|
private readonly ICameraAccountRepository _cameraAccountRepository;
|
||||||
private readonly IPositionRepository _positionRepository;
|
private readonly IPositionRepository _positionRepository;
|
||||||
private readonly IAccountLeftworkRepository _accountLeftworkRepository;
|
private readonly IAccountLeftworkRepository _accountLeftworkRepository;
|
||||||
private readonly IWorkshopRepository _workshopRepository;
|
private readonly IWorkshopRepository _workshopRepository;
|
||||||
private readonly ISubAccountRepository _subAccountRepository;
|
private readonly ISubAccountRepository _subAccountRepository;
|
||||||
private readonly ISubAccountRoleRepository _subAccountRoleRepository;
|
private readonly ISubAccountRoleRepository _subAccountRoleRepository;
|
||||||
private readonly IWorkshopSubAccountRepository _workshopSubAccountRepository;
|
private readonly IWorkshopSubAccountRepository _workshopSubAccountRepository;
|
||||||
private readonly ISubAccountPermissionSubtitle1Repository _accountPermissionSubtitle1Repository;
|
private readonly ISubAccountPermissionSubtitle1Repository _accountPermissionSubtitle1Repository;
|
||||||
|
|
||||||
public AccountApplication(IAccountRepository accountRepository, IPasswordHasher passwordHasher,
|
private readonly IUnitOfWork _unitOfWork;
|
||||||
IFileUploader fileUploader, IAuthHelper authHelper, IRoleRepository roleRepository, IWorker worker, ISmsService smsService, ICameraAccountRepository cameraAccountRepository, IPositionRepository positionRepository, IAccountLeftworkRepository accountLeftworkRepository, IWorkshopRepository workshopRepository, ISubAccountRepository subAccountRepository, ISubAccountRoleRepository subAccountRoleRepository, IWorkshopSubAccountRepository workshopSubAccountRepository, ISubAccountPermissionSubtitle1Repository accountPermissionSubtitle1Repository)
|
private readonly IPmUserQueryService _pmUserQueryService;
|
||||||
|
private readonly IPmUserCommandService _pmUserCommandService;
|
||||||
|
|
||||||
|
public AccountApplication(IAccountRepository accountRepository, IPasswordHasher passwordHasher,
|
||||||
|
IFileUploader fileUploader, IAuthHelper authHelper, IRoleRepository roleRepository, IWorker worker,
|
||||||
|
ISmsService smsService, ICameraAccountRepository cameraAccountRepository,
|
||||||
|
IPositionRepository positionRepository, IAccountLeftworkRepository accountLeftworkRepository,
|
||||||
|
IWorkshopRepository workshopRepository, ISubAccountRepository subAccountRepository,
|
||||||
|
ISubAccountRoleRepository subAccountRoleRepository, IWorkshopSubAccountRepository workshopSubAccountRepository,
|
||||||
|
ISubAccountPermissionSubtitle1Repository accountPermissionSubtitle1Repository, IUnitOfWork unitOfWork,
|
||||||
|
IPmUserQueryService pmUserQueryService, IPmUserCommandService pmUserCommandService)
|
||||||
{
|
{
|
||||||
_authHelper = authHelper;
|
_authHelper = authHelper;
|
||||||
_roleRepository = roleRepository;
|
_roleRepository = roleRepository;
|
||||||
@@ -59,10 +66,13 @@ public class AccountApplication : IAccountApplication
|
|||||||
_subAccountRoleRepository = subAccountRoleRepository;
|
_subAccountRoleRepository = subAccountRoleRepository;
|
||||||
_workshopSubAccountRepository = workshopSubAccountRepository;
|
_workshopSubAccountRepository = workshopSubAccountRepository;
|
||||||
_accountPermissionSubtitle1Repository = accountPermissionSubtitle1Repository;
|
_accountPermissionSubtitle1Repository = accountPermissionSubtitle1Repository;
|
||||||
|
_unitOfWork = unitOfWork;
|
||||||
|
|
||||||
|
_pmUserQueryService = pmUserQueryService;
|
||||||
|
_pmUserCommandService = pmUserCommandService;
|
||||||
_fileUploader = fileUploader;
|
_fileUploader = fileUploader;
|
||||||
_passwordHasher = passwordHasher;
|
_passwordHasher = passwordHasher;
|
||||||
_accountRepository = accountRepository;
|
_accountRepository = accountRepository;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public OperationResult EditClient(EditClientAccount command)
|
public OperationResult EditClient(EditClientAccount command)
|
||||||
@@ -83,7 +93,8 @@ public class AccountApplication : IAccountApplication
|
|||||||
(x.Mobile == command.Mobile && x.id != command.Id)))
|
(x.Mobile == command.Mobile && x.id != command.Id)))
|
||||||
return opreation.Failed("شماره موبایل تکراری است");
|
return opreation.Failed("شماره موبایل تکراری است");
|
||||||
if (_accountRepository.Exists(x =>
|
if (_accountRepository.Exists(x =>
|
||||||
(x.NationalCode == command.NationalCode && !string.IsNullOrWhiteSpace(x.NationalCode) && x.id != command.Id)))
|
(x.NationalCode == command.NationalCode && !string.IsNullOrWhiteSpace(x.NationalCode) &&
|
||||||
|
x.id != command.Id)))
|
||||||
return opreation.Failed("کد ملی تکراری است");
|
return opreation.Failed("کد ملی تکراری است");
|
||||||
if (_accountRepository.Exists(x =>
|
if (_accountRepository.Exists(x =>
|
||||||
(x.Email == command.Email && !string.IsNullOrWhiteSpace(x.Email) && x.id != command.Id)))
|
(x.Email == command.Email && !string.IsNullOrWhiteSpace(x.Email) && x.id != command.Id)))
|
||||||
@@ -91,7 +102,8 @@ public class AccountApplication : IAccountApplication
|
|||||||
|
|
||||||
var path = $"profilePhotos";
|
var path = $"profilePhotos";
|
||||||
var picturePath = _fileUploader.Upload(command.ProfilePhoto, path);
|
var picturePath = _fileUploader.Upload(command.ProfilePhoto, path);
|
||||||
editAccount.EditClient(command.Fullname,command.Username,command.Mobile,picturePath,command.Email,command.NationalCode);
|
editAccount.EditClient(command.Fullname, command.Username, command.Mobile, picturePath, command.Email,
|
||||||
|
command.NationalCode);
|
||||||
_accountRepository.SaveChanges();
|
_accountRepository.SaveChanges();
|
||||||
return opreation.Succcedded();
|
return opreation.Succcedded();
|
||||||
}
|
}
|
||||||
@@ -122,7 +134,7 @@ public class AccountApplication : IAccountApplication
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public OperationResult Create(CreateAccount command)
|
public async Task<OperationResult> Create(CreateAccount command)
|
||||||
{
|
{
|
||||||
var operation = new OperationResult();
|
var operation = new OperationResult();
|
||||||
|
|
||||||
@@ -132,15 +144,59 @@ public class AccountApplication : IAccountApplication
|
|||||||
var password = _passwordHasher.Hash(command.Password);
|
var password = _passwordHasher.Hash(command.Password);
|
||||||
var roleName = _roleRepository.GetDetails(command.RoleId);
|
var roleName = _roleRepository.GetDetails(command.RoleId);
|
||||||
var path = $"profilePhotos";
|
var path = $"profilePhotos";
|
||||||
|
var picturePath = "";
|
||||||
if (_fileUploader != null)
|
if (_fileUploader != null)
|
||||||
{
|
{
|
||||||
var picturePath = _fileUploader.Upload(command.ProfilePhoto, path);
|
picturePath = _fileUploader.Upload(command.ProfilePhoto, path);
|
||||||
var account = new Account(command.Fullname, command.Username, password, command.Mobile, command.RoleId,
|
|
||||||
picturePath, roleName.Name,"true","false");
|
|
||||||
_accountRepository.Create(account);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var account = new Account(command.Fullname, command.Username, password, command.Mobile, command.RoleId,
|
||||||
|
picturePath, roleName.Name, "true", "false");
|
||||||
|
|
||||||
|
_unitOfWork.BeginAccountContext();
|
||||||
|
|
||||||
|
|
||||||
|
_accountRepository.Create(account);
|
||||||
_accountRepository.SaveChanges();
|
_accountRepository.SaveChanges();
|
||||||
|
|
||||||
|
if (command.IsProgramManagerUser)
|
||||||
|
{
|
||||||
|
if (command.UserRoles == null)
|
||||||
|
return operation.Failed("حداقل یک نقش برای کاربر مدیریت پروژه لازم است");
|
||||||
|
var pmUserRoles = command.UserRoles.Where(x => x > 0).ToList();
|
||||||
|
var createPm = await _pmUserCommandService.Create(new CreatePmUserDto(command.Fullname, command.Username,
|
||||||
|
account.Password, command.Mobile,
|
||||||
|
null, account.id, pmUserRoles));
|
||||||
|
if (!createPm.isSuccess)
|
||||||
|
{
|
||||||
|
_unitOfWork.RollbackAccountContext();
|
||||||
|
return operation.Failed("خطا در ویرایش کاربر پروگرام منیجر");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//var url = "api/user/create";
|
||||||
|
//var key = SecretKeys.ProgramManagerInternalApi;
|
||||||
|
|
||||||
|
//var response = InternalApiCaller.PostAsync<CreateProgramManagerUser, ApiResponse>(
|
||||||
|
// url,
|
||||||
|
// key,
|
||||||
|
// parameters
|
||||||
|
//);
|
||||||
|
|
||||||
|
//if (!response.Success)
|
||||||
|
//{
|
||||||
|
// _unitOfWork.RollbackAccountContext();
|
||||||
|
// return operation.Failed(response.Error);
|
||||||
|
//}
|
||||||
|
|
||||||
|
//if (!response.Result.isSuccess)
|
||||||
|
//{
|
||||||
|
// _unitOfWork.RollbackAccountContext();
|
||||||
|
// return operation.Failed(response.Result.errorMessage);
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
_unitOfWork.CommitAccountContext();
|
||||||
return operation.Succcedded();
|
return operation.Succcedded();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,8 +210,8 @@ public class AccountApplication : IAccountApplication
|
|||||||
return opreation.Failed("پر کردن تمامی فیلدها الزامی است");
|
return opreation.Failed("پر کردن تمامی فیلدها الزامی است");
|
||||||
if (_accountRepository.Exists(x => x.Username == command.Username))
|
if (_accountRepository.Exists(x => x.Username == command.Username))
|
||||||
return opreation.Failed("نام کاربری تکراری است");
|
return opreation.Failed("نام کاربری تکراری است");
|
||||||
if (_accountRepository.Exists(x => x.Mobile == command.Mobile && x.IsActiveString =="true"))
|
if (_accountRepository.Exists(x => x.Mobile == command.Mobile && x.IsActiveString == "true"))
|
||||||
|
|
||||||
return opreation.Failed("مقادیر وارد شده تکراری است");
|
return opreation.Failed("مقادیر وارد شده تکراری است");
|
||||||
|
|
||||||
//var nationalCodeValidation = command.NationalCode.NationalCodeValid();
|
//var nationalCodeValidation = command.NationalCode.NationalCodeValid();
|
||||||
@@ -172,14 +228,14 @@ public class AccountApplication : IAccountApplication
|
|||||||
// break;
|
// break;
|
||||||
//}
|
//}
|
||||||
var password = _passwordHasher.Hash(command.Password);
|
var password = _passwordHasher.Hash(command.Password);
|
||||||
var register =new Account(command.Fullname,command.Username, password, command.Mobile, command.NationalCode);
|
var register = new Account(command.Fullname, command.Username, password, command.Mobile, command.NationalCode);
|
||||||
_accountRepository.Create(register);
|
_accountRepository.Create(register);
|
||||||
_accountRepository.SaveChanges();
|
_accountRepository.SaveChanges();
|
||||||
|
|
||||||
return opreation.Succcedded(register.id,message: "ثبت نام شما با موفقیت انجام شد");
|
return opreation.Succcedded(register.id, message: "ثبت نام شما با موفقیت انجام شد");
|
||||||
}
|
}
|
||||||
|
|
||||||
public OperationResult Edit(EditAccount command)
|
public async Task<OperationResult> Edit(EditAccount command)
|
||||||
{
|
{
|
||||||
var operation = new OperationResult();
|
var operation = new OperationResult();
|
||||||
var account = _accountRepository.Get(command.Id);
|
var account = _accountRepository.Get(command.Id);
|
||||||
@@ -193,8 +249,124 @@ public class AccountApplication : IAccountApplication
|
|||||||
var roleName = _roleRepository.GetDetails(command.RoleId);
|
var roleName = _roleRepository.GetDetails(command.RoleId);
|
||||||
var path = $"profilePhotos";
|
var path = $"profilePhotos";
|
||||||
var picturePath = _fileUploader.Upload(command.ProfilePhoto, path);
|
var picturePath = _fileUploader.Upload(command.ProfilePhoto, path);
|
||||||
|
_unitOfWork.BeginAccountContext();
|
||||||
account.Edit(command.Fullname, command.Username, command.Mobile, command.RoleId, picturePath, roleName.Name);
|
account.Edit(command.Fullname, command.Username, command.Mobile, command.RoleId, picturePath, roleName.Name);
|
||||||
_accountRepository.SaveChanges();
|
_accountRepository.SaveChanges();
|
||||||
|
var key = SecretKeys.ProgramManagerInternalApi;
|
||||||
|
|
||||||
|
//var apiResult = InternalApiCaller.GetAsync<SingleUserResponseResult>(
|
||||||
|
// $"api/user/{account.id}",
|
||||||
|
// key
|
||||||
|
//);
|
||||||
|
var userResult = await _pmUserQueryService.GetPmUserDataByAccountId(account.id);
|
||||||
|
|
||||||
|
if (command.UserRoles == null)
|
||||||
|
return operation.Failed("حداقل یک نقش برای کاربر مدیریت پروژه لازم است");
|
||||||
|
var pmUserRoles = command.UserRoles.Where(x => x > 0).ToList();
|
||||||
|
|
||||||
|
//اگر کاربر در پروگرام منیجر قبلا ایجاد شده
|
||||||
|
if (userResult.Id > 0)
|
||||||
|
{
|
||||||
|
if (!command.UserRoles.Any())
|
||||||
|
{
|
||||||
|
_unitOfWork.RollbackAccountContext();
|
||||||
|
return operation.Failed("حداقل یک نقش باید انتخاب شود");
|
||||||
|
}
|
||||||
|
|
||||||
|
var editPm = await _pmUserCommandService.Edit(new EditPmUserDto(command.Fullname, command.Username,
|
||||||
|
command.Mobile, account.id, pmUserRoles,
|
||||||
|
command.IsProgramManagerUser));
|
||||||
|
if (!editPm.isSuccess)
|
||||||
|
{
|
||||||
|
_unitOfWork.RollbackAccountContext();
|
||||||
|
return operation.Failed("خطا در ویرایش کاربر پروگرام منیجر");
|
||||||
|
}
|
||||||
|
|
||||||
|
//var parameters = new EditUserCommand(
|
||||||
|
// command.Fullname,
|
||||||
|
// command.Username,
|
||||||
|
// command.Mobile,
|
||||||
|
// account.id,
|
||||||
|
// command.UserRoles,
|
||||||
|
// command.IsProgramManagerUser
|
||||||
|
//);
|
||||||
|
//var url = "api/user/edit";
|
||||||
|
//var response = InternalApiCaller.PostAsync<EditUserCommand, ApiResponse>(
|
||||||
|
// url,
|
||||||
|
// key,
|
||||||
|
// parameters
|
||||||
|
//);
|
||||||
|
|
||||||
|
//if (!response.Success)
|
||||||
|
//{
|
||||||
|
// _unitOfWork.RollbackAccountContext();
|
||||||
|
// return operation.Failed(response.Error);
|
||||||
|
|
||||||
|
//}
|
||||||
|
|
||||||
|
//if (!response.Result.isSuccess)
|
||||||
|
//{
|
||||||
|
// _unitOfWork.RollbackAccountContext();
|
||||||
|
// return operation.Failed(response.Error);
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
else //اگر کاربر قبلا ایجاد نشده
|
||||||
|
{
|
||||||
|
//اگر تیک فعالیت در پروگرام منیجر روشن بود
|
||||||
|
if (command.IsProgramManagerUser)
|
||||||
|
{
|
||||||
|
if (!command.UserRoles.Any())
|
||||||
|
{
|
||||||
|
_unitOfWork.RollbackAccountContext();
|
||||||
|
return operation.Failed("حداقل یک نقش باید انتخاب شود");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var createPm = await _pmUserCommandService.Create(new CreatePmUserDto(command.Fullname,
|
||||||
|
command.Username, account.Password, command.Mobile,
|
||||||
|
null, account.id, pmUserRoles));
|
||||||
|
if (!createPm.isSuccess)
|
||||||
|
{
|
||||||
|
_unitOfWork.RollbackAccountContext();
|
||||||
|
return operation.Failed("خطا در ویرایش کاربر پروگرام منیجر");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//var parameters = new CreateProgramManagerUser(
|
||||||
|
// command.Fullname,
|
||||||
|
// command.Username,
|
||||||
|
// account.Password,
|
||||||
|
// command.Mobile,
|
||||||
|
// command.Email,
|
||||||
|
// account.id,
|
||||||
|
// command.UserRoles
|
||||||
|
//);
|
||||||
|
|
||||||
|
//var url = "api/user/Create";
|
||||||
|
|
||||||
|
|
||||||
|
//var response = InternalApiCaller.PostAsync<CreateProgramManagerUser, ApiResponse>(
|
||||||
|
// url,
|
||||||
|
// key,
|
||||||
|
// parameters
|
||||||
|
//);
|
||||||
|
|
||||||
|
//if (!response.Success)
|
||||||
|
//{
|
||||||
|
// _unitOfWork.RollbackAccountContext();
|
||||||
|
// return operation.Failed(response.Error);
|
||||||
|
|
||||||
|
//}
|
||||||
|
|
||||||
|
//if (!response.Result.isSuccess)
|
||||||
|
//{
|
||||||
|
// _unitOfWork.RollbackAccountContext();
|
||||||
|
// return operation.Failed(response.Error);
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_unitOfWork.CommitAccountContext();
|
||||||
return operation.Succcedded();
|
return operation.Succcedded();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,22 +377,21 @@ public class AccountApplication : IAccountApplication
|
|||||||
|
|
||||||
public OperationResult Login(Login command)
|
public OperationResult Login(Login command)
|
||||||
{
|
{
|
||||||
|
|
||||||
long idAutoriz = 0;
|
long idAutoriz = 0;
|
||||||
var operation = new OperationResult();
|
var operation = new OperationResult();
|
||||||
if (string.IsNullOrWhiteSpace(command.Password))
|
if (string.IsNullOrWhiteSpace(command.Password))
|
||||||
return operation.Failed(ApplicationMessages.EmptyPassword);
|
return operation.Failed(ApplicationMessages.EmptyPassword);
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(command.Username))
|
if (string.IsNullOrWhiteSpace(command.Username))
|
||||||
return operation.Failed(ApplicationMessages.EmptyUsername);
|
return operation.Failed(ApplicationMessages.EmptyUsername);
|
||||||
|
|
||||||
var account = _accountRepository.GetBy(command.Username);
|
var account = _accountRepository.GetBy(command.Username);
|
||||||
var cameraAccount = _cameraAccountRepository.GetBy(command.Username);
|
var cameraAccount = _cameraAccountRepository.GetBy(command.Username);
|
||||||
SubAccount subAccount = _subAccountRepository.GetBy(command.Username);
|
SubAccount subAccount = _subAccountRepository.GetBy(command.Username);
|
||||||
if (account == null && cameraAccount == null && subAccount == null)
|
if (account == null && cameraAccount == null && subAccount == null)
|
||||||
return operation.Failed(ApplicationMessages.WrongUserPass);
|
return operation.Failed(ApplicationMessages.WrongUserPass);
|
||||||
|
|
||||||
if (account != null)
|
if (account != null)
|
||||||
{
|
{
|
||||||
(bool Verified, bool NeedUpgrade) result = _passwordHasher.Check(account.Password, command.Password);
|
(bool Verified, bool NeedUpgrade) result = _passwordHasher.Check(account.Password, command.Password);
|
||||||
if (!result.Verified)
|
if (!result.Verified)
|
||||||
@@ -229,6 +400,29 @@ public class AccountApplication : IAccountApplication
|
|||||||
.Permissions
|
.Permissions
|
||||||
.Select(x => x.Code)
|
.Select(x => x.Code)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
//PmPermission
|
||||||
|
var PmUserData = _pmUserQueryService.GetPmUserDataByAccountId(account.id)
|
||||||
|
.GetAwaiter().GetResult();
|
||||||
|
long? pmUserId = null;
|
||||||
|
if (PmUserData != null)
|
||||||
|
{
|
||||||
|
if (PmUserData.AccountId > 0 && PmUserData.IsActive)
|
||||||
|
{
|
||||||
|
var pmUserPermissions =
|
||||||
|
PmUserData.RoleListDto != null
|
||||||
|
? PmUserData.RoleListDto
|
||||||
|
.SelectMany(x => x.Permissions)
|
||||||
|
.Where(p => p != 99)
|
||||||
|
.Distinct()
|
||||||
|
.ToList()
|
||||||
|
: new List<int>();
|
||||||
|
permissions.AddRange(pmUserPermissions);
|
||||||
|
}
|
||||||
|
|
||||||
|
pmUserId = PmUserData.Id > 0 ? PmUserData.Id : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int? positionValue;
|
int? positionValue;
|
||||||
if (account.PositionId != null)
|
if (account.PositionId != null)
|
||||||
{
|
{
|
||||||
@@ -238,36 +432,45 @@ public class AccountApplication : IAccountApplication
|
|||||||
{
|
{
|
||||||
positionValue = null;
|
positionValue = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var authViewModel = new AuthViewModel(account.id, account.RoleId, account.Fullname
|
var authViewModel = new AuthViewModel(account.id, account.RoleId, account.Fullname
|
||||||
, account.Username, account.Mobile, account.ProfilePhoto, permissions, account.RoleName, account.AdminAreaPermission, account.ClientAriaPermission, positionValue);
|
, account.Username, account.Mobile, account.ProfilePhoto,
|
||||||
|
permissions, account.RoleName, account.AdminAreaPermission,
|
||||||
|
account.ClientAriaPermission, positionValue, 0, pmUserId);
|
||||||
|
|
||||||
if (account.ClientAriaPermission == "true" && account.AdminAreaPermission == "false" &&
|
if (account.ClientAriaPermission == "true" && account.AdminAreaPermission == "false" &&
|
||||||
account.IsActiveString == "true")
|
account.IsActiveString == "true")
|
||||||
{
|
{
|
||||||
var clientPermissions = _accountPermissionSubtitle1Repository.GetAllPermissionCodes();
|
var clientPermissions = _accountPermissionSubtitle1Repository.GetAllPermissionCodes();
|
||||||
authViewModel.Permissions = clientPermissions;
|
authViewModel.Permissions = clientPermissions;
|
||||||
var workshopList = _workshopRepository.GetWorkshopsByClientAccountId(account.id).Select(x => new WorkshopClaim
|
var workshopList = _workshopRepository.GetWorkshopsByClientAccountId(account.id).Select(x =>
|
||||||
{
|
new WorkshopClaim
|
||||||
PersonnelCount = x.PersonnelCount,
|
{
|
||||||
Id = x.Id,
|
PersonnelCount = x.PersonnelCount,
|
||||||
Name = x.WorkshopFullName,
|
Id = x.Id,
|
||||||
Slug = _passwordHasher.SlugHasher(x.Id)
|
Name = x.WorkshopFullName,
|
||||||
}).OrderByDescending(x => x.PersonnelCount).ToList();
|
Slug = _passwordHasher.SlugHasher(x.Id)
|
||||||
|
}).OrderByDescending(x => x.PersonnelCount).ToList();
|
||||||
authViewModel.WorkshopList = workshopList;
|
authViewModel.WorkshopList = workshopList;
|
||||||
if (workshopList.Any())
|
if (workshopList.Any())
|
||||||
{
|
{
|
||||||
var workshop = workshopList.First();
|
var workshop = workshopList.First();
|
||||||
authViewModel.WorkshopName = workshop.Name;
|
authViewModel.WorkshopName = workshop.Name;
|
||||||
authViewModel.WorkshopSlug = _passwordHasher.SlugHasher(workshop.Id);
|
authViewModel.WorkshopSlug = _passwordHasher.SlugHasher(workshop.Id);
|
||||||
}
|
authViewModel.WorkshopId = workshop.Id;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_authHelper.Signin(authViewModel);
|
_authHelper.Signin(authViewModel);
|
||||||
|
|
||||||
if ((account.AdminAreaPermission == "true" && account.ClientAriaPermission == "true" && account.IsActiveString == "true") || (account.AdminAreaPermission == "true" && account.ClientAriaPermission == "false" && account.IsActiveString == "true"))
|
if ((account.AdminAreaPermission == "true" && account.ClientAriaPermission == "true" &&
|
||||||
|
account.IsActiveString == "true") || (account.AdminAreaPermission == "true" &&
|
||||||
|
account.ClientAriaPermission == "false" &&
|
||||||
|
account.IsActiveString == "true"))
|
||||||
idAutoriz = 1;
|
idAutoriz = 1;
|
||||||
|
|
||||||
if (account.ClientAriaPermission == "true" && account.AdminAreaPermission == "false" && account.IsActiveString == "true")
|
if (account.ClientAriaPermission == "true" && account.AdminAreaPermission == "false" &&
|
||||||
|
account.IsActiveString == "true")
|
||||||
idAutoriz = 2;
|
idAutoriz = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -279,7 +482,8 @@ public class AccountApplication : IAccountApplication
|
|||||||
|
|
||||||
var mobile = string.IsNullOrWhiteSpace(cameraAccount.Mobile) ? " " : cameraAccount.Mobile;
|
var mobile = string.IsNullOrWhiteSpace(cameraAccount.Mobile) ? " " : cameraAccount.Mobile;
|
||||||
var authViewModel = new CameraAuthViewModel(cameraAccount.id, cameraAccount.WorkshopId,
|
var authViewModel = new CameraAuthViewModel(cameraAccount.id, cameraAccount.WorkshopId,
|
||||||
cameraAccount.Username, mobile, cameraAccount.WorkshopName, cameraAccount.AccountId,cameraAccount.IsActiveSting);
|
cameraAccount.Username, mobile, cameraAccount.WorkshopName, cameraAccount.AccountId,
|
||||||
|
cameraAccount.IsActiveSting);
|
||||||
if (cameraAccount.IsActiveSting == "true")
|
if (cameraAccount.IsActiveSting == "true")
|
||||||
{
|
{
|
||||||
_authHelper.CameraSignIn(authViewModel);
|
_authHelper.CameraSignIn(authViewModel);
|
||||||
@@ -289,41 +493,43 @@ public class AccountApplication : IAccountApplication
|
|||||||
{
|
{
|
||||||
idAutoriz = 0;
|
idAutoriz = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (subAccount != null)
|
if (subAccount != null)
|
||||||
{
|
{
|
||||||
(bool Verified, bool NeedUpgrade) result = _passwordHasher.Check(subAccount.Password, command.Password);
|
(bool Verified, bool NeedUpgrade) result = _passwordHasher.Check(subAccount.Password, command.Password);
|
||||||
if (!result.Verified)
|
if (!result.Verified)
|
||||||
return operation.Failed(ApplicationMessages.WrongUserPass);
|
return operation.Failed(ApplicationMessages.WrongUserPass);
|
||||||
var role = _subAccountRoleRepository.Get(subAccount.SubAccountRoleId);
|
var role = _subAccountRoleRepository.Get(subAccount.SubAccountRoleId);
|
||||||
|
|
||||||
var permissions = role.RolePermissions.Select(x => x.PermissionCode).ToList();
|
var permissions = role.RolePermissions.Select(x => x.PermissionCode).ToList();
|
||||||
var authViewModel = new AuthViewModel(subAccount.AccountId, subAccount.SubAccountRoleId, subAccount.FullName
|
var authViewModel = new AuthViewModel(subAccount.AccountId, subAccount.SubAccountRoleId, subAccount.FullName
|
||||||
, subAccount.Username, subAccount.PhoneNumber, "", permissions, role.Title, "false",
|
, subAccount.Username, subAccount.PhoneNumber, "", permissions, role.Title, "false",
|
||||||
"true", 0, subAccount.id);
|
"true", 0, subAccount.id);
|
||||||
var workshopList = _workshopSubAccountRepository.GetWorkshopsBySubAccountId(subAccount.id);
|
var workshopList = _workshopSubAccountRepository.GetWorkshopsBySubAccountId(subAccount.id);
|
||||||
authViewModel.WorkshopList = workshopList.Select(x => new WorkshopClaim()
|
authViewModel.WorkshopList = workshopList.Select(x => new WorkshopClaim()
|
||||||
{
|
{
|
||||||
Slug = _passwordHasher.SlugHasher(x.WorkshopId),
|
Slug = _passwordHasher.SlugHasher(x.WorkshopId),
|
||||||
Name = x.WorkshopName,
|
Name = x.WorkshopName,
|
||||||
PersonnelCount = 0,
|
PersonnelCount = x.PersonnelCount,
|
||||||
Id = x.WorkshopId
|
Id = x.WorkshopId
|
||||||
}).ToList();
|
}).ToList();
|
||||||
|
|
||||||
if (workshopList.Any())
|
if (workshopList.Any())
|
||||||
{
|
{
|
||||||
var workshop = workshopList.First();
|
var workshop = workshopList.First();
|
||||||
authViewModel.WorkshopName = workshop.WorkshopName;
|
authViewModel.WorkshopName = workshop.WorkshopName;
|
||||||
authViewModel.WorkshopSlug = _passwordHasher.SlugHasher(workshop.WorkshopId);
|
authViewModel.WorkshopSlug = _passwordHasher.SlugHasher(workshop.WorkshopId);
|
||||||
}
|
authViewModel.WorkshopId = workshop.WorkshopId;
|
||||||
_authHelper.Signin(authViewModel);
|
}
|
||||||
idAutoriz = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
return operation.Succcedded(idAutoriz);
|
_authHelper.Signin(authViewModel);
|
||||||
|
idAutoriz = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return operation.Succcedded(idAutoriz);
|
||||||
}
|
}
|
||||||
|
|
||||||
public OperationResult LoginWithMobile(long id)
|
public OperationResult LoginWithMobile(long id)
|
||||||
{
|
{
|
||||||
var operation = new OperationResult();
|
var operation = new OperationResult();
|
||||||
@@ -332,7 +538,6 @@ public class AccountApplication : IAccountApplication
|
|||||||
return operation.Failed(ApplicationMessages.WrongUserPass);
|
return operation.Failed(ApplicationMessages.WrongUserPass);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var permissions = _roleRepository.Get(account.RoleId)
|
var permissions = _roleRepository.Get(account.RoleId)
|
||||||
.Permissions
|
.Permissions
|
||||||
.Select(x => x.Code)
|
.Select(x => x.Code)
|
||||||
@@ -348,38 +553,43 @@ public class AccountApplication : IAccountApplication
|
|||||||
}
|
}
|
||||||
|
|
||||||
var authViewModel = new AuthViewModel(account.id, account.RoleId, account.Fullname
|
var authViewModel = new AuthViewModel(account.id, account.RoleId, account.Fullname
|
||||||
, account.Username, account.Mobile, account.ProfilePhoto, permissions, account.RoleName, account.AdminAreaPermission, account.ClientAriaPermission, positionValue);
|
, account.Username, account.Mobile, account.ProfilePhoto, permissions, account.RoleName,
|
||||||
|
account.AdminAreaPermission, account.ClientAriaPermission, positionValue);
|
||||||
|
|
||||||
if (account.ClientAriaPermission == "true" && account.AdminAreaPermission == "false" &&
|
if (account.ClientAriaPermission == "true" && account.AdminAreaPermission == "false" &&
|
||||||
account.IsActiveString == "true")
|
account.IsActiveString == "true")
|
||||||
{
|
{
|
||||||
var clientPermissions = _accountPermissionSubtitle1Repository.GetAllPermissionCodes();
|
var clientPermissions = _accountPermissionSubtitle1Repository.GetAllPermissionCodes();
|
||||||
authViewModel.Permissions = clientPermissions;
|
authViewModel.Permissions = clientPermissions;
|
||||||
var workshopList = _workshopRepository.GetWorkshopsByClientAccountId(account.id).Select(x => new WorkshopClaim
|
var workshopList = _workshopRepository.GetWorkshopsByClientAccountId(account.id).Select(x =>
|
||||||
{
|
new WorkshopClaim
|
||||||
PersonnelCount = x.PersonnelCount,
|
{
|
||||||
Id = x.Id,
|
PersonnelCount = x.PersonnelCount,
|
||||||
Name = x.WorkshopFullName,
|
Id = x.Id,
|
||||||
Slug = _passwordHasher.SlugHasher(x.Id)
|
Name = x.WorkshopFullName,
|
||||||
}).OrderByDescending(x => x.PersonnelCount).ToList();
|
Slug = _passwordHasher.SlugHasher(x.Id)
|
||||||
authViewModel.WorkshopList = workshopList;
|
}).OrderByDescending(x => x.PersonnelCount).ToList();
|
||||||
if (workshopList.Any())
|
authViewModel.WorkshopList = workshopList;
|
||||||
{
|
if (workshopList.Any())
|
||||||
var workshop = workshopList.First();
|
{
|
||||||
authViewModel.WorkshopName = workshop.Name;
|
var workshop = workshopList.First();
|
||||||
authViewModel.WorkshopSlug = _passwordHasher.SlugHasher(workshop.Id);
|
authViewModel.WorkshopName = workshop.Name;
|
||||||
}
|
authViewModel.WorkshopSlug = _passwordHasher.SlugHasher(workshop.Id);
|
||||||
}
|
authViewModel.WorkshopId = workshop.Id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_authHelper.Signin(authViewModel);
|
_authHelper.Signin(authViewModel);
|
||||||
long idAutoriz = 0;
|
long idAutoriz = 0;
|
||||||
if (account.AdminAreaPermission == "true" && account.ClientAriaPermission == "true" || account.AdminAreaPermission == "true" && account.ClientAriaPermission == "false")
|
if (account.AdminAreaPermission == "true" && account.ClientAriaPermission == "true" ||
|
||||||
|
account.AdminAreaPermission == "true" && account.ClientAriaPermission == "false")
|
||||||
idAutoriz = 1;
|
idAutoriz = 1;
|
||||||
|
|
||||||
if (account.ClientAriaPermission == "true" && account.AdminAreaPermission == "false")
|
if (account.ClientAriaPermission == "true" && account.AdminAreaPermission == "false")
|
||||||
idAutoriz = 2;
|
idAutoriz = 2;
|
||||||
return operation.Succcedded(idAutoriz);
|
return operation.Succcedded(idAutoriz);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Logout()
|
public void Logout()
|
||||||
{
|
{
|
||||||
_authHelper.SignOut();
|
_authHelper.SignOut();
|
||||||
@@ -415,6 +625,7 @@ public class AccountApplication : IAccountApplication
|
|||||||
_accountRepository.SaveChanges();
|
_accountRepository.SaveChanges();
|
||||||
return operation.Succcedded();
|
return operation.Succcedded();
|
||||||
}
|
}
|
||||||
|
|
||||||
public EditAccount GetByVerifyCode(string code, string phone)
|
public EditAccount GetByVerifyCode(string code, string phone)
|
||||||
{
|
{
|
||||||
return _accountRepository.GetByVerifyCode(code, phone);
|
return _accountRepository.GetByVerifyCode(code, phone);
|
||||||
@@ -425,7 +636,7 @@ public class AccountApplication : IAccountApplication
|
|||||||
return _accountRepository.GetByUserNameAndId(id, username);
|
return _accountRepository.GetByUserNameAndId(id, username);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task <OperationResult> SetVerifyCode(string phone, long id)
|
public async Task<OperationResult> SetVerifyCode(string phone, long id)
|
||||||
{
|
{
|
||||||
var operation = new OperationResult();
|
var operation = new OperationResult();
|
||||||
var account = _accountRepository.Get(id);
|
var account = _accountRepository.Get(id);
|
||||||
@@ -439,11 +650,10 @@ public class AccountApplication : IAccountApplication
|
|||||||
_smsService.LoginSend(phone, r);
|
_smsService.LoginSend(phone, r);
|
||||||
|
|
||||||
//TimeSpan delay = TimeSpan.FromSeconds(30);
|
//TimeSpan delay = TimeSpan.FromSeconds(30);
|
||||||
|
|
||||||
await _accountRepository.RemoveCode(id);
|
await _accountRepository.RemoveCode(id);
|
||||||
|
|
||||||
return operation.Succcedded();
|
return operation.Succcedded();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -488,88 +698,89 @@ public class AccountApplication : IAccountApplication
|
|||||||
return operation.Failed("این اکانت وجود ندارد");
|
return operation.Failed("این اکانت وجود ندارد");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var permissions = _roleRepository.Get(account.RoleId)
|
var permissions = _roleRepository.Get(account.RoleId)
|
||||||
.Permissions
|
.Permissions
|
||||||
.Select(x => x.Code)
|
.Select(x => x.Code)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
|
|
||||||
_authHelper.SignOut();
|
_authHelper.SignOut();
|
||||||
var authViewModel = new AuthViewModel(account.id, account.RoleId, account.Fullname
|
var authViewModel = new AuthViewModel(account.id, account.RoleId, account.Fullname
|
||||||
, account.Username, account.Mobile, account.ProfilePhoto, permissions, account.RoleName, "false", "true",null);
|
, account.Username, account.Mobile, account.ProfilePhoto, permissions, account.RoleName, "false", "true",
|
||||||
var workshopList = _workshopRepository.GetWorkshopsByClientAccountId(account.id).Select(x => new WorkshopClaim
|
null);
|
||||||
{
|
var workshopList = _workshopRepository.GetWorkshopsByClientAccountId(account.id).Select(x => new WorkshopClaim
|
||||||
PersonnelCount = x.PersonnelCount,
|
{
|
||||||
Id = x.Id,
|
PersonnelCount = x.PersonnelCount,
|
||||||
Name = x.WorkshopFullName,
|
Id = x.Id,
|
||||||
Slug = _passwordHasher.SlugHasher(x.Id)
|
Name = x.WorkshopFullName,
|
||||||
}).OrderByDescending(x => x.PersonnelCount).ToList();
|
Slug = _passwordHasher.SlugHasher(x.Id)
|
||||||
|
}).OrderByDescending(x => x.PersonnelCount).ToList();
|
||||||
|
|
||||||
authViewModel.WorkshopList = workshopList;
|
authViewModel.WorkshopList = workshopList;
|
||||||
|
|
||||||
var clientPermissions = _accountPermissionSubtitle1Repository.GetAllPermissionCodes();
|
var clientPermissions = _accountPermissionSubtitle1Repository.GetAllPermissionCodes();
|
||||||
authViewModel.Permissions = clientPermissions;
|
authViewModel.Permissions = clientPermissions;
|
||||||
if (authViewModel.WorkshopList.Any())
|
if (authViewModel.WorkshopList.Any())
|
||||||
{
|
{
|
||||||
var workshop = authViewModel.WorkshopList.First();
|
var workshop = authViewModel.WorkshopList.First();
|
||||||
authViewModel.WorkshopSlug = _passwordHasher.SlugHasher(workshop.Id);
|
authViewModel.WorkshopSlug = _passwordHasher.SlugHasher(workshop.Id);
|
||||||
authViewModel.WorkshopName = workshop.Name;
|
authViewModel.WorkshopName = workshop.Name;
|
||||||
}
|
authViewModel.WorkshopId = workshop.Id;
|
||||||
_authHelper.Signin(authViewModel);
|
}
|
||||||
|
|
||||||
|
_authHelper.Signin(authViewModel);
|
||||||
return operation.Succcedded(2);
|
return operation.Succcedded(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public OperationResult DirectCameraLogin(long cameraAccountId)
|
public OperationResult DirectCameraLogin(long cameraAccountId)
|
||||||
{
|
{
|
||||||
var prAcc = _authHelper.CurrentAccountInfo();
|
var prAcc = _authHelper.CurrentAccountInfo();
|
||||||
var operation = new OperationResult();
|
var operation = new OperationResult();
|
||||||
var cameraAccount = _cameraAccountRepository.GetById(cameraAccountId);
|
var cameraAccount = _cameraAccountRepository.GetById(cameraAccountId);
|
||||||
if (cameraAccount == null)
|
if (cameraAccount == null)
|
||||||
return operation.Failed("این اکانت وجود ندارد");
|
return operation.Failed("این اکانت وجود ندارد");
|
||||||
|
|
||||||
|
|
||||||
|
_authHelper.SignOut();
|
||||||
|
|
||||||
|
|
||||||
|
var mobile = string.IsNullOrWhiteSpace(cameraAccount.Mobile) ? " " : cameraAccount.Mobile;
|
||||||
_authHelper.SignOut();
|
var authViewModel = new CameraAuthViewModel(cameraAccount.id, cameraAccount.WorkshopId,
|
||||||
|
cameraAccount.Username, mobile, cameraAccount.WorkshopName, cameraAccount.AccountId,
|
||||||
|
cameraAccount.IsActiveSting);
|
||||||
var mobile = string.IsNullOrWhiteSpace(cameraAccount.Mobile) ? " " : cameraAccount.Mobile;
|
if (cameraAccount.IsActiveSting == "true")
|
||||||
var authViewModel = new CameraAuthViewModel(cameraAccount.id, cameraAccount.WorkshopId,
|
|
||||||
cameraAccount.Username, mobile, cameraAccount.WorkshopName, cameraAccount.AccountId, cameraAccount.IsActiveSting);
|
|
||||||
if (cameraAccount.IsActiveSting == "true")
|
|
||||||
{
|
|
||||||
_authHelper.CameraSignIn(authViewModel);
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return operation.Failed("این اکانت غیر فعال شده است");
|
|
||||||
}
|
|
||||||
return operation.Succcedded(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public AccountLeftWorkViewModel WorkshopList(long accountId)
|
|
||||||
{
|
|
||||||
string fullname = this._accountRepository.GetById(accountId).Fullname;
|
|
||||||
List<WorkshopAccountlistViewModel> source =_accountLeftworkRepository.WorkshopList(accountId);
|
|
||||||
List<long> userWorkshopIds = source.Select(x => x.WorkshopId).ToList();
|
|
||||||
List<WorkshopSelectList> allWorkshops = this._accountLeftworkRepository.GetAllWorkshops();
|
|
||||||
List<AccountViewModel> accountSelectList = this._accountRepository.GetAdminAccountSelectList();
|
|
||||||
(string StartWorkFa, string LeftWorkFa) byAccountId = this._accountLeftworkRepository.GetByAccountId(accountId);
|
|
||||||
return new AccountLeftWorkViewModel()
|
|
||||||
{
|
{
|
||||||
AccountId = accountId,
|
_authHelper.CameraSignIn(authViewModel);
|
||||||
AccountFullName = fullname,
|
}
|
||||||
StartDateFa = byAccountId.StartWorkFa,
|
else
|
||||||
LeftDateFa = byAccountId.LeftWorkFa,
|
{
|
||||||
WorkshopAccountlist = source,
|
return operation.Failed("این اکانت غیر فعال شده است");
|
||||||
WorkshopSelectList = new SelectList(allWorkshops.Where(x => !userWorkshopIds.Contains(x.Id)), "Id", "WorkshopFullName"),
|
}
|
||||||
AccountSelectList = new SelectList(accountSelectList, "Id", "Fullname")
|
|
||||||
};
|
return operation.Succcedded(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// public AccountLeftWorkViewModel WorkshopList(long accountId)
|
||||||
|
// {
|
||||||
|
// string fullname = this._accountRepository.GetById(accountId).Fullname;
|
||||||
|
// List<WorkshopAccountlistViewModel> source = _accountLeftworkRepository.WorkshopList(accountId);
|
||||||
|
// List<long> userWorkshopIds = source.Select(x => x.WorkshopId).ToList();
|
||||||
|
// List<WorkshopSelectList> allWorkshops = this._accountLeftworkRepository.GetAllWorkshops();
|
||||||
|
// List<AccountViewModel> accountSelectList = this._accountRepository.GetAdminAccountSelectList();
|
||||||
|
// (string StartWorkFa, string LeftWorkFa) byAccountId = this._accountLeftworkRepository.GetByAccountId(accountId);
|
||||||
|
// return new AccountLeftWorkViewModel()
|
||||||
|
// {
|
||||||
|
// AccountId = accountId,
|
||||||
|
// AccountFullName = fullname,
|
||||||
|
// StartDateFa = byAccountId.StartWorkFa,
|
||||||
|
// LeftDateFa = byAccountId.LeftWorkFa,
|
||||||
|
// WorkshopAccountlist = source,
|
||||||
|
// WorkshopSelectList = new SelectList(allWorkshops.Where(x => !userWorkshopIds.Contains(x.Id)), "Id", "WorkshopFullName"),
|
||||||
|
// AccountSelectList = new SelectList(accountSelectList, "Id", "Fullname")
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
|
||||||
public OperationResult SaveWorkshopAccount(
|
public OperationResult SaveWorkshopAccount(
|
||||||
List<WorkshopAccountlistViewModel> workshopAccountList,
|
List<WorkshopAccountlistViewModel> workshopAccountList,
|
||||||
string startDate,
|
string startDate,
|
||||||
@@ -578,10 +789,12 @@ public class AccountApplication : IAccountApplication
|
|||||||
{
|
{
|
||||||
return this._accountLeftworkRepository.SaveWorkshopAccount(workshopAccountList, startDate, leftDate, accountId);
|
return this._accountLeftworkRepository.SaveWorkshopAccount(workshopAccountList, startDate, leftDate, accountId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public OperationResult CreateNewWorkshopAccount(long currentAccountId, long newAccountId)
|
public OperationResult CreateNewWorkshopAccount(long currentAccountId, long newAccountId)
|
||||||
{
|
{
|
||||||
return this._accountLeftworkRepository.CopyWorkshopToNewAccount(currentAccountId, newAccountId);
|
return this._accountLeftworkRepository.CopyWorkshopToNewAccount(currentAccountId, newAccountId);
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Mahan
|
#region Mahan
|
||||||
|
|
||||||
public List<AccountViewModel> AccountsForAssign(long taskId)
|
public List<AccountViewModel> AccountsForAssign(long taskId)
|
||||||
@@ -595,6 +808,7 @@ public class AccountApplication : IAccountApplication
|
|||||||
{
|
{
|
||||||
return new List<AccountViewModel>();
|
return new List<AccountViewModel>();
|
||||||
}
|
}
|
||||||
|
|
||||||
return _accountRepository.GetAccountsByPositionId(positionId);
|
return _accountRepository.GetAccountsByPositionId(positionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -612,7 +826,6 @@ public class AccountApplication : IAccountApplication
|
|||||||
return operation.Failed("این اکانت وجود ندارد");
|
return operation.Failed("این اکانت وجود ندارد");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var permissions = _roleRepository.Get(account.RoleId)
|
var permissions = _roleRepository.Get(account.RoleId)
|
||||||
.Permissions
|
.Permissions
|
||||||
.Select(x => x.Code)
|
.Select(x => x.Code)
|
||||||
@@ -621,77 +834,86 @@ public class AccountApplication : IAccountApplication
|
|||||||
|
|
||||||
_authHelper.SignOut();
|
_authHelper.SignOut();
|
||||||
var authViewModel = new AuthViewModel(account.id, account.RoleId, account.Fullname
|
var authViewModel = new AuthViewModel(account.id, account.RoleId, account.Fullname
|
||||||
, account.Username, account.Mobile, account.ProfilePhoto, permissions, account.RoleName, account.AdminAreaPermission, account.ClientAriaPermission, account.Position.PositionValue);
|
, account.Username, account.Mobile, account.ProfilePhoto, permissions, account.RoleName,
|
||||||
|
account.AdminAreaPermission, account.ClientAriaPermission, account.Position.PositionValue);
|
||||||
_authHelper.Signin(authViewModel);
|
_authHelper.Signin(authViewModel);
|
||||||
return operation.Succcedded(2);
|
return operation.Succcedded(2);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<List<AccountSelectListViewModel>> GetAdminSelectList()
|
||||||
|
{
|
||||||
|
return await _accountRepository.GetAdminSelectList();
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Pooya
|
#region Pooya
|
||||||
public OperationResult IsPhoneNumberAndPasswordValid(long accountId, string phoneNumber, string password, string rePassword)
|
|
||||||
|
public OperationResult IsPhoneNumberAndPasswordValid(long accountId, string phoneNumber, string password,
|
||||||
|
string rePassword)
|
||||||
{
|
{
|
||||||
OperationResult op = new();
|
OperationResult op = new();
|
||||||
|
|
||||||
var entity = _accountRepository.Get(accountId);
|
var entity = _accountRepository.Get(accountId);
|
||||||
|
|
||||||
if (entity == null)
|
if (entity == null)
|
||||||
return op.Failed(ApplicationMessages.RecordNotFound);
|
return op.Failed(ApplicationMessages.RecordNotFound);
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(rePassword) || !string.IsNullOrWhiteSpace(password))
|
if (!string.IsNullOrWhiteSpace(rePassword) || !string.IsNullOrWhiteSpace(password))
|
||||||
{
|
{
|
||||||
if (rePassword != password)
|
if (rePassword != password)
|
||||||
return op.Failed("تکرار رمز عبور با رمز عبور مطابقت ندارد");
|
return op.Failed("تکرار رمز عبور با رمز عبور مطابقت ندارد");
|
||||||
|
|
||||||
if (password.Length < 8)
|
if (password.Length < 8)
|
||||||
return op.Failed("رمز عبور نمی تواند کمتر از 8 کاراکتر باشد");
|
return op.Failed("رمز عبور نمی تواند کمتر از 8 کاراکتر باشد");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((string.IsNullOrWhiteSpace(phoneNumber) || entity.Mobile == phoneNumber) && string.IsNullOrWhiteSpace(rePassword))
|
if ((string.IsNullOrWhiteSpace(phoneNumber) || entity.Mobile == phoneNumber) &&
|
||||||
return op.Failed("چیزی برای تغییر وجود ندارد");
|
string.IsNullOrWhiteSpace(rePassword))
|
||||||
|
return op.Failed("چیزی برای تغییر وجود ندارد");
|
||||||
|
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(phoneNumber) && entity.Mobile != phoneNumber)
|
if (!string.IsNullOrWhiteSpace(phoneNumber) && entity.Mobile != phoneNumber)
|
||||||
{
|
{
|
||||||
phoneNumber = phoneNumber.Trim();
|
phoneNumber = phoneNumber.Trim();
|
||||||
if (phoneNumber.Length != 11)
|
if (phoneNumber.Length != 11)
|
||||||
return op.Failed("شماره تلفن همراه به درستی وارد نشده است");
|
return op.Failed("شماره تلفن همراه به درستی وارد نشده است");
|
||||||
if (_accountRepository.Exists(x => x.Mobile == phoneNumber && x.id != accountId) ||
|
if (_accountRepository.Exists(x => x.Mobile == phoneNumber && x.id != accountId) ||
|
||||||
_subAccountRepository.Exists(x => x.PhoneNumber == phoneNumber) ||
|
_subAccountRepository.Exists(x => x.PhoneNumber == phoneNumber) ||
|
||||||
_cameraAccountRepository.Exists(x => x.Mobile == phoneNumber))
|
_cameraAccountRepository.Exists(x => x.Mobile == phoneNumber))
|
||||||
return op.Failed("قبلا یک حساب با این شماره ثبت شده است");
|
return op.Failed("قبلا یک حساب با این شماره ثبت شده است");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return op.Succcedded();
|
return op.Succcedded();
|
||||||
}
|
}
|
||||||
|
|
||||||
public OperationResult ChangePasswordAndPhoneNumber(AccountChangePasswordAndPhoneNumber command)
|
public OperationResult ChangePasswordAndPhoneNumber(AccountChangePasswordAndPhoneNumber command)
|
||||||
{
|
{
|
||||||
OperationResult op = new();
|
OperationResult op = new();
|
||||||
command.PhoneNumber = command.PhoneNumber.Trim();
|
command.PhoneNumber = command.PhoneNumber.Trim();
|
||||||
var entity = _accountRepository.Get(command.AccountId);
|
var entity = _accountRepository.Get(command.AccountId);
|
||||||
if (entity == null)
|
if (entity == null)
|
||||||
return op.Failed(ApplicationMessages.RecordNotFound);
|
return op.Failed(ApplicationMessages.RecordNotFound);
|
||||||
var validationResult = IsPhoneNumberAndPasswordValid(command.AccountId, command.PhoneNumber, command.Password, command.RePassword);
|
var validationResult = IsPhoneNumberAndPasswordValid(command.AccountId, command.PhoneNumber, command.Password,
|
||||||
if (validationResult.IsSuccedded == false)
|
command.RePassword);
|
||||||
return validationResult;
|
if (validationResult.IsSuccedded == false)
|
||||||
|
return validationResult;
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(command.RePassword))
|
if (!string.IsNullOrWhiteSpace(command.RePassword))
|
||||||
{
|
{
|
||||||
|
entity.ChangePassword(_passwordHasher.Hash(command.Password));
|
||||||
|
}
|
||||||
|
|
||||||
entity.ChangePassword(_passwordHasher.Hash(command.Password));
|
if (!string.IsNullOrWhiteSpace(command.PhoneNumber))
|
||||||
}
|
{
|
||||||
|
entity.Edit(entity.Fullname, entity.Username, command.PhoneNumber, entity.RoleId, entity.ProfilePhoto,
|
||||||
|
entity.RoleName);
|
||||||
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(command.PhoneNumber))
|
_accountRepository.SaveChanges();
|
||||||
{
|
return op.Succcedded();
|
||||||
entity.Edit(entity.Fullname, entity.Username, command.PhoneNumber, entity.RoleId, entity.ProfilePhoto, entity.RoleName);
|
}
|
||||||
}
|
|
||||||
_accountRepository.SaveChanges();
|
|
||||||
return op.Succcedded();
|
|
||||||
}
|
|
||||||
//public UserClaimsResponseDTO GetClaimsForSignIn(Login command)
|
//public UserClaimsResponseDTO GetClaimsForSignIn(Login command)
|
||||||
//{
|
//{
|
||||||
// var operation = new OperationResult();
|
// var operation = new OperationResult();
|
||||||
@@ -784,6 +1006,7 @@ public class AccountApplication : IAccountApplication
|
|||||||
|
|
||||||
// return claimsResponse.Failed(ApplicationMessages.WrongUserPass);
|
// return claimsResponse.Failed(ApplicationMessages.WrongUserPass);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
@@ -792,4 +1015,38 @@ public class AccountApplication : IAccountApplication
|
|||||||
return _accountRepository.CheckExistClientAccount(userName);
|
return _accountRepository.CheckExistClientAccount(userName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<AccountViewModel> GetAdminAccountsNew()
|
||||||
|
{
|
||||||
|
return _accountRepository.GetAdminAccountsNew();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CameraLogin(CameraLoginRequest request)
|
||||||
|
{
|
||||||
|
var cameraAccount = _cameraAccountRepository.GetBy(request.UserName);
|
||||||
|
|
||||||
|
if (cameraAccount == null)
|
||||||
|
{
|
||||||
|
throw new BadRequestException(ApplicationMessages.WrongUserPass);
|
||||||
|
}
|
||||||
|
|
||||||
|
(bool Verified, bool NeedUpgrade) result = _passwordHasher.Check(cameraAccount.Password, request.Password);
|
||||||
|
|
||||||
|
if (!result.Verified)
|
||||||
|
throw new BadRequestException(ApplicationMessages.WrongUserPass);
|
||||||
|
|
||||||
|
var mobile = string.IsNullOrWhiteSpace(cameraAccount.Mobile) ? " " : cameraAccount.Mobile;
|
||||||
|
|
||||||
|
var authViewModel = new CameraAuthViewModel(cameraAccount.id, cameraAccount.WorkshopId,
|
||||||
|
cameraAccount.Username, mobile, cameraAccount.WorkshopName, cameraAccount.AccountId,
|
||||||
|
cameraAccount.IsActiveSting);
|
||||||
|
if (cameraAccount.IsActiveSting != "true")
|
||||||
|
throw new BadRequestException(ApplicationMessages.WrongUserPass);
|
||||||
|
|
||||||
|
_authHelper.CameraSignIn(authViewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<GetPmUserDto> GetPmUserAsync(long accountId)
|
||||||
|
{
|
||||||
|
return await _pmUserQueryService.GetPmUserDataByAccountId(accountId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,13 +1,14 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\AccountManagement.Application.Contracts\AccountManagement.Application.Contracts.csproj" />
|
<ProjectReference Include="..\AccountManagement.Application.Contracts\AccountManagement.Application.Contracts.csproj" />
|
||||||
<ProjectReference Include="..\AccountManagement.Domain\AccountManagement.Domain.csproj" />
|
<ProjectReference Include="..\AccountManagement.Domain\AccountManagement.Domain.csproj" />
|
||||||
<ProjectReference Include="..\Company.Domain\Company.Domain.csproj" />
|
<ProjectReference Include="..\Company.Domain\Company.Domain.csproj" />
|
||||||
|
<ProjectReference Include="..\Shared.Contracts\Shared.Contracts.csproj" />
|
||||||
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using _0_Framework.Application;
|
using _0_Framework.Application;
|
||||||
using AccountManagement.Application.Contracts.Account;
|
using AccountManagement.Application.Contracts.Account;
|
||||||
using AccountManagement.Application.Contracts.CameraAccount;
|
using AccountManagement.Application.Contracts.CameraAccount;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using _0_Framework.Application;
|
using _0_Framework.Application;
|
||||||
@@ -9,147 +8,113 @@ using Microsoft.AspNetCore.Http;
|
|||||||
|
|
||||||
namespace AccountManagement.Application
|
namespace AccountManagement.Application
|
||||||
{
|
{
|
||||||
public class MediaApplication:IMediaApplication
|
public class MediaApplication : IMediaApplication
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
private const string _basePath = "Medias";
|
private const string _basePath = "Medias";
|
||||||
private readonly IMediaRepository _mediaRepository;
|
private readonly IMediaRepository _mediaRepository;
|
||||||
|
|
||||||
public MediaApplication(IMediaRepository mediaRepository)
|
public MediaApplication(IMediaRepository mediaRepository)
|
||||||
{
|
{
|
||||||
_mediaRepository = mediaRepository;
|
_mediaRepository = mediaRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// دریافت فایل و نوشتن آن در مسیر داده شده، و ثبت مدیا
|
/// دریافت فایل و نوشتن آن در مسیر داده شده، و ثبت مدیا
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="file">فایل</param>
|
/// <param name="file">فایل</param>
|
||||||
/// <param name="fileLabel">برچسب فایل که در نام فایل ظاهر می شود</param>
|
/// <param name="fileLabel">برچسب فایل که در نام فایل ظاهر می شود</param>
|
||||||
/// <param name="relativePath">مسیر فایل</param>
|
/// <param name="relativePath">مسیر فایل</param>
|
||||||
/// <param name="allowedExtensions">[.png,.jpg,.jpeg] پسوند های مجاز مثلا </param>
|
/// <param name="maximumFileLength">حداکثر حجم فایل به مگابایت</param>
|
||||||
/// <param name="maximumFileLength">حداکثر حجم فایل به مگابایت</param>
|
/// <param name="allowedExtensions">[.png,.jpg,.jpeg] پسوند های مجاز مثلا </param>
|
||||||
/// <returns></returns>
|
/// <param name="category"></param>
|
||||||
public OperationResult UploadFile(IFormFile file, string fileLabel, string relativePath,int maximumFileLength,List<string> allowedExtensions)
|
/// <returns></returns>
|
||||||
{
|
public OperationResult UploadFile(IFormFile file, string fileLabel, string relativePath, int maximumFileLength,
|
||||||
OperationResult op = new();
|
List<string> allowedExtensions, string category)
|
||||||
var path = Path.Combine(_basePath, relativePath);
|
{
|
||||||
var fileExtension = Path.GetExtension(file.FileName);
|
return _mediaRepository.UploadFile(file, fileLabel, relativePath, maximumFileLength, allowedExtensions, category);
|
||||||
|
}
|
||||||
if (file == null || file.Length == 0)
|
|
||||||
return op.Failed("خطای سیستمی");
|
|
||||||
|
|
||||||
if (file.Length > (maximumFileLength * 1024 * 1024))
|
|
||||||
return op.Failed($"حجم فایل نمی تواند بیشتر از " +
|
|
||||||
$"{maximumFileLength}" +
|
|
||||||
$"مگابایت باشد");
|
|
||||||
|
|
||||||
if (!allowedExtensions.Contains(fileExtension.ToLower()))
|
|
||||||
{
|
|
||||||
var operationMessage = ":فرمت فایل باید یکی از موارد زیر باشد";
|
|
||||||
operationMessage += "\n";
|
|
||||||
operationMessage += string.Join(" ", allowedExtensions);
|
|
||||||
return op.Failed(operationMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Directory.CreateDirectory(path);
|
/// <summary>
|
||||||
|
/// حذف فایل
|
||||||
|
/// </summary>
|
||||||
|
public OperationResult DeleteFile(long mediaId)
|
||||||
|
{
|
||||||
|
OperationResult op = new();
|
||||||
|
var media = _mediaRepository.Get(mediaId);
|
||||||
|
if (media == null)
|
||||||
|
return op.Failed("رکورد مورد نظر یافت نشد");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (File.Exists(media.Path))
|
||||||
|
File.Delete(media.Path);
|
||||||
|
else
|
||||||
|
return op.Failed("فایل یافت نشد");
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return op.Failed("خطایی در حذف فایل رخ داده است");
|
||||||
|
}
|
||||||
|
|
||||||
var extension = Path.GetExtension(file.FileName);
|
_mediaRepository.Remove(media.id);
|
||||||
|
_mediaRepository.SaveChanges();
|
||||||
|
return op.Succcedded();
|
||||||
|
}
|
||||||
|
|
||||||
var uniqueFileName = $"{fileLabel}-{DateTime.Now.Ticks}{extension}";
|
/// <summary>
|
||||||
var filePath = Path.Combine(path, uniqueFileName);
|
/// جابجا کردن فایل
|
||||||
using (var fileStream = new FileStream(filePath, FileMode.CreateNew))
|
/// </summary>
|
||||||
{
|
public OperationResult MoveFile(long mediaId, string newRelativePath)
|
||||||
file.CopyTo(fileStream);
|
{
|
||||||
}
|
OperationResult op = new();
|
||||||
var mediaEntity = new Media(filePath, extension, "فایل", "EmployeeDocuments");
|
var media = _mediaRepository.Get(mediaId);
|
||||||
_mediaRepository.Create(mediaEntity);
|
var oldPath = media.Path;
|
||||||
_mediaRepository.SaveChanges();
|
var path = Path.Combine(_basePath, newRelativePath);
|
||||||
|
Directory.CreateDirectory(path);
|
||||||
|
|
||||||
return op.Succcedded(mediaEntity.id);
|
string filepath = Path.Combine(path, Path.GetFileName(oldPath));
|
||||||
|
try
|
||||||
|
{
|
||||||
|
File.Move(oldPath, filepath);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return op.Failed("در جابجایی فایل خطایی رخ داده است");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
media.Edit(filepath, media.Type, media.Category);
|
||||||
|
_mediaRepository.SaveChanges();
|
||||||
|
return op.Succcedded();
|
||||||
|
}
|
||||||
|
|
||||||
|
public MediaViewModel Get(long id)
|
||||||
|
{
|
||||||
|
var media = _mediaRepository.Get(id);
|
||||||
|
if (media == null)
|
||||||
|
return new();
|
||||||
|
return new MediaViewModel()
|
||||||
|
{
|
||||||
|
Category = media.Category,
|
||||||
|
Path = media.Path,
|
||||||
|
Id = media.id,
|
||||||
|
Type = media.Type
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
public List<MediaViewModel> GetRange(IEnumerable<long> ids)
|
||||||
/// حذف فایل
|
{
|
||||||
/// </summary>
|
var medias = _mediaRepository.GetRange(ids);
|
||||||
public OperationResult DeleteFile(long mediaId)
|
return medias.Select(x => new MediaViewModel()
|
||||||
{
|
{
|
||||||
OperationResult op = new();
|
Category = x.Category,
|
||||||
var media = _mediaRepository.Get(mediaId);
|
Path = x.Path,
|
||||||
if (media == null)
|
Id = x.id,
|
||||||
return op.Failed("رکورد مورد نظر یافت نشد");
|
Type = x.Type,
|
||||||
try
|
}).ToList();
|
||||||
{
|
}
|
||||||
if (File.Exists(media.Path))
|
|
||||||
File.Delete(media.Path);
|
|
||||||
else
|
|
||||||
return op.Failed("فایل یافت نشد");
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
return op.Failed("خطایی در حذف فایل رخ داده است");
|
|
||||||
}
|
|
||||||
|
|
||||||
_mediaRepository.Remove(media.id);
|
}
|
||||||
_mediaRepository.SaveChanges();
|
|
||||||
return op.Succcedded();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// جابجا کردن فایل
|
|
||||||
/// </summary>
|
|
||||||
public OperationResult MoveFile(long mediaId, string newRelativePath)
|
|
||||||
{
|
|
||||||
OperationResult op = new();
|
|
||||||
var media = _mediaRepository.Get(mediaId);
|
|
||||||
var oldPath = media.Path;
|
|
||||||
var path = Path.Combine(_basePath, newRelativePath);
|
|
||||||
Directory.CreateDirectory(path);
|
|
||||||
|
|
||||||
string filepath = Path.Combine(path, Path.GetFileName(oldPath));
|
|
||||||
try
|
|
||||||
{
|
|
||||||
File.Move(oldPath, filepath);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
return op.Failed("در جابجایی فایل خطایی رخ داده است");
|
|
||||||
}
|
|
||||||
|
|
||||||
media.Edit(filepath, media.Type, media.Category);
|
|
||||||
_mediaRepository.SaveChanges();
|
|
||||||
return op.Succcedded();
|
|
||||||
}
|
|
||||||
|
|
||||||
public MediaViewModel Get(long id)
|
|
||||||
{
|
|
||||||
var media = _mediaRepository.Get(id);
|
|
||||||
if (media == null)
|
|
||||||
return new();
|
|
||||||
return new MediaViewModel()
|
|
||||||
{
|
|
||||||
Category = media.Category,
|
|
||||||
Path = media.Path,
|
|
||||||
Id = media.id,
|
|
||||||
Type = media.Type
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<MediaViewModel> GetRange(IEnumerable<long> ids)
|
|
||||||
{
|
|
||||||
var medias = _mediaRepository.GetRange(ids);
|
|
||||||
return medias.Select(x=>new MediaViewModel()
|
|
||||||
{
|
|
||||||
Category = x.Category,
|
|
||||||
Path = x.Path,
|
|
||||||
Id = x.id,
|
|
||||||
Type = x.Type,
|
|
||||||
}).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,14 @@
|
|||||||
using AccountManagement.Application.Contracts.Role;
|
using AccountManagement.Application.Contracts.Role;
|
||||||
using AccountManagement.Domain.RoleAgg;
|
using AccountManagement.Domain.RoleAgg;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Company.Domain._common;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||||
|
using Shared.Contracts.PmRole.Commands;
|
||||||
|
using GetPmRolesDto = Shared.Contracts.PmRole.Queries.GetPmRolesDto;
|
||||||
|
using Role = AccountManagement.Domain.RoleAgg.Role;
|
||||||
|
using Shared.Contracts.PmRole.Queries;
|
||||||
|
|
||||||
namespace AccountManagement.Application;
|
namespace AccountManagement.Application;
|
||||||
|
|
||||||
@@ -9,32 +17,82 @@ public class RoleApplication : IRoleApplication
|
|||||||
{
|
{
|
||||||
private readonly IRoleRepository _roleRepository;
|
private readonly IRoleRepository _roleRepository;
|
||||||
|
|
||||||
public RoleApplication(IRoleRepository roleRepository)
|
private readonly IPmRoleQueryService _pmRoleQueryService;
|
||||||
|
private readonly IPmRoleCommandService _pmRoleCommandService;
|
||||||
|
private readonly IUnitOfWork _unitOfWork;
|
||||||
|
|
||||||
|
public RoleApplication(IRoleRepository roleRepository, IUnitOfWork unitOfWork, IPmRoleQueryService pmRoleQueryService, IPmRoleCommandService pmRoleCommandService)
|
||||||
{
|
{
|
||||||
_roleRepository = roleRepository;
|
_roleRepository = roleRepository;
|
||||||
|
_unitOfWork = unitOfWork;
|
||||||
|
_pmRoleQueryService = pmRoleQueryService;
|
||||||
|
_pmRoleCommandService = pmRoleCommandService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public OperationResult Create(CreateRole command)
|
public async Task<OperationResult> Create(CreateRole command)
|
||||||
{
|
{
|
||||||
var operation = new OperationResult();
|
var operation = new OperationResult();
|
||||||
if (_roleRepository.Exists(x => x.Name == command.Name))
|
if (_roleRepository.Exists(x => x.Name == command.Name))
|
||||||
return operation.Failed(ApplicationMessages.DuplicatedRecord);
|
return operation.Failed(ApplicationMessages.DuplicatedRecord);
|
||||||
var permissions = new List<Permission>();
|
var permissions = command.Permissions.Where(x => x > 0).Select(x => new Permission(x)).ToList();
|
||||||
foreach (var code in command.Permissions)
|
|
||||||
{
|
|
||||||
if (code > 0)
|
|
||||||
{
|
|
||||||
permissions.Add(new Permission(code));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//command.Permissions.ForEach(code => permissions.Add(new Permission(code)));
|
|
||||||
var role = new Role(command.Name, permissions);
|
var role = new Role(command.Name, permissions);
|
||||||
|
_unitOfWork.BeginAccountContext();
|
||||||
|
|
||||||
_roleRepository.Create(role);
|
_roleRepository.Create(role);
|
||||||
_roleRepository.SaveChanges();
|
_roleRepository.SaveChanges();
|
||||||
|
|
||||||
|
var pmPermissions = command.PmPermissions.Where(x => x > 0).ToList();
|
||||||
|
if (pmPermissions.Any())
|
||||||
|
{
|
||||||
|
|
||||||
|
var pmRole = new CreatePmRoleDto{ RoleName = command.Name, Permissions = pmPermissions, GozareshgirRoleId = role.id};
|
||||||
|
var res =await _pmRoleCommandService.Create(pmRole);
|
||||||
|
if (!res.Item1)
|
||||||
|
{
|
||||||
|
_unitOfWork.RollbackAccountContext();
|
||||||
|
return operation.Failed("خطا در ویرایش دسترسی ها در پروگرام منیجر");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//var parameters = new CreateProgramManagerRole
|
||||||
|
//{
|
||||||
|
// RoleName = command.Name,
|
||||||
|
// Permissions = pmPermissions,
|
||||||
|
// GozareshgirRoleId = role.id
|
||||||
|
|
||||||
|
//};
|
||||||
|
|
||||||
|
//var url = "api/role";
|
||||||
|
//var key = SecretKeys.ProgramManagerInternalApi;
|
||||||
|
|
||||||
|
//var response = InternalApiCaller.PostAsync<CreateProgramManagerRole, ApiResponse>(
|
||||||
|
// url,
|
||||||
|
// key,
|
||||||
|
// parameters
|
||||||
|
//);
|
||||||
|
|
||||||
|
|
||||||
|
//if (!response.Success)
|
||||||
|
//{
|
||||||
|
// _unitOfWork.RollbackAccountContext();
|
||||||
|
// return operation.Failed("ارتباط با اپلیکیش پروگرام منیجر برقرار نشد");
|
||||||
|
//}
|
||||||
|
|
||||||
|
//if (!response.Result.isSuccess)
|
||||||
|
//{
|
||||||
|
// _unitOfWork.RollbackAccountContext();
|
||||||
|
// return operation.Failed(response.Result.errorMessage);
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//command.Permissions.ForEach(code => permissions.Add(new Permission(code)));
|
||||||
|
_unitOfWork.CommitAccountContext();
|
||||||
return operation.Succcedded();
|
return operation.Succcedded();
|
||||||
}
|
}
|
||||||
|
|
||||||
public OperationResult Edit(EditRole command)
|
public async Task<OperationResult> Edit(EditRole command)
|
||||||
{
|
{
|
||||||
var operation = new OperationResult();
|
var operation = new OperationResult();
|
||||||
var role = _roleRepository.Get(command.Id);
|
var role = _roleRepository.Get(command.Id);
|
||||||
@@ -47,17 +105,134 @@ public class RoleApplication : IRoleApplication
|
|||||||
//var permissions = new List<Permission>();
|
//var permissions = new List<Permission>();
|
||||||
//command.Permissions.ForEach(code => permissions.Add(new Permission(code)));
|
//command.Permissions.ForEach(code => permissions.Add(new Permission(code)));
|
||||||
|
|
||||||
var permissions = new List<Permission>();
|
var permissions = command.Permissions.Where(x => x > 0).Select(x => new Permission(x)).ToList();
|
||||||
foreach (var code in command.Permissions)
|
|
||||||
{
|
|
||||||
if (code > 0)
|
|
||||||
{
|
|
||||||
permissions.Add(new Permission(code));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
_unitOfWork.BeginAccountContext();
|
||||||
role.Edit(command.Name, permissions);
|
role.Edit(command.Name, permissions);
|
||||||
_roleRepository.SaveChanges();
|
_roleRepository.SaveChanges();
|
||||||
|
var key = SecretKeys.ProgramManagerInternalApi;
|
||||||
|
var pmPermissions = command.PmPermissions.Where(x => x > 0).ToList();
|
||||||
|
|
||||||
|
|
||||||
|
//یافتن نقش در پروگرام منیجر
|
||||||
|
//var apiResult = InternalApiCaller.GetAsync<RoleResponse>(
|
||||||
|
// "api/role",
|
||||||
|
// key,
|
||||||
|
// new Dictionary<string, object>
|
||||||
|
// {
|
||||||
|
// { "RoleName", "" },
|
||||||
|
|
||||||
|
// { "GozareshgirRoleId", command.Id}
|
||||||
|
// }
|
||||||
|
//);
|
||||||
|
|
||||||
|
|
||||||
|
var pmRoleListResult = await _pmRoleQueryService.GetPmRoleList(command.Id);
|
||||||
|
var pmRoleResult = pmRoleListResult.FirstOrDefault();
|
||||||
|
|
||||||
|
//اگر این نقش در پروگرام منیجر وجود داشت ویرایش کن
|
||||||
|
if (pmRoleResult != null)
|
||||||
|
{
|
||||||
|
var edit = new CreatePmRoleDto { RoleName = command.Name, Permissions = pmPermissions, GozareshgirRoleId = role.id };
|
||||||
|
var res = await _pmRoleCommandService.Edit(edit);
|
||||||
|
if (!res.Item1)
|
||||||
|
{
|
||||||
|
_unitOfWork.RollbackAccountContext();
|
||||||
|
return operation.Failed("خطا در ویرایش دسترسی ها در پروگرام منیجر");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//var parameters = new CreateProgramManagerRole
|
||||||
|
//{
|
||||||
|
// RoleName = command.Name,
|
||||||
|
// Permissions = pmPermissions,
|
||||||
|
// GozareshgirRoleId = role.id
|
||||||
|
|
||||||
|
//};
|
||||||
|
//var url = "api/role/edit";
|
||||||
|
//var response = InternalApiCaller.PostAsync<CreateProgramManagerRole, ApiResponse>(
|
||||||
|
// url,
|
||||||
|
// key,
|
||||||
|
// parameters
|
||||||
|
//);
|
||||||
|
|
||||||
|
|
||||||
|
//if (!response.Success)
|
||||||
|
//{
|
||||||
|
// _unitOfWork.RollbackAccountContext();
|
||||||
|
// return operation.Failed("ارتباط با اپلیکیش پروگرام منیجر برقرار نشد");
|
||||||
|
//}
|
||||||
|
|
||||||
|
//if (!response.Result.isSuccess)
|
||||||
|
//{
|
||||||
|
// _unitOfWork.RollbackAccountContext();
|
||||||
|
// return operation.Failed(response.Result.errorMessage);
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
else //اگر نقش در پروگرام منیجر وجود نداشت
|
||||||
|
{
|
||||||
|
|
||||||
|
//اگر تیک پرمیشن های پروگرام منیجر زده شده
|
||||||
|
//این نقش را سمت پروگرام منیجر بساز
|
||||||
|
if (pmPermissions.Any())
|
||||||
|
{
|
||||||
|
var pmRole = new CreatePmRoleDto { RoleName = command.Name, Permissions = pmPermissions, GozareshgirRoleId = role.id };
|
||||||
|
var res = await _pmRoleCommandService.Create(pmRole);
|
||||||
|
if (!res.Item1)
|
||||||
|
{
|
||||||
|
_unitOfWork.RollbackAccountContext();
|
||||||
|
return operation.Failed("خطا در ویرایش دسترسی ها در پروگرام منیجر");
|
||||||
|
}
|
||||||
|
|
||||||
|
//try
|
||||||
|
//{
|
||||||
|
// var pmPermissionsData = pmPermissions.Where(x => x > 0).Select(x => new PmPermission(x)).ToList();
|
||||||
|
// var pmRole = new PmRole(command.Name, command.Id, pmPermissionsData);
|
||||||
|
// await _pmRoleRepository.CreateAsync(pmRole);
|
||||||
|
// await _pmRoleRepository.SaveChangesAsync();
|
||||||
|
|
||||||
|
//}
|
||||||
|
//catch (System.Exception)
|
||||||
|
//{
|
||||||
|
// _unitOfWork.RollbackAccountContext();
|
||||||
|
// return operation.Failed("خطا در ویرایش دسترسی ها در پروگرام منیجر");
|
||||||
|
//}
|
||||||
|
|
||||||
|
//var parameters = new CreateProgramManagerRole
|
||||||
|
//{
|
||||||
|
// RoleName = command.Name,
|
||||||
|
// Permissions = pmPermissions,
|
||||||
|
// GozareshgirRoleId = role.id
|
||||||
|
|
||||||
|
//};
|
||||||
|
|
||||||
|
//var url = "api/role";
|
||||||
|
|
||||||
|
|
||||||
|
//var response = InternalApiCaller.PostAsync<CreateProgramManagerRole, ApiResponse>(
|
||||||
|
// url,
|
||||||
|
// key,
|
||||||
|
// parameters
|
||||||
|
//);
|
||||||
|
|
||||||
|
|
||||||
|
//if (!response.Success)
|
||||||
|
//{
|
||||||
|
// _unitOfWork.RollbackAccountContext();
|
||||||
|
// return operation.Failed("ارتباط با اپلیکیش پروگرام منیجر برقرار نشد");
|
||||||
|
//}
|
||||||
|
|
||||||
|
//if (!response.Result.isSuccess)
|
||||||
|
//{
|
||||||
|
// _unitOfWork.RollbackAccountContext();
|
||||||
|
// return operation.Failed(response.Result.errorMessage);
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_unitOfWork.CommitAccountContext();
|
||||||
return operation.Succcedded();
|
return operation.Succcedded();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,4 +245,23 @@ public class RoleApplication : IRoleApplication
|
|||||||
{
|
{
|
||||||
return _roleRepository.List();
|
return _roleRepository.List();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public async Task<SelectList> GetPmRoleList(long? gozareshgirRoleId)
|
||||||
|
{
|
||||||
|
var rolse = await _pmRoleQueryService.GetPmRoleList(gozareshgirRoleId);
|
||||||
|
return new SelectList(rolse, "Id", "RoleName");
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<List<GetPmRolesDto>> GetPmRoleListToEdit(long? gozareshgirRoleId)
|
||||||
|
{
|
||||||
|
return await _pmRoleQueryService.GetPmRoleList(gozareshgirRoleId);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -5,14 +5,11 @@ using AccountManagement.Domain.AccountAgg;
|
|||||||
using AccountManagement.Domain.CameraAccountAgg;
|
using AccountManagement.Domain.CameraAccountAgg;
|
||||||
using AccountManagement.Domain.SubAccountAgg;
|
using AccountManagement.Domain.SubAccountAgg;
|
||||||
using AccountManagement.Domain.SubAccountRoleAgg;
|
using AccountManagement.Domain.SubAccountRoleAgg;
|
||||||
using Company.Domain.WorkshopAccountAgg;
|
|
||||||
using Company.Domain.WorkshopSubAccountAgg;
|
using Company.Domain.WorkshopSubAccountAgg;
|
||||||
using CompanyManagment.App.Contracts.Workshop;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using static Microsoft.EntityFrameworkCore.DbLoggerCategory.Database;
|
|
||||||
|
|
||||||
|
|
||||||
namespace AccountManagement.Application
|
namespace AccountManagement.Application
|
||||||
@@ -113,12 +110,12 @@ namespace AccountManagement.Application
|
|||||||
if (cmd.PhoneNumber.Length != 11)
|
if (cmd.PhoneNumber.Length != 11)
|
||||||
return op.Failed("شماره تلفن همراه نامعتبر است");
|
return op.Failed("شماره تلفن همراه نامعتبر است");
|
||||||
|
|
||||||
if (!cmd.WorkshopIds.Any())
|
//if (!cmd.WorkshopIds.Any())
|
||||||
return op.Failed("حداقل یک کارگاه را انتخاب کنید");
|
// return op.Failed("حداقل یک کارگاه را انتخاب کنید");
|
||||||
|
|
||||||
|
|
||||||
if (!cmd.WorkshopIds.All(x => accountWorkshopsList.Contains(x)))
|
//if (!cmd.WorkshopIds.All(x => accountWorkshopsList.Contains(x)))
|
||||||
return op.Failed("خطای سیستمی");
|
// return op.Failed("خطای سیستمی");
|
||||||
|
|
||||||
|
|
||||||
if (cmd.SubAccountRoleId == 0 || !_subAccountRoleRepository.Exists(x => cmd.SubAccountRoleId == x.id))
|
if (cmd.SubAccountRoleId == 0 || !_subAccountRoleRepository.Exists(x => cmd.SubAccountRoleId == x.id))
|
||||||
@@ -131,6 +128,10 @@ namespace AccountManagement.Application
|
|||||||
_cameraAccountRepository.Exists(x => x.Username == cmd.Username))
|
_cameraAccountRepository.Exists(x => x.Username == cmd.Username))
|
||||||
return op.Failed("نام کاربری نمی تواند تکراری باشد");
|
return op.Failed("نام کاربری نمی تواند تکراری باشد");
|
||||||
|
|
||||||
|
var role = _subAccountRoleRepository.Get(cmd.SubAccountRoleId);
|
||||||
|
var workshopId = role.RoleWorkshops.Select(x => x.WorkshopId).ToList();
|
||||||
|
|
||||||
|
|
||||||
var entity = new SubAccount(cmd.AccountId, cmd.SubAccountRoleId, cmd.NationalCode, cmd.FName, cmd.LName, cmd.PhoneNumber, cmd.Username, _passwordHasher.Hash(cmd.Password),
|
var entity = new SubAccount(cmd.AccountId, cmd.SubAccountRoleId, cmd.NationalCode, cmd.FName, cmd.LName, cmd.PhoneNumber, cmd.Username, _passwordHasher.Hash(cmd.Password),
|
||||||
cmd.ProfilePhoto);
|
cmd.ProfilePhoto);
|
||||||
|
|
||||||
@@ -142,7 +143,7 @@ namespace AccountManagement.Application
|
|||||||
_subAccountRepository.SaveChanges();
|
_subAccountRepository.SaveChanges();
|
||||||
|
|
||||||
|
|
||||||
var workshops = cmd.WorkshopIds.Select(x => new WorkshopSubAccount(x, entity.id));
|
var workshops = workshopId.Select(x => new WorkshopSubAccount(x, entity.id));
|
||||||
|
|
||||||
foreach (var w in workshops)
|
foreach (var w in workshops)
|
||||||
_workshopSubAccountRepository.Create(w);
|
_workshopSubAccountRepository.Create(w);
|
||||||
@@ -175,22 +176,22 @@ namespace AccountManagement.Application
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (!cmd.WorkshopIds.All(x => accountWorkshopsList.Contains(x)))
|
//if (!cmd.WorkshopIds.All(x => accountWorkshopsList.Contains(x)))
|
||||||
return op.Failed("خطای سیستمی");
|
// return op.Failed("خطای سیستمی");
|
||||||
|
|
||||||
|
|
||||||
if (cmd.SubAccountRoleId == 0 || !_subAccountRoleRepository.Exists(x => cmd.SubAccountRoleId == x.id))
|
if (cmd.SubAccountRoleId == 0 || !_subAccountRoleRepository.Exists(x => cmd.SubAccountRoleId == x.id))
|
||||||
return op.Failed("نقش مورد نظر وجود ندارد");
|
return op.Failed("نقش مورد نظر وجود ندارد");
|
||||||
|
|
||||||
var workshopSubAccounts = _workshopSubAccountRepository.GetWorkshopsSubAccountEntityBySubAccountId(entity.id);
|
//var workshopSubAccounts = _workshopSubAccountRepository.GetWorkshopsSubAccountEntityBySubAccountId(entity.id);
|
||||||
foreach (var workshopSubAccount in workshopSubAccounts)
|
//foreach (var workshopSubAccount in workshopSubAccounts)
|
||||||
_workshopSubAccountRepository.Remove(workshopSubAccount);
|
// _workshopSubAccountRepository.Remove(workshopSubAccount);
|
||||||
|
|
||||||
|
|
||||||
var workshops = cmd.WorkshopIds.Select(x => new WorkshopSubAccount(x, entity.id));
|
//var workshops = cmd.WorkshopIds.Select(x => new WorkshopSubAccount(x, entity.id));
|
||||||
|
|
||||||
foreach (var w in workshops)
|
//foreach (var w in workshops)
|
||||||
_workshopSubAccountRepository.Create(w);
|
// _workshopSubAccountRepository.Create(w);
|
||||||
|
|
||||||
entity.Edit(cmd.SubAccountRoleId, cmd.NationalCode, cmd.FName, cmd.LName, cmd.ProfilePhoto);
|
entity.Edit(cmd.SubAccountRoleId, cmd.NationalCode, cmd.FName, cmd.LName, cmd.ProfilePhoto);
|
||||||
_workshopSubAccountRepository.SaveChanges();
|
_workshopSubAccountRepository.SaveChanges();
|
||||||
@@ -227,7 +228,8 @@ namespace AccountManagement.Application
|
|||||||
{
|
{
|
||||||
Id = entity.id,
|
Id = entity.id,
|
||||||
Title = entity.Title,
|
Title = entity.Title,
|
||||||
Permissions = entity.RolePermissions.Select(x => x.PermissionCode).ToList()
|
Permissions = entity.RolePermissions.Select(x => x.PermissionCode).ToList(),
|
||||||
|
WorkshopIds = entity.RoleWorkshops.Select(x=>x.WorkshopId).ToList()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -241,7 +243,7 @@ namespace AccountManagement.Application
|
|||||||
OperationResult op = new();
|
OperationResult op = new();
|
||||||
if (_subAccountRoleRepository.Exists(x => x.AccountId == command.AccountId && x.Title.Trim() == command.Title.Trim()))
|
if (_subAccountRoleRepository.Exists(x => x.AccountId == command.AccountId && x.Title.Trim() == command.Title.Trim()))
|
||||||
return op.Failed("یک نقش با این عنوان وجود دارد");
|
return op.Failed("یک نقش با این عنوان وجود دارد");
|
||||||
var role = new SubAccountRole(command.Title, command.Permissions, command.AccountId);
|
var role = new SubAccountRole(command.Title, command.Permissions, command.AccountId,command.WorkshopIds);
|
||||||
_subAccountRoleRepository.Create(role);
|
_subAccountRoleRepository.Create(role);
|
||||||
_subAccountRoleRepository.SaveChanges();
|
_subAccountRoleRepository.SaveChanges();
|
||||||
return op.Succcedded(role.id);
|
return op.Succcedded(role.id);
|
||||||
@@ -254,8 +256,26 @@ namespace AccountManagement.Application
|
|||||||
var entity = _subAccountRoleRepository.Get(cmd.Id);
|
var entity = _subAccountRoleRepository.Get(cmd.Id);
|
||||||
if (entity == null)
|
if (entity == null)
|
||||||
return op.Failed(ApplicationMessages.RecordNotFound);
|
return op.Failed(ApplicationMessages.RecordNotFound);
|
||||||
entity.Edit(cmd.Title, cmd.Permissions);
|
entity.Edit(cmd.Title, cmd.Permissions,cmd.WorkshopIds);
|
||||||
_subAccountRoleRepository.SaveChanges();
|
|
||||||
|
var subAccountRoles = _subAccountRepository.GetBySubAccountRole(cmd.Id);
|
||||||
|
|
||||||
|
foreach (var subAccount in subAccountRoles)
|
||||||
|
{
|
||||||
|
var workshopSubAccounts = _workshopSubAccountRepository.GetWorkshopsSubAccountEntityBySubAccountId(subAccount.id);
|
||||||
|
foreach (var workshopSubAccount in workshopSubAccounts)
|
||||||
|
_workshopSubAccountRepository.Remove(workshopSubAccount);
|
||||||
|
|
||||||
|
|
||||||
|
var workshops = cmd.WorkshopIds.Select(x => new WorkshopSubAccount(x, subAccount.id));
|
||||||
|
|
||||||
|
foreach (var w in workshops)
|
||||||
|
_workshopSubAccountRepository.Create(w);
|
||||||
|
}
|
||||||
|
|
||||||
|
_subAccountRoleRepository.SaveChanges();
|
||||||
|
_workshopSubAccountRepository.SaveChanges();
|
||||||
|
|
||||||
return op.Succcedded();
|
return op.Succcedded();
|
||||||
}
|
}
|
||||||
public OperationResult AssignRoleToSubAccount(AssignSubAccountRole command)
|
public OperationResult AssignRoleToSubAccount(AssignSubAccountRole command)
|
||||||
|
|||||||
@@ -597,7 +597,7 @@ public class TaskApplication : ITaskApplication
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
assign.AcceptTimeRequest();
|
assign.AcceptTimeRequest();
|
||||||
message = string.IsNullOrWhiteSpace(message) ? "درخواست شما مورد تایید قرار گرفت" : message;
|
message = string.IsNullOrWhiteSpace(message) ? "درخواست شما مورد تایید قرار گرفت" : message;
|
||||||
var messageEntity = new TaskMessage(message, "تایید درخواست مهلت", assign.id);
|
var messageEntity = new TaskMessage(message, "تایید درخواست مهلت", assign.id);
|
||||||
@@ -622,6 +622,7 @@ public class TaskApplication : ITaskApplication
|
|||||||
{
|
{
|
||||||
return operation.Failed("چنین وظیفه ای درخواستی برای مهلت ندارد");
|
return operation.Failed("چنین وظیفه ای درخواستی برای مهلت ندارد");
|
||||||
}
|
}
|
||||||
|
|
||||||
assign.RejectTimeRequest();
|
assign.RejectTimeRequest();
|
||||||
if (assign.EndTaskDate.Date <= DateTime.Now.Date)
|
if (assign.EndTaskDate.Date <= DateTime.Now.Date)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using _0_Framework.Application;
|
using _0_Framework.Application;
|
||||||
using AccountManagement.Application.Contracts.TaskSubject;
|
using AccountManagement.Application.Contracts.TaskSubject;
|
||||||
using AccountManagement.Domain.TaskSubjectAgg;
|
using AccountManagement.Domain.TaskSubjectAgg;
|
||||||
using static Microsoft.EntityFrameworkCore.DbLoggerCategory.Database;
|
|
||||||
|
|
||||||
namespace AccountManagement.Application;
|
namespace AccountManagement.Application;
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.4" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.1" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.4" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="10.0.1" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.4">
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="10.0.1">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ namespace AccountManagement.Domain.AccountAgg
|
|||||||
List<AccountViewModel> GetAccountEqualToLowerPositionValue();
|
List<AccountViewModel> GetAccountEqualToLowerPositionValue();
|
||||||
AccountViewModel GetAccountViewModel(long id);
|
AccountViewModel GetAccountViewModel(long id);
|
||||||
List<AccountViewModel> GetAccountsDeactivePositionValue(long Positionid);
|
List<AccountViewModel> GetAccountsDeactivePositionValue(long Positionid);
|
||||||
|
Task<List<AccountSelectListViewModel>> GetAdminSelectList();
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
List<AccountViewModel> GetAdminAccountsNew();
|
List<AccountViewModel> GetAdminAccountsNew();
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ public interface IAccountLeftworkRepository : IRepository<long, AccountLeftWork>
|
|||||||
{
|
{
|
||||||
(string StartWorkFa, string LeftWorkFa) GetByAccountId(long accountId);
|
(string StartWorkFa, string LeftWorkFa) GetByAccountId(long accountId);
|
||||||
List<WorkshopAccountlistViewModel> WorkshopList(long accountId);
|
List<WorkshopAccountlistViewModel> WorkshopList(long accountId);
|
||||||
List<WorkshopSelectList> GetAllWorkshops();
|
// List<WorkshopSelectList> GetAllWorkshops();
|
||||||
|
|
||||||
OperationResult CopyWorkshopToNewAccount(long currentAccountId, long newAccountId);
|
OperationResult CopyWorkshopToNewAccount(long currentAccountId, long newAccountId);
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,16 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.3.0" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.3.0" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="10.0.1" />
|
||||||
|
<PackageReference Include="System.Security.Cryptography.Xml" Version="10.0.1" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\0_Framework\0_Framework.csproj" />
|
<ProjectReference Include="..\0_Framework\0_Framework.csproj" />
|
||||||
<ProjectReference Include="..\AccountManagement.Application.Contracts\AccountManagement.Application.Contracts.csproj" />
|
<ProjectReference Include="..\AccountManagement.Application.Contracts\AccountManagement.Application.Contracts.csproj" />
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
using AccountManagement.Domain.TaskAgg;
|
using AccountManagement.Domain.TaskAgg;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using AccountManagement.Domain.TaskMessageAgg;
|
using AccountManagement.Domain.TaskMessageAgg;
|
||||||
|
|
||||||
namespace AccountManagement.Domain.AssignAgg;
|
namespace AccountManagement.Domain.AssignAgg;
|
||||||
@@ -71,14 +72,16 @@ public class Assign : EntityBase
|
|||||||
|
|
||||||
public void AcceptTimeRequest()
|
public void AcceptTimeRequest()
|
||||||
{
|
{
|
||||||
TimeRequest = false;
|
ClearRequests();
|
||||||
|
TimeRequest = false;
|
||||||
AcceptedTimeRequest++;
|
AcceptedTimeRequest++;
|
||||||
EndTaskDate = RequestDate < DateTime.Today ? DateTime.Today : RequestDate.Value;
|
EndTaskDate = RequestDate < DateTime.Today ? DateTime.Today : RequestDate.Value;
|
||||||
|
|
||||||
}
|
}
|
||||||
public void RejectTimeRequest()
|
public void RejectTimeRequest()
|
||||||
{
|
{
|
||||||
TimeRequest = false;
|
ClearRequests();
|
||||||
|
TimeRequest = false;
|
||||||
TimeRequestDescription = null;
|
TimeRequestDescription = null;
|
||||||
RequestDate = null;
|
RequestDate = null;
|
||||||
}
|
}
|
||||||
@@ -92,31 +95,36 @@ public class Assign : EntityBase
|
|||||||
}
|
}
|
||||||
public void AcceptCancelRequest()
|
public void AcceptCancelRequest()
|
||||||
{
|
{
|
||||||
IsCanceledRequest = false;
|
ClearRequests();
|
||||||
|
IsCanceledRequest = false;
|
||||||
IsCancel = true;
|
IsCancel = true;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
public void RejectCancel()
|
public void RejectCancel()
|
||||||
{
|
{
|
||||||
CancelDescription = null;
|
ClearRequests();
|
||||||
|
CancelDescription = null;
|
||||||
IsCanceledRequest = false;
|
IsCanceledRequest = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CompleteRequest(string? doneDescription)
|
public void CompleteRequest(string? doneDescription)
|
||||||
{
|
{
|
||||||
DoneDescription = doneDescription;
|
ClearRequests();
|
||||||
|
DoneDescription = doneDescription;
|
||||||
IsDoneRequest = true;
|
IsDoneRequest = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RejectCompleteRequest()
|
public void RejectCompleteRequest()
|
||||||
{
|
{
|
||||||
IsDoneRequest = false;
|
ClearRequests();
|
||||||
|
IsDoneRequest = false;
|
||||||
DoneDescription = null;
|
DoneDescription = null;
|
||||||
}
|
}
|
||||||
public void Completed()
|
public void Completed()
|
||||||
{
|
{
|
||||||
IsDoneRequest = false;
|
ClearRequests();
|
||||||
|
IsDoneRequest = false;
|
||||||
IsDone = true;
|
IsDone = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,6 +136,13 @@ public class Assign : EntityBase
|
|||||||
TimeRequest = false;
|
TimeRequest = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ClearRequests()
|
||||||
|
{
|
||||||
|
IsDoneRequest = false;
|
||||||
|
IsCanceledRequest = false;
|
||||||
|
TimeRequest = false;
|
||||||
|
}
|
||||||
|
|
||||||
public void InsertNewData(DateTime endTaskDate,bool timeRequest,int acceptedTimeRequest,DateTime? requestDate, string timeRequestDescription, bool isCanceledRequest,
|
public void InsertNewData(DateTime endTaskDate,bool timeRequest,int acceptedTimeRequest,DateTime? requestDate, string timeRequestDescription, bool isCanceledRequest,
|
||||||
bool isCancel,string cancelDescription,bool isDone,bool isDoneRequest,string? doneDescription)
|
bool isCancel,string cancelDescription,bool isDone,bool isDoneRequest,string? doneDescription)
|
||||||
{
|
{
|
||||||
@@ -144,4 +159,24 @@ public class Assign : EntityBase
|
|||||||
IsDoneRequest=isDoneRequest;
|
IsDoneRequest=isDoneRequest;
|
||||||
DoneDescription=doneDescription;
|
DoneDescription=doneDescription;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ChangeAssignedId(long assignedId)
|
||||||
|
{
|
||||||
|
AssignedId = assignedId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetAssignerId(long assignerId)
|
||||||
|
{
|
||||||
|
AssignerId = assignerId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ChangeSender(long senderId)
|
||||||
|
{
|
||||||
|
Task.SetSender(senderId);
|
||||||
|
var taskMessageItemsEnumerable =TaskMessageList.SelectMany(m => m.TaskMessageItemsList);
|
||||||
|
foreach (var taskMessageItems in taskMessageItemsEnumerable)
|
||||||
|
{
|
||||||
|
taskMessageItems.SetSenderId(senderId);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
155
AccountManagement.Domain/InternalApiCaller/InternalApiCaller.cs
Normal file
155
AccountManagement.Domain/InternalApiCaller/InternalApiCaller.cs
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Text;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
|
||||||
|
namespace AccountManagement.Domain.InternalApiCaller;
|
||||||
|
|
||||||
|
public class ApiResult<T>
|
||||||
|
{
|
||||||
|
public bool Success { get; set; }
|
||||||
|
public T Result { get; set; }
|
||||||
|
public string Error { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class InternalApiCaller
|
||||||
|
{
|
||||||
|
private static string _baseUrl = "";
|
||||||
|
|
||||||
|
public static void SetBaseUrl(string baseUrl)
|
||||||
|
{
|
||||||
|
_baseUrl = baseUrl.TrimEnd('/'); // حذف / اضافی
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
///api post متد
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TRequest"></typeparam>
|
||||||
|
/// <typeparam name="TResponse"></typeparam>
|
||||||
|
/// <param name="url"></param>
|
||||||
|
/// <param name="internalKey"></param>
|
||||||
|
/// <param name="body"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static ApiResult<TResponse> PostAsync<TRequest, TResponse>(
|
||||||
|
string url,
|
||||||
|
string internalKey,
|
||||||
|
TRequest body
|
||||||
|
)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var client = new HttpClient();
|
||||||
|
|
||||||
|
// ساخت URL نهایی
|
||||||
|
var finalUrl = $"{_baseUrl}/{url.TrimStart('/')}";
|
||||||
|
|
||||||
|
var request = new HttpRequestMessage(HttpMethod.Post, finalUrl);
|
||||||
|
|
||||||
|
request.Headers.Add("X-INTERNAL-KEY", internalKey);
|
||||||
|
|
||||||
|
var json = JsonConvert.SerializeObject(body);
|
||||||
|
request.Content = new StringContent(json, Encoding.UTF8, "application/json");
|
||||||
|
|
||||||
|
var response = client.SendAsync(request).GetAwaiter().GetResult();
|
||||||
|
|
||||||
|
if (!response.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
return new ApiResult<TResponse>
|
||||||
|
{
|
||||||
|
Success = false,
|
||||||
|
Error = $"HTTP Error: {response.StatusCode}"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
var text = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
|
||||||
|
var deserialized = JsonConvert.DeserializeObject<TResponse>(text);
|
||||||
|
|
||||||
|
return new ApiResult<TResponse>
|
||||||
|
{
|
||||||
|
Success = true,
|
||||||
|
Result = deserialized
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return new ApiResult<TResponse>
|
||||||
|
{
|
||||||
|
Success = false,
|
||||||
|
Error = ex.Message
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Api Get متد
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TResponse"></typeparam>
|
||||||
|
/// <param name="url"></param>
|
||||||
|
/// <param name="internalKey"></param>
|
||||||
|
/// <param name="parameters"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static ApiResult<TResponse> GetAsync<TResponse>(
|
||||||
|
string url,
|
||||||
|
string internalKey,
|
||||||
|
Dictionary<string, object> parameters = null
|
||||||
|
)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (parameters != null && parameters.Any())
|
||||||
|
{
|
||||||
|
var query = string.Join("&",
|
||||||
|
parameters
|
||||||
|
.Where(p => p.Value != null)
|
||||||
|
.Select(p => $"{p.Key}={p.Value}")
|
||||||
|
);
|
||||||
|
|
||||||
|
url += url.Contains("?") ? "&" + query : "?" + query;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ساخت URL نهایی
|
||||||
|
var finalUrl = $"{_baseUrl}/{url.TrimStart('/')}";
|
||||||
|
|
||||||
|
var client = new HttpClient();
|
||||||
|
var request = new HttpRequestMessage(HttpMethod.Get, finalUrl);
|
||||||
|
|
||||||
|
request.Headers.Add("X-INTERNAL-KEY", internalKey);
|
||||||
|
|
||||||
|
var response = client.SendAsync(request).GetAwaiter().GetResult();
|
||||||
|
|
||||||
|
if (!response.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
return new ApiResult<TResponse>
|
||||||
|
{
|
||||||
|
Success = false,
|
||||||
|
Error = $"HTTP Error: {response.StatusCode}"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
var text = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
|
||||||
|
var deserialized = JsonConvert.DeserializeObject<TResponse>(text);
|
||||||
|
|
||||||
|
return new ApiResult<TResponse>
|
||||||
|
{
|
||||||
|
Success = true,
|
||||||
|
Result = deserialized
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return new ApiResult<TResponse>
|
||||||
|
{
|
||||||
|
Success = false,
|
||||||
|
Error = ex.Message
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,12 +1,15 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using _0_Framework.Application;
|
||||||
using _0_Framework.Domain;
|
using _0_Framework.Domain;
|
||||||
using AccountManagement.Application.Contracts.Media;
|
using AccountManagement.Application.Contracts.Media;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
||||||
|
|
||||||
namespace AccountManagement.Domain.MediaAgg;
|
namespace AccountManagement.Domain.MediaAgg;
|
||||||
|
|
||||||
public interface IMediaRepository:IRepository<long,Media>
|
public interface IMediaRepository : IRepository<long, Media>
|
||||||
{
|
{
|
||||||
|
public string BasePath { get; protected set; }
|
||||||
void CreateMediaWithTaskMedia(long taskId, long mediaId);
|
void CreateMediaWithTaskMedia(long taskId, long mediaId);
|
||||||
List<MediaViewModel> GetMediaByTaskId(long taskId);
|
List<MediaViewModel> GetMediaByTaskId(long taskId);
|
||||||
void Remove(long id);
|
void Remove(long id);
|
||||||
@@ -23,4 +26,6 @@ public interface IMediaRepository:IRepository<long,Media>
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
OperationResult UploadFile(IFormFile file, string fileLabel, string relativePath, int maximumFileLength,
|
||||||
|
List<string> allowedExtensions, string category);
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
using _0_Framework.Domain;
|
using _0_Framework.Domain;
|
||||||
using AccountManagement.Application.Contracts.SubAccount;
|
using AccountManagement.Application.Contracts.SubAccount;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Specialized;
|
||||||
|
|
||||||
namespace AccountManagement.Domain.SubAccountAgg
|
namespace AccountManagement.Domain.SubAccountAgg
|
||||||
{
|
{
|
||||||
@@ -13,5 +14,6 @@ namespace AccountManagement.Domain.SubAccountAgg
|
|||||||
SubAccount GetDetails(long subAccountId);
|
SubAccount GetDetails(long subAccountId);
|
||||||
SubAccount GetBy(string commandUsername);
|
SubAccount GetBy(string commandUsername);
|
||||||
SubAccountViewModel GetByVerifyCodeAndPhoneNumber(string code, string phone);
|
SubAccountViewModel GetByVerifyCodeAndPhoneNumber(string code, string phone);
|
||||||
|
List<SubAccount> GetBySubAccountRole(long subAccountRoleId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,17 +13,21 @@ namespace AccountManagement.Domain.SubAccountRoleAgg
|
|||||||
|
|
||||||
public List<SubAccountRolePermission> RolePermissions { get; private set; }
|
public List<SubAccountRolePermission> RolePermissions { get; private set; }
|
||||||
public List<SubAccount> SubAccounts { get; private set; }
|
public List<SubAccount> SubAccounts { get; private set; }
|
||||||
|
public List<SubAccountRoleWorkshop> RoleWorkshops { get; set; }
|
||||||
|
|
||||||
private SubAccountRole()
|
private SubAccountRole()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public SubAccountRole(string title, List<int> permissions, long accountId)
|
public SubAccountRole(string title, List<int> permissions, long accountId, List<long> workshopIds)
|
||||||
{
|
{
|
||||||
Title = title;
|
Title = title;
|
||||||
RolePermissions = permissions.Select(x => new SubAccountRolePermission(x, id)).ToList();
|
RolePermissions = permissions.Select(x => new SubAccountRolePermission(x, id)).ToList();
|
||||||
AccountId = accountId;
|
AccountId = accountId;
|
||||||
|
RoleWorkshops = workshopIds.Select(x => new SubAccountRoleWorkshop(x, id)).ToList();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ChangeTitle(string title)
|
public void ChangeTitle(string title)
|
||||||
{
|
{
|
||||||
Title = title;
|
Title = title;
|
||||||
@@ -32,10 +36,12 @@ namespace AccountManagement.Domain.SubAccountRoleAgg
|
|||||||
{
|
{
|
||||||
RolePermissions.AddRange(permissionIds.Select(x => new SubAccountRolePermission(x, id)));
|
RolePermissions.AddRange(permissionIds.Select(x => new SubAccountRolePermission(x, id)));
|
||||||
}
|
}
|
||||||
public void Edit(string title, List<int> permissions)
|
public void Edit(string title, List<int> permissions,List<long> workshopIds)
|
||||||
{
|
{
|
||||||
Title = title;
|
Title = title;
|
||||||
RolePermissions = permissions.Select(x => new SubAccountRolePermission(x, id)).ToList();
|
RolePermissions = permissions.Select(x => new SubAccountRolePermission(x, id)).ToList();
|
||||||
}
|
RoleWorkshops = workshopIds.Select(x => new SubAccountRoleWorkshop(x, id)).ToList();
|
||||||
}
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
using _0_Framework.Domain;
|
||||||
|
|
||||||
|
namespace AccountManagement.Domain.SubAccountRoleAgg;
|
||||||
|
|
||||||
|
public class SubAccountRoleWorkshop:EntityBase
|
||||||
|
{
|
||||||
|
public SubAccountRoleWorkshop(long workshopId, long subAccountId)
|
||||||
|
{
|
||||||
|
WorkshopId = workshopId;
|
||||||
|
SubAccountId = subAccountId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long WorkshopId { get; set; }
|
||||||
|
public long SubAccountId { get; set; }
|
||||||
|
public SubAccountRole SubAccountRole { get; set; }
|
||||||
|
}
|
||||||
@@ -1,10 +1,12 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Security.AccessControl;
|
using System.Security.AccessControl;
|
||||||
using _0_Framework.Domain;
|
using _0_Framework.Domain;
|
||||||
using AccountManagement.Domain.AssignAgg;
|
using AccountManagement.Domain.AssignAgg;
|
||||||
using AccountManagement.Domain.TaskMediaAgg;
|
using AccountManagement.Domain.TaskMediaAgg;
|
||||||
using AccountManagement.Domain.TaskScheduleAgg;
|
using AccountManagement.Domain.TaskScheduleAgg;
|
||||||
|
using OfficeOpenXml.Style;
|
||||||
|
|
||||||
namespace AccountManagement.Domain.TaskAgg;
|
namespace AccountManagement.Domain.TaskAgg;
|
||||||
|
|
||||||
@@ -80,4 +82,40 @@ public class Tasks : EntityBase
|
|||||||
TaskScheduleId = taskScheduleId;
|
TaskScheduleId = taskScheduleId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ChangeSender(long senderId)
|
||||||
|
{
|
||||||
|
var prevSender = SenderId;
|
||||||
|
|
||||||
|
var assigners = Assigns.Where(x => x.AssignerId == prevSender).ToList();
|
||||||
|
|
||||||
|
foreach (var assigner in assigners)
|
||||||
|
{
|
||||||
|
assigner.SetAssignerId(senderId);
|
||||||
|
}
|
||||||
|
|
||||||
|
var senderMessageItem = Assigns
|
||||||
|
.SelectMany(x=>x.TaskMessageList
|
||||||
|
.SelectMany(m=>m.TaskMessageItemsList)).Where(x=>x.SenderAccountId == prevSender).ToList();
|
||||||
|
|
||||||
|
var receiverMessageItem = Assigns.SelectMany(x=>x.TaskMessageList
|
||||||
|
.SelectMany(m=>m.TaskMessageItemsList)).Where(x=>x.ReceiverAccountId == prevSender).ToList();
|
||||||
|
|
||||||
|
|
||||||
|
SenderId = senderId;
|
||||||
|
|
||||||
|
foreach (var taskMessageItems in senderMessageItem)
|
||||||
|
{
|
||||||
|
taskMessageItems.SetSenderId(senderId);
|
||||||
|
}
|
||||||
|
foreach (var taskMessageItems in receiverMessageItem)
|
||||||
|
{
|
||||||
|
taskMessageItems.SetReceiver(senderId);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetSender(long senderId)
|
||||||
|
{
|
||||||
|
SenderId = senderId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -19,4 +19,13 @@ public class TaskMessageItems:EntityBase
|
|||||||
public TaskMessage TaskMessage { get; set; }
|
public TaskMessage TaskMessage { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
public void SetSenderId(long senderId)
|
||||||
|
{
|
||||||
|
SenderAccountId = senderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetReceiver(long receiverId)
|
||||||
|
{
|
||||||
|
ReceiverAccountId = receiverId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -16,7 +16,7 @@ public class TaskSchedule:EntityBase
|
|||||||
UnitType = unitType;
|
UnitType = unitType;
|
||||||
UnitNumber = unitNumber;
|
UnitNumber = unitNumber;
|
||||||
LastEndTaskDate = lastEndTaskDate;
|
LastEndTaskDate = lastEndTaskDate;
|
||||||
IsActive = IsActive.False;
|
IsActive = IsActive.True;
|
||||||
}
|
}
|
||||||
public string Count { get; private set; }
|
public string Count { get; private set; }
|
||||||
public TaskScheduleType Type { get; private set; }
|
public TaskScheduleType Type { get; private set; }
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using AccountManagement.Domain.AccountAgg;
|
using AccountManagement.Domain.AccountAgg;
|
||||||
using AccountMangement.Infrastructure.EFCore.Mappings;
|
using AccountMangement.Infrastructure.EFCore.Mappings;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using System;
|
using System;
|
||||||
@@ -26,7 +26,6 @@ using AccountManagement.Domain.SubAccountPermissionSubtitle2Agg;
|
|||||||
using AccountManagement.Domain.SubAccountPermissionSubtitle3Agg;
|
using AccountManagement.Domain.SubAccountPermissionSubtitle3Agg;
|
||||||
using AccountManagement.Domain.SubAccountPermissionSubtitle4Agg;
|
using AccountManagement.Domain.SubAccountPermissionSubtitle4Agg;
|
||||||
using AccountManagement.Domain.SubAccountRoleAgg;
|
using AccountManagement.Domain.SubAccountRoleAgg;
|
||||||
using AccountMangement.Infrastructure.EFCore.Seed;
|
|
||||||
using AccountManagement.Domain.TaskScheduleAgg;
|
using AccountManagement.Domain.TaskScheduleAgg;
|
||||||
|
|
||||||
namespace AccountMangement.Infrastructure.EFCore
|
namespace AccountMangement.Infrastructure.EFCore
|
||||||
@@ -60,9 +59,10 @@ namespace AccountMangement.Infrastructure.EFCore
|
|||||||
|
|
||||||
public DbSet<TaskSchedule> TaskSchedules { get; set; }
|
public DbSet<TaskSchedule> TaskSchedules { get; set; }
|
||||||
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#region Pooya
|
#region Pooya
|
||||||
public DbSet<SubAccount> SubAccounts { get; set; }
|
public DbSet<SubAccount> SubAccounts { get; set; }
|
||||||
public DbSet<SubAccountRole> SubAccountRoles { get; set; }
|
public DbSet<SubAccountRole> SubAccountRoles { get; set; }
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.4" />
|
<PackageReference Include="Azure.Identity" Version="1.17.1" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.4" />
|
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.3.0" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.4">
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.1" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="10.0.1" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="10.0.1">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
@@ -18,4 +20,12 @@
|
|||||||
<ProjectReference Include="..\Company.Domain\Company.Domain.csproj" />
|
<ProjectReference Include="..\Company.Domain\Company.Domain.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Services\" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Remove="Mappings\BugReportMapping.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -21,6 +21,10 @@ namespace AccountMangement.Infrastructure.EFCore.Mappings
|
|||||||
opt.WithOwner(x => x.SubAccountRole);
|
opt.WithOwner(x => x.SubAccountRole);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
builder.OwnsMany(x => x.RoleWorkshops, roleWorkshop =>
|
||||||
|
{
|
||||||
|
roleWorkshop.WithOwner(x => x.SubAccountRole).HasForeignKey(x => x.SubAccountId);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
1303
AccountMangement.Infrastructure.EFCore/Migrations/20250530133036_add workshop to subAccountRole.Designer.cs
generated
Normal file
1303
AccountMangement.Infrastructure.EFCore/Migrations/20250530133036_add workshop to subAccountRole.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,43 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace AccountMangement.Infrastructure.EFCore.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class addworkshoptosubAccountRole : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "SubAccountRoleWorkshop",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
id = table.Column<long>(type: "bigint", nullable: false)
|
||||||
|
.Annotation("SqlServer:Identity", "1, 1"),
|
||||||
|
SubAccountId = table.Column<long>(type: "bigint", nullable: false),
|
||||||
|
WorkshopId = table.Column<long>(type: "bigint", nullable: false),
|
||||||
|
CreationDate = table.Column<DateTime>(type: "datetime2", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_SubAccountRoleWorkshop", x => new { x.SubAccountId, x.id });
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_SubAccountRoleWorkshop_SubAccountRoles_SubAccountId",
|
||||||
|
column: x => x.SubAccountId,
|
||||||
|
principalTable: "SubAccountRoles",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "SubAccountRoleWorkshop");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,31 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace AccountMangement.Infrastructure.EFCore.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class addprogrammangerbooinaccount : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<bool>(
|
||||||
|
name: "IsProgramManagerUser",
|
||||||
|
table: "Accounts",
|
||||||
|
type: "bit",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: false);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "IsProgramManagerUser",
|
||||||
|
table: "Accounts");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user