Compare commits
2030 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e6bd35ae04 | |||
| 102e193ae8 | |||
| 20d557e795 | |||
| 593ab42882 | |||
| b56d256e10 | |||
| 614a3bd70e | |||
| 2eb3b04365 | |||
| 1fa3a5a181 | |||
| cd2007c4fd | |||
| 67e710eac0 | |||
| ef451d82ec | |||
| 899ebf2a30 | |||
| f233d27f96 | |||
| 9e8ab8acca | |||
| 2265387f47 | |||
| baf8f39bc6 | |||
| 3fa14d92ae | |||
| e6c577e68b | |||
| bb111dbbeb | |||
| 0df0b10a72 | |||
| 0a7ba9f0f5 | |||
| cd88990c32 | |||
| d53a1300fc | |||
| 07332ff3e1 | |||
| 8195a1cf3e | |||
| f5e5a47624 | |||
| 28608f3ecb | |||
| bb2da7ca81 | |||
| 713518a68c | |||
| bc448da297 | |||
| 8447878cb2 | |||
| 1b5a9673f6 | |||
| 27711f4184 | |||
| bb9bac1edf | |||
| 41ae2febc7 | |||
| c072c526e2 | |||
| d6bb98b84f | |||
| 42587ee59f | |||
| 62a964a3ea | |||
| 72447eb82f | |||
| 2f83c27fde | |||
| b219593f61 | |||
| 8521b0c28c | |||
| 26a62426f0 | |||
| 1246413e30 | |||
| f50b5819c0 | |||
| 6db8d61b7c | |||
| 58250fe993 | |||
| 6cae7a1ae4 | |||
| 73541efbf4 | |||
| f4bd891deb | |||
| a9831657cc | |||
| 500a9fbaca | |||
| 5f11c3a602 | |||
| 7680e90d65 | |||
| 06a57cd056 | |||
| 7626d17540 | |||
| 344b92c427 | |||
| 4719177009 | |||
| c1461633ce | |||
| 6be7aa1ad9 | |||
| 4da7c2f960 | |||
| 47a45df610 | |||
| 1a44e48b2d | |||
| c566a703eb | |||
| 001c248cb8 | |||
| 654462fe6b | |||
| ab6642ce33 | |||
| 946386ad43 | |||
| cf9c79a928 | |||
| 493e4e8dca | |||
| ecbe8434f3 | |||
| 644fe1bd3c | |||
| 870fca2e93 | |||
| 6207fb5006 | |||
| ae913d8213 | |||
| ce969822a0 | |||
| 4fc311d4a5 | |||
| 2b424ff45c | |||
| e5d9cfc50e | |||
| ac3552818b | |||
| c004741f95 | |||
| 2bdc0c7704 | |||
| 35d90d56dd | |||
| f14525ea95 | |||
| c2350f1418 | |||
| 4b8b02fa55 | |||
| 62102b8b03 | |||
| 0655318d2d | |||
| 0bd2a10091 | |||
| ce11788878 | |||
| 0cb74296c3 | |||
| def08b72ca | |||
| 1ef8d2913b | |||
| 7e18b1287e | |||
| fdcb6ad12f | |||
| 988bf0e92c | |||
| f6612286d9 | |||
| c21845c60d | |||
| 867ef0ef97 | |||
| f27bee83b7 | |||
| e3b6feb4da | |||
| d727703075 | |||
| c49cf0ed12 | |||
| f324d207dd | |||
| c9bda275f5 | |||
| 62ed1a408d | |||
| 25efb34f1f | |||
| eb0f13c075 | |||
| 7ca92a7675 | |||
| e313f88bca | |||
| 4823eb29d5 | |||
| 43ec332f61 | |||
| cac0652120 | |||
| cc088900b6 | |||
| 824b165723 | |||
| 443b94b332 | |||
| dc116d3a6f | |||
| bbc8859a16 | |||
| 09e388b01a | |||
| e5fcb75b9f | |||
| 8e104e133f | |||
| e2a77537f0 | |||
| a73a79b627 | |||
| e79c3a8f37 | |||
| ca9a2dad18 | |||
| cd03f5f31d | |||
| 33e25de801 | |||
| 9cd60e9575 | |||
| 4da4a4de89 | |||
| ec0a88a5ec | |||
| a52a00e58c | |||
| 0a6ffbba07 | |||
| 8cb5423b0b | |||
| 5a6411c6c3 | |||
| b97a8b5a68 | |||
| 91794266e7 | |||
| 2f86e2dae1 | |||
| fb76c5af6c | |||
| 3f6ec5b7ea | |||
| c95ea8c547 | |||
| facd9e0e5f | |||
| 9d0c3d3fc5 | |||
| 907d0d39a1 | |||
| 4d689100ee | |||
| 818d9d6f62 | |||
| 9a2059726f | |||
| 8bcac405e5 | |||
| 19661c5e82 | |||
| 9875d9622d | |||
| 7573ffe941 | |||
| 47166ab2eb | |||
| 0295b7d919 | |||
| 3653072497 | |||
| 0e7f203a1b | |||
| ab99265c88 | |||
| f774d95f5c | |||
| 9e1e32f16d | |||
| 0accb453e5 | |||
| e2b285c792 | |||
| 935f95fa3b | |||
| a4d20d9f08 | |||
| 0e23719c7b | |||
| eb1f06658d | |||
| 1e177a2530 | |||
| 49031b0e48 | |||
| ca5bbb3064 | |||
| b338188c5f | |||
| 9cbe4cc36e | |||
| 6f5f521803 | |||
| a6db30280b | |||
| 4db3860ade | |||
| 57837cfe1d | |||
| b51fdc5769 | |||
| 5038d7ad53 | |||
| c1d618326b | |||
| db1a0195fe | |||
| 238def8089 | |||
| 59e969c2a8 | |||
| 029a288be2 | |||
| 11e5448acf | |||
| 71577d0346 | |||
| 681e559cb4 | |||
| 862390ae78 | |||
| f210799c4d | |||
| d7700c3c77 | |||
| 44fa4d3fc4 | |||
| f0c57c643b | |||
| 5e48ed1e23 | |||
| a3f12b2a53 | |||
| cc00cce704 | |||
| 9c244c6750 | |||
| ffb5d46ca3 | |||
| 7376732b1a | |||
| 1caf4ff8e6 | |||
| 22147483c1 | |||
| c7dbf7ba92 | |||
| fd3f76d35c | |||
| e10bca6892 | |||
| 4a01960426 | |||
| 318364e70b | |||
| 383064a7b7 | |||
| 78bbfb5f41 | |||
| 9aec1f5f50 | |||
| 66beb43daf | |||
| b02589a957 | |||
| d4a1d83851 | |||
| 53aee1020d | |||
| 010c106879 | |||
| fb43e38c7d | |||
| ca96c67e96 | |||
| 1fbf635582 | |||
| 44d62b187f | |||
| 57600cbad1 | |||
| 311d6507ce | |||
| 8e520ce579 | |||
| 5a97e15885 | |||
| bb36c67159 | |||
| 7a33edc7a6 | |||
| a7d6303da4 | |||
| 704c201c33 | |||
| c69d3eec36 | |||
| 6e5a3a0078 | |||
| ed62de9135 | |||
| a8b218ce95 | |||
| f6d2b1e7f1 | |||
| 85439213b2 | |||
| 2933d100f7 | |||
| ac799688d3 | |||
| a4b9c44cfa | |||
| af282d2bb8 | |||
| a93bbebb61 | |||
| 4552a24caa | |||
| fc22ec0672 | |||
| 963fbcb5e8 | |||
| 3da3b9de45 | |||
| a055d1c668 | |||
| 0b130bbc01 | |||
| 9f9bc9c747 | |||
| 75367ae727 | |||
| bd9d78622f | |||
| 6b807f419b | |||
| f58ee6f63a | |||
| 7510d86a52 | |||
| 65fba6ca41 | |||
| 3e2198b7ba | |||
| 535c0fc419 | |||
| 1c5d30b673 | |||
| 3bf26dbbef | |||
| 329437411d | |||
| 090cdaf2e4 | |||
| 7c257f261c | |||
| 477bc7baf7 | |||
| 32d6ebef9c | |||
| 51e0676ce5 | |||
| 53156e210f | |||
| 84f76c09f7 | |||
| 74e0765d7a | |||
| 51cfadbc77 | |||
| 01e047f639 | |||
| 4050d7e4a3 | |||
| adab66172d | |||
| 7c850c969e | |||
| f55fa98dec | |||
| 7f28c984e1 | |||
| 6220e53d8f | |||
| 5bb0231354 | |||
| 58eec48af7 | |||
| 65545dd3e5 | |||
| 5b92015c98 | |||
| 64c97b22d5 | |||
| 87adbe9bed | |||
| c6ed8b8318 | |||
| 4d2890976a | |||
| 9cfddf1327 | |||
| 84203d5aa2 | |||
| 4d19fffc5f | |||
| 18683390b7 | |||
| fb137ae840 | |||
| c8bc0c4a32 | |||
| 8ded82fa81 | |||
| acd1f47f4a | |||
| 054827bbae | |||
| a5ebe97dc5 | |||
| 02b2d8f754 | |||
| cf5da8f55a | |||
| 40947de05a | |||
| 662648691d | |||
| 29836a9c62 | |||
| a2b1a0d64b | |||
| 87fbd2cb59 | |||
| c91e21c23a | |||
| 0f25c7db0e | |||
| e5b5cbb8d8 | |||
| 9c1af1b8dc | |||
| 0da09da45e | |||
| 87aaefadf6 | |||
| b5b739a5cb | |||
| 1315d5dc29 | |||
| 72b70f5311 | |||
| fd15a62148 | |||
| e9bd625195 | |||
| c37fcf588c | |||
| 3f8d5027c8 | |||
| 972fc32eeb | |||
| 1ba9efe894 | |||
| f85ac8a813 | |||
| 7bf097c127 | |||
| fc579d9cf4 | |||
| b1c0933428 | |||
| bd7dd906fb | |||
| 3a8e400f33 | |||
| c6dd323b80 | |||
| dfb45d8391 | |||
| 0b0df00525 | |||
| 96fc5ae78c | |||
| a4b2d68995 | |||
| 70ababc2d9 | |||
| e57887eba5 | |||
| aef7fded18 | |||
| e0613c1f2d | |||
| f6d323cc31 | |||
| aa85562076 | |||
| 0165688799 | |||
| c2aefebedc | |||
| 1c5e4454da | |||
| 65e2a45d74 | |||
| 99026d6483 | |||
| 9190783ac4 | |||
| ae8f50dc14 | |||
| 2a51de03b7 | |||
| 2be9daa443 | |||
| 2778b3ea7b | |||
| 4cedb9dbcb | |||
| ed6a6fb844 | |||
| 8daf02246e | |||
| b3178e6f8d | |||
| 00cbde90c7 | |||
| 938175c49f | |||
| 146fc916d1 | |||
| 87776513fb | |||
| 60d462e5f9 | |||
| b39d8dd546 | |||
| b65635c41c | |||
| fe2539afba | |||
| d2ff216396 | |||
| 4c05da8335 | |||
| 6061cf5d93 | |||
| d313b7d8a6 | |||
| 71c21ccc00 | |||
| f415c03daa | |||
| 2bfef364ec | |||
| c822d20d0d | |||
| 3a996212ed | |||
| 5a3b6a5f93 | |||
| 3f7227ce32 | |||
| af0df80874 | |||
| a163d8a785 | |||
| 70fbf8d352 | |||
| d9a8692be8 | |||
| 56fb9c14d1 | |||
| 8bc0cee81f | |||
| dc86767184 | |||
| e1383445e2 | |||
| 0a30107859 | |||
| ba27925409 | |||
| 3a52021cdc | |||
| aba4fc70c2 | |||
| 5b89343192 | |||
| 20f9e90a69 | |||
| 5c58171ac3 | |||
| e98d80eea6 | |||
| c14d5be4ac | |||
| fea108371f | |||
| dd47bf05f8 | |||
| 3a160c1913 | |||
| c42c26d76a | |||
| f7117563f7 | |||
| 39968194b1 | |||
| 0d5f7e5673 | |||
| 7f4e111f7d | |||
| 0c92fcb011 | |||
| 2f4418e3ed | |||
| 75a3d7c80f | |||
| 4605053e50 | |||
| a8da0c0b55 | |||
| ba984f9263 | |||
| 451a311142 | |||
| f86bc219cf | |||
| 06bd63b6d1 | |||
| be088d8ba2 | |||
| c718ec8446 | |||
| 668e1019f0 | |||
| e2f5a7fae1 | |||
| f1a141c018 | |||
| 30a0f428bc | |||
| 7a8346621d | |||
| 6d93054d3d | |||
| 5c53e78aca | |||
| 1eeb832b0e | |||
| c8db9431b2 | |||
| ce8e0e3972 | |||
| ed4192838d | |||
| d900c368e2 | |||
| 6926bb877c | |||
| cb9b54a089 | |||
| 57c5d14f5a | |||
| 4f19d1638d | |||
| ace39a7f94 | |||
| e8e0540cc2 | |||
| a98799daaf | |||
| f2b53cd359 | |||
| 960f479b91 | |||
| d6dacb93dd | |||
| 8823656231 | |||
| 2c859e7186 | |||
| 99828dd82e | |||
| 855242e6fe | |||
| 90a1a920fa | |||
| c73968f490 | |||
| 282368b9e0 | |||
| 726a2be71e | |||
| 510104d0ff | |||
| 12318937f4 | |||
| 8f17d4b110 | |||
| 18496246b2 | |||
| 55f60e897a | |||
| dd2d142340 | |||
| 49a0cf3ece | |||
| f0d4a1c075 | |||
| 5e6db93250 | |||
| 12adf2f3a9 | |||
| b08908b1dc | |||
| 8f08746377 | |||
| 045e9346ad | |||
| 864ab17ff3 | |||
| 700d111011 | |||
| 7168d68997 | |||
| 40ec535e8a | |||
| 4dfaf29f3d | |||
| 702cd361fe | |||
| b776103328 | |||
| 381e7b5046 | |||
| ebdec8dd62 | |||
| 6677f2a01e | |||
| 5aaa9043ff | |||
| 48874adda3 | |||
| 0cf5a88d63 | |||
| 4b92874ca6 | |||
| 2d81b05fba | |||
| 78756aa2f4 | |||
| a15c91ebcb | |||
| 4b389c8293 | |||
| 2313b5e907 | |||
| e22941d947 | |||
| 3efc173056 | |||
| 6389919cfd | |||
| 984b840fa7 | |||
| 2bf01fbf0c | |||
| 116eeb753d | |||
| 82a6237323 | |||
| 6220a96666 | |||
| 259ab2c569 | |||
| efda4e0fdd | |||
| 968264fe9a | |||
| 57911cf567 | |||
| a61d9ae4d1 | |||
| 5735383cd7 | |||
| e3607895b4 | |||
| 16a2e0b53f | |||
| 41e5f9fd78 | |||
| 64b750b06e | |||
| ca90736366 | |||
| 664b308e31 | |||
| 8de0671d31 | |||
| 19d7192842 | |||
| c3ed54f05f | |||
| ef6655a014 | |||
| 234e549b22 | |||
| 903f72989a | |||
| 3e9900cc45 | |||
| 78d0cffd3d | |||
| 658e8d983c | |||
| 8174237a82 | |||
| 39a5e8eade | |||
| 54dea66f5f | |||
| 86fd9ddc0e | |||
| b071d1126b | |||
| 139e9daec0 | |||
| 4eeda2b3e7 | |||
| fa64b42a84 | |||
| ce67f4828f | |||
| 87e3d953d3 | |||
| 5d4668eaee | |||
| cfce8dba1f | |||
| c11e319472 | |||
| 7c7a0cd20b | |||
| a66bb42126 | |||
| 7d63f3f5cb | |||
| b102d23477 | |||
| e19c03412d | |||
| 56cba570bf | |||
| c7abcc153e | |||
| 967a77f371 | |||
| 2060f2c62e | |||
| 193c107539 | |||
| 2fe0851786 | |||
| 46b68ca2c9 | |||
| 396797dc0c | |||
| 5579f543de | |||
| ce31ab3097 | |||
| daa4764aac | |||
| a24c6775e8 | |||
| eb9de1769e | |||
| d675cc50b3 | |||
| 350d089c39 | |||
| 116969f4f2 | |||
| 112d9f9a63 | |||
| 5dae9c5d06 | |||
| c0a63ecfed | |||
| 881a5320a8 | |||
| 22a254890e | |||
| 0912909b68 | |||
| cd7318dd63 | |||
| 21cc610095 | |||
| cc8151caf8 | |||
| 8cce399430 | |||
| 99688df446 | |||
| de0a278cac | |||
| 7031ea1a04 | |||
| 541455a08b | |||
| 814efc4e35 | |||
| f85bbc41c4 | |||
| c00e8eb809 | |||
| 9dd00170af | |||
| fdba16de86 | |||
| 38f319b425 | |||
| d35046b277 | |||
| bdcaf2f2be | |||
| bba622da0e | |||
| 0d4f694fcf | |||
| a41824414e | |||
| c54b0abbd7 | |||
| d772ea527a | |||
| 62b76220d4 | |||
| 6aa8628c0c | |||
| 7d9f4864d0 | |||
| d149d5a5d5 | |||
| 7572bf9fb0 | |||
| 40ab925a4e | |||
| 75a989b4f1 | |||
| f98f89a51d | |||
| 423ea4bc6f | |||
| 3c60dd9ae8 | |||
| f9006be79b | |||
| 0492563838 | |||
| d58089b9ee | |||
| e17a33a16f | |||
| c935599fcf | |||
| efafdc50b8 | |||
| 8846c1d728 | |||
| 9bfd89cb9b | |||
| 35f01818dd | |||
| 875af7e9f7 | |||
| 7dfce2db55 | |||
| cab5772068 | |||
| 6319f1e82d | |||
| d42c8477aa | |||
| b559a7882b | |||
| 30e1d70099 | |||
| 84a8d18519 | |||
| 1fc20e5640 | |||
| d8f0fba8e2 | |||
| 2921404540 | |||
| df79b7b57b | |||
| 0a45638bac | |||
| 4f725af6cd | |||
| 44ae7bde56 | |||
| cd5e0405de | |||
| 5bbf2d3c82 | |||
| 09743f7153 | |||
| f88ef2f3fc | |||
| ef032b548e | |||
| db2f3cc85a | |||
| 7584f4a5b4 | |||
| aac559e221 | |||
| aee5c17591 | |||
| d8248a7973 | |||
| b68d060f85 | |||
| 74399df5eb | |||
| c3b62137d8 | |||
| 352bd23766 | |||
| 398344854b | |||
| e181c3cc82 | |||
| 24e4008b72 | |||
| 50d9ed7e3c | |||
| 9fd113c95f | |||
| 5683ced93d | |||
| 4360f4b2cb | |||
| 43a873defd | |||
| e5d08cdb3e | |||
| c78b80c679 | |||
| 9cd3ba1c67 | |||
| dd22b206dc | |||
| 12b668642c | |||
| 77fa881d69 | |||
| 05dcbfed2e | |||
| 6471041fad | |||
| 69ab56f878 | |||
| 97538333c0 | |||
| a094e1a2b7 | |||
| d0c8df1452 | |||
| 1b6a31e626 | |||
| 2c1cde9f69 | |||
| 1aa5e45694 | |||
| 9fc04193c7 | |||
| b685b9fa13 | |||
| 59f97d0c2d | |||
| 8f94460537 | |||
| 26fe947991 | |||
| 16829f9075 | |||
| 246314561b | |||
| 331a3c4178 | |||
| 35ba7861d1 | |||
| 59cb66331e | |||
| 782bfaa6c4 | |||
| 830af4a164 | |||
| 994cb73104 | |||
| 8e3dc73408 | |||
| 6792f9e916 | |||
| a350c35f49 | |||
| fb498b3723 | |||
| 7b9c90b77c | |||
| f4fd16d8fd | |||
| 5656e66c28 | |||
| 39882e43ce | |||
| e5f2d1cde9 | |||
| 4f978863e4 | |||
| f26aafa8cb | |||
| e444354cf7 | |||
| 0e4ae72016 | |||
| c1121a2d3f | |||
| 1737825506 | |||
| 437c569617 | |||
| 9580d77512 | |||
| f7fb89313c | |||
| 721a7d2341 | |||
| 3529ab6cb6 | |||
| 484bb3ca5b | |||
| 121b2d5df1 | |||
| 472887d627 | |||
| 03f514d5fe | |||
| 36d2203e4c | |||
| 4e11cc7db3 | |||
| f23963896d | |||
| fd2b13b391 | |||
| b90743ded1 | |||
| ee499d9352 | |||
| d12f0bddad | |||
| 9eabd9031b | |||
| 552e7a430d | |||
| b97f9f8f12 | |||
| 8be0cea193 | |||
| bce088bcdf | |||
| 6955c42c8b | |||
| 07b36279cf | |||
| 5c1dc0754b | |||
| 7eaa644028 | |||
| 1b29312bef | |||
| 930412bf21 | |||
| 0e1f4931eb | |||
| 2e2c4b4397 | |||
| 7665cc7f73 | |||
| c743335d13 | |||
| e9aeb1c918 | |||
| c092e9a8d0 | |||
| a55ec01992 | |||
| 302e503e02 | |||
| f82639cdf3 | |||
| 9172d8c5f8 | |||
| 69fd8ec123 | |||
| d9c7a512e9 | |||
| 38383f34ff | |||
| b7585fe022 | |||
| b7d9009ff4 | |||
| 9c26745c2a | |||
| 67f8e57ab6 | |||
| b2ef603729 | |||
| 110ea953c4 | |||
| cef07a5bff | |||
| a5899023b9 | |||
| 61530be208 | |||
| 292bcd7100 | |||
| 8f4a6fcf80 | |||
| dfdb3b5951 | |||
| 0cc7b373b7 | |||
| 7e5cbd92b4 | |||
| 2594ecd27e | |||
| edf8af3e4d | |||
| 5a76275571 | |||
| b147ee1c99 | |||
| 8b7cc8a220 | |||
| 88931a4a56 | |||
| df187bed58 | |||
| 8b86bc6b3f | |||
| f9ac64023a | |||
| 3a710e1e50 | |||
| 1d4f58f362 | |||
| abfd0a0a2e | |||
| 98839b15dc | |||
| 5b885e98cc | |||
| 58e29608e5 | |||
| db71cfd396 | |||
| 0de9cfb240 | |||
| 2a8efb246d | |||
| 071cf4eed8 | |||
| 87a8d8d490 | |||
| d3caa1dda9 | |||
| f832d44f3a | |||
| 103ab700fc | |||
| 6419fa6e61 | |||
| 98cf2adf92 | |||
| 5660d2e83b | |||
| 5e3e242981 | |||
| 65c31fb457 | |||
| 0f891075cc | |||
| 6d898367e4 | |||
| 003e63b7fb | |||
| 73c9e15976 | |||
| 1dc1d673dd | |||
| 46818d9a02 | |||
| d6a585c6cc | |||
| c54fcf920c | |||
| 467c7f77f5 | |||
| 3c51287178 | |||
| 9d8fdcfa12 | |||
| fadd8a7f79 | |||
| f2afb7ab1a | |||
| b52d8785bb | |||
| 70846525bf | |||
| abe77916a3 | |||
| 660846a0d8 | |||
| 8dec77f30a | |||
| 5812c8f939 | |||
| 1c673e11ac | |||
| bf54bcfd9b | |||
| 33a0b8f11f | |||
| 61ffdabc51 | |||
| 2f224047bc | |||
| 2747fa82e3 | |||
| 5dd80c91cf | |||
| 495e602599 | |||
| 545ddd4ec9 | |||
| 9fff53f137 | |||
| 1d38fc0879 | |||
| 48f44b8920 | |||
| e365818ef5 | |||
| c2bb3010cc | |||
| 4ca8003d24 | |||
| 6a212926e0 | |||
| dae5c0440f | |||
| 6b1d083faa | |||
| c8510bea2a | |||
| a00e84018a | |||
| 3435806020 | |||
| 27f0a0fcfa | |||
| 1f4bb0128a | |||
| e686b6b7d4 | |||
| b74d46b425 | |||
| aa08628b72 | |||
| d4b2c48916 | |||
| 152846cfd5 | |||
| 48ef1c8605 | |||
| de72cdb61a | |||
| 4c17101e27 | |||
| 0c1b3b0175 | |||
| 45b51d9bfa | |||
| 127916f03e | |||
| f94e9c98f9 | |||
| e52523f1fa | |||
| 2d36f75660 | |||
| a541423de5 | |||
| 8e98d1710b | |||
| 7b53756753 | |||
| e20d7982f4 | |||
| ff8604f44a | |||
| aaddd8e26f | |||
| 5e7fd398f2 | |||
| 53cc5f129f | |||
| 881e67d3e2 | |||
| 2c385aba12 | |||
| b53616addc | |||
| ff3796b7a0 | |||
| 9aa061e093 | |||
| 9524a31fe6 | |||
| 9c4f2dcf6b | |||
| c70120bcaa | |||
| ea693b3ffc | |||
| 62ec7d91a9 | |||
| 01b6799a31 | |||
| 52f3a88e36 | |||
| 35687c01ec | |||
| ed01407382 | |||
| 3dbe92a667 | |||
| 127ae75b5b | |||
| 3d90eaf32c | |||
| 4bbfacd7de | |||
| 5bb0f30c77 | |||
| b179a2fa49 | |||
| 3d0f0b0f52 | |||
| c11f4a5dc7 | |||
| dcb9d7b7fc | |||
| 87a39fa264 | |||
| 24f64e9d59 | |||
| d7f380fc73 | |||
| a37a1a6b95 | |||
| 33c3fc158f | |||
| 3a6afd6958 | |||
| 378f4e13fb | |||
| f4d7e30b5d | |||
| 088be2f1a5 | |||
| 56cab93554 | |||
| 17734753c8 | |||
| 36fa5e1d73 | |||
| abc364835c | |||
| 061625e474 | |||
| 0888577cde | |||
| 906bf18971 | |||
| 4398afe298 | |||
| 7c14e9e7a3 | |||
| b6798a3466 | |||
| 867c7b1752 | |||
| 0ef8f62a58 | |||
| 03f1f9f157 | |||
| a5e257a2f1 | |||
| f550750e30 | |||
| 6865c7f4a1 | |||
| 9d2bb15ffd | |||
| 336b14a4ce | |||
| 344e8f50ae | |||
| ba0b7f33bc | |||
| 49bc2e1762 | |||
| d3ec067224 | |||
| 267d0494d3 | |||
| 172f6bc29f | |||
| 4f93db928f | |||
| c10ee98076 | |||
| 0820cffd9d | |||
| 7f90d64064 | |||
| c4c98910e8 | |||
| 06f1ca232e | |||
| 90320c2b12 | |||
| f5885f612a | |||
| af74059945 | |||
| 42948185f9 | |||
| 6329778123 | |||
| eadf8f5266 | |||
| c4a0e47a84 | |||
| f9661e3b72 | |||
| 1715d4d056 | |||
| 40fae42a9e | |||
| 19e55c1185 | |||
| 6443a46abb | |||
| 8fb2e4b7f4 | |||
| 0be25fa16a | |||
| 8743c028a3 | |||
| 7174fd056a | |||
| cd188691f6 | |||
| c9586e7320 | |||
| c35da39ba6 | |||
| e2639b8055 | |||
| 558ed48874 | |||
| e38a3e5f53 | |||
| 1175696590 | |||
| 95862906a4 | |||
| 44cc8d883d | |||
| 4c607302f3 | |||
| a37ccac097 | |||
| b8c460e252 | |||
| 4df35ef8c0 | |||
| 397ac4a154 | |||
| 3e6854053d | |||
| e155301b60 | |||
| 197c315f07 | |||
| 5654125091 | |||
| 3768c22aed | |||
| beb43a785e | |||
| 34e10ac41e | |||
| 8e26edabba | |||
| d6cda6337b | |||
| 5b1638ab42 | |||
| 3537ccf3cd | |||
| d15a9945de | |||
| 61fa371fd4 | |||
| 05802ae91c | |||
| b4df799a37 | |||
| 6553bd70c5 | |||
| f3d0c6f28c | |||
| 09e35513b0 | |||
| 381e25cda1 | |||
| c763c174d5 | |||
| d4f3239844 | |||
| 806e9528f0 | |||
| aa59d9ecca | |||
| 1226af6376 | |||
| 596ecba13f | |||
| 57290d6a4b | |||
| 52251d420f | |||
| 95e365fe4f | |||
| 4f37f2fa0a | |||
| 716b7833b0 | |||
| 84d8d33349 | |||
| 132f90b28e | |||
| 7caabad651 | |||
| c4f3b0d653 | |||
| ddb9410c60 | |||
| f8ca73c164 | |||
| 9512846bb0 | |||
| 224097311c | |||
| 903718019e | |||
| a79ae2d6b5 | |||
| 71cc352982 | |||
| 94381dc5c0 | |||
| ac90d678c1 | |||
| c3959bbe63 | |||
| b88b92d884 | |||
| b05356b8e2 | |||
| 37a9315066 | |||
| 7324ec72ed | |||
| 90e8aa234d | |||
| 40669a14fe | |||
| f55c52d99e | |||
| a47b94e1a6 | |||
| 505af40b7b | |||
| 1fef1aa500 | |||
| 3aa63675c1 | |||
| 5825a5cd63 | |||
| 01d5b031a9 | |||
| 30b6aae25b | |||
| 54ebf14f02 | |||
| 2654f85c32 | |||
| fa9573cf54 | |||
| 98ea3d1a92 | |||
| e4b20908dc | |||
| 9b51ca3753 | |||
| 6d4ce03c10 | |||
| 1316dae035 | |||
| 79a6e43e02 | |||
| 625a4819e9 | |||
| 2838b3756f | |||
| 4f9dcfd584 | |||
| 37200b4ced | |||
| 4afbbcde99 | |||
| a05c3725e7 | |||
| 7110844c7c | |||
| 2a205a9634 | |||
| 1fad2c513c | |||
| 1ad4c16d23 | |||
| affc336f7d | |||
| e7f21db79a | |||
| 523dd52567 | |||
| 3191df85e4 | |||
| 2c37915ef7 | |||
| 1a8bd17f01 | |||
| a42907e7c8 | |||
| 1fc5bc8f3b | |||
| afebbc294b | |||
| dd50d9cd12 | |||
| 70f682edd6 | |||
| 48f7cee0c4 | |||
| 91fddff077 | |||
| c09144690e | |||
| 5cd4fde48a | |||
| fe90438f52 | |||
| a227bfe826 | |||
| a5f2e3f2e1 | |||
| 0dead1c4fe | |||
| 2db751bae4 | |||
| 5d6cd6ab9d | |||
| c93655d199 | |||
| 53cb22c474 | |||
| b58ab5e692 | |||
| f98dfb7c52 | |||
| f7c8178a45 | |||
| 336462bc02 | |||
| 7af0b6e6a5 | |||
| d1d22660c8 | |||
| 8afeeefc51 | |||
| 7f49a437ad | |||
| 6f1651dfc5 | |||
| 5372023651 | |||
| 659e92f95b | |||
| fd79df810c | |||
| 3f714dd030 | |||
| f39e013eca | |||
| d0367ddc36 | |||
| 1ce519673a | |||
| 03a96d4fff | |||
| 768eeeba1f | |||
| b068d20dd3 | |||
| 97a61ddfc0 | |||
| 4ed45c8616 | |||
| f4fc3dfab9 | |||
| 4673034737 | |||
| da155bfca3 | |||
| b6676b92bf | |||
| 363e0e11b3 | |||
| 7af5249e9c | |||
| ff663a1a9a | |||
| 860a09f6e8 | |||
| 59262a5c72 | |||
| e10e1f990f | |||
| ce8fe53d4d | |||
| bfad36af3d | |||
| c909dee4aa | |||
| 6775cfe170 | |||
| 995b612537 | |||
| e61b8e9777 | |||
| db0d90c0f0 | |||
| 6edacd4fd4 | |||
| 0df5e56dee | |||
| 16e0bebc29 | |||
| 5be959f4b8 | |||
| ea9a5fa3a0 | |||
| 2e15cfaed5 | |||
| 57d8673bb2 | |||
| bd8a8f744c | |||
| edc0734f9f | |||
| 0ad9da1076 | |||
| 6a8a005951 | |||
| fc8aaea395 | |||
| f469ce0227 | |||
| 1fb1b3d563 | |||
| 1baa31db04 | |||
| 0e4c972b19 | |||
| 8f438ff314 | |||
| 9bb5266d61 | |||
| edbcabace6 | |||
| bcc9e1c761 | |||
| c390997f79 | |||
| adff45de00 | |||
| a9cf555513 | |||
| 7885e4f80c | |||
| 8cccb5da36 | |||
| 1dc6c60de6 | |||
| 8cc9cb8caf | |||
| b718fcf185 | |||
| 495418cac2 | |||
| 3c031a9065 | |||
| 5109e84fcb | |||
| 7616813537 | |||
| 06230bb14b | |||
| a8e0c1691d | |||
| 8e9e2670fd | |||
| 95665f0274 | |||
| 26dbbd8dc9 | |||
| 2c991043ae | |||
| e739925da2 | |||
| 65ca6be4cd | |||
| bddb4eee6d | |||
| 8470a5f2ac | |||
| 2509d9cd9b | |||
| 633c2e5b8b | |||
| 9f5ae6f897 | |||
| 06231fe321 | |||
| 76a9a99762 | |||
| e2f1036ff1 | |||
| acd8e1765b | |||
| 79b97f089c | |||
| 6a6a314718 | |||
| 6be556dad2 | |||
| cee45b87ee | |||
| 9e47c34449 | |||
| ba96432757 | |||
| 7acd7ec8fb | |||
| 333763b3e1 | |||
| 7137064ead | |||
| 9813ab55a7 | |||
| a656b0c7dd | |||
| 9cf8ef47bb | |||
| ae6a0faa03 | |||
| 88a000d1d6 | |||
| 158c3608a0 | |||
| d529d5c52f | |||
| 2e549869af | |||
| 5346a12641 | |||
| c872f46257 | |||
| 56389be6a0 | |||
| 169b76161f | |||
| 2a56a8490b | |||
| 25844c5870 | |||
| 8b68fb319f | |||
| 3dfae86b00 | |||
| d26da8a4a8 | |||
| 0cbb375a49 | |||
| de1d971e44 | |||
| a031752d33 | |||
| b3b3cfff57 | |||
| a730b4485e | |||
| 897ad8c3eb | |||
| 6266146ecb | |||
| 7ed13b2b12 | |||
| 13e8ed7b6e | |||
| d2e2355673 | |||
| 951b4fde90 | |||
| 0b5cf19078 | |||
| 1274eaaec3 | |||
| 638fb12e16 | |||
| aacfbf7178 | |||
| 0f5a1a6335 | |||
| 73cbf96a65 | |||
| bee4a4b22b | |||
| 332e39b0fd | |||
| 7827fa2846 | |||
| 9d7c8f9786 | |||
| fbe02cd287 | |||
| 570fd0a27f | |||
| 7164c183ea | |||
| 094b43e748 | |||
| d16009272d | |||
| 3a3212f96c | |||
| 63b02936b1 | |||
| 2eced17ca9 | |||
| c4f0b0d60d | |||
| ec64533b4b | |||
| 670cee5923 | |||
| 67091fd72f | |||
| a5dee142bf | |||
| ade516d188 | |||
| da746c0e66 | |||
| 14826ee44b | |||
| 767c24dd56 | |||
| 22487c1893 | |||
| e6e2e8a91d | |||
| 4ebe354caa | |||
| 3b9c87c172 | |||
| c36aac0cdf | |||
| ab04db17f3 | |||
| 624cbee901 | |||
| a7891ee323 | |||
| 404c414f76 | |||
| bc55b870cb | |||
| ed282e444d | |||
| 8d3cf31941 | |||
| bec8720a4d | |||
| b9121e1468 | |||
| 55b72a9156 | |||
| 2ce78f333b | |||
| 5834ac7f37 | |||
| 1aaf5e10f4 | |||
| 82212aac16 | |||
| a118cbeb1e | |||
| c7b956344f | |||
| 2fe19dbf0e | |||
| 50e0e3bf98 | |||
| 5be941663b | |||
| 7a7acfa15c | |||
| 15ee30bcdf | |||
| 70362b8f96 | |||
| b217967d9c | |||
| eadf2d2cfa | |||
| ba441a826a | |||
| 7f063cf626 | |||
| bb2de4cca0 | |||
| fae51b4444 | |||
| 45438e09e5 | |||
| 1492d5acbb | |||
| 8f0dae936b | |||
| cd1222d27f | |||
| 71cfaaad63 | |||
| 66682260a0 | |||
| a1fdd5de05 | |||
| 5bcba84acb | |||
| 2cc362edfc | |||
| 8e5e638914 | |||
| 1c689ccfbd | |||
| 7b300a97c6 | |||
| 3199bea647 | |||
| bd31a3a598 | |||
| b3d58c5fa5 | |||
| 3457283220 | |||
| 33fc733f6d | |||
| 07a600c05f | |||
| cf30c49b0e | |||
| e2fd05db81 | |||
| 9d49ed9e61 | |||
| 5d6a44912e | |||
| ad3b0f84c2 | |||
| ceb111eccd | |||
| 53c56f5c0a | |||
| 15834921a8 | |||
| 8a1970bb3d | |||
| 50ce20071a | |||
| a8771052f3 | |||
| c53390beb3 | |||
| 0ec468becb | |||
| 2c45d4f1a5 | |||
| 2036c63a59 | |||
| e56d3dc632 | |||
| 8dedf719e0 | |||
| c04dfb4b77 | |||
| 281d10f3b4 | |||
| e28665fd05 | |||
| cc3b6d7e55 | |||
| 37d1c48f2e | |||
| 28187aea37 | |||
| 963d0d582f | |||
| ce279dda60 | |||
| ba92a90832 | |||
| 624bec0c88 | |||
| 85934de439 | |||
| 6a56132de9 | |||
| 8075684d1d | |||
| 3d3ac28848 | |||
| 5ec879833e | |||
| e8d2b494bf | |||
| c271537878 | |||
| ae2a3ba8a3 | |||
| 72215ad898 | |||
| d36e3c0d91 | |||
| 086ca46218 | |||
| 6c1288823d | |||
| 11c83759d2 | |||
| 9e2268ce72 | |||
| ce2f8ad003 | |||
| af661212b0 | |||
| f26db2b523 | |||
| 0451ef4190 | |||
| 84c5cdeca7 | |||
| ee8014385a | |||
| 27c63202cd | |||
| 9d446a6e29 | |||
| df27d6492f | |||
| 1d12d8e2ff | |||
| 551eb3851b | |||
| cb683b6674 | |||
| 4e5b96b8ea | |||
| 1db7b86f89 | |||
| 7198962847 | |||
| c7b32fd29a | |||
| 4b9ca6ca25 | |||
| f4a502024d | |||
| a9fd1978e1 | |||
| a73f6a4aeb | |||
| e34f13bd6a | |||
| f39ef0d799 | |||
| 66b9f2dd5c | |||
| b9d50179c0 | |||
| 35cac0d7e9 | |||
| 46980e6b50 | |||
| 7fc93a667d | |||
| e8e9105f5c | |||
| e6cd24065c | |||
| 65ae0e06f5 | |||
| 04a702fb0e | |||
| 5934178a5f | |||
| e43b28969e | |||
| a1bd7b4815 | |||
| baaf5af664 | |||
| 1f1500c661 | |||
| 3d92fac1d6 | |||
| 682a5d1c44 | |||
| e5f10d052a | |||
| 91bd2ac69f | |||
| e7ec55eb61 | |||
| c469b5e506 | |||
| e384470705 | |||
| 7c1e91b945 | |||
| 78e9623598 | |||
| a0f756a4cb | |||
| 108be0bc23 | |||
| e772407e38 | |||
| e789c32564 | |||
| 03f7173855 | |||
| 61b5a8295c | |||
| 665c88a681 | |||
| 53402bdda5 | |||
| 56295b3c98 | |||
| 0cbd0f67a1 | |||
| 7cf23668af | |||
| 7465b8b5b9 | |||
| 6019fdbe36 | |||
| 532eb15e3b | |||
| 064abbf8dd | |||
| d88a0412a0 | |||
| 296b510c41 | |||
| 473bb64b42 | |||
| 6df9099707 | |||
| b8c7441c92 | |||
| 79c21b24cd | |||
| b72e90f0b9 | |||
| 658ce479eb | |||
| 2e316c35fe | |||
| 3e9546aa10 | |||
| 21bd781468 | |||
| 2ea9c49b2e | |||
| b926519424 | |||
| 9e82fd124a | |||
| d859def7d6 | |||
| 2d5926913e | |||
| 8bde83bb7b | |||
| 08f592a9cb | |||
| a088071914 | |||
| a313f97736 | |||
| 367a096b8a | |||
| 363411f57c | |||
| 3bedd60b72 | |||
| bed277f899 | |||
| 6131101520 | |||
| b8f5709e65 | |||
| 689e8cf259 | |||
| 4acbe5b560 | |||
| 2c80ca7812 | |||
| 75b5458c02 | |||
| 1f446ac60f | |||
| 0b59b0a2cb | |||
| a13b1d08c4 | |||
| 39f5110464 | |||
| e67bf63bc5 | |||
| 2fffaca696 | |||
| be3dde7657 | |||
| 4d94784e88 | |||
| 7ea39def40 | |||
| 5b202121df | |||
| 1e0278fe72 | |||
| fd70a01803 | |||
| e6a909bba0 | |||
| 7ceb4b264b | |||
| fbaf78d18e | |||
| 7b8189dae2 | |||
| f29bdcab3f | |||
| 45de42fc71 | |||
| b62a1e5d88 | |||
| fbf86ab7e3 | |||
| 5dec67aa32 | |||
| 6e4d038b38 | |||
| 9b25cea893 | |||
| 4a2fd0166e | |||
| dfeab8793f | |||
| a867291b51 | |||
| 0fdf9a3419 | |||
| 796b3cf710 | |||
| 27e9cadf91 | |||
| 89d852f4ed | |||
| 9ad4c96572 | |||
| ed89bc652e | |||
| 746f2ba7e0 | |||
| 09acd12586 | |||
| a1d8e2237c | |||
| 86a486b060 | |||
| 173f899881 | |||
| 8436a319f8 | |||
| a565282a94 | |||
| 5d7beb71e6 | |||
| 3218be613d | |||
| 9ade3a7c39 | |||
| 3de5142a5b | |||
| ba3319d0cd | |||
| 2c82cf525a | |||
| c4e53d5654 | |||
| 7591f19707 | |||
| 7739652e21 | |||
| 40806ffda4 | |||
| 29783e2f3f | |||
| a888ed25ec | |||
| c402878262 | |||
| b8cbec9462 | |||
| 3d60c3af49 | |||
| 551198b6ec | |||
| 11395d8e5f | |||
| 5c89478ecb | |||
| f0a8133b94 | |||
| 83bdcdad1f | |||
| f1b5a457df | |||
| 8d00a6b2a3 | |||
| 8823392846 | |||
| 70f1faa312 | |||
| 61f95bf59b | |||
| 992dfe39fb | |||
| 964a95d934 | |||
| 2f1df92dc3 | |||
| 71d128a325 | |||
| 1c5aa8ce28 | |||
| 5dab6ef30b | |||
| 473dafbb58 | |||
| 6020248afc | |||
| 2c119e900c | |||
| 9f08024514 | |||
| 6e1c6fbc49 | |||
| a8212404ba | |||
| 5399c89d8e | |||
| 52e8e68cfc | |||
| b3e5d2924a | |||
| 2161a5d36d | |||
| 4a482adefe | |||
| 3c23dfd792 | |||
| d644e150ec | |||
| ceda3f8427 | |||
| 6ae2e60b33 | |||
| 56f86b1303 | |||
| e62774bf9a | |||
| c97253cb5f | |||
| 285992d137 | |||
| 67f137927d | |||
| f96025ae38 | |||
| 166b46f6a3 | |||
| 304ad35f29 | |||
| 8d8b41253e | |||
| 46ad5920de | |||
| 03c824a1c9 | |||
| 7f3fae5da7 | |||
| a9a51a76c7 | |||
| d887e9fe6a | |||
| 1a14eeb39e | |||
| c68e1494ac | |||
| ad0b3d4c28 | |||
| 785641cc47 | |||
| ae40f36853 | |||
| 2cada0fcbe | |||
| 1f45a3aa9f | |||
| 2a917ec091 | |||
| bad5f32ffc | |||
| b006fff6ed | |||
| 35f5a362e3 | |||
| 8924b2ca7a | |||
| 46de4000a1 | |||
| aea09998f9 | |||
| 80c001ba9c | |||
| eebf08217c | |||
| 44ca1ebc9a | |||
| 6854f5c8d3 | |||
| a362d5a977 | |||
| d2aef5df04 | |||
| 87992a36e1 | |||
| 2c6ef0dffe | |||
| a94670d6ca | |||
| 9d876b44cf | |||
| 32af01c8f4 | |||
| 803f7f43b4 | |||
| 2260303876 | |||
| 943058b84a | |||
| 4f8f4fe9b8 | |||
| 92aa223f3f | |||
| 4dafe15386 | |||
| 5e70d2ec36 | |||
| f7f84ef28a | |||
| 1f7ce33643 | |||
| 22a03ff3df | |||
| a256aec1cc | |||
| 8da1ab2413 | |||
| 6b6ab9e406 | |||
| a2c35ba83d | |||
| dfb8757719 | |||
| 65d68a3116 | |||
| 13d709c88d | |||
| 31bbd5295e | |||
| 270bccc432 | |||
| 4915b3c62c | |||
| 8d8f9c166e | |||
| 6be7f3e81b | |||
| a635360c95 | |||
| 2d32a5e0de | |||
| 3cd37c2be6 | |||
| dc63f1c735 | |||
| 94462015f2 | |||
| 689cce246a | |||
| 5d3ed34a31 | |||
| 8099ff0fa9 | |||
| c0fd38b03b | |||
| ab1fd89026 | |||
| b1d357956c | |||
| 045269d88f | |||
| c456045381 | |||
| 54a44991fd | |||
| 975adba203 | |||
| 0d8091b41a | |||
| 41db19ec01 | |||
| 00be8908ef | |||
| 7c5263415f | |||
| d93da5abd9 | |||
| 08a7dd9e85 | |||
| 7476f8a8e9 | |||
| 0c04c845b4 | |||
| b4448df047 | |||
| 74502510db | |||
| c5d94eff03 | |||
| 01501b36b5 | |||
| 5e5913255c | |||
| b1cf4dc592 | |||
| ec53815bb0 | |||
| 01c91a6398 | |||
| 6d1c72718b | |||
| 768d936ba9 | |||
| ef8220c236 | |||
| 47a4403cbe | |||
| 09e0187a7d | |||
| 9d4fea4407 | |||
| df508335a0 | |||
| 6900433496 | |||
| fc5f68bd7c | |||
| e9ee41e1a1 | |||
| e1a63b6da5 | |||
| 45a84a65ec | |||
| 8550612a8b | |||
| cc02e89e1b | |||
| ec808c68f5 | |||
| 644d94ed22 | |||
| b7d50de7d1 | |||
| 6a53aaf010 | |||
| edaab02d0b | |||
| 7a03474d07 | |||
| c810f6165f | |||
| 23673ba60c | |||
| 065be00d43 | |||
| da29b194a7 | |||
| 010a69f7ad | |||
| 242bae10d1 | |||
| b44f79ab60 | |||
| 4f5d817789 | |||
| fd13769010 | |||
| fb94e1cf6c | |||
| b03d539578 | |||
| 9f4582bf27 | |||
| 3a79251b91 | |||
| b4bc39f0d9 | |||
| 2526ac32fa | |||
| fc71dea8e9 | |||
| 27b51e7ede | |||
| 5511d6339e | |||
| 79a4ad8cfd | |||
| a23325584b | |||
| 61cdb2fada | |||
| 8b96163e37 | |||
| d84e246b23 | |||
| 3dd7da5a39 | |||
| 260e29989c | |||
| a08cc44cd0 | |||
| 98cc35e614 | |||
| b5e4b7db86 | |||
| a10a9a2255 | |||
| 18f5bcd62f | |||
| c2cbbba637 | |||
| 8e9b9c54fd | |||
| f0a7af4af1 | |||
| 2c262f27ad | |||
| a4819c4016 | |||
| 52e7166177 | |||
| 581f7fcbf3 | |||
| 65da0b877b | |||
| 06e8dc21fa | |||
| 03c07cf969 | |||
| a52aac876a | |||
| 32d8f8b648 | |||
| bfeb41fea9 | |||
| fb118d88f1 | |||
| aacce0b453 | |||
| cee382651b | |||
| 64633a1d63 | |||
| 63e5880154 | |||
| 5e383cb7b5 | |||
| 163af3b269 | |||
| c1bfa55ea6 | |||
| 5ffcc21917 | |||
| 790b69d0a6 | |||
| 313e07de43 | |||
| 7b27009d31 | |||
| 6b318f94fd | |||
| 7da1b40a5c | |||
| d90a98c1ef | |||
| 8a174711f4 | |||
| 48f386546e | |||
| 24d7912f1f | |||
| 090868b299 | |||
| 6dbfda36ee | |||
| 4c6315f2a5 | |||
| e2cdbb7580 | |||
| 13abd86be0 | |||
| 8364b00d3f | |||
| 274e4fdcce | |||
| 5354d3b9dc | |||
| 560f58a7b3 | |||
| b3697c1e21 | |||
| 051b61b2e8 | |||
| fc229fb645 | |||
| 93517d90ec | |||
| 0611e373b8 | |||
| cadaf368ef | |||
| ddcd9cb0c1 | |||
| d00158fa38 | |||
| 4a6dfc9a2a | |||
| e0829ffecf | |||
| 02ce0c993d | |||
| ac3eaea3f6 | |||
| 891af745bb | |||
| 3e49e78dfe | |||
| c67dcb1d5c | |||
| 0208edb9ed | |||
| 7f966b0a24 | |||
| b6f398bd2b | |||
| cb096a1d9b | |||
| 9913ff67ca | |||
| 9f4b274985 | |||
| 6903ccb3a6 | |||
| 020fbf33e5 | |||
| a7b8cc6307 | |||
| 1e5edd1c4c | |||
| faafc8fdfc | |||
| 75543f9bcf | |||
| 5f158137dd | |||
| e7f281a03d | |||
| 6813b42ae1 | |||
| b20d78c102 | |||
| ec3087efc4 | |||
| bf04562180 | |||
| 2faec8513f | |||
| a8b732abb9 | |||
| fbf90b4efc | |||
| 34aa515344 | |||
| 35f8379d65 | |||
| 9d752286f4 | |||
| 6b854cc9ad | |||
| 58e11f12e1 | |||
| 850c44b12a | |||
| d6a37cbd6b | |||
| f2dee26cdb | |||
| 2ee115a47d | |||
| 849c0be13d | |||
| 9a51c7a3b6 | |||
| e9e083d9ee | |||
| bb871a32fd | |||
| 04811681a3 | |||
| ec3f4cf121 | |||
| e2060a1460 | |||
| 4a70ba0134 | |||
| 630fda3c45 | |||
| 04762b3f7e | |||
| 00b48695f6 | |||
| e996557b51 | |||
| e5faf00df9 | |||
| 4beca9497b | |||
| 049c3918a4 | |||
| d71286b265 | |||
| 80eb9aa036 | |||
| 70813984be | |||
| f904ca8f11 | |||
| 068c347178 | |||
| c9f5b2a330 | |||
| 529dc52823 | |||
| b4b4c82e59 | |||
| 276e7ee729 | |||
| 808dfe7d31 | |||
| 88b800415c | |||
| 1679b6b406 | |||
| 748cc495be | |||
| c3ad6ae8cb | |||
| da44e67d65 | |||
| 70be5ae184 | |||
| fe260a6a06 | |||
| 631afde7b6 | |||
| 7a6e4d5f2c | |||
| 8683273022 | |||
| 2c9f691d8e | |||
| 398a804b41 | |||
| 79ffa3e29a | |||
| db0319bfba | |||
| 747ad313e6 | |||
| 4f5b7be7b8 | |||
| e3b9576a2d | |||
| 0dcd74388f | |||
| 302f99172f | |||
| 05adb5ee84 | |||
| 013f63b52f | |||
| 640c28a260 | |||
| 2c06dfb553 | |||
| 63ae52d99c | |||
| 03026a84c7 | |||
| fd33e4c3d4 | |||
| 4606b3980c | |||
| be6affb2c6 | |||
| b75fc89011 | |||
| 5849309dad | |||
| 02dd9aca32 | |||
| 4c4905e60b | |||
| c63251b832 | |||
| 808ade6e8d | |||
| 73fb523b3d | |||
| 0c56b55c2a | |||
| e66b56af58 | |||
| a718aa9c69 | |||
| 49749b3f59 | |||
| 045c6bfc9f | |||
| 91a6f20dba | |||
| 4eb5c97725 | |||
| 978b230f00 | |||
| 9d2632106c | |||
| dd73415c00 | |||
| f0635ba323 | |||
| 38205b3b97 | |||
| ae7306a3ef | |||
| 5448216e7a | |||
| 4f111a710d | |||
| f5df39a971 | |||
| 1866257ff5 | |||
| 8d9fbbf7e9 | |||
| bcd87dfa6d | |||
| 653aca500f | |||
| ca36fd35a6 | |||
| 260b2ad5c9 | |||
| 230413a5cc | |||
| d9618472cb | |||
| 9d96789302 | |||
| 0a69979417 | |||
| ce21c72f37 | |||
| b4ade5e956 | |||
| c79f387af2 | |||
| 9171a62979 | |||
| 793704c111 | |||
| 0cb5c8ca94 | |||
| ca5f50586b | |||
| 6f09c10bd7 | |||
| 8205f33ec6 | |||
| 5360c577af | |||
| ea48fcac64 | |||
| fbc639030a | |||
| eef042b469 | |||
| d34bf1ee7d | |||
| 6987f4be83 | |||
| 1b443af123 | |||
| aa100c2383 | |||
| e3541d78ce | |||
| c0b973370c | |||
| 129419df9d | |||
| ac635c4b38 | |||
| f05f7168ac | |||
| 21a5c25760 | |||
| 756b44db5e | |||
| 38538ca358 | |||
| e22b019147 | |||
| 39fab36541 | |||
| b96a1dcefc | |||
| 4ab56202f0 | |||
| 9baa6e3c85 | |||
| 300b4582ec | |||
| 3cdd9b6af2 | |||
| 355d71769a | |||
| 851f785f50 | |||
| c462dbb745 | |||
| 5706fea2eb | |||
| c403951050 | |||
| 214e425796 | |||
| 2ea2c037e8 | |||
| a20ed9c876 | |||
| d995cc01bc | |||
| 3643693bde | |||
| 928c3ea3c2 | |||
| 779b07b1b5 | |||
| 2aea40d26f | |||
| 7a2a05063b | |||
| fa58ac7419 | |||
| 44ad83790d | |||
| 48ede05926 | |||
| 50ef2e83ce | |||
| 1be72c87f2 | |||
| 961b76fd1e | |||
| bc6a82a7fe | |||
| 1ac81b8f17 | |||
| 79e556ac80 | |||
| 50fdea4095 | |||
| f77c1f0256 | |||
| 9775d3b93f | |||
| 4fb431f3bd | |||
| e66edbf2c7 | |||
| 8828de9456 | |||
| 484ad67152 | |||
| 97e8ec44cb | |||
| 3454e330f5 | |||
| e91af9cea4 | |||
| 8e1d2855c6 | |||
| 0e01bd167e | |||
| ec4952766e | |||
| e976de18e0 | |||
| 81f5b47918 | |||
| 5e7ddc07db | |||
| 11a8e6e565 | |||
| b9f78c5f0b | |||
| af4aec6a69 | |||
| f8c3064b07 | |||
| d3c0e5979a | |||
| 43a720e09e | |||
| 8a232be59f | |||
| 01018737fd | |||
| 0c228fab1f | |||
| 0d0e795faf | |||
| 76965111fe | |||
| 67d2067a28 | |||
| 4e63395a35 | |||
| 1d85f49a97 | |||
| bcad91dc18 | |||
| d516b8a4dc | |||
| 2d651ca51d | |||
| f9b52f9433 | |||
| f6f3fcf1d3 | |||
| 1d3e324b9a | |||
| 350101091a | |||
| 343360cdbe | |||
| 739c3ad4cb | |||
| ed38a863d4 | |||
| 5d797959e3 | |||
| 3626d2e1bf | |||
| 7b272a0b21 | |||
| cdd0c52182 | |||
| 8b490dd4f9 | |||
| f30494ad30 | |||
| 6e6b456115 | |||
| ebc56e5eb7 | |||
| 2b5fb427df | |||
| 8f62b8cd5f | |||
| de673afb9e | |||
| 8bd4ef169c | |||
| 59ff0f2ad0 | |||
| fd478715f3 | |||
| 8b21f29978 | |||
| 367f698348 | |||
| bda31f2ba7 | |||
| f9d48272ef | |||
| 865412a551 | |||
| c033ef2d28 | |||
| e1ddb5920f | |||
| 4f6225047e | |||
| 107e3ec360 | |||
| 2b766e216c | |||
| 419453a8c5 | |||
| 862128abf0 | |||
| 491b0522ab | |||
| 5d61780b7c | |||
| 6bd3956e2e | |||
| 3a7963d0f9 | |||
| 9cd2c684b5 | |||
| b9a5881333 | |||
| 9bbf81875f | |||
| 09a1d06c8d | |||
| 1e8daafba4 | |||
| a726021ea9 | |||
| 189ed2a22d | |||
| b03397ca87 | |||
| d9bf39acb0 | |||
| 21b68e6bb9 | |||
| aa15145765 | |||
| c6b7902eca | |||
| 72d60bea62 | |||
| 1239b1e542 | |||
| 420e730003 | |||
| 56e682314f | |||
| 8e8fb1cc8c | |||
| cf00e51559 | |||
| 8a9b61185e | |||
| ac406ac6f3 | |||
| 9f43bd5294 | |||
| 7b853c74f3 | |||
| 83bd026c4e | |||
| 3fce40b4c9 | |||
| 75056923dc | |||
| 597d4b7469 | |||
| e7ddec4329 | |||
| 5f1a25c2ec | |||
| 5b8f08f3a3 | |||
| 544ceefef7 | |||
| 33c55db206 | |||
| ce12fa0d22 | |||
| 2f50c17320 | |||
| 83b6fe7cb2 | |||
| 63eeb88066 | |||
| dfeb4204e7 | |||
| 2a8f66f360 | |||
| d34f047418 | |||
| 56331ea150 | |||
| 482d789870 | |||
| 0e6055881a | |||
| f10d1b0a9e | |||
| a2ef29e75d | |||
| 6468a6505b | |||
| 0e1655004a | |||
| 26421f78e2 | |||
| 22d3d542ae | |||
| 714f48deb7 | |||
| dda82466c9 | |||
| 1678f9a021 | |||
| fc9969570d | |||
| 5c760a83d6 | |||
| bed0b41789 | |||
| 4859fd301a | |||
| 957c85d641 | |||
| a1c4c00d1c | |||
| 2cd8e25466 | |||
| d7829c371f | |||
| 36f236f69f | |||
| 80b877879c | |||
| f698d77719 | |||
| bebb76e51a | |||
| af86dd92c5 | |||
| 3ed4d29af3 | |||
| 14f4f66f84 | |||
| d4ffe2eadf | |||
| b0c3ba2a11 | |||
| 0adf7a5c84 | |||
| 2e9a252910 | |||
| ecb4854c78 | |||
| b8ecc5e591 | |||
| 9dc272fd17 | |||
| 763430099b | |||
| 28d28cffd7 | |||
| 78e9d430bd | |||
| 499fa59b92 | |||
| 817164c4f3 | |||
| e0ad618d1a | |||
| 9329ef34e2 | |||
| 2c7444c15b | |||
| a586b267db | |||
| f665b1f623 | |||
| c34425b231 | |||
| 7e47e07747 | |||
| 90e1f87fb4 | |||
| 05a9ef9410 | |||
| c41b6b2eb3 | |||
| c8ce49a383 | |||
| 919a6c7028 | |||
| 8a1a07980d | |||
| 8556f7cdf6 | |||
| 0d82e3e72b | |||
| 8bbdbc6cf5 | |||
| ac10d4ca70 | |||
| 1355688a36 | |||
| 88c8d5e34c | |||
| b54ebcb0d1 | |||
| 3532a8c5c0 | |||
| fe28fd355b | |||
| 9a976022e5 | |||
| 240a577361 | |||
| 3851eb0c29 | |||
| 976f6d8224 | |||
| 1461240f27 | |||
| 0c29fcb9bd | |||
| a754a4fcc6 | |||
| 0e165a196c | |||
| 53d29fe79d | |||
| 2854acf146 | |||
| 73035a4369 | |||
| 1da0435b4e | |||
| 84ccbe3ac0 | |||
| 4a86ae0bfd | |||
| ceb1337cde | |||
| 6013555139 | |||
| 1e533706aa | |||
| 2fe9e88c52 | |||
| 2a0b21c8b1 | |||
| f8a5e753da | |||
| 559b18ff5a | |||
| b95592db96 | |||
| a3c471de38 | |||
| 36576d1936 | |||
| e000b7ea6d | |||
| 74c3b2c180 | |||
| 0b7878b1c6 | |||
| 8cffbd9901 | |||
| d32eae030e | |||
| b991e9950f | |||
| 683abe0035 | |||
| a77eabd379 | |||
| c58913062a | |||
| e736fe6557 | |||
| 43464ee4aa | |||
| 26e246e71a | |||
| 98a9a62b2d | |||
| 5210684c50 | |||
| 7ea2dc7176 | |||
| a8c5bf8e34 | |||
| ff3b0db3ea | |||
| e7917d5ee7 | |||
| 2cd3cdaf38 | |||
| d5639a26d6 | |||
| a13cdae4d2 | |||
| 2d53a9e82c | |||
| 57c860a643 | |||
| 744230d7ec | |||
| 8f4cd8a447 | |||
| 9e2d1289c9 | |||
| d05e5ed2c0 | |||
| 070b99d6ef | |||
| eae1040695 | |||
| 06dde739c3 | |||
| 8875595012 | |||
| 1bb95bd1b5 | |||
| 40599918ba | |||
| 1b4483dfa5 | |||
| e18987f235 | |||
| 817089d81b | |||
| 41883ca5da | |||
| 4d71478d50 | |||
| 43ef5bcdd9 | |||
| 55bd30c24d | |||
| 7447b30892 | |||
| 18d4ee0dfa | |||
| f0be7d2e9e | |||
| a0747230ac | |||
| 1df06fc0ee | |||
| ece6bb6e0a | |||
| 0d5810a8fb | |||
| 2bae90e339 | |||
| 0a994573cd | |||
| e941bd8266 | |||
| b167ec794a | |||
| fb3647fc99 | |||
| fbe94c0f57 | |||
| d87aa2620e | |||
| 83b006c615 | |||
| 9feba1c570 | |||
| 57c4b198f7 | |||
| 127b643e44 | |||
| 2fbd0b09f6 | |||
| 520aa26a11 | |||
| d09dae8378 | |||
| 8689ac9139 | |||
| 212a7ed2b8 | |||
| d9b3e56930 | |||
| 7fae8de733 | |||
| be8af75e61 | |||
| b4cf5cd2a3 | |||
| 7649e60d28 | |||
| 0aa981eea5 | |||
| 122b50e114 |
@@ -0,0 +1,30 @@
|
|||||||
|
**/.classpath
|
||||||
|
**/.dockerignore
|
||||||
|
**/.env
|
||||||
|
**/.git
|
||||||
|
**/.gitignore
|
||||||
|
**/.project
|
||||||
|
**/.settings
|
||||||
|
**/.toolstarget
|
||||||
|
**/.vs
|
||||||
|
**/.vscode
|
||||||
|
**/*.*proj.user
|
||||||
|
**/*.dbmdl
|
||||||
|
**/*.jfm
|
||||||
|
**/azds.yaml
|
||||||
|
**/bin
|
||||||
|
**/charts
|
||||||
|
**/docker-compose*
|
||||||
|
**/Dockerfile*
|
||||||
|
**/node_modules
|
||||||
|
**/npm-debug.log
|
||||||
|
**/obj
|
||||||
|
**/secrets.dev.yaml
|
||||||
|
**/values.dev.yaml
|
||||||
|
LICENSE
|
||||||
|
README.md
|
||||||
|
!**/.gitignore
|
||||||
|
!.git/HEAD
|
||||||
|
!.git/config
|
||||||
|
!.git/packed-refs
|
||||||
|
!.git/refs/heads/**
|
||||||
@@ -126,6 +126,15 @@ csharp_style_deconstructed_variable_declaration = true:suggestion
|
|||||||
csharp_style_unused_value_assignment_preference = discard_variable:suggestion
|
csharp_style_unused_value_assignment_preference = discard_variable:suggestion
|
||||||
csharp_style_unused_value_expression_statement_preference = discard_variable:silent
|
csharp_style_unused_value_expression_statement_preference = discard_variable:silent
|
||||||
|
|
||||||
|
|
||||||
|
dotnet_diagnostic.CS1570.severity = none
|
||||||
|
dotnet_diagnostic.CS1587.severity = none
|
||||||
|
dotnet_diagnostic.CS8619.severity = none
|
||||||
|
dotnet_diagnostic.CS8620.severity = none
|
||||||
|
dotnet_diagnostic.CS8632.severity = none
|
||||||
|
dotnet_diagnostic.CS8604.severity = none
|
||||||
|
dotnet_diagnostic.CS1998.severity = none
|
||||||
|
|
||||||
[*.vb]
|
[*.vb]
|
||||||
#### 命名样式 ####
|
#### 命名样式 ####
|
||||||
|
|
||||||
|
|||||||
@@ -11,25 +11,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IRaCIS.Core.Application", "
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IRaCIS.Core.Domain.Share", "IRaCIS.Core.Domain.Share\IRaCIS.Core.Domain.Share.csproj", "{7CBC76F5-3817-46B7-8D9D-79253A89B578}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IRaCIS.Core.Domain.Share", "IRaCIS.Core.Domain.Share\IRaCIS.Core.Domain.Share.csproj", "{7CBC76F5-3817-46B7-8D9D-79253A89B578}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IRaCIS.JWT.RS256", "ZhiZhunAuthenticationCenter\IRaCIS.JWT.RS256.csproj", "{3EF210EE-D5D1-4C93-A8FA-E0DB1852BD39}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IRaCIS.Core.Test", "IRaCIS.Core.Test\IRaCIS.Core.Test.csproj", "{3292B2B4-6E8A-43AA-84C0-AB4A391E8A2A}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IRaCIS.Core.Test", "IRaCIS.Core.Test\IRaCIS.Core.Test.csproj", "{3292B2B4-6E8A-43AA-84C0-AB4A391E8A2A}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IRaCIS.Core.Infra.EFCore", "IRaCIS.Core.Infra.EFCore\IRaCIS.Core.Infra.EFCore.csproj", "{6D8115E5-84D6-424B-8F8D-0C2D40347A8C}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IRaCIS.Core.Infra.EFCore", "IRaCIS.Core.Infra.EFCore\IRaCIS.Core.Infra.EFCore.csproj", "{6D8115E5-84D6-424B-8F8D-0C2D40347A8C}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IRaCIS.Core.Infrastructure", "IRaCIS.Core.Infrastructure\IRaCIS.Core.Infrastructure.csproj", "{07EED0F8-08E6-46F3-ACBE-17BC1391BD4C}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IRaCIS.Core.Infrastructure", "IRaCIS.Core.Infrastructure\IRaCIS.Core.Infrastructure.csproj", "{07EED0F8-08E6-46F3-ACBE-17BC1391BD4C}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "IRaCIS.AuthenticationCenter", "IRaCIS.AuthenticationCenter", "{481329D6-B8A0-491F-A398-1DF66A0FBB62}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IRaCIS.Core.IdentityServer4", "IRaCIS.Core.IdentityServer4\IRaCIS.Core.IdentityServer4.csproj", "{C3DD48CF-B8B3-40F6-9BDB-B7C7F0851674}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IRaCIS.Core.IdentityServer4.MVC", "IRaCIS.Core.IdentityServer4.MVC\IRaCIS.Core.IdentityServer4.MVC.csproj", "{F621ADD6-94E8-4A4B-998E-25B8EF15D39C}"
|
|
||||||
EndProject
|
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{F852ABFB-88AC-48BE-B876-2228BE2373D6}"
|
|
||||||
ProjectSection(SolutionItems) = preProject
|
|
||||||
.editorconfig = .editorconfig
|
|
||||||
EndProjectSection
|
|
||||||
EndProject
|
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@@ -52,10 +39,6 @@ Global
|
|||||||
{7CBC76F5-3817-46B7-8D9D-79253A89B578}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{7CBC76F5-3817-46B7-8D9D-79253A89B578}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{7CBC76F5-3817-46B7-8D9D-79253A89B578}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{7CBC76F5-3817-46B7-8D9D-79253A89B578}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{7CBC76F5-3817-46B7-8D9D-79253A89B578}.Release|Any CPU.Build.0 = Release|Any CPU
|
{7CBC76F5-3817-46B7-8D9D-79253A89B578}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{3EF210EE-D5D1-4C93-A8FA-E0DB1852BD39}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{3EF210EE-D5D1-4C93-A8FA-E0DB1852BD39}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{3EF210EE-D5D1-4C93-A8FA-E0DB1852BD39}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{3EF210EE-D5D1-4C93-A8FA-E0DB1852BD39}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{3292B2B4-6E8A-43AA-84C0-AB4A391E8A2A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{3292B2B4-6E8A-43AA-84C0-AB4A391E8A2A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{3292B2B4-6E8A-43AA-84C0-AB4A391E8A2A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{3292B2B4-6E8A-43AA-84C0-AB4A391E8A2A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{3292B2B4-6E8A-43AA-84C0-AB4A391E8A2A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{3292B2B4-6E8A-43AA-84C0-AB4A391E8A2A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
@@ -68,23 +51,10 @@ Global
|
|||||||
{07EED0F8-08E6-46F3-ACBE-17BC1391BD4C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{07EED0F8-08E6-46F3-ACBE-17BC1391BD4C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{07EED0F8-08E6-46F3-ACBE-17BC1391BD4C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{07EED0F8-08E6-46F3-ACBE-17BC1391BD4C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{07EED0F8-08E6-46F3-ACBE-17BC1391BD4C}.Release|Any CPU.Build.0 = Release|Any CPU
|
{07EED0F8-08E6-46F3-ACBE-17BC1391BD4C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{C3DD48CF-B8B3-40F6-9BDB-B7C7F0851674}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{C3DD48CF-B8B3-40F6-9BDB-B7C7F0851674}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{C3DD48CF-B8B3-40F6-9BDB-B7C7F0851674}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{C3DD48CF-B8B3-40F6-9BDB-B7C7F0851674}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{F621ADD6-94E8-4A4B-998E-25B8EF15D39C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{F621ADD6-94E8-4A4B-998E-25B8EF15D39C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{F621ADD6-94E8-4A4B-998E-25B8EF15D39C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{F621ADD6-94E8-4A4B-998E-25B8EF15D39C}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(NestedProjects) = preSolution
|
|
||||||
{3EF210EE-D5D1-4C93-A8FA-E0DB1852BD39} = {481329D6-B8A0-491F-A398-1DF66A0FBB62}
|
|
||||||
{C3DD48CF-B8B3-40F6-9BDB-B7C7F0851674} = {481329D6-B8A0-491F-A398-1DF66A0FBB62}
|
|
||||||
{F621ADD6-94E8-4A4B-998E-25B8EF15D39C} = {481329D6-B8A0-491F-A398-1DF66A0FBB62}
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {BCC2EB19-3914-489B-B1D7-B7303E0218A3}
|
SolutionGuid = {BCC2EB19-3914-489B-B1D7-B7303E0218A3}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
|
|||||||
@@ -1,231 +0,0 @@
|
|||||||
//using Autofac;
|
|
||||||
//using Autofac.Extensions.DependencyInjection;
|
|
||||||
//using IRaCIS.Core.API;
|
|
||||||
//using IRaCIS.Core.Application.Filter;
|
|
||||||
//using IRaCIS.Core.Application.MediatR.Handlers;
|
|
||||||
//using LogDashboard;
|
|
||||||
//using MassTransit;
|
|
||||||
//using MassTransit.NewIdProviders;
|
|
||||||
//using MediatR;
|
|
||||||
//using Microsoft.AspNetCore.Builder;
|
|
||||||
//using Microsoft.AspNetCore.Http.Features;
|
|
||||||
//using Microsoft.AspNetCore.HttpOverrides;
|
|
||||||
//using Microsoft.AspNetCore.SignalR;
|
|
||||||
//using Microsoft.Extensions.Configuration;
|
|
||||||
//using Microsoft.Extensions.DependencyInjection;
|
|
||||||
//using Microsoft.Extensions.Hosting;
|
|
||||||
//using Serilog;
|
|
||||||
//using System;
|
|
||||||
|
|
||||||
//var builder = WebApplication.CreateBuilder(args);
|
|
||||||
|
|
||||||
|
|
||||||
// //以配置文件为准,否则 从url中取环境值(服务以命令行传递参数启动,配置文件配置了就不需要传递环境参数)
|
|
||||||
// var config = new ConfigurationBuilder()
|
|
||||||
// .AddEnvironmentVariables()
|
|
||||||
// .Build();
|
|
||||||
|
|
||||||
// var enviromentName = config["ASPNETCORE_ENVIRONMENT"];
|
|
||||||
|
|
||||||
// if (string.IsNullOrWhiteSpace(enviromentName))
|
|
||||||
// {
|
|
||||||
|
|
||||||
// var index = Array.IndexOf(args, "--env");
|
|
||||||
// enviromentName = index > -1
|
|
||||||
// ? args[index + 1]
|
|
||||||
// : "Development";
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
// NewId.SetProcessIdProvider(new CurrentProcessIdProvider());
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory())
|
|
||||||
// .ConfigureContainer<ContainerBuilder>(containerBuilder =>
|
|
||||||
// {
|
|
||||||
// containerBuilder.RegisterModule<AutofacModuleSetup>();
|
|
||||||
// })
|
|
||||||
// .UseWindowsService().UseSerilog();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//// Add services to the container.
|
|
||||||
|
|
||||||
////本地化
|
|
||||||
//builder.Services.AddJsonLocalization(options => options.ResourcesPath = "Resources");
|
|
||||||
|
|
||||||
//// 异常、参数统一验证过滤器、Json序列化配置、字符串参数绑型统一Trim()
|
|
||||||
//builder.Services.AddControllers(options =>
|
|
||||||
//{
|
|
||||||
// //options.Filters.Add<LogActionFilter>();
|
|
||||||
// options.Filters.Add<ModelActionFilter>();
|
|
||||||
// options.Filters.Add<ProjectExceptionFilter>();
|
|
||||||
// //options.Filters.Add<UnitOfWorkFilter>();
|
|
||||||
|
|
||||||
// //if (_configuration.GetSection("BasicSystemConfig").GetValue<bool>("OpenLoginLimit"))
|
|
||||||
// //{
|
|
||||||
// // options.Filters.Add<LimitUserRequestAuthorization>();
|
|
||||||
|
|
||||||
// //}
|
|
||||||
|
|
||||||
|
|
||||||
//}).AddNewtonsoftJsonSetup(); // NewtonsoftJson 序列化 处理
|
|
||||||
|
|
||||||
////动态WebApi + UnifiedApiResultFilter 省掉控制器代码
|
|
||||||
//builder.Services.AddDynamicWebApiSetup();
|
|
||||||
////AutoMapper
|
|
||||||
//builder.Services.AddAutoMapperSetup();
|
|
||||||
////EF ORM QueryWithNoLock
|
|
||||||
//builder.Services.AddEFSetup(builder.Configuration);
|
|
||||||
////Http 响应压缩
|
|
||||||
//builder.Services.AddResponseCompressionSetup();
|
|
||||||
////Swagger Api 文档
|
|
||||||
//builder.Services.AddSwaggerSetup();
|
|
||||||
////JWT Token 验证
|
|
||||||
//builder.Services.AddJWTAuthSetup(builder.Configuration);
|
|
||||||
//// MediatR 进程内消息 事件解耦 从程序集中 注册命令和handler对应关系
|
|
||||||
//builder.Services.AddMediatR(typeof(ConsistencyVerificationHandler).Assembly);
|
|
||||||
//// EasyCaching 缓存
|
|
||||||
//builder.Services.AddEasyCachingSetup();
|
|
||||||
|
|
||||||
////services.AddDistributedMemoryCache();
|
|
||||||
|
|
||||||
////// hangfire 定时任务框架 有界面,更友好~
|
|
||||||
//builder.Services.AddhangfireSetup(builder.Configuration);
|
|
||||||
////// QuartZ 定时任务框架 使用了hangfire 暂时不用,后续需要可以打开,已经配好
|
|
||||||
////builder.Services.AddQuartZSetup(_configuration);
|
|
||||||
|
|
||||||
//// 保护上传文件
|
|
||||||
////services.AddStaticFileAuthorizationSetup();
|
|
||||||
|
|
||||||
|
|
||||||
//////HttpReports 暂时废弃
|
|
||||||
////services.AddHttpReports().AddHttpTransport();
|
|
||||||
////Serilog 日志可视化 LogDashboard日志
|
|
||||||
//builder.Services.AddLogDashboardSetup();
|
|
||||||
////上传限制 配置
|
|
||||||
//builder.Services.Configure<FormOptions>(options =>
|
|
||||||
//{
|
|
||||||
// options.MultipartBodyLengthLimit = int.MaxValue;
|
|
||||||
// options.ValueCountLimit = int.MaxValue;
|
|
||||||
// options.ValueLengthLimit = int.MaxValue;
|
|
||||||
//});
|
|
||||||
////IP 限流 可设置白名单 或者黑名单
|
|
||||||
////services.AddIpPolicyRateLimitSetup(_configuration);
|
|
||||||
////用户类型 策略授权
|
|
||||||
//builder.Services.AddAuthorizationPolicySetup(builder.Configuration);
|
|
||||||
|
|
||||||
//builder.Services.AddJsonConfigSetup(builder.Configuration);
|
|
||||||
|
|
||||||
////转发头设置 获取真实IP
|
|
||||||
//builder.Services.Configure<ForwardedHeadersOptions>(options =>
|
|
||||||
//{
|
|
||||||
// options.ForwardedHeaders =
|
|
||||||
// ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
|
|
||||||
//});
|
|
||||||
////Dicom影像渲染图片 跨平台
|
|
||||||
//builder.Services.AddDicomSetup();
|
|
||||||
|
|
||||||
//// 实时应用
|
|
||||||
//builder.Services.AddSignalR();
|
|
||||||
|
|
||||||
|
|
||||||
//builder.Services.AddSingleton<IUserIdProvider, IRaCISUserIdProvider>();
|
|
||||||
|
|
||||||
//builder.Services.AddControllers();
|
|
||||||
//// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
|
|
||||||
////builder.Services.AddEndpointsApiExplorer();
|
|
||||||
////builder.Services.AddSwaggerGen();
|
|
||||||
|
|
||||||
////SerilogExtension.AddSerilogSetup(enviromentName, builder.Host.confi);
|
|
||||||
|
|
||||||
|
|
||||||
//var app = builder.Build();
|
|
||||||
|
|
||||||
//// Configure the HTTP request pipeline.
|
|
||||||
|
|
||||||
////本地化
|
|
||||||
//app.UseLocalization();
|
|
||||||
|
|
||||||
//app.UseForwardedHeaders();
|
|
||||||
|
|
||||||
|
|
||||||
////不需要 token 访问的静态文件 wwwroot css, JavaScript, and images don't require authentication.
|
|
||||||
//app.UseStaticFiles();
|
|
||||||
|
|
||||||
//app.UseIRacisHostStaticFileStore(app.Environment);
|
|
||||||
|
|
||||||
////LogDashboard
|
|
||||||
//app.UseLogDashboard("/LogDashboard");
|
|
||||||
|
|
||||||
////hangfire
|
|
||||||
////app.UseHangfireConfig(app.Environment);
|
|
||||||
|
|
||||||
//////暂时废弃
|
|
||||||
////app.UseHttpReports();
|
|
||||||
|
|
||||||
//////限流 中间件
|
|
||||||
////app.UseIpRateLimiting();
|
|
||||||
|
|
||||||
////响应压缩
|
|
||||||
//app.UseResponseCompression();
|
|
||||||
|
|
||||||
//if (app.Environment.IsDevelopment())
|
|
||||||
//{
|
|
||||||
// app.UseDeveloperExceptionPage();
|
|
||||||
//}
|
|
||||||
//else
|
|
||||||
//{
|
|
||||||
|
|
||||||
// //app.UseHsts();
|
|
||||||
//}
|
|
||||||
|
|
||||||
//SwaggerSetup.Configure(app, app.Environment);
|
|
||||||
|
|
||||||
//Console.WriteLine("当前环境: " + builder.Environment.EnvironmentName);
|
|
||||||
|
|
||||||
////app.UseMiddleware<AuthMiddleware>();
|
|
||||||
|
|
||||||
//// 特殊异常处理 比如 404
|
|
||||||
//app.UseStatusCodePagesWithReExecute("/Error/{0}");
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//////serilog 记录请求的用户信息
|
|
||||||
//app.UseSerilogConfig(app.Environment);
|
|
||||||
|
|
||||||
//app.UseRouting();
|
|
||||||
|
|
||||||
//app.UseCors(t => t.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
|
|
||||||
|
|
||||||
|
|
||||||
//app.UseAuthentication();
|
|
||||||
////app.UseJwtBearerQueryString();
|
|
||||||
//app.UseAuthorization();
|
|
||||||
|
|
||||||
//////文件伺服 必须带Token 访问
|
|
||||||
//////app.UseIRacisHostStaticFileStore(env);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////app.UseEndpoints(endpoints =>
|
|
||||||
////{
|
|
||||||
|
|
||||||
|
|
||||||
//// endpoints.MapControllers();
|
|
||||||
|
|
||||||
//// endpoints.MapHub<UploadHub>("/UploadHub")/*.RequireCors(t=>t.WithOrigins(new string[] {"null"}).AllowAnyMethod().AllowAnyHeader().AllowCredentials())*/;
|
|
||||||
////});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//app.MapControllers();
|
|
||||||
//app.MapHub<UploadHub>("/UploadHub")/*.RequireCors(t=>t.WithOrigins(new string[] {"null"}).AllowAnyMethod().AllowAnyHeader().AllowCredentials())*/;
|
|
||||||
|
|
||||||
|
|
||||||
//app.Run();
|
|
||||||
|
|
||||||
//测试同步
|
|
||||||
@@ -1,106 +0,0 @@
|
|||||||
{
|
|
||||||
"needAnonymizeTag": [
|
|
||||||
{ //PatientsName
|
|
||||||
"Group": "0010",
|
|
||||||
"Element": "0010",
|
|
||||||
"ReplaceValue": "",
|
|
||||||
"Enable": true
|
|
||||||
},
|
|
||||||
{ // PatientID
|
|
||||||
"Group": "0010",
|
|
||||||
"Element": "0020",
|
|
||||||
"ReplaceValue": "",
|
|
||||||
"Enable": true
|
|
||||||
},
|
|
||||||
{ // IssuerOfPatientID
|
|
||||||
"Group": "0010",
|
|
||||||
"Element": "0021",
|
|
||||||
"ReplaceValue": "",
|
|
||||||
"Enable": true
|
|
||||||
},
|
|
||||||
{ // PatientsBirthDate
|
|
||||||
"Group": "0010",
|
|
||||||
"Element": "0030",
|
|
||||||
"ReplaceValue": "",
|
|
||||||
"Enable": true
|
|
||||||
},
|
|
||||||
{ // PatientsBirthTime
|
|
||||||
"Group": "0010",
|
|
||||||
"Element": "0032",
|
|
||||||
"ReplaceValue": "",
|
|
||||||
"Enable": false
|
|
||||||
},
|
|
||||||
{ // PatientsSex
|
|
||||||
"Group": "0010",
|
|
||||||
"Element": "0040",
|
|
||||||
"ReplaceValue": "",
|
|
||||||
"Enable": false
|
|
||||||
},
|
|
||||||
{ // OtherPatientIDs
|
|
||||||
"Group": "0010",
|
|
||||||
"Element": "1000",
|
|
||||||
"ReplaceValue": "",
|
|
||||||
"Enable": false
|
|
||||||
},
|
|
||||||
{ // OtherPatientNames
|
|
||||||
"Group": "0010",
|
|
||||||
"Element": "1001",
|
|
||||||
"ReplaceValue": "",
|
|
||||||
"Enable": false
|
|
||||||
},
|
|
||||||
{ // OtherPatientNames
|
|
||||||
"Group": "0010",
|
|
||||||
"Element": "1005",
|
|
||||||
"ReplaceValue": "",
|
|
||||||
"Enable": true
|
|
||||||
},
|
|
||||||
{ // PatientBirthName
|
|
||||||
"Group": "0010",
|
|
||||||
"Element": "1005",
|
|
||||||
"ReplaceValue": "",
|
|
||||||
"Enable": true
|
|
||||||
},
|
|
||||||
{ // PatientsAge
|
|
||||||
"Group": "0010",
|
|
||||||
"Element": "1010",
|
|
||||||
"ReplaceValue": "",
|
|
||||||
"Enable": true
|
|
||||||
},
|
|
||||||
{ // PatientsAddress
|
|
||||||
"Group": "0010",
|
|
||||||
"Element": "1040",
|
|
||||||
"ReplaceValue": "",
|
|
||||||
"Enable": true
|
|
||||||
},
|
|
||||||
{ // PatientsMothersBirthName
|
|
||||||
"Group": "0010",
|
|
||||||
"Element": "1060",
|
|
||||||
"ReplaceValue": "",
|
|
||||||
"Enable": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Group": "0010",
|
|
||||||
"Element": "2150",
|
|
||||||
"ReplaceValue": "",
|
|
||||||
"Enable": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Group": "0010",
|
|
||||||
"Element": "2152",
|
|
||||||
"ReplaceValue": "",
|
|
||||||
"Enable": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Group": "0010",
|
|
||||||
"Element": "2154",
|
|
||||||
"ReplaceValue": "",
|
|
||||||
"Enable": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Group": "0012",
|
|
||||||
"Element": "0040",
|
|
||||||
"ReplaceValue": "XXX",
|
|
||||||
"Enable": true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,9 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using EasyCaching.Core;
|
using EasyCaching.Core;
|
||||||
using gRPC.ZHiZHUN.AuthServer.protos;
|
|
||||||
using Grpc.Net.Client;
|
|
||||||
using Grpc.Net.Client.Configuration;
|
|
||||||
using IRaCIS.Application.Interfaces;
|
using IRaCIS.Application.Interfaces;
|
||||||
using IRaCIS.Application.Contracts;
|
using IRaCIS.Application.Contracts;
|
||||||
using IRaCIS.Core.Application.Auth;
|
using IRaCIS.Core.Application.Auth;
|
||||||
@@ -24,6 +21,17 @@ using IRaCIS.Core.Domain.Models;
|
|||||||
using IRaCIS.Core.Infrastructure;
|
using IRaCIS.Core.Infrastructure;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using MassTransit;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Aliyun.Acs.Core.Profile;
|
||||||
|
using Aliyun.Acs.Core.Auth.Sts;
|
||||||
|
using Aliyun.Acs.Core;
|
||||||
|
using IRaCIS.Core.Application.Helper;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using IRaCIS.Core.Application.Contracts;
|
||||||
|
using LoginReturnDTO = IRaCIS.Application.Contracts.LoginReturnDTO;
|
||||||
|
using DocumentFormat.OpenXml.Spreadsheet;
|
||||||
|
using AutoMapper.QueryableExtensions;
|
||||||
|
|
||||||
namespace IRaCIS.Api.Controllers
|
namespace IRaCIS.Api.Controllers
|
||||||
{
|
{
|
||||||
@@ -50,6 +58,7 @@ namespace IRaCIS.Api.Controllers
|
|||||||
|
|
||||||
public async Task<IResponseOutput<DoctorDetailDTO>> GetDoctorDetail([FromServices] IAttachmentService attachmentService, [FromServices] IDoctorService _doctorService,
|
public async Task<IResponseOutput<DoctorDetailDTO>> GetDoctorDetail([FromServices] IAttachmentService attachmentService, [FromServices] IDoctorService _doctorService,
|
||||||
[FromServices] IEducationService _educationService, [FromServices] ITrialExperienceService _trialExperienceService,
|
[FromServices] IEducationService _educationService, [FromServices] ITrialExperienceService _trialExperienceService,
|
||||||
|
|
||||||
[FromServices] IResearchPublicationService _researchPublicationService, [FromServices] IVacationService _vacationService, Guid doctorId)
|
[FromServices] IResearchPublicationService _researchPublicationService, [FromServices] IVacationService _vacationService, Guid doctorId)
|
||||||
{
|
{
|
||||||
var education = await _educationService.GetEducation(doctorId);
|
var education = await _educationService.GetEducation(doctorId);
|
||||||
@@ -89,10 +98,55 @@ namespace IRaCIS.Api.Controllers
|
|||||||
/// <summary> 系统用户登录接口[New] </summary>
|
/// <summary> 系统用户登录接口[New] </summary>
|
||||||
[HttpPost, Route("user/login")]
|
[HttpPost, Route("user/login")]
|
||||||
[AllowAnonymous]
|
[AllowAnonymous]
|
||||||
public async Task<IResponseOutput<LoginReturnDTO>> Login(UserLoginDTO loginUser, [FromServices] IEasyCachingProvider provider, [FromServices] IUserService _userService,
|
public async Task<IResponseOutput> Login(UserLoginDTO loginUser,
|
||||||
[FromServices] ITokenService _tokenService, [FromServices] IConfiguration configuration)
|
[FromServices] IEasyCachingProvider provider,
|
||||||
|
[FromServices] IUserService _userService,
|
||||||
|
[FromServices] ITokenService _tokenService,
|
||||||
|
[FromServices] IReadingImageTaskService readingImageTaskService,
|
||||||
|
IOptionsMonitor<ServiceVerifyConfigOption> _verifyConfig,
|
||||||
|
IMailVerificationService _mailVerificationService)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
//MFA 邮箱验证 前端传递用户Id 和MFACode
|
||||||
|
if (loginUser.UserId != null && _verifyConfig.CurrentValue.OpenLoginMFA)
|
||||||
|
{
|
||||||
|
Guid userId = (Guid)loginUser.UserId;
|
||||||
|
|
||||||
|
//验证MFA 编码是否有问题 ,前端要拆开,自己调用验证的逻辑
|
||||||
|
//await _userService.VerifyMFACodeAsync(userId, loginUser.MFACode);
|
||||||
|
|
||||||
|
//var loginUser = await _userRepository.Where(u => u.UserName.Equals(userName) && u.Password == password).ProjectTo<UserBasicInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync();
|
||||||
|
|
||||||
|
var basicInfo = await _userService.GetUserBasicInfo(userId, loginUser.Password);
|
||||||
|
|
||||||
|
var loginReturn = new LoginReturnDTO() { BasicInfo = basicInfo };
|
||||||
|
|
||||||
|
loginReturn.JWTStr = _tokenService.GetToken(IRaCISClaims.Create(loginReturn.BasicInfo));
|
||||||
|
|
||||||
|
|
||||||
|
// 创建一个 CookieOptions 对象,用于设置 Cookie 的属性
|
||||||
|
var option = new CookieOptions
|
||||||
|
{
|
||||||
|
Expires = DateTime.Now.AddMonths(1), // 设置过期时间为 30 分钟之后
|
||||||
|
HttpOnly = false, // 确保 cookie 只能通过 HTTP 访问
|
||||||
|
SameSite = Microsoft.AspNetCore.Http.SameSiteMode.None, // 设置 SameSite 属性
|
||||||
|
Secure = false // 确保 cookie 只能通过 HTTPS 访问
|
||||||
|
};
|
||||||
|
|
||||||
|
HttpContext.Response.Cookies.Append("access_token", loginReturn.JWTStr, option);
|
||||||
|
|
||||||
|
// 验证阅片休息时间
|
||||||
|
await readingImageTaskService.ResetReadingRestTime(userId);
|
||||||
|
|
||||||
|
await provider.SetAsync(userId.ToString(), loginReturn.JWTStr, TimeSpan.FromDays(7));
|
||||||
|
|
||||||
|
await provider.SetAsync($"{userId.ToString()}_Online", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromMinutes(_verifyConfig.CurrentValue.AutoLoginOutMinutes));
|
||||||
|
|
||||||
|
return ResponseOutput.Ok(loginReturn);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
var returnModel = await _userService.Login(loginUser.UserName, loginUser.Password);
|
var returnModel = await _userService.Login(loginUser.UserName, loginUser.Password);
|
||||||
|
|
||||||
if (returnModel.IsSuccess)
|
if (returnModel.IsSuccess)
|
||||||
@@ -158,17 +212,80 @@ namespace IRaCIS.Api.Controllers
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
var userId = returnModel.Data.BasicInfo.Id;
|
||||||
|
|
||||||
|
if (_verifyConfig.CurrentValue.OpenLoginMFA)
|
||||||
|
{
|
||||||
|
//发版屏蔽
|
||||||
|
|
||||||
|
//returnModel.Data.JWTStr = _tokenService.GetToken(IRaCISClaims.Create(returnModel.Data.BasicInfo));
|
||||||
|
|
||||||
|
//MFA 发送邮件
|
||||||
|
|
||||||
|
returnModel.Data.IsMFA = true;
|
||||||
|
|
||||||
|
var email = returnModel.Data.BasicInfo.EMail;
|
||||||
|
|
||||||
|
#region 隐藏Email
|
||||||
|
// 找到 "@" 符号的位置
|
||||||
|
int atIndex = email.IndexOf('@');
|
||||||
|
|
||||||
|
// 替换 "@" 符号前的中间两位为星号
|
||||||
|
string visiblePart = email.Substring(0, atIndex);
|
||||||
|
|
||||||
|
int startIndex = (visiblePart.Length - 2) / 2;
|
||||||
|
|
||||||
|
// 替换中间两位字符为星号
|
||||||
|
string hiddenPartBeforeAt = visiblePart.Substring(0, startIndex) + "**" + visiblePart.Substring(startIndex + 2);
|
||||||
|
|
||||||
|
string afterAt = email.Substring(atIndex + 1);
|
||||||
|
|
||||||
|
// 组合隐藏和可见部分
|
||||||
|
string hiddenEmail = hiddenPartBeforeAt + "@" + afterAt;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
returnModel.Data.BasicInfo.EMail = hiddenEmail;
|
||||||
|
|
||||||
|
await _userService.SendMFAEmail(userId);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
returnModel.Data.JWTStr = _tokenService.GetToken(IRaCISClaims.Create(returnModel.Data.BasicInfo));
|
returnModel.Data.JWTStr = _tokenService.GetToken(IRaCISClaims.Create(returnModel.Data.BasicInfo));
|
||||||
|
|
||||||
}
|
// 创建一个 CookieOptions 对象,用于设置 Cookie 的属性
|
||||||
|
var option = new CookieOptions
|
||||||
|
{
|
||||||
|
Expires = DateTime.Now.AddMonths(1), // 设置过期时间为 30 分钟之后
|
||||||
|
HttpOnly = false, // 确保 cookie 只能通过 HTTP 访问
|
||||||
|
SameSite = Microsoft.AspNetCore.Http.SameSiteMode.None, // 设置 SameSite 属性
|
||||||
|
Secure = false // 确保 cookie 只能通过 HTTPS 访问
|
||||||
|
};
|
||||||
|
|
||||||
var userId = returnModel.Data.BasicInfo.Id.ToString();
|
HttpContext.Response.Cookies.Append("access_token", returnModel.Data.JWTStr, option);
|
||||||
//provider.Set(userId, userId, TimeSpan.FromMinutes(AppSettings.LoginExpiredTimeSpan));
|
|
||||||
|
|
||||||
|
|
||||||
|
// 验证阅片休息时间
|
||||||
|
await readingImageTaskService.ResetReadingRestTime(returnModel.Data.BasicInfo.Id);
|
||||||
|
|
||||||
await provider.SetAsync(userId.ToString(), returnModel.Data.JWTStr, TimeSpan.FromDays(7));
|
await provider.SetAsync(userId.ToString(), returnModel.Data.JWTStr, TimeSpan.FromDays(7));
|
||||||
return returnModel;
|
|
||||||
|
await provider.SetAsync($"{userId.ToString()}_Online", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromMinutes(_verifyConfig.CurrentValue.AutoLoginOutMinutes));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return returnModel;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[HttpGet, Route("imageShare/ShareImage")]
|
[HttpGet, Route("imageShare/ShareImage")]
|
||||||
@@ -190,7 +307,106 @@ namespace IRaCIS.Api.Controllers
|
|||||||
return ResponseOutput.Ok("/showdicom?studyId=f7b67793-8155-0223-2f15-118f2642efb8&type=Share&token=" + token);
|
return ResponseOutput.Ok("/showdicom?studyId=f7b67793-8155-0223-2f15-118f2642efb8&type=Share&token=" + token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpGet("user/GetObjectStoreToken")]
|
||||||
|
public IResponseOutput GetObjectStoreToken([FromServices] IOptionsMonitor<ObjectStoreServiceOptions> options)
|
||||||
|
{
|
||||||
|
var serviceOption = options.CurrentValue;
|
||||||
|
|
||||||
|
if (Enum.TryParse<ObjectStoreUse>(serviceOption.ObjectStoreUse, out var parsedEnum) && parsedEnum == ObjectStoreUse.AliyunOSS)
|
||||||
|
{
|
||||||
|
|
||||||
|
var ossOptions = serviceOption.AliyunOSS;
|
||||||
|
|
||||||
|
return ResponseOutput.Ok(new ObjectStoreDTO() { ObjectStoreUse = serviceOption.ObjectStoreUse, MinIO = serviceOption.MinIO, AliyunOSS = serviceOption.AliyunOSS, AWS = serviceOption.AWS });
|
||||||
|
|
||||||
|
#region 临时token 屏蔽
|
||||||
|
//IClientProfile profile = DefaultProfile.GetProfile(ossOptions.RegionId, ossOptions.AccessKeyId, ossOptions.AccessKeySecret);
|
||||||
|
//DefaultAcsClient client = new DefaultAcsClient(profile);
|
||||||
|
|
||||||
|
|
||||||
|
//// 创建一个STS请求
|
||||||
|
//AssumeRoleRequest request = new AssumeRoleRequest
|
||||||
|
//{
|
||||||
|
// RoleArn = ossOptions.RoleArn, // 角色ARN,需要替换为你的角色ARN
|
||||||
|
// RoleSessionName = $"session-name-{NewId.NextGuid()}", // 角色会话名称,可自定义
|
||||||
|
// DurationSeconds = 900, // 令牌有效期(单位:秒),这里设置为1小时
|
||||||
|
//};
|
||||||
|
|
||||||
|
|
||||||
|
//AssumeRoleResponse response = client.GetAcsResponse(request);
|
||||||
|
|
||||||
|
//// 返回STS令牌信息给前端
|
||||||
|
//var stsToken = new ObjectStoreDTO()
|
||||||
|
//{
|
||||||
|
// ObjectStoreUse = serviceOption.ObjectStoreUse,
|
||||||
|
// AliyunOSS = new AliyunOSSTempToken()
|
||||||
|
// {
|
||||||
|
// AccessKeyId = response.Credentials.AccessKeyId,
|
||||||
|
// AccessKeySecret = response.Credentials.AccessKeySecret,
|
||||||
|
// SecurityToken = response.Credentials.SecurityToken,
|
||||||
|
// Expiration = response.Credentials.Expiration,
|
||||||
|
|
||||||
|
// Region = ossOptions.Region,
|
||||||
|
// BucketName = ossOptions.BucketName,
|
||||||
|
// ViewEndpoint = ossOptions.ViewEndpoint,
|
||||||
|
|
||||||
|
// },
|
||||||
|
// MinIO = serviceOption.MinIO
|
||||||
|
//};
|
||||||
|
//return ResponseOutput.Ok(stsToken);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (Enum.TryParse<ObjectStoreUse>(serviceOption.ObjectStoreUse, out var parsedValue) && parsedValue == ObjectStoreUse.MinIO)
|
||||||
|
{
|
||||||
|
return ResponseOutput.Ok(new ObjectStoreDTO() { ObjectStoreUse = serviceOption.ObjectStoreUse, MinIO = serviceOption.MinIO, AWS = serviceOption.AWS });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return ResponseOutput.Ok(new ObjectStoreDTO() { ObjectStoreUse = serviceOption.ObjectStoreUse, MinIO = serviceOption.MinIO, AWS = serviceOption.AWS });
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("user/GenerateSTS")]
|
||||||
|
public IResponseOutput GenerateSTS([FromServices] IOptionsMonitor<AliyunOSSOptions> options)
|
||||||
|
{
|
||||||
|
var ossOptions = options.CurrentValue;
|
||||||
|
|
||||||
|
|
||||||
|
IClientProfile profile = DefaultProfile.GetProfile(ossOptions.regionId, ossOptions.accessKeyId, ossOptions.accessKeySecret);
|
||||||
|
DefaultAcsClient client = new DefaultAcsClient(profile);
|
||||||
|
|
||||||
|
|
||||||
|
// 创建一个STS请求
|
||||||
|
AssumeRoleRequest request = new AssumeRoleRequest
|
||||||
|
{
|
||||||
|
RoleArn = ossOptions.roleArn, // 角色ARN,需要替换为你的角色ARN
|
||||||
|
RoleSessionName = $"session-name-{NewId.NextGuid()}", // 角色会话名称,可自定义
|
||||||
|
DurationSeconds = 900, // 令牌有效期(单位:秒),这里设置为1小时
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
AssumeRoleResponse response = client.GetAcsResponse(request);
|
||||||
|
|
||||||
|
// 返回STS令牌信息给前端
|
||||||
|
var stsToken = new
|
||||||
|
{
|
||||||
|
AccessKeyId = response.Credentials.AccessKeyId,
|
||||||
|
AccessKeySecret = response.Credentials.AccessKeySecret,
|
||||||
|
SecurityToken = response.Credentials.SecurityToken,
|
||||||
|
Expiration = response.Credentials.Expiration,
|
||||||
|
|
||||||
|
Region = ossOptions.region,
|
||||||
|
BucketName = ossOptions.bucketName,
|
||||||
|
ViewEndpoint = ossOptions.viewEndpoint,
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
return ResponseOutput.Ok(stsToken);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -205,6 +421,8 @@ namespace IRaCIS.Api.Controllers
|
|||||||
|
|
||||||
var token = decodeUrl.Substring(decodeUrl.IndexOf("access_token=") + "access_token=".Length);
|
var token = decodeUrl.Substring(decodeUrl.IndexOf("access_token=") + "access_token=".Length);
|
||||||
|
|
||||||
|
var lang = decodeUrl.Substring(decodeUrl.IndexOf("lang=") + "lang=".Length, 2);
|
||||||
|
|
||||||
var domainStrList = decodeUrl.Split("/").ToList().Take(3).ToList();
|
var domainStrList = decodeUrl.Split("/").ToList().Take(3).ToList();
|
||||||
|
|
||||||
var errorUrl = domainStrList[0] + "//" + domainStrList[2] + "/error";
|
var errorUrl = domainStrList[0] + "//" + domainStrList[2] + "/error";
|
||||||
@@ -212,7 +430,7 @@ namespace IRaCIS.Api.Controllers
|
|||||||
|
|
||||||
if (!await _userRepository.AnyAsync(t => t.Id == Guid.Parse(userId) && t.EmailToken == token && t.IsFirstAdd))
|
if (!await _userRepository.AnyAsync(t => t.Id == Guid.Parse(userId) && t.EmailToken == token && t.IsFirstAdd))
|
||||||
{
|
{
|
||||||
decodeUrl = errorUrl+ $"?ErrorMessage={System.Web.HttpUtility.UrlEncode("您的初始化链接已过期")} ";
|
decodeUrl = errorUrl + $"?lang={lang}&ErrorMessage={System.Web.HttpUtility.UrlEncode(lang == "zh" ? "您的初始化链接已过期" : "Error!The initialization link has expired. Return")} ";
|
||||||
}
|
}
|
||||||
|
|
||||||
return Redirect(decodeUrl);
|
return Redirect(decodeUrl);
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ namespace IRaCIS.Core.API.Controllers.Special
|
|||||||
/// <param name="param"></param>
|
/// <param name="param"></param>
|
||||||
/// <returns>新记录Id</returns>
|
/// <returns>新记录Id</returns>
|
||||||
[HttpPost, Route("trial/addOrUpdateTrial")]
|
[HttpPost, Route("trial/addOrUpdateTrial")]
|
||||||
[Authorize(Policy = IRaCISPolicy.PM_APM)]
|
//[Authorize(Policy = IRaCISPolicy.PM_APM)]
|
||||||
|
|
||||||
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AddOrUpdateTrial", "BeforeOngoingCantOpt", "AfterStopCannNotOpt" })]
|
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AddOrUpdateTrial", "BeforeOngoingCantOpt", "AfterStopCannNotOpt" })]
|
||||||
public async Task<IResponseOutput<Trial>> AddOrUpdateTrial(TrialCommand param)
|
public async Task<IResponseOutput<Trial>> AddOrUpdateTrial(TrialCommand param)
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ using IRaCIS.Core.Application.Service;
|
|||||||
using IRaCIS.Core.Application.Service.Inspection.DTO;
|
using IRaCIS.Core.Application.Service.Inspection.DTO;
|
||||||
using IRaCIS.Core.Application.Service.Inspection.Interface;
|
using IRaCIS.Core.Application.Service.Inspection.Interface;
|
||||||
using IRaCIS.Core.Application.Service.Reading.Dto;
|
using IRaCIS.Core.Application.Service.Reading.Dto;
|
||||||
|
using IRaCIS.Core.Application.Service.Reading.Interface;
|
||||||
using IRaCIS.Core.Application.ViewModel;
|
using IRaCIS.Core.Application.ViewModel;
|
||||||
using IRaCIS.Core.Domain.Models;
|
using IRaCIS.Core.Domain.Models;
|
||||||
using IRaCIS.Core.Domain.Share;
|
using IRaCIS.Core.Domain.Share;
|
||||||
@@ -36,6 +37,7 @@ namespace IRaCIS.Core.API.Controllers
|
|||||||
private readonly IHttpContextAccessor _httpContext;
|
private readonly IHttpContextAccessor _httpContext;
|
||||||
private readonly ITrialConfigService _trialConfigService;
|
private readonly ITrialConfigService _trialConfigService;
|
||||||
private readonly INoneDicomStudyService _noneDicomStudyService;
|
private readonly INoneDicomStudyService _noneDicomStudyService;
|
||||||
|
private readonly IClinicalAnswerService _clinicalAnswerService;
|
||||||
private readonly ISubjectService _subjectService;
|
private readonly ISubjectService _subjectService;
|
||||||
private readonly IReadingClinicalDataService _readingClinicalDataService;
|
private readonly IReadingClinicalDataService _readingClinicalDataService;
|
||||||
private readonly ISubjectVisitService _subjectVisitService;
|
private readonly ISubjectVisitService _subjectVisitService;
|
||||||
@@ -62,6 +64,7 @@ namespace IRaCIS.Core.API.Controllers
|
|||||||
IReadingMedicineQuestionService readingMedicineQuestionService,
|
IReadingMedicineQuestionService readingMedicineQuestionService,
|
||||||
ITrialConfigService _trialConfigService,
|
ITrialConfigService _trialConfigService,
|
||||||
INoneDicomStudyService noneDicomStudyService,
|
INoneDicomStudyService noneDicomStudyService,
|
||||||
|
IClinicalAnswerService clinicalAnswerService,
|
||||||
ISubjectService _subjectService,
|
ISubjectService _subjectService,
|
||||||
IReadingClinicalDataService _readingClinicalDataService,
|
IReadingClinicalDataService _readingClinicalDataService,
|
||||||
ISubjectVisitService subjectVisitService,
|
ISubjectVisitService subjectVisitService,
|
||||||
@@ -82,6 +85,7 @@ namespace IRaCIS.Core.API.Controllers
|
|||||||
this._httpContext = httpContext;
|
this._httpContext = httpContext;
|
||||||
this._trialConfigService = _trialConfigService;
|
this._trialConfigService = _trialConfigService;
|
||||||
this._noneDicomStudyService = noneDicomStudyService;
|
this._noneDicomStudyService = noneDicomStudyService;
|
||||||
|
this._clinicalAnswerService = clinicalAnswerService;
|
||||||
this._subjectService = _subjectService;
|
this._subjectService = _subjectService;
|
||||||
this._readingClinicalDataService = _readingClinicalDataService;
|
this._readingClinicalDataService = _readingClinicalDataService;
|
||||||
this._subjectVisitService = subjectVisitService;
|
this._subjectVisitService = subjectVisitService;
|
||||||
@@ -233,6 +237,94 @@ namespace IRaCIS.Core.API.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// CRC签名临床数据
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="opt"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost, Route("Inspection/ClinicalAnswer/CRCSignClinicalData")]
|
||||||
|
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||||||
|
|
||||||
|
[UnitOfWork]
|
||||||
|
public async Task<IResponseOutput> CRCSignClinicalData(DataInspectionDto<CRCSignClinicalDataInDto> opt)
|
||||||
|
{
|
||||||
|
var singid = await _inspectionService.RecordSing(opt.SignInfo);
|
||||||
|
var result = await _clinicalAnswerService.CRCSignClinicalData(opt.Data);
|
||||||
|
await _inspectionService.CompletedSign(singid, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// CRC确认临床数据
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="opt"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost, Route("Inspection/ClinicalAnswer/CRCConfirmClinical")]
|
||||||
|
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||||||
|
|
||||||
|
[UnitOfWork]
|
||||||
|
public async Task<IResponseOutput> CRCConfirmClinical(DataInspectionDto<CRCConfirmClinicalInDto> opt)
|
||||||
|
{
|
||||||
|
var singid = await _inspectionService.RecordSing(opt.SignInfo);
|
||||||
|
var result = await _clinicalAnswerService.CRCConfirmClinical(opt.Data);
|
||||||
|
await _inspectionService.CompletedSign(singid, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// CRC撤销临床数据
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="opt"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost, Route("Inspection/ClinicalAnswer/CRCCancelConfirmClinical")]
|
||||||
|
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||||||
|
|
||||||
|
[UnitOfWork]
|
||||||
|
public async Task<IResponseOutput> CRCCancelConfirmClinical(DataInspectionDto<CRCCancelConfirmClinicalInDto> opt)
|
||||||
|
{
|
||||||
|
var singid = await _inspectionService.RecordSing(opt.SignInfo);
|
||||||
|
var result = await _clinicalAnswerService.CRCCancelConfirmClinical(opt.Data);
|
||||||
|
await _inspectionService.CompletedSign(singid, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// PM确认临床数据
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="opt"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost, Route("Inspection/ClinicalAnswer/PMConfirmClinical")]
|
||||||
|
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||||||
|
|
||||||
|
[UnitOfWork]
|
||||||
|
public async Task<IResponseOutput> PMConfirmClinical(DataInspectionDto<CRCConfirmClinicalInDto> opt)
|
||||||
|
{
|
||||||
|
var singid = await _inspectionService.RecordSing(opt.SignInfo);
|
||||||
|
var result = await _clinicalAnswerService.PMConfirmClinical(opt.Data);
|
||||||
|
await _inspectionService.CompletedSign(singid, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 提交结构化录入并签名
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="opt"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost, Route("Inspection/ClinicalAnswer/SubmitClinicalFormAndSign")]
|
||||||
|
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||||||
|
|
||||||
|
[UnitOfWork]
|
||||||
|
public async Task<IResponseOutput> SubmitClinicalFormAndSign(DataInspectionDto<SubmitClinicalFormInDto> opt)
|
||||||
|
{
|
||||||
|
var singid = await _inspectionService.RecordSing(opt.SignInfo);
|
||||||
|
var result = await _clinicalAnswerService.SubmitClinicalForm(opt.Data);
|
||||||
|
await _inspectionService.CompletedSign(singid, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 提交阅片裁判问题
|
/// 提交阅片裁判问题
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -327,6 +419,23 @@ namespace IRaCIS.Core.API.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 重置并同步项目阅片标准
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost, Route("Inspection/ReadingCriterion/ResetAndAsyncCriterion")]
|
||||||
|
[UnitOfWork]
|
||||||
|
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||||||
|
|
||||||
|
public async Task<IResponseOutput> ResetAndAsyncCriterion(DataInspectionDto<ResetAndAsyncCriterionInDto> opt)
|
||||||
|
{
|
||||||
|
var singid = await _inspectionService.RecordSing(opt.SignInfo);
|
||||||
|
var result = await _trialConfigService.ResetAndAsyncCriterion(opt.Data);
|
||||||
|
await _inspectionService.CompletedSign(singid, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// CRC RequestToQC 批量提交
|
/// CRC RequestToQC 批量提交
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,16 +1,16 @@
|
|||||||
// 使用的是proto3版本
|
// 使用的是proto3版本
|
||||||
syntax = "proto3";
|
syntax = "proto3";
|
||||||
// 定义命名空间,后续生成代码时就会生成对应的命名空间
|
// 定义命名空间,后续生成代码时就会生成对应的命名空间
|
||||||
option csharp_namespace = "gRPC.ZHiZHUN.AuthServer.protos";
|
option csharp_namespace = "gRPC.ZHiZHUN.AuthServer.protos";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
每一句需要用分号结尾
|
每一句需要用分号结尾
|
||||||
message 用来定义请求和返回数据格式
|
message 用来定义请求和返回数据格式
|
||||||
tag message后面的值数字代表是字段的标识(tag),不是赋值,
|
tag message后面的值数字代表是字段的标识(tag),不是赋值,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
// 新增用户时需要传递数据消息, 可理解为一个类
|
// 新增用户时需要传递数据消息, 可理解为一个类
|
||||||
message GetTokenReuqest{
|
message GetTokenReuqest{
|
||||||
string id=1;
|
string id=1;
|
||||||
string userName=2;
|
string userName=2;
|
||||||
@@ -22,48 +22,48 @@ message GetTokenReuqest{
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 新增时返回的消息格式
|
// 新增时返回的消息格式
|
||||||
message GetTokenResponse {
|
message GetTokenResponse {
|
||||||
int32 code=1;
|
int32 code=1;
|
||||||
string token =2;
|
string token =2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// service 用标识定义服务的,里面写对应的方法
|
// service 用标识定义服务的,里面写对应的方法
|
||||||
service TokenGrpcService{
|
service TokenGrpcService{
|
||||||
// 获取token
|
// 获取token
|
||||||
rpc GetUserToken(GetTokenReuqest) returns (GetTokenResponse);
|
rpc GetUserToken(GetTokenReuqest) returns (GetTokenResponse);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// 新增用户时需要传递数据消息, 可理解为一个类
|
// 新增用户时需要传递数据消息, 可理解为一个类
|
||||||
message AddUserReuqest{
|
message AddUserReuqest{
|
||||||
string name=1;
|
string name=1;
|
||||||
int32 age=2;
|
int32 age=2;
|
||||||
bool isBoy=3;
|
bool isBoy=3;
|
||||||
}
|
}
|
||||||
// 新增时返回的消息格式
|
// 新增时返回的消息格式
|
||||||
message ResultResponse {
|
message ResultResponse {
|
||||||
int32 code=1;
|
int32 code=1;
|
||||||
string msg =2;
|
string msg =2;
|
||||||
}
|
}
|
||||||
//传递的查询条件信息格式,可理解为平时传入的查询条件对象
|
//传递的查询条件信息格式,可理解为平时传入的查询条件对象
|
||||||
message QueryUserReuqest{
|
message QueryUserReuqest{
|
||||||
string name=1;
|
string name=1;
|
||||||
}
|
}
|
||||||
//查询返回的用户信息格式,可理解为返回的类
|
//查询返回的用户信息格式,可理解为返回的类
|
||||||
message UserInfoResponse {
|
message UserInfoResponse {
|
||||||
string name=1;
|
string name=1;
|
||||||
int32 age=2;
|
int32 age=2;
|
||||||
string gender=3;
|
string gender=3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// service 用标识定义服务的,里面写对应的方法
|
// service 用标识定义服务的,里面写对应的方法
|
||||||
service UserService{
|
service UserService{
|
||||||
// 新增用户
|
// 新增用户
|
||||||
rpc AddUser(AddUserReuqest) returns (ResultResponse);
|
rpc AddUser(AddUserReuqest) returns (ResultResponse);
|
||||||
// 查询用户
|
// 查询用户
|
||||||
rpc GetAllUser(QueryUserReuqest) returns (UserInfoResponse);
|
rpc GetAllUser(QueryUserReuqest) returns (UserInfoResponse);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|||||||
Binary file not shown.
@@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<SignAssembly>false</SignAssembly>
|
<SignAssembly>false</SignAssembly>
|
||||||
<UserSecretsId>354572d4-9e15-4099-807c-63a2d29ff9f2</UserSecretsId>
|
<UserSecretsId>354572d4-9e15-4099-807c-63a2d29ff9f2</UserSecretsId>
|
||||||
<LangVersion>default</LangVersion>
|
<LangVersion>default</LangVersion>
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||||
<DocumentationFile>.\IRaCIS.Core.API.xml</DocumentationFile>
|
<DocumentationFile>.\IRaCIS.Core.API.xml</DocumentationFile>
|
||||||
<NoWarn>1701;1702;1591;</NoWarn>
|
<NoWarn>1701;1702;1591;1570;</NoWarn>
|
||||||
<OutputPath>..\bin\</OutputPath>
|
<OutputPath>..\bin\</OutputPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
@@ -24,12 +24,7 @@
|
|||||||
<NoWarn>1701;1702;1591</NoWarn>
|
<NoWarn>1701;1702;1591</NoWarn>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Compile Remove="wwwroot\**" />
|
|
||||||
<EmbeddedResource Remove="UploadFile\**" />
|
|
||||||
<EmbeddedResource Remove="wwwroot\**" />
|
|
||||||
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Remove="web.config" />
|
<Content Remove="web.config" />
|
||||||
@@ -66,31 +61,26 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="AspNetCoreRateLimit" Version="4.0.2" />
|
<PackageReference Include="aliyun-net-sdk-sts" Version="3.1.2" />
|
||||||
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="8.0.0" />
|
<PackageReference Include="AspNetCoreRateLimit" Version="5.0.0" />
|
||||||
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.0" />
|
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="9.0.0" />
|
||||||
<PackageReference Include="EasyCaching.InMemory" Version="1.7.0" />
|
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" />
|
||||||
<PackageReference Include="EasyCaching.Interceptor.Castle" Version="1.7.0" />
|
<PackageReference Include="EasyCaching.Interceptor.Castle" Version="1.9.2" />
|
||||||
<PackageReference Include="EntityFrameworkCore.Triggered.Extensions" Version="3.2.1" />
|
<PackageReference Include="EasyCaching.Serialization.MessagePack" Version="1.9.2">
|
||||||
<PackageReference Include="Google.Protobuf" Version="3.21.8" />
|
<TreatAsUsed>true</TreatAsUsed>
|
||||||
<PackageReference Include="Grpc.Net.Client" Version="2.49.0" />
|
|
||||||
<PackageReference Include="Grpc.Tools" Version="2.50.0">
|
|
||||||
<PrivateAssets>all</PrivateAssets>
|
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Hangfire.Tags.SqlServer" Version="1.8.1" />
|
<PackageReference Include="Hangfire.AspNetCore" Version="1.8.12" />
|
||||||
|
<PackageReference Include="Hangfire.Dashboard.BasicAuthorization" Version="1.0.2" />
|
||||||
|
<PackageReference Include="Hangfire.SqlServer" Version="1.8.12" />
|
||||||
<PackageReference Include="Invio.Extensions.Authentication.JwtBearer" Version="2.0.1" />
|
<PackageReference Include="Invio.Extensions.Authentication.JwtBearer" Version="2.0.1" />
|
||||||
<PackageReference Include="LogDashboard" Version="1.4.8" />
|
<PackageReference Include="LogDashboard" Version="1.4.8" />
|
||||||
<PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="11.0.0" />
|
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.5" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.10" />
|
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="8.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="6.0.1" />
|
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.20.1" />
|
||||||
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.17.0" />
|
<PackageReference Include="Serilog.AspNetCore" Version="8.0.1" />
|
||||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="6.0.10" />
|
<PackageReference Include="Serilog.Enrichers.ClientInfo" Version="2.0.3" />
|
||||||
<PackageReference Include="Serilog.AspNetCore" Version="6.0.1" />
|
|
||||||
<PackageReference Include="Serilog.Enrichers.ClientInfo" Version="1.2.0" />
|
|
||||||
<PackageReference Include="Serilog.Sinks.Email" Version="2.4.0" />
|
|
||||||
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
|
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="6.4.0" />
|
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="6.6.2" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -103,9 +93,6 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Update="NLog.config">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Update="wwwroot\EmailTemplate\AdminAddUser_US.html">
|
<Content Update="wwwroot\EmailTemplate\AdminAddUser_US.html">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
@@ -115,12 +102,6 @@
|
|||||||
<Content Update="wwwroot\EmailTemplate\AdminResetUser.html">
|
<Content Update="wwwroot\EmailTemplate\AdminResetUser.html">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
<Content Update="wwwroot\EmailTemplate\EmailConfigTest_US.html">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Update="wwwroot\EmailTemplate\EmailConfigTest.html">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Update="wwwroot\EmailTemplate\SubjectEnrollConfirmOrPDProgress_US.html">
|
<Content Update="wwwroot\EmailTemplate\SubjectEnrollConfirmOrPDProgress_US.html">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
@@ -172,7 +153,7 @@
|
|||||||
<Folder Include="Properties\PublishProfiles\" />
|
<Folder Include="Properties\PublishProfiles\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ProjectExtensions><VisualStudio><UserProperties anonymizetagsetting_1json__JsonSchema="http://json.schemastore.org/jovo-language-model" properties_4launchsettings_1json__JsonSchema="" /></VisualStudio></ProjectExtensions>
|
<ProjectExtensions><VisualStudio><UserProperties properties_4launchsettings_1json__JsonSchema="" /></VisualStudio></ProjectExtensions>
|
||||||
|
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
<param name="doctorId"></param>
|
<param name="doctorId"></param>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
<member name="M:IRaCIS.Api.Controllers.ExtraController.Login(IRaCIS.Application.Contracts.UserLoginDTO,EasyCaching.Core.IEasyCachingProvider,IRaCIS.Application.Services.IUserService,IRaCIS.Core.Application.Auth.ITokenService,Microsoft.Extensions.Configuration.IConfiguration)">
|
<member name="M:IRaCIS.Api.Controllers.ExtraController.Login(IRaCIS.Application.Contracts.UserLoginDTO,EasyCaching.Core.IEasyCachingProvider,IRaCIS.Application.Services.IUserService,IRaCIS.Core.Application.Auth.ITokenService,IRaCIS.Core.Application.Contracts.IReadingImageTaskService,Microsoft.Extensions.Options.IOptionsMonitor{IRaCIS.Core.Domain.Share.ServiceVerifyConfigOption},IRaCIS.Application.Services.IMailVerificationService)">
|
||||||
<summary> 系统用户登录接口[New] </summary>
|
<summary> 系统用户登录接口[New] </summary>
|
||||||
</member>
|
</member>
|
||||||
<member name="M:IRaCIS.Core.API.Controllers.Special.FinancialChangeController.AddOrUpdateTrialInspection(IRaCIS.Core.Application.Service.Inspection.DTO.DataInspectionDto{IRaCIS.Application.Contracts.TrialCommand})">
|
<member name="M:IRaCIS.Core.API.Controllers.Special.FinancialChangeController.AddOrUpdateTrialInspection(IRaCIS.Core.Application.Service.Inspection.DTO.DataInspectionDto{IRaCIS.Application.Contracts.TrialCommand})">
|
||||||
@@ -139,6 +139,41 @@
|
|||||||
<param name="opt"></param>
|
<param name="opt"></param>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:IRaCIS.Core.API.Controllers.InspectionController.CRCSignClinicalData(IRaCIS.Core.Application.Service.Inspection.DTO.DataInspectionDto{IRaCIS.Core.Application.Service.Reading.Dto.CRCSignClinicalDataInDto})">
|
||||||
|
<summary>
|
||||||
|
CRC签名临床数据
|
||||||
|
</summary>
|
||||||
|
<param name="opt"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:IRaCIS.Core.API.Controllers.InspectionController.CRCConfirmClinical(IRaCIS.Core.Application.Service.Inspection.DTO.DataInspectionDto{IRaCIS.Core.Application.Service.Reading.Dto.CRCConfirmClinicalInDto})">
|
||||||
|
<summary>
|
||||||
|
CRC确认临床数据
|
||||||
|
</summary>
|
||||||
|
<param name="opt"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:IRaCIS.Core.API.Controllers.InspectionController.CRCCancelConfirmClinical(IRaCIS.Core.Application.Service.Inspection.DTO.DataInspectionDto{IRaCIS.Core.Application.Service.Reading.Dto.CRCCancelConfirmClinicalInDto})">
|
||||||
|
<summary>
|
||||||
|
CRC撤销临床数据
|
||||||
|
</summary>
|
||||||
|
<param name="opt"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:IRaCIS.Core.API.Controllers.InspectionController.PMConfirmClinical(IRaCIS.Core.Application.Service.Inspection.DTO.DataInspectionDto{IRaCIS.Core.Application.Service.Reading.Dto.CRCConfirmClinicalInDto})">
|
||||||
|
<summary>
|
||||||
|
PM确认临床数据
|
||||||
|
</summary>
|
||||||
|
<param name="opt"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:IRaCIS.Core.API.Controllers.InspectionController.SubmitClinicalFormAndSign(IRaCIS.Core.Application.Service.Inspection.DTO.DataInspectionDto{IRaCIS.Core.Application.Service.Reading.Dto.SubmitClinicalFormInDto})">
|
||||||
|
<summary>
|
||||||
|
提交结构化录入并签名
|
||||||
|
</summary>
|
||||||
|
<param name="opt"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
<member name="M:IRaCIS.Core.API.Controllers.InspectionController.SubmitJudgeVisitTaskResult(IRaCIS.Core.Application.Service.Inspection.DTO.DataInspectionDto{IRaCIS.Core.Application.Service.Reading.Dto.SaveJudgeVisitTaskResult})">
|
<member name="M:IRaCIS.Core.API.Controllers.InspectionController.SubmitJudgeVisitTaskResult(IRaCIS.Core.Application.Service.Inspection.DTO.DataInspectionDto{IRaCIS.Core.Application.Service.Reading.Dto.SaveJudgeVisitTaskResult})">
|
||||||
<summary>
|
<summary>
|
||||||
提交阅片裁判问题
|
提交阅片裁判问题
|
||||||
@@ -173,6 +208,12 @@
|
|||||||
</summary>
|
</summary>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:IRaCIS.Core.API.Controllers.InspectionController.ResetAndAsyncCriterion(IRaCIS.Core.Application.Service.Inspection.DTO.DataInspectionDto{IRaCIS.Core.Application.Service.Reading.Dto.ResetAndAsyncCriterionInDto})">
|
||||||
|
<summary>
|
||||||
|
重置并同步项目阅片标准
|
||||||
|
</summary>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
<member name="M:IRaCIS.Core.API.Controllers.InspectionController.CRCRequestToQC(IRaCIS.Core.Application.Service.Inspection.DTO.DataInspectionDto{IRaCIS.Core.Application.Contracts.CRCRequestToQCCommand})">
|
<member name="M:IRaCIS.Core.API.Controllers.InspectionController.CRCRequestToQC(IRaCIS.Core.Application.Service.Inspection.DTO.DataInspectionDto{IRaCIS.Core.Application.Contracts.CRCRequestToQCCommand})">
|
||||||
<summary>
|
<summary>
|
||||||
CRC RequestToQC 批量提交
|
CRC RequestToQC 批量提交
|
||||||
@@ -233,95 +274,49 @@
|
|||||||
<member name="M:IRaCIS.Core.API.Controllers.StudyController.ArchiveStudyNew(System.Guid,System.Guid,System.String,System.Nullable{System.Guid},System.Guid,Microsoft.Extensions.Logging.ILogger{IRaCIS.Core.API.Controllers.UploadDownLoadController},EasyCaching.Core.IEasyCachingProvider,IRaCIS.Core.Application.Contracts.IStudyService,Microsoft.AspNetCore.SignalR.IHubContext{IRaCIS.Core.API.UploadHub,IRaCIS.Core.API.IUploadClient},IRaCIS.Core.Application.Contracts.Dicom.IDicomArchiveService,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.StudyMonitor})">
|
<member name="M:IRaCIS.Core.API.Controllers.StudyController.ArchiveStudyNew(System.Guid,System.Guid,System.String,System.Nullable{System.Guid},System.Guid,Microsoft.Extensions.Logging.ILogger{IRaCIS.Core.API.Controllers.UploadDownLoadController},EasyCaching.Core.IEasyCachingProvider,IRaCIS.Core.Application.Contracts.IStudyService,Microsoft.AspNetCore.SignalR.IHubContext{IRaCIS.Core.API.UploadHub,IRaCIS.Core.API.IUploadClient},IRaCIS.Core.Application.Contracts.Dicom.IDicomArchiveService,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.StudyMonitor})">
|
||||||
<summary>Dicom 归档</summary>
|
<summary>Dicom 归档</summary>
|
||||||
</member>
|
</member>
|
||||||
<member name="M:IRaCIS.Core.API.Controllers.StudyController.UploadVisitClinicalData(System.Guid)">
|
<member name="M:IRaCIS.Core.API.Controllers.StudyController.UploadNoneDicomFile(IRaCIS.Core.API.Controllers.StudyController.UploadNoneDicomFileCommand,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.NoneDicomStudy},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.StudyMonitor})">
|
||||||
<summary>
|
|
||||||
上传临床数据 多文件
|
|
||||||
</summary>
|
|
||||||
<param name="subjectVisitId"></param>
|
|
||||||
<returns></returns>
|
|
||||||
</member>
|
|
||||||
<member name="M:IRaCIS.Core.API.Controllers.StudyController.UploadClinicalTemplate(System.Nullable{System.Guid})">
|
|
||||||
<summary>
|
|
||||||
上传临床数据模板
|
|
||||||
</summary>
|
|
||||||
<param name="trialId"></param>
|
|
||||||
<returns></returns>
|
|
||||||
</member>
|
|
||||||
<member name="M:IRaCIS.Core.API.Controllers.StudyController.UploadReadClinicalData(System.Guid,System.Guid,System.Guid)">
|
|
||||||
<summary>
|
|
||||||
上传阅片临床数据
|
|
||||||
</summary>
|
|
||||||
<param name="trialId"></param>
|
|
||||||
<param name="subjectId"></param>
|
|
||||||
<param name="readingId"></param>
|
|
||||||
<returns></returns>
|
|
||||||
</member>
|
|
||||||
<member name="M:IRaCIS.Core.API.Controllers.StudyController.UploadPrintscreen(System.Guid)">
|
|
||||||
<summary>
|
|
||||||
上传截图
|
|
||||||
</summary>
|
|
||||||
<param name="subjectId"></param>
|
|
||||||
<returns></returns>
|
|
||||||
</member>
|
|
||||||
<member name="M:IRaCIS.Core.API.Controllers.StudyController.UploadReadingAnswerImage(System.Guid,System.Guid)">
|
|
||||||
<summary>
|
|
||||||
上传Reading问题的图像
|
|
||||||
</summary>
|
|
||||||
<param name="trialId"></param>
|
|
||||||
<param name="visitTaskId"></param>
|
|
||||||
<returns></returns>
|
|
||||||
</member>
|
|
||||||
<member name="M:IRaCIS.Core.API.Controllers.StudyController.UploadJudgeTaskImage(System.Guid,System.Guid)">
|
|
||||||
<summary>
|
|
||||||
上传裁判任务的图像
|
|
||||||
</summary>
|
|
||||||
<param name="trialId"></param>
|
|
||||||
<param name="visitTaskId"></param>
|
|
||||||
<returns></returns>
|
|
||||||
</member>
|
|
||||||
<member name="M:IRaCIS.Core.API.Controllers.StudyController.UploadMedicalReviewImage(System.Guid,System.Guid)">
|
|
||||||
<summary>
|
|
||||||
上传医学审核图片
|
|
||||||
</summary>
|
|
||||||
<param name="trialId"></param>
|
|
||||||
<param name="taskMedicalReviewId"></param>
|
|
||||||
<returns></returns>
|
|
||||||
</member>
|
|
||||||
<member name="M:IRaCIS.Core.API.Controllers.StudyController.UploadNoneDicomFile(Microsoft.AspNetCore.Http.IFormCollection,System.Guid,System.Guid,System.Guid,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.NoneDicomStudy},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.StudyMonitor})">
|
|
||||||
<summary>
|
<summary>
|
||||||
上传非Dicom 文件 支持压缩包 多文件上传
|
上传非Dicom 文件 支持压缩包 多文件上传
|
||||||
</summary>
|
</summary>
|
||||||
<param name="formCollection"></param>
|
<param name="incommand"></param>
|
||||||
<param name="subjectVisitId"></param>
|
|
||||||
<param name="noneDicomStudyId"></param>
|
|
||||||
<param name="studyMonitorId"></param>
|
|
||||||
<param name="_noneDicomStudyRepository"></param>
|
<param name="_noneDicomStudyRepository"></param>
|
||||||
|
<param name="_studyMonitorRepository"></param>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
<member name="M:IRaCIS.Core.API.Controllers.StudyController.UploadVisitCheckExcel(System.Guid)">
|
<member name="M:IRaCIS.Core.API.Controllers.StudyController.UploadVisitCheckExcel(System.Guid,IRaCIS.Core.Application.Helper.IOSSService)">
|
||||||
<summary>
|
<summary>
|
||||||
一致性核查 excel上传 支持三种格式
|
一致性核查 excel上传 支持三种格式
|
||||||
</summary>
|
</summary>
|
||||||
<param name="trialId"></param>
|
<param name="trialId"></param>
|
||||||
|
<param name="oSSService"></param>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
|
<exception cref="T:IRaCIS.Core.Infrastructure.BusinessValidationFailedException"></exception>
|
||||||
</member>
|
</member>
|
||||||
<member name="T:IRaCIS.Core.API.Controllers.FileController">
|
<member name="T:IRaCIS.Core.API.Controllers.FileController">
|
||||||
<summary>医生文件上传下载</summary>
|
<summary>医生文件上传下载</summary>
|
||||||
</member>
|
</member>
|
||||||
<member name="M:IRaCIS.Core.API.Controllers.FileController.UploadOrdinaryFile(System.String,System.Guid)">
|
<member name="M:IRaCIS.Core.API.Controllers.FileController.GetOfficialResume(IRaCIS.Core.API.Controllers.GetDoctorPathCommand,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Attachment})">
|
||||||
<summary>
|
<summary>
|
||||||
上传文件[FileUpload]
|
New 医生首页 多选 获取多个医生信息+文件路径列表 医生压缩包名称 doctorCode + "_" + doctorName _(时间戳或者随机的Guid)
|
||||||
</summary>
|
</summary>
|
||||||
<param name="attachmentType">附件类型</param>
|
<returns></returns>
|
||||||
<param name="doctorId">医生Id</param>
|
|
||||||
<returns>返回文件信息</returns>
|
|
||||||
</member>
|
</member>
|
||||||
<member name="M:IRaCIS.Core.API.Controllers.FileController.UploadNonDoctorFile(System.String)">
|
<member name="M:IRaCIS.Core.API.Controllers.FileController.GetTrialDoctorOfficialResume(IRaCIS.Core.API.Controllers.GetDoctorPathCommand,IRaCIS.Application.Interfaces.IDoctorService,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Attachment})">
|
||||||
<summary>
|
<summary>
|
||||||
上传文件( 不是医生个人的文件)[FileUpload]
|
New 项目入组 勾选获取简历路径
|
||||||
例如:阅片章程等
|
|
||||||
</summary>
|
</summary>
|
||||||
<param name="type">文件类型</param>
|
<param name="command"></param>
|
||||||
|
<param name="_doctorService"></param>
|
||||||
|
<param name="_attachmentrepository"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:IRaCIS.Core.API.Controllers.FileController.GetDoctorAttachment(IRaCIS.Core.API.Controllers.GetDoctoreAttachPathCommand,IRaCIS.Application.Interfaces.IDoctorService,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Attachment})">
|
||||||
|
<summary>
|
||||||
|
new 医生详情 勾选或者下载文件路径
|
||||||
|
</summary>
|
||||||
|
<param name="command"></param>
|
||||||
|
<param name="_doctorService"></param>
|
||||||
|
<param name="_attachmentrepository"></param>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
<member name="M:IRaCIS.Core.API.Controllers.FileController.DownloadAttachment(System.Guid[])">
|
<member name="M:IRaCIS.Core.API.Controllers.FileController.DownloadAttachment(System.Guid[])">
|
||||||
@@ -331,14 +326,6 @@
|
|||||||
<param name="doctorIds"></param>
|
<param name="doctorIds"></param>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
<member name="M:IRaCIS.Core.API.Controllers.FileController.DownloadOfficialResume(System.Int32,System.Guid[])">
|
|
||||||
<summary>
|
|
||||||
下载医生官方简历
|
|
||||||
</summary>
|
|
||||||
<param name="language"></param>
|
|
||||||
<param name="doctorIds"></param>
|
|
||||||
<returns></returns>
|
|
||||||
</member>
|
|
||||||
<member name="M:IRaCIS.Core.API.Controllers.FileController.DownloadAttachmentById(System.Guid,System.Guid[])">
|
<member name="M:IRaCIS.Core.API.Controllers.FileController.DownloadAttachmentById(System.Guid,System.Guid[])">
|
||||||
<summary>
|
<summary>
|
||||||
下载指定医生的指定附件
|
下载指定医生的指定附件
|
||||||
@@ -347,50 +334,35 @@
|
|||||||
<param name="attachmentIds">要下载的附件Id</param>
|
<param name="attachmentIds">要下载的附件Id</param>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
<member name="M:IRaCIS.Core.API.Controllers.UploadDownLoadController.LocalFilePreview(System.String)">
|
<member name="M:IRaCIS.Core.API.Controllers.FileController.DownloadOfficialResume(System.Int32,System.Guid[])">
|
||||||
<summary> 缩略图 </summary>
|
<summary>
|
||||||
|
下载医生官方简历 首页 区分 中文和英文
|
||||||
|
</summary>
|
||||||
|
<param name="language"></param>
|
||||||
|
<param name="doctorIds"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:IRaCIS.Core.API.Controllers.FileController.DownloadResume(System.Int32,System.Guid,System.Guid[])">
|
||||||
|
<summary>
|
||||||
|
入组 项目下载简历
|
||||||
|
</summary>
|
||||||
|
<param name="language"></param>
|
||||||
|
<param name="trialId"></param>
|
||||||
|
<param name="doctorIdArray"></param>
|
||||||
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
<member name="M:IRaCIS.Core.API.Controllers.UploadDownLoadController.DownloadCommonFile(System.String,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.CommonDocument})">
|
<member name="M:IRaCIS.Core.API.Controllers.UploadDownLoadController.DownloadCommonFile(System.String,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.CommonDocument})">
|
||||||
<summary> 通用文件下载 </summary>
|
<summary> 通用文件下载 </summary>
|
||||||
</member>
|
</member>
|
||||||
<member name="M:IRaCIS.Core.API.Controllers.UploadDownLoadController.DownloadTrialClinicalFile(System.Guid,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ClinicalDataTrialSet})">
|
|
||||||
<summary>
|
|
||||||
下载项目临床数据文件
|
|
||||||
</summary>
|
|
||||||
<param name="clinicalDataTrialSetId"></param>
|
|
||||||
<param name="_clinicalDataTrialSetRepository"></param>
|
|
||||||
<returns></returns>
|
|
||||||
</member>
|
|
||||||
<member name="M:IRaCIS.Core.API.Controllers.UploadDownLoadController.DownloadSystemClinicalFile(System.Guid,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ClinicalDataSystemSet})">
|
|
||||||
<summary>
|
|
||||||
下载系统临床数据文件
|
|
||||||
</summary>
|
|
||||||
<param name="clinicalDataSystemSetId"></param>
|
|
||||||
<param name="_clinicalDataSystemSetRepository"></param>
|
|
||||||
<returns></returns>
|
|
||||||
</member>
|
|
||||||
<member name="M:IRaCIS.Core.API.Controllers.UploadDownLoadController.UploadTrialDoc(System.Guid)">
|
|
||||||
<summary>
|
|
||||||
上传项目签名文档
|
|
||||||
</summary>
|
|
||||||
<param name="trialId"></param>
|
|
||||||
<returns></returns>
|
|
||||||
</member>
|
|
||||||
<member name="M:IRaCIS.Core.API.Controllers.UploadDownLoadController.UploadSysTemDoc">
|
|
||||||
<summary>
|
|
||||||
上传系统签名文档
|
|
||||||
</summary>
|
|
||||||
<returns></returns>
|
|
||||||
</member>
|
|
||||||
<member name="M:IRaCIS.Core.API.Controllers.UploadDownLoadController.UploadCommonDoc">
|
<member name="M:IRaCIS.Core.API.Controllers.UploadDownLoadController.UploadCommonDoc">
|
||||||
<summary>
|
<summary>
|
||||||
上传通用文档 比如一致性核查的 比如导出的excel 模板
|
上传通用文档 比如一致性核查的 比如导出的excel 模板
|
||||||
</summary>
|
</summary>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
<member name="M:IRaCIS.Core.API.Controllers.UploadDownLoadController.UploadSystemNoticeDoc">
|
<member name="M:IRaCIS.Core.API.Controllers.UploadDownLoadController.Upload(IRaCIS.Core.API.Controllers.UploadDownLoadController.UploadFileType)">
|
||||||
<summary>
|
<summary>
|
||||||
上传系统通知文档
|
1:数据上传 2:导出、 3:邮件附件 4:邮件Html 通过 ----new
|
||||||
</summary>
|
</summary>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
@@ -399,6 +371,11 @@
|
|||||||
IPLimit限流 启动服务
|
IPLimit限流 启动服务
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="T:IRaCIS.Core.API.JSONTimeZoneConverter">
|
||||||
|
<summary>
|
||||||
|
序列化,反序列化的时候,处理时间 时区转换
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
<member name="M:IRaCIS.Core.API.NullToEmptyStringResolver.CreateProperties(System.Type,Newtonsoft.Json.MemberSerialization)">
|
<member name="M:IRaCIS.Core.API.NullToEmptyStringResolver.CreateProperties(System.Type,Newtonsoft.Json.MemberSerialization)">
|
||||||
<summary>
|
<summary>
|
||||||
创建属性
|
创建属性
|
||||||
@@ -414,6 +391,11 @@
|
|||||||
<param name="httpContext"></param>
|
<param name="httpContext"></param>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="T:TimeZoneAdjustmentMiddleware">
|
||||||
|
<summary>
|
||||||
|
废弃,没用
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
<member name="T:ZhaoXi._001.NET5Demo.Practice.WebApi.Utility.Jwt.CustomHSJWTService">
|
<member name="T:ZhaoXi._001.NET5Demo.Practice.WebApi.Utility.Jwt.CustomHSJWTService">
|
||||||
<summary>
|
<summary>
|
||||||
对称可逆加密
|
对称可逆加密
|
||||||
@@ -449,113 +431,5 @@
|
|||||||
<param name="withPrivate"></param>
|
<param name="withPrivate"></param>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
<member name="T:gRPC.ZHiZHUN.AuthServer.protos.GrpcTokenReflection">
|
|
||||||
<summary>Holder for reflection information generated from Protos/GrpcToken.proto</summary>
|
|
||||||
</member>
|
|
||||||
<member name="P:gRPC.ZHiZHUN.AuthServer.protos.GrpcTokenReflection.Descriptor">
|
|
||||||
<summary>File descriptor for Protos/GrpcToken.proto</summary>
|
|
||||||
</member>
|
|
||||||
<member name="T:gRPC.ZHiZHUN.AuthServer.protos.GetTokenReuqest">
|
|
||||||
<summary>
|
|
||||||
新增用户时需要传递数据消息, 可理解为一个类
|
|
||||||
</summary>
|
|
||||||
</member>
|
|
||||||
<member name="F:gRPC.ZHiZHUN.AuthServer.protos.GetTokenReuqest.IdFieldNumber">
|
|
||||||
<summary>Field number for the "id" field.</summary>
|
|
||||||
</member>
|
|
||||||
<member name="F:gRPC.ZHiZHUN.AuthServer.protos.GetTokenReuqest.UserNameFieldNumber">
|
|
||||||
<summary>Field number for the "userName" field.</summary>
|
|
||||||
</member>
|
|
||||||
<member name="F:gRPC.ZHiZHUN.AuthServer.protos.GetTokenReuqest.RealNameFieldNumber">
|
|
||||||
<summary>Field number for the "realName" field.</summary>
|
|
||||||
</member>
|
|
||||||
<member name="F:gRPC.ZHiZHUN.AuthServer.protos.GetTokenReuqest.ReviewerCodeFieldNumber">
|
|
||||||
<summary>Field number for the "reviewerCode" field.</summary>
|
|
||||||
</member>
|
|
||||||
<member name="F:gRPC.ZHiZHUN.AuthServer.protos.GetTokenReuqest.UserTypeEnumIntFieldNumber">
|
|
||||||
<summary>Field number for the "userTypeEnumInt" field.</summary>
|
|
||||||
</member>
|
|
||||||
<member name="F:gRPC.ZHiZHUN.AuthServer.protos.GetTokenReuqest.UserTypeShortNameFieldNumber">
|
|
||||||
<summary>Field number for the "userTypeShortName" field.</summary>
|
|
||||||
</member>
|
|
||||||
<member name="F:gRPC.ZHiZHUN.AuthServer.protos.GetTokenReuqest.IsAdminFieldNumber">
|
|
||||||
<summary>Field number for the "isAdmin" field.</summary>
|
|
||||||
</member>
|
|
||||||
<member name="T:gRPC.ZHiZHUN.AuthServer.protos.GetTokenResponse">
|
|
||||||
<summary>
|
|
||||||
新增时返回的消息格式
|
|
||||||
</summary>
|
|
||||||
</member>
|
|
||||||
<member name="F:gRPC.ZHiZHUN.AuthServer.protos.GetTokenResponse.CodeFieldNumber">
|
|
||||||
<summary>Field number for the "code" field.</summary>
|
|
||||||
</member>
|
|
||||||
<member name="F:gRPC.ZHiZHUN.AuthServer.protos.GetTokenResponse.TokenFieldNumber">
|
|
||||||
<summary>Field number for the "token" field.</summary>
|
|
||||||
</member>
|
|
||||||
<member name="T:gRPC.ZHiZHUN.AuthServer.protos.TokenGrpcService">
|
|
||||||
<summary>
|
|
||||||
service 用标识定义服务的,里面写对应的方法
|
|
||||||
</summary>
|
|
||||||
</member>
|
|
||||||
<member name="P:gRPC.ZHiZHUN.AuthServer.protos.TokenGrpcService.Descriptor">
|
|
||||||
<summary>Service descriptor</summary>
|
|
||||||
</member>
|
|
||||||
<member name="T:gRPC.ZHiZHUN.AuthServer.protos.TokenGrpcService.TokenGrpcServiceClient">
|
|
||||||
<summary>Client for TokenGrpcService</summary>
|
|
||||||
</member>
|
|
||||||
<member name="M:gRPC.ZHiZHUN.AuthServer.protos.TokenGrpcService.TokenGrpcServiceClient.#ctor(Grpc.Core.ChannelBase)">
|
|
||||||
<summary>Creates a new client for TokenGrpcService</summary>
|
|
||||||
<param name="channel">The channel to use to make remote calls.</param>
|
|
||||||
</member>
|
|
||||||
<member name="M:gRPC.ZHiZHUN.AuthServer.protos.TokenGrpcService.TokenGrpcServiceClient.#ctor(Grpc.Core.CallInvoker)">
|
|
||||||
<summary>Creates a new client for TokenGrpcService that uses a custom <c>CallInvoker</c>.</summary>
|
|
||||||
<param name="callInvoker">The callInvoker to use to make remote calls.</param>
|
|
||||||
</member>
|
|
||||||
<member name="M:gRPC.ZHiZHUN.AuthServer.protos.TokenGrpcService.TokenGrpcServiceClient.#ctor">
|
|
||||||
<summary>Protected parameterless constructor to allow creation of test doubles.</summary>
|
|
||||||
</member>
|
|
||||||
<member name="M:gRPC.ZHiZHUN.AuthServer.protos.TokenGrpcService.TokenGrpcServiceClient.#ctor(Grpc.Core.ClientBase.ClientBaseConfiguration)">
|
|
||||||
<summary>Protected constructor to allow creation of configured clients.</summary>
|
|
||||||
<param name="configuration">The client configuration.</param>
|
|
||||||
</member>
|
|
||||||
<member name="M:gRPC.ZHiZHUN.AuthServer.protos.TokenGrpcService.TokenGrpcServiceClient.GetUserToken(gRPC.ZHiZHUN.AuthServer.protos.GetTokenReuqest,Grpc.Core.Metadata,System.Nullable{System.DateTime},System.Threading.CancellationToken)">
|
|
||||||
<summary>
|
|
||||||
获取token
|
|
||||||
</summary>
|
|
||||||
<param name="request">The request to send to the server.</param>
|
|
||||||
<param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
|
|
||||||
<param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
|
|
||||||
<param name="cancellationToken">An optional token for canceling the call.</param>
|
|
||||||
<returns>The response received from the server.</returns>
|
|
||||||
</member>
|
|
||||||
<member name="M:gRPC.ZHiZHUN.AuthServer.protos.TokenGrpcService.TokenGrpcServiceClient.GetUserToken(gRPC.ZHiZHUN.AuthServer.protos.GetTokenReuqest,Grpc.Core.CallOptions)">
|
|
||||||
<summary>
|
|
||||||
获取token
|
|
||||||
</summary>
|
|
||||||
<param name="request">The request to send to the server.</param>
|
|
||||||
<param name="options">The options for the call.</param>
|
|
||||||
<returns>The response received from the server.</returns>
|
|
||||||
</member>
|
|
||||||
<member name="M:gRPC.ZHiZHUN.AuthServer.protos.TokenGrpcService.TokenGrpcServiceClient.GetUserTokenAsync(gRPC.ZHiZHUN.AuthServer.protos.GetTokenReuqest,Grpc.Core.Metadata,System.Nullable{System.DateTime},System.Threading.CancellationToken)">
|
|
||||||
<summary>
|
|
||||||
获取token
|
|
||||||
</summary>
|
|
||||||
<param name="request">The request to send to the server.</param>
|
|
||||||
<param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
|
|
||||||
<param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
|
|
||||||
<param name="cancellationToken">An optional token for canceling the call.</param>
|
|
||||||
<returns>The call object.</returns>
|
|
||||||
</member>
|
|
||||||
<member name="M:gRPC.ZHiZHUN.AuthServer.protos.TokenGrpcService.TokenGrpcServiceClient.GetUserTokenAsync(gRPC.ZHiZHUN.AuthServer.protos.GetTokenReuqest,Grpc.Core.CallOptions)">
|
|
||||||
<summary>
|
|
||||||
获取token
|
|
||||||
</summary>
|
|
||||||
<param name="request">The request to send to the server.</param>
|
|
||||||
<param name="options">The options for the call.</param>
|
|
||||||
<returns>The call object.</returns>
|
|
||||||
</member>
|
|
||||||
<member name="M:gRPC.ZHiZHUN.AuthServer.protos.TokenGrpcService.TokenGrpcServiceClient.NewInstance(Grpc.Core.ClientBase.ClientBaseConfiguration)">
|
|
||||||
<summary>Creates a new instance of client from given <c>ClientBaseConfiguration</c>.</summary>
|
|
||||||
</member>
|
|
||||||
</members>
|
</members>
|
||||||
</doc>
|
</doc>
|
||||||
|
|||||||
@@ -0,0 +1,118 @@
|
|||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.Extensions.Primitives;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 废弃,没用
|
||||||
|
/// </summary>
|
||||||
|
public class TimeZoneAdjustmentMiddleware
|
||||||
|
{
|
||||||
|
private readonly RequestDelegate _next;
|
||||||
|
|
||||||
|
public TimeZoneAdjustmentMiddleware(RequestDelegate next)
|
||||||
|
{
|
||||||
|
_next = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Invoke(HttpContext context)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(context.Request.ContentType))
|
||||||
|
{
|
||||||
|
// 请求没有内容体,可能是一个没有请求体的请求,比如 GET 请求
|
||||||
|
await _next(context);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var timeZoneId = "Asia/Shanghai"; // 客户端默认时区
|
||||||
|
|
||||||
|
var timeZoneIdHeaderValue = context.Request.Headers["TimeZoneId"];
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(timeZoneIdHeaderValue))
|
||||||
|
{
|
||||||
|
timeZoneId = timeZoneIdHeaderValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var timeZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 处理 JSON 请求体中的时间字段
|
||||||
|
if (context.Request.ContentType.StartsWith("application/json"))
|
||||||
|
{
|
||||||
|
var requestBody = await new StreamReader(context.Request.Body).ReadToEndAsync();
|
||||||
|
|
||||||
|
// 使用 JSON.NET 或 System.Text.Json 解析 JSON 请求体
|
||||||
|
// 假设请求体中有一个名为 "dateTime" 的时间字段
|
||||||
|
dynamic jsonData = JsonConvert.DeserializeObject(requestBody);
|
||||||
|
|
||||||
|
if (jsonData.dateTime != null)
|
||||||
|
{
|
||||||
|
if (DateTime.TryParse((string)jsonData.dateTime, out DateTime dateTime))
|
||||||
|
{
|
||||||
|
// 将 JSON 请求体中的时间字段转换为服务器时区的时间
|
||||||
|
var serverTime = TimeZoneInfo.ConvertTime(dateTime, timeZone);
|
||||||
|
jsonData.dateTime = serverTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将修改后的 JSON 请求体重新写入请求流中
|
||||||
|
var jsonBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(jsonData));
|
||||||
|
context.Request.Body = new MemoryStream(jsonBytes);
|
||||||
|
context.Request.ContentLength = jsonBytes.Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 处理 URL 表单参数
|
||||||
|
var modifiedQuery = new Dictionary<string, StringValues>();
|
||||||
|
|
||||||
|
foreach (var key in context.Request.Query.Keys)
|
||||||
|
{
|
||||||
|
if (DateTime.TryParse(context.Request.Query[key], out DateTime dateTime))
|
||||||
|
{
|
||||||
|
// 将 URL 表单参数中的时间转换为服务器时区的时间
|
||||||
|
var serverTime = TimeZoneInfo.ConvertTime(dateTime, timeZone);
|
||||||
|
modifiedQuery[key] = new StringValues(serverTime.ToString());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
modifiedQuery[key] = context.Request.Query[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
context.Request.Query = new QueryCollection(modifiedQuery);
|
||||||
|
|
||||||
|
// 处理Form请求体中的参数
|
||||||
|
if (context.Request.HasFormContentType)
|
||||||
|
{
|
||||||
|
var modifiedForm = new Dictionary<string, StringValues>();
|
||||||
|
|
||||||
|
foreach (var key in context.Request.Form.Keys)
|
||||||
|
{
|
||||||
|
if (DateTime.TryParse(context.Request.Form[key], out DateTime dateTime))
|
||||||
|
{
|
||||||
|
// 将请求体中的时间转换为服务器时区的时间
|
||||||
|
var serverTime = TimeZoneInfo.ConvertTime(dateTime, timeZone);
|
||||||
|
modifiedForm[key] = new StringValues(serverTime.ToString());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
modifiedForm[key] = context.Request.Form[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var newFormCollection = new FormCollection(modifiedForm);
|
||||||
|
|
||||||
|
// 将新的表单集合设置回请求对象
|
||||||
|
context.Request.Form = newFormCollection;
|
||||||
|
}
|
||||||
|
|
||||||
|
await _next(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
|
||||||
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
autoReload="true"
|
|
||||||
throwExceptions="false"
|
|
||||||
internalLogLevel="Off" internalLogFile="c:\temp\nlog-internal.log">
|
|
||||||
<variable name="myvar" value="myvalue"/>
|
|
||||||
|
|
||||||
<targets>
|
|
||||||
|
|
||||||
<target xsi:type="file" name="File" fileName="${basedir}/logs/${shortdate}/${level}.log"
|
|
||||||
layout="${longdate}||${level}||${logger}||${message}||${exception:format=ToString:innerFormat=ToString:maxInnerExceptionLevel=10:separator=\r\n}||end" />
|
|
||||||
</targets>
|
|
||||||
|
|
||||||
<rules>
|
|
||||||
<logger name="*" minlevel="Debug" writeTo="file" />
|
|
||||||
</rules>
|
|
||||||
</nlog>
|
|
||||||
@@ -1,157 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Autofac.Extensions.DependencyInjection;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Microsoft.Extensions.Hosting;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
|
||||||
using Serilog;
|
|
||||||
using MediatR;
|
|
||||||
using IRaCIS.Core.Application.MediatR.Handlers;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using MassTransit;
|
|
||||||
using MassTransit.NewIdProviders;
|
|
||||||
using System.IO;
|
|
||||||
using IRaCIS.Core.Domain.Share;
|
|
||||||
|
|
||||||
namespace IRaCIS.Core.API
|
|
||||||
{
|
|
||||||
public class Program
|
|
||||||
{
|
|
||||||
public readonly string environment;
|
|
||||||
public static async Task Main(string[] args)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
//以配置文件为准,否则 从url中取环境值(服务以命令行传递参数启动,配置文件配置了就不需要传递环境参数)
|
|
||||||
var config = new ConfigurationBuilder()
|
|
||||||
.AddEnvironmentVariables()
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
var enviromentName = config["ASPNETCORE_ENVIRONMENT"];
|
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(enviromentName))
|
|
||||||
{
|
|
||||||
|
|
||||||
var index = Array.IndexOf(args, "--env");
|
|
||||||
enviromentName = index > -1
|
|
||||||
? args[index + 1]
|
|
||||||
: "Development";
|
|
||||||
}
|
|
||||||
|
|
||||||
//Dicom 浏览
|
|
||||||
//ImageManager.SetImplementation(WinFormsImageManager.Instance);
|
|
||||||
|
|
||||||
var host = CreateHostBuilder(args)
|
|
||||||
.UseEnvironment(enviromentName) //命令行传入环境
|
|
||||||
.ConfigureAppConfiguration((hostContext, config) =>
|
|
||||||
{
|
|
||||||
|
|
||||||
//Console.WriteLine(hostContext.HostingEnvironment.EnvironmentName);
|
|
||||||
config.AddJsonFile("appsettings.json", false, true)
|
|
||||||
.AddJsonFile($"appsettings.{enviromentName}.json", false, true);
|
|
||||||
})
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
|
|
||||||
//// Serilog
|
|
||||||
SerilogExtension.AddSerilogSetup(enviromentName, host.Services);
|
|
||||||
Log.Logger.Warning($"当前环境:{enviromentName}");
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
NewId.SetProcessIdProvider(new CurrentProcessIdProvider());
|
|
||||||
|
|
||||||
|
|
||||||
//缓存项目的状态 匿名化数据
|
|
||||||
await InitCache(host);
|
|
||||||
|
|
||||||
WatchJsonFile(Path.Combine(AppContext.BaseDirectory, StaticData.Folder.Resources, StaticData.En_US_Json) );
|
|
||||||
|
|
||||||
WatchJsonFile(Path.Combine(AppContext.BaseDirectory, StaticData.Folder.Resources, StaticData.Zh_CN_Json));
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
host.Run();
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
|
|
||||||
Log.Logger.Error(e.InnerException is null ? e.Message + e.StackTrace : e.InnerException?.Message + e.InnerException?.StackTrace);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
|
||||||
Host.CreateDefaultBuilder(args)
|
|
||||||
.UseWindowsService()
|
|
||||||
.ConfigureWebHostDefaults(webBuilder =>
|
|
||||||
{
|
|
||||||
webBuilder.ConfigureKestrel((context, options) =>
|
|
||||||
{
|
|
||||||
//设置应用服务器Kestrel请求体最大为1GB // if don't set default value is: 30 MB
|
|
||||||
options.Limits.MaxRequestBodySize = long.MaxValue;
|
|
||||||
options.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(30);
|
|
||||||
options.Limits.RequestHeadersTimeout = TimeSpan.FromMinutes(20);
|
|
||||||
|
|
||||||
});
|
|
||||||
//webBuilder.UseSerilog();//在宿主机启动的时候配置serilog,与微软ILogger进行整合
|
|
||||||
webBuilder.UseStartup<Startup>();
|
|
||||||
}).UseSerilog()
|
|
||||||
.UseServiceProviderFactory(new AutofacServiceProviderFactory());
|
|
||||||
|
|
||||||
|
|
||||||
private static async Task InitCache(IHost host)
|
|
||||||
{
|
|
||||||
var _mediator = host.Services.GetService(typeof(IMediator)) as IMediator;
|
|
||||||
|
|
||||||
await _mediator.Send(new AnonymizeCacheRequest());
|
|
||||||
|
|
||||||
await _mediator.Send(new TrialStateCacheRequest());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private static void LoadJsonFile(string filePath)
|
|
||||||
{
|
|
||||||
|
|
||||||
IConfigurationBuilder builder = new ConfigurationBuilder()
|
|
||||||
.AddJsonFile(filePath);
|
|
||||||
|
|
||||||
IConfigurationRoot enConfiguration = builder.Build();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
foreach (IConfigurationSection section in enConfiguration.GetChildren())
|
|
||||||
{
|
|
||||||
if (filePath.Contains(StaticData.En_US_Json) )
|
|
||||||
{
|
|
||||||
StaticData.En_US_Dic[section.Key] = section.Value;
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
StaticData.Zh_CN_Dic[section.Key] = section.Value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
public static void WatchJsonFile(string filePath)
|
|
||||||
{
|
|
||||||
LoadJsonFile(filePath);
|
|
||||||
|
|
||||||
|
|
||||||
FileSystemWatcher watcher = new FileSystemWatcher(Path.GetDirectoryName(filePath), Path.GetFileName(filePath));
|
|
||||||
watcher.Changed += (sender, e) => LoadJsonFile(filePath);
|
|
||||||
watcher.EnableRaisingEvents = true;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,312 @@
|
|||||||
|
using System;
|
||||||
|
using Autofac.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Serilog;
|
||||||
|
using MediatR;
|
||||||
|
using IRaCIS.Core.Application.MediatR.Handlers;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using MassTransit;
|
||||||
|
using MassTransit.NewIdProviders;
|
||||||
|
using System.IO;
|
||||||
|
using IRaCIS.Core.Domain.Share;
|
||||||
|
using IRaCIS.Core.Infra.EFCore;
|
||||||
|
using IRaCIS.Core.Application.Helper;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using IRaCIS.Core.API;
|
||||||
|
using Autofac;
|
||||||
|
using Microsoft.AspNetCore.Http.Features;
|
||||||
|
using Microsoft.AspNetCore.SignalR;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using IRaCIS.Core.Application.Filter;
|
||||||
|
using Microsoft.AspNetCore.HttpOverrides;
|
||||||
|
using IRaCIS.Application.Services.BackGroundJob;
|
||||||
|
using LogDashboard;
|
||||||
|
using FellowOakDicom.Network;
|
||||||
|
using IRaCIS.Core.Application.Service.ImageAndDoc;
|
||||||
|
using IP2Region.Net.Abstractions;
|
||||||
|
using IP2Region.Net.XDB;
|
||||||
|
|
||||||
|
|
||||||
|
#region 获取环境变量
|
||||||
|
//以配置文件为准,否则 从url中取环境值(服务以命令行传递参数启动,配置文件配置了就不需要传递环境参数)
|
||||||
|
var config = new ConfigurationBuilder()
|
||||||
|
.AddEnvironmentVariables()
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
var enviromentName = config["ASPNETCORE_ENVIRONMENT"];
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(enviromentName))
|
||||||
|
{
|
||||||
|
|
||||||
|
var index = Array.IndexOf(args, "--env");
|
||||||
|
enviromentName = index > -1
|
||||||
|
? args[index + 1]
|
||||||
|
: "Development";
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
var builder = WebApplication.CreateBuilder(new WebApplicationOptions
|
||||||
|
{
|
||||||
|
EnvironmentName = enviromentName
|
||||||
|
});
|
||||||
|
|
||||||
|
#region 兼容windows 服务命令行的方式
|
||||||
|
|
||||||
|
//foreach (var arg in args)
|
||||||
|
//{
|
||||||
|
// Console.WriteLine(arg);
|
||||||
|
//}
|
||||||
|
|
||||||
|
int urlsIndex = Array.FindIndex(args, arg => arg != null && arg.StartsWith("--urls"));
|
||||||
|
|
||||||
|
if (urlsIndex > -1)
|
||||||
|
{
|
||||||
|
var url = args[urlsIndex].Substring("--urls=".Length);
|
||||||
|
Console.WriteLine(url);
|
||||||
|
builder.WebHost.UseUrls(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 主机配置
|
||||||
|
|
||||||
|
|
||||||
|
NewId.SetProcessIdProvider(new CurrentProcessIdProvider());
|
||||||
|
|
||||||
|
builder.Configuration.AddJsonFile("appsettings.json", false, true)
|
||||||
|
.AddJsonFile($"appsettings.{enviromentName}.json", false, true);
|
||||||
|
|
||||||
|
builder.Host
|
||||||
|
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
|
||||||
|
.ConfigureContainer<ContainerBuilder>(containerBuilder =>
|
||||||
|
{
|
||||||
|
containerBuilder.RegisterModule<AutofacModuleSetup>();
|
||||||
|
})
|
||||||
|
.UseWindowsService().UseSerilog();
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region 配置服务
|
||||||
|
var _configuration = builder.Configuration;
|
||||||
|
|
||||||
|
//健康检查
|
||||||
|
builder.Services.AddHealthChecks();
|
||||||
|
//本地化
|
||||||
|
builder.Services.AddJsonLocalization(options => options.ResourcesPath = "Resources");
|
||||||
|
|
||||||
|
// 异常、参数统一验证过滤器、Json序列化配置、字符串参数绑型统一Trim()
|
||||||
|
builder.Services.AddControllers(options =>
|
||||||
|
{
|
||||||
|
//options.Filters.Add<LogActionFilter>();
|
||||||
|
options.Filters.Add<ModelActionFilter>();
|
||||||
|
options.Filters.Add<ProjectExceptionFilter>();
|
||||||
|
options.Filters.Add<UnitOfWorkFilter>();
|
||||||
|
|
||||||
|
if (_configuration.GetSection("BasicSystemConfig").GetValue<bool>("OpenLoginLimit"))
|
||||||
|
{
|
||||||
|
options.Filters.Add<LimitUserRequestAuthorization>();
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
.AddNewtonsoftJsonSetup(builder.Services); // NewtonsoftJson 序列化 处理
|
||||||
|
|
||||||
|
builder.Services.AddOptions().Configure<SystemEmailSendConfig>(_configuration.GetSection("SystemEmailSendConfig"));
|
||||||
|
builder.Services.AddOptions().Configure<ServiceVerifyConfigOption>(_configuration.GetSection("BasicSystemConfig"));
|
||||||
|
builder.Services.AddOptions().Configure<AliyunOSSOptions>(_configuration.GetSection("AliyunOSS"));
|
||||||
|
builder.Services.AddOptions().Configure<ObjectStoreServiceOptions>(_configuration.GetSection("ObjectStoreService"));
|
||||||
|
|
||||||
|
|
||||||
|
//动态WebApi + UnifiedApiResultFilter 省掉控制器代码
|
||||||
|
builder.Services.AddDynamicWebApiSetup();
|
||||||
|
//AutoMapper
|
||||||
|
builder.Services.AddAutoMapperSetup();
|
||||||
|
//EF ORM QueryWithNoLock
|
||||||
|
builder.Services.AddEFSetup(_configuration);
|
||||||
|
//Http 响应压缩
|
||||||
|
builder.Services.AddResponseCompressionSetup();
|
||||||
|
//Swagger Api 文档
|
||||||
|
builder.Services.AddSwaggerSetup();
|
||||||
|
//JWT Token 验证
|
||||||
|
builder.Services.AddJWTAuthSetup(_configuration);
|
||||||
|
|
||||||
|
// MediatR 进程内消息 事件解耦 从程序集中 注册命令和handler对应关系
|
||||||
|
builder.Services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblyContaining<ConsistencyVerificationHandler>());
|
||||||
|
// EasyCaching 缓存
|
||||||
|
builder.Services.AddEasyCachingSetup(_configuration);
|
||||||
|
|
||||||
|
// hangfire 定时任务框架 有界面,更友好~
|
||||||
|
builder.Services.AddhangfireSetup(_configuration);
|
||||||
|
|
||||||
|
|
||||||
|
//Serilog 日志可视化 LogDashboard日志
|
||||||
|
builder.Services.AddLogDashboardSetup();
|
||||||
|
|
||||||
|
|
||||||
|
builder.Services.AddJsonConfigSetup(_configuration);
|
||||||
|
//转发头设置 获取真实IP
|
||||||
|
builder.Services.Configure<ForwardedHeadersOptions>(options =>
|
||||||
|
{
|
||||||
|
options.ForwardedHeaders =
|
||||||
|
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
|
||||||
|
});
|
||||||
|
//Dicom影像渲染图片 跨平台
|
||||||
|
builder.Services.AddDicomSetup();
|
||||||
|
|
||||||
|
// 实时应用
|
||||||
|
builder.Services.AddSignalR();
|
||||||
|
|
||||||
|
builder.Services.AddSingleton<IUserIdProvider, IRaCISUserIdProvider>();
|
||||||
|
|
||||||
|
|
||||||
|
builder.Services.AddSingleton<ISearcher>(new Searcher(CachePolicy.Content, Path.Combine(AppContext.BaseDirectory, StaticData.Folder.Resources, "ip2region.xdb")));
|
||||||
|
|
||||||
|
|
||||||
|
#region 历史废弃配置
|
||||||
|
//builder.Services.AddMemoryCache();
|
||||||
|
////上传限制 配置
|
||||||
|
//builder.Services.Configure<FormOptions>(options =>
|
||||||
|
//{
|
||||||
|
// options.MultipartBodyLengthLimit = int.MaxValue;
|
||||||
|
// options.ValueCountLimit = int.MaxValue;
|
||||||
|
// options.ValueLengthLimit = int.MaxValue;
|
||||||
|
//});
|
||||||
|
//IP 限流 可设置白名单 或者黑名单
|
||||||
|
//services.AddIpPolicyRateLimitSetup(_configuration);
|
||||||
|
// 用户类型 策略授权
|
||||||
|
//services.AddAuthorizationPolicySetup(_configuration);
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
var app = builder.Build();
|
||||||
|
var env = app.Environment;
|
||||||
|
|
||||||
|
#region 配置中间件
|
||||||
|
|
||||||
|
|
||||||
|
// Configure the HTTP request pipeline.
|
||||||
|
|
||||||
|
//本地化
|
||||||
|
app.UseLocalization();
|
||||||
|
|
||||||
|
app.UseForwardedHeaders();
|
||||||
|
|
||||||
|
//响应压缩
|
||||||
|
app.UseResponseCompression();
|
||||||
|
|
||||||
|
//app.UseCors(t => t.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
|
||||||
|
|
||||||
|
//不需要 token 访问的静态文件 wwwroot css, JavaScript, and images don't require authentication.
|
||||||
|
app.UseStaticFiles();
|
||||||
|
|
||||||
|
app.UseMiddleware<MultiDiskStaticFilesMiddleware>();
|
||||||
|
|
||||||
|
//LogDashboard
|
||||||
|
app.UseLogDashboard("/LogDashboard");
|
||||||
|
|
||||||
|
//hangfire
|
||||||
|
app.UseHangfireConfig(env);
|
||||||
|
|
||||||
|
|
||||||
|
////限流 中间件
|
||||||
|
//app.UseIpRateLimiting();
|
||||||
|
|
||||||
|
|
||||||
|
if (env.IsDevelopment())
|
||||||
|
{
|
||||||
|
app.UseDeveloperExceptionPage();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//app.UseHsts();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 特殊异常处理 比如 404
|
||||||
|
app.UseStatusCodePagesWithReExecute("/Error/{0}");
|
||||||
|
|
||||||
|
SwaggerSetup.Configure(app, env);
|
||||||
|
|
||||||
|
|
||||||
|
////serilog 记录请求的用户信息
|
||||||
|
app.UseSerilogConfig(env);
|
||||||
|
|
||||||
|
app.UseRouting();
|
||||||
|
|
||||||
|
app.UseCors(t => t.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
|
||||||
|
|
||||||
|
//app.UseIRacisHostStaticFileStore(env);
|
||||||
|
|
||||||
|
|
||||||
|
app.UseAuthentication();
|
||||||
|
app.UseAuthorization();
|
||||||
|
|
||||||
|
app.MapControllers();
|
||||||
|
|
||||||
|
app.MapHub<UploadHub>("/UploadHub");
|
||||||
|
app.MapHealthChecks("/health");
|
||||||
|
|
||||||
|
|
||||||
|
// Serilog
|
||||||
|
SerilogExtension.AddSerilogSetup(enviromentName, app.Services);
|
||||||
|
|
||||||
|
|
||||||
|
var hangfireJobService = app.Services.GetRequiredService<IIRaCISHangfireJob>();
|
||||||
|
|
||||||
|
await hangfireJobService.InitHangfireJobTaskAsync();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
#region 运行环境 部署平台
|
||||||
|
|
||||||
|
Log.Logger.Warning($"当前环境:{enviromentName}");
|
||||||
|
|
||||||
|
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||||
|
{
|
||||||
|
Log.Logger.Warning($"当前部署平台环境:windows");
|
||||||
|
}
|
||||||
|
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
||||||
|
{
|
||||||
|
Log.Logger.Warning($"当前部署平台环境:linux");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.Logger.Warning($"当前部署平台环境:OSX or FreeBSD");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
Log.Logger.Warning($"ContentRootPath:{env.ContentRootPath}");
|
||||||
|
|
||||||
|
|
||||||
|
string parentDirectory = Path.GetFullPath(Path.Combine(env.ContentRootPath, ".."));
|
||||||
|
|
||||||
|
|
||||||
|
Log.Logger.Warning($"ContentRootPath——parentDirectory:{parentDirectory}");
|
||||||
|
|
||||||
|
//Log.Logger.Warning($"ContentRootPath——GetParent:{Directory.GetParent(env.ContentRootPath).Parent.FullName}");
|
||||||
|
//Log.Logger.Warning($"ContentRootPath——xx:{Path.GetDirectoryName(Path.GetDirectoryName(env.ContentRootPath))}");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var server = DicomServerFactory.Create<CStoreSCPService>(11112,userState: app.Services);
|
||||||
|
|
||||||
|
app.Run();
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
|
||||||
|
Log.Logger.Error(e.InnerException is null ? e.Message + e.StackTrace : e.InnerException?.Message + e.InnerException?.StackTrace);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -13,14 +13,22 @@
|
|||||||
"commandName": "IISExpress",
|
"commandName": "IISExpress",
|
||||||
"launchBrowser": true,
|
"launchBrowser": true,
|
||||||
"environmentVariables": {
|
"environmentVariables": {
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
"ASPNETCORE_ENVIRONMENT": "Test_IRC"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"IRaCIS.Development": {
|
"IRaCIS.Test_IRC": {
|
||||||
"commandName": "Project",
|
"commandName": "Project",
|
||||||
"launchBrowser": true,
|
"launchBrowser": true,
|
||||||
"environmentVariables": {
|
"environmentVariables": {
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
"ASPNETCORE_ENVIRONMENT": "Test_IRC"
|
||||||
|
},
|
||||||
|
"applicationUrl": "http://localhost:6100"
|
||||||
|
},
|
||||||
|
"IRaCIS.Event_IRC": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Event_IRC"
|
||||||
},
|
},
|
||||||
"applicationUrl": "http://localhost:6100"
|
"applicationUrl": "http://localhost:6100"
|
||||||
},
|
},
|
||||||
@@ -30,29 +38,30 @@
|
|||||||
"launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}",
|
"launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}",
|
||||||
"publishAllPorts": true
|
"publishAllPorts": true
|
||||||
},
|
},
|
||||||
"IRaCIS.Staging": {
|
"IRaCIS.Uat_IRC": {
|
||||||
"commandName": "Project",
|
"commandName": "Project",
|
||||||
"launchBrowser": true,
|
"launchBrowser": true,
|
||||||
"environmentVariables": {
|
"environmentVariables": {
|
||||||
"ASPNETCORE_ENVIRONMENT": "Staging"
|
"ASPNETCORE_ENVIRONMENT": "Uat_IRC"
|
||||||
},
|
},
|
||||||
"applicationUrl": "http://localhost:6200"
|
"applicationUrl": "http://localhost:6100"
|
||||||
},
|
},
|
||||||
"IRaCIS.Production": {
|
"IRaCIS.Prod_IRC": {
|
||||||
"commandName": "Project",
|
"commandName": "Project",
|
||||||
"launchBrowser": true,
|
"launchBrowser": true,
|
||||||
"environmentVariables": {
|
"environmentVariables": {
|
||||||
"ASPNETCORE_ENVIRONMENT": "Production"
|
"ASPNETCORE_ENVIRONMENT": "Prod_IRC"
|
||||||
},
|
},
|
||||||
"applicationUrl": "http://localhost:6300"
|
"applicationUrl": "http://localhost:6100"
|
||||||
},
|
},
|
||||||
"IRaCIS.CertificateApply": {
|
"IRaCIS.US_Uat_IRC": {
|
||||||
"commandName": "Project",
|
"commandName": "Project",
|
||||||
"launchBrowser": true,
|
"launchBrowser": true,
|
||||||
"environmentVariables": {
|
"environmentVariables": {
|
||||||
"ASPNETCORE_ENVIRONMENT": "CertificateApply"
|
"ASPNETCORE_ENVIRONMENT": "US_Uat_IRC"
|
||||||
},
|
},
|
||||||
"applicationUrl": "http://localhost:6400"
|
"applicationUrl": "http://localhost:6100"
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,16 +1,16 @@
|
|||||||
// 使用的是proto3版本
|
// 使用的是proto3版本
|
||||||
syntax = "proto3";
|
syntax = "proto3";
|
||||||
// 定义命名空间,后续生成代码时就会生成对应的命名空间
|
// 定义命名空间,后续生成代码时就会生成对应的命名空间
|
||||||
option csharp_namespace = "gRPC.ZHiZHUN.AuthServer.protos";
|
option csharp_namespace = "gRPC.ZHiZHUN.AuthServer.protos";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
每一句需要用分号结尾
|
每一句需要用分号结尾
|
||||||
message 用来定义请求和返回数据格式
|
message 用来定义请求和返回数据格式
|
||||||
tag message后面的值数字代表是字段的标识(tag),不是赋值,
|
tag message后面的值数字代表是字段的标识(tag),不是赋值,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
// 新增用户时需要传递数据消息, 可理解为一个类
|
// 新增用户时需要传递数据消息, 可理解为一个类
|
||||||
message GetTokenReuqest{
|
message GetTokenReuqest{
|
||||||
string id=1;
|
string id=1;
|
||||||
string userName=2;
|
string userName=2;
|
||||||
@@ -22,48 +22,48 @@ message GetTokenReuqest{
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 新增时返回的消息格式
|
// 新增时返回的消息格式
|
||||||
message GetTokenResponse {
|
message GetTokenResponse {
|
||||||
int32 code=1;
|
int32 code=1;
|
||||||
string token =2;
|
string token =2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// service 用标识定义服务的,里面写对应的方法
|
// service 用标识定义服务的,里面写对应的方法
|
||||||
service TokenGrpcService{
|
service TokenGrpcService{
|
||||||
// 获取token
|
// 获取token
|
||||||
rpc GetUserToken(GetTokenReuqest) returns (GetTokenResponse);
|
rpc GetUserToken(GetTokenReuqest) returns (GetTokenResponse);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// 新增用户时需要传递数据消息, 可理解为一个类
|
// 新增用户时需要传递数据消息, 可理解为一个类
|
||||||
message AddUserReuqest{
|
message AddUserReuqest{
|
||||||
string name=1;
|
string name=1;
|
||||||
int32 age=2;
|
int32 age=2;
|
||||||
bool isBoy=3;
|
bool isBoy=3;
|
||||||
}
|
}
|
||||||
// 新增时返回的消息格式
|
// 新增时返回的消息格式
|
||||||
message ResultResponse {
|
message ResultResponse {
|
||||||
int32 code=1;
|
int32 code=1;
|
||||||
string msg =2;
|
string msg =2;
|
||||||
}
|
}
|
||||||
//传递的查询条件信息格式,可理解为平时传入的查询条件对象
|
//传递的查询条件信息格式,可理解为平时传入的查询条件对象
|
||||||
message QueryUserReuqest{
|
message QueryUserReuqest{
|
||||||
string name=1;
|
string name=1;
|
||||||
}
|
}
|
||||||
//查询返回的用户信息格式,可理解为返回的类
|
//查询返回的用户信息格式,可理解为返回的类
|
||||||
message UserInfoResponse {
|
message UserInfoResponse {
|
||||||
string name=1;
|
string name=1;
|
||||||
int32 age=2;
|
int32 age=2;
|
||||||
string gender=3;
|
string gender=3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// service 用标识定义服务的,里面写对应的方法
|
// service 用标识定义服务的,里面写对应的方法
|
||||||
service UserService{
|
service UserService{
|
||||||
// 新增用户
|
// 新增用户
|
||||||
rpc AddUser(AddUserReuqest) returns (ResultResponse);
|
rpc AddUser(AddUserReuqest) returns (ResultResponse);
|
||||||
// 查询用户
|
// 查询用户
|
||||||
rpc GetAllUser(QueryUserReuqest) returns (UserInfoResponse);
|
rpc GetAllUser(QueryUserReuqest) returns (UserInfoResponse);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,242 +0,0 @@
|
|||||||
using Autofac;
|
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Microsoft.AspNetCore.Http.Features;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Microsoft.Extensions.Hosting;
|
|
||||||
using System;
|
|
||||||
using IRaCIS.Core.Application.Filter;
|
|
||||||
using LogDashboard;
|
|
||||||
using MediatR;
|
|
||||||
using IRaCIS.Core.Application.MediatR.Handlers;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using AspNetCoreRateLimit;
|
|
||||||
using Microsoft.AspNetCore.HttpOverrides;
|
|
||||||
using IRaCIS.Core.Infra.EFCore;
|
|
||||||
using System.Globalization;
|
|
||||||
using Microsoft.AspNetCore.Localization;
|
|
||||||
using Localization;
|
|
||||||
using Magicodes.ExporterAndImporter.Core.Filters;
|
|
||||||
using IRaCIS.Core.Application.MediatR.CommandAndQueries;
|
|
||||||
using IRaCIS.Core.Infra.EFCore.Common;
|
|
||||||
using Invio.Extensions.Authentication.JwtBearer;
|
|
||||||
using Microsoft.AspNetCore.SignalR;
|
|
||||||
using IRaCIS.Core.Domain.Share;
|
|
||||||
using Microsoft.AspNetCore.StaticFiles;
|
|
||||||
|
|
||||||
namespace IRaCIS.Core.API
|
|
||||||
{
|
|
||||||
public class Startup
|
|
||||||
{
|
|
||||||
public Startup(IConfiguration configuration)
|
|
||||||
{
|
|
||||||
_configuration = configuration;
|
|
||||||
}
|
|
||||||
public ILogger<Startup> _logger { get; }
|
|
||||||
|
|
||||||
public IConfiguration _configuration { get; }
|
|
||||||
|
|
||||||
//// ConfigureContainer is where you can register things directly
|
|
||||||
//// with Autofac. This runs after ConfigureServices so the things
|
|
||||||
//// here will override registrations made in ConfigureServices.
|
|
||||||
//// Don't build the container; that gets done for you by the factory.
|
|
||||||
// for castle
|
|
||||||
public void ConfigureContainer(ContainerBuilder containerBuilder)
|
|
||||||
{
|
|
||||||
containerBuilder.RegisterModule<AutofacModuleSetup>();
|
|
||||||
|
|
||||||
#region Test
|
|
||||||
//containerBuilder.RegisterType<ClinicalDataService>().PropertiesAutowired().InstancePerLifetimeScope();//注册仓储
|
|
||||||
|
|
||||||
//var container = containerBuilder.Build();
|
|
||||||
|
|
||||||
//// Now you can resolve services using Autofac. For example,
|
|
||||||
//// this line will execute the lambda expression registered
|
|
||||||
//// to the IConfigReader service.
|
|
||||||
//using (var scope = container.BeginLifetimeScope())
|
|
||||||
//{
|
|
||||||
// var reader = scope.Resolve<BaseService>();
|
|
||||||
|
|
||||||
// var test = scope.Resolve<ClinicalDataService>();
|
|
||||||
// var test2 = scope.Resolve<IClinicalDataService>();
|
|
||||||
|
|
||||||
// var test3 = scope.Resolve<IEFUnitOfWork<IRaCISDBContext>>();
|
|
||||||
//}
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
|
|
||||||
// This method gets called by the runtime. Use this method to add services to the container.
|
|
||||||
public void ConfigureServices(IServiceCollection services)
|
|
||||||
{
|
|
||||||
//本地化
|
|
||||||
services.AddJsonLocalization(options => options.ResourcesPath = "Resources");
|
|
||||||
|
|
||||||
// 异常、参数统一验证过滤器、Json序列化配置、字符串参数绑型统一Trim()
|
|
||||||
services.AddControllers(options =>
|
|
||||||
{
|
|
||||||
//options.Filters.Add<LogActionFilter>();
|
|
||||||
options.Filters.Add<ModelActionFilter>();
|
|
||||||
options.Filters.Add<ProjectExceptionFilter>();
|
|
||||||
options.Filters.Add<UnitOfWorkFilter>();
|
|
||||||
|
|
||||||
if (_configuration.GetSection("BasicSystemConfig").GetValue<bool>("OpenLoginLimit"))
|
|
||||||
{
|
|
||||||
options.Filters.Add<LimitUserRequestAuthorization>();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
.AddNewtonsoftJsonSetup(); // NewtonsoftJson 序列化 处理
|
|
||||||
|
|
||||||
services.AddOptions().Configure<SystemEmailSendConfig>( _configuration.GetSection("SystemEmailSendConfig"));
|
|
||||||
services.AddOptions().Configure<ServiceVerifyConfigOption>(_configuration.GetSection("BasicSystemConfig"));
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//动态WebApi + UnifiedApiResultFilter 省掉控制器代码
|
|
||||||
services.AddDynamicWebApiSetup();
|
|
||||||
//AutoMapper
|
|
||||||
services.AddAutoMapperSetup();
|
|
||||||
//EF ORM QueryWithNoLock
|
|
||||||
services.AddEFSetup(_configuration);
|
|
||||||
//Http 响应压缩
|
|
||||||
services.AddResponseCompressionSetup();
|
|
||||||
//Swagger Api 文档
|
|
||||||
services.AddSwaggerSetup();
|
|
||||||
//JWT Token 验证
|
|
||||||
services.AddJWTAuthSetup(_configuration);
|
|
||||||
// MediatR 进程内消息 事件解耦 从程序集中 注册命令和handler对应关系
|
|
||||||
services.AddMediatR(typeof(ConsistencyVerificationHandler).Assembly);
|
|
||||||
// EasyCaching 缓存
|
|
||||||
services.AddEasyCachingSetup();
|
|
||||||
|
|
||||||
//services.AddDistributedMemoryCache();
|
|
||||||
|
|
||||||
// hangfire 定时任务框架 有界面,更友好~
|
|
||||||
services.AddhangfireSetup(_configuration);
|
|
||||||
// QuartZ 定时任务框架 使用了hangfire 暂时不用,后续需要可以打开,已经配好
|
|
||||||
services.AddQuartZSetup(_configuration);
|
|
||||||
|
|
||||||
// 保护上传文件
|
|
||||||
//services.AddStaticFileAuthorizationSetup();
|
|
||||||
|
|
||||||
|
|
||||||
////HttpReports 暂时废弃
|
|
||||||
//services.AddHttpReports().AddHttpTransport();
|
|
||||||
//Serilog 日志可视化 LogDashboard日志
|
|
||||||
services.AddLogDashboardSetup();
|
|
||||||
//上传限制 配置
|
|
||||||
services.Configure<FormOptions>(options =>
|
|
||||||
{
|
|
||||||
options.MultipartBodyLengthLimit = int.MaxValue;
|
|
||||||
options.ValueCountLimit = int.MaxValue;
|
|
||||||
options.ValueLengthLimit = int.MaxValue;
|
|
||||||
});
|
|
||||||
//IP 限流 可设置白名单 或者黑名单
|
|
||||||
//services.AddIpPolicyRateLimitSetup(_configuration);
|
|
||||||
// 用户类型 策略授权
|
|
||||||
services.AddAuthorizationPolicySetup(_configuration);
|
|
||||||
|
|
||||||
services.AddJsonConfigSetup(_configuration);
|
|
||||||
//转发头设置 获取真实IP
|
|
||||||
services.Configure<ForwardedHeadersOptions>(options =>
|
|
||||||
{
|
|
||||||
options.ForwardedHeaders =
|
|
||||||
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
|
|
||||||
});
|
|
||||||
//Dicom影像渲染图片 跨平台
|
|
||||||
services.AddDicomSetup();
|
|
||||||
|
|
||||||
// 实时应用
|
|
||||||
services.AddSignalR();
|
|
||||||
|
|
||||||
|
|
||||||
services.AddSingleton<IUserIdProvider, IRaCISUserIdProvider>();
|
|
||||||
|
|
||||||
//services.AddSingleton<IImportResultFilter, ImportResultFilteTest>();
|
|
||||||
|
|
||||||
services.AddMemoryCache();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
|
||||||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
|
||||||
{
|
|
||||||
//本地化
|
|
||||||
app.UseLocalization();
|
|
||||||
|
|
||||||
app.UseForwardedHeaders();
|
|
||||||
|
|
||||||
//响应压缩
|
|
||||||
app.UseResponseCompression();
|
|
||||||
|
|
||||||
//app.UseCors(t => t.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
|
|
||||||
|
|
||||||
//不需要 token 访问的静态文件 wwwroot css, JavaScript, and images don't require authentication.
|
|
||||||
app.UseStaticFiles();
|
|
||||||
|
|
||||||
|
|
||||||
//LogDashboard
|
|
||||||
app.UseLogDashboard("/LogDashboard");
|
|
||||||
|
|
||||||
//hangfire
|
|
||||||
app.UseHangfireConfig(env);
|
|
||||||
|
|
||||||
////暂时废弃
|
|
||||||
//app.UseHttpReports();
|
|
||||||
|
|
||||||
////限流 中间件
|
|
||||||
//app.UseIpRateLimiting();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (env.IsDevelopment())
|
|
||||||
{
|
|
||||||
app.UseDeveloperExceptionPage();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//app.UseHsts();
|
|
||||||
}
|
|
||||||
Console.WriteLine("当前环境: " + env.EnvironmentName);
|
|
||||||
|
|
||||||
//app.UseMiddleware<AuthMiddleware>();
|
|
||||||
|
|
||||||
// 特殊异常处理 比如 404
|
|
||||||
app.UseStatusCodePagesWithReExecute("/Error/{0}");
|
|
||||||
|
|
||||||
SwaggerSetup.Configure(app, env);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////serilog 记录请求的用户信息
|
|
||||||
app.UseSerilogConfig(env);
|
|
||||||
|
|
||||||
app.UseRouting();
|
|
||||||
|
|
||||||
app.UseCors(t => t.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
|
|
||||||
|
|
||||||
app.UseIRacisHostStaticFileStore(env);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
app.UseAuthentication();
|
|
||||||
//app.UseJwtBearerQueryString();
|
|
||||||
app.UseAuthorization();
|
|
||||||
|
|
||||||
////文件伺服 必须带Token 访问
|
|
||||||
////app.UseIRacisHostStaticFileStore(env);
|
|
||||||
|
|
||||||
app.UseEndpoints(endpoints =>
|
|
||||||
{
|
|
||||||
endpoints.MapControllers();
|
|
||||||
|
|
||||||
endpoints.MapHub<UploadHub>("/UploadHub");
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
using Hangfire;
|
|
||||||
using Hangfire.Dashboard;
|
|
||||||
using IRaCIS.Application.Services.BackGroundJob;
|
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
|
|
||||||
namespace IRaCIS.Core.API
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
public static class HangfireConfig
|
|
||||||
{
|
|
||||||
|
|
||||||
public static void UseHangfireConfig(this IApplicationBuilder app, IWebHostEnvironment env)
|
|
||||||
{
|
|
||||||
app.UseHangfireDashboard("/api/hangfire", new DashboardOptions()
|
|
||||||
{
|
|
||||||
//直接访问,没有带token 获取不到用户身份信息,所以这种自定义授权暂时没法使用
|
|
||||||
//Authorization = new[] { new hangfireAuthorizationFilter() }
|
|
||||||
|
|
||||||
//本地请求 才能看
|
|
||||||
Authorization = new[] { new LocalRequestsOnlyAuthorizationFilter() }
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
#region hangfire
|
|
||||||
//// 延迟任务执行 1秒之后执行 有时启动没运行 换成添加到队列中
|
|
||||||
//BackgroundJob.Schedule<ICacheTrialStatusJob>(t => t.MemoryCacheTrialStatus(), TimeSpan.FromSeconds(1));
|
|
||||||
////添加到后台任务队列,
|
|
||||||
//BackgroundJob.Enqueue<ICacheTrialStatusJob>(t => t.MemoryCacheTrialStatus());
|
|
||||||
|
|
||||||
//周期性任务,1天执行一次
|
|
||||||
|
|
||||||
RecurringJob.AddOrUpdate<IIRaCISCacheHangfireJob>(t => t.ProjectStartCache(), Cron.Daily);
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
using Hangfire;
|
||||||
|
using Hangfire.Dashboard;
|
||||||
|
using Hangfire.Dashboard.BasicAuthorization;
|
||||||
|
using IRaCIS.Application.Services.BackGroundJob;
|
||||||
|
using IRaCIS.Core.API.Filter;
|
||||||
|
using IRaCIS.Core.Application.Helper;
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
|
||||||
|
namespace IRaCIS.Core.API
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
public static class HangfireConfig
|
||||||
|
{
|
||||||
|
|
||||||
|
public static void UseHangfireConfig(this IApplicationBuilder app, IWebHostEnvironment env)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
app.UseHangfireDashboard("/back/hangfire", new DashboardOptions()
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Authorization = new IDashboardAuthorizationFilter[] { /*new hangfireAuthorizationFilter(),*/
|
||||||
|
|
||||||
|
new BasicAuthAuthorizationFilter(new BasicAuthAuthorizationFilterOptions(){
|
||||||
|
SslRedirect=false,
|
||||||
|
RequireSsl=false,
|
||||||
|
Users=new BasicAuthAuthorizationUser[]{
|
||||||
|
new BasicAuthAuthorizationUser(){
|
||||||
|
Login="admin",
|
||||||
|
PasswordClear="admin",
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
DashboardTitle ="后台任务管理",
|
||||||
|
|
||||||
|
|
||||||
|
//Authorization = new BasicAuthAuthorizationFilter[] {
|
||||||
|
// new BasicAuthAuthorizationFilter(new BasicAuthAuthorizationFilterOptions(){
|
||||||
|
// SslRedirect=false,
|
||||||
|
// RequireSsl=false,
|
||||||
|
// Users=new BasicAuthAuthorizationUser[]{
|
||||||
|
// new BasicAuthAuthorizationUser(){
|
||||||
|
// Login="admin",
|
||||||
|
// PasswordClear="test",
|
||||||
|
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// })
|
||||||
|
//}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+86
-36
@@ -1,8 +1,11 @@
|
|||||||
using IRaCIS.Core.Application.Helper;
|
using Azure;
|
||||||
|
using IRaCIS.Core.Application.Helper;
|
||||||
using IRaCIS.Core.Domain.Share;
|
using IRaCIS.Core.Domain.Share;
|
||||||
|
using IRaCIS.Core.Infrastructure.Extention;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.StaticFiles;
|
using Microsoft.AspNetCore.StaticFiles;
|
||||||
using Microsoft.Extensions.FileProviders;
|
using Microsoft.Extensions.FileProviders;
|
||||||
using Microsoft.Extensions.FileProviders.Physical;
|
using Microsoft.Extensions.FileProviders.Physical;
|
||||||
@@ -11,6 +14,8 @@ using Microsoft.Extensions.Hosting.Internal;
|
|||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Microsoft.VisualBasic;
|
using Microsoft.VisualBasic;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using SharpCompress.Common;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@@ -23,16 +28,14 @@ namespace IRaCIS.Core.API
|
|||||||
{
|
{
|
||||||
private readonly RequestDelegate _next;
|
private readonly RequestDelegate _next;
|
||||||
private readonly IWebHostEnvironment _hostingEnv;
|
private readonly IWebHostEnvironment _hostingEnv;
|
||||||
private readonly StaticFileOptions _options;
|
|
||||||
private readonly ILoggerFactory _loggerFactory;
|
private readonly ILoggerFactory _loggerFactory;
|
||||||
|
|
||||||
private string iRaCISDefaultDataFolder = string.Empty;
|
private string iRaCISDefaultDataFolder = string.Empty;
|
||||||
|
|
||||||
public MultiDiskStaticFilesMiddleware(RequestDelegate next, IWebHostEnvironment hostingEnv, StaticFileOptions options, ILoggerFactory loggerFactory)
|
public MultiDiskStaticFilesMiddleware(RequestDelegate next, IWebHostEnvironment hostingEnv, ILoggerFactory loggerFactory)
|
||||||
{
|
{
|
||||||
_next = next;
|
_next = next;
|
||||||
_hostingEnv = hostingEnv;
|
_hostingEnv = hostingEnv;
|
||||||
_options = options;
|
|
||||||
_loggerFactory = loggerFactory;
|
_loggerFactory = loggerFactory;
|
||||||
|
|
||||||
iRaCISDefaultDataFolder = FileStoreHelper.GetIRaCISRootDataFolder(_hostingEnv);
|
iRaCISDefaultDataFolder = FileStoreHelper.GetIRaCISRootDataFolder(_hostingEnv);
|
||||||
@@ -48,58 +51,112 @@ namespace IRaCIS.Core.API
|
|||||||
var path = context.Request.Path.Value;
|
var path = context.Request.Path.Value;
|
||||||
var isIRacisFile = path.StartsWith($"/{StaticData.Folder.IRaCISDataFolder}");
|
var isIRacisFile = path.StartsWith($"/{StaticData.Folder.IRaCISDataFolder}");
|
||||||
|
|
||||||
var isDicomFile = path.Contains($"{StaticData.Folder.DicomFolder}");
|
var isDicomFile = isIRacisFile && path.Contains($"{StaticData.Folder.DicomFolder}");
|
||||||
|
|
||||||
var defaultFileProvider = new PhysicalFileProvider(iRaCISDefaultDataFolder);
|
|
||||||
var staticFileOptions = new StaticFileOptions
|
|
||||||
{
|
|
||||||
FileProvider = defaultFileProvider,
|
|
||||||
RequestPath = $"/{StaticData.Folder.IRaCISDataFolder}",
|
|
||||||
ServeUnknownFileTypes = true,
|
|
||||||
DefaultContentType = "application/octet-stream"
|
|
||||||
};
|
|
||||||
|
|
||||||
var defaultRoot = Path.GetPathRoot(iRaCISDefaultDataFolder);
|
|
||||||
|
|
||||||
//先从默认里面去找
|
//先从默认里面去找
|
||||||
if (isIRacisFile)
|
if (isIRacisFile)
|
||||||
{
|
{
|
||||||
if (defaultFileProvider.GetFileInfo(context.Request.Path).Exists)
|
|
||||||
|
|
||||||
|
|
||||||
|
#region 方式二
|
||||||
|
|
||||||
|
//var defaultFileProvider = new PhysicalFileProvider(iRaCISDefaultDataFolder);
|
||||||
|
|
||||||
|
//var staticFileOptions = new StaticFileOptions
|
||||||
|
//{
|
||||||
|
// FileProvider = defaultFileProvider,
|
||||||
|
// RequestPath = $"/{StaticData.Folder.IRaCISDataFolder}",
|
||||||
|
// ServeUnknownFileTypes = true,
|
||||||
|
// DefaultContentType = "application/octet-stream"
|
||||||
|
//};
|
||||||
|
|
||||||
|
//var a = defaultFileProvider.GetFileInfo(context.Request.Path).Exists;
|
||||||
|
|
||||||
|
//var staticFileMiddleware = new StaticFileMiddleware(_next, _hostingEnv, Options.Create(staticFileOptions), _loggerFactory);
|
||||||
|
//await staticFileMiddleware.Invoke(context);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region 文档上传默认会加wwwroot 奇怪...
|
||||||
|
|
||||||
|
var defaultFileProvider = new PhysicalFileProvider(FileStoreHelper.GetIRaCISRootPath(_hostingEnv));
|
||||||
|
|
||||||
|
if (defaultFileProvider.GetFileInfo(path).Exists)
|
||||||
{
|
{
|
||||||
var staticFileMiddleware = new StaticFileMiddleware(_next, _hostingEnv, Options.Create(staticFileOptions), _loggerFactory);
|
|
||||||
await staticFileMiddleware.Invoke(context);
|
var actrualPath = defaultFileProvider.GetFileInfo(path).PhysicalPath;
|
||||||
|
|
||||||
|
await context.Response.SendFileAsync(new PhysicalFileInfo(new FileInfo(actrualPath)));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//没找到
|
//没找到
|
||||||
//dicom影像,从多个文件夹尝试,因为会存在切换磁盘
|
//dicom影像,从多个文件夹尝试,因为会存在切换磁盘
|
||||||
if (isDicomFile)
|
if (isDicomFile)
|
||||||
{
|
{
|
||||||
var disks = GetDisks().Where(t=>!t.Contains(defaultRoot));
|
var defaultRoot = Path.GetPathRoot(iRaCISDefaultDataFolder);
|
||||||
|
|
||||||
|
//除默认部署路径的其他路径
|
||||||
|
var disks = DriveInfo.GetDrives()
|
||||||
|
.Where(d => d.IsReady && d.DriveType == DriveType.Fixed)/*.Where(t => !t.Name.Contains("C") && !t.Name.Contains("c"))*/
|
||||||
|
.OrderBy(d => d.AvailableFreeSpace)
|
||||||
|
.Select(d => d.RootDirectory.FullName)
|
||||||
|
.ToArray().Where(t=>!t.Contains(defaultRoot));
|
||||||
|
|
||||||
|
|
||||||
foreach (var item in disks)
|
foreach (var item in disks)
|
||||||
{
|
{
|
||||||
var otherFileStoreFolder = Path.Combine(item, _hostingEnv.EnvironmentName);
|
var otherFileStoreFolder = Path.Combine(item, _hostingEnv.EnvironmentName);
|
||||||
|
|
||||||
|
if (!Directory.Exists(otherFileStoreFolder))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
var otherFileProvider= new PhysicalFileProvider(otherFileStoreFolder);
|
var otherFileProvider= new PhysicalFileProvider(otherFileStoreFolder);
|
||||||
|
|
||||||
var otherStaticFileOptions = new StaticFileOptions
|
|
||||||
{
|
|
||||||
FileProvider = otherFileProvider,
|
|
||||||
RequestPath = $"/{StaticData.Folder.IRaCISDataFolder}",
|
|
||||||
ServeUnknownFileTypes = true,
|
|
||||||
DefaultContentType = "application/octet-stream"
|
|
||||||
};
|
|
||||||
|
|
||||||
if (otherFileProvider.GetFileInfo(context.Request.Path).Exists)
|
|
||||||
|
if (otherFileProvider.GetFileInfo(path).Exists)
|
||||||
{
|
{
|
||||||
var staticFileMiddleware = new StaticFileMiddleware(_next, _hostingEnv, Options.Create(staticFileOptions), _loggerFactory);
|
|
||||||
await staticFileMiddleware.Invoke(context);
|
var actrualPath = otherFileProvider.GetFileInfo(path).PhysicalPath;
|
||||||
|
|
||||||
|
//方式一
|
||||||
|
await context.Response.SendFileAsync( new PhysicalFileInfo(new FileInfo(actrualPath)));
|
||||||
|
|
||||||
|
#region 方式二 报错 otherFileProvider 应该还包含/{StaticData.Folder.IRaCISDataFolder} 这一层级
|
||||||
|
//var otherStaticFileOptions = new StaticFileOptions
|
||||||
|
//{
|
||||||
|
// FileProvider = otherFileProvider,
|
||||||
|
// RequestPath = $"/{StaticData.Folder.IRaCISDataFolder}",
|
||||||
|
// ServeUnknownFileTypes = true,
|
||||||
|
// DefaultContentType = "application/octet-stream"
|
||||||
|
//};
|
||||||
|
//var staticFileMiddleware = new StaticFileMiddleware(_next, _hostingEnv, Options.Create(otherStaticFileOptions), _loggerFactory);
|
||||||
|
//await staticFileMiddleware.Invoke(context);
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 如果没有找到文件,返回404
|
||||||
|
context.Response.StatusCode = 404;
|
||||||
|
context.Response.ContentType = "application/json";
|
||||||
|
|
||||||
|
await context.Response.WriteAsync(JsonConvert.SerializeObject(ResponseOutput.NotOk("File not found")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -109,14 +166,7 @@ namespace IRaCIS.Core.API
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
private string[] GetDisks()
|
|
||||||
{
|
|
||||||
// 获取系统中所有可用的磁盘
|
|
||||||
return DriveInfo.GetDrives()
|
|
||||||
.Where(d => d.IsReady && d.DriveType == DriveType.Fixed).Where(t => !t.Name.Contains("C") && !t.Name.Contains("c"))
|
|
||||||
.Select(d => d.RootDirectory.FullName)
|
|
||||||
.ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//private static string GetContentType(string path)
|
//private static string GetContentType(string path)
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ namespace IRaCIS.Core.API
|
|||||||
app.UseSerilogRequestLogging(opts
|
app.UseSerilogRequestLogging(opts
|
||||||
=>
|
=>
|
||||||
{
|
{
|
||||||
opts.MessageTemplate = "{TokenUserRealName} {TokenUserType} {ClientIp} {RequestIP} {Host} {Protocol} {RequestMethod} {RequestPath} {RequestBody} responded {StatusCode} in {Elapsed:0.0000} ms";
|
opts.MessageTemplate = "{TokenUserRealName} {TokenUserTypeShortName} {ClientIp} {LocalIP} {Host} {Protocol} {RequestMethod} {RequestPath} {RequestBody} responded {StatusCode} in {Elapsed:0.0000} ms";
|
||||||
opts.EnrichDiagnosticContext = SerilogHelper.EnrichFromRequest;
|
opts.EnrichDiagnosticContext = SerilogHelper.EnrichFromRequest;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using IRaCIS.Core.Infrastructure.Extention;
|
using IRaCIS.Core.Domain.Share;
|
||||||
|
using IRaCIS.Core.Infrastructure.Extention;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
using System;
|
using System;
|
||||||
@@ -20,7 +21,7 @@ namespace IRaCIS.Core.API
|
|||||||
diagnosticContext.Set("Host", request.Host);
|
diagnosticContext.Set("Host", request.Host);
|
||||||
|
|
||||||
//这种获取的Ip不准 配置服务才行
|
//这种获取的Ip不准 配置服务才行
|
||||||
diagnosticContext.Set("RequestIP", httpContext.Connection.RemoteIpAddress.ToString());
|
//diagnosticContext.Set("RequestIP", httpContext.Connection.RemoteIpAddress.ToString());
|
||||||
|
|
||||||
//这种方式可以,但是serilog提供了 就不用了
|
//这种方式可以,但是serilog提供了 就不用了
|
||||||
//diagnosticContext.Set("TestIP", httpContext.GetUserIp());
|
//diagnosticContext.Set("TestIP", httpContext.GetUserIp());
|
||||||
@@ -41,9 +42,9 @@ namespace IRaCIS.Core.API
|
|||||||
// Set the content-type of the Response at this point
|
// Set the content-type of the Response at this point
|
||||||
diagnosticContext.Set("ContentType", httpContext.Response.ContentType);
|
diagnosticContext.Set("ContentType", httpContext.Response.ContentType);
|
||||||
|
|
||||||
diagnosticContext.Set("TokenUserRealName", httpContext?.User?.FindFirst("realName")?.Value);
|
diagnosticContext.Set("TokenUserRealName", httpContext?.User?.FindFirst(JwtIRaCISClaimType.RealName)?.Value);
|
||||||
|
|
||||||
diagnosticContext.Set("TokenUserType", httpContext?.User?.FindFirst("userTypeEnumName")?.Value);
|
diagnosticContext.Set("TokenUserTypeShortName", httpContext?.User?.FindFirst(JwtIRaCISClaimType.UserTypeShortName)?.Value);
|
||||||
|
|
||||||
// Retrieve the IEndpointFeature selected for the request
|
// Retrieve the IEndpointFeature selected for the request
|
||||||
var endpoint = httpContext.GetEndpoint();
|
var endpoint = httpContext.GetEndpoint();
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using IRaCIS.Core.Infrastructure.Extention;
|
using IRaCIS.Core.Infrastructure.Extention;
|
||||||
using Microsoft.AspNetCore.Authentication;
|
using Microsoft.AspNetCore.Authentication;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.Extensions.Localization;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
@@ -12,8 +13,13 @@ namespace IRaCIS.Core.API
|
|||||||
{
|
{
|
||||||
public class ApiResponseHandler : AuthenticationHandler<AuthenticationSchemeOptions>
|
public class ApiResponseHandler : AuthenticationHandler<AuthenticationSchemeOptions>
|
||||||
{
|
{
|
||||||
public ApiResponseHandler(IOptionsMonitor<AuthenticationSchemeOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock)
|
public IStringLocalizer _localizer;
|
||||||
|
public ApiResponseHandler(IOptionsMonitor<AuthenticationSchemeOptions> options,
|
||||||
|
IStringLocalizer localizer,
|
||||||
|
ILoggerFactory logger, UrlEncoder encoder) : base(options, logger, encoder)
|
||||||
{
|
{
|
||||||
|
_localizer = localizer;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Task<AuthenticateResult> HandleAuthenticateAsync()
|
protected override Task<AuthenticateResult> HandleAuthenticateAsync()
|
||||||
@@ -24,14 +30,16 @@ namespace IRaCIS.Core.API
|
|||||||
{
|
{
|
||||||
Response.ContentType = "application/json";
|
Response.ContentType = "application/json";
|
||||||
Response.StatusCode = StatusCodes.Status401Unauthorized;
|
Response.StatusCode = StatusCodes.Status401Unauthorized;
|
||||||
await Response.WriteAsync(JsonConvert.SerializeObject(ResponseOutput.NotOk("您无权访问该接口", ApiResponseCodeEnum.NoToken)));
|
//---您无权访问该接口
|
||||||
|
await Response.WriteAsync(JsonConvert.SerializeObject(ResponseOutput.NotOk(_localizer["ApiResponse_NoAccess"], ApiResponseCodeEnum.NoToken)));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async Task HandleForbiddenAsync(AuthenticationProperties properties)
|
protected override async Task HandleForbiddenAsync(AuthenticationProperties properties)
|
||||||
{
|
{
|
||||||
Response.ContentType = "application/json";
|
Response.ContentType = "application/json";
|
||||||
Response.StatusCode = StatusCodes.Status403Forbidden;
|
Response.StatusCode = StatusCodes.Status403Forbidden;
|
||||||
await Response.WriteAsync(JsonConvert.SerializeObject(ResponseOutput.NotOk("您的权限不允许进行该操作",ApiResponseCodeEnum.HaveTokenNotAccess)));
|
//---您的权限不允许进行该操作
|
||||||
|
await Response.WriteAsync(JsonConvert.SerializeObject(ResponseOutput.NotOk(_localizer["ApiResponse_Permission"],ApiResponseCodeEnum.HaveTokenNotAccess)));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using Autofac;
|
using Autofac;
|
||||||
using Autofac.Extras.DynamicProxy;
|
using Autofac.Extras.DynamicProxy;
|
||||||
using IRaCIS.Core.Application;
|
using IRaCIS.Core.Application;
|
||||||
using IRaCIS.Core.Application.AOP;
|
|
||||||
using IRaCIS.Core.Application.BackGroundJob;
|
using IRaCIS.Core.Application.BackGroundJob;
|
||||||
using IRaCIS.Core.Infra.EFCore;
|
using IRaCIS.Core.Infra.EFCore;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
@@ -31,10 +30,6 @@ namespace IRaCIS.Core.API
|
|||||||
|
|
||||||
containerBuilder.RegisterType<Repository>().As<IRepository>().InstancePerLifetimeScope();
|
containerBuilder.RegisterType<Repository>().As<IRepository>().InstancePerLifetimeScope();
|
||||||
|
|
||||||
//containerBuilder.RegisterType<Mapper>().As<IMapper>().InstancePerLifetimeScope();
|
|
||||||
|
|
||||||
//containerBuilder.RegisterGeneric(typeof(EFUnitOfWork<>))
|
|
||||||
// .As(typeof(IEFUnitOfWork<>)).InstancePerLifetimeScope();//注册仓储
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@@ -50,8 +45,7 @@ namespace IRaCIS.Core.API
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
//containerBuilder.RegisterType<BaseService>().As<IBaseService>().PropertiesAutowired().InstancePerLifetimeScope();
|
|
||||||
//containerBuilder.RegisterType<DictionaryService>().As<IDictionaryService>().InstancePerLifetimeScope();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -59,21 +53,12 @@ namespace IRaCIS.Core.API
|
|||||||
containerBuilder.RegisterAssemblyTypes(application).Where(t => t.FullName.Contains("Service"))
|
containerBuilder.RegisterAssemblyTypes(application).Where(t => t.FullName.Contains("Service"))
|
||||||
.PropertiesAutowired().AsImplementedInterfaces().EnableClassInterceptors();
|
.PropertiesAutowired().AsImplementedInterfaces().EnableClassInterceptors();
|
||||||
|
|
||||||
//Assembly infrastructure = Assembly.Load("IRaCIS.Core.Infra.EFCore");
|
|
||||||
//containerBuilder.RegisterAssemblyTypes(infrastructure).AsImplementedInterfaces();
|
|
||||||
|
|
||||||
containerBuilder.RegisterType<HttpContextAccessor>().As<IHttpContextAccessor>().SingleInstance();
|
containerBuilder.RegisterType<HttpContextAccessor>().As<IHttpContextAccessor>().SingleInstance();
|
||||||
containerBuilder.RegisterType<UserInfo>().As<IUserInfo>().InstancePerLifetimeScope();
|
containerBuilder.RegisterType<UserInfo>().As<IUserInfo>().InstancePerLifetimeScope();
|
||||||
|
|
||||||
|
|
||||||
//containerBuilder.RegisterType<Dictionary>().InstancePerLifetimeScope();
|
|
||||||
//Autofac 注册拦截器 需要注意的是生成api上服务上的动态代理AOP失效 间接掉用不影响
|
|
||||||
//containerBuilder.RegisterType<TrialStatusAutofacAOP>();
|
|
||||||
//containerBuilder.RegisterType<UserAddAOP>();
|
|
||||||
//containerBuilder.RegisterType<QANoticeAOP>();
|
|
||||||
//containerBuilder.RegisterType<LogService>().As<ILogService>().SingleInstance();
|
|
||||||
|
|
||||||
|
|
||||||
//注册hangfire任务 依赖注入
|
//注册hangfire任务 依赖注入
|
||||||
containerBuilder.RegisterType<ObtainTaskAutoCancelJob>().As<IObtainTaskAutoCancelJob>().InstancePerDependency();
|
containerBuilder.RegisterType<ObtainTaskAutoCancelJob>().As<IObtainTaskAutoCancelJob>().InstancePerDependency();
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
using IRaCIS.Core.Application.Triggers;
|
using Hangfire.SqlServer;
|
||||||
|
using IRaCIS.Core.Application.Triggers;
|
||||||
using IRaCIS.Core.Infra.EFCore;
|
using IRaCIS.Core.Infra.EFCore;
|
||||||
|
using Medallion.Threading;
|
||||||
|
using Medallion.Threading.SqlServer;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using StackExchange.Redis;
|
||||||
|
|
||||||
namespace IRaCIS.Core.API
|
namespace IRaCIS.Core.API
|
||||||
{
|
{
|
||||||
@@ -37,6 +41,7 @@ namespace IRaCIS.Core.API
|
|||||||
triggerOptions.AddTrigger<AddSubjectTrigger>();
|
triggerOptions.AddTrigger<AddSubjectTrigger>();
|
||||||
triggerOptions.AddTrigger<ChallengeStateTrigger>();
|
triggerOptions.AddTrigger<ChallengeStateTrigger>();
|
||||||
triggerOptions.AddTrigger<SubjectStateTrigger>();
|
triggerOptions.AddTrigger<SubjectStateTrigger>();
|
||||||
|
triggerOptions.AddTrigger<AddCRCCliniaclDataTrigger>();
|
||||||
triggerOptions.AddTrigger<SubjectVisitCheckPassedTrigger>();
|
triggerOptions.AddTrigger<SubjectVisitCheckPassedTrigger>();
|
||||||
triggerOptions.AddTrigger<SubjectVisitFinalVisitTrigger>();
|
triggerOptions.AddTrigger<SubjectVisitFinalVisitTrigger>();
|
||||||
triggerOptions.AddTrigger<SubjectVisitTrigger>();
|
triggerOptions.AddTrigger<SubjectVisitTrigger>();
|
||||||
@@ -44,6 +49,9 @@ namespace IRaCIS.Core.API
|
|||||||
triggerOptions.AddTrigger<TableQuestionRowTrigger>();
|
triggerOptions.AddTrigger<TableQuestionRowTrigger>();
|
||||||
//triggerOptions.AddTrigger<AddlTrialUserTrigger>();
|
//triggerOptions.AddTrigger<AddlTrialUserTrigger>();
|
||||||
triggerOptions.AddTrigger<VisitTaskIsFrontTaskNeedSignButNotSignTrigger>();
|
triggerOptions.AddTrigger<VisitTaskIsFrontTaskNeedSignButNotSignTrigger>();
|
||||||
|
triggerOptions.AddTrigger<VisitTaskIbeforeTrigger>();
|
||||||
|
|
||||||
|
triggerOptions.AddTrigger<UserLogTrigger>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -54,6 +62,13 @@ namespace IRaCIS.Core.API
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//注意区分 easy caching 也有 IDistributedLockProvider
|
||||||
|
services.AddSingleton<IDistributedLockProvider>(sp =>
|
||||||
|
{
|
||||||
|
//var connection = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]!);
|
||||||
|
|
||||||
|
return new SqlDistributedSynchronizationProvider(configuration.GetSection("ConnectionStrings:RemoteNew").Value);
|
||||||
|
});
|
||||||
|
|
||||||
//services.AddAssemblyTriggers(typeof(SubjectVisitImageDateTrigger).Assembly);
|
//services.AddAssemblyTriggers(typeof(SubjectVisitImageDateTrigger).Assembly);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,26 @@
|
|||||||
using EasyCaching.Core;
|
using EasyCaching.Core;
|
||||||
|
using EasyCaching.Core.Configurations;
|
||||||
using EasyCaching.Interceptor.Castle;
|
using EasyCaching.Interceptor.Castle;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace IRaCIS.Core.API
|
namespace IRaCIS.Core.API
|
||||||
{
|
{
|
||||||
public static class EasyCachingSetup
|
public static class EasyCachingSetup
|
||||||
{
|
{
|
||||||
public static void AddEasyCachingSetup(this IServiceCollection services)
|
public static void AddEasyCachingSetup(this IServiceCollection services, IConfiguration configuration)
|
||||||
{
|
{
|
||||||
services.AddEasyCaching(options =>
|
services.AddEasyCaching(options =>
|
||||||
{
|
{
|
||||||
options.UseInMemory();
|
options.UseInMemory();
|
||||||
|
|
||||||
|
//options.UseRedis(configuration, EasyCachingConstValue.DefaultRedisName).WithMessagePack(EasyCachingConstValue.DefaultRedisName);
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//services.ConfigureCastleInterceptor(options => options.CacheProviderName = EasyCachingConstValue.DefaultRedisName);
|
||||||
|
|
||||||
services.ConfigureCastleInterceptor(options => options.CacheProviderName = EasyCachingConstValue.DefaultInMemoryName);
|
services.ConfigureCastleInterceptor(options => options.CacheProviderName = EasyCachingConstValue.DefaultInMemoryName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,81 +0,0 @@
|
|||||||
//using System;
|
|
||||||
//using Microsoft.Extensions.DependencyInjection;
|
|
||||||
//using StackExchange.Profiling.Storage;
|
|
||||||
|
|
||||||
//namespace IRaCIS.Core.API
|
|
||||||
//{
|
|
||||||
// public class MiniProfilerConfigure
|
|
||||||
// {
|
|
||||||
// public static void ConfigureMiniProfiler(IServiceCollection services)
|
|
||||||
// {
|
|
||||||
|
|
||||||
// services.AddMiniProfiler(options =>
|
|
||||||
// {
|
|
||||||
// // All of this is optional. You can simply call .AddMiniProfiler() for all defaults
|
|
||||||
|
|
||||||
// // (Optional) Path to use for profiler URLs, default is /mini-profiler-resources
|
|
||||||
// options.RouteBasePath = "/profiler";
|
|
||||||
|
|
||||||
// //// (Optional) Control storage
|
|
||||||
// //// (default is 30 minutes in MemoryCacheStorage)
|
|
||||||
// (options.Storage as MemoryCacheStorage).CacheDuration = TimeSpan.FromMinutes(10);
|
|
||||||
|
|
||||||
// //// (Optional) Control which SQL formatter to use, InlineFormatter is the default
|
|
||||||
// //options.SqlFormatter = new StackExchange.Profiling.SqlFormatters.InlineFormatter();
|
|
||||||
|
|
||||||
// //// (Optional) To control authorization, you can use the Func<HttpRequest, bool> options:
|
|
||||||
// //// (default is everyone can access profilers)
|
|
||||||
// //options.ResultsAuthorize = request => MyGetUserFunction(request).CanSeeMiniProfiler;
|
|
||||||
// //options.ResultsListAuthorize = request => MyGetUserFunction(request).CanSeeMiniProfiler;
|
|
||||||
// //// Or, there are async versions available:
|
|
||||||
// //options.ResultsAuthorizeAsync = async request => (await MyGetUserFunctionAsync(request)).CanSeeMiniProfiler;
|
|
||||||
// //options.ResultsAuthorizeListAsync = async request => (await MyGetUserFunctionAsync(request)).CanSeeMiniProfilerLists;
|
|
||||||
|
|
||||||
// //// (Optional) To control which requests are profiled, use the Func<HttpRequest, bool> option:
|
|
||||||
// //// (default is everything should be profiled)
|
|
||||||
// //options.ShouldProfile = request => MyShouldThisBeProfiledFunction(request);
|
|
||||||
|
|
||||||
// //// (Optional) Profiles are stored under a user ID, function to get it:
|
|
||||||
// //// (default is null, since above methods don't use it by default)
|
|
||||||
// //options.UserIdProvider = request => MyGetUserIdFunction(request);
|
|
||||||
|
|
||||||
// //// (Optional) Swap out the entire profiler provider, if you want
|
|
||||||
// //// (default handles async and works fine for almost all applications)
|
|
||||||
// //options.ProfilerProvider = new MyProfilerProvider();
|
|
||||||
|
|
||||||
// //// (Optional) You can disable "Connection Open()", "Connection Close()" (and async variant) tracking.
|
|
||||||
// //// (defaults to true, and connection opening/closing is tracked)
|
|
||||||
// //options.TrackConnectionOpenClose = true;
|
|
||||||
|
|
||||||
// //// (Optional) Use something other than the "light" color scheme.
|
|
||||||
// //// (defaults to "light")
|
|
||||||
// //options.ColorScheme = StackExchange.Profiling.ColorScheme.Auto;
|
|
||||||
|
|
||||||
// //// The below are newer options, available in .NET Core 3.0 and above:
|
|
||||||
|
|
||||||
// //// (Optional) You can disable MVC filter profiling
|
|
||||||
// //// (defaults to true, and filters are profiled)
|
|
||||||
// //options.EnableMvcFilterProfiling = true;
|
|
||||||
// //// ...or only save filters that take over a certain millisecond duration (including their children)
|
|
||||||
// //// (defaults to null, and all filters are profiled)
|
|
||||||
// //// options.MvcFilterMinimumSaveMs = 1.0m;
|
|
||||||
|
|
||||||
// //// (Optional) You can disable MVC view profiling
|
|
||||||
// //// (defaults to true, and views are profiled)
|
|
||||||
// //options.EnableMvcViewProfiling = true;
|
|
||||||
// //// ...or only save views that take over a certain millisecond duration (including their children)
|
|
||||||
// //// (defaults to null, and all views are profiled)
|
|
||||||
// //// options.MvcViewMinimumSaveMs = 1.0m;
|
|
||||||
|
|
||||||
// //// (Optional) listen to any errors that occur within MiniProfiler itself
|
|
||||||
// //// options.OnInternalError = e => MyExceptionLogger(e);
|
|
||||||
|
|
||||||
// //// (Optional - not recommended) You can enable a heavy debug mode with stacks and tooltips when using memory storage
|
|
||||||
// //// It has a lot of overhead vs. normal profiling and should only be used with that in mind
|
|
||||||
// //// (defaults to false, debug/heavy mode is off)
|
|
||||||
// ////options.EnableDebugMode = true;
|
|
||||||
// });
|
|
||||||
// //.AddEntityFramework();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
using IRaCIS.Core.Domain.Share;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Newtonsoft.Json.Converters;
|
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace IRaCIS.Core.API
|
|
||||||
{
|
|
||||||
public class JSONCustomDateConverter : DateTimeConverterBase
|
|
||||||
{
|
|
||||||
private TimeZoneInfo _timeZoneInfo;
|
|
||||||
private string _dateFormat;
|
|
||||||
|
|
||||||
private IUserInfo _userInfo;
|
|
||||||
public JSONCustomDateConverter(string dateFormat, TimeZoneInfo timeZoneInfo, IUserInfo userInfo)
|
|
||||||
{
|
|
||||||
_dateFormat = dateFormat;
|
|
||||||
_timeZoneInfo = timeZoneInfo;
|
|
||||||
|
|
||||||
_userInfo = userInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
|
||||||
{
|
|
||||||
var timeZoneId = _userInfo.TimeZoneId;
|
|
||||||
|
|
||||||
var needConvertUtcDateTime = Convert.ToDateTime(value);
|
|
||||||
|
|
||||||
|
|
||||||
var tz = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId);
|
|
||||||
|
|
||||||
|
|
||||||
var dateTimeOffset = new DateTimeOffset(needConvertUtcDateTime);
|
|
||||||
|
|
||||||
var time = TimeZoneInfo.ConvertTimeFromUtc(needConvertUtcDateTime, tz).ToString(_dateFormat);
|
|
||||||
|
|
||||||
writer.WriteValue(time);
|
|
||||||
writer.Flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
using IRaCIS.Core.Domain.Share;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Converters;
|
||||||
|
using StackExchange.Redis;
|
||||||
|
using System;
|
||||||
|
using System.Globalization;
|
||||||
|
|
||||||
|
namespace IRaCIS.Core.API
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 序列化,反序列化的时候,处理时间 时区转换
|
||||||
|
/// </summary>
|
||||||
|
public class JSONTimeZoneConverter : DateTimeConverterBase
|
||||||
|
{
|
||||||
|
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||||
|
|
||||||
|
private readonly TimeZoneInfo _clientTimeZone;
|
||||||
|
public JSONTimeZoneConverter(IHttpContextAccessor httpContextAccessor)
|
||||||
|
{
|
||||||
|
_httpContextAccessor = httpContextAccessor;
|
||||||
|
|
||||||
|
//默认是UTC
|
||||||
|
//var timeZoneId = "Etc/UTC";
|
||||||
|
var timeZoneId = "Asia/Shanghai";
|
||||||
|
|
||||||
|
var timeZoneIdHeader = _httpContextAccessor?.HttpContext?.Request?.Headers["TimeZoneId"];
|
||||||
|
|
||||||
|
if (timeZoneIdHeader is not null && !string.IsNullOrEmpty(timeZoneIdHeader.Value))
|
||||||
|
{
|
||||||
|
timeZoneId = timeZoneIdHeader.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
_clientTimeZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool CanConvert(Type objectType)
|
||||||
|
{
|
||||||
|
// 仅支持 DateTime 类型的转换
|
||||||
|
return objectType == typeof(DateTime)|| objectType == typeof(DateTime?);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||||
|
{
|
||||||
|
if (reader.Value == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTime dateTime;
|
||||||
|
|
||||||
|
if (reader.ValueType == typeof(DateTime) || reader.ValueType == typeof(DateTime?))
|
||||||
|
{
|
||||||
|
DateTime? nullableDateTime = reader.Value as DateTime?;
|
||||||
|
|
||||||
|
|
||||||
|
if (nullableDateTime != null && nullableDateTime.HasValue)
|
||||||
|
{
|
||||||
|
dateTime = nullableDateTime.Value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (DateTime.TryParse((string)reader.Value, out dateTime) == false)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 将客户端时间转换为服务器时区的时间
|
||||||
|
var serverZoneTime = TimeZoneInfo.ConvertTime(dateTime, _clientTimeZone, TimeZoneInfo.Local);
|
||||||
|
|
||||||
|
return serverZoneTime;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||||
|
{
|
||||||
|
DateTime? nullableDateTime = value as DateTime?;
|
||||||
|
|
||||||
|
if (nullableDateTime != null && nullableDateTime.HasValue)
|
||||||
|
{
|
||||||
|
//第一个参数默认使用系统本地时区 也就是应用服务器的时区
|
||||||
|
DateTime clientZoneTime = TimeZoneInfo.ConvertTime(nullableDateTime.Value, _clientTimeZone);
|
||||||
|
writer.WriteValue(clientZoneTime);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
writer.WriteNull();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
|
|
||||||
|
using IRaCIS.Core.API._ServiceExtensions.NewtonsoftJson;
|
||||||
|
using IRaCIS.Core.Application.Helper;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Converters;
|
using Newtonsoft.Json.Converters;
|
||||||
@@ -8,8 +10,12 @@ namespace IRaCIS.Core.API
|
|||||||
{
|
{
|
||||||
public static class NewtonsoftJsonSetup
|
public static class NewtonsoftJsonSetup
|
||||||
{
|
{
|
||||||
public static void AddNewtonsoftJsonSetup(this IMvcBuilder builder)
|
public static void AddNewtonsoftJsonSetup(this IMvcBuilder builder, IServiceCollection services)
|
||||||
{
|
{
|
||||||
|
services.AddHttpContextAccessor();
|
||||||
|
services.AddScoped<JSONTimeZoneConverter>();
|
||||||
|
services.AddScoped<CustomStringConverter>();
|
||||||
|
services.AddScoped<IOSSService,OSSService>();
|
||||||
|
|
||||||
builder.AddNewtonsoftJson(options =>
|
builder.AddNewtonsoftJson(options =>
|
||||||
{
|
{
|
||||||
@@ -23,8 +29,15 @@ namespace IRaCIS.Core.API
|
|||||||
// 设置时间格式
|
// 设置时间格式
|
||||||
options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
|
options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
|
||||||
|
|
||||||
|
options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind;
|
||||||
|
|
||||||
//options.SerializerSettings.Converters.Add(new JSONCustomDateConverter()) ;
|
//options.SerializerSettings.Converters.Add(new JSONCustomDateConverter()) ;
|
||||||
|
|
||||||
|
options.SerializerSettings.Converters.Add(services.BuildServiceProvider().GetService<JSONTimeZoneConverter>());
|
||||||
|
|
||||||
|
//options.SerializerSettings.Converters.Add(services.BuildServiceProvider().GetService<CustomStringConverter>());
|
||||||
|
|
||||||
|
|
||||||
//IsoDateTimeConverter
|
//IsoDateTimeConverter
|
||||||
//options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
|
//options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ namespace IRaCIS.Core.API
|
|||||||
if(_MemberInfo.PropertyType == typeof(string))
|
if(_MemberInfo.PropertyType == typeof(string))
|
||||||
{
|
{
|
||||||
//去掉前后空格
|
//去掉前后空格
|
||||||
_MemberInfo.SetValue(target, value==null?string.Empty: value.ToString()==string.Empty? value:value.ToString().Trim());
|
_MemberInfo.SetValue(target, value==null?string.Empty: value.ToString()==string.Empty? value:value/*.ToString().Trim()*/);
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -0,0 +1,65 @@
|
|||||||
|
using IRaCIS.Core.Application.Helper;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Converters;
|
||||||
|
using Newtonsoft.Json.Serialization;
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
namespace IRaCIS.Core.API._ServiceExtensions.NewtonsoftJson
|
||||||
|
{
|
||||||
|
public class CustomStringConverter : JsonConverter<string>
|
||||||
|
{
|
||||||
|
//private readonly IHttpContextAccessor _httpContextAccessor;
|
||||||
|
private readonly IOSSService _oSSService;
|
||||||
|
|
||||||
|
// 构造函数
|
||||||
|
public CustomStringConverter(/*IHttpContextAccessor httpContextAccessor*/ IOSSService oSSService)
|
||||||
|
{
|
||||||
|
//_httpContextAccessor = httpContextAccessor;
|
||||||
|
_oSSService = oSSService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ReadJson(JsonReader reader, Type objectType, string existingValue, bool hasExistingValue, JsonSerializer serializer)
|
||||||
|
{
|
||||||
|
if (reader.TokenType == JsonToken.String)
|
||||||
|
{
|
||||||
|
return (string)reader.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void WriteJson(JsonWriter writer, string value, JsonSerializer serializer)
|
||||||
|
{
|
||||||
|
if (value != null)
|
||||||
|
{
|
||||||
|
// 在这里对字符串进行处理,例如转换大小写、去除空格等
|
||||||
|
// 这里只是一个示例,您可以根据实际需求进行更改
|
||||||
|
|
||||||
|
// 获取当前正在序列化的属性名
|
||||||
|
string propertyName = writer.Path.Split('.').Last();
|
||||||
|
|
||||||
|
Regex guidRegex = new Regex(@"[0-9a-fA-F]{8}(-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}");
|
||||||
|
|
||||||
|
if (propertyName.IndexOf("Path") > -1 && value.IndexOf('.')>-1 && guidRegex.IsMatch(value))
|
||||||
|
{
|
||||||
|
var tt= _oSSService.GetSignedUrl(value);
|
||||||
|
writer.WriteValue(tt);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 将处理后的字符串写入到 JsonWriter 中
|
||||||
|
writer.WriteValue(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
writer.WriteNull();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
|
|
||||||
using Microsoft.Extensions.Configuration;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
|
|
||||||
namespace IRaCIS.Core.API
|
|
||||||
{
|
|
||||||
public static class QuartZSetup
|
|
||||||
{
|
|
||||||
public static void AddQuartZSetup(this IServiceCollection services, IConfiguration configuration)
|
|
||||||
{
|
|
||||||
//services.AddTransient<CacheTrialStatusQuartZJob>();
|
|
||||||
|
|
||||||
//services.AddQuartz(q =>
|
|
||||||
//{
|
|
||||||
// // base quartz scheduler, job and trigger configuration
|
|
||||||
|
|
||||||
// // as of 3.3.2 this also injects scoped services (like EF DbContext) without problems
|
|
||||||
// q.UseMicrosoftDependencyInjectionJobFactory();
|
|
||||||
|
|
||||||
// // 基本Quartz调度器、作业和触发器配置
|
|
||||||
// var jobKey = new JobKey("RegularTrialWork", "regularWorkGroup");
|
|
||||||
// q.AddJob<CacheTrialStatusQuartZJob>(jobKey, j => j
|
|
||||||
// .WithDescription("Trial regular work")
|
|
||||||
// );
|
|
||||||
// q.AddTrigger(t => t
|
|
||||||
// .WithIdentity("TrialStatusTrigger")
|
|
||||||
// .ForJob(jobKey)
|
|
||||||
// //.StartNow()
|
|
||||||
// //.WithSimpleSchedule(x => x.WithInterval(TimeSpan.FromSeconds(15))//开始秒数 15s
|
|
||||||
// // .RepeatForever())//持续工作
|
|
||||||
// .WithCronSchedule("0 0 0/2 * * ?")//每小时执行一次
|
|
||||||
// .WithDescription("My regular trial work trigger")
|
|
||||||
// );
|
|
||||||
//});
|
|
||||||
|
|
||||||
//// ASP.NET Core hosting
|
|
||||||
//services.AddQuartzServer(options =>
|
|
||||||
//{
|
|
||||||
// // when shutting down we want jobs to complete gracefully
|
|
||||||
// options.WaitForJobsToComplete = true;
|
|
||||||
//});
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
using Serilog.Events;
|
using Serilog.Events;
|
||||||
using Serilog.Sinks.Email;
|
//using Serilog.Sinks.Email;
|
||||||
using System;
|
using System;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
|
||||||
@@ -21,29 +21,31 @@ namespace IRaCIS.Core.API
|
|||||||
.MinimumLevel.Override("Hangfire", LogEventLevel.Warning)
|
.MinimumLevel.Override("Hangfire", LogEventLevel.Warning)
|
||||||
.MinimumLevel.Override("System.Net.Http.HttpClient.HttpReports", LogEventLevel.Warning)
|
.MinimumLevel.Override("System.Net.Http.HttpClient.HttpReports", LogEventLevel.Warning)
|
||||||
.Enrich.WithClientIp()
|
.Enrich.WithClientIp()
|
||||||
.Enrich.WithClientAgent()
|
|
||||||
.Enrich.FromLogContext()
|
.Enrich.FromLogContext()
|
||||||
|
.Filter.ByExcluding(logEvent =>logEvent.Properties.ContainsKey("RequestPath") && logEvent.Properties["RequestPath"].ToString().Contains("/health"))
|
||||||
|
|
||||||
//控制台 方便调试 问题 我们显示记录日志 时 获取上下文的ip 和用户名 用户类型
|
//控制台 方便调试 问题 我们显示记录日志 时 获取上下文的ip 和用户名 用户类型
|
||||||
.WriteTo.Console(restrictedToMinimumLevel: LogEventLevel.Warning,
|
.WriteTo.Console(restrictedToMinimumLevel: LogEventLevel.Warning,
|
||||||
outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3} ] {LocalIP} {ClientIp} {TokenUserRealName} {TokenUserType} {Message:lj} {Properties:j}{NewLine} {Exception}")
|
outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {SourceContext:l} || {Message} || {Exception} ||end {NewLine}")
|
||||||
|
|
||||||
.WriteTo.File($"{AppContext.BaseDirectory}Serilogs/.log", rollingInterval: RollingInterval.Day,
|
.WriteTo.File($"{AppContext.BaseDirectory}Serilogs/.log", rollingInterval: RollingInterval.Day,
|
||||||
outputTemplate: "{Timestamp:HH:mm:ss} || {Level} || {SourceContext:l} || {Message} ||{Exception} ||end {NewLine}");
|
outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {SourceContext:l} || {Message} || {Exception} ||end {NewLine}");
|
||||||
|
|
||||||
//.WriteTo.MSSqlServer("Data Source=DESKTOP-4TU9A6M;Initial Catalog=CoreFrame;User ID=sa;Password=123456", "logs", autoCreateSqlTable: true, restrictedToMinimumLevel: LogEventLevel.Information)//从左至右四个参数分别是数据库连接字符串、表名、如果表不存在是否创建、最低等级。Serilog会默认创建一些列。
|
//.WriteTo.MSSqlServer("Data Source=DESKTOP-4TU9A6M;Initial Catalog=CoreFrame;User ID=sa;Password=123456", "logs", autoCreateSqlTable: true, restrictedToMinimumLevel: LogEventLevel.Information)//从左至右四个参数分别是数据库连接字符串、表名、如果表不存在是否创建、最低等级。Serilog会默认创建一些列。
|
||||||
|
|
||||||
if (environment == "Production")
|
//if (environment == "Production")
|
||||||
{
|
//{
|
||||||
config.WriteTo.Email(new EmailConnectionInfo()
|
// config.WriteTo.Email(new EmailConnectionInfo()
|
||||||
{
|
// {
|
||||||
EmailSubject = "系统警告,请速速查看!",//邮件标题
|
// EmailSubject = "系统警告,请速速查看!",//邮件标题
|
||||||
FromEmail = "test@extimaging.com",//发件人邮箱
|
// FromEmail = "test@extimaging.com",//发件人邮箱
|
||||||
MailServer = "smtp.qiye.aliyun.com",//smtp服务器地址
|
// MailServer = "smtp.qiye.aliyun.com",//smtp服务器地址
|
||||||
NetworkCredentials = new NetworkCredential("test@extimaging.com", "SHzyyl2021"),//两个参数分别是发件人邮箱与客户端授权码
|
// NetworkCredentials = new NetworkCredential("test@extimaging.com", "SHzyyl2021"),//两个参数分别是发件人邮箱与客户端授权码
|
||||||
Port = 465,//端口号
|
// Port = 465,//端口号
|
||||||
ToEmail = "872297557@qq.com"//收件人
|
// ToEmail = "872297557@qq.com"//收件人
|
||||||
}, restrictedToMinimumLevel: LogEventLevel.Error,
|
// }, restrictedToMinimumLevel: LogEventLevel.Error,
|
||||||
outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [ {Level} {ClientIp} {ClientAgent} {TokenUserRealName} {TokenUserType} ] || [path: {RequestPath} arguments: {RequestBody}] {SourceContext:l} || {Message} || {Exception} ||end {NewLine})");
|
// outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [ {Level} {ClientIp} {ClientAgent} {TokenUserRealName} {TokenUserType} ] || [path: {RequestPath} arguments: {RequestBody}] {SourceContext:l} || {Message} || {Exception} ||end {NewLine})");
|
||||||
}
|
//}
|
||||||
|
|
||||||
//扩展方法 获取上下文的ip 用户名 用户类型
|
//扩展方法 获取上下文的ip 用户名 用户类型
|
||||||
Log.Logger = config.Enrich.WithHttpContextInfo(serviceProvider).CreateLogger();
|
Log.Logger = config.Enrich.WithHttpContextInfo(serviceProvider).CreateLogger();
|
||||||
|
|||||||
@@ -1,55 +0,0 @@
|
|||||||
using Microsoft.OpenApi.Models;
|
|
||||||
using Swashbuckle.AspNetCore.SwaggerGen;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace IRaCIS.Core.API
|
|
||||||
{
|
|
||||||
public class JsonPatchDocumentFilter : IDocumentFilter
|
|
||||||
{
|
|
||||||
public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
|
|
||||||
{
|
|
||||||
var schemas = swaggerDoc.Components.Schemas.ToList();
|
|
||||||
foreach (var item in schemas)
|
|
||||||
{
|
|
||||||
if (item.Key.StartsWith("Operation") || item.Key.StartsWith("JsonPatchDocument"))
|
|
||||||
swaggerDoc.Components.Schemas.Remove(item.Key);
|
|
||||||
}
|
|
||||||
|
|
||||||
swaggerDoc.Components.Schemas.Add("Operation", new OpenApiSchema
|
|
||||||
{
|
|
||||||
Type = "object",
|
|
||||||
Properties = new Dictionary<string, OpenApiSchema>
|
|
||||||
{
|
|
||||||
{ "op", new OpenApiSchema { Type = "string" } },
|
|
||||||
{"value", new OpenApiSchema{ Type = "object", Nullable = true } },
|
|
||||||
{ "path", new OpenApiSchema { Type = "string" } }
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
swaggerDoc.Components.Schemas.Add("JsonPatchDocument", new OpenApiSchema
|
|
||||||
{
|
|
||||||
Type = "array",
|
|
||||||
Items = new OpenApiSchema
|
|
||||||
{
|
|
||||||
Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = "Operation" }
|
|
||||||
},
|
|
||||||
Description = "Array of operations to perform"
|
|
||||||
});
|
|
||||||
|
|
||||||
foreach (var path in swaggerDoc.Paths.SelectMany(p => p.Value.Operations)
|
|
||||||
.Where(p => p.Key == Microsoft.OpenApi.Models.OperationType.Patch))
|
|
||||||
{
|
|
||||||
foreach (var item in path.Value.RequestBody.Content.Where(c => c.Key != "application/json-patch+json"))
|
|
||||||
path.Value.RequestBody.Content.Remove(item.Key);
|
|
||||||
|
|
||||||
var response = path.Value.RequestBody.Content.SingleOrDefault(c => c.Key == "application/json-patch+json");
|
|
||||||
|
|
||||||
response.Value.Schema = new OpenApiSchema
|
|
||||||
{
|
|
||||||
Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = "JsonPatchDocument" }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -18,7 +18,6 @@ namespace IRaCIS.Core.API
|
|||||||
{
|
{
|
||||||
public static void AddSwaggerSetup(this IServiceCollection services)
|
public static void AddSwaggerSetup(this IServiceCollection services)
|
||||||
{
|
{
|
||||||
services.AddSwaggerExamplesFromAssemblyOf<JsonPatchUserRequestExample>();
|
|
||||||
|
|
||||||
services.AddSwaggerGen(options =>
|
services.AddSwaggerGen(options =>
|
||||||
{
|
{
|
||||||
@@ -63,7 +62,6 @@ namespace IRaCIS.Core.API
|
|||||||
// 在header中添加token,传递到后台
|
// 在header中添加token,传递到后台
|
||||||
options.OperationFilter<SecurityRequirementsOperationFilter>();
|
options.OperationFilter<SecurityRequirementsOperationFilter>();
|
||||||
|
|
||||||
options.DocumentFilter<JsonPatchDocumentFilter>();
|
|
||||||
|
|
||||||
// 添加登录按钮
|
// 添加登录按钮
|
||||||
options.AddSecurityDefinition("bearerAuth", new OpenApiSecurityScheme()
|
options.AddSecurityDefinition("bearerAuth", new OpenApiSecurityScheme()
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using Hangfire;
|
using Hangfire;
|
||||||
using Hangfire.SqlServer;
|
using Hangfire.SqlServer;
|
||||||
using Hangfire.Tags.SqlServer;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using System;
|
using System;
|
||||||
@@ -15,24 +14,29 @@ namespace IRaCIS.Core.API
|
|||||||
|
|
||||||
services.AddHangfire(hangFireConfig =>
|
services.AddHangfire(hangFireConfig =>
|
||||||
{
|
{
|
||||||
|
|
||||||
|
//hangFireConfig.UseInMemoryStorage();
|
||||||
|
|
||||||
//指定存储介质
|
//指定存储介质
|
||||||
hangFireConfig.UseSqlServerStorage(hangFireConnStr, new SqlServerStorageOptions()
|
hangFireConfig.UseSqlServerStorage(hangFireConnStr, new SqlServerStorageOptions()
|
||||||
{
|
{
|
||||||
SchemaName = "hangfire",
|
SchemaName = "dbo",
|
||||||
CommandBatchMaxTimeout = TimeSpan.FromMinutes(5),
|
CommandBatchMaxTimeout = TimeSpan.FromMinutes(5),
|
||||||
SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
|
SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
|
||||||
QueuePollInterval = TimeSpan.Zero,
|
QueuePollInterval = TimeSpan.Zero,
|
||||||
UseRecommendedIsolationLevel = true,
|
UseRecommendedIsolationLevel = true,
|
||||||
UsePageLocksOnDequeue = true,
|
|
||||||
DisableGlobalLocks = true
|
DisableGlobalLocks = true
|
||||||
});
|
});
|
||||||
|
|
||||||
hangFireConfig.UseTagsWithSql(); //nuget引入Hangfire.Tags.SqlServer
|
//hangFireConfig.UseTagsWithSql(); //nuget引入Hangfire.Tags.SqlServer
|
||||||
//.UseHangfireHttpJob();
|
//.UseHangfireHttpJob();
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
services.AddHangfireServer();
|
services.AddHangfireServer(option =>
|
||||||
|
{
|
||||||
|
option.Queues = new[] { "immediately_once", "default", "sys_init", "not_immediately_once" };
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,33 +0,0 @@
|
|||||||
{
|
|
||||||
"Logging": {
|
|
||||||
"LogLevel": {
|
|
||||||
"Default": "Information",
|
|
||||||
"Microsoft": "Warning",
|
|
||||||
"Microsoft.Hosting.Lifetime": "Information"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ConnectionStrings": {
|
|
||||||
"RemoteNew": "Server=123.56.94.154,1433\\MSSQLSERVER;Database=IRaCIS_Certificate;User ID=sa;Password=dev123456DEV;TrustServerCertificate=true",
|
|
||||||
"Hangfire": "Server=123.56.94.154,1433\\MSSQLSERVER;Database=Hangfire_IRaCIS;User ID=sa;Password=dev123456DEV;TrustServerCertificate=true"
|
|
||||||
|
|
||||||
},
|
|
||||||
"BasicSystemConfig": {
|
|
||||||
|
|
||||||
"OpenUserComplexPassword": false,
|
|
||||||
|
|
||||||
"OpenSignDocumentBeforeWork": false,
|
|
||||||
|
|
||||||
"OpenTrialRelationDelete": true,
|
|
||||||
|
|
||||||
"OpenLoginLimit": false
|
|
||||||
},
|
|
||||||
|
|
||||||
"SystemEmailSendConfig": {
|
|
||||||
"Port": 465,
|
|
||||||
"Host": "smtp.qiye.aliyun.com",
|
|
||||||
"FromEmail": "test@extimaging.com",
|
|
||||||
"FromName": "Test_IRC",
|
|
||||||
"AuthorizationCode": "SHzyyl2021"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
{
|
|
||||||
"Logging": {
|
|
||||||
"LogLevel": {
|
|
||||||
"Default": "Information",
|
|
||||||
"Microsoft": "Warning",
|
|
||||||
"Microsoft.Hosting.Lifetime": "Information"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ConnectionStrings": {
|
|
||||||
"RemoteNew": "Server=123.56.94.154,1433\\MSSQLSERVER;Database=IRaCIS_New_Tet;User ID=sa;Password=dev123456DEV;TrustServerCertificate=true",
|
|
||||||
"Hangfire": "Server=123.56.94.154,1433\\MSSQLSERVER;Database=Hangfire_IRaCIS;User ID=sa;Password=dev123456DEV;TrustServerCertificate=true"
|
|
||||||
|
|
||||||
},
|
|
||||||
"BasicSystemConfig": {
|
|
||||||
|
|
||||||
"OpenUserComplexPassword": false,
|
|
||||||
|
|
||||||
"OpenSignDocumentBeforeWork": false,
|
|
||||||
|
|
||||||
"OpenTrialRelationDelete": true,
|
|
||||||
|
|
||||||
"OpenLoginLimit": false
|
|
||||||
},
|
|
||||||
|
|
||||||
"SystemEmailSendConfig": {
|
|
||||||
"Port": 465,
|
|
||||||
"Host": "smtp.qiye.aliyun.com",
|
|
||||||
"FromEmail": "test@extimaging.com",
|
|
||||||
"FromName": "Test_IRC",
|
|
||||||
"AuthorizationCode": "SHzyyl2021"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft": "Warning",
|
||||||
|
"Microsoft.Hosting.Lifetime": "Information"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ConnectionStrings": {
|
||||||
|
"RemoteNew": "Server=47.117.164.182,1434;Database=Event_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
|
||||||
|
"Hangfire": "Server=47.117.164.182,1434;Database=Event_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
|
||||||
|
},
|
||||||
|
"ObjectStoreService": {
|
||||||
|
"ObjectStoreUse": "AliyunOSS",
|
||||||
|
"AliyunOSS": {
|
||||||
|
"regionId": "cn-shanghai",
|
||||||
|
"endpoint": "https://oss-cn-shanghai.aliyuncs.com",
|
||||||
|
"accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ",
|
||||||
|
"accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio",
|
||||||
|
"bucketName": "zy-irc-store",
|
||||||
|
"roleArn": "acs:ram::1899121822495495:role/oss-upload",
|
||||||
|
"viewEndpoint": "https://zy-irc-cache.oss-cn-shanghai.aliyuncs.com",
|
||||||
|
"region": "oss-cn-shanghai"
|
||||||
|
},
|
||||||
|
"MinIO": {
|
||||||
|
"endpoint": "http://192.168.3.68",
|
||||||
|
"port": "8001",
|
||||||
|
"useSSL": false,
|
||||||
|
"accessKey": "IDFkwEpWej0b4DtiuThL",
|
||||||
|
"secretKey": "Lhuu83yMhVwu7c1SnjvGY6lq74jzpYqifK6Qtj4h",
|
||||||
|
"bucketName": "test"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"BasicSystemConfig": {
|
||||||
|
|
||||||
|
"OpenUserComplexPassword": true,
|
||||||
|
|
||||||
|
"OpenSignDocumentBeforeWork": true,
|
||||||
|
|
||||||
|
"OpenLoginLimit": true,
|
||||||
|
"LoginMaxFailCount": 5,
|
||||||
|
|
||||||
|
"LoginFailLockMinutes": 30,
|
||||||
|
"AutoLoginOutMinutes": 60,
|
||||||
|
|
||||||
|
"ContinuousReadingTimeMin": 120,
|
||||||
|
|
||||||
|
"ReadingRestTimeMin": 10
|
||||||
|
},
|
||||||
|
"SystemEmailSendConfig": {
|
||||||
|
"Port": 465,
|
||||||
|
"Host": "smtp.qiye.aliyun.com",
|
||||||
|
"FromEmail": "uat@extimaging.com",
|
||||||
|
"FromName": "UAT_IRC",
|
||||||
|
"AuthorizationCode": "SHzyyl2021",
|
||||||
|
"SiteUrl": "http://irc.event.extimaging.com/login",
|
||||||
|
"CompanyName": "Extensive Imaging",
|
||||||
|
"CompanyNameCN": "上海展影医疗科技有限公司",
|
||||||
|
"CompanyShortName": "Extensive Imaging",
|
||||||
|
"CompanyShortNameCN": "展影医疗"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft": "Warning",
|
||||||
|
"Microsoft.Hosting.Lifetime": "Information"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ConnectionStrings": {
|
||||||
|
//"RemoteNew": "Server=101.132.193.237,1434;Database=Prod_IRC;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true",
|
||||||
|
//"Hangfire": "Server=101.132.193.237,1434;Database=Prod_IRC_Hangfire;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true"
|
||||||
|
"RemoteNew": "Server=prod_mssql_standard,1433;Database=Prod_IRC;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true",
|
||||||
|
"Hangfire": "Server=prod_mssql_standard,1433;Database=Prod_IRC_Hangfire;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true"
|
||||||
|
},
|
||||||
|
"ObjectStoreService": {
|
||||||
|
"ObjectStoreUse": "AliyunOSS",
|
||||||
|
"AliyunOSS": {
|
||||||
|
"regionId": "cn-shanghai",
|
||||||
|
"endpoint": "https://oss-cn-shanghai.aliyuncs.com",
|
||||||
|
"accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ",
|
||||||
|
"accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio",
|
||||||
|
"bucketName": "zy-irc-store",
|
||||||
|
"roleArn": "acs:ram::1899121822495495:role/oss-upload",
|
||||||
|
"viewEndpoint": "https://zy-irc-cache.oss-cn-shanghai.aliyuncs.com",
|
||||||
|
"region": "oss-cn-shanghai"
|
||||||
|
},
|
||||||
|
"MinIO": {
|
||||||
|
"endpoint": "http://192.168.3.68",
|
||||||
|
"port": "8001",
|
||||||
|
"useSSL": false,
|
||||||
|
"accessKey": "IDFkwEpWej0b4DtiuThL",
|
||||||
|
"secretKey": "Lhuu83yMhVwu7c1SnjvGY6lq74jzpYqifK6Qtj4h",
|
||||||
|
"bucketName": "test"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"BasicSystemConfig": {
|
||||||
|
|
||||||
|
"OpenUserComplexPassword": true,
|
||||||
|
"OpenSignDocumentBeforeWork": true,
|
||||||
|
|
||||||
|
"OpenLoginLimit": true,
|
||||||
|
"LoginMaxFailCount": 5,
|
||||||
|
"LoginFailLockMinutes": 30,
|
||||||
|
|
||||||
|
"AutoLoginOutMinutes": 360,
|
||||||
|
|
||||||
|
"OpenLoginMFA": false,
|
||||||
|
|
||||||
|
"ContinuousReadingTimeMin": 120,
|
||||||
|
|
||||||
|
"ReadingRestTimeMin": 10
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
"SystemEmailSendConfig": {
|
||||||
|
"Port": 465,
|
||||||
|
"Host": "smtp.qiye.aliyun.com",
|
||||||
|
"FromEmail": "IRC@extimaging.com",
|
||||||
|
"FromName": "IRC",
|
||||||
|
"AuthorizationCode": "ExtImg@2022",
|
||||||
|
"SiteUrl": "http://irc.extimaging.com/login",
|
||||||
|
"OrganizationName": "Extlmaging",
|
||||||
|
"OrganizationNameCN": "Extlmaging",
|
||||||
|
"CompanyName": "Extensive Imaging",
|
||||||
|
"CompanyNameCN": "上海展影医疗科技有限公司",
|
||||||
|
"CompanyShortName": "Extensive Imaging",
|
||||||
|
"CompanyShortNameCN": "展影医疗"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
{
|
|
||||||
"Logging": {
|
|
||||||
"LogLevel": {
|
|
||||||
"Default": "Information",
|
|
||||||
"Microsoft": "Warning",
|
|
||||||
"Microsoft.Hosting.Lifetime": "Information"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
//"RootUrl": "http://123.56.181.144:8060/",
|
|
||||||
"ConnectionStrings": {
|
|
||||||
"RemoteNew": "Server=101.132.193.237,1433;Database=IRaCIS.Production;User ID=sa;Password=zhanying2021;TrustServerCertificate=true",
|
|
||||||
"Hangfire": "Server=101.132.193.237,1433;Database=Hangfire.IRaCIS.Production;User ID=sa;Password=zhanying2021;TrustServerCertificate=true"
|
|
||||||
},
|
|
||||||
"BasicSystemConfig": {
|
|
||||||
|
|
||||||
"OpenUserComplexPassword": true,
|
|
||||||
|
|
||||||
"OpenSignDocumentBeforeWork": true,
|
|
||||||
|
|
||||||
"OpenLoginLimit": true
|
|
||||||
},
|
|
||||||
//"SystemEmailSendConfig": {
|
|
||||||
// "Port": 465,
|
|
||||||
// "Host": "smtp.163.com",
|
|
||||||
// "FromEmail": "zhou941003@qq.com",
|
|
||||||
// "FromName": "hangZhou",
|
|
||||||
// "AuthorizationCode": "sqfhlpfdvnexbcab"
|
|
||||||
//}
|
|
||||||
|
|
||||||
"SystemEmailSendConfig": {
|
|
||||||
"Port": 465,
|
|
||||||
"Host": "smtp.qiye.aliyun.com",
|
|
||||||
"FromEmail": "IRC@extimaging.com",
|
|
||||||
"FromName": "IRC",
|
|
||||||
"AuthorizationCode": "ExtImg@2022"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
{
|
|
||||||
"Logging": {
|
|
||||||
"LogLevel": {
|
|
||||||
"Default": "Information",
|
|
||||||
"Microsoft": "Warning",
|
|
||||||
"Microsoft.Hosting.Lifetime": "Information"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ConnectionStrings": {
|
|
||||||
"RemoteNew": "Server=123.56.94.154,1433\\MSSQLSERVER;Database=IRaCIS_Verify;User ID=sa;Password=dev123456DEV;TrustServerCertificate=true",
|
|
||||||
"Hangfire": "Server=123.56.94.154,1433\\MSSQLSERVER;Database=Hangfire_IRaCIS;User ID=sa;Password=dev123456DEV;TrustServerCertificate=true"
|
|
||||||
},
|
|
||||||
"BasicSystemConfig": {
|
|
||||||
|
|
||||||
"OpenUserComplexPassword": true,
|
|
||||||
|
|
||||||
"OpenSignDocumentBeforeWork": true,
|
|
||||||
|
|
||||||
"OpenLoginLimit": true
|
|
||||||
|
|
||||||
},
|
|
||||||
"SystemEmailSendConfig": {
|
|
||||||
"Port": 465,
|
|
||||||
"Host": "smtp.qiye.aliyun.com",
|
|
||||||
"FromEmail": "uat@extimaging.com",
|
|
||||||
"FromName": "UAT_IRC",
|
|
||||||
"AuthorizationCode": "SHzyyl2021"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft": "Warning",
|
||||||
|
"Microsoft.Hosting.Lifetime": "Information"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ConnectionStrings": {
|
||||||
|
"RemoteNew": "Server=106.14.89.110,1435;Database=Test_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
|
||||||
|
"Hangfire": "Server=106.14.89.110,1435;Database=Test_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
"ObjectStoreService": {
|
||||||
|
|
||||||
|
"ObjectStoreUse": "AliyunOSS",
|
||||||
|
|
||||||
|
"AliyunOSS": {
|
||||||
|
"regionId": "cn-shanghai",
|
||||||
|
"endPoint": "https://oss-cn-shanghai.aliyuncs.com",
|
||||||
|
"accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ",
|
||||||
|
"accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio",
|
||||||
|
"bucketName": "zy-irc-test-store",
|
||||||
|
"roleArn": "acs:ram::1899121822495495:role/oss-upload",
|
||||||
|
"viewEndpoint": "https://zy-irc-test-store.oss-cn-shanghai.aliyuncs.com",
|
||||||
|
"region": "oss-cn-shanghai"
|
||||||
|
},
|
||||||
|
"MinIO": {
|
||||||
|
"endPoint": "hir-oss.test.extimaging.com",
|
||||||
|
"port": "443",
|
||||||
|
"useSSL": true,
|
||||||
|
"accessKey": "fbStsVYCIPKHQneeqMwD",
|
||||||
|
"secretKey": "TzgvyA3zGXMUnpilJNUlyMYHfosl1hBMl6lxPmjy",
|
||||||
|
"bucketName": "irc-test",
|
||||||
|
"viewEndpoint": "https://hir-oss.test.extimaging.com/irc-test"
|
||||||
|
},
|
||||||
|
|
||||||
|
"AWS": {
|
||||||
|
"endPoint": "s3.us-east-1.amazonaws.com",
|
||||||
|
"useSSL": true,
|
||||||
|
"accessKey": "AKIAZQ3DRSOHFPJJ6FEU",
|
||||||
|
"secretKey": "l+yjtvV7Z4jiwm/7xCYv30UeUj/SvuqqYzAwjJHf",
|
||||||
|
"bucketName": "ei-irc-test-store",
|
||||||
|
"viewEndpoint": "https://ei-irc-test-store.s3.amazonaws.com/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"BasicSystemConfig": {
|
||||||
|
|
||||||
|
"OpenUserComplexPassword": false,
|
||||||
|
|
||||||
|
"OpenSignDocumentBeforeWork": false,
|
||||||
|
|
||||||
|
"OpenTrialRelationDelete": true,
|
||||||
|
|
||||||
|
"OpenLoginLimit": false,
|
||||||
|
|
||||||
|
"LoginMaxFailCount": 5,
|
||||||
|
|
||||||
|
"LoginFailLockMinutes": 1,
|
||||||
|
|
||||||
|
"AutoLoginOutMinutes": 1,
|
||||||
|
|
||||||
|
"OpenLoginMFA": false,
|
||||||
|
|
||||||
|
"ContinuousReadingTimeMin": 120,
|
||||||
|
|
||||||
|
"ReadingRestTimeMin": 10
|
||||||
|
},
|
||||||
|
|
||||||
|
"SystemEmailSendConfig": {
|
||||||
|
"Port": 465,
|
||||||
|
"Host": "smtp.qiye.aliyun.com",
|
||||||
|
"FromEmail": "test@extimaging.com",
|
||||||
|
"FromName": "Test_IRC",
|
||||||
|
"AuthorizationCode": "SHzyyl2021",
|
||||||
|
|
||||||
|
"SiteUrl": "http://irc.test.extimaging.com/login",
|
||||||
|
|
||||||
|
"OrganizationName": "Extlmaging",
|
||||||
|
"OrganizationNameCN": "Extlmaging",
|
||||||
|
"CompanyName": "Extensive Imaging",
|
||||||
|
"CompanyNameCN": "上海展影医疗科技有限公司",
|
||||||
|
"CompanyShortName": "Extensive Imaging",
|
||||||
|
"CompanyShortNameCN": "展影医疗"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
{
|
|
||||||
"Logging": {
|
|
||||||
"LogLevel": {
|
|
||||||
"Default": "Information",
|
|
||||||
"Microsoft": "Warning",
|
|
||||||
"Microsoft.Hosting.Lifetime": "Information"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ConnectionStrings": {
|
|
||||||
"RemoteNew": "Server=47.90.161.85,1433\\MSSQLSERVER;Database=IRaCIS_Demo_US;User ID=sa;Password=zhanying2021;TrustServerCertificate=true",
|
|
||||||
"Hangfire": "Server=47.90.161.85,1433\\MSSQLSERVER;Database=Hangfire.IRaCIS_Demo_US;User ID=sa;Password=zhanying2021;TrustServerCertificate=true"
|
|
||||||
|
|
||||||
},
|
|
||||||
"BasicSystemConfig": {
|
|
||||||
|
|
||||||
"OpenUserComplexPassword": false,
|
|
||||||
|
|
||||||
"OpenSignDocumentBeforeWork": false,
|
|
||||||
|
|
||||||
"OpenTrialRelationDelete": true,
|
|
||||||
|
|
||||||
"OpenLoginLimit": false
|
|
||||||
},
|
|
||||||
|
|
||||||
"SystemEmailSendConfig": {
|
|
||||||
"Port": 465,
|
|
||||||
"Host": "smtp.qiye.aliyun.com",
|
|
||||||
"FromEmail": "test@extimaging.com",
|
|
||||||
"FromName": "Test_IRC",
|
|
||||||
"AuthorizationCode": "SHzyyl2021"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft": "Warning",
|
||||||
|
"Microsoft.Hosting.Lifetime": "Information"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ConnectionStrings": {
|
||||||
|
"RemoteNew": "Server=us-prod-mssql-service,1433;Database=US_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
|
||||||
|
"Hangfire": "Server=us-prod-mssql-service,1433;Database=US_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
|
||||||
|
//"RemoteNew": "Server=44.210.231.169,1435;Database=US_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
|
||||||
|
//"Hangfire": "Server=44.210.231.169,1435;Database=US_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
|
||||||
|
},
|
||||||
|
|
||||||
|
"ObjectStoreService": {
|
||||||
|
"ObjectStoreUse": "AWS",
|
||||||
|
"AliyunOSS": {
|
||||||
|
"regionId": "cn-shanghai",
|
||||||
|
"endPoint": "https://oss-cn-shanghai.aliyuncs.com",
|
||||||
|
"accessKeyId": "",
|
||||||
|
"accessKeySecret": "",
|
||||||
|
"bucketName": "zy-irc-test-store",
|
||||||
|
"roleArn": "acs:ram::1899121822495495:role/oss-upload",
|
||||||
|
"viewEndpoint": "https://zy-irc-test-store.oss-cn-shanghai.aliyuncs.com",
|
||||||
|
"region": "oss-cn-shanghai"
|
||||||
|
},
|
||||||
|
|
||||||
|
"MinIO": {
|
||||||
|
"endPoint": "44.210.231.169",
|
||||||
|
"port": "9001",
|
||||||
|
"useSSL": false,
|
||||||
|
"accessKey": "e9bT1isTOqSAUxb6wd4n",
|
||||||
|
"secretKey": "b5TaDzNdQCBtCvfm8eZ3dR6yY7tfZu2JYze2Po1i",
|
||||||
|
"bucketName": "prod-irc-us",
|
||||||
|
"viewEndpoint": "http://44.210.231.169:9001/prod-irc-us/"
|
||||||
|
},
|
||||||
|
|
||||||
|
"AWS": {
|
||||||
|
"endPoint": "s3.us-east-1.amazonaws.com",
|
||||||
|
"useSSL": true,
|
||||||
|
"accessKey": "AKIAW3MEAFJX5P32P6NA",
|
||||||
|
"secretKey": "soKfYlzZE11Zi4RyTjXp0myXN0U3U+ka8rT49+B/",
|
||||||
|
"bucketName": "ei-med-s3-lili-store",
|
||||||
|
"viewEndpoint": "https://ei-med-s3-lili-store.s3.amazonaws.com/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"BasicSystemConfig": {
|
||||||
|
|
||||||
|
"OpenUserComplexPassword": false,
|
||||||
|
|
||||||
|
"OpenSignDocumentBeforeWork": false,
|
||||||
|
|
||||||
|
"OpenTrialRelationDelete": true,
|
||||||
|
|
||||||
|
"OpenLoginLimit": false,
|
||||||
|
|
||||||
|
"LoginMaxFailCount": 5,
|
||||||
|
|
||||||
|
"LoginFailLockMinutes": 30,
|
||||||
|
"AutoLoginOutMinutes": 60,
|
||||||
|
|
||||||
|
"ContinuousReadingTimeMin": 120,
|
||||||
|
|
||||||
|
"ReadingRestTimeMin": 10
|
||||||
|
},
|
||||||
|
|
||||||
|
"SystemEmailSendConfig": {
|
||||||
|
"Port": 587,
|
||||||
|
"Host": "smtp-mail.outlook.com",
|
||||||
|
"FromEmail": "donotreply@elevateimaging.ai",
|
||||||
|
"FromName": "LiLi",
|
||||||
|
"AuthorizationCode": "Q#669869497420ul",
|
||||||
|
|
||||||
|
"OrganizationName": "Elevate Imaging",
|
||||||
|
"OrganizationNameCN": "Elevate Imaging",
|
||||||
|
"CompanyName": "Elevate Imaging Inc.",
|
||||||
|
"CompanyNameCN": "上海展影医疗科技有限公司",
|
||||||
|
"CompanyShortName": "Elevate Imaging",
|
||||||
|
"CompanyShortNameCN": "展影医疗",
|
||||||
|
"SiteUrl": "https://lili.elevateimaging.ai/login"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft": "Warning",
|
||||||
|
"Microsoft.Hosting.Lifetime": "Information"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ConnectionStrings": {
|
||||||
|
"RemoteNew": "Server=106.14.89.110,1435;Database=Test_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
|
||||||
|
"Hangfire": "Server=106.14.89.110,1435;Database=Test_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
|
||||||
|
},
|
||||||
|
|
||||||
|
"ObjectStoreService": {
|
||||||
|
|
||||||
|
"ObjectStoreUse": "MinIO",
|
||||||
|
"AliyunOSS": {
|
||||||
|
"regionId": "cn-shanghai",
|
||||||
|
"endPoint": "https://oss-cn-shanghai.aliyuncs.com",
|
||||||
|
"accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ",
|
||||||
|
"accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio",
|
||||||
|
"bucketName": "zy-irc-test-store",
|
||||||
|
"roleArn": "acs:ram::1899121822495495:role/oss-upload",
|
||||||
|
"viewEndpoint": "https://zy-irc-test-store.oss-cn-shanghai.aliyuncs.com",
|
||||||
|
"region": "oss-cn-shanghai"
|
||||||
|
},
|
||||||
|
|
||||||
|
"MinIO": {
|
||||||
|
//"endPoint": "hir-oss.uat.extimaging.com",
|
||||||
|
//"port": "443",
|
||||||
|
//"useSSL": true,
|
||||||
|
//"viewEndpoint": "https://hir-oss.uat.extimaging.com/hir-uat",
|
||||||
|
|
||||||
|
"endPoint": "47.117.164.182",
|
||||||
|
"port": "9001",
|
||||||
|
"useSSL": false,
|
||||||
|
"viewEndpoint": "http://47.117.164.182:9001/test-irc-us",
|
||||||
|
|
||||||
|
"accessKey": "b9Ul0e98xPzt6PwRXA1Q",
|
||||||
|
"secretKey": "DzMaU2L4OXl90uytwOmDXF2encN0Jf4Nxu2XkYqQ",
|
||||||
|
"bucketName": "test-irc-us"
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
"AWS": {
|
||||||
|
"endPoint": "s3.us-east-1.amazonaws.com",
|
||||||
|
"useSSL": true,
|
||||||
|
"accessKey": "AKIAZQ3DRSOHFPJJ6FEU",
|
||||||
|
"secretKey": "l+yjtvV7Z4jiwm/7xCYv30UeUj/SvuqqYzAwjJHf",
|
||||||
|
"bucketName": "ei-irc-test-store",
|
||||||
|
"viewEndpoint": "https://ei-irc-test-store.s3.amazonaws.com/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"BasicSystemConfig": {
|
||||||
|
|
||||||
|
"OpenUserComplexPassword": false,
|
||||||
|
|
||||||
|
"OpenSignDocumentBeforeWork": false,
|
||||||
|
|
||||||
|
"OpenTrialRelationDelete": true,
|
||||||
|
|
||||||
|
"OpenLoginLimit": false,
|
||||||
|
|
||||||
|
"LoginMaxFailCount": 5,
|
||||||
|
|
||||||
|
"LoginFailLockMinutes": 30,
|
||||||
|
"AutoLoginOutMinutes": 60,
|
||||||
|
|
||||||
|
"ContinuousReadingTimeMin": 120,
|
||||||
|
|
||||||
|
"ReadingRestTimeMin": 10
|
||||||
|
},
|
||||||
|
|
||||||
|
"SystemEmailSendConfig": {
|
||||||
|
"Port": 587,
|
||||||
|
"Host": "smtp-mail.outlook.com",
|
||||||
|
"FromEmail": "donotreply@elevateimaging.ai",
|
||||||
|
"FromName": "LiLi",
|
||||||
|
"AuthorizationCode": "Q#669869497420ul",
|
||||||
|
|
||||||
|
"OrganizationName": "Elevate Imaging",
|
||||||
|
"OrganizationNameCN": "Elevate Imaging",
|
||||||
|
"CompanyName": "Elevate Imaging Inc.",
|
||||||
|
"CompanyNameCN": "上海展影医疗科技有限公司",
|
||||||
|
"CompanyShortName": "Elevate Imaging",
|
||||||
|
"CompanyShortNameCN": "展影医疗",
|
||||||
|
"SiteUrl": "https://lili.test.elevateimaging.ai/login"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft": "Warning",
|
||||||
|
"Microsoft.Hosting.Lifetime": "Information"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ConnectionStrings": {
|
||||||
|
"RemoteNew": "Server=us-mssql-service,1433;Database=US_Uat_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
|
||||||
|
"Hangfire": "Server=us-mssql-service,1433;Database=US_Uat_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
|
||||||
|
|
||||||
|
//"RemoteNew": "Server=44.218.11.19,1435;Database=Prod_US_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
|
||||||
|
//"Hangfire": "Server=44.218.11.19,1435;Database=Prod_US_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
|
||||||
|
},
|
||||||
|
|
||||||
|
"ObjectStoreService": {
|
||||||
|
|
||||||
|
"ObjectStoreUse": "MinIO",
|
||||||
|
|
||||||
|
"AliyunOSS": {
|
||||||
|
"regionId": "cn-shanghai",
|
||||||
|
"endPoint": "https://oss-cn-shanghai.aliyuncs.com",
|
||||||
|
"accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ",
|
||||||
|
"accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio",
|
||||||
|
"bucketName": "zy-irc-test-store",
|
||||||
|
"roleArn": "acs:ram::1899121822495495:role/oss-upload",
|
||||||
|
"viewEndpoint": "https://zy-irc-test-store.oss-cn-shanghai.aliyuncs.com",
|
||||||
|
"region": "oss-cn-shanghai"
|
||||||
|
},
|
||||||
|
|
||||||
|
"MinIO": {
|
||||||
|
//"endPoint": "hir-oss.us.extimaging.com",
|
||||||
|
//"port": "443",
|
||||||
|
//"useSSL": true,
|
||||||
|
//"viewEndpoint": "https://hir-oss.us.extimaging.com/hir-us",
|
||||||
|
|
||||||
|
"endPoint": "44.218.11.19",
|
||||||
|
"port": "9001",
|
||||||
|
"useSSL": false,
|
||||||
|
"viewEndpoint": "http://44.218.11.19:9001/uat-irc-us",
|
||||||
|
|
||||||
|
"accessKey": "lH8DkKskLuDqPaiubuSQ",
|
||||||
|
"secretKey": "pdPdicvvLeH7xAC5yFUrI7odMyBfOXxvVWMvKYV4",
|
||||||
|
"bucketName": "uat-irc-us"
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
"AWS": {
|
||||||
|
"endPoint": "s3.us-east-1.amazonaws.com",
|
||||||
|
"useSSL": true,
|
||||||
|
"accessKey": "AKIAZQ3DRSOHFPJJ6FEU",
|
||||||
|
"secretKey": "l+yjtvV7Z4jiwm/7xCYv30UeUj/SvuqqYzAwjJHf",
|
||||||
|
"bucketName": "ei-irc-test-store",
|
||||||
|
"viewEndpoint": "https://ei-irc-test-store.s3.amazonaws.com/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"BasicSystemConfig": {
|
||||||
|
|
||||||
|
"OpenUserComplexPassword": false,
|
||||||
|
|
||||||
|
"OpenSignDocumentBeforeWork": false,
|
||||||
|
|
||||||
|
"OpenTrialRelationDelete": true,
|
||||||
|
|
||||||
|
"OpenLoginLimit": false,
|
||||||
|
|
||||||
|
"LoginMaxFailCount": 5,
|
||||||
|
|
||||||
|
"LoginFailLockMinutes": 30,
|
||||||
|
"AutoLoginOutMinutes": 60,
|
||||||
|
|
||||||
|
"ContinuousReadingTimeMin": 120,
|
||||||
|
|
||||||
|
"ReadingRestTimeMin": 10
|
||||||
|
},
|
||||||
|
|
||||||
|
"SystemEmailSendConfig": {
|
||||||
|
"Port": 587,
|
||||||
|
"Host": "smtp-mail.outlook.com",
|
||||||
|
"FromEmail": "donotreply@elevateimaging.ai",
|
||||||
|
"FromName": "LiLi",
|
||||||
|
"AuthorizationCode": "Q#669869497420ul",
|
||||||
|
|
||||||
|
"OrganizationName": "Elevate Imaging",
|
||||||
|
"OrganizationNameCN": "Elevate Imaging",
|
||||||
|
"CompanyName": "Elevate Imaging Inc.",
|
||||||
|
"CompanyNameCN": "上海展影医疗科技有限公司",
|
||||||
|
"CompanyShortName": "Elevate Imaging",
|
||||||
|
"CompanyShortNameCN": "展影医疗",
|
||||||
|
"SiteUrl": "https://lili.test.elevateimaging.ai/login"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft": "Warning",
|
||||||
|
"Microsoft.Hosting.Lifetime": "Information"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ConnectionStrings": {
|
||||||
|
"RemoteNew": "Server=47.117.164.182,1434;Database=Uat_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
|
||||||
|
"Hangfire": "Server=47.117.164.182,1434;Database=Uat_IRC.Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
|
||||||
|
},
|
||||||
|
"ObjectStoreService": {
|
||||||
|
|
||||||
|
"ObjectStoreUse": "AliyunOSS",
|
||||||
|
|
||||||
|
"AliyunOSS": {
|
||||||
|
"regionId": "cn-shanghai",
|
||||||
|
"endpoint": "https://oss-cn-shanghai.aliyuncs.com",
|
||||||
|
"accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ",
|
||||||
|
"accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio",
|
||||||
|
"bucketName": "zy-irc-uat-store",
|
||||||
|
"roleArn": "acs:ram::1899121822495495:role/oss-upload",
|
||||||
|
"viewEndpoint": "https://zy-irc-uat-store.oss-cn-shanghai.aliyuncs.com",
|
||||||
|
"region": "oss-cn-shanghai"
|
||||||
|
},
|
||||||
|
|
||||||
|
"MinIO": {
|
||||||
|
"endPoint": "hir-oss.uat.extimaging.com",
|
||||||
|
//"port": "80",
|
||||||
|
//"useSSL": false,
|
||||||
|
//"viewEndpoint": "http://hir-oss.uat.extimaging.com/irc-uat",
|
||||||
|
"port": "443",
|
||||||
|
"useSSL": true,
|
||||||
|
"viewEndpoint": "https://hir-oss.uat.extimaging.com/irc-uat",
|
||||||
|
"accessKey": "b9Ul0e98xPzt6PwRXA1Q",
|
||||||
|
"secretKey": "DzMaU2L4OXl90uytwOmDXF2encN0Jf4Nxu2XkYqQ",
|
||||||
|
"bucketName": "irc-uat"
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"BasicSystemConfig": {
|
||||||
|
|
||||||
|
"OpenUserComplexPassword": true,
|
||||||
|
|
||||||
|
"OpenSignDocumentBeforeWork": true,
|
||||||
|
|
||||||
|
"OpenLoginLimit": true,
|
||||||
|
"LoginMaxFailCount": 5,
|
||||||
|
|
||||||
|
"LoginFailLockMinutes": 30,
|
||||||
|
"AutoLoginOutMinutes": 60,
|
||||||
|
"OpenLoginMFA": false,
|
||||||
|
|
||||||
|
"ContinuousReadingTimeMin": 120,
|
||||||
|
|
||||||
|
"ReadingRestTimeMin": 10
|
||||||
|
|
||||||
|
},
|
||||||
|
"SystemEmailSendConfig": {
|
||||||
|
"Port": 465,
|
||||||
|
"Host": "smtp.qiye.aliyun.com",
|
||||||
|
"FromEmail": "uat@extimaging.com",
|
||||||
|
"FromName": "UAT_IRC",
|
||||||
|
"AuthorizationCode": "SHzyyl2021",
|
||||||
|
"SiteUrl": "http://irc.uat.extimaging.com/login",
|
||||||
|
"OrganizationName": "Extlmaging",
|
||||||
|
"OrganizationNameCN": "Extlmaging",
|
||||||
|
"CompanyName": "Extensive Imaging",
|
||||||
|
"CompanyNameCN": "上海展影医疗科技有限公司",
|
||||||
|
"CompanyShortName": "Extensive Imaging",
|
||||||
|
"CompanyShortNameCN": "展影医疗"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"JwtSetting": {
|
"JwtSetting": {
|
||||||
"SecurityKey": "3e6dbfa227234a03977a2f421bdb7f4f",
|
"SecurityKey": "ShangHaiZhanYing_SecurityKey_SHzyyl@2021",
|
||||||
"Issuer": "IRaCIS",
|
"Issuer": "Extimaging",
|
||||||
"Audience": "ZhiZhun",
|
"Audience": "EICS",
|
||||||
"TokenExpireDays": "7"
|
"TokenExpireDays": "7"
|
||||||
},
|
},
|
||||||
"IpRateLimiting": {
|
"IpRateLimiting": {
|
||||||
@@ -55,6 +55,26 @@
|
|||||||
"EnableReadDeepClone": true,
|
"EnableReadDeepClone": true,
|
||||||
"EnableWriteDeepClone": false
|
"EnableWriteDeepClone": false
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"redis": {
|
||||||
|
"MaxRdSecond": 120,
|
||||||
|
"EnableLogging": false,
|
||||||
|
"LockMs": 5000,
|
||||||
|
"SleepMs": 300,
|
||||||
|
"dbconfig": {
|
||||||
|
"Password": "xc@123456",
|
||||||
|
"IsSsl": false,
|
||||||
|
"SslHost": null,
|
||||||
|
"ConnectionTimeout": 5000,
|
||||||
|
"AllowAdmin": true,
|
||||||
|
"Endpoints": [
|
||||||
|
{
|
||||||
|
"Host": "47.117.164.182",
|
||||||
|
"Port": 6379
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Database": 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"IRaCISImageStore": {
|
"IRaCISImageStore": {
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
尊敬的 {0} ,您好:
|
尊敬的 {0} ,您好:
|
||||||
</div>
|
</div>
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||||
展影医疗为您添加了账户,账户信息如下:
|
{company abbreviation}为您添加了账户,账户信息如下:
|
||||||
</div>
|
</div>
|
||||||
<span style="color: #00D1B2"></span>
|
<span style="color: #00D1B2"></span>
|
||||||
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
|
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
首次登陆前,请通过该链接修改您的账户信息:
|
首次登陆前,请通过该链接修改您的账户信息:
|
||||||
<a href='{3}' style='margin-left:30px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
|
<a href='{3}' style='margin-left:1px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
|
||||||
初始化账号信息
|
初始化账号信息
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -31,8 +31,8 @@
|
|||||||
|
|
||||||
|
|
||||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
||||||
<div>祝您顺利!/Best Regards</div>
|
<div>祝您顺利!</div>
|
||||||
<div style="font-size: 14px;">上海展影医疗科技有限公司</div>
|
<div style="font-size: 14px;">{company}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -11,28 +11,28 @@
|
|||||||
Dear {0} ,
|
Dear {0} ,
|
||||||
</div>
|
</div>
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||||
Extimaging has added an account for you. The account information is as follows:
|
{company abbreviation} has created an account for you. The account information is as follows:
|
||||||
</div>
|
</div>
|
||||||
<span style="color: #00D1B2"></span>
|
<span style="color: #00D1B2"></span>
|
||||||
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
|
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
|
||||||
<div>
|
<div>
|
||||||
User name: {1}
|
User ID: {1}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
Role: {2}
|
Role: {2}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
Before logging in for the first time, please modify your account information by this link:
|
Before logging in for the first time, please modify the account information through this link:
|
||||||
<a href='{3}' style='margin-left:30px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
|
<a href='{3}' style='margin-left:1px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
|
||||||
Initialize the account information
|
Initialize account information
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
||||||
<div>Best Regards</div>
|
<div>Best regards,</div>
|
||||||
<div style="font-size: 14px;">Shanghai Extensive Imaging Medical Technology Co., LTD</div>
|
<div style="font-size: 14px;">{company}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
尊敬的 {0} ,您好:
|
尊敬的 {0} ,您好:
|
||||||
</div>
|
</div>
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||||
展影医疗将您的账户密码已重置,账户信息如下:
|
{company abbreviation}将您的账户密码已重置,账户信息如下:
|
||||||
</div>
|
</div>
|
||||||
<span style="color: #00D1B2"></span>
|
<span style="color: #00D1B2"></span>
|
||||||
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
|
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
|
||||||
@@ -28,8 +28,8 @@
|
|||||||
|
|
||||||
|
|
||||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
||||||
<div>祝您顺利!/Best Regards</div>
|
<div>祝您顺利!</div>
|
||||||
<div style="font-size: 14px;">上海展影医疗科技有限公司</div>
|
<div style="font-size: 14px;">{company}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -11,12 +11,12 @@
|
|||||||
Dear {0} ,
|
Dear {0} ,
|
||||||
</div>
|
</div>
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||||
Extimaging has reset your account password, and the account information is as follows:
|
{company abbreviation} has reset your account password, and the account information is as follows:
|
||||||
</div>
|
</div>
|
||||||
<span style="color: #00D1B2"></span>
|
<span style="color: #00D1B2"></span>
|
||||||
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
|
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
|
||||||
<div>
|
<div>
|
||||||
User name: {1}
|
User ID: {1}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
Role: {2}
|
Role: {2}
|
||||||
@@ -28,8 +28,8 @@
|
|||||||
|
|
||||||
|
|
||||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
||||||
<div>Best Regards</div>
|
<div>Best regards,</div>
|
||||||
<div style="font-size: 14px;">Shanghai Extensive Imaging Medical Technology Co., LTD</div>
|
<div style="font-size: 14px;">{company}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,27 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang='en'>
|
|
||||||
<head>
|
|
||||||
<meta charset='UTF-8'>
|
|
||||||
<title>Title</title>
|
|
||||||
</head>
|
|
||||||
<body style='font-family: 微软雅黑;padding: 0;margin: 0;'>
|
|
||||||
<div style='padding-left: 40px;background: #f6f6f6'>
|
|
||||||
<div style='padding-top: 20px;'>
|
|
||||||
<div style='line-height: 40px;font-size: 18px'>
|
|
||||||
您好:
|
|
||||||
</div>
|
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
|
||||||
感谢您使用展影云平台。
|
|
||||||
</div>
|
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
|
||||||
{0}。
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
|
||||||
<div>祝您顺利!/Best Regards</div>
|
|
||||||
<div style="font-size: 14px;">上海展影医疗科技有限公司</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang='en'>
|
|
||||||
<head>
|
|
||||||
<meta charset='UTF-8'>
|
|
||||||
<title>Title</title>
|
|
||||||
</head>
|
|
||||||
<body style='font-family: 微软雅黑;padding: 0;margin: 0;'>
|
|
||||||
<div style='padding-left: 40px;background: #f6f6f6'>
|
|
||||||
<div style='padding-top: 20px;'>
|
|
||||||
<div style='line-height: 40px;font-size: 18px'>
|
|
||||||
Dear:
|
|
||||||
</div>
|
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
|
||||||
Thank you for using Extensive Imaging Cloud System.
|
|
||||||
</div>
|
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
|
||||||
{0}。
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
|
||||||
<div>Best Regards</div>
|
|
||||||
<div style="font-size: 14px;">Shanghai Extensive Imaging Medical Technology Co., LTD</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -18,8 +18,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
||||||
<div>祝您顺利!/Best Regards</div>
|
<div>祝您顺利!</div>
|
||||||
<div style="font-size: 14px;">上海展影医疗科技有限公司</div>
|
<div style="font-size: 14px;">{company}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -11,15 +11,15 @@
|
|||||||
Dear:
|
Dear:
|
||||||
</div>
|
</div>
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||||
Thank you for using Extensive Imaging Cloud System.
|
Thank you for using {company abbreviation} Cloud System.
|
||||||
</div>
|
</div>
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||||
{0}。
|
{0}。
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
||||||
<div>Best Regards</div>
|
<div>Best regards,</div>
|
||||||
<div style="font-size: 14px;">Shanghai Extensive Imaging Medical Technology Co., LTD</div>
|
<div style="font-size: 14px;">{company}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
尊敬的 {0} ,您好:
|
尊敬的 {0} ,您好:
|
||||||
</div>
|
</div>
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||||
展影医疗作为 [{1} (试验方案号:{2 })] 项目的IRC供应商,诚邀您参加该项目IRC阅片相关工作,欢迎您提供指导和建议,非常感谢!
|
{company abbreviation}作为 [{1} (试验方案号:{2 })] 项目的供应商,诚邀您参加该项目阅片相关工作。
|
||||||
</div>
|
</div>
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||||
该项目采用电子化工作流,系统及您的账号信息如下:
|
该项目采用电子化工作流,系统及您的账号信息如下:
|
||||||
@@ -34,14 +34,16 @@
|
|||||||
角色: {5}
|
角色: {5}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
系统登录地址:{6}
|
系统登录地址:
|
||||||
|
<a href='{6}' style='margin-left:1px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
|
||||||
|
点击跳转
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
||||||
<div>祝您顺利!/Best Regards</div>
|
<div>祝您顺利!</div>
|
||||||
<div style="font-size: 14px;">上海展影医疗科技有限公司</div>
|
<div style="font-size: 14px;">{company}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -10,11 +10,11 @@
|
|||||||
<div style='line-height: 40px;font-size: 18px'>
|
<div style='line-height: 40px;font-size: 18px'>
|
||||||
Dear {0},
|
Dear {0},
|
||||||
</div>
|
</div>
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
|
||||||
Hello, as the IRC supplier of [ {1} (Protocol ID is {2}) ] project,Extiming sincerely invites you to participate in the IRC related work of this project. Your guidance and suggestions are welcome.
|
{company abbreviation} invites you to participate in the IRC work of a trial ({1} , {2}).
|
||||||
</div>
|
</div>
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||||
This project adopts electronic workflow. The system and your account information are as follows:
|
Your account information is as follows:
|
||||||
</div>
|
</div>
|
||||||
<span style="color: #00D1B2"></span>
|
<span style="color: #00D1B2"></span>
|
||||||
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
|
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
|
||||||
@@ -25,23 +25,26 @@
|
|||||||
Protocol ID: {2}
|
Protocol ID: {2}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
Study name: {1}
|
Study Name: {1}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
User name: {4}
|
User ID: {4}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
Role: {5}
|
Role: {5}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
System login address:{6}
|
Login URL:
|
||||||
|
<a href='{6}' style='margin-left:1px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
|
||||||
|
Click to login
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
||||||
<div>Best Regards</div>
|
<div>Best regards,</div>
|
||||||
<div style="font-size: 14px;">Shanghai Extensive Imaging Medical Technology Co., LTD</div>
|
<div style="font-size: 14px;">{company}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
尊敬的 {0} ,您好:
|
尊敬的 {0} ,您好:
|
||||||
</div>
|
</div>
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||||
展影医疗作为 [{1} (试验方案号:{2 })] 项目的IRC供应商,诚邀您参加该项目IRC阅片相关工作,欢迎您提供指导和建议,非常感谢!
|
{company abbreviation}作为 [{1} (试验方案号:{2 })] 项目的IRC供应商,诚邀您参加该项目IRC阅片相关工作,欢迎您提供指导和建议,非常感谢!
|
||||||
</div>
|
</div>
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||||
该项目采用电子化工作流,系统及您的账号信息如下:
|
该项目采用电子化工作流,系统及您的账号信息如下:
|
||||||
@@ -35,7 +35,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
首次登陆前,请通过该链接修改您的账户信息:
|
首次登陆前,请通过该链接修改您的账户信息:
|
||||||
<a href='{6}' style='margin-left:30px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
|
<a href='{6}' style='margin-left:1px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
|
||||||
初始化账号信息
|
初始化账号信息
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -43,8 +43,8 @@
|
|||||||
|
|
||||||
|
|
||||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
||||||
<div>祝您顺利!/Best Regards</div>
|
<div>祝您顺利!</div>
|
||||||
<div style="font-size: 14px;">上海展影医疗科技有限公司</div>
|
<div style="font-size: 14px;">{company}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -11,10 +11,10 @@
|
|||||||
Dear {0},
|
Dear {0},
|
||||||
</div>
|
</div>
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||||
Hello, as the IRC supplier of [ {1} (Protocol ID is {2}) ] project,Extiming sincerely invites you to participate in the IRC related work of this project. Your guidance and suggestions are welcome.
|
{company abbreviation} invites you to participate in the IRC work of a trial ({1}, {2}).
|
||||||
</div>
|
</div>
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||||
This project adopts electronic workflow. The system and your account information are as follows:
|
Your account information is as follows:
|
||||||
</div>
|
</div>
|
||||||
<span style="color: #00D1B2"></span>
|
<span style="color: #00D1B2"></span>
|
||||||
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
|
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
|
||||||
@@ -25,26 +25,26 @@
|
|||||||
Protocol ID: {2}
|
Protocol ID: {2}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
Study name: {1}
|
Study Name: {1}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
User name: {4}
|
User ID: {4}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
Role: {5}
|
Role: {5}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
Before logging in for the first time, please modify your account information by this link:
|
Before logging in for the first time, please modify the account information through this link:
|
||||||
<a href='{6}' style='margin-left:30px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
|
<a href='{6}' style='margin-left:1px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
|
||||||
Initialize the account information
|
Initialize account information
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
||||||
<div>Best Regards</div>
|
<div>Best regards,</div>
|
||||||
<div style="font-size: 14px;">Shanghai Extensive Imaging Medical Technology Co., LTD</div>
|
<div style="font-size: 14px;">{company}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
尊敬的 {0} ,您好:
|
尊敬的 {0} ,您好:
|
||||||
</div>
|
</div>
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||||
您好, 您填写的中心调研表被驳回,详细信息如下:
|
您填写的中心调研表被驳回,详细信息如下:
|
||||||
</div>
|
</div>
|
||||||
<span style="color: #00D1B2"></span>
|
<span style="color: #00D1B2"></span>
|
||||||
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
|
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
|
||||||
@@ -40,8 +40,8 @@
|
|||||||
</a>
|
</a>
|
||||||
|
|
||||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
||||||
<div>祝您顺利!/Best Regards</div>
|
<div>祝您顺利!</div>
|
||||||
<div style="font-size: 14px;">上海展影医疗科技有限公司</div>
|
<div style="font-size: 14px;">{company}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
Dear {0} ,
|
Dear {0} ,
|
||||||
</div>
|
</div>
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||||
Hello, the center survey form you filled in has been rejected. The details are as follows:
|
The site survey form you filled in has been rejected. The details are as follows:
|
||||||
</div>
|
</div>
|
||||||
<span style="color: #00D1B2"></span>
|
<span style="color: #00D1B2"></span>
|
||||||
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
|
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
Protocol ID: {2}
|
Protocol ID: {2}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
Study name: {3}
|
Study Name: {3}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
Site ID: {4}
|
Site ID: {4}
|
||||||
@@ -40,8 +40,8 @@
|
|||||||
</a>
|
</a>
|
||||||
|
|
||||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
||||||
<div>Best Regards</div>
|
<div>Best regards,</div>
|
||||||
<div style="font-size: 14px;">Shanghai Extensive Imaging Medical Technology Co., LTD</div>
|
<div style="font-size: 14px;">{company}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
尊敬的 {0} ,您好:
|
尊敬的 {0} ,您好:
|
||||||
</div>
|
</div>
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||||
展影医疗作为 [{1} (试验方案号:{2 })] 项目的IRC供应商,诚邀您参加该项目IRC相关工作,欢迎您提供指导和建议,非常感谢!
|
{company abbreviation}作为 [{1} (试验方案号:{2 })] 项目的供应商,诚邀您参加该项目相关工作,欢迎您提供指导和建议,非常感谢!
|
||||||
</div>
|
</div>
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||||
该项目采用电子化工作流,系统及您的账号信息如下:
|
该项目采用电子化工作流,系统及您的账号信息如下:
|
||||||
@@ -34,14 +34,17 @@
|
|||||||
角色: {5}
|
角色: {5}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
系统登录地址:{6}
|
系统登录地址:
|
||||||
|
<a href='{6}' style='margin-left:5px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
|
||||||
|
点击跳转
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
||||||
<div>祝您顺利!/Best Regards</div>
|
<div>祝您顺利!</div>
|
||||||
<div style="font-size: 14px;">上海展影医疗科技有限公司</div>
|
<div style="font-size: 14px;">{company}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -10,11 +10,11 @@
|
|||||||
<div style='line-height: 40px;font-size: 18px'>
|
<div style='line-height: 40px;font-size: 18px'>
|
||||||
Dear {0},
|
Dear {0},
|
||||||
</div>
|
</div>
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
|
||||||
Hello, as the IRC supplier of [ {1} (Protocol ID is {2}) ] project,Extiming sincerely invites you to participate in the IRC related work of this project. Your guidance and suggestions are welcome.
|
{company abbreviation} invites you to participate in the IRC work of a trial ({1}, {2}).
|
||||||
</div>
|
</div>
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||||
This project adopts electronic workflow. The system and your account information are as follows:
|
Your account information is as follows:
|
||||||
</div>
|
</div>
|
||||||
<span style="color: #00D1B2"></span>
|
<span style="color: #00D1B2"></span>
|
||||||
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
|
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
|
||||||
@@ -25,23 +25,26 @@
|
|||||||
Protocol ID: {2}
|
Protocol ID: {2}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
Study name: {1}
|
Study Name: {1}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
User name: {4}
|
User ID: {4}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
Role: {5}
|
Role: {5}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
System login address:{6}
|
Login URL:
|
||||||
|
<a href='{6}' style='margin-left:1px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
|
||||||
|
Click to login
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
||||||
<div>Best Regards</div>
|
<div>Best regards,</div>
|
||||||
<div style="font-size: 14px;">Shanghai Extensive Imaging Medical Technology Co., LTD</div>
|
<div style="font-size: 14px;">{company}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
尊敬的 {0} ,您好:
|
尊敬的 {0} ,您好:
|
||||||
</div>
|
</div>
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||||
展影医疗作为 [{1} (试验方案号:{2 })] 项目的IRC供应商,诚邀您参加该项目IRC相关工作,欢迎您提供指导和建议,非常感谢!
|
{company abbreviation}作为 [{1} (试验方案号:{2 })] 项目的IRC供应商,诚邀您参加该项目IRC相关工作,欢迎您提供指导和建议,非常感谢!
|
||||||
</div>
|
</div>
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||||
该项目采用电子化工作流,系统及您的账号信息如下:
|
该项目采用电子化工作流,系统及您的账号信息如下:
|
||||||
@@ -35,7 +35,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
首次登陆前,请通过该链接修改您的账户信息:
|
首次登陆前,请通过该链接修改您的账户信息:
|
||||||
<a href='{6}' style='margin-left:30px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
|
<a href='{6}' style='margin-left:1px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
|
||||||
初始化账号信息
|
初始化账号信息
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -43,8 +43,8 @@
|
|||||||
|
|
||||||
|
|
||||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
||||||
<div>祝您顺利!/Best Regards</div>
|
<div>祝您顺利!</div>
|
||||||
<div style="font-size: 14px;">上海展影医疗科技有限公司</div>
|
<div style="font-size: 14px;">{company}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -11,10 +11,10 @@
|
|||||||
Dear {0},
|
Dear {0},
|
||||||
</div>
|
</div>
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||||
Hello, as the IRC supplier of [ {1} (Protocol ID is {2}) ] project,Extiming sincerely invites you to participate in the IRC related work of this project. Your guidance and suggestions are welcome.
|
{company abbreviation} invites you to participate in the IRC work of a trial ({1}, {2}).
|
||||||
</div>
|
</div>
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||||
This project adopts electronic workflow. The system and your account information are as follows:
|
Your account information is as follows:
|
||||||
</div>
|
</div>
|
||||||
<span style="color: #00D1B2"></span>
|
<span style="color: #00D1B2"></span>
|
||||||
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
|
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
|
||||||
@@ -25,17 +25,17 @@
|
|||||||
Protocol ID: {2}
|
Protocol ID: {2}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
Study name: {1}
|
Study Name: {1}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
User name: {4}
|
User ID: {4}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
Role: {5}
|
Role: {5}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
Before logging in for the first time, please modify your account information by this link:
|
Before logging in for the first time, please modify the account information through this link:
|
||||||
<a href='{6}' style='margin-left:30px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
|
<a href='{6}' style='margin-left:1px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
|
||||||
Initialize the account information
|
Initialize the account information
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -43,8 +43,8 @@
|
|||||||
|
|
||||||
|
|
||||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
||||||
<div>Best Regards</div>
|
<div>Best regards,</div>
|
||||||
<div style="font-size: 14px;">Shanghai Extensive Imaging Medical Technology Co., LTD</div>
|
<div style="font-size: 14px;">{company}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -8,18 +8,20 @@
|
|||||||
<div style='padding-left: 40px;background: #f6f6f6'>
|
<div style='padding-left: 40px;background: #f6f6f6'>
|
||||||
<div style='padding-top: 20px;'>
|
<div style='padding-top: 20px;'>
|
||||||
<div style='line-height: 40px;font-size: 18px'>
|
<div style='line-height: 40px;font-size: 18px'>
|
||||||
Dear {0},
|
{0}您好,
|
||||||
</div>
|
</div>
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||||
感谢您使用展影云平台。
|
感谢您使用展影云平台。
|
||||||
</div>
|
</div>
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||||
{1},验证码是: {2},请在3分钟内输入该验证码,进行后续操作。如非本人操作,请忽略该邮件。
|
{1},验证码是: <span style="font-weight:bold">{2}</span>。
|
||||||
|
</div>
|
||||||
|
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||||
|
请在3分钟内输入该验证码,进行后续操作
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
||||||
<div>祝您顺利!/Best Regards</div>
|
<div>祝您顺利!</div>
|
||||||
<div style="font-size: 14px;">上海展影医疗科技有限公司</div>
|
<div style="font-size: 14px;">{company}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -11,16 +11,18 @@
|
|||||||
Dear {0},
|
Dear {0},
|
||||||
</div>
|
</div>
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||||
Thank you for using Extensive Imaging Cloud System.
|
{1}
|
||||||
</div>
|
</div>
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||||
{1}, the verification code is {2}. Enter the verification code within 3 minutes for subsequent operations. Please ignore this email if not by yourself.
|
The verification code is <span style="font-weight:bold">{2}</span>.
|
||||||
|
</div>
|
||||||
|
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||||
|
This code will expire in 3 minutes.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
||||||
<div>Best Regards</div>
|
<div>Best regards,</div>
|
||||||
<div style="font-size: 14px;">Shanghai Extensive Imaging Medical Technology Co., LTD</div>
|
<div style="font-size: 14px;">{company}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Binary file not shown.
@@ -276,8 +276,10 @@ var abp = abp || {};
|
|||||||
}
|
}
|
||||||
|
|
||||||
var password = document.getElementById('password').value;
|
var password = document.getElementById('password').value;
|
||||||
if (!password) {
|
var pwdMd5 = document.getElementById('pwdMd5').value;
|
||||||
alert('PassWord Can Not Be Null');
|
console.log(pwdMd5);
|
||||||
|
if (!password && !pwdMd5) {
|
||||||
|
alert('PassWord And Md5 Can Not Be Null');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -321,6 +323,9 @@ var abp = abp || {};
|
|||||||
UserName: usernameOrEmailAddress,
|
UserName: usernameOrEmailAddress,
|
||||||
Password: hex_md5(password),
|
Password: hex_md5(password),
|
||||||
}
|
}
|
||||||
|
if (pwdMd5 != '') {
|
||||||
|
parm.Password = pwdMd5;
|
||||||
|
}
|
||||||
xhr.send(JSON.stringify(parm));
|
xhr.send(JSON.stringify(parm));
|
||||||
//xhr.send("{" + "userName:'" + usernameOrEmailAddress + "'," + "passWord:'" + password + "'}");
|
//xhr.send("{" + "userName:'" + usernameOrEmailAddress + "'," + "passWord:'" + password + "'}");
|
||||||
|
|
||||||
@@ -414,8 +419,9 @@ var abp = abp || {};
|
|||||||
|
|
||||||
//Inputs
|
//Inputs
|
||||||
createInput(modalUxContent, 'tenancyName', 'Tenancy Name (Leave empty for Host)');
|
createInput(modalUxContent, 'tenancyName', 'Tenancy Name (Leave empty for Host)');
|
||||||
createInput(modalUxContent, 'userName', 'Username or email address','text','admin');
|
createInput(modalUxContent, 'userName', 'Username or email address','text','cyldev');
|
||||||
createInput(modalUxContent, 'password', 'Password','password');
|
createInput(modalUxContent, 'password', 'Password', 'password', '123456');
|
||||||
|
createInput(modalUxContent, 'pwdMd5', 'PwdMd5', 'text', '');
|
||||||
|
|
||||||
//Buttons
|
//Buttons
|
||||||
var authBtnWrapper = document.createElement('div');
|
var authBtnWrapper = document.createElement('div');
|
||||||
|
|||||||
@@ -1,97 +0,0 @@
|
|||||||
using Castle.DynamicProxy;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace IRaCIS.Core.Application.AOP
|
|
||||||
{
|
|
||||||
public abstract class AsyncInterceptorBase : IInterceptor
|
|
||||||
{
|
|
||||||
public AsyncInterceptorBase()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Intercept(IInvocation invocation)
|
|
||||||
{
|
|
||||||
BeforeProceed(invocation);
|
|
||||||
invocation.Proceed();
|
|
||||||
if (IsAsyncMethod(invocation.MethodInvocationTarget))
|
|
||||||
{
|
|
||||||
invocation.ReturnValue = InterceptAsync((dynamic)invocation.ReturnValue, invocation);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AfterProceedSync(invocation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool CheckMethodReturnTypeIsTaskType(MethodInfo method)
|
|
||||||
{
|
|
||||||
var methodReturnType = method.ReturnType;
|
|
||||||
if (methodReturnType.IsGenericType)
|
|
||||||
{
|
|
||||||
if (methodReturnType.GetGenericTypeDefinition() == typeof(Task<>) ||
|
|
||||||
methodReturnType.GetGenericTypeDefinition() == typeof(ValueTask<>))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (methodReturnType == typeof(Task) ||
|
|
||||||
methodReturnType == typeof(ValueTask))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool IsAsyncMethod(MethodInfo method)
|
|
||||||
{
|
|
||||||
bool isDefAsync = Attribute.IsDefined(method, typeof(AsyncStateMachineAttribute), false);
|
|
||||||
bool isTaskType = CheckMethodReturnTypeIsTaskType(method);
|
|
||||||
bool isAsync = isDefAsync && isTaskType;
|
|
||||||
|
|
||||||
return isAsync;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected object ProceedAsyncResult { get; set; }
|
|
||||||
|
|
||||||
|
|
||||||
private async Task InterceptAsync(Task task, IInvocation invocation)
|
|
||||||
{
|
|
||||||
await task.ConfigureAwait(false);
|
|
||||||
await AfterProceedAsync(invocation, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<TResult> InterceptAsync<TResult>(Task<TResult> task, IInvocation invocation)
|
|
||||||
{
|
|
||||||
ProceedAsyncResult = await task.ConfigureAwait(false);
|
|
||||||
await AfterProceedAsync(invocation, true);
|
|
||||||
return (TResult)ProceedAsyncResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async ValueTask InterceptAsync(ValueTask task, IInvocation invocation)
|
|
||||||
{
|
|
||||||
await task.ConfigureAwait(false);
|
|
||||||
await AfterProceedAsync(invocation, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async ValueTask<TResult> InterceptAsync<TResult>(ValueTask<TResult> task, IInvocation invocation)
|
|
||||||
{
|
|
||||||
ProceedAsyncResult = await task.ConfigureAwait(false);
|
|
||||||
await AfterProceedAsync(invocation, true);
|
|
||||||
return (TResult)ProceedAsyncResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void BeforeProceed(IInvocation invocation) { }
|
|
||||||
|
|
||||||
protected virtual void AfterProceedSync(IInvocation invocation) { }
|
|
||||||
|
|
||||||
protected virtual Task AfterProceedAsync(IInvocation invocation, bool hasAsynResult)
|
|
||||||
{
|
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,499 +0,0 @@
|
|||||||
//using System;
|
|
||||||
//using Castle.DynamicProxy;
|
|
||||||
//using IRaCIS.Core.Application.Contracts.Dicom.DTO;
|
|
||||||
//using IRaCIS.Core.Infra.EFCore;
|
|
||||||
|
|
||||||
//using System.Linq;
|
|
||||||
//using IRaCIS.Core.Domain.Models;
|
|
||||||
//using IRaCIS.Core.Domain.Share;
|
|
||||||
|
|
||||||
//namespace IRaCIS.Core.API.Utility.AOP
|
|
||||||
//{
|
|
||||||
//#pragma warning disable
|
|
||||||
// public class QANoticeAOP : IInterceptor
|
|
||||||
// {
|
|
||||||
// private readonly IRepository<QANotice> _qaNoticeRepository;
|
|
||||||
|
|
||||||
// private readonly IRepository<DicomStudy> _studyRepository;
|
|
||||||
// private readonly IRepository<TrialUser> _userTrialRepository;
|
|
||||||
// private readonly IRepository<TrialSiteUser> _userTrialSiteRepository;
|
|
||||||
// private readonly IUserInfo _userInfo;
|
|
||||||
|
|
||||||
// public QANoticeAOP(IRepository<QANotice> qaNoticeRepository,
|
|
||||||
// IUserInfo userInfo, IRepository<DicomStudy> studyRepository, IRepository<TrialUser> userTrialRepository, IRepository<TrialSiteUser> userTrialSiteRepository)
|
|
||||||
// {
|
|
||||||
// _qaNoticeRepository = qaNoticeRepository;
|
|
||||||
|
|
||||||
// _studyRepository = studyRepository;
|
|
||||||
// _userTrialRepository = userTrialRepository;
|
|
||||||
// _userTrialSiteRepository = userTrialSiteRepository;
|
|
||||||
// _userInfo = userInfo;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// public void Intercept(IInvocation invocation)
|
|
||||||
// {
|
|
||||||
// //处理拦截的方法
|
|
||||||
// invocation.Proceed();
|
|
||||||
|
|
||||||
// if (invocation.Method.Name == "UpdateStudyStatus")
|
|
||||||
// {
|
|
||||||
// var studyStatus = invocation.Arguments[0] as StudyStatusDetailCommand;
|
|
||||||
|
|
||||||
// var study = _studyRepository.FirstOrDefault(t=>t.Id==studyStatus.StudyId);
|
|
||||||
|
|
||||||
|
|
||||||
// if (study.Status == (int)StudyStatus.Uploaded)
|
|
||||||
// {
|
|
||||||
// _qaNoticeRepository.Add(new QANotice()
|
|
||||||
// {
|
|
||||||
// TrialId = study.TrialId,
|
|
||||||
// SubjectVisitId = study.Id,
|
|
||||||
// FromUser = _userInfo.RealName,
|
|
||||||
// FromUserId = _userInfo.Id,
|
|
||||||
// FromUserType = _userInfo.UserTypeShortName,
|
|
||||||
|
|
||||||
// NoticeTypeEnum = NoticeType.NotNeedNotice,
|
|
||||||
// NeedDeal = false,
|
|
||||||
// StudyStatusStr = "Uploaded",
|
|
||||||
// Message = $"CRC : {_userInfo.RealName} has uploaded {study.StudyCode} ",
|
|
||||||
// SendTime = DateTime.Now,
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
// #region 处理QA通知模块
|
|
||||||
|
|
||||||
// //查询项目的参与者 和 负责site下CRC用户
|
|
||||||
// var trialUserList = _userTrialRepository.Where(t => t.TrialId == study.TrialId).ToList();
|
|
||||||
|
|
||||||
// // 找到该study 关联Site 下的CRC
|
|
||||||
|
|
||||||
// var crcList = _userTrialSiteRepository.Where(t =>
|
|
||||||
// t.SiteId == study.SiteId && t.User.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator && t.TrialId == study.TrialId).ToList();
|
|
||||||
|
|
||||||
|
|
||||||
// var qaList = trialUserList.Where(t => t.User.UserTypeEnum == UserTypeEnum.IQC).ToList();
|
|
||||||
|
|
||||||
// var pm = trialUserList.FirstOrDefault(t => t.User.UserTypeEnum == UserTypeEnum.ProjectManager);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// // CRC =>QA
|
|
||||||
// if (studyStatus.Status == (int)StudyStatus.QARequested)
|
|
||||||
// {
|
|
||||||
// //找出当前操作的CRC
|
|
||||||
// //PM 或者admin可以代替CRC角色 不能从CRC列表中查询用户
|
|
||||||
// //var currentCRC = trialUserList.First(t => t.UserId == _userInfo.Id);
|
|
||||||
|
|
||||||
// var notice = new QANotice()
|
|
||||||
// {
|
|
||||||
// TrialId = study.TrialId,
|
|
||||||
// SubjectVisitId = study.Id,
|
|
||||||
// FromUser = _userInfo.RealName,
|
|
||||||
// FromUserId = _userInfo.Id,
|
|
||||||
// FromUserType = _userInfo.UserTypeShortName,
|
|
||||||
|
|
||||||
// //FromUser = currentCRC.UserRealName,
|
|
||||||
// //FromUserId = _userInfo.Id,
|
|
||||||
// //FromUserType = currentCRC.UserType,
|
|
||||||
// NoticeTypeEnum = NoticeType.CRC_RequestToQA_NoticeQA,
|
|
||||||
// NeedDeal = true,
|
|
||||||
// StudyStatusStr = "QA Requested",
|
|
||||||
// Message =
|
|
||||||
// $"CRC -> QA : {_userInfo.RealName} request QA {study.StudyCode} , Inquiry can be performed! ",
|
|
||||||
// SendTime = DateTime.Now,
|
|
||||||
// };
|
|
||||||
|
|
||||||
// qaList.ForEach(t => notice.QANoticeUserList.Add(new QANoticeUser()
|
|
||||||
// {
|
|
||||||
// QANoticeId = notice.Id,
|
|
||||||
// SubjectVisitId = study.Id,
|
|
||||||
// ToUser = t.User.LastName + " / " + t.User.FirstName,
|
|
||||||
// ToUserId = t.UserId,
|
|
||||||
// ToUserType = t.User.UserTypeRole.UserTypeShortName
|
|
||||||
// }));
|
|
||||||
|
|
||||||
// _qaNoticeRepository.Add(notice);
|
|
||||||
|
|
||||||
// //DealRequestToQA(study.Id);
|
|
||||||
|
|
||||||
// var needDealNoticeList = _qaNoticeRepository.AsQueryable()
|
|
||||||
// .Where(t => t.SubjectVisitId == study.Id && t.NeedDeal && t.NoticeTypeEnum == NoticeType.CRC_RequestToQA_NoticeQA).ToList();
|
|
||||||
|
|
||||||
// needDealNoticeList.ForEach(t =>
|
|
||||||
// {
|
|
||||||
// t.NeedDeal = false;
|
|
||||||
// t.DealTime = DateTime.Now;
|
|
||||||
// _qaNoticeRepository.Update(t);
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // QA =>CRC 向CRC推送消息影像有问题 同时作为 requestToQA 的边界
|
|
||||||
// else if (studyStatus.Status == (int)StudyStatus.QAing)
|
|
||||||
// {
|
|
||||||
// //找出当前操作的QA 如果是pm 或者admin 代替操作 此时会有问题 所以 谁代替,就以谁的名义执行
|
|
||||||
// //var currentQA = qaList.First(t => t.UserId == _userInfo.Id);
|
|
||||||
// //var currentQA = trialUserList.First(t => t.UserId == _userInfo.Id);
|
|
||||||
|
|
||||||
// //在项目CRC列表中筛选出 负责该study关联 site的CRC
|
|
||||||
// var siteCRCList = _userTrialSiteRepository.Where(t =>
|
|
||||||
// t.SiteId == study.SiteId && t.User.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator && t.TrialId == study.TrialId).ToList();
|
|
||||||
|
|
||||||
// //查询项目的参与者 和 负责site下CRC用户
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// var notice = new QANotice()
|
|
||||||
// {
|
|
||||||
// TrialId = study.TrialId,
|
|
||||||
// SubjectVisitId = study.Id,
|
|
||||||
// //FromUser = currentQA.UserRealName,
|
|
||||||
// //FromUserId = _userInfo.Id,
|
|
||||||
// //FromUserType = currentQA.UserType,
|
|
||||||
// FromUser = _userInfo.RealName,
|
|
||||||
// FromUserId = _userInfo.Id,
|
|
||||||
// FromUserType = _userInfo.UserTypeShortName,
|
|
||||||
// NoticeTypeEnum = NoticeType.QA_InQA_NoticeCRC,
|
|
||||||
// NeedDeal = true,
|
|
||||||
// StudyStatusStr = "In QA",
|
|
||||||
// Message = $"QA -> CRC : {_userInfo.RealName} inquiry {study.StudyCode} ",
|
|
||||||
// SendTime = DateTime.Now,
|
|
||||||
// };
|
|
||||||
|
|
||||||
// siteCRCList.ForEach(t => notice.QANoticeUserList.Add(new QANoticeUser()
|
|
||||||
// {
|
|
||||||
// QANoticeId = notice.Id,
|
|
||||||
// SubjectVisitId = study.Id,
|
|
||||||
// ToUser = t.User.LastName + " / " + t.User.FirstName,
|
|
||||||
// ToUserId = t.UserId,
|
|
||||||
// ToUserType = t.UserTypeRole.UserTypeShortName
|
|
||||||
// }));
|
|
||||||
|
|
||||||
// //添加 发送给CRC的消息 消息和CRC是 一对多
|
|
||||||
// _qaNoticeRepository.Add(notice);
|
|
||||||
|
|
||||||
|
|
||||||
// //处理 消息 标记已处理
|
|
||||||
// var needDealNoticeList = _qaNoticeRepository.AsQueryable()
|
|
||||||
// .Where(t => t.SubjectVisitId == study.Id && t.NeedDeal &&
|
|
||||||
// (t.NoticeTypeEnum == NoticeType.CRC_RequestToQA_NoticeQA ||
|
|
||||||
// t.NoticeTypeEnum == NoticeType.CRC_ReUpload_NoticeQA ||
|
|
||||||
// t.NoticeTypeEnum == NoticeType.CRC_QARecordDialogPost_NoticeQA)).ToList();
|
|
||||||
|
|
||||||
// needDealNoticeList.ForEach(t =>
|
|
||||||
// {
|
|
||||||
// t.NeedDeal = false;
|
|
||||||
// t.DealTime = DateTime.Now;
|
|
||||||
// _qaNoticeRepository.Update(t);
|
|
||||||
// });
|
|
||||||
|
|
||||||
|
|
||||||
// }
|
|
||||||
// // QA =>QA 给自己的消息 通知需要匿名化 同时作为 requestToQA 的边界
|
|
||||||
// else if (studyStatus.Status == (int)StudyStatus.QAFinish)
|
|
||||||
// {
|
|
||||||
|
|
||||||
// //找出当前操作的QA 如果是pm 或者admin 代替操作 此时会有问题 所以 谁代替,就以谁的名义执行
|
|
||||||
// //var currentQA = qaList.First(t => t.UserId == _userInfo.Id);
|
|
||||||
// //var currentQA = trialUserList.First(t => t.UserId == _userInfo.Id);
|
|
||||||
|
|
||||||
// //发送给当前项目QA列表
|
|
||||||
|
|
||||||
// var notice = new QANotice()
|
|
||||||
// {
|
|
||||||
// TrialId = study.TrialId,
|
|
||||||
// SubjectVisitId = study.Id,
|
|
||||||
// //FromUser = currentQA.UserRealName,
|
|
||||||
// //FromUserId = _userInfo.Id,
|
|
||||||
// //FromUserType = currentQA.UserType,
|
|
||||||
// FromUser = _userInfo.RealName,
|
|
||||||
// FromUserId = _userInfo.Id,
|
|
||||||
// FromUserType = _userInfo.UserTypeShortName,
|
|
||||||
// NoticeTypeEnum = NoticeType.QA_QAPass_NoticeQA,
|
|
||||||
// NeedDeal = true,
|
|
||||||
// StudyStatusStr = "QA-Passed",
|
|
||||||
// Message =
|
|
||||||
// $"QA -> QA : {_userInfo.RealName} inquiry {study.StudyCode} finished,Anonymization can be performed!",
|
|
||||||
// SendTime = DateTime.Now,
|
|
||||||
// };
|
|
||||||
|
|
||||||
// qaList.ForEach(t => notice.QANoticeUserList.Add(new QANoticeUser()
|
|
||||||
// {
|
|
||||||
// QANoticeId = notice.Id,
|
|
||||||
// SubjectVisitId = study.Id,
|
|
||||||
// ToUser = t.User.LastName+" / "+t.User.FirstName,
|
|
||||||
// ToUserId = t.UserId,
|
|
||||||
// ToUserType = t.User.UserTypeRole.UserTypeShortName
|
|
||||||
// }));
|
|
||||||
|
|
||||||
// _qaNoticeRepository.Add(notice);
|
|
||||||
|
|
||||||
// //处理 消息 标记已处理 存在意外情况 qa发给CRC的 但是qa里面设置了 通过或者不通过 此时qa发送的消息也设置为已处理
|
|
||||||
// var needDealNoticeList = _qaNoticeRepository.AsQueryable()
|
|
||||||
// .Where(t => t.SubjectVisitId == study.Id && t.NeedDeal &&
|
|
||||||
// (t.NoticeTypeEnum == NoticeType.CRC_RequestToQA_NoticeQA ||
|
|
||||||
// t.NoticeTypeEnum == NoticeType.CRC_ReUpload_NoticeQA ||
|
|
||||||
// t.NoticeTypeEnum == NoticeType.CRC_QARecordDialogPost_NoticeQA ||
|
|
||||||
|
|
||||||
// t.NoticeTypeEnum == NoticeType.QA_QARecordDialogPost_NoticeCRC ||
|
|
||||||
// t.NoticeTypeEnum == NoticeType.QA_InQA_NoticeCRC ||
|
|
||||||
// t.NoticeTypeEnum == NoticeType.QA_AddQARecord_NoticeCRC)).ToList();
|
|
||||||
|
|
||||||
// needDealNoticeList.ForEach(t =>
|
|
||||||
// {
|
|
||||||
// t.NeedDeal = false;
|
|
||||||
// t.DealTime = DateTime.Now;
|
|
||||||
// _qaNoticeRepository.Update(t);
|
|
||||||
// });
|
|
||||||
|
|
||||||
|
|
||||||
// }
|
|
||||||
// // QA =>CRC 暂时不用发送消息给CRC 因为CRC 暂时没有入口回复 同时作为 requestToQA 的边界
|
|
||||||
// else if (studyStatus.Status == (int)StudyStatus.QAFInishNotPass)
|
|
||||||
// {
|
|
||||||
|
|
||||||
// _qaNoticeRepository.Add(new QANotice()
|
|
||||||
// {
|
|
||||||
// TrialId = study.TrialId,
|
|
||||||
// SubjectVisitId = study.Id,
|
|
||||||
// FromUser = _userInfo.RealName,
|
|
||||||
// FromUserId = _userInfo.Id,
|
|
||||||
// FromUserType = _userInfo.UserTypeShortName,
|
|
||||||
// NoticeTypeEnum = NoticeType.NotNeedNotice,
|
|
||||||
// NeedDeal = false,
|
|
||||||
// StudyStatusStr = "QA-Failed",
|
|
||||||
// Message = $"QA : {_userInfo.RealName} set {study.StudyCode} QA-Failed !",
|
|
||||||
// SendTime = DateTime.Now,
|
|
||||||
// });
|
|
||||||
|
|
||||||
// //处理 消息 标记已处理
|
|
||||||
// var needDealNoticeList = _qaNoticeRepository.AsQueryable()
|
|
||||||
// .Where(t => t.SubjectVisitId == study.Id && t.NeedDeal &&
|
|
||||||
// (t.NoticeTypeEnum == NoticeType.CRC_RequestToQA_NoticeQA ||
|
|
||||||
// t.NoticeTypeEnum == NoticeType.CRC_ReUpload_NoticeQA ||
|
|
||||||
// t.NoticeTypeEnum == NoticeType.CRC_QARecordDialogPost_NoticeQA ||
|
|
||||||
|
|
||||||
|
|
||||||
// t.NoticeTypeEnum == NoticeType.QA_QARecordDialogPost_NoticeCRC ||
|
|
||||||
// t.NoticeTypeEnum == NoticeType.QA_InQA_NoticeCRC ||
|
|
||||||
// t.NoticeTypeEnum == NoticeType.QA_AddQARecord_NoticeCRC)).ToList();
|
|
||||||
|
|
||||||
// needDealNoticeList.ForEach(t =>
|
|
||||||
// {
|
|
||||||
// t.NeedDeal = false;
|
|
||||||
// t.DealTime = DateTime.Now;
|
|
||||||
// _qaNoticeRepository.Update(t);
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
// #endregion
|
|
||||||
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
// else if (invocation.Method.Name == "ReUploadSameStudy")
|
|
||||||
// {
|
|
||||||
// var studyId = Guid.Parse(invocation.Arguments[0].ToString());
|
|
||||||
|
|
||||||
// var study = _studyRepository.FirstOrDefault(t => t.Id == studyId);
|
|
||||||
// var status = study.Status;
|
|
||||||
|
|
||||||
// //处理CRC 重传时 QA消息
|
|
||||||
|
|
||||||
// if (status == (int)StudyStatus.QAing)
|
|
||||||
// {
|
|
||||||
// //查询项目的参与者 和 负责site下CRC用户
|
|
||||||
// var trialUserList = _userTrialRepository.Where(t => t.TrialId == study.TrialId).ToList();
|
|
||||||
|
|
||||||
// // 找到该study 关联Site 下的CRC
|
|
||||||
|
|
||||||
// var crcList = _userTrialSiteRepository.Where(t =>
|
|
||||||
// t.SiteId == study.SiteId && t.User.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator && t.TrialId == study.TrialId).ToList();
|
|
||||||
|
|
||||||
// var qaList = trialUserList.Where(t => t.User.UserTypeEnum == UserTypeEnum.IQC).ToList();
|
|
||||||
|
|
||||||
// //CRC =>QA CRC的职能被PM 或者admin代替
|
|
||||||
// //if (_userInfo.UserTypeEnumInt == (int)UserType.ClinicalResearchCoordinator)
|
|
||||||
// {
|
|
||||||
// //PM 或者admin可以代替CRC角色 不能从CRC列表中查询用户
|
|
||||||
// //var currentCRC = trialUserList.First(t => t.UserId == _userInfo.Id);
|
|
||||||
|
|
||||||
// var notice = new QANotice()
|
|
||||||
// {
|
|
||||||
// TrialId = study.TrialId,
|
|
||||||
// SubjectVisitId = study.Id,
|
|
||||||
// //FromUser = currentCRC.UserRealName,
|
|
||||||
// //FromUserId = _userInfo.Id,
|
|
||||||
// //FromUserType = currentCRC.UserType,
|
|
||||||
// FromUser = _userInfo.RealName,
|
|
||||||
// FromUserId = _userInfo.Id,
|
|
||||||
// FromUserType = _userInfo.UserTypeShortName,
|
|
||||||
// NoticeTypeEnum = NoticeType.CRC_ReUpload_NoticeQA,
|
|
||||||
// NeedDeal = true,
|
|
||||||
// Message = $"CRC -> QA :{_userInfo.RealName} has reuploaded {study.StudyCode} , Need to be inquiry again",
|
|
||||||
// SendTime = DateTime.Now
|
|
||||||
// };
|
|
||||||
|
|
||||||
// qaList.ForEach(t => notice.QANoticeUserList.Add(new QANoticeUser()
|
|
||||||
// {
|
|
||||||
// QANoticeId = notice.Id,
|
|
||||||
// SubjectVisitId = study.Id,
|
|
||||||
// ToUser = t.User.LastName+" / "+t.User.FirstName,
|
|
||||||
// ToUserId = t.UserId,
|
|
||||||
// ToUserType = t.User.UserTypeRole.UserTypeShortName
|
|
||||||
// }));
|
|
||||||
|
|
||||||
// _qaNoticeRepository.Add(notice);
|
|
||||||
|
|
||||||
// //这里作为 QA 设置 Inqa 状态的回复 或者QA和CRC对话的
|
|
||||||
// var needDealNoticeList = _qaNoticeRepository.Where(t => t.SubjectVisitId == study.Id && t.NeedDeal
|
|
||||||
// && (t.NoticeTypeEnum == NoticeType.QA_InQA_NoticeCRC || t.NoticeTypeEnum == NoticeType.QA_QARecordDialogPost_NoticeCRC))
|
|
||||||
// .ToList();
|
|
||||||
|
|
||||||
// needDealNoticeList.ForEach(t =>
|
|
||||||
// {
|
|
||||||
// t.NeedDeal = false;
|
|
||||||
// t.DealTime = DateTime.Now;
|
|
||||||
// _qaNoticeRepository.Update(t);
|
|
||||||
// });
|
|
||||||
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// //不是QAing 的重传 不发送qa消息
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
// else if (invocation.Method.Name == "DicomAnonymize")
|
|
||||||
// {
|
|
||||||
// var studyId = Guid.Parse(invocation.Arguments[0].ToString());
|
|
||||||
|
|
||||||
// var study = _studyRepository.FirstOrDefault(t => t.Id == studyId);
|
|
||||||
|
|
||||||
// #region 处理QA通知 匿名化完毕 通知PM
|
|
||||||
|
|
||||||
// //查询项目的参与者 和 负责site下CRC用户
|
|
||||||
// var trialUserList = _userTrialRepository.Where(t => t.TrialId == study.TrialId).ToList();
|
|
||||||
|
|
||||||
// // 找到该study 关联Site 下的CRC
|
|
||||||
|
|
||||||
// var crcList = _userTrialSiteRepository.Where(t =>
|
|
||||||
// t.SiteId == study.SiteId && t.User.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator && t.TrialId == study.TrialId).ToList();
|
|
||||||
|
|
||||||
// var qaList = trialUserList.Where(t => t.User.UserTypeEnum == UserTypeEnum.IQC).ToList();
|
|
||||||
|
|
||||||
// //
|
|
||||||
// var pm = trialUserList.FirstOrDefault(t => t.User.UserTypeEnum == UserTypeEnum.ProjectManager);
|
|
||||||
|
|
||||||
|
|
||||||
// //找出当前操作的QA 如果是pm 或者admin 代替操作 此时会有问题 所以 谁代替,就以谁的名义执行
|
|
||||||
// //var currentQA = trialUserList.First(t =>
|
|
||||||
// // t.UserTypeEnum == UserType.IQC && t.UserId == _userInfo.Id);
|
|
||||||
// //var currentQA = trialUserList.First(t => t.UserId == _userInfo.Id);
|
|
||||||
|
|
||||||
// var notice = new QANotice()
|
|
||||||
// {
|
|
||||||
// TrialId = study.TrialId,
|
|
||||||
// SubjectVisitId = study.Id,
|
|
||||||
// //FromUser = currentQA.UserRealName,
|
|
||||||
// //FromUserId = _userInfo.Id,
|
|
||||||
// //FromUserType = currentQA.UserType,
|
|
||||||
// FromUser = _userInfo.RealName,
|
|
||||||
// FromUserId = _userInfo.Id,
|
|
||||||
// FromUserType = _userInfo.UserTypeShortName,
|
|
||||||
// NoticeTypeEnum = NoticeType.QA_Anonymized_NoticeQA,
|
|
||||||
// NeedDeal = true,
|
|
||||||
// StudyStatusStr = "Anonymized",
|
|
||||||
// //Message = $"QA -> PM :{_userInfo.RealName} has anonymized {study.StudyCode} ,Forward can be performed!!",
|
|
||||||
// Message = $"QA -> QA :{_userInfo.RealName} has anonymized {study.StudyCode} ,Forward can be performed!!",
|
|
||||||
|
|
||||||
// SendTime = DateTime.Now,
|
|
||||||
|
|
||||||
// };
|
|
||||||
|
|
||||||
// //notice.QANoticeUserList.Add(new QANoticeUser()
|
|
||||||
// //{
|
|
||||||
// // QANoticeId = notice.Id,
|
|
||||||
// // StudyId = study.Id,
|
|
||||||
// // ToUser = pm.UserRealName,
|
|
||||||
// // ToUserId = pm.UserId,
|
|
||||||
// // ToUserType = pm.UserType
|
|
||||||
// //});
|
|
||||||
|
|
||||||
// qaList.ForEach(t => notice.QANoticeUserList.Add(new QANoticeUser()
|
|
||||||
// {
|
|
||||||
// QANoticeId = notice.Id,
|
|
||||||
// SubjectVisitId = study.Id,
|
|
||||||
// ToUser = t.User.LastName+" / "+t.User.FirstName,
|
|
||||||
// ToUserId = t.UserId,
|
|
||||||
// ToUserType = t.User.UserTypeRole.UserTypeShortName
|
|
||||||
// }));
|
|
||||||
|
|
||||||
// _qaNoticeRepository.Add(notice);
|
|
||||||
|
|
||||||
// var needDealNoticeList = _qaNoticeRepository.AsQueryable()
|
|
||||||
// .Where(t => t.SubjectVisitId == study.Id && t.NeedDeal && (t.NoticeTypeEnum == NoticeType.QA_QAPass_NoticeQA)).ToList();
|
|
||||||
|
|
||||||
// needDealNoticeList.ForEach(t =>
|
|
||||||
// {
|
|
||||||
// t.NeedDeal = false;
|
|
||||||
// t.DealTime = DateTime.Now;
|
|
||||||
// _qaNoticeRepository.Update(t);
|
|
||||||
// });
|
|
||||||
|
|
||||||
|
|
||||||
// #endregion
|
|
||||||
// }
|
|
||||||
|
|
||||||
// else if (invocation.Method.Name == "ForwardStudy")
|
|
||||||
// {
|
|
||||||
// var studyId = Guid.Parse(invocation.Arguments[0].ToString());
|
|
||||||
|
|
||||||
// var study = _studyRepository.FirstOrDefault(t => t.Id == studyId);
|
|
||||||
|
|
||||||
// //匿名化操作产生的消息 设置为已经处理
|
|
||||||
// _qaNoticeRepository.Add(new QANotice()
|
|
||||||
// {
|
|
||||||
// TrialId = study.TrialId,
|
|
||||||
// SubjectVisitId = study.Id,
|
|
||||||
// //FromUser = currentQA.UserRealName,
|
|
||||||
// //FromUserId = _userInfo.Id,
|
|
||||||
// //FromUserType = currentQA.UserType,
|
|
||||||
// FromUser = _userInfo.RealName,
|
|
||||||
// FromUserId = _userInfo.Id,
|
|
||||||
// FromUserType = _userInfo.UserTypeShortName,
|
|
||||||
// NoticeTypeEnum = NoticeType.NotNeedNotice,
|
|
||||||
// NeedDeal = false,
|
|
||||||
// StudyStatusStr = "Forwarded",
|
|
||||||
// //Message = $"PM :{_userInfo.RealName} has forwarded {study.StudyCode} !",
|
|
||||||
// Message = $"QA :{_userInfo.RealName} has forwarded {study.StudyCode} !",
|
|
||||||
// SendTime = DateTime.Now,
|
|
||||||
// });
|
|
||||||
|
|
||||||
// var needDealList = _qaNoticeRepository.Where(t =>
|
|
||||||
// t.SubjectVisitId == study.Id && t.NeedDeal && t.NoticeTypeEnum == NoticeType.QA_Anonymized_NoticeQA).ToList();
|
|
||||||
|
|
||||||
// needDealList.ForEach(t =>
|
|
||||||
// {
|
|
||||||
// t.NeedDeal = false;
|
|
||||||
// t.DealTime = DateTime.Now;
|
|
||||||
// _qaNoticeRepository.Update(t);
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
// var success = _qaNoticeRepository.SaveChanges();
|
|
||||||
|
|
||||||
// if (!success)
|
|
||||||
// {
|
|
||||||
// throw new Exception("Send QA message failed");
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
using Castle.DynamicProxy;
|
|
||||||
using EasyCaching.Core;
|
|
||||||
using IRaCIS.Application.Contracts;
|
|
||||||
using IRaCIS.Core.Domain.Share;
|
|
||||||
|
|
||||||
namespace IRaCIS.Core.Application.AOP
|
|
||||||
{
|
|
||||||
public class TrialStatusAutofacAOP : IAsyncInterceptor
|
|
||||||
{
|
|
||||||
private readonly IEasyCachingProvider _provider;
|
|
||||||
|
|
||||||
public TrialStatusAutofacAOP(IEasyCachingProvider provider)
|
|
||||||
{
|
|
||||||
_provider = provider;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void InterceptAsynchronous(IInvocation invocation)
|
|
||||||
{
|
|
||||||
invocation.Proceed();
|
|
||||||
}
|
|
||||||
|
|
||||||
//这里AOP 处理两个方法 分别是 项目的添加和更新、项目状态的变更
|
|
||||||
|
|
||||||
public void InterceptAsynchronous<TResult>(IInvocation invocation)
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
//处理拦截的方法
|
|
||||||
invocation.Proceed();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
dynamic result = invocation.ReturnValue;
|
|
||||||
|
|
||||||
//接口成功了,才修改缓存
|
|
||||||
if (!result.IsSuccess)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#region 处理项目列表的查询 在前端界面已经在某个界面,但是服务器重置了,此时没有缓存项目信息,接口不能正确返回,因故采用,启动时查询,每天查询一次,缓存一天,然后项目添加、更改状态时,及时更新
|
|
||||||
|
|
||||||
//if (invocation.Method.Name == "GetTrialList")
|
|
||||||
//{
|
|
||||||
// //在此 将当前查询的项目Id 和对应的项目状态进行缓存
|
|
||||||
// dynamic result = invocation.ReturnValue;
|
|
||||||
// foreach (var item in result.CurrentPageData)
|
|
||||||
// {
|
|
||||||
// _provider.Remove(item.Id.ToString());
|
|
||||||
// _provider.Set(item.Id.ToString(), item.TrialStatusStr.ToString(), TimeSpan.FromDays(1));
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
if (invocation.Method.Name == "AddOrUpdateTrial")
|
|
||||||
{
|
|
||||||
//如果是添加 那么将对应的初始状态加进去 更新状态是单独操作的
|
|
||||||
|
|
||||||
var trialModel = (invocation.Arguments[0] as TrialCommand).IfNullThrowConvertException();
|
|
||||||
if (trialModel.Id == null || trialModel.Id == Guid.Empty)
|
|
||||||
{
|
|
||||||
_provider.Set(result.Data.Id.ToString(), StaticData.TrialState.TrialOngoing, TimeSpan.FromDays(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
// 更新缓存
|
|
||||||
else if (invocation.Method.Name == "UpdateTrialStatus")
|
|
||||||
{
|
|
||||||
//项目状态更新,也需要及时更新
|
|
||||||
_provider.Set(invocation.Arguments[0].ToString(), invocation.Arguments[1].ToString(), TimeSpan.FromDays(1));
|
|
||||||
|
|
||||||
////Test参数是否符合要求
|
|
||||||
//var tt = invocation.Arguments[0].ToString();
|
|
||||||
//var cc = _provider.Get<string>(invocation.Arguments[0].ToString());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void InterceptSynchronous(IInvocation invocation)
|
|
||||||
{
|
|
||||||
invocation.Proceed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using EasyCaching.Core;
|
|
||||||
using IRaCIS.Core.Domain;
|
|
||||||
using IRaCIS.Core.Infra.EFCore;
|
|
||||||
using IRaCIS.Core.Domain.Models;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using Quartz;
|
|
||||||
|
|
||||||
namespace IRaCIS.Application.Services.BackGroundJob
|
|
||||||
{
|
|
||||||
|
|
||||||
public class CacheTrialStatusQuartZJob: IJob
|
|
||||||
{
|
|
||||||
|
|
||||||
private readonly IRepository<Trial> _trialRepository;
|
|
||||||
private readonly IEasyCachingProvider _provider;
|
|
||||||
private readonly ILogger<CacheTrialStatusQuartZJob> _logger;
|
|
||||||
|
|
||||||
public CacheTrialStatusQuartZJob(IRepository<Trial> trialRepository, IEasyCachingProvider provider,ILogger<CacheTrialStatusQuartZJob> logger)
|
|
||||||
{
|
|
||||||
_trialRepository = trialRepository;
|
|
||||||
_provider = provider;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task Execute(IJobExecutionContext context)
|
|
||||||
|
|
||||||
{
|
|
||||||
_logger.LogInformation($"开始执行QuartZ定时任务作业");
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var list = _trialRepository.Select(t => new { TrialId = t.Id, TrialStatusStr = t.TrialStatusStr })
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
list.ForEach(t => _provider.Set(t.TrialId.ToString(), t.TrialStatusStr, TimeSpan.FromDays(1)));
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
_logger.LogError($" 查询和缓存过程出现异常"+e.Message);
|
|
||||||
}
|
|
||||||
_logger.LogInformation("QuartZ定时任务作业结束");
|
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,229 @@
|
|||||||
|
using EasyCaching.Core;
|
||||||
|
using Hangfire;
|
||||||
|
using Hangfire.Storage;
|
||||||
|
using IRaCIS.Core.Application.Helper;
|
||||||
|
using IRaCIS.Core.Application.Service;
|
||||||
|
using IRaCIS.Core.Domain.Share;
|
||||||
|
using IRaCIS.Core.Infrastructure;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using SharpCompress.Common;
|
||||||
|
|
||||||
|
namespace IRaCIS.Application.Services.BackGroundJob
|
||||||
|
{
|
||||||
|
|
||||||
|
public interface IIRaCISHangfireJob
|
||||||
|
{
|
||||||
|
|
||||||
|
Task MemoryCacheTrialStatusAsync();
|
||||||
|
|
||||||
|
Task InitHangfireJobTaskAsync();
|
||||||
|
|
||||||
|
}
|
||||||
|
public class IRaCISCHangfireJob : IIRaCISHangfireJob
|
||||||
|
{
|
||||||
|
public static string JsonFileFolder = Path.Combine(AppContext.BaseDirectory, StaticData.Folder.Resources);
|
||||||
|
|
||||||
|
public static FileSystemWatcher FileSystemWatcher_US { get; set; }
|
||||||
|
public static FileSystemWatcher FileSystemWatcher_CN { get; set; }
|
||||||
|
private readonly IRepository<Trial> _trialRepository;
|
||||||
|
private readonly IEasyCachingProvider _provider;
|
||||||
|
private readonly ILogger<IRaCISCHangfireJob> _logger;
|
||||||
|
private readonly IRepository<SystemAnonymization> _systemAnonymizationRepository;
|
||||||
|
private readonly IRepository<TrialEmailNoticeConfig> _trialEmailNoticeConfigRepository;
|
||||||
|
private readonly IRepository<Internationalization> _internationalizationRepository;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public IRaCISCHangfireJob(IRepository<Trial> trialRepository, ILogger<IRaCISCHangfireJob> logger, IEasyCachingProvider provider, IRepository<TrialEmailNoticeConfig> trialEmailNoticeConfigRepository, IRepository<Internationalization> internationalizationRepository, IRepository<SystemAnonymization> systemAnonymizationRepository)
|
||||||
|
{
|
||||||
|
_trialRepository = trialRepository;
|
||||||
|
_provider = provider;
|
||||||
|
_logger = logger;
|
||||||
|
_trialEmailNoticeConfigRepository = trialEmailNoticeConfigRepository;
|
||||||
|
_internationalizationRepository = internationalizationRepository;
|
||||||
|
_systemAnonymizationRepository = systemAnonymizationRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task InitHangfireJobTaskAsync()
|
||||||
|
{
|
||||||
|
_logger.LogInformation("项目启动 hangfire 任务初始化 执行开始~");
|
||||||
|
|
||||||
|
|
||||||
|
//项目状态 立即加载到缓存中
|
||||||
|
await MemoryCacheTrialStatusAsync();
|
||||||
|
|
||||||
|
await MemoryCacheAnonymizeData();
|
||||||
|
|
||||||
|
|
||||||
|
//创建项目缓存 定时任务
|
||||||
|
HangfireJobHelper.AddOrUpdateInitCronJob<IIRaCISHangfireJob>("RecurringJob_Cache_TrialState", t => t.MemoryCacheTrialStatusAsync(), Cron.Daily());
|
||||||
|
|
||||||
|
//初始化
|
||||||
|
|
||||||
|
await InitInternationlizationDataAndWatchJsonFileAsync();
|
||||||
|
|
||||||
|
//创建邮件定时任务
|
||||||
|
await InitSysAndTrialCronJobAsync();
|
||||||
|
|
||||||
|
|
||||||
|
_logger.LogInformation("项目启动 hangfire 任务初始化 执行结束");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 缓存项目状态
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task MemoryCacheTrialStatusAsync()
|
||||||
|
{
|
||||||
|
|
||||||
|
var list = await _trialRepository.Select(t => new { TrialId = t.Id, TrialStatusStr = t.TrialStatusStr })
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
list.ForEach(t => _provider.Set(t.TrialId.ToString(), t.TrialStatusStr, TimeSpan.FromDays(7)));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task MemoryCacheAnonymizeData()
|
||||||
|
{
|
||||||
|
var systemAnonymizationList = await _systemAnonymizationRepository.Where(t => t.IsEnable).ToListAsync();
|
||||||
|
|
||||||
|
_provider.Set(StaticData.Anonymize.Anonymize_AddFixedFiled, systemAnonymizationList.Where(t => t.IsAdd && t.IsFixed).ToList(), TimeSpan.FromDays(7));
|
||||||
|
_provider.Set(StaticData.Anonymize.Anonymize_AddIRCInfoFiled, systemAnonymizationList.Where(t => t.IsAdd && t.IsFixed == false).ToList(), TimeSpan.FromDays(7));
|
||||||
|
_provider.Set(StaticData.Anonymize.Anonymize_FixedField, systemAnonymizationList.Where(t => t.IsAdd == false && t.IsFixed).ToList(), TimeSpan.FromDays(7));
|
||||||
|
_provider.Set(StaticData.Anonymize.Anonymize_IRCInfoField, systemAnonymizationList.Where(t => t.IsAdd == false && t.IsFixed == false).ToList(), TimeSpan.FromDays(7));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#region 国际化 初始化
|
||||||
|
|
||||||
|
|
||||||
|
public async Task InitInternationlizationDataAndWatchJsonFileAsync()
|
||||||
|
{
|
||||||
|
//查询数据库的数据
|
||||||
|
var toJsonList = await _internationalizationRepository.Where(t => t.InternationalizationType == 1).Select(t => new
|
||||||
|
{
|
||||||
|
t.Code,
|
||||||
|
t.Value,
|
||||||
|
t.ValueCN
|
||||||
|
}).ToListAsync();
|
||||||
|
|
||||||
|
//组织成json 文件
|
||||||
|
|
||||||
|
var usJsonPath = Path.Combine(JsonFileFolder, StaticData.En_US_Json);
|
||||||
|
var cnJsonPath = Path.Combine(JsonFileFolder, StaticData.Zh_CN_Json);
|
||||||
|
|
||||||
|
|
||||||
|
//本地静态文件国际化需要
|
||||||
|
foreach (var tojsonItem in toJsonList)
|
||||||
|
{
|
||||||
|
StaticData.En_US_Dic[tojsonItem.Code] = tojsonItem.Value;
|
||||||
|
StaticData.Zh_CN_Dic[tojsonItem.Code] = tojsonItem.ValueCN;
|
||||||
|
}
|
||||||
|
|
||||||
|
File.WriteAllText(usJsonPath, JsonConvert.SerializeObject(StaticData.En_US_Dic));
|
||||||
|
File.WriteAllText(cnJsonPath, JsonConvert.SerializeObject(StaticData.Zh_CN_Dic));
|
||||||
|
|
||||||
|
|
||||||
|
//监测Json文件变更 实时刷新数据
|
||||||
|
|
||||||
|
if (!File.Exists(usJsonPath)|| !File.Exists(cnJsonPath))
|
||||||
|
{
|
||||||
|
throw new BusinessValidationFailedException(StaticData.International("IRaCISCHangfireJob_FileNotFound"));
|
||||||
|
}
|
||||||
|
|
||||||
|
FileSystemWatcher_US = new FileSystemWatcher
|
||||||
|
{
|
||||||
|
Path = Path.GetDirectoryName(usJsonPath)!,
|
||||||
|
NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.Size,
|
||||||
|
Filter = Path.GetFileName(usJsonPath),
|
||||||
|
EnableRaisingEvents = true,
|
||||||
|
|
||||||
|
};
|
||||||
|
// 添加文件更改事件的处理程序
|
||||||
|
FileSystemWatcher_US.Changed += (sender, e) => LoadJsonFile(usJsonPath);
|
||||||
|
|
||||||
|
|
||||||
|
FileSystemWatcher_CN = new FileSystemWatcher
|
||||||
|
{
|
||||||
|
Path = Path.GetDirectoryName(cnJsonPath)!,
|
||||||
|
NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.Size,
|
||||||
|
Filter = Path.GetFileName(cnJsonPath),
|
||||||
|
EnableRaisingEvents = true,
|
||||||
|
|
||||||
|
};
|
||||||
|
FileSystemWatcher_CN.Changed += (sender, e) => LoadJsonFile(cnJsonPath);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void LoadJsonFile(string filePath)
|
||||||
|
{
|
||||||
|
Console.WriteLine("刷新json内存数据");
|
||||||
|
IConfigurationBuilder builder = new ConfigurationBuilder().AddJsonFile(filePath,false,true);
|
||||||
|
|
||||||
|
IConfigurationRoot enConfiguration = builder.Build();
|
||||||
|
|
||||||
|
foreach (IConfigurationSection section in enConfiguration.GetChildren())
|
||||||
|
{
|
||||||
|
if (filePath.Contains(StaticData.En_US_Json))
|
||||||
|
{
|
||||||
|
StaticData.En_US_Dic[section.Key] = section.Value;
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
StaticData.Zh_CN_Dic[section.Key] = section.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public async Task InitSysAndTrialCronJobAsync()
|
||||||
|
{
|
||||||
|
//var deleteJobIdList = await _trialEmailNoticeConfigRepository.Where(t => t.Trial.TrialStatusStr != StaticData.TrialState.TrialOngoing && t.EmailCron != string.Empty && t.IsAutoSend)
|
||||||
|
// .Select(t => t.TrialId + "_" + t.Id)
|
||||||
|
// .ToListAsync();
|
||||||
|
|
||||||
|
//foreach (var jobId in deleteJobIdList)
|
||||||
|
//{
|
||||||
|
// HangfireJobHelper.RemoveCronJob(jobId);
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
var taskInfoList = await _trialEmailNoticeConfigRepository.Where(t => t.Trial.TrialStatusStr == StaticData.TrialState.TrialOngoing && t.EmailCron != string.Empty && t.IsAutoSend)
|
||||||
|
.Select(t => new { t.Id, t.Code, t.EmailCron, t.BusinessScenarioEnum, t.TrialId })
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
foreach (var task in taskInfoList)
|
||||||
|
{
|
||||||
|
//利用主键作为任务Id
|
||||||
|
var jobId = $"{task.TrialId}_{task.Id}";
|
||||||
|
|
||||||
|
HangfireJobHelper.AddOrUpdateTrialCronJob(jobId, task.TrialId, task.BusinessScenarioEnum, task.EmailCron);
|
||||||
|
}
|
||||||
|
|
||||||
|
var addOrUpdateJobIdList = taskInfoList.Select(t => $"{t.TrialId}_{t.Id}").ToList();
|
||||||
|
|
||||||
|
var list = JobStorage.Current.GetConnection().GetRecurringJobs().ToList();
|
||||||
|
|
||||||
|
//项目定时任务都在default 队列
|
||||||
|
//var dbJobIdList = JobStorage.Current.GetConnection().GetRecurringJobs().Where(t => t.Queue == "default").Select(t => t.Id).ToList();
|
||||||
|
|
||||||
|
//var deleteList= dbJobIdList.Except(addOrUpdateJobIdList).ToList();
|
||||||
|
|
||||||
|
// foreach (var jobId in deleteList)
|
||||||
|
// {
|
||||||
|
// HangfireJobHelper.RemoveCronJob(jobId);
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,99 +0,0 @@
|
|||||||
using EasyCaching.Core;
|
|
||||||
using IRaCIS.Core.Domain.Share;
|
|
||||||
using Microsoft.EntityFrameworkCore.SqlServer.Query.Internal;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
|
|
||||||
namespace IRaCIS.Application.Services.BackGroundJob
|
|
||||||
{
|
|
||||||
|
|
||||||
public interface IIRaCISCacheHangfireJob
|
|
||||||
{
|
|
||||||
|
|
||||||
Task ProjectStartCache();
|
|
||||||
Task MemoryCacheTrialStatus();
|
|
||||||
|
|
||||||
Task MemoryCacheAnonymizeData();
|
|
||||||
|
|
||||||
Task CacheUserTypePermission(Guid? cacheUserTypeId);
|
|
||||||
}
|
|
||||||
public class IRaCISCacheHangfireJob: IIRaCISCacheHangfireJob
|
|
||||||
{
|
|
||||||
private readonly IRepository<Trial> _trialRepository;
|
|
||||||
private readonly IEasyCachingProvider _provider;
|
|
||||||
private readonly ILogger<IRaCISCacheHangfireJob> _logger;
|
|
||||||
private readonly IRepository<SystemAnonymization> _systemAnonymizationRepository;
|
|
||||||
|
|
||||||
private readonly IRepository<UserTypeMenu> _userTypeMenuRepository;
|
|
||||||
|
|
||||||
public IRaCISCacheHangfireJob(IRepository<Trial> trialRepository,
|
|
||||||
IRepository<SystemAnonymization> systemAnonymizationRepository, IRepository<UserTypeMenu> userTypeMenuRepository,
|
|
||||||
IEasyCachingProvider provider,ILogger<IRaCISCacheHangfireJob> logger)
|
|
||||||
{
|
|
||||||
_trialRepository = trialRepository;
|
|
||||||
_provider = provider;
|
|
||||||
_logger = logger;
|
|
||||||
_systemAnonymizationRepository = systemAnonymizationRepository;
|
|
||||||
_userTypeMenuRepository = userTypeMenuRepository;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public async Task ProjectStartCache()
|
|
||||||
{
|
|
||||||
_logger.LogInformation("hangfire 定时缓存项目状态任务开始~");
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await MemoryCacheTrialStatus();
|
|
||||||
|
|
||||||
await MemoryCacheAnonymizeData();
|
|
||||||
|
|
||||||
await CacheUserTypePermission();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
_logger.LogError("hangfire 定时任务执行失败" + e.Message);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
_logger.LogInformation("hangfire 定时任务执行结束");
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task MemoryCacheTrialStatus()
|
|
||||||
{
|
|
||||||
var list = await _trialRepository.Select(t => new { TrialId = t.Id, TrialStatusStr = t.TrialStatusStr })
|
|
||||||
.ToListAsync();
|
|
||||||
|
|
||||||
list.ForEach(t => _provider.Set(t.TrialId.ToString(), t.TrialStatusStr, TimeSpan.FromDays(7)));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public async Task MemoryCacheAnonymizeData()
|
|
||||||
{
|
|
||||||
var systemAnonymizationList = await _systemAnonymizationRepository.Where(t => t.IsEnable).ToListAsync();
|
|
||||||
|
|
||||||
_provider.Set(StaticData.Anonymize.Anonymize_AddFixedFiled, systemAnonymizationList.Where(t => t.IsAdd && t.IsFixed).ToList(), TimeSpan.FromDays(7));
|
|
||||||
_provider.Set(StaticData.Anonymize.Anonymize_AddIRCInfoFiled, systemAnonymizationList.Where(t => t.IsAdd && t.IsFixed == false).ToList(), TimeSpan.FromDays(7));
|
|
||||||
_provider.Set(StaticData.Anonymize.Anonymize_FixedField, systemAnonymizationList.Where(t => t.IsAdd == false && t.IsFixed).ToList(), TimeSpan.FromDays(7));
|
|
||||||
_provider.Set(StaticData.Anonymize.Anonymize_IRCInfoField, systemAnonymizationList.Where(t => t.IsAdd == false && t.IsFixed == false).ToList(), TimeSpan.FromDays(7));
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task CacheUserTypePermission(Guid? cacheUserTypeId=null)
|
|
||||||
{
|
|
||||||
|
|
||||||
var permissionList = await _userTypeMenuRepository.Where(t => t.Menu.MenuType == "F")
|
|
||||||
.WhereIf(cacheUserTypeId != null, t => t.UserTypeId == cacheUserTypeId.Value).Select(t => new { t.UserTypeId, t.Menu.PermissionStr }).ToListAsync();
|
|
||||||
|
|
||||||
foreach (var userTypeGroup in permissionList.GroupBy(t => t.UserTypeId))
|
|
||||||
{
|
|
||||||
_provider.Set($"{StaticData.CacheKey.UserTypeId}_{userTypeGroup.Key}", userTypeGroup.Select(t => t.PermissionStr).ToList(), TimeSpan.FromDays(7));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,11 @@
|
|||||||
using EasyCaching.Core;
|
using EasyCaching.Core;
|
||||||
using IRaCIS.Core.Domain.Share;
|
using IRaCIS.Core.Domain.Share;
|
||||||
|
using Microsoft.AspNetCore.Authentication;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.Mvc.Filters;
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
|
using Microsoft.Extensions.Localization;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
@@ -11,9 +14,9 @@ namespace IRaCIS.Core.Application.Filter;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class LimitUserRequestAuthorization :BaseService, IAsyncAuthorizationFilter
|
public class LimitUserRequestAuthorization : IAsyncAuthorizationFilter
|
||||||
{
|
{
|
||||||
|
public IStringLocalizer _localizer { get; set; }
|
||||||
|
|
||||||
private readonly IEasyCachingProvider _provider;
|
private readonly IEasyCachingProvider _provider;
|
||||||
|
|
||||||
@@ -21,16 +24,19 @@ public class LimitUserRequestAuthorization :BaseService, IAsyncAuthorizationFilt
|
|||||||
|
|
||||||
private readonly IOptionsMonitor<ServiceVerifyConfigOption> _verifyConfig;
|
private readonly IOptionsMonitor<ServiceVerifyConfigOption> _verifyConfig;
|
||||||
|
|
||||||
public LimitUserRequestAuthorization(IEasyCachingProvider provider, IUserInfo userInfo, IOptionsMonitor<ServiceVerifyConfigOption> verifyConfig)
|
public LimitUserRequestAuthorization(IEasyCachingProvider provider, IUserInfo userInfo, IStringLocalizer localizer ,IOptionsMonitor<ServiceVerifyConfigOption> verifyConfig)
|
||||||
{
|
{
|
||||||
_provider = provider;
|
_provider = provider;
|
||||||
_userInfo = userInfo;
|
_userInfo = userInfo;
|
||||||
_verifyConfig = verifyConfig;
|
_verifyConfig = verifyConfig;
|
||||||
|
_localizer = localizer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
|
public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
|
||||||
{
|
{
|
||||||
|
var minutes = _verifyConfig.CurrentValue.AutoLoginOutMinutes;
|
||||||
|
|
||||||
if (_verifyConfig.CurrentValue.OpenLoginLimit)
|
if (_verifyConfig.CurrentValue.OpenLoginLimit)
|
||||||
{
|
{
|
||||||
if (context.ActionDescriptor.EndpointMetadata.Any(item => item is IAllowAnonymous))
|
if (context.ActionDescriptor.EndpointMetadata.Any(item => item is IAllowAnonymous))
|
||||||
@@ -43,33 +49,56 @@ public class LimitUserRequestAuthorization :BaseService, IAsyncAuthorizationFilt
|
|||||||
{
|
{
|
||||||
//1、用户登陆的时候,设置缓存
|
//1、用户登陆的时候,设置缓存
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//没有从请求中取到token
|
//没有从请求中取到token
|
||||||
if (string.IsNullOrWhiteSpace(_userInfo.UserToken))
|
if (string.IsNullOrWhiteSpace(_userInfo.UserToken))
|
||||||
{
|
{
|
||||||
context.HttpContext.Response.ContentType = "application/json";
|
context.HttpContext.Response.ContentType = "application/json";
|
||||||
context.HttpContext.Response.StatusCode = StatusCodes.Status200OK;
|
context.HttpContext.Response.StatusCode = StatusCodes.Status200OK;
|
||||||
//---当前请求未从Header/Url取到用户Token,请联系开发者
|
//---当前请求未从Header/Url取到用户Token,请联系开发者
|
||||||
await context.HttpContext.Response.WriteAsync(JsonConvert.SerializeObject(ResponseOutput.NotOk(_localizer["LimitUser_AuthTokenMissing"])));
|
//await context.HttpContext.Response.WriteAsync(JsonConvert.SerializeObject(ResponseOutput.NotOk(_localizer["LimitUser_AuthTokenMissing"])));
|
||||||
|
|
||||||
|
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["LimitUser_AuthTokenMissing"]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//2、在这里取缓存 进行比较 看是否有其他人进行了登陆,如果其他人登陆了,就把之前用户挤掉
|
//2、在这里取缓存 进行比较 看是否有其他人进行了登陆,如果其他人登陆了,就把之前用户挤掉
|
||||||
var cacheUserToken = (await _provider.GetAsync<string>(_userInfo.Id.ToString())).Value;
|
var cacheUserToken = (await _provider.GetAsync<string>(_userInfo.Id.ToString())).Value;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//缓存中没有取到Token
|
//缓存中没有取到Token
|
||||||
if (string.IsNullOrWhiteSpace(cacheUserToken))
|
if (string.IsNullOrWhiteSpace(cacheUserToken))
|
||||||
{
|
{
|
||||||
|
cacheUserToken = _userInfo.UserToken;
|
||||||
|
|
||||||
//设置当前用户最新Token
|
//设置当前用户最新Token
|
||||||
await _provider.SetAsync(_userInfo.Id.ToString(), _userInfo.UserToken, TimeSpan.FromDays(7));
|
await _provider.SetAsync(_userInfo.Id.ToString(), _userInfo.UserToken, TimeSpan.FromDays(7));
|
||||||
|
|
||||||
cacheUserToken = _userInfo.UserToken;
|
//重启应用程序,所有人续期,不一下子踢出所有人
|
||||||
|
await _provider.SetAsync($"{_userInfo.Id.ToString()}_Online", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromMinutes(minutes));
|
||||||
|
|
||||||
}
|
}
|
||||||
//是同一个人
|
//是同一个人
|
||||||
else if (cacheUserToken == _userInfo.UserToken)
|
else if (cacheUserToken == _userInfo.UserToken)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
var cacheTime = (await _provider.GetAsync<string>($"{_userInfo.Id.ToString()}_Online")).Value;
|
||||||
|
|
||||||
|
//过期了 需要自动退出
|
||||||
|
if (string.IsNullOrEmpty(cacheTime))
|
||||||
|
{
|
||||||
|
context.HttpContext.Response.ContentType = "application/json";
|
||||||
|
context.HttpContext.Response.StatusCode = StatusCodes.Status403Forbidden;
|
||||||
|
|
||||||
|
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["LimitUser_AccountAuto_LoginOut"], ApiResponseCodeEnum.AutoLoginOut));
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await _provider.SetAsync($"{_userInfo.Id.ToString()}_Online", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromMinutes(minutes));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
@@ -78,7 +107,12 @@ public class LimitUserRequestAuthorization :BaseService, IAsyncAuthorizationFilt
|
|||||||
context.HttpContext.Response.ContentType = "application/json";
|
context.HttpContext.Response.ContentType = "application/json";
|
||||||
context.HttpContext.Response.StatusCode = StatusCodes.Status403Forbidden;
|
context.HttpContext.Response.StatusCode = StatusCodes.Status403Forbidden;
|
||||||
//---您的账户在其他地方已登陆,您被迫下线。
|
//---您的账户在其他地方已登陆,您被迫下线。
|
||||||
await context.HttpContext.Response.WriteAsync(JsonConvert.SerializeObject(ResponseOutput.NotOk(_localizer["LimitUser_AccountLoggedInElsewhere"], ApiResponseCodeEnum.LoginInOtherPlace)));
|
|
||||||
|
|
||||||
|
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["LimitUser_AccountLoggedInElsewhere"], ApiResponseCodeEnum.LoginInOtherPlace));
|
||||||
|
|
||||||
|
|
||||||
|
//await context.HttpContext.Response.WriteAsync(JsonConvert.SerializeObject(ResponseOutput.NotOk(_localizer["LimitUser_AccountLoggedInElsewhere"], ApiResponseCodeEnum.LoginInOtherPlace)));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,81 +0,0 @@
|
|||||||
//using System.Diagnostics;
|
|
||||||
//using IRaCIS.Application.Interfaces;
|
|
||||||
//using IRaCIS.Application.Contracts;
|
|
||||||
//using IRaCIS.Core.Infra.EFCore;
|
|
||||||
//using IRaCIS.Core.Infrastructure.Extention;
|
|
||||||
//using Microsoft.AspNetCore.Mvc;
|
|
||||||
//using Microsoft.AspNetCore.Mvc.Filters;
|
|
||||||
//using Microsoft.Extensions.Logging;
|
|
||||||
//using Newtonsoft.Json;
|
|
||||||
|
|
||||||
//namespace IRaCIS.Core.Application.Filter
|
|
||||||
//{
|
|
||||||
|
|
||||||
// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
|
|
||||||
// public class LogFilter : Attribute
|
|
||||||
// {
|
|
||||||
// }
|
|
||||||
// public class LogActionFilter : IAsyncActionFilter
|
|
||||||
// {
|
|
||||||
// private readonly ILogService _logService;
|
|
||||||
// private readonly IUserInfo _userInfo;
|
|
||||||
// private readonly ILogger<LogActionFilter> _logger;
|
|
||||||
|
|
||||||
// public LogActionFilter(ILogService logService, IUserInfo userInfo , ILogger<LogActionFilter> logger)
|
|
||||||
// {
|
|
||||||
// _logService = logService;
|
|
||||||
// _userInfo = userInfo;
|
|
||||||
// _logger = logger;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// public Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
|
|
||||||
// {
|
|
||||||
|
|
||||||
// if (context.ActionDescriptor.EndpointMetadata!=null&& context.ActionDescriptor.EndpointMetadata.Any(m => m.GetType() == typeof(LogFilter)))
|
|
||||||
// {
|
|
||||||
// return LogAsync(context, next);
|
|
||||||
// }
|
|
||||||
// return next();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// public async Task LogAsync(ActionExecutingContext context, ActionExecutionDelegate next)
|
|
||||||
// {
|
|
||||||
// var sw = new Stopwatch();
|
|
||||||
// sw.Start();
|
|
||||||
|
|
||||||
// dynamic actionResult = (await next()).Result;
|
|
||||||
// sw.Stop();
|
|
||||||
// var args = JsonConvert.SerializeObject(context.ActionArguments);
|
|
||||||
// var result = JsonConvert.SerializeObject(actionResult?.Value);
|
|
||||||
|
|
||||||
// var attr = (ApiExplorerSettingsAttribute)context.ActionDescriptor.EndpointMetadata.FirstOrDefault(m => m.GetType() == typeof(ApiExplorerSettingsAttribute));
|
|
||||||
// var groupName = attr?.GroupName;
|
|
||||||
// var res = actionResult?.Value as IResponseOutput;
|
|
||||||
// var input = new SystemLogDTO
|
|
||||||
// {
|
|
||||||
// ClientIP = string.Empty,
|
|
||||||
// OptUserId = _userInfo.Id,
|
|
||||||
// OptUserName = _userInfo.UserName,
|
|
||||||
// ApiPath = context.ActionDescriptor.AttributeRouteInfo.Template.ToLower(),
|
|
||||||
// Params = args,
|
|
||||||
// Result = result,
|
|
||||||
// RequestTime = DateTime.Now,
|
|
||||||
// ElapsedMilliseconds = sw.ElapsedMilliseconds,
|
|
||||||
// Status =res?.IsSuccess?? false,
|
|
||||||
// Message = res?.ErrorMessage,
|
|
||||||
// LogCategory = groupName
|
|
||||||
// };
|
|
||||||
|
|
||||||
// try
|
|
||||||
// {
|
|
||||||
// _logService.SaveLog2Db(input);
|
|
||||||
// }
|
|
||||||
// catch (Exception ex)
|
|
||||||
// {
|
|
||||||
|
|
||||||
// _logger.LogError(ex.Message);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
@@ -11,6 +11,12 @@ namespace IRaCIS.Core.Application.Filter
|
|||||||
|
|
||||||
public class ModelActionFilter : ActionFilterAttribute, IActionFilter
|
public class ModelActionFilter : ActionFilterAttribute, IActionFilter
|
||||||
{
|
{
|
||||||
|
public IStringLocalizer _localizer;
|
||||||
|
public ModelActionFilter(IStringLocalizer localizer)
|
||||||
|
{
|
||||||
|
_localizer = localizer;
|
||||||
|
}
|
||||||
|
|
||||||
public override void OnActionExecuting(ActionExecutingContext context)
|
public override void OnActionExecuting(ActionExecutingContext context)
|
||||||
{
|
{
|
||||||
if (!context.ModelState.IsValid)
|
if (!context.ModelState.IsValid)
|
||||||
@@ -23,7 +29,7 @@ namespace IRaCIS.Core.Application.Filter
|
|||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
||||||
//---提供给接口的参数无效。
|
//---提供给接口的参数无效。
|
||||||
context.Result = new JsonResult(ResponseOutput.NotOk("Invalid parameters provided for the API." + JsonConvert.SerializeObject( validationErrors)));
|
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["ModelAction_InvalidAPIParameter"] + JsonConvert.SerializeObject( validationErrors)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
using IRaCIS.Core.Infrastructure.Extention;
|
using IRaCIS.Core.Infrastructure.Extention;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.Mvc.Filters;
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
|
using Microsoft.Extensions.Localization;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace IRaCIS.Core.Application.Filter
|
namespace IRaCIS.Core.Application.Filter
|
||||||
@@ -10,9 +11,12 @@ namespace IRaCIS.Core.Application.Filter
|
|||||||
{
|
{
|
||||||
private readonly ILogger<ProjectExceptionFilter> _logger;
|
private readonly ILogger<ProjectExceptionFilter> _logger;
|
||||||
|
|
||||||
public ProjectExceptionFilter(ILogger<ProjectExceptionFilter> logger)
|
public IStringLocalizer _localizer;
|
||||||
|
|
||||||
|
public ProjectExceptionFilter(IStringLocalizer localizer, ILogger<ProjectExceptionFilter> logger)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
_localizer = localizer;
|
||||||
}
|
}
|
||||||
public void OnException(ExceptionContext context)
|
public void OnException(ExceptionContext context)
|
||||||
{
|
{
|
||||||
@@ -23,12 +27,14 @@ namespace IRaCIS.Core.Application.Filter
|
|||||||
if (context.Exception.GetType().Name == "DbUpdateConcurrencyException")
|
if (context.Exception.GetType().Name == "DbUpdateConcurrencyException")
|
||||||
{
|
{
|
||||||
//---并发更新,当前不允许该操作
|
//---并发更新,当前不允许该操作
|
||||||
context.Result = new JsonResult(ResponseOutput.NotOk("Concurrent update, operation not allowed at this time." + context.Exception.Message));
|
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["ProjectException_ConcurrentUpdateNotAllowed"] + context.Exception.Message));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context.Exception.GetType() == typeof(BusinessValidationFailedException))
|
if (context.Exception.GetType() == typeof(BusinessValidationFailedException))
|
||||||
{
|
{
|
||||||
context.Result = new JsonResult(ResponseOutput.NotOk(context.Exception.Message,ApiResponseCodeEnum.BusinessValidationFailed));
|
var error = context.Exception as BusinessValidationFailedException;
|
||||||
|
|
||||||
|
context.Result = new JsonResult(ResponseOutput.NotOk(context.Exception.Message, error!.Code));
|
||||||
}
|
}
|
||||||
else if(context.Exception.GetType() == typeof(QueryBusinessObjectNotExistException))
|
else if(context.Exception.GetType() == typeof(QueryBusinessObjectNotExistException))
|
||||||
{
|
{
|
||||||
@@ -36,7 +42,7 @@ namespace IRaCIS.Core.Application.Filter
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
context.Result = new JsonResult(ResponseOutput.NotOk("程序异常,请联系开发人员。" + (context.Exception.InnerException is null ? (context.Exception.Message /*+ context.Exception.StackTrace*/)
|
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["Project_ExceptionContactDeveloper"] + (context.Exception.InnerException is null ? (context.Exception.Message /*+ context.Exception.StackTrace*/)
|
||||||
: (context.Exception.InnerException?.Message /*+ context.Exception.InnerException?.StackTrace*/)), ApiResponseCodeEnum.ProgramException));
|
: (context.Exception.InnerException?.Message /*+ context.Exception.InnerException?.StackTrace*/)), ApiResponseCodeEnum.ProgramException));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -56,7 +56,7 @@ namespace IRaCIS.Core.Application.Filter
|
|||||||
#region 处理新的用户类型,不能操作项目相关接口
|
#region 处理新的用户类型,不能操作项目相关接口
|
||||||
|
|
||||||
// 后期列举出具体的类型,其他任何用户类型,都不允许操作
|
// 后期列举出具体的类型,其他任何用户类型,都不允许操作
|
||||||
if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA)
|
if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA && _userInfo.RequestUrl.ToLower()!= "TrialDocument/userConfirm".ToLower())
|
||||||
{
|
{
|
||||||
//---对不起,您的账户没有操作权限。
|
//---对不起,您的账户没有操作权限。
|
||||||
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["TrialResource_NoAccessPermission"]));
|
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["TrialResource_NoAccessPermission"]));
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ namespace IRaCIS.Application.Services.BusinessFilter
|
|||||||
|
|
||||||
//OK
|
//OK
|
||||||
var tuple = (dynamic)objectResult.Value;
|
var tuple = (dynamic)objectResult.Value;
|
||||||
var apiResponse = ResponseOutput.Ok(tuple.Item1, tuple.Item2);
|
var apiResponse = ResponseOutput.Ok(tuple!.Item1, tuple!.Item2);
|
||||||
|
|
||||||
|
|
||||||
objectResult.Value = apiResponse;
|
objectResult.Value = apiResponse;
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
using DocumentFormat.OpenXml.Drawing.Diagrams;
|
using DocumentFormat.OpenXml.Drawing.Diagrams;
|
||||||
|
using DocumentFormat.OpenXml.Spreadsheet;
|
||||||
|
using DocumentFormat.OpenXml.Wordprocessing;
|
||||||
|
using IRaCIS.Application.Contracts;
|
||||||
using IRaCIS.Application.Interfaces;
|
using IRaCIS.Application.Interfaces;
|
||||||
using IRaCIS.Core.Application.Helper;
|
using IRaCIS.Core.Application.Helper;
|
||||||
using IRaCIS.Core.Domain.Share;
|
using IRaCIS.Core.Domain.Share;
|
||||||
@@ -9,17 +12,22 @@ using MiniExcelLibs.OpenXml;
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using NPOI.HSSF.UserModel;
|
using NPOI.HSSF.UserModel;
|
||||||
|
using NPOI.XSSF.UserModel;
|
||||||
|
using System.Collections;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
namespace IRaCIS.Core.Application.Service;
|
namespace IRaCIS.Core.Application.Service;
|
||||||
|
|
||||||
public static class ExcelExportHelper
|
public static class ExcelExportHelper
|
||||||
{
|
{
|
||||||
//MiniExcel_Export
|
//MiniExcel_Export
|
||||||
public static async Task<IActionResult> DataExportAsync(string code, object data, string exportFileNamePrefix, IRepository<CommonDocument> _commonDocumentRepository, IWebHostEnvironment _hostEnvironment, IDictionaryService? _dictionaryService = null, Type? translateType = null, CriterionType? criterionType = null)
|
public static async Task<IActionResult> DataExportAsync(string code, ExcelExportInfo data, string exportFileNamePrefix, IRepository<CommonDocument> _commonDocumentRepository, IWebHostEnvironment _hostEnvironment, IDictionaryService? _dictionaryService = null, Type? translateType = null, CriterionType? criterionType = null)
|
||||||
{
|
{
|
||||||
|
|
||||||
//判断是否有字典翻译
|
//判断是否有字典翻译
|
||||||
|
|
||||||
|
object translateData = data;
|
||||||
|
|
||||||
if (_dictionaryService != null && translateType != null)
|
if (_dictionaryService != null && translateType != null)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -42,20 +50,24 @@ public static class ExcelExportHelper
|
|||||||
var translateDataList = await _dictionaryService.GetBasicDataSelect(needTranslatePropertyList.Select(t => t.DicParentCode).Distinct().ToArray());
|
var translateDataList = await _dictionaryService.GetBasicDataSelect(needTranslatePropertyList.Select(t => t.DicParentCode).Distinct().ToArray());
|
||||||
|
|
||||||
|
|
||||||
var dic = JsonConvert.DeserializeObject<IDictionary<string, object>>(data.ToJsonNotIgnoreNull());
|
var dic = data.ConvertToDictionary();
|
||||||
|
|
||||||
|
|
||||||
foreach (var key in dic.Keys)
|
foreach (var key in dic.Keys)
|
||||||
{
|
{
|
||||||
//是数组 那么找到对应的属性 进行翻译
|
//是数组 那么找到对应的属性 进行翻译
|
||||||
if (dic[key].GetType().IsAssignableFrom(typeof(JArray)))
|
if (dic[key].GetType().GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IList<>)))
|
||||||
{
|
{
|
||||||
|
|
||||||
var newObjList = new List<object>();
|
var newObjList = new List<object>();
|
||||||
var no = 1;
|
var no = 1;
|
||||||
|
|
||||||
foreach (var item in dic[key] as JArray)
|
foreach (var item in dic[key] as IList )
|
||||||
{
|
{
|
||||||
var itemDic = JsonConvert.DeserializeObject<IDictionary<string, object>>(item.ToJsonNotIgnoreNull());
|
//var itemDic = JsonConvert.DeserializeObject<IDictionary<string, object>>(item.ToJsonNotIgnoreNull());
|
||||||
|
|
||||||
|
var itemDic = item.ConvertToDictionary();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
foreach (var needTranslateProperty in needTranslatePropertyList)
|
foreach (var needTranslateProperty in needTranslatePropertyList)
|
||||||
@@ -63,11 +75,11 @@ public static class ExcelExportHelper
|
|||||||
//翻译的属性依赖其他属性
|
//翻译的属性依赖其他属性
|
||||||
if (needTranslateProperty.IsTranslateDenpendOtherProperty)
|
if (needTranslateProperty.IsTranslateDenpendOtherProperty)
|
||||||
{
|
{
|
||||||
if (item[needTranslateProperty.DependPropertyName]?.ToString().ToLower() == needTranslateProperty.DependPropertyValueStr.ToLower())
|
if (itemDic[needTranslateProperty.DependPropertyName]?.ToString().ToLower() == needTranslateProperty.DependPropertyValueStr.ToLower())
|
||||||
{
|
{
|
||||||
var beforeValue = itemDic[needTranslateProperty.Name]?.ToString();
|
var beforeValue = itemDic[needTranslateProperty.Name]?.ToString();
|
||||||
|
|
||||||
itemDic[needTranslateProperty.Name] = translateDataList[needTranslateProperty.DicParentCode].Where(t => t.Code.ToLower() == beforeValue?.ToLower()).FirstOrDefault()?.ValueCN ?? String.Empty;
|
itemDic[needTranslateProperty.Name] = translateDataList[needTranslateProperty.DicParentCode].Where(t => t.Code.ToLower() == beforeValue?.ToLower()).Select(t=>data.IsEn_US?t.Value:t.ValueCN).FirstOrDefault() ?? String.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//普通翻译 或者某一标准翻译
|
//普通翻译 或者某一标准翻译
|
||||||
@@ -76,7 +88,7 @@ public static class ExcelExportHelper
|
|||||||
var beforeValue = itemDic[needTranslateProperty.Name]?.ToString();
|
var beforeValue = itemDic[needTranslateProperty.Name]?.ToString();
|
||||||
|
|
||||||
|
|
||||||
itemDic[needTranslateProperty.Name] = translateDataList[needTranslateProperty.DicParentCode].Where(t => t.Code.ToLower() == beforeValue?.ToLower()).FirstOrDefault()?.ValueCN ?? String.Empty;
|
itemDic[needTranslateProperty.Name] = translateDataList[needTranslateProperty.DicParentCode].Where(t => t.Code.ToLower() == beforeValue?.ToLower()).Select(t => data.IsEn_US ? t.Value : t.ValueCN).FirstOrDefault() ?? String.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -95,8 +107,9 @@ public static class ExcelExportHelper
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
data = dic;
|
//data = dic;
|
||||||
|
|
||||||
|
translateData = dic;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,6 +123,48 @@ public static class ExcelExportHelper
|
|||||||
//模板路径
|
//模板路径
|
||||||
var tplPath = physicalPath;
|
var tplPath = physicalPath;
|
||||||
|
|
||||||
|
#region 根据中英文 删除模板sheet
|
||||||
|
|
||||||
|
// 打开模板文件
|
||||||
|
var templateFile = new FileStream(tplPath, FileMode.Open, FileAccess.Read);
|
||||||
|
|
||||||
|
// 获取文件流
|
||||||
|
var templateStream = new MemoryStream();
|
||||||
|
templateFile.CopyTo(templateStream);
|
||||||
|
templateStream.Seek(0, SeekOrigin.Begin);
|
||||||
|
|
||||||
|
var workbook = new XSSFWorkbook(templateStream);
|
||||||
|
|
||||||
|
int sheetCount = workbook.NumberOfSheets;
|
||||||
|
|
||||||
|
if (sheetCount == 2)
|
||||||
|
{
|
||||||
|
if (data.IsEn_US)
|
||||||
|
{
|
||||||
|
workbook.RemoveSheetAt(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
workbook.RemoveSheetAt(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
var memoryStream2 = new MemoryStream();
|
||||||
|
workbook.Write(memoryStream2,true);
|
||||||
|
|
||||||
|
memoryStream2.Seek(0, SeekOrigin.Begin);
|
||||||
|
|
||||||
|
templateStream = memoryStream2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 文件名称 从sheet里面取
|
||||||
|
fileNmae = workbook.GetSheetName(0);
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#region MiniExcel
|
#region MiniExcel
|
||||||
|
|
||||||
var memoryStream = new MemoryStream();
|
var memoryStream = new MemoryStream();
|
||||||
@@ -119,13 +174,14 @@ public static class ExcelExportHelper
|
|||||||
IgnoreTemplateParameterMissing = true,
|
IgnoreTemplateParameterMissing = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
await MiniExcel.SaveAsByTemplateAsync(memoryStream, tplPath, data, config);
|
await MiniExcel.SaveAsByTemplateAsync(memoryStream, templateStream.ToArray(), translateData, config);
|
||||||
|
|
||||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||||
|
|
||||||
|
|
||||||
return new FileStreamResult(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
|
return new FileStreamResult(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
|
||||||
{
|
{
|
||||||
FileDownloadName = $"{exportFileNamePrefix}_{fileNmae.Substring(0, fileNmae.LastIndexOf('.'))}_{DateTime.Now.ToString("yyyyMMddHHmmss")}.xlsx"
|
FileDownloadName = $"{exportFileNamePrefix}_{fileNmae/*.Substring(0, fileNmae.LastIndexOf('.'))*/}_{DateTime.Now.ToString("yyyyMMddHHmmss")}.xlsx"
|
||||||
};
|
};
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@@ -146,10 +202,12 @@ public static class ExcelExportHelper
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static async Task<(MemoryStream,string)> DataExport_NpoiTestAsync(string code, object data, IRepository<CommonDocument> _commonDocumentRepository, IWebHostEnvironment _hostEnvironment, IDictionaryService? _dictionaryService = null, Type? translateType = null, CriterionType? criterionType = null)
|
public static async Task<(MemoryStream, string)> DataExport_NpoiTestAsync(string code, ExcelExportInfo data, IRepository<CommonDocument> _commonDocumentRepository, IWebHostEnvironment _hostEnvironment, IDictionaryService? _dictionaryService = null, Type? translateType = null, CriterionType? criterionType = null)
|
||||||
{
|
{
|
||||||
//判断是否有字典翻译
|
//判断是否有字典翻译
|
||||||
|
|
||||||
|
object translateData = data;
|
||||||
|
|
||||||
if (_dictionaryService != null && translateType != null)
|
if (_dictionaryService != null && translateType != null)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -171,33 +229,34 @@ public static class ExcelExportHelper
|
|||||||
|
|
||||||
var translateDataList = await _dictionaryService.GetBasicDataSelect(needTranslatePropertyList.Select(t => t.DicParentCode).Distinct().ToArray());
|
var translateDataList = await _dictionaryService.GetBasicDataSelect(needTranslatePropertyList.Select(t => t.DicParentCode).Distinct().ToArray());
|
||||||
|
|
||||||
|
var dic = data.ConvertToDictionary();
|
||||||
var dic = JsonConvert.DeserializeObject<IDictionary<string, object>>(data.ToJsonNotIgnoreNull());
|
//var dic = (JsonConvert.DeserializeObject<IDictionary<string, object>>(data.ToJsonNotIgnoreNull())).IfNullThrowException();
|
||||||
|
|
||||||
foreach (var key in dic.Keys)
|
foreach (var key in dic.Keys)
|
||||||
{
|
{
|
||||||
//是数组 那么找到对应的属性 进行翻译
|
//是数组 那么找到对应的属性 进行翻译
|
||||||
if (dic[key].GetType().IsAssignableFrom(typeof(JArray)))
|
if (dic[key].GetType().GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IList<>)))
|
||||||
|
//if (dic[key].GetType().IsAssignableFrom(typeof(JArray)))
|
||||||
{
|
{
|
||||||
|
|
||||||
var newObjList = new List<object>();
|
var newObjList = new List<object>();
|
||||||
var no = 1;
|
var no = 1;
|
||||||
|
foreach (var item in dic[key] as IList)
|
||||||
foreach (var item in dic[key] as JArray)
|
//foreach (var item in dic[key] as JArray)
|
||||||
{
|
{
|
||||||
var itemDic = JsonConvert.DeserializeObject<IDictionary<string, object>>(item.ToJsonNotIgnoreNull());
|
//var itemDic = JsonConvert.DeserializeObject<IDictionary<string, object>>(item.ToJsonNotIgnoreNull());
|
||||||
|
var itemDic = item.ConvertToDictionary();
|
||||||
|
|
||||||
foreach (var needTranslateProperty in needTranslatePropertyList)
|
foreach (var needTranslateProperty in needTranslatePropertyList)
|
||||||
{
|
{
|
||||||
//翻译的属性依赖其他属性
|
//翻译的属性依赖其他属性
|
||||||
if (needTranslateProperty.IsTranslateDenpendOtherProperty)
|
if (needTranslateProperty.IsTranslateDenpendOtherProperty)
|
||||||
{
|
{
|
||||||
if (item[needTranslateProperty.DependPropertyName]?.ToString().ToLower() == needTranslateProperty.DependPropertyValueStr.ToLower())
|
if (itemDic[needTranslateProperty.DependPropertyName]?.ToString().ToLower() == needTranslateProperty.DependPropertyValueStr.ToLower())
|
||||||
{
|
{
|
||||||
var beforeValue = itemDic[needTranslateProperty.Name]?.ToString();
|
var beforeValue = itemDic[needTranslateProperty.Name]?.ToString();
|
||||||
|
|
||||||
itemDic[needTranslateProperty.Name] = translateDataList[needTranslateProperty.DicParentCode].Where(t => t.Code.ToLower() == beforeValue?.ToLower()).FirstOrDefault()?.ValueCN ?? String.Empty;
|
itemDic[needTranslateProperty.Name] = translateDataList[needTranslateProperty.DicParentCode].Where(t => t.Code.ToLower() == beforeValue?.ToLower()).Select(t => data.IsEn_US ? t.Value : t.ValueCN).FirstOrDefault() ?? String.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//普通翻译 或者某一标准翻译
|
//普通翻译 或者某一标准翻译
|
||||||
@@ -206,7 +265,7 @@ public static class ExcelExportHelper
|
|||||||
var beforeValue = itemDic[needTranslateProperty.Name]?.ToString();
|
var beforeValue = itemDic[needTranslateProperty.Name]?.ToString();
|
||||||
|
|
||||||
|
|
||||||
itemDic[needTranslateProperty.Name] = translateDataList[needTranslateProperty.DicParentCode].Where(t => t.Code.ToLower() == beforeValue?.ToLower()).FirstOrDefault()?.ValueCN ?? String.Empty;
|
itemDic[needTranslateProperty.Name] = translateDataList[needTranslateProperty.DicParentCode].Where(t => t.Code.ToLower() == beforeValue?.ToLower()).Select(t => data.IsEn_US ? t.Value : t.ValueCN).FirstOrDefault() ?? String.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -223,8 +282,8 @@ public static class ExcelExportHelper
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
data = dic;
|
//data = dic;
|
||||||
|
translateData = dic;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -235,6 +294,43 @@ public static class ExcelExportHelper
|
|||||||
//模板路径
|
//模板路径
|
||||||
var tplPath = physicalPath;
|
var tplPath = physicalPath;
|
||||||
|
|
||||||
|
#region 根据中英文 删除模板sheet
|
||||||
|
|
||||||
|
// 打开模板文件
|
||||||
|
var templateFile = new FileStream(tplPath, FileMode.Open, FileAccess.Read);
|
||||||
|
|
||||||
|
// 获取文件流
|
||||||
|
var templateStream = new MemoryStream();
|
||||||
|
templateFile.CopyTo(templateStream);
|
||||||
|
templateStream.Seek(0, SeekOrigin.Begin);
|
||||||
|
|
||||||
|
var workbook = new XSSFWorkbook(templateStream);
|
||||||
|
|
||||||
|
int sheetCount = workbook.NumberOfSheets;
|
||||||
|
|
||||||
|
if (sheetCount == 2)
|
||||||
|
{
|
||||||
|
if (data.IsEn_US)
|
||||||
|
{
|
||||||
|
workbook.RemoveSheetAt(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
workbook.RemoveSheetAt(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
var memoryStream2 = new MemoryStream();
|
||||||
|
workbook.Write(memoryStream2,true);
|
||||||
|
|
||||||
|
memoryStream2.Seek(0, SeekOrigin.Begin);
|
||||||
|
|
||||||
|
templateStream = memoryStream2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 文件名称 从sheet里面取
|
||||||
|
fileName = workbook.GetSheetName(0);
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region MiniExcel
|
#region MiniExcel
|
||||||
|
|
||||||
var memoryStream = new MemoryStream();
|
var memoryStream = new MemoryStream();
|
||||||
@@ -244,7 +340,7 @@ public static class ExcelExportHelper
|
|||||||
IgnoreTemplateParameterMissing = true,
|
IgnoreTemplateParameterMissing = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
await MiniExcel.SaveAsByTemplateAsync(memoryStream, tplPath, data, config);
|
await MiniExcel.SaveAsByTemplateAsync(memoryStream, templateStream.ToArray(), translateData, config);
|
||||||
|
|
||||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace IRaCIS.Core.Application.Helper
|
||||||
|
{
|
||||||
|
public class FileConvertHelper
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
static public void ConvertWordToPdf(string inputWordFilePath, string outputPdfDir)
|
||||||
|
{
|
||||||
|
// 设置 libreoffice 命令行参数
|
||||||
|
string arguments = $"--headless --invisible --convert-to pdf \"{inputWordFilePath}\" --outdir \"{outputPdfDir}\"";
|
||||||
|
|
||||||
|
// 启动 libreoffice 进程
|
||||||
|
using (Process process = new Process())
|
||||||
|
{
|
||||||
|
process.StartInfo.FileName = "libreoffice";
|
||||||
|
process.StartInfo.Arguments = arguments;
|
||||||
|
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
|
||||||
|
process.StartInfo.RedirectStandardOutput = true;
|
||||||
|
process.StartInfo.RedirectStandardError = true;
|
||||||
|
process.StartInfo.UseShellExecute = false;
|
||||||
|
process.StartInfo.CreateNoWindow = true;
|
||||||
|
|
||||||
|
process.Start();
|
||||||
|
|
||||||
|
// 等待进程结束
|
||||||
|
process.WaitForExit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
using DocumentFormat.OpenXml.Bibliography;
|
|
||||||
using NPOI.XWPF.UserModel;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace IRaCIS.Core.Application.Helper
|
|
||||||
{
|
|
||||||
public class FileFormatConvertHelper
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,12 @@
|
|||||||
|
|
||||||
|
|
||||||
|
using Aliyun.OSS;
|
||||||
using IRaCIS.Core.Domain.Share;
|
using IRaCIS.Core.Domain.Share;
|
||||||
using IRaCIS.Core.Infrastructure;
|
using IRaCIS.Core.Infrastructure;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using System.Configuration;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
namespace IRaCIS.Core.Application.Helper;
|
namespace IRaCIS.Core.Application.Helper;
|
||||||
@@ -10,7 +14,6 @@ namespace IRaCIS.Core.Application.Helper;
|
|||||||
public static class FileStoreHelper
|
public static class FileStoreHelper
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
//处理文件名 压缩包,或者目录类的 会带上相对路径
|
//处理文件名 压缩包,或者目录类的 会带上相对路径
|
||||||
public static (string TrustedFileNameForFileStorage, string RealName) GetStoreFileName(string fileName,bool isChangeToPdfFormat=false)
|
public static (string TrustedFileNameForFileStorage, string RealName) GetStoreFileName(string fileName,bool isChangeToPdfFormat=false)
|
||||||
{
|
{
|
||||||
@@ -53,8 +56,9 @@ public static class FileStoreHelper
|
|||||||
//API vue 部署目录
|
//API vue 部署目录
|
||||||
public static string GetIRaCISRootPath(IWebHostEnvironment _hostEnvironment)
|
public static string GetIRaCISRootPath(IWebHostEnvironment _hostEnvironment)
|
||||||
{
|
{
|
||||||
var rootPath = (Directory.GetParent(_hostEnvironment.ContentRootPath.TrimEnd('\\'))).IfNullThrowException().FullName;
|
string parentDirectory = Path.GetFullPath(Path.Combine(_hostEnvironment.ContentRootPath, ".."));
|
||||||
return rootPath;
|
|
||||||
|
return parentDirectory;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,11 +78,56 @@ public static class FileStoreHelper
|
|||||||
{
|
{
|
||||||
var rootPath = GetIRaCISRootPath(_hostEnvironment);
|
var rootPath = GetIRaCISRootPath(_hostEnvironment);
|
||||||
|
|
||||||
var physicalFilePath = Path.Combine(rootPath, relativePath.Trim('/'));
|
var physicalFilePath = Path.Combine(rootPath, relativePath.TrimStart('/'));
|
||||||
|
|
||||||
return physicalFilePath;
|
return physicalFilePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#region 修改后留存
|
||||||
|
|
||||||
|
|
||||||
|
public static (string PhysicalPath, string RelativePath) GetSystemFileUploadPath(IWebHostEnvironment _hostEnvironment, string templateFolderName, string fileName)
|
||||||
|
{
|
||||||
|
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
|
||||||
|
|
||||||
|
//文件类型路径处理
|
||||||
|
var uploadFolderPath = Path.Combine(rootPath, StaticData.Folder.SystemDataFolder, templateFolderName);
|
||||||
|
if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath);
|
||||||
|
|
||||||
|
|
||||||
|
var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName);
|
||||||
|
|
||||||
|
|
||||||
|
var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.SystemDataFolder}/{templateFolderName}/{trustedFileNameForFileStorage}";
|
||||||
|
|
||||||
|
var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
|
||||||
|
|
||||||
|
return (serverFilePath, relativePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static (string PhysicalPath, string RelativePath) GetOtherFileUploadPath(IWebHostEnvironment _hostEnvironment, string templateFolderName, string fileName)
|
||||||
|
{
|
||||||
|
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
|
||||||
|
|
||||||
|
//文件类型路径处理
|
||||||
|
var uploadFolderPath = Path.Combine(rootPath, StaticData.Folder.OtherDataFolder, templateFolderName);
|
||||||
|
if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath);
|
||||||
|
|
||||||
|
|
||||||
|
var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName);
|
||||||
|
|
||||||
|
|
||||||
|
var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.OtherDataFolder}/{templateFolderName}/{trustedFileNameForFileStorage}";
|
||||||
|
|
||||||
|
var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
|
||||||
|
|
||||||
|
return (serverFilePath, relativePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -380,7 +429,6 @@ public static class FileStoreHelper
|
|||||||
/// <param name="trialId"></param>
|
/// <param name="trialId"></param>
|
||||||
/// <param name="siteid"></param>
|
/// <param name="siteid"></param>
|
||||||
/// <param name="subjectId"></param>
|
/// <param name="subjectId"></param>
|
||||||
/// <param name="type"></param>
|
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static (string PhysicalPath, string RelativePath, string FileRealName) GetUploadPrintscreenFilePath(IWebHostEnvironment _hostEnvironment, string fileName, Guid trialId, Guid siteid, Guid subjectId)
|
public static (string PhysicalPath, string RelativePath, string FileRealName) GetUploadPrintscreenFilePath(IWebHostEnvironment _hostEnvironment, string fileName, Guid trialId, Guid siteid, Guid subjectId)
|
||||||
{
|
{
|
||||||
@@ -467,18 +515,18 @@ public static class FileStoreHelper
|
|||||||
|
|
||||||
// 获取 入组确认 PD 进展发送邮件Word|PDF 存放路径
|
// 获取 入组确认 PD 进展发送邮件Word|PDF 存放路径
|
||||||
|
|
||||||
public static (string PhysicalPath, string RelativePath, string FileRealName) GetSubjectEnrollConfirmOrPDEmailPath(IWebHostEnvironment _hostEnvironment, string fileName, Guid trialId, Guid siteId, Guid subjectId,bool isChangeToPdfFormat=false)
|
public static (string PhysicalPath, string RelativePath, string FileRealName) GetSubjectEnrollConfirmOrPDEmailPath(IWebHostEnvironment _hostEnvironment, string fileName, Guid trialId, Guid trialSiteId, Guid subjectId,bool isChangeToPdfFormat=false)
|
||||||
{
|
{
|
||||||
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
|
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
|
||||||
|
|
||||||
string uploadFolderPath = Path.Combine(rootPath, StaticData.Folder.TrialDataFolder, trialId.ToString(), siteId.ToString(), subjectId.ToString());
|
string uploadFolderPath = Path.Combine(rootPath, StaticData.Folder.TrialDataFolder, trialId.ToString(), trialSiteId.ToString(), subjectId.ToString());
|
||||||
|
|
||||||
if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath);
|
if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath);
|
||||||
|
|
||||||
var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName, isChangeToPdfFormat);
|
var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName, isChangeToPdfFormat);
|
||||||
|
|
||||||
|
|
||||||
var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.TrialDataFolder}/{trialId}/{siteId}/{subjectId}/{trustedFileNameForFileStorage}";
|
var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.TrialDataFolder}/{trialId}/{trialSiteId}/{subjectId}/{trustedFileNameForFileStorage}";
|
||||||
|
|
||||||
var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
|
var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
|
||||||
|
|
||||||
@@ -493,13 +541,18 @@ public static class FileStoreHelper
|
|||||||
return Path.Combine(rootPath, StaticData.Folder.TrialDataFolder, trialId.ToString(), siteId.ToString(), subjectId.ToString(), subjectVisitId.ToString(), StaticData.Folder.DicomFolder);
|
return Path.Combine(rootPath, StaticData.Folder.TrialDataFolder, trialId.ToString(), siteId.ToString(), subjectId.ToString(), subjectVisitId.ToString(), StaticData.Folder.DicomFolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static (string PhysicalPath, string RelativePath) GetDicomInstanceFilePath(IWebHostEnvironment _hostEnvironment, Guid trialId, Guid siteId, Guid subjectId, Guid subjectVisitId, Guid studyId, Guid instanceId)
|
public static (string PhysicalPath, string RelativePath) GetDicomInstanceFilePath(IWebHostEnvironment _hostEnvironment, Guid trialId, Guid subjectId, Guid subjectVisitId, Guid studyId, Guid instanceId)
|
||||||
{
|
{
|
||||||
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
|
#region 切换存储前
|
||||||
|
//var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
|
||||||
|
#endregion
|
||||||
|
var rootPath = Path.Combine(FileStoreHelper.GetBestStoreDisk(_hostEnvironment), StaticData.Folder.IRaCISDataFolder) ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//加入访视层级 和Data
|
//加入访视层级 和Data
|
||||||
var path = Path.Combine(rootPath, StaticData.Folder.TrialDataFolder, trialId.ToString(),
|
var path = Path.Combine(rootPath, StaticData.Folder.TrialDataFolder, trialId.ToString(),
|
||||||
siteId.ToString(), subjectId.ToString(), subjectVisitId.ToString(), StaticData.Folder.DicomFolder, studyId.ToString());
|
subjectId.ToString(), subjectVisitId.ToString(), StaticData.Folder.DicomFolder, studyId.ToString());
|
||||||
|
|
||||||
if (!Directory.Exists(path))
|
if (!Directory.Exists(path))
|
||||||
{
|
{
|
||||||
@@ -508,7 +561,7 @@ public static class FileStoreHelper
|
|||||||
|
|
||||||
var physicalPath = Path.Combine(path, instanceId.ToString() );
|
var physicalPath = Path.Combine(path, instanceId.ToString() );
|
||||||
|
|
||||||
var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.TrialDataFolder}/{trialId}/{siteId}/{subjectId}/{subjectVisitId}/{StaticData.Folder.DicomFolder}/{studyId}/{instanceId}";
|
var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.TrialDataFolder}/{trialId}/{subjectId}/{subjectVisitId}/{StaticData.Folder.DicomFolder}/{studyId}/{instanceId}";
|
||||||
|
|
||||||
//var physicalPath = Path.Combine(path, instanceId.ToString() + ".dcm");
|
//var physicalPath = Path.Combine(path, instanceId.ToString() + ".dcm");
|
||||||
|
|
||||||
@@ -517,6 +570,62 @@ public static class FileStoreHelper
|
|||||||
return (physicalPath, relativePath);
|
return (physicalPath, relativePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string GetBestStoreDisk(IWebHostEnvironment _hostEnvironment)
|
||||||
|
{
|
||||||
|
|
||||||
|
var json = File.ReadAllText( Path.Combine(_hostEnvironment.ContentRootPath, "appsettings.json"));
|
||||||
|
|
||||||
|
JObject jsonObject = (JObject.Parse(json, new JsonLoadSettings() { CommentHandling = CommentHandling.Load })).IfNullThrowException();
|
||||||
|
|
||||||
|
int switchingRatio = 80;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
switchingRatio = (int)jsonObject["IRaCISImageStore"]["SwitchingRatio"];
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
|
||||||
|
//---解析Json文件配置出现问题
|
||||||
|
throw new BusinessValidationFailedException(StaticData.International("SysMon_JsonConfig") + e.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
//默认存储的路径
|
||||||
|
var defaultStoreRootFolder = FileStoreHelper.GetIRaCISRootPath(_hostEnvironment);
|
||||||
|
|
||||||
|
|
||||||
|
DriveInfo defaultDrive = new DriveInfo(Path.GetPathRoot(defaultStoreRootFolder));
|
||||||
|
|
||||||
|
var drives = DriveInfo.GetDrives().Where(t => !t.Name.Contains("C") && !t.Name.Contains("c"))
|
||||||
|
.Where(d => d.DriveType == DriveType.Fixed && d.IsReady)
|
||||||
|
//剩余空间最多的
|
||||||
|
.OrderByDescending(d => d.AvailableFreeSpace)
|
||||||
|
|
||||||
|
//存储空间相同,则按照按照总空间从大到小排序
|
||||||
|
.ThenByDescending(d => d.TotalSize - d.TotalFreeSpace);
|
||||||
|
|
||||||
|
var bestDrive = drives.FirstOrDefault();
|
||||||
|
var bestStoreRootFolder = string.Empty;
|
||||||
|
|
||||||
|
//仅仅只有C 盘
|
||||||
|
if (bestDrive == null || ((double)(defaultDrive.TotalSize - defaultDrive.TotalFreeSpace) / defaultDrive.TotalSize) * 100 < switchingRatio)
|
||||||
|
{
|
||||||
|
bestStoreRootFolder = defaultStoreRootFolder;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bestStoreRootFolder = Path.Combine(bestDrive?.RootDirectory.FullName, _hostEnvironment.EnvironmentName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Directory.Exists(bestStoreRootFolder))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(bestStoreRootFolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
return bestStoreRootFolder;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,92 @@
|
|||||||
|
using Hangfire;
|
||||||
|
using IRaCIS.Core.Application.Service;
|
||||||
|
using IRaCIS.Core.Domain.Share;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using NPOI.SS.Formula.Functions;
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace IRaCIS.Core.Application.Helper
|
||||||
|
{
|
||||||
|
public static class HangfireJobHelper
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//public static void AddOrUpdateCronJob(string jobId, string queueName, Expression<Action> methodCall, string cron)
|
||||||
|
//{
|
||||||
|
// RecurringJob.AddOrUpdate(jobId, queueName, methodCall, cron);
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//添加 或者更新定时任务 Id 要唯一标识一个定义任务
|
||||||
|
public static void AddOrUpdateCronJob<T>(string jobId, Expression<Action<T>> methodCall, string cron, string queueName = "default")
|
||||||
|
{
|
||||||
|
RecurringJob.AddOrUpdate<T>(jobId, queueName, methodCall, cron);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void AddOrUpdateInitCronJob<T>(string jobId, Expression<Action<T>> methodCall, string cron)
|
||||||
|
{
|
||||||
|
RecurringJob.AddOrUpdate<T>(jobId, "sys_init", methodCall, cron);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void RemoveCronJob(string jobId)
|
||||||
|
{
|
||||||
|
RecurringJob.RemoveIfExists(jobId);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static void ImmediatelyOnceOnlyJob(Expression<Action> methodCall)
|
||||||
|
{
|
||||||
|
BackgroundJob.Enqueue("immediately_once", methodCall);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ImmediatelyOnceOnlyJob<T>(Expression<Action<T>> methodCall)
|
||||||
|
{
|
||||||
|
BackgroundJob.Enqueue<T>("immediately_once", methodCall);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void NotImmediatelyOnceOnlyJob(Expression<Action> methodCall, TimeSpan timeSpan)
|
||||||
|
{
|
||||||
|
BackgroundJob.Schedule("not_immediately_once", methodCall, timeSpan);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void NotImmediatelyOnceOnlyJob<T>(Expression<Action<T>> methodCall, TimeSpan timeSpan)
|
||||||
|
{
|
||||||
|
BackgroundJob.Schedule<T>("not_immediately_once", methodCall, timeSpan);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void AddOrUpdateTrialCronJob (string jobId, Guid trialId, EmailBusinessScenario businessScenario, string emailCron)
|
||||||
|
{
|
||||||
|
|
||||||
|
switch (businessScenario)
|
||||||
|
{
|
||||||
|
|
||||||
|
case EmailBusinessScenario.QCTask:
|
||||||
|
HangfireJobHelper.AddOrUpdateCronJob<IEmailSendService>(jobId, t => t.SendTrialImageQCTaskEmailAsync(trialId), emailCron);
|
||||||
|
break;
|
||||||
|
case EmailBusinessScenario.QCQuestion:
|
||||||
|
HangfireJobHelper.AddOrUpdateCronJob<IEmailSendService>(jobId, t => t.SendTrialQCQuestionEmailAsync(trialId), emailCron);
|
||||||
|
break;
|
||||||
|
case EmailBusinessScenario.ImageQuestion:
|
||||||
|
HangfireJobHelper.AddOrUpdateCronJob<IEmailSendService>(jobId, t => t.SendTrialImageQuestionAsync(trialId), emailCron);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,179 @@
|
|||||||
|
using IRaCIS.Core.Application.ViewModel;
|
||||||
|
using IRaCIS.Core.Domain.Share;
|
||||||
|
using IRaCIS.Core.Infrastructure;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using static BeetleX.Redis.Commands.HSCAN;
|
||||||
|
using static IRaCIS.Core.Application.Service.Common.SystemMonitor;
|
||||||
|
|
||||||
|
namespace IRaCIS.Core.Application.Helper
|
||||||
|
{
|
||||||
|
public static class InternationalizationHelper
|
||||||
|
{
|
||||||
|
public static string JsonFileFolder = Path.Combine(AppContext.BaseDirectory, StaticData.Folder.Resources);
|
||||||
|
|
||||||
|
private static void VerifyFolder()
|
||||||
|
{
|
||||||
|
if (!Directory.Exists(JsonFileFolder) ||
|
||||||
|
!Directory.GetFiles(JsonFileFolder).Any(filePath => Path.GetExtension(filePath).Equals(".json", StringComparison.OrdinalIgnoreCase)))
|
||||||
|
{
|
||||||
|
throw new BusinessValidationFailedException("国际化Json文件目录有误");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task BatchAddJsonKeyValueAsync(List<BatchAddInternationalizationDto> batchAddDtos)
|
||||||
|
{
|
||||||
|
VerifyFolder();
|
||||||
|
|
||||||
|
var usJsonPath = Path.Combine(JsonFileFolder, StaticData.En_US_Json);
|
||||||
|
var cnJsonPath = Path.Combine(JsonFileFolder, StaticData.Zh_CN_Json);
|
||||||
|
|
||||||
|
|
||||||
|
//更新json 文件 同时更新内存缓存的数据
|
||||||
|
foreach (var filePath in new string[] { usJsonPath, cnJsonPath })
|
||||||
|
{
|
||||||
|
var json = await File.ReadAllTextAsync(filePath);
|
||||||
|
|
||||||
|
JObject jsonObject = JObject.Parse(json, new JsonLoadSettings() { CommentHandling = CommentHandling.Load });
|
||||||
|
|
||||||
|
// 添加或更新指定的键值对
|
||||||
|
|
||||||
|
if (filePath.Contains(StaticData.En_US_Json))
|
||||||
|
{
|
||||||
|
foreach (var item in batchAddDtos)
|
||||||
|
{
|
||||||
|
jsonObject[item.Code] = item.Value;
|
||||||
|
|
||||||
|
StaticData.En_US_Dic[item.Code] = item.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (var item in batchAddDtos)
|
||||||
|
{
|
||||||
|
jsonObject[item.Code] = item.Value;
|
||||||
|
|
||||||
|
StaticData.Zh_CN_Dic[item.Code] = item.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
await File.WriteAllTextAsync(filePath, jsonObject.ToString());
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task AddOrUpdateJsonKeyValueAsync(string key, string value, string valueCN)
|
||||||
|
{
|
||||||
|
|
||||||
|
VerifyFolder();
|
||||||
|
|
||||||
|
var usJsonPath = Path.Combine(JsonFileFolder, StaticData.En_US_Json);
|
||||||
|
var cnJsonPath = Path.Combine(JsonFileFolder, StaticData.Zh_CN_Json);
|
||||||
|
|
||||||
|
|
||||||
|
//更新json 文件 同时更新内存缓存的数据
|
||||||
|
foreach (var filePath in new string[] { usJsonPath, cnJsonPath })
|
||||||
|
{
|
||||||
|
var json = await File.ReadAllTextAsync(filePath);
|
||||||
|
|
||||||
|
JObject jsonObject = JObject.Parse(json, new JsonLoadSettings() { CommentHandling = CommentHandling.Load });
|
||||||
|
|
||||||
|
// 添加或更新指定的键值对
|
||||||
|
|
||||||
|
if (filePath.Contains(StaticData.En_US_Json))
|
||||||
|
{
|
||||||
|
jsonObject[key] = value;
|
||||||
|
|
||||||
|
StaticData.En_US_Dic[key] = value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
jsonObject[key] = valueCN;
|
||||||
|
|
||||||
|
StaticData.Zh_CN_Dic[key] = valueCN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
await File.WriteAllTextAsync(filePath, jsonObject.ToString());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task InitInternationlizationDataAndWatchJsonFileAsync(IRepository _repository)
|
||||||
|
{
|
||||||
|
//查询数据库的数据
|
||||||
|
var toJsonList = await _repository.Where<Internationalization>(t => t.InternationalizationType == 1).Select(t => new
|
||||||
|
{
|
||||||
|
t.Code,
|
||||||
|
t.Value,
|
||||||
|
t.ValueCN
|
||||||
|
}).ToListAsync();
|
||||||
|
|
||||||
|
//组织成json 文件
|
||||||
|
|
||||||
|
var usJsonPath = Path.Combine(JsonFileFolder, StaticData.En_US_Json);
|
||||||
|
var cnJsonPath = Path.Combine(JsonFileFolder, StaticData.Zh_CN_Json);
|
||||||
|
|
||||||
|
|
||||||
|
//本地静态文件国际化需要
|
||||||
|
foreach (var tojsonItem in toJsonList)
|
||||||
|
{
|
||||||
|
StaticData.En_US_Dic[tojsonItem.Code] = tojsonItem.Value;
|
||||||
|
StaticData.Zh_CN_Dic[tojsonItem.Code] = tojsonItem.ValueCN;
|
||||||
|
}
|
||||||
|
|
||||||
|
File.WriteAllText(usJsonPath, JsonConvert.SerializeObject(StaticData.En_US_Dic));
|
||||||
|
File.WriteAllText(cnJsonPath, JsonConvert.SerializeObject(StaticData.Zh_CN_Dic));
|
||||||
|
|
||||||
|
|
||||||
|
//监测Json文件变更 实时刷新数据
|
||||||
|
|
||||||
|
WatchJsonFile(usJsonPath);
|
||||||
|
WatchJsonFile(cnJsonPath);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void WatchJsonFile(string filePath)
|
||||||
|
{
|
||||||
|
if (!File.Exists(filePath))
|
||||||
|
{
|
||||||
|
throw new BusinessValidationFailedException("国际化Json文件不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
FileSystemWatcher watcher = new FileSystemWatcher(Path.GetDirectoryName(filePath), Path.GetFileName(filePath));
|
||||||
|
watcher.Changed += (sender, e) => LoadJsonFile(filePath);
|
||||||
|
watcher.EnableRaisingEvents = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static void LoadJsonFile(string filePath)
|
||||||
|
{
|
||||||
|
|
||||||
|
IConfigurationBuilder builder = new ConfigurationBuilder().AddJsonFile(filePath);
|
||||||
|
|
||||||
|
IConfigurationRoot enConfiguration = builder.Build();
|
||||||
|
|
||||||
|
foreach (IConfigurationSection section in enConfiguration.GetChildren())
|
||||||
|
{
|
||||||
|
if (filePath.Contains(StaticData.En_US_Json))
|
||||||
|
{
|
||||||
|
StaticData.En_US_Dic[section.Key] = section.Value;
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
StaticData.Zh_CN_Dic[section.Key] = section.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,171 +0,0 @@
|
|||||||
|
|
||||||
using IRaCIS.Core.Application.Helper;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using NPOI.OpenXmlFormats.Wordprocessing;
|
|
||||||
using NPOI.XWPF.UserModel;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Reflection;
|
|
||||||
|
|
||||||
namespace IRaCIS.Core.Application.Service;
|
|
||||||
|
|
||||||
public static class NpoiWordHelper
|
|
||||||
{
|
|
||||||
public static async Task<IActionResult> TemplateExportWordAsync(string code, object data, IRepository<CommonDocument>? _commonDocumentRepository, IWebHostEnvironment _hostEnvironment)
|
|
||||||
{
|
|
||||||
//var (physicalPath, fileNmae) = await FileStoreHelper.GetCommonDocPhysicalFilePathAsync(_hostEnvironment, _commonDocumentRepository, code);
|
|
||||||
|
|
||||||
var physicalPath = code;
|
|
||||||
|
|
||||||
|
|
||||||
using (FileStream stream = File.OpenRead(physicalPath))
|
|
||||||
{
|
|
||||||
XWPFDocument doc = new XWPFDocument(stream);
|
|
||||||
//遍历段落
|
|
||||||
foreach (var para in doc.Paragraphs)
|
|
||||||
{
|
|
||||||
ReplaceKey(para, data);
|
|
||||||
}
|
|
||||||
//遍历表格
|
|
||||||
var tables = doc.Tables;
|
|
||||||
foreach (var table in tables)
|
|
||||||
{
|
|
||||||
//ReplaceTableKey(table, data, "Data");
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var table in tables)
|
|
||||||
{
|
|
||||||
foreach (var row in table.Rows)
|
|
||||||
{
|
|
||||||
foreach (var cell in row.GetTableCells())
|
|
||||||
{
|
|
||||||
foreach (var para in cell.Paragraphs)
|
|
||||||
{
|
|
||||||
ReplaceKey(para, data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FileStream out1 = new FileStream("table.docx", FileMode.Create);
|
|
||||||
doc.Write(out1);
|
|
||||||
out1.Close();
|
|
||||||
return new FileStreamResult(stream, "application/msword")
|
|
||||||
{
|
|
||||||
FileDownloadName = $"replaced_{DateTime.Now.ToString("yyyyMMddHHmmss")}.docx"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void ReplaceKey(XWPFParagraph para, object model)
|
|
||||||
{
|
|
||||||
string text = para.ParagraphText;
|
|
||||||
|
|
||||||
Type t = model.GetType();
|
|
||||||
PropertyInfo[] pi = t.GetProperties();
|
|
||||||
foreach (PropertyInfo p in pi)
|
|
||||||
{
|
|
||||||
//$$与模板中$$对应,也可以改成其它符号,比如{$name},务必做到唯一
|
|
||||||
if (text.Contains("$" + p.Name + "$"))
|
|
||||||
{
|
|
||||||
text = text.Replace("$" + p.Name + "$", p.GetValue(model)?.ToString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//var runs = para.Runs;
|
|
||||||
//string styleid = para.Style;
|
|
||||||
//for (int i = 0; i < runs.Count; i++)
|
|
||||||
//{
|
|
||||||
// var run = runs[i];
|
|
||||||
// text = run.ToString();
|
|
||||||
// Type t = model.GetType();
|
|
||||||
// PropertyInfo[] pi = t.GetProperties();
|
|
||||||
// foreach (PropertyInfo p in pi)
|
|
||||||
// {
|
|
||||||
// //$$与模板中$$对应,也可以改成其它符号,比如{$name},务必做到唯一
|
|
||||||
// if (text.Contains("$" + p.Name + "$"))
|
|
||||||
// {
|
|
||||||
// text = text.Replace("$" + p.Name + "$", p.GetValue(model)?.ToString());
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// runs[i].SetText(text, 0);
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 替换表格Key
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="table"></param>
|
|
||||||
/// <param name="list"></param>
|
|
||||||
/// <param name="field"></param>
|
|
||||||
|
|
||||||
private static void ReplaceTableKey(XWPFTable table, IList list, String field)
|
|
||||||
{
|
|
||||||
List<XWPFParagraph> paras = new List<XWPFParagraph>();
|
|
||||||
// 获取最后一行数据,最后一行设置值
|
|
||||||
Int32 iLastRowIndex = 0;
|
|
||||||
for (int iIndex = 0; iIndex < table.Rows.Count; iIndex++)
|
|
||||||
{
|
|
||||||
if (iIndex == table.Rows.Count - 1)
|
|
||||||
{
|
|
||||||
iLastRowIndex = iIndex;
|
|
||||||
foreach (var cell in table.Rows[iIndex].GetTableCells())
|
|
||||||
{
|
|
||||||
foreach (var para in cell.Paragraphs)
|
|
||||||
{
|
|
||||||
paras.Add(para);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 删除最后一行
|
|
||||||
table.RemoveRow(iLastRowIndex);
|
|
||||||
|
|
||||||
for (int iIndex = 0; iIndex < list.Count; iIndex++)
|
|
||||||
{
|
|
||||||
object data = list[iIndex];
|
|
||||||
Type t = data.GetType();
|
|
||||||
PropertyInfo[] pi = t.GetProperties();
|
|
||||||
// 表增加行
|
|
||||||
XWPFTableRow m_row = table.CreateRow();
|
|
||||||
CT_Row m_NewRow = new CT_Row();
|
|
||||||
String text = String.Empty;
|
|
||||||
Int32 jIndex = 0;
|
|
||||||
paras.ForEach(para =>
|
|
||||||
{
|
|
||||||
text = para.ParagraphText;
|
|
||||||
foreach (PropertyInfo p in pi)
|
|
||||||
{
|
|
||||||
if (text.Contains("$" + field + "." + p.Name + "$"))
|
|
||||||
{
|
|
||||||
m_row.GetCell(jIndex).SetText(p.GetValue(data, null).ToString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
jIndex++;
|
|
||||||
});
|
|
||||||
m_row = new XWPFTableRow(m_NewRow, table);
|
|
||||||
table.AddRow(m_row);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,421 @@
|
|||||||
|
using Aliyun.OSS;
|
||||||
|
using IRaCIS.Core.Application.Contracts;
|
||||||
|
using IRaCIS.Core.Infrastructure;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using Minio.DataModel.Args;
|
||||||
|
using Minio;
|
||||||
|
using NPOI.HPSF;
|
||||||
|
using SharpCompress.Common;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Security.AccessControl;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace IRaCIS.Core.Application.Helper
|
||||||
|
{
|
||||||
|
public class MinIOOptions : AWSOptions
|
||||||
|
{
|
||||||
|
public int port { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AWSOptions
|
||||||
|
{
|
||||||
|
public string endPoint { get; set; }
|
||||||
|
public bool useSSL { get; set; }
|
||||||
|
public string accessKey { get; set; }
|
||||||
|
public string secretKey { get; set; }
|
||||||
|
public string bucketName { get; set; }
|
||||||
|
public string viewEndpoint { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AliyunOSSOptions
|
||||||
|
{
|
||||||
|
public string regionId { get; set; }
|
||||||
|
public string accessKeyId { get; set; }
|
||||||
|
public string accessKeySecret { get; set; }
|
||||||
|
public string endPoint { get; set; }
|
||||||
|
public string bucketName { get; set; }
|
||||||
|
|
||||||
|
public string roleArn { get; set; }
|
||||||
|
|
||||||
|
public string region { get; set; }
|
||||||
|
|
||||||
|
public string viewEndpoint { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ObjectStoreServiceOptions
|
||||||
|
{
|
||||||
|
public string ObjectStoreUse { get; set; }
|
||||||
|
public AliyunOSSOptions AliyunOSS { get; set; }
|
||||||
|
public MinIOOptions MinIO { get; set; }
|
||||||
|
|
||||||
|
public AWSOptions AWS { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ObjectStoreDTO
|
||||||
|
{
|
||||||
|
public string ObjectStoreUse { get; set; }
|
||||||
|
|
||||||
|
public AliyunOSSOptions AliyunOSS { get; set; }
|
||||||
|
|
||||||
|
public MinIOOptions MinIO { get; set; }
|
||||||
|
|
||||||
|
public AWSOptions AWS { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AliyunOSSTempToken
|
||||||
|
{
|
||||||
|
public string AccessKeyId { get; set; }
|
||||||
|
public string AccessKeySecret { get; set; }
|
||||||
|
public string SecurityToken { get; set; }
|
||||||
|
public string Expiration { get; set; }
|
||||||
|
|
||||||
|
public string Region { get; set; }
|
||||||
|
public string BucketName { get; set; }
|
||||||
|
public string ViewEndpoint { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public enum ObjectStoreUse
|
||||||
|
{
|
||||||
|
AliyunOSS = 0,
|
||||||
|
MinIO = 1,
|
||||||
|
AWS = 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IOSSService
|
||||||
|
{
|
||||||
|
public Task<string> UploadToOSSAsync(Stream fileStream, string oosFolderPath, string fileRealName, bool isFileNameAddGuid = true);
|
||||||
|
public Task<string> UploadToOSSAsync(string localFilePath, string oosFolderPath, bool isFileNameAddGuid = true);
|
||||||
|
|
||||||
|
public Task DownLoadFromOSSAsync(string ossRelativePath, string localFilePath);
|
||||||
|
|
||||||
|
public ObjectStoreServiceOptions ObjectStoreServiceOptions { get; set; }
|
||||||
|
|
||||||
|
public Task<string> GetSignedUrl(string ossRelativePath);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class OSSService : IOSSService
|
||||||
|
{
|
||||||
|
public ObjectStoreServiceOptions ObjectStoreServiceOptions { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
public OSSService(IOptionsMonitor<ObjectStoreServiceOptions> options)
|
||||||
|
{
|
||||||
|
ObjectStoreServiceOptions = options.CurrentValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// oosFolderPath 不要 "/ "开头 应该: TempFolder/ChildFolder
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fileStream"></param>
|
||||||
|
/// <param name="oosFolderPath"></param>
|
||||||
|
/// <param name="fileRealName"></param>
|
||||||
|
/// <param name="isFileNameAddGuid"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<string> UploadToOSSAsync(Stream fileStream, string oosFolderPath, string fileRealName, bool isFileNameAddGuid = true)
|
||||||
|
{
|
||||||
|
var ossRelativePath = isFileNameAddGuid ? $"{oosFolderPath}/{Guid.NewGuid()}_{fileRealName}" : $"{oosFolderPath}/{fileRealName}";
|
||||||
|
//var ossRelativePath = $"{oosFolderPath}/{Guid.NewGuid()}_{fileRealName}";
|
||||||
|
//var ossRelativePath = oosFolderPath + "/" + fileRealName;
|
||||||
|
|
||||||
|
using (var memoryStream = new MemoryStream())
|
||||||
|
{
|
||||||
|
fileStream.Seek(0, SeekOrigin.Begin);
|
||||||
|
|
||||||
|
fileStream.CopyTo(memoryStream);
|
||||||
|
|
||||||
|
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||||
|
|
||||||
|
|
||||||
|
if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS")
|
||||||
|
{
|
||||||
|
var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
|
||||||
|
|
||||||
|
var _ossClient = new OssClient(aliConfig.endPoint, aliConfig.accessKeyId, aliConfig.accessKeySecret);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 上传文件
|
||||||
|
var result = _ossClient.PutObject(aliConfig.bucketName, ossRelativePath, memoryStream);
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO")
|
||||||
|
{
|
||||||
|
var minIOConfig = ObjectStoreServiceOptions.MinIO;
|
||||||
|
|
||||||
|
|
||||||
|
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}:{minIOConfig.port}")
|
||||||
|
.WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
var putObjectArgs = new PutObjectArgs()
|
||||||
|
.WithBucket(minIOConfig.bucketName)
|
||||||
|
.WithObject(ossRelativePath)
|
||||||
|
.WithStreamData(memoryStream)
|
||||||
|
.WithObjectSize(memoryStream.Length);
|
||||||
|
|
||||||
|
await minioClient.PutObjectAsync(putObjectArgs);
|
||||||
|
}
|
||||||
|
else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS")
|
||||||
|
{
|
||||||
|
var minIOConfig = ObjectStoreServiceOptions.AWS;
|
||||||
|
|
||||||
|
|
||||||
|
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}")
|
||||||
|
.WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
var putObjectArgs = new PutObjectArgs()
|
||||||
|
.WithBucket(minIOConfig.bucketName)
|
||||||
|
.WithObject(ossRelativePath)
|
||||||
|
.WithStreamData(memoryStream)
|
||||||
|
.WithObjectSize(memoryStream.Length);
|
||||||
|
|
||||||
|
await minioClient.PutObjectAsync(putObjectArgs);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new BusinessValidationFailedException("未定义的存储介质类型");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return "/" + ossRelativePath;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// oosFolderPath 不要 "/ "开头 应该: TempFolder/ChildFolder
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="localFilePath"></param>
|
||||||
|
/// <param name="oosFolderPath"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
/// <exception cref="BusinessValidationFailedException"></exception>
|
||||||
|
public async Task<string> UploadToOSSAsync(string localFilePath, string oosFolderPath, bool isFileNameAddGuid = true)
|
||||||
|
{
|
||||||
|
var localFileName = Path.GetFileName(localFilePath);
|
||||||
|
|
||||||
|
var ossRelativePath = isFileNameAddGuid ? $"{oosFolderPath}/{Guid.NewGuid()}_{localFileName}" : $"{oosFolderPath}/{localFileName}";
|
||||||
|
|
||||||
|
|
||||||
|
//var ossRelativePath = oosFolderPath + "/" + localFileName;
|
||||||
|
|
||||||
|
|
||||||
|
if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS")
|
||||||
|
{
|
||||||
|
var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
|
||||||
|
|
||||||
|
var _ossClient = new OssClient(aliConfig.endPoint, aliConfig.accessKeyId, aliConfig.accessKeySecret);
|
||||||
|
|
||||||
|
// 上传文件
|
||||||
|
var result = _ossClient.PutObject(aliConfig.bucketName, ossRelativePath, localFilePath);
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO")
|
||||||
|
{
|
||||||
|
var minIOConfig = ObjectStoreServiceOptions.MinIO;
|
||||||
|
|
||||||
|
|
||||||
|
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}:{minIOConfig.port}")
|
||||||
|
.WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
var putObjectArgs = new PutObjectArgs()
|
||||||
|
.WithBucket(minIOConfig.bucketName)
|
||||||
|
.WithObject(ossRelativePath)
|
||||||
|
.WithFileName(localFilePath);
|
||||||
|
|
||||||
|
await minioClient.PutObjectAsync(putObjectArgs);
|
||||||
|
}
|
||||||
|
else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS")
|
||||||
|
{
|
||||||
|
var minIOConfig = ObjectStoreServiceOptions.AWS;
|
||||||
|
|
||||||
|
|
||||||
|
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}")
|
||||||
|
.WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
var putObjectArgs = new PutObjectArgs()
|
||||||
|
.WithBucket(minIOConfig.bucketName)
|
||||||
|
.WithObject(ossRelativePath)
|
||||||
|
.WithFileName(localFilePath);
|
||||||
|
|
||||||
|
await minioClient.PutObjectAsync(putObjectArgs);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new BusinessValidationFailedException("未定义的存储介质类型");
|
||||||
|
}
|
||||||
|
return "/" + ossRelativePath;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public async Task DownLoadFromOSSAsync(string ossRelativePath, string localFilePath)
|
||||||
|
{
|
||||||
|
|
||||||
|
ossRelativePath = ossRelativePath.TrimStart('/');
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS")
|
||||||
|
{
|
||||||
|
var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
|
||||||
|
|
||||||
|
var _ossClient = new OssClient(aliConfig.endPoint, aliConfig.accessKeyId, aliConfig.accessKeySecret);
|
||||||
|
|
||||||
|
// 上传文件
|
||||||
|
var result = _ossClient.GetObject(aliConfig.bucketName, ossRelativePath);
|
||||||
|
|
||||||
|
// 将下载的文件流保存到本地文件
|
||||||
|
using (var fs = File.OpenWrite(localFilePath))
|
||||||
|
{
|
||||||
|
result.Content.CopyTo(fs);
|
||||||
|
fs.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO")
|
||||||
|
{
|
||||||
|
var minIOConfig = ObjectStoreServiceOptions.MinIO;
|
||||||
|
|
||||||
|
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}:{minIOConfig.port}")
|
||||||
|
.WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
var getObjectArgs = new GetObjectArgs()
|
||||||
|
.WithBucket(minIOConfig.bucketName)
|
||||||
|
.WithObject(ossRelativePath)
|
||||||
|
.WithFile(localFilePath);
|
||||||
|
|
||||||
|
await minioClient.GetObjectAsync(getObjectArgs);
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS")
|
||||||
|
{
|
||||||
|
var minIOConfig = ObjectStoreServiceOptions.AWS;
|
||||||
|
|
||||||
|
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}")
|
||||||
|
.WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
var getObjectArgs = new GetObjectArgs()
|
||||||
|
.WithBucket(minIOConfig.bucketName)
|
||||||
|
.WithObject(ossRelativePath)
|
||||||
|
.WithFile(localFilePath);
|
||||||
|
|
||||||
|
await minioClient.GetObjectAsync(getObjectArgs);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new BusinessValidationFailedException("未定义的存储介质类型");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
|
||||||
|
throw new BusinessValidationFailedException("oss下载失败!" + ex.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<string> GetSignedUrl(string ossRelativePath)
|
||||||
|
{
|
||||||
|
ossRelativePath = ossRelativePath.TrimStart('/');
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS")
|
||||||
|
{
|
||||||
|
var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
|
||||||
|
|
||||||
|
var _ossClient = new OssClient(aliConfig.endPoint, aliConfig.accessKeyId, aliConfig.accessKeySecret);
|
||||||
|
|
||||||
|
// 生成签名URL。
|
||||||
|
var req = new GeneratePresignedUriRequest(aliConfig.bucketName, ossRelativePath, SignHttpMethod.Get)
|
||||||
|
{
|
||||||
|
// 设置签名URL过期时间,默认值为3600秒。
|
||||||
|
Expiration = DateTime.Now.AddHours(1),
|
||||||
|
};
|
||||||
|
var uri = _ossClient.GeneratePresignedUri(req);
|
||||||
|
|
||||||
|
return uri.PathAndQuery;
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO")
|
||||||
|
{
|
||||||
|
var minIOConfig = ObjectStoreServiceOptions.MinIO;
|
||||||
|
|
||||||
|
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}:{minIOConfig.port}")
|
||||||
|
.WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
//var reqParams = new Dictionary<string, string>(StringComparer.Ordinal)
|
||||||
|
// {
|
||||||
|
// { "response-content-type", "application/json" }
|
||||||
|
// };
|
||||||
|
|
||||||
|
var args = new PresignedGetObjectArgs()
|
||||||
|
.WithBucket(minIOConfig.bucketName)
|
||||||
|
.WithObject(ossRelativePath)
|
||||||
|
.WithExpiry(3600)
|
||||||
|
/*.WithHeaders(reqParams)*/;
|
||||||
|
|
||||||
|
var presignedUrl = await minioClient.PresignedGetObjectAsync(args);
|
||||||
|
|
||||||
|
Uri uri = new Uri(presignedUrl);
|
||||||
|
|
||||||
|
string relativePath = uri.PathAndQuery;
|
||||||
|
|
||||||
|
|
||||||
|
return relativePath;
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS")
|
||||||
|
{
|
||||||
|
var minIOConfig = ObjectStoreServiceOptions.AWS;
|
||||||
|
|
||||||
|
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}")
|
||||||
|
.WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new BusinessValidationFailedException("未定义的存储介质类型");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
|
||||||
|
throw new BusinessValidationFailedException("oss授权url失败!" + ex.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -29,10 +29,11 @@ public static class SendEmailHelper
|
|||||||
|
|
||||||
//await smtp.AuthenticateAsync("zhou941003@qq.com", "sqfhlpfdvnexbcab");
|
//await smtp.AuthenticateAsync("zhou941003@qq.com", "sqfhlpfdvnexbcab");
|
||||||
|
|
||||||
await smtp.ConnectAsync(_systemEmailConfig.Host, _systemEmailConfig.Port, SecureSocketOptions.SslOnConnect);
|
await smtp.ConnectAsync(_systemEmailConfig.Host, _systemEmailConfig.Port, SecureSocketOptions.Auto);
|
||||||
|
|
||||||
await smtp.AuthenticateAsync(_systemEmailConfig.FromEmail, _systemEmailConfig.AuthorizationCode);
|
await smtp.AuthenticateAsync(_systemEmailConfig.FromEmail, _systemEmailConfig.AuthorizationCode);
|
||||||
|
|
||||||
|
|
||||||
await smtp.SendAsync(messageToSend);
|
await smtp.SendAsync(messageToSend);
|
||||||
|
|
||||||
await smtp.DisconnectAsync(true);
|
await smtp.DisconnectAsync(true);
|
||||||
@@ -43,12 +44,27 @@ public static class SendEmailHelper
|
|||||||
{
|
{
|
||||||
|
|
||||||
//---邮件发送失败,您进行的操作未能成功,请检查邮箱或联系维护人员
|
//---邮件发送失败,您进行的操作未能成功,请检查邮箱或联系维护人员
|
||||||
throw new Exception(StaticData.International("SendEmail_SendFail"));
|
throw new Exception(StaticData.International("SendEmail_SendFail"),new Exception(ex.Message));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static async Task<bool> TestEmailConfigAsync(SystemEmailSendConfig _systemEmailConfig)
|
||||||
|
{
|
||||||
|
using (var client = new MailKit.Net.Smtp.SmtpClient())
|
||||||
|
{
|
||||||
|
|
||||||
|
await client.ConnectAsync(_systemEmailConfig.Host, _systemEmailConfig.Port, SecureSocketOptions.Auto);
|
||||||
|
|
||||||
|
await client.AuthenticateAsync(_systemEmailConfig.FromEmail, _systemEmailConfig.AuthorizationCode);
|
||||||
|
|
||||||
|
await client.DisconnectAsync(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public static async Task SendEmailAsync(SMTPEmailConfig sMTPEmailConfig, EventHandler<MessageSentEventArgs>? messageSentSuccess = null)
|
public static async Task SendEmailAsync(SMTPEmailConfig sMTPEmailConfig, EventHandler<MessageSentEventArgs>? messageSentSuccess = null)
|
||||||
{
|
{
|
||||||
var messageToSend = new MimeMessage();
|
var messageToSend = new MimeMessage();
|
||||||
@@ -117,7 +133,7 @@ public static class SendEmailHelper
|
|||||||
|
|
||||||
smtp.ServerCertificateValidationCallback = (s, c, h, e) => true;
|
smtp.ServerCertificateValidationCallback = (s, c, h, e) => true;
|
||||||
|
|
||||||
await smtp.ConnectAsync(sMTPEmailConfig.Host, sMTPEmailConfig.Port, SecureSocketOptions.SslOnConnect);
|
await smtp.ConnectAsync(sMTPEmailConfig.Host, sMTPEmailConfig.Port, SecureSocketOptions.Auto);
|
||||||
|
|
||||||
await smtp.AuthenticateAsync(sMTPEmailConfig.UserName, sMTPEmailConfig.AuthorizationCode);
|
await smtp.AuthenticateAsync(sMTPEmailConfig.UserName, sMTPEmailConfig.AuthorizationCode);
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<LangVersion>default</LangVersion>
|
<LangVersion>default</LangVersion>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
@@ -63,52 +63,45 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="AutoMapper.Collection.EntityFrameworkCore" Version="9.0.0" />
|
<PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.13.0" />
|
||||||
|
<PackageReference Include="FreeSpire.Doc" Version="12.2.0" />
|
||||||
|
<PackageReference Include="Hangfire.Core" Version="1.8.12" />
|
||||||
<PackageReference Include="BeetleX.BNR" Version="1.0.1" />
|
<PackageReference Include="BeetleX.BNR" Version="1.0.1" />
|
||||||
<PackageReference Include="Castle.Core.AsyncInterceptor" Version="2.1.0" />
|
<PackageReference Include="Castle.Core.AsyncInterceptor" Version="2.1.0" />
|
||||||
<PackageReference Include="EasyCaching.Interceptor.AspectCore" Version="1.7.0" />
|
<PackageReference Include="EasyCaching.Redis" Version="1.9.2" />
|
||||||
|
<PackageReference Include="EasyCaching.InMemory" Version="1.9.2" />
|
||||||
<PackageReference Include="ExcelDataReader" Version="3.6.0" />
|
<PackageReference Include="ExcelDataReader" Version="3.6.0" />
|
||||||
<PackageReference Include="ExcelDataReader.DataSet" Version="3.6.0" />
|
<PackageReference Include="ExcelDataReader.DataSet" Version="3.6.0" />
|
||||||
<PackageReference Include="fo-dicom.Codecs" Version="5.1.0">
|
<PackageReference Include="DistributedLock.Redis" Version="1.0.3" />
|
||||||
|
<PackageReference Include="DistributedLock.SqlServer" Version="1.0.4" />
|
||||||
|
<PackageReference Include="fo-dicom" Version="5.1.2" />
|
||||||
|
<PackageReference Include="fo-dicom.Imaging.ImageSharp" Version="5.1.2" />
|
||||||
|
<PackageReference Include="fo-dicom.Codecs" Version="5.12.0" />
|
||||||
|
<PackageReference Include="IP2Region.Net" Version="2.0.2" />
|
||||||
|
<PackageReference Include="MailKit" Version="4.2.0" />
|
||||||
|
<PackageReference Include="MediatR" Version="12.2.0" />
|
||||||
|
<PackageReference Include="MimeKit" Version="4.2.0" />
|
||||||
|
<PackageReference Include="MiniExcel" Version="1.32.0" />
|
||||||
|
<PackageReference Include="Minio" Version="6.0.2" />
|
||||||
|
<PackageReference Include="MiniWord" Version="0.8.0" />
|
||||||
|
<PackageReference Include="My.Extensions.Localization.Json" Version="3.3.0">
|
||||||
<TreatAsUsed>true</TreatAsUsed>
|
<TreatAsUsed>true</TreatAsUsed>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="fo-dicom.Drawing" Version="4.0.8" />
|
<PackageReference Include="NPOI" Version="2.7.0" />
|
||||||
<PackageReference Include="fo-dicom.Imaging.ImageSharp" Version="5.0.3" />
|
<PackageReference Include="Panda.DynamicWebApi" Version="1.2.2" />
|
||||||
<PackageReference Include="FreeSpire.Doc" Version="10.8.0" />
|
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.4" />
|
||||||
<PackageReference Include="Hangfire" Version="1.7.31">
|
<PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="8.0.2" />
|
||||||
<TreatAsUsed>true</TreatAsUsed>
|
<PackageReference Include="WinSCP" Version="6.3.3" />
|
||||||
</PackageReference>
|
|
||||||
<PackageReference Include="Magicodes.IE.Core" Version="2.7.4.2" />
|
|
||||||
<PackageReference Include="Magicodes.IE.Csv" Version="2.7.4.2">
|
|
||||||
<TreatAsUsed>true</TreatAsUsed>
|
|
||||||
</PackageReference>
|
|
||||||
<PackageReference Include="Magicodes.IE.Excel" Version="2.7.4.2">
|
|
||||||
<TreatAsUsed>true</TreatAsUsed>
|
|
||||||
</PackageReference>
|
|
||||||
<PackageReference Include="Magicodes.IE.Excel.AspNetCore" Version="2.7.4.2" />
|
|
||||||
<PackageReference Include="MailKit" Version="3.4.2" />
|
|
||||||
<PackageReference Include="MediatR" Version="11.0.0" />
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="6.0.10" />
|
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.10">
|
|
||||||
<TreatAsUsed>true</TreatAsUsed>
|
|
||||||
</PackageReference>
|
|
||||||
<PackageReference Include="MimeKit" Version="3.4.2" />
|
|
||||||
<PackageReference Include="MiniExcel" Version="1.30.1" />
|
|
||||||
<PackageReference Include="MiniWord" Version="0.6.1" />
|
|
||||||
<PackageReference Include="My.Extensions.Localization.Json" Version="3.0.0">
|
|
||||||
<TreatAsUsed>true</TreatAsUsed>
|
|
||||||
</PackageReference>
|
|
||||||
<PackageReference Include="Nito.AsyncEx" Version="5.1.2" />
|
|
||||||
<PackageReference Include="NPOI" Version="2.6.0" />
|
|
||||||
<PackageReference Include="Panda.DynamicWebApi" Version="1.2.0" />
|
|
||||||
<PackageReference Include="Quartz" Version="3.5.0" />
|
|
||||||
<PackageReference Include="SixLabors.ImageSharp" Version="2.1.3" />
|
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="7.0.5" />
|
|
||||||
<PackageReference Include="WinSCP" Version="5.21.5" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\IRaCIS.Core.Infra.EFCore\IRaCIS.Core.Infra.EFCore.csproj" />
|
<ProjectReference Include="..\IRaCIS.Core.Infra.EFCore\IRaCIS.Core.Infra.EFCore.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Update="Resources\ip2region.xdb">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
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