Compare commits
696 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ed0dacccbb | |||
| 0dd6ace8c1 | |||
| 4135349bfa | |||
| 98b126f630 | |||
| 5ccaf1acc1 | |||
| a9def7e6ae | |||
| f9d81aa726 | |||
| 8f8c5d0744 | |||
| 5133f9e3d7 | |||
| bb6bf409b7 | |||
| 64a0e68448 | |||
| fa6c552149 | |||
| 074c302077 | |||
| 8800ddb0a0 | |||
| 2ee3ff0a7c | |||
| 3a09caa43b | |||
| b0277d0ccf | |||
| 179d030f76 | |||
| 8ebf10b373 | |||
| 3eb5094c3e | |||
| a27c6f6f18 | |||
| 03f4a7b63b | |||
| f7b99c23aa | |||
| 8e554bbeb8 | |||
| 8e5e2a0714 | |||
| a15e908e76 | |||
| a980f6ca58 | |||
| f89f0de740 | |||
| 7e54379ad3 | |||
| 5336bfd709 | |||
| c6092358d8 | |||
| da29f743cd | |||
| 422a1cd63d | |||
| 7c09594c4d | |||
| ca3a6122be | |||
| d6bb1fcb5a | |||
| 602f971309 | |||
| 1c21479c82 | |||
| 9d81fa9251 | |||
| b9ee682ace | |||
| 6d37838654 | |||
| 8a5eaff5f6 | |||
| 5967fd19b2 | |||
| e3af442b8f | |||
| cfb54d9c9c | |||
| 43d87e612a | |||
| 8f1d46f113 | |||
| 10283bbceb | |||
| 10a2238cba | |||
| 6db7229cb2 | |||
| c80c8c0a16 | |||
| 06d3026207 | |||
| ac37818caf | |||
| 408d42f6b8 | |||
| ac1f5c6628 | |||
| e3ab23f20c | |||
| 111dd526d9 | |||
| 14238b6556 | |||
| 736a4eea18 | |||
| 46b2744bc3 | |||
| 5738687f06 | |||
| b5b0d24c97 | |||
| 183723370a | |||
| b2dc406a72 | |||
| 7d37fdc3c0 | |||
| 00e44f36e2 | |||
| 4058bddd21 | |||
| 16f0d72917 | |||
| d429f00733 | |||
| b7413c31b7 | |||
| d3645a808a | |||
| 4b3ef5c7a5 | |||
| 2ea9786626 | |||
| fcc79b0c65 | |||
| 0963441235 | |||
| a6475baee9 | |||
| be972c6fe8 | |||
| c2607041ff | |||
| 28297aa9ba | |||
| d4c5c517fb | |||
| d91a24c154 | |||
| a3b9cb7469 | |||
| 134fba1e77 | |||
| fff5a0fcf5 | |||
| eaba3520e9 | |||
| 4c98f91677 | |||
| 11b1e92488 | |||
| c863eaac3d | |||
| 1a24217cd6 | |||
| ac05f74980 | |||
| 01cb109448 | |||
| 7d2f95cba5 | |||
| 5975a414d2 | |||
| e5efbf7448 | |||
| f9e62fe21b | |||
| 30ff00fc84 | |||
| 23e55e612f | |||
| ee090e995c | |||
| bed03a67d8 | |||
| dfbd7a7a06 | |||
| 17a4585a52 | |||
| e3e7203b1a | |||
| a3f5cdb445 | |||
| b9163c18f1 | |||
| 5b2a3ecc54 | |||
| 06a91499ef | |||
| 28fd6a2c71 | |||
| 2de65e4c1d | |||
| 663faba14d | |||
| 93b0621ba1 | |||
| e1dfbb5d74 | |||
| 23172eeed3 | |||
| 4bd286ca45 | |||
| 873262444f | |||
| ef6135a9e4 | |||
| bc07f69687 | |||
| c2b9dcd277 | |||
| 9cdc89f4df | |||
| 1744d48889 | |||
| 6c9e471e75 | |||
| d0bf19e3bf | |||
| 1a77962c42 | |||
| e3f6204bd2 | |||
| 714a24040f | |||
| 76f2db5722 | |||
| 305433e3b1 | |||
| 76efc90a8b | |||
| cf4b6887da | |||
| cd58d4d182 | |||
| 31a2b6c6fb | |||
| c6f8b8cafa | |||
| 9779c028c6 | |||
| d94d864b9e | |||
| 3212f0cde2 | |||
| 0592f9fc3d | |||
| 24e472d973 | |||
| c18364104f | |||
| eec16c1a2c | |||
| 6737d33dcb | |||
| ab242991bd | |||
| a2facabb7b | |||
| 7e7e374e38 | |||
| 1b66fd6573 | |||
| 31b1b1e3b6 | |||
| 4b10b567e0 | |||
| dc1cd3870e | |||
| 5542ad74e7 | |||
| be74844410 | |||
| fd67706269 | |||
| e8ddecfc68 | |||
| 4ea73a455e | |||
| 84f5f5430c | |||
| 523220093f | |||
| 08c8d49ae1 | |||
| 9e4014afb0 | |||
| 4b1e698612 | |||
| d5b4d4bbb0 | |||
| 8dbe02438c | |||
| df5a6b7fdd | |||
| 3bbe3b3fa3 | |||
| 17c3c6f6d2 | |||
| c653ab607f | |||
| 79f6e508af | |||
| d9fd181bae | |||
| 0ce246689b | |||
| 9102259c75 | |||
| 11627f109d | |||
| 4eb202e4e7 | |||
| d27ed741db | |||
| 093be87efb | |||
| c3e5ed0bff | |||
| ee487483d6 | |||
| f8d921d9e5 | |||
| 7758671f89 | |||
| 59237c85c9 | |||
| f505d297e9 | |||
| b34eda2139 | |||
| 8f354e4813 | |||
| 84c48adb39 | |||
| 2892e75fd0 | |||
| ade801d323 | |||
| 29dbe52991 | |||
| cbfe303aec | |||
| 56b94a97fd | |||
| 0baa90d86f | |||
| 59fe18fe34 | |||
| b07708ebb1 | |||
| d7a21af10c | |||
| 307403d897 | |||
| e473d03074 | |||
| f2f1668b05 | |||
| 6950883dbf | |||
| f767451a4e | |||
| 6d01361917 | |||
| 37521c378a | |||
| ebe7c74614 | |||
| d50cc049ec | |||
| 8d795994f6 | |||
| 880a0615c9 | |||
| 77320ee132 | |||
| e7ccb10ba3 | |||
| 456ff203bb | |||
| e3034e3b07 | |||
| b2700df68a | |||
| c129d79273 | |||
| 9c5fa63b89 | |||
| 54df1b8504 | |||
| a0ec36ac28 | |||
| 416afbe84d | |||
| 6fd5caf8cb | |||
| 90512f7967 | |||
| 71073d749b | |||
| 564d6e7764 | |||
| 2129f7c90f | |||
| 960acf2007 | |||
| c3be341247 | |||
| 35abb4d573 | |||
| 747eadb7f1 | |||
| f26fdb82ee | |||
| 85a518d900 | |||
| 289230b72c | |||
| baf2f9aa10 | |||
| 229bf36ce5 | |||
| e416429087 | |||
| bd1ee8a520 | |||
| 5cc38ada71 | |||
| 75f8018fc8 | |||
| e868d50893 | |||
| e4378d244b | |||
| 16a5f4866d | |||
| 115dae48c7 | |||
| 49dcab2a0e | |||
| e9188115fc | |||
| 264e0ee7c4 | |||
| 434fe551b3 | |||
| cd95f0b018 | |||
| f16f5adfd6 | |||
| 26009d0626 | |||
| ec41415305 | |||
| 3a4967e6ab | |||
| 384d7197a2 | |||
| 5a98d503f8 | |||
| 782324b19c | |||
| 7c7573cdc4 | |||
| ff87692f69 | |||
| 1cbe9ce258 | |||
| 3dfa1ae296 | |||
| f5492e42d5 | |||
| cc0b201036 | |||
| de545a0847 | |||
| 8a6a7962ae | |||
| 806010c6d4 | |||
| e744cbda51 | |||
| 1e098c44c1 | |||
| 9feb906c3e | |||
| 79a5e67b59 | |||
| 6c4f022764 | |||
| 519e1519e2 | |||
| 830cd1e93e | |||
| 1e7237e7ac | |||
| 13ac2e2834 | |||
| 04b22f5b50 | |||
| 8d36fde03d | |||
| 0680bdf805 | |||
| 88f2c34db9 | |||
| 612724cbea | |||
| afd362ba72 | |||
| 1825ac34e1 | |||
| 0e33b60681 | |||
| 1fdbdc4103 | |||
| be6fdf2277 | |||
| 96c35e1736 | |||
| f3f826d60a | |||
| 300a9ad536 | |||
| 5ec96c76bf | |||
| d96c4c743b | |||
| 227f583e7a | |||
| 3646acf378 | |||
| 8618b188ae | |||
| 28b644a0ce | |||
| c886900005 | |||
| 7dbe8c92e1 | |||
| 7623264487 | |||
| db0d5f7ff6 | |||
| 1b5c62df75 | |||
| 0ad25e273a | |||
| 437c571b57 | |||
| 138ea2cfb8 | |||
| 08f0d76aa7 | |||
| 967edf7378 | |||
| 236f07e46b | |||
| 6d4ae0a616 | |||
| a576204ac3 | |||
| fc0ea89d74 | |||
| 7d2fdd222a | |||
| 56783a6f3a | |||
| df6a1cb412 | |||
| cb24021c0d | |||
| 917f95030b | |||
| bf131e09e4 | |||
| 17ed3d4dca | |||
| 6fa4a6349c | |||
| 2f722f8c0e | |||
| 15a7b6d1ac | |||
| 852a794c44 | |||
| 14d71fc3f9 | |||
| 1888ec4fe5 | |||
| e132f84c48 | |||
| c02ce4b350 | |||
| 4ca0f35cad | |||
| 62dd650447 | |||
| 06761092e3 | |||
| b4f58fddb7 | |||
| 33e836cd81 | |||
| 790e828257 | |||
| e7d799ceb5 | |||
| 3a69256a04 | |||
| 425782e015 | |||
| db1d2cc4e1 | |||
| 3283f7f5f2 | |||
| 892b71c011 | |||
| 82b3ca055f | |||
| 15cc9c00be | |||
| 6740e584ae | |||
| d8401d57f7 | |||
| c04aaf2db6 | |||
| c29b60cbbe | |||
| 6f0cfb0122 | |||
| bfdd137cba | |||
| 15f7e35de5 | |||
| 0accca7ec1 | |||
| 606d637d21 | |||
| 94e80cbb38 | |||
| 63a4a56feb | |||
| 55085438aa | |||
| c8e7645fa5 | |||
| 59543a383c | |||
| 92a92ac353 | |||
| 91ee952707 | |||
| d5cb03209a | |||
| c2aad16566 | |||
| dd006a6269 | |||
| 4896aabe3d | |||
| 8164ef38eb | |||
| 0401a95635 | |||
| b461716195 | |||
| ada50a7e73 | |||
| 4f51946c3f | |||
| edfa41291b | |||
| f34de6073f | |||
| 1d1805f8cc | |||
| 0a56880080 | |||
| bcf69f6194 | |||
| 72b7cdbc71 | |||
| 90c1123113 | |||
| 6a5f6b0da3 | |||
| 9b601c0f9a | |||
| fa2bf66dd1 | |||
| 7969db76fe | |||
| 08462786de | |||
| 990c152a99 | |||
| a00a4957fd | |||
| 1351a9192c | |||
| 51c59a7be9 | |||
| 773aa65116 | |||
| 139e4ab5e2 | |||
| e4fa9c7afd | |||
| aa04344503 | |||
| 7278841b0c | |||
| a9cbdf9b08 | |||
| cafd40d83e | |||
| cdf26294d0 | |||
| a8fa74b270 | |||
| 2c97e1d441 | |||
| d3244cee7c | |||
| cd0e62fbef | |||
| c0519613e2 | |||
| 10ff7f31d8 | |||
| 5729f2246e | |||
| 7b475b4873 | |||
| 12db782153 | |||
| f4b2c8a6a4 | |||
| 9aaf2e4ad5 | |||
| 5bcd7cfa59 | |||
| efa7c61fe4 | |||
| 82e5142bac | |||
| 3083ee1e8b | |||
| c7d362e1d0 | |||
| 1f3cb0284a | |||
| 431d8a0682 | |||
| fe40027765 | |||
| 3eeefaaa2c | |||
| d4ea8bb4d5 | |||
| 1812877f88 | |||
| f5ded882ee | |||
| 711373075c | |||
| afa835e3b9 | |||
| 06b3632bf8 | |||
| 1a9f6c37b8 | |||
| 0de0e887b4 | |||
| 07a32b9b2a | |||
| 7e1165888b | |||
| 0e5d1fb718 | |||
| db7498938f | |||
| fd5cce0ed9 | |||
| 9c16e74d3e | |||
| 88cc255c56 | |||
| 372213c7e5 | |||
| 0343ba6043 | |||
| 595da0a7de | |||
| 4fabe3fa14 | |||
| c745756c8c | |||
| 6407cd8264 | |||
| f4842ba34d | |||
| 1724e020f6 | |||
| 5e2522147f | |||
| 05bc41f5e2 | |||
| 9d47ae2561 | |||
| 2d94f07796 | |||
| 3ea4617d45 | |||
| bbcb092f3e | |||
| 2cd92b1dcd | |||
| 81171f6486 | |||
| 0df518f025 | |||
| 0f87682432 | |||
| e6107ffe70 | |||
| 3e24df32f0 | |||
| 9233dff4ba | |||
| 33f5bcb079 | |||
| 92d34d59f4 | |||
| 7db7e91468 | |||
| d74a4506c9 | |||
| 956e3b7152 | |||
| 9bc0b7b02a | |||
| 33747d1317 | |||
| 88da86504d | |||
| c2dc340a1d | |||
| f17c230267 | |||
| 5e56098750 | |||
| eed3cac20e | |||
| 5df5836571 | |||
| 3fbc2710a3 | |||
| 16f943dd50 | |||
| f960eeb445 | |||
| d18d61ee01 | |||
| a86c4bdd0e | |||
| 83c441b7de | |||
| 49d3247f27 | |||
| efc40de310 | |||
| 0cd33687ee | |||
| 994598c216 | |||
| c31a92fbaa | |||
| 7bbf60dd7c | |||
| a51d613633 | |||
| 20480cfad6 | |||
| 9577d1d90e | |||
| 9fbeb4ce04 | |||
| f34f7a0656 | |||
| ee049b4017 | |||
| d5594e87b2 | |||
| 3524e7730c | |||
| 18c31112b3 | |||
| 0ae82ff145 | |||
| af9ad72798 | |||
| dc6340f65c | |||
| cd45362a07 | |||
| a048572403 | |||
| 766a2a786f | |||
| 0cca8f71b4 | |||
| 76392409f6 | |||
| a298048ed0 | |||
| b6f46cec28 | |||
| 94b0aeb239 | |||
| ce5bbaaa4a | |||
| 482d37b4cf | |||
| 531c2a5146 | |||
| eb4d058c8a | |||
| c09b1a2322 | |||
| 40f142e1d2 | |||
| c266b9fcf1 | |||
| 586d406b4a | |||
| 54efc9b1ed | |||
| f487792d8e | |||
| 4290f51ce1 | |||
| c08db443c9 | |||
| 9fc1628cce | |||
| 77e1eba8d5 | |||
| b707c09d2d | |||
| b195e6d7ce | |||
| 8c38700b51 | |||
| a675d5d79e | |||
| 54c7bb055a | |||
| 9a63a206d5 | |||
| dfaa255427 | |||
| 7f9589427f | |||
| 145655f8fc | |||
| eadd5b0223 | |||
| 46ea20a9f5 | |||
| 37c415c0ef | |||
| 84ade87b25 | |||
| 157b65c507 | |||
| 68ea60857d | |||
| 78685918a9 | |||
| 56a8e738d3 | |||
| ccf5830fa0 | |||
| c73c84b15d | |||
| d131953beb | |||
| 6e4a674b62 | |||
| 3b7f141956 | |||
| c114f1bb23 | |||
| d9b5d76ac7 | |||
| 53dc05a48c | |||
| e457df9325 | |||
| 72c6b433b6 | |||
| 5edd252a12 | |||
| e96a4a4d7b | |||
| f126d8c40b | |||
| d15eab1a8e | |||
| 3fb2c5ca40 | |||
| 8afaf8a39e | |||
| 9827baf122 | |||
| ae77e4f048 | |||
| 0928fef04c | |||
| d91f07bba6 | |||
| 2ff15bc2b8 | |||
| f66f0da07e | |||
| 661f0e5dfb | |||
| a4070374c6 | |||
| 9aa68bf5f4 | |||
| 88887e5d92 | |||
| 437e224f1a | |||
| 22e22c3901 | |||
| 73a054ad27 | |||
| 4fff154ad6 | |||
| 6914926567 | |||
| 998c8bc701 | |||
| 058bf39c6e | |||
| 727d4f8c19 | |||
| 277ffa5def | |||
| 283533ff6d | |||
| 70adad29e4 | |||
| 195c176c34 | |||
| 0ac75d7c44 | |||
| c23e9fb081 | |||
| 2a4ddaf6f2 | |||
| f67a5a9f43 | |||
| d0e67f6937 | |||
| c3a0d3e361 | |||
| 64691a2833 | |||
| 10fdbc427d | |||
| 313bc28a96 | |||
| ebddc9beb2 | |||
| b2290ca739 | |||
| 81bc7f281d | |||
| 451fa0078d | |||
| 5d113f128f | |||
| ad99367224 | |||
| 8dedf6ee42 | |||
| f413ca60f3 | |||
| 2ed3dd1376 | |||
| d5e41679c4 | |||
| 0728220a2d | |||
| 15f0154b5d | |||
| 8ec94d0fa5 | |||
| b574da9edf | |||
| c559ff52b5 | |||
| ab0744d550 | |||
| 80b4f123f8 | |||
| 25c14bc463 | |||
| cbec716a6d | |||
| 2dc2383d9d | |||
| c1c52f007f | |||
| 299995dd09 | |||
| aea1bf16bf | |||
| 6fa98f8deb | |||
| 2aef040a34 | |||
| 2d50b6f320 | |||
| 3fcefdb1f4 | |||
| f3c992bfc9 | |||
| 84ada9bc73 | |||
| c34146ae76 | |||
| ef4fab35b4 | |||
| 265f8771f5 | |||
| 48f3d4e40c | |||
| bd0f07aaed | |||
| 644cca6d0f | |||
| 0977570575 | |||
| 5acac110b1 | |||
| 7308f43f81 | |||
| 22c9732382 | |||
| 1154c700c3 | |||
| 10a1238ab5 | |||
| 5782fa5f38 | |||
| 8c5a364d23 | |||
| ccb6aed115 | |||
| a048167ab0 | |||
| d42bb57ee4 | |||
| 91fee13101 | |||
| d14b23761b | |||
| 1d3fa6a837 | |||
| fb79702a65 | |||
| d95e0958eb | |||
| b8384d111a | |||
| 2ba19fd395 | |||
| 5859102225 | |||
| 19bc56bb66 | |||
| 4d63318d8b | |||
| 7101276aab | |||
| ee20254cf8 | |||
| bd024773bd | |||
| de40cb6ec5 | |||
| c197e22f92 | |||
| 8512b91ebd | |||
| 0b82a73c9c | |||
| e7842282bf | |||
| 9c4fc174d0 | |||
| 196dd3de92 | |||
| f21d8871b5 | |||
| 95de39abcd | |||
| 4f9022a18e | |||
| 62b69e8591 | |||
| 6a4bffd8ab | |||
| b2965e8c69 | |||
| d3a88c0f55 | |||
| 6cd8d2de5c | |||
| 74a8fa2524 | |||
| 1bbdf57fdb | |||
| 66c586009e | |||
| d224bf8700 | |||
| 29e535a10a | |||
| 1b905f1f9d | |||
| 30c411d03f | |||
| 6eb8957d1c | |||
| 47288bcca0 | |||
| 95d1207a45 | |||
| 33be113d8d | |||
| ad7b9054da | |||
| f6eab06c78 | |||
| ef732066f4 | |||
| 82c80b71cc | |||
| ae69036777 | |||
| c1008810d6 | |||
| 0c4065102c | |||
| c1faaf9ef0 | |||
| 770df06c88 | |||
| fcc239b54e | |||
| 2cc0b81c90 | |||
| e9a4509ced | |||
| ce3065d88f | |||
| f0dd5398c8 | |||
| c1a9e848b0 | |||
| 89eaccf1c2 | |||
| 791746097d | |||
| 1bf99379a8 | |||
| 1cb52de265 | |||
| 0d9fabb596 | |||
| 101dd3210e | |||
| 6c0f148a77 | |||
| 05cdf17282 | |||
| 89f924d077 | |||
| fa831ed6cc | |||
| b9eaab1900 | |||
| ee15957aa7 | |||
| f30e859e33 | |||
| 949a09ac50 | |||
| e3ffd6d6c9 | |||
| 8085585cfa | |||
| d8cd8d336d | |||
| 8d9790f68e | |||
| a1dc9e4031 | |||
| 734e574713 | |||
| 9033119fb1 | |||
| 59b36aee8b | |||
| c5f86d0557 | |||
| f09901bcf6 | |||
| 80597d1f98 | |||
| b56f3f1eb7 | |||
| 7e39c67fc2 | |||
| d995e1f729 | |||
| 246e9a5bbd | |||
| dc60128cae | |||
| 052fdbcdbf | |||
| 9929045d4b | |||
| 893a528bfc | |||
| 6e95127522 | |||
| 9906f44677 | |||
| 4de108cd42 | |||
| be96b2e93e | |||
| ee8b630806 | |||
| 6778784111 | |||
| 6a8308fe5f | |||
| 227009eb39 | |||
| f09bf427e5 | |||
| 2a6d0faf11 | |||
| 61993e331b | |||
| ddd7e4638c |
@@ -14,6 +14,9 @@ VUE_CLI_BABEL_TRANSPILE_MODULES = false
|
||||
# 是否开启登陆限制 true:是 false:否
|
||||
VUE_APP_LOGIN_FOR_PERMISSION = false
|
||||
|
||||
# 是否开启长时间无操作锁定弹框MFA验证 true:是 false:否
|
||||
VUE_APP_LOCK_FOR_PERMISSION_MFA = false
|
||||
|
||||
# 是否开启长时间无操作锁定弹框 true:是 false:否
|
||||
VUE_APP_LOCK_FOR_PERMISSION = false
|
||||
|
||||
@@ -27,7 +30,7 @@ VUE_APP_LOGOUT_FOR_PERMISSION = false
|
||||
VUE_APP_LOGOUT_FOR_TIME = 1800
|
||||
|
||||
# 是否开启密码正则验证 true:是 false:否
|
||||
VUE_APP_PASSWORD_FOR_PERMISSION = true
|
||||
VUE_APP_PASSWORD_FOR_PERMISSION = false
|
||||
|
||||
# 密码校验规则
|
||||
VUE_APP_PASSWORD_FOR_REGULAR = ^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[-_.@^+\$!%#*?&\$~])[A-Za-z0-9-~_.@^+\$~!%#*?&]{8,32}$
|
||||
@@ -35,6 +38,9 @@ VUE_APP_PASSWORD_FOR_REGULAR = ^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[-_.@^+\$!
|
||||
# 是否开启文档签署验证 true:是 false:否
|
||||
VUE_APP_WORD_FOR_PERMISSION = false
|
||||
|
||||
# 公司名称
|
||||
VUE_APP_COMPANY_NAME = "Extensive Imaging"
|
||||
|
||||
|
||||
# dicom文件地址
|
||||
VUE_APP_DICOM_PATH = 'https://zyypacs.oss-cn-shanghai.aliyuncs.com'
|
||||
|
||||
@@ -8,6 +8,9 @@ VUE_APP_BASE_PATH = '/'
|
||||
# 是否开启登陆限制 true:是 false:否
|
||||
VUE_APP_LOGIN_FOR_PERMISSION = true
|
||||
|
||||
# 是否开启长时间无操作锁定弹框MFA验证 true:是 false:否
|
||||
VUE_APP_LOCK_FOR_PERMISSION_MFA = false
|
||||
|
||||
# 是否开启长时间无操作锁定弹框 true:是 false:否
|
||||
VUE_APP_LOCK_FOR_PERMISSION = true
|
||||
|
||||
@@ -29,6 +32,9 @@ VUE_APP_PASSWORD_FOR_REGULAR = ^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[-_.@^+\$!
|
||||
# 是否开启文档签署验证 true:是 false:否
|
||||
VUE_APP_WORD_FOR_PERMISSION = true
|
||||
|
||||
# 公司名称
|
||||
VUE_APP_COMPANY_NAME = "Extensive Imaging"
|
||||
|
||||
# dicom文件地址
|
||||
# VUE_APP_DICOM_PATH = 'http://101.132.193.237:7080'
|
||||
VUE_APP_DICOM_PATH = 'https://zyypacs-prod.oss-cn-shanghai.aliyuncs.com'
|
||||
|
||||
@@ -9,6 +9,9 @@ VUE_APP_IS_TEST = true
|
||||
# 是否开启登陆限制 true:是 false:否
|
||||
VUE_APP_LOGIN_FOR_PERMISSION = false
|
||||
|
||||
# 是否开启长时间无操作锁定弹框MFA验证 true:是 false:否
|
||||
VUE_APP_LOCK_FOR_PERMISSION_MFA = false
|
||||
|
||||
# 是否开启长时间无操作锁定弹框 true:是 false:否
|
||||
VUE_APP_LOCK_FOR_PERMISSION = false
|
||||
|
||||
|
||||
@@ -5,6 +5,9 @@ NODE_ENV = 'prop'
|
||||
# 是否开启登陆限制 true:是 false:否
|
||||
VUE_APP_LOGIN_FOR_PERMISSION = true
|
||||
|
||||
# 是否开启长时间无操作锁定弹框MFA验证 true:是 false:否
|
||||
VUE_APP_LOCK_FOR_PERMISSION_MFA = false
|
||||
|
||||
# 是否开启长时间无操作锁定弹框 true:是 false:否
|
||||
VUE_APP_LOCK_FOR_PERMISSION = true
|
||||
|
||||
|
||||
@@ -10,6 +10,9 @@ VUE_APP_BASE_PATH = '/'
|
||||
# 是否开启登陆限制 true:是 false:否
|
||||
VUE_APP_LOGIN_FOR_PERMISSION = true
|
||||
|
||||
# 是否开启长时间无操作锁定弹框MFA验证 true:是 false:否
|
||||
VUE_APP_LOCK_FOR_PERMISSION_MFA = false
|
||||
|
||||
# 是否开启长时间无操作锁定弹框 true:是 false:否
|
||||
VUE_APP_LOCK_FOR_PERMISSION = true
|
||||
|
||||
@@ -31,6 +34,9 @@ VUE_APP_PASSWORD_FOR_REGULAR = ^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[-_.@^+\$!
|
||||
# 是否开启文档签署验证 true:是 false:否
|
||||
VUE_APP_WORD_FOR_PERMISSION = true
|
||||
|
||||
# 公司名称
|
||||
VUE_APP_COMPANY_NAME = "Extensive Imaging"
|
||||
|
||||
# dicom文件地址
|
||||
VUE_APP_DICOM_PATH = 'https://zyypacs-uat.oss-cn-shanghai.aliyuncs.com'
|
||||
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
# just a flag
|
||||
ENV = 'production'
|
||||
NODE_ENV = 'production'
|
||||
ENV = 'usa'
|
||||
NODE_ENV = 'usa'
|
||||
# base public path
|
||||
VUE_APP_BASE_PATH = 'https://ei-code-prod.s3.amazonaws.com/2024-01-31/'
|
||||
VUE_APP_BASE_PATH = 'https://ei-code-prod.s3.amazonaws.com/2024-07-03/'
|
||||
|
||||
# 是否开启登陆限制 true:是 false:否
|
||||
VUE_APP_LOGIN_FOR_PERMISSION = false
|
||||
|
||||
# 是否开启长时间无操作锁定弹框MFA验证 true:是 false:否
|
||||
VUE_APP_LOCK_FOR_PERMISSION_MFA = true
|
||||
|
||||
# 是否开启长时间无操作锁定弹框 true:是 false:否
|
||||
VUE_APP_LOCK_FOR_PERMISSION = false
|
||||
|
||||
@@ -28,6 +31,9 @@ VUE_APP_PASSWORD_FOR_REGULAR = ^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[-_.@^+\$!
|
||||
# 是否开启文档签署验证 true:是 false:否
|
||||
VUE_APP_WORD_FOR_PERMISSION = true
|
||||
|
||||
# 公司名称
|
||||
VUE_APP_COMPANY_NAME = "Elevate Imaging"
|
||||
|
||||
# dicom文件地址
|
||||
VUE_APP_DICOM_PATH = 'https://zyypacs-usa.oss-us-west-1.aliyuncs.com'
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ clone:
|
||||
disable: true #禁用默认克隆
|
||||
|
||||
server:
|
||||
host: 192.168.3.68
|
||||
host: 106.14.89.110
|
||||
user: root
|
||||
password:
|
||||
from_secret: local_pwd
|
||||
@@ -19,7 +19,7 @@ steps:
|
||||
- name: publish-test-irc-vue
|
||||
commands:
|
||||
- echo start publish test-irc-vue
|
||||
- cd /opt/hang/vue/test-irc
|
||||
- cd /opt/1panel/hang/vue/test-irc
|
||||
- sh test-irc.sh v${DRONE_BUILD_NUMBER}
|
||||
|
||||
trigger:
|
||||
@@ -41,7 +41,7 @@ clone:
|
||||
disable: true #禁用默认克隆
|
||||
|
||||
server:
|
||||
host: 123.56.94.154
|
||||
host: 106.14.89.110
|
||||
user: root
|
||||
password:
|
||||
from_secret: local_pwd
|
||||
|
||||
@@ -11520,6 +11520,15 @@
|
||||
"resolved": "https://registry.npmmirror.com/moment/-/moment-2.29.4.tgz",
|
||||
"integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w=="
|
||||
},
|
||||
"moment-timezone": {
|
||||
"version": "0.5.45",
|
||||
"resolved": "https://registry.npmmirror.com/moment-timezone/-/moment-timezone-0.5.45.tgz",
|
||||
"integrity": "sha512-HIWmqA86KcmCAhnMAN0wuDOARV/525R2+lOLotuGFzn4HO+FH+/645z2wx0Dt3iDv6/p61SIvKnDstISainhLQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"moment": "^2.29.4"
|
||||
}
|
||||
},
|
||||
"move-concurrently": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/move-concurrently/-/move-concurrently-1.0.1.tgz",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "EICS",
|
||||
"version": "1.3.2",
|
||||
"scripts": {
|
||||
"dev": "vue-cli-service serve --open",
|
||||
"dev": "vue-cli-service serve --open --mode development",
|
||||
"build": "vue-cli-service build",
|
||||
"build:prod": "vue-cli-service build --mode prod",
|
||||
"build:uat": "vue-cli-service build --mode uat",
|
||||
@@ -83,6 +83,7 @@
|
||||
"eslint-plugin-vue": "^6.2.2",
|
||||
"html-webpack-plugin": "3.2.0",
|
||||
"minio": "^7.1.3",
|
||||
"moment-timezone": "^0.5.45",
|
||||
"node-xlsx": "^0.21.0",
|
||||
"runjs": "^4.3.2",
|
||||
"script-ext-html-webpack-plugin": "2.1.3",
|
||||
|
||||
@@ -1,20 +1,30 @@
|
||||
<template>
|
||||
<div id="app" style="position: relative">
|
||||
<router-view />
|
||||
<div v-show="show" v-adaptive @click="openI18n" style="position: fixed;bottom: 50px;left: 50px;z-index: 100000;width: 50px;height: 50px;background: #409eff88;line-height: 50px;text-align: center;color:#fff;border-radius: 50%;cursor: pointer">
|
||||
<div
|
||||
v-show="show"
|
||||
v-adaptive
|
||||
@click="openI18n"
|
||||
style="
|
||||
position: fixed;
|
||||
bottom: 50px;
|
||||
left: 50px;
|
||||
z-index: 100000;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
background: #409eff88;
|
||||
line-height: 50px;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
"
|
||||
>
|
||||
i18n
|
||||
</div>
|
||||
<el-drawer
|
||||
title="国际化"
|
||||
:visible.sync="drawer"
|
||||
direction="rtl"
|
||||
size="80%">
|
||||
<el-drawer title="国际化" :visible.sync="drawer" direction="rtl" size="80%">
|
||||
<div style="width: 320px">
|
||||
<el-form
|
||||
label-width="100px"
|
||||
@submit.native.prevent
|
||||
size="small"
|
||||
>
|
||||
<el-form label-width="100px" @submit.native.prevent size="small">
|
||||
<el-form-item label="关键字">
|
||||
<el-input v-model="key" @input="keyChange" />
|
||||
</el-form-item>
|
||||
@@ -24,11 +34,9 @@
|
||||
:data="tableData"
|
||||
v-adaptive="{ bottomOffset: 50 }"
|
||||
height="100"
|
||||
style="width: 100%">
|
||||
<el-table-column
|
||||
prop="Code"
|
||||
label="标签"
|
||||
width="300">
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column prop="Code" label="标签" width="300">
|
||||
</el-table-column>
|
||||
<!-- <el-table-column-->
|
||||
<!-- prop="Description"-->
|
||||
@@ -39,123 +47,159 @@
|
||||
<!-- {{scope.row.Description}}-->
|
||||
<!-- </template>-->
|
||||
<!-- </el-table-column>-->
|
||||
<el-table-column
|
||||
prop="Value"
|
||||
label="英文">
|
||||
<el-table-column prop="Value" label="英文">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.Value" @input="(e) => {$set(scope.row, 'Value', e)}" size="mini"></el-input>
|
||||
<el-input
|
||||
v-model="scope.row.Value"
|
||||
@input="
|
||||
(e) => {
|
||||
$set(scope.row, 'Value', e);
|
||||
}
|
||||
"
|
||||
size="mini"
|
||||
></el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="ValueCN"
|
||||
label="中文">
|
||||
<el-table-column prop="ValueCN" label="中文">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.ValueCN" @input="(e) => {$set(scope.row, 'ValueCN', e)}" size="mini"></el-input>
|
||||
<el-input
|
||||
v-model="scope.row.ValueCN"
|
||||
@input="
|
||||
(e) => {
|
||||
$set(scope.row, 'ValueCN', e);
|
||||
}
|
||||
"
|
||||
size="mini"
|
||||
></el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div style="text-align: right;padding-top: 10px;padding-right: 10px;">
|
||||
<el-button size="mini" @click="drawer = false">取消
|
||||
</el-button>
|
||||
<el-button size="mini" type="primary" @click="handleSave">保存</el-button>
|
||||
<div style="text-align: right; padding-top: 10px; padding-right: 10px">
|
||||
<el-button size="mini" @click="drawer = false">取消 </el-button>
|
||||
<el-button size="mini" type="primary" @click="handleSave"
|
||||
>保存</el-button
|
||||
>
|
||||
</div>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { batchAddOrUpdateFrontInternationalization, getFrontInternationalizationList } from '@/api/dictionary/dictionary'
|
||||
import {
|
||||
batchAddOrUpdateFrontInternationalization,
|
||||
getFrontInternationalizationList,
|
||||
} from "@/api/dictionary/dictionary";
|
||||
import Vue from "vue";
|
||||
import i18n from "./lang";
|
||||
export default {
|
||||
name: 'App',
|
||||
name: "App",
|
||||
data() {
|
||||
return {
|
||||
drawer: false,
|
||||
tableData: [],
|
||||
show: false,
|
||||
key: null,
|
||||
arr: []
|
||||
}
|
||||
arr: [],
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.show = process.env.VUE_APP_OSS_PATH === '/test/dist'
|
||||
this.show = process.env.VUE_APP_OSS_PATH === "/test/dist";
|
||||
},
|
||||
methods: {
|
||||
changeValue(target, attr, e) {
|
||||
this.$set(target, attr, e)
|
||||
this.$set(target, attr, e);
|
||||
},
|
||||
keyChange(v) {
|
||||
if (this.key) {
|
||||
this.tableData = Object.assign([], this.arr.filter(v => ~v.Code.indexOf(this.key) || ~v.Value.indexOf(this.key) || ~v.ValueCN.indexOf(this.key)))
|
||||
this.tableData = Object.assign(
|
||||
[],
|
||||
this.arr.filter(
|
||||
(v) =>
|
||||
~v.Code.indexOf(this.key) ||
|
||||
~v.Value.indexOf(this.key) ||
|
||||
~v.ValueCN.indexOf(this.key)
|
||||
)
|
||||
);
|
||||
} else {
|
||||
this.tableData = Object.assign([], this.arr)
|
||||
this.tableData = Object.assign([], this.arr);
|
||||
}
|
||||
},
|
||||
handleSave() {
|
||||
this.$confirm('确定修改当前页面国际化内容?').then(() => {
|
||||
batchAddOrUpdateFrontInternationalization(this.tableData).then(async res => {
|
||||
var zhMessages = {}, enMessages = {}
|
||||
var Internationalization = await getFrontInternationalizationList()
|
||||
Vue.prototype.$tl = Internationalization.Result
|
||||
this.tableData.forEach(v => {
|
||||
this.$confirm("确定修改当前页面国际化内容?").then(() => {
|
||||
batchAddOrUpdateFrontInternationalization(this.tableData).then(
|
||||
async (res) => {
|
||||
var zhMessages = {},
|
||||
enMessages = {};
|
||||
var Internationalization = await getFrontInternationalizationList();
|
||||
Vue.prototype.$tl = Internationalization.Result;
|
||||
this.tableData.forEach((v) => {
|
||||
// zhMessages[v.Description + '_' + v.Code] = v.ValueCN
|
||||
// enMessages[v.Description + '_' + v.Code] = v.Value
|
||||
zhMessages[v.Code] = v.ValueCN
|
||||
enMessages[v.Code] = v.Value
|
||||
})
|
||||
i18n.mergeLocaleMessage('zh', zhMessages)
|
||||
i18n.mergeLocaleMessage('en', enMessages)
|
||||
this.drawer = false
|
||||
this.$message.success('国际化修改成功')
|
||||
})
|
||||
})
|
||||
zhMessages[v.Code] = v.ValueCN;
|
||||
enMessages[v.Code] = v.Value;
|
||||
});
|
||||
i18n.mergeLocaleMessage("zh", zhMessages);
|
||||
i18n.mergeLocaleMessage("en", enMessages);
|
||||
this.drawer = false;
|
||||
this.$message.success("国际化修改成功");
|
||||
}
|
||||
);
|
||||
});
|
||||
},
|
||||
openI18n() {
|
||||
this.tableData = []
|
||||
this.key = null
|
||||
this.drawer = true
|
||||
let arr = []
|
||||
let tableData = this.$tl.map(v => {
|
||||
let a = {...v}
|
||||
this.tableData = [];
|
||||
this.key = null;
|
||||
this.drawer = true;
|
||||
let arr = [];
|
||||
let tableData = this.$tl.map((v) => {
|
||||
let a = { ...v };
|
||||
// if (!a.Description) {
|
||||
// a.Description = this.$route.path
|
||||
// }
|
||||
return a
|
||||
})
|
||||
tableData = tableData.filter(v => {
|
||||
return a;
|
||||
});
|
||||
tableData = tableData.filter((v) => {
|
||||
// return ~this.$path.indexOf(v.Description + '_' + v.Code)
|
||||
return ~this.$path.indexOf(v.Code)
|
||||
})
|
||||
this.$path.forEach(v => {
|
||||
let o = tableData.find(a => {
|
||||
return a.Code === v
|
||||
})
|
||||
return ~this.$path.indexOf(v.Code);
|
||||
});
|
||||
this.$path.forEach((v) => {
|
||||
let o = tableData.find((a) => {
|
||||
return a.Code === v;
|
||||
});
|
||||
if (o) {
|
||||
arr.push(o)
|
||||
arr.push(o);
|
||||
} else {
|
||||
arr.push({
|
||||
Code: v,
|
||||
Description: null,
|
||||
Value: null,
|
||||
ValueCN: null
|
||||
})
|
||||
ValueCN: null,
|
||||
});
|
||||
}
|
||||
})
|
||||
this.arr = arr
|
||||
});
|
||||
this.arr = arr;
|
||||
if (this.key) {
|
||||
this.tableData = Object.assign([], this.arr.filter(v => ~v.Code.indexOf(this.key) || ~v.Value.indexOf(this.key) || ~v.ValueCN.indexOf(this.key)))
|
||||
this.tableData = Object.assign(
|
||||
[],
|
||||
this.arr.filter(
|
||||
(v) =>
|
||||
~v.Code.indexOf(this.key) ||
|
||||
~v.Value.indexOf(this.key) ||
|
||||
~v.ValueCN.indexOf(this.key)
|
||||
)
|
||||
);
|
||||
} else {
|
||||
this.tableData = Object.assign([], this.arr)
|
||||
}
|
||||
console.log(JSON.stringify(this.$path))
|
||||
console.log(JSON.stringify(this.tableData))
|
||||
}
|
||||
}
|
||||
this.tableData = Object.assign([], this.arr);
|
||||
}
|
||||
// console.log(JSON.stringify(this.$path))
|
||||
// console.log(JSON.stringify(this.tableData))
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
$light_gray: #606266;
|
||||
.el-tooltip__popper {
|
||||
max-width: 400px;
|
||||
}
|
||||
@@ -197,4 +241,15 @@ textarea{
|
||||
.box-body .el-button.is-circle i.el-icon-question:before {
|
||||
color: #fff;
|
||||
}
|
||||
.system-title {
|
||||
font-size: 35px;
|
||||
color: $light_gray;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
font-family: "Times New Roman";
|
||||
text-shadow: 1px 0.5px 1.5px #666;
|
||||
}
|
||||
.title-logo {
|
||||
height: 40px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1006,3 +1006,11 @@ export function deleteCommonDocument(commonDocumentId) {
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
//getTrialSiteList
|
||||
export function getTrialSiteList(params) {
|
||||
return request({
|
||||
url: `/site/getTrialSiteList`,
|
||||
method: 'post',
|
||||
data: params
|
||||
})
|
||||
}
|
||||
@@ -76,3 +76,11 @@ export function fullyReplicated(param) {
|
||||
})
|
||||
}
|
||||
|
||||
// 获取所有字典key
|
||||
export function getDictionaryCodeList() {
|
||||
return request({
|
||||
url: `/Dictionary/getAllDictionaryKey`,
|
||||
method: 'post',
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -22,9 +22,9 @@ export function getBasicDataSelects(param) {
|
||||
})
|
||||
}
|
||||
|
||||
export function getBasicDataAllSelect(params) {
|
||||
export function getBasicDataAllSelect(params, isSystem) {
|
||||
return request({
|
||||
url: params ? `/Dictionary/getBasicDataAllSelect?TrialReadingCriterionId=${params}` : `/Dictionary/getBasicDataAllSelect`,
|
||||
url: params ? (isSystem ? `/Dictionary/getBasicDataAllSelect?SystemReadingCriterionId=${params}` : `/Dictionary/getBasicDataAllSelect?TrialReadingCriterionId=${params}`) : `/Dictionary/getBasicDataAllSelect`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
@@ -14,17 +14,19 @@ export function getHospitalList() {
|
||||
})
|
||||
}
|
||||
|
||||
export function getAllSponsorList() {
|
||||
export function getAllSponsorList(params) {
|
||||
return request({
|
||||
url: '/sponsor/getAllSponsorList',
|
||||
method: 'get'
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
export function getAllCROList() {
|
||||
export function getAllCROList(params) {
|
||||
return request({
|
||||
url: '/cro/getAllCROList',
|
||||
method: 'get'
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
export function getAllSiteList() {
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
import request from '@/utils/request'
|
||||
// 下载打包影像
|
||||
export function requestPackageAndAnonymizImage(params) {
|
||||
return request({
|
||||
url: '/DownloadAndUpload/requestPackageAndAnonymizImage',
|
||||
method: 'post',
|
||||
params
|
||||
})
|
||||
}
|
||||
// 获取影像上传列表
|
||||
export function getSubjectImageUploadList(params) {
|
||||
return request({
|
||||
url: '/DownloadAndUpload/getSubjectImageUploadList',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
// 预上传
|
||||
export function preArchiveDicomStudy(data) {
|
||||
return request({
|
||||
url: '/DownloadAndUpload/preArchiveDicomStudy',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
// 归档
|
||||
export function addOrUpdateArchiveTaskStudy(data) {
|
||||
return request({
|
||||
url: '/DownloadAndUpload/addOrUpdateArchiveTaskStudy',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除上传文件
|
||||
export function deleteTaskStudy(params) {
|
||||
return request({
|
||||
url: '/DownloadAndUpload/deleteTaskStudy',
|
||||
method: 'delete',
|
||||
params
|
||||
})
|
||||
}
|
||||
@@ -1364,9 +1364,9 @@ export function getForwardList(param) {
|
||||
})
|
||||
}
|
||||
|
||||
export function getNoneDicomStudyList(subjectVisitId, sudyId = '') {
|
||||
export function getNoneDicomStudyList(subjectVisitId, sudyId = '', isFilterZip = false) {
|
||||
return request({
|
||||
url: `/NoneDicomStudy/getNoneDicomStudyList?subjectVisitId=${subjectVisitId}&nonedicomStudyId=${sudyId}`,
|
||||
url: `/NoneDicomStudy/getNoneDicomStudyList?subjectVisitId=${subjectVisitId}&nonedicomStudyId=${sudyId}&isFilterZip=${isFilterZip}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
@@ -1747,6 +1747,21 @@ export function deleteTrialExternalUser(id) {
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
export function getUserTobeDoneRecord() {
|
||||
return request({
|
||||
url: `/PersonalWorkstation/getUserTobeDoneRecord`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function getNeedSignTrialDocTrialIdList() {
|
||||
return request({
|
||||
url: `/PersonalWorkstation/getNeedSignTrialDocTrialIdList`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function getBasicStat() {
|
||||
return request({
|
||||
url: `/PersonalWorkstation/getBasicStat`,
|
||||
@@ -2795,6 +2810,29 @@ export function saveImageQuality(param) {
|
||||
data: param
|
||||
})
|
||||
}
|
||||
export function getIsSuvMaxLesion(param) {
|
||||
return request({
|
||||
url: `/LuganoCalculate/getIsSuvMaxLesion`,
|
||||
method: 'post',
|
||||
data: param
|
||||
})
|
||||
}
|
||||
|
||||
export function getCanChooseNotMerge(param) {
|
||||
return request({
|
||||
url: `/LuganoCalculate/getCanChooseNotMerge`,
|
||||
method: 'post',
|
||||
data: param
|
||||
})
|
||||
}
|
||||
export function saveTaskQuestion(saveQuestionType, param) {
|
||||
return request({
|
||||
url: `/SaveTaskQuestion/${saveQuestionType}`,
|
||||
method: 'post',
|
||||
data: param
|
||||
})
|
||||
}
|
||||
|
||||
export function deleteReadingRowAnswer(param) {
|
||||
return request({
|
||||
url: `/ReadingImageTask/deleteReadingRowAnswer`,
|
||||
@@ -2864,6 +2902,14 @@ export function asyncTrialCriterionDictionary(param) {
|
||||
})
|
||||
}
|
||||
|
||||
export function configTrialProcessInfoVerification(param) {
|
||||
return request({
|
||||
url: `/TrialConfig/configTrialProcessInfoVerification`,
|
||||
method: 'post',
|
||||
data: param
|
||||
})
|
||||
}
|
||||
|
||||
export function getTrialEmailNoticeConfigList(param) {
|
||||
return request({
|
||||
url: `/TrialEmailNoticeConfig/getTrialEmailNoticeConfigList`,
|
||||
@@ -3519,3 +3565,113 @@ export function getTrialSiteSurveySelectList(param) {
|
||||
data: param
|
||||
})
|
||||
}
|
||||
export function getCanMergeLesion(param) {
|
||||
return request({
|
||||
url: `/ReadingImageTask/getCanMergeLesion`,
|
||||
method: 'post',
|
||||
data: param
|
||||
})
|
||||
}
|
||||
|
||||
export function mergeLesion(param) {
|
||||
return request({
|
||||
url: `/ReadingImageTask/mergeLesion`,
|
||||
method: 'post',
|
||||
data: param
|
||||
})
|
||||
}
|
||||
|
||||
export function resetAndAsyncCriterion(param) {
|
||||
return request({
|
||||
url: `/Inspection/ReadingCriterion/ResetAndAsyncCriterion`,
|
||||
method: 'post',
|
||||
data: param
|
||||
})
|
||||
}
|
||||
|
||||
export function batchSetCriterionJoinJoinAnalysis(param) {
|
||||
return request({
|
||||
url: `/DoctorWorkload/batchSetCriterionJoinJoinAnalysis`,
|
||||
method: 'post',
|
||||
data: param
|
||||
})
|
||||
}
|
||||
|
||||
export function updateTrialVirtualSiteCode(param) {
|
||||
return request({
|
||||
url: `/TaskConsistentRule/updateTrialVirtualSiteCode`,
|
||||
method: 'post',
|
||||
data: param
|
||||
})
|
||||
}
|
||||
|
||||
export function getUpdateVirtualSiteCodeList(param) {
|
||||
return request({
|
||||
url: `/TaskConsistentRule/getUpdateVirtualSiteCodeList?trialId=${param.trialId}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function addDefaultQuestions(param) {
|
||||
return request({
|
||||
url: `/ReadingMedicineQuestion/addDefaultQuestions`,
|
||||
method: 'post',
|
||||
data: param
|
||||
})
|
||||
}
|
||||
|
||||
export function getReadingCalculationData(param) {
|
||||
return request({
|
||||
url: `/ReadingImageTask/getReadingCalculationData`,
|
||||
method: 'post',
|
||||
data: param
|
||||
})
|
||||
}
|
||||
|
||||
export function getTrialSignDocumentList(param) {
|
||||
return request({
|
||||
url: `/TrialDocument/getTrialSignDocumentList`,
|
||||
method: 'post',
|
||||
data: param
|
||||
})
|
||||
}
|
||||
|
||||
export function getPreviousOtherPicturePath(param) {
|
||||
return request({
|
||||
url: `/ReadingImageTask/getPreviousOtherPicturePath`,
|
||||
method: 'post',
|
||||
data: param
|
||||
})
|
||||
}
|
||||
|
||||
export function verifyIsCanConfirm(param) {
|
||||
return request({
|
||||
url: `/ReadingMedicineQuestion/verifyIsCanConfirm`,
|
||||
method: 'post',
|
||||
data: param
|
||||
})
|
||||
}
|
||||
|
||||
export function getPTAndCtSeries(param) {
|
||||
return request({
|
||||
url: `/SubjectVisit/getPTAndCtSeries`,
|
||||
method: 'post',
|
||||
data: param
|
||||
})
|
||||
}
|
||||
|
||||
export function getDicomSeriesInfo(param) {
|
||||
return request({
|
||||
url: `/SubjectVisit/getDicomSeriesInfo`,
|
||||
method: 'post',
|
||||
data: param
|
||||
})
|
||||
}
|
||||
|
||||
export function getTrialSiteSelectList(params) {
|
||||
return request({
|
||||
url: `/trialMaintenance/getTrialSiteSelectList`,
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
@@ -436,9 +436,9 @@ export function addSubjectCancelDoctorNote(params) {
|
||||
})
|
||||
}
|
||||
|
||||
export function getSubjectCancelDoctorHistoryList(SubjectId) {
|
||||
export function getSubjectCancelDoctorHistoryList(SubjectId, TrialReadingCriterionId) {
|
||||
return request({
|
||||
url: `/TaskAllocationRule/getSubjectCancelDoctorHistoryList?SubjectId=${SubjectId}`,
|
||||
url: `/TaskAllocationRule/getSubjectCancelDoctorHistoryList?SubjectId=${SubjectId}&&TrialReadingCriterionId=${TrialReadingCriterionId}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
@@ -94,4 +94,20 @@ export function getTrialJudgyInfo(params) {
|
||||
data: params
|
||||
})
|
||||
}
|
||||
// 获取检查部位列表
|
||||
export function getTrialBodyPartList(params) {
|
||||
return request({
|
||||
url: `/TrialConfig/getTrialBodyPartList`,
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
// 新增检查部位
|
||||
export function addOrUpdateTrialBodyPart(data) {
|
||||
return request({
|
||||
url: `/TrialConfig/addOrUpdateTrialBodyPart`,
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,13 @@ export function login(data) {
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function loginOut(params) {
|
||||
return request({
|
||||
url: `/User/loginOut`,
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
export function getAllDictionary() {
|
||||
return request({
|
||||
url: '/dictionary/getAllDictionary',
|
||||
@@ -152,3 +158,30 @@ export function getUserLogList(params) {
|
||||
data: params
|
||||
})
|
||||
}
|
||||
|
||||
// 获取登录用户
|
||||
export function getTrialUserList(params) {
|
||||
return request({
|
||||
url: `/TrialMaintenance/getTrialUserList`,
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// 验证MFA邮件
|
||||
export function verifyMFACode(params) {
|
||||
return request({
|
||||
url: `/User/verifyMFACode`,
|
||||
method: 'post',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// 发送MFA邮件
|
||||
export function sendMFAEmail(params) {
|
||||
return request({
|
||||
url: `/User/sendMFAEmail`,
|
||||
method: 'post',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 145 KiB |
|
After Width: | Height: | Size: 55 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 15 KiB |
@@ -2,9 +2,20 @@
|
||||
<template>
|
||||
<div class="base-search-form">
|
||||
<el-form :size="size" :inline="true" :label-width="labelWidth">
|
||||
<el-form-item v-for="item in searchForm" :key="item.prop" :label="item.label">
|
||||
<el-form-item
|
||||
v-for="item in searchForm"
|
||||
:key="item.prop"
|
||||
:label="item.label"
|
||||
>
|
||||
<!-- 输入框 -->
|
||||
<el-input v-if="item.type==='Input'" v-model="searchData[item.prop]" :placeholder="item.placeholder" size="mini" :style="{width:item.width}" :readonly="item.readonly" />
|
||||
<el-input
|
||||
v-if="item.type === 'Input'"
|
||||
v-model="searchData[item.prop]"
|
||||
:placeholder="item.placeholder"
|
||||
size="mini"
|
||||
:style="{ width: item.width }"
|
||||
:readonly="item.readonly"
|
||||
/>
|
||||
<!-- 下拉框 -->
|
||||
<el-select
|
||||
v-if="item.type === 'Select'"
|
||||
@@ -12,7 +23,6 @@
|
||||
:placeholder="item.placeholder"
|
||||
size="mini"
|
||||
:style="{ width: item.width }"
|
||||
|
||||
@change="item.change && item.change(that, searchData[item.prop])"
|
||||
>
|
||||
<el-option
|
||||
@@ -28,7 +38,6 @@
|
||||
:placeholder="item.placeholder"
|
||||
size="mini"
|
||||
:style="{ width: item.width }"
|
||||
|
||||
@change="item.change && item.change(that, searchData[item.prop])"
|
||||
>
|
||||
<el-option
|
||||
@@ -39,33 +48,107 @@
|
||||
/>
|
||||
</el-select>
|
||||
<!-- 单选 -->
|
||||
<el-radio-group v-if="item.type==='Radio'" v-model="searchData[item.prop]" :style="{width:item.width}">
|
||||
<el-radio v-for="ra in item.radios" :key="ra.value" :label="ra.value">{{ ra.label }}</el-radio>
|
||||
<el-radio-group
|
||||
v-if="item.type === 'Radio'"
|
||||
v-model="searchData[item.prop]"
|
||||
:style="{ width: item.width }"
|
||||
>
|
||||
<el-radio
|
||||
v-for="ra in item.radios"
|
||||
:key="ra.value"
|
||||
:label="ra.value"
|
||||
>{{ ra.label }}</el-radio
|
||||
>
|
||||
</el-radio-group>
|
||||
<!-- 单选按钮 -->
|
||||
<el-radio-group v-if="item.type==='RadioButton'" v-model="searchData[item.prop]" :style="{width:item.width}" @change="item.change && item.change(searchData[item.prop])">
|
||||
<el-radio-button v-for="ra in item.radios" :key="ra.value" :label="ra.value">{{ ra.label }}</el-radio-button>
|
||||
<el-radio-group
|
||||
v-if="item.type === 'RadioButton'"
|
||||
v-model="searchData[item.prop]"
|
||||
:style="{ width: item.width }"
|
||||
@change="item.change && item.change(searchData[item.prop])"
|
||||
>
|
||||
<el-radio-button
|
||||
v-for="ra in item.radios"
|
||||
:key="ra.value"
|
||||
:label="ra.value"
|
||||
>{{ ra.label }}</el-radio-button
|
||||
>
|
||||
</el-radio-group>
|
||||
<!-- 复选框 -->
|
||||
<el-checkbox-group v-if="item.type==='Checkbox'" v-model="searchData[item.prop]" :style="{width:item.width}">
|
||||
<el-checkbox v-for="ch in item.checkboxs" :key="ch.value" :label="ch.value">{{ ch.label }}</el-checkbox>
|
||||
<el-checkbox-group
|
||||
v-if="item.type === 'Checkbox'"
|
||||
v-model="searchData[item.prop]"
|
||||
:style="{ width: item.width }"
|
||||
>
|
||||
<el-checkbox
|
||||
v-for="ch in item.checkboxs"
|
||||
:key="ch.value"
|
||||
:label="ch.value"
|
||||
>{{ ch.label }}</el-checkbox
|
||||
>
|
||||
</el-checkbox-group>
|
||||
<!-- 日期 -->
|
||||
<el-date-picker v-if="item.type==='Date'" v-model="searchData[item.prop]" :placeholder="item.placeholder" :style="{width:item.width}" value-format="yyyy-MM-dd" format="yyyy-MM-dd" :picker-options="item.pickerOption" />
|
||||
<el-date-picker
|
||||
v-if="item.type === 'Date'"
|
||||
v-model="searchData[item.prop]"
|
||||
:placeholder="item.placeholder"
|
||||
:style="{ width: item.width }"
|
||||
value-format="yyyy-MM-dd"
|
||||
format="yyyy-MM-dd"
|
||||
:picker-options="item.pickerOption"
|
||||
/>
|
||||
<!-- 时间 -->
|
||||
<el-time-select v-if="item.type==='Time'" v-model="searchData[item.prop]" :placeholder="item.placeholder" type="" :style="{width:item.width}" />
|
||||
<el-time-select
|
||||
v-if="item.type === 'Time'"
|
||||
v-model="searchData[item.prop]"
|
||||
:placeholder="item.placeholder"
|
||||
type=""
|
||||
:style="{ width: item.width }"
|
||||
/>
|
||||
<!-- 日期时间 -->
|
||||
<el-date-picker v-if="item.type==='DateTime'" v-model="searchData[item.prop]" :placeholder="item.placeholder" type="datetime" :disabled="item.disable && item.disable(searchData[item.prop])" :style="{width:item.width}" />
|
||||
<el-date-picker
|
||||
v-if="item.type === 'DateTime'"
|
||||
v-model="searchData[item.prop]"
|
||||
:placeholder="item.placeholder"
|
||||
type="datetime"
|
||||
value-format="yyyy-MM-dd HH:mm:ss"
|
||||
:disabled="item.disable && item.disable(searchData[item.prop])"
|
||||
:style="{ width: item.width }"
|
||||
/>
|
||||
<!-- 日期时间段 -->
|
||||
<el-date-picker
|
||||
v-if="item.type === 'Daterange'"
|
||||
v-model="searchData[item.prop]"
|
||||
type="datetimerange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始时间"
|
||||
end-placeholder="结束时间"
|
||||
value-format="yyyy-MM-dd HH:mm:ss"
|
||||
format="yyyy-MM-dd HH:mm:ss"
|
||||
:style="{ width: item.width }"
|
||||
clearable
|
||||
/>
|
||||
<!-- 滑块 -->
|
||||
<!-- <el-slider v-if="item.type==='Slider'" v-model="searchData[item.prop]"></el-slider> -->
|
||||
<!-- 开关 -->
|
||||
<el-switch v-if="item.type==='Switch'" v-model="searchData[item.prop]" :style="{width:item.width}" />
|
||||
<el-switch
|
||||
v-if="item.type === 'Switch'"
|
||||
v-model="searchData[item.prop]"
|
||||
:style="{ width: item.width }"
|
||||
/>
|
||||
<!-- 具名slot -->
|
||||
<slot v-if="item.type === 'Custom'" :name="item.slot" />
|
||||
</el-form-item>
|
||||
<el-form-item v-for="item in searchHandle" :key="item.label">
|
||||
<slot v-if="item.slot" :name="item.slot" />
|
||||
<el-button v-else :type="item.type" :size="item.size || size" :icon="item.icon || ''" @click="handleClick(item.emitKey)">{{ item.label }}</el-button>
|
||||
<el-button
|
||||
v-else
|
||||
:type="item.type"
|
||||
:size="item.size || size"
|
||||
:icon="item.icon || ''"
|
||||
@click="handleClick(item.emitKey)"
|
||||
>{{ item.label }}</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
@@ -76,42 +159,40 @@ export default {
|
||||
props: {
|
||||
that: {
|
||||
type: Object,
|
||||
default: this
|
||||
default: this,
|
||||
},
|
||||
isHandle: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
default: true,
|
||||
},
|
||||
labelWidth: {
|
||||
type: String,
|
||||
default: ''
|
||||
default: "",
|
||||
},
|
||||
size: {
|
||||
type: String,
|
||||
default: 'mini'
|
||||
default: "mini",
|
||||
},
|
||||
searchForm: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
default: () => [],
|
||||
},
|
||||
searchHandle: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
default: () => [],
|
||||
},
|
||||
searchData: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
}
|
||||
default: () => {},
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleClick(emitKey) {
|
||||
// emit事件
|
||||
this.$emit(`${emitKey}`)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this.$emit(`${emitKey}`);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.base-search-form {
|
||||
|
||||
@@ -1,6 +1,16 @@
|
||||
<template>
|
||||
<div class="base-model-wrapper">
|
||||
<el-dialog v-if="config.visible" v-dialogDrag :title="config.title" :append-to-body="config.appendToBody" :visible.sync="config.visible" :close-on-click-modal="false" :show-close="config.showClose" :width="config.width" :fullscreen="config.fullscreen">
|
||||
<el-dialog
|
||||
v-if="config.visible"
|
||||
v-dialogDrag
|
||||
:title="config.title"
|
||||
:append-to-body="config.appendToBody"
|
||||
:visible.sync="config.visible"
|
||||
:close-on-click-modal="false"
|
||||
:show-close="config.showClose"
|
||||
:width="config.width"
|
||||
:fullscreen="config.fullscreen"
|
||||
>
|
||||
<div class="base-modal-body">
|
||||
<slot name="dialog-body" />
|
||||
</div>
|
||||
@@ -12,24 +22,24 @@
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'BaseDialog',
|
||||
name: "BaseDialog",
|
||||
props: {
|
||||
config: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {
|
||||
visible: false,
|
||||
title: '',
|
||||
title: "",
|
||||
closeOnClickModal: false,
|
||||
showClose: true,
|
||||
appendToBody: false,
|
||||
width: '100px',
|
||||
fullscreen: false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
width: "100px",
|
||||
fullscreen: false,
|
||||
};
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.base-model-wrapper {
|
||||
@@ -54,4 +64,9 @@ export default {
|
||||
padding: 10px;
|
||||
}
|
||||
}
|
||||
.notFooter {
|
||||
.is-fullscreen .el-dialog__footer {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="chat-wrapper">
|
||||
<div class="chat-content">
|
||||
<div v-for="(record,index) in recordContent" :key="index">
|
||||
<div v-for="(record,index) in recordContent" :key="`${record.chatTime}${index}`">
|
||||
<div v-if="!record.mineMsg" class="word">
|
||||
<!-- <img :src="record.headUrl"> -->
|
||||
<img src="@/assets/CRC.png">
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
style="width:100%;height:100%;position:relative;"
|
||||
class="cornerstone-element"
|
||||
@contextmenu.prevent="onContextmenu"
|
||||
@mousemove="sliderMousemove"
|
||||
@mouseup="sliderMouseup"
|
||||
>
|
||||
<div v-show="dicomInfo.series" class="info-series">
|
||||
@@ -54,7 +53,7 @@
|
||||
<!-- <div v-show="dicomInfo.acc">ACC {{ dicomInfo.acc }}</div> -->
|
||||
<!-- <div>{{ dicomInfo.time }}</div> -->
|
||||
</div>
|
||||
<div ref="sliderBox" class="my_slider_box" style="position: absolute;right: 1px;height: calc(100% - 100px);transform: translateY(-50%);top: calc(50% - 30px);width: 10px;background: #333;cursor: pointer">
|
||||
<div ref="sliderBox" class="my_slider_box" style="position: absolute;right: 1px;height: calc(100% - 100px);transform: translateY(-50%);top: calc(50% - 30px);width: 10px;background: #333;cursor: pointer" @click.stop="goViewer($event)">
|
||||
<div :style="{top: height + '%'}" style="z-index:10;background: #9e9e9e;height: 20px;width: 100%;position: absolute;top: 0;cursor: move" @mousedown="sliderMousedown($event)" />
|
||||
</div>
|
||||
<div style="position: absolute;left: 50%;top: 15px;color: #f44336;">
|
||||
@@ -163,7 +162,9 @@ export default {
|
||||
isMove: false
|
||||
},
|
||||
mousePosition: { x: '', y: '', mo: '' },
|
||||
markers: { top: '', right: '', bottom: '', left: '' }
|
||||
markers: { top: '', right: '', bottom: '', left: '' },
|
||||
orientationMarkers: [],
|
||||
originalMarkers: []
|
||||
}
|
||||
},
|
||||
|
||||
@@ -186,6 +187,9 @@ export default {
|
||||
document.addEventListener('mouseup', () => {
|
||||
this.sliderMouseup()
|
||||
})
|
||||
document.addEventListener('mousemove', (e) => {
|
||||
this.sliderMousemove(e)
|
||||
})
|
||||
this.canvas.addEventListener('cornerstonetoolsstackscroll', this.stackScrollCallback)
|
||||
},
|
||||
|
||||
@@ -205,7 +209,7 @@ export default {
|
||||
var instanceId = imageId.split('/')[imageId.split('/').length - 1]
|
||||
instanceId = instanceId.split('.')[0]
|
||||
this.stack.instanceId = instanceId
|
||||
if (this.toolState.clipPlaying) this.toggleClipPlay()
|
||||
this.toolState.clipPlaying = false
|
||||
const element = this.$refs.canvas
|
||||
cornerstone.enable(element)
|
||||
this.loading = true
|
||||
@@ -213,7 +217,9 @@ export default {
|
||||
cornerstone.loadAndCacheImage(this.stack.imageIds[this.stack.currentImageIdIndex])
|
||||
.then(image => {
|
||||
this.loading = false
|
||||
if (this.stack.imageIds.indexOf(image.imageId) !== -1) {
|
||||
this.onFirstImageLoaded(image)
|
||||
}
|
||||
}).catch((error) => {
|
||||
this.loading = false
|
||||
if (error.error && error.error.message) {
|
||||
@@ -356,6 +362,12 @@ export default {
|
||||
if (this.dicomInfo.thick) {
|
||||
this.dicomInfo.thick = this.dicomInfo.thick.toFixed(2)
|
||||
}
|
||||
let newImageIdIndex = this.stack.imageIds.findIndex(i=>i===e.detail.image.imageId)
|
||||
if(newImageIdIndex === -1) return
|
||||
this.stack.currentImageIdIndex = newImageIdIndex
|
||||
this.stack.imageIdIndex = newImageIdIndex
|
||||
this.series.imageIdIndex = newImageIdIndex
|
||||
this.height = (this.stack.currentImageIdIndex) * 100 / (this.stack.imageIds.length - 1)
|
||||
},
|
||||
stackScrollCallback(e) {
|
||||
const { detail } = e
|
||||
@@ -403,6 +415,7 @@ export default {
|
||||
this.dicomInfo.location = position
|
||||
},
|
||||
getOrientationMarker(element) {
|
||||
console.log('getOrientationMarker')
|
||||
const enabledElement = cornerstone.getEnabledElement(element)
|
||||
const imagePlane = cornerstone.metaData.get(
|
||||
'imagePlaneModule',
|
||||
@@ -426,6 +439,7 @@ export default {
|
||||
if (!markers) {
|
||||
return
|
||||
}
|
||||
|
||||
this.orientationMarkers = [oppositeColumn, row, column, oppositeRow]
|
||||
this.originalMarkers = [oppositeColumn, row, column, oppositeRow]
|
||||
this.setMarkers()
|
||||
@@ -438,10 +452,10 @@ export default {
|
||||
}
|
||||
},
|
||||
onImageLoaded(e) {
|
||||
var image = e.detail.image
|
||||
// var seriesIndex = -1
|
||||
var seriesUid = image.data.string('x0020000e')
|
||||
console.log(seriesUid)
|
||||
// var image = e.detail.image
|
||||
// // var seriesIndex = -1
|
||||
// var seriesUid = image.data.string('x0020000e')
|
||||
// console.log(seriesUid)
|
||||
},
|
||||
getToolForElement(toolName) {
|
||||
var isExist = false
|
||||
@@ -521,6 +535,9 @@ export default {
|
||||
this.sliderInfo.oldB = parseInt(e.srcElement.style.top) * boxHeight / 100
|
||||
this.sliderInfo.oldM = e.clientY
|
||||
this.sliderInfo.isMove = true
|
||||
e.stopImmediatePropagation()
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
},
|
||||
sliderMousemove(e) {
|
||||
if (!this.sliderInfo.isMove) return
|
||||
@@ -540,6 +557,13 @@ export default {
|
||||
sliderMouseup(e) {
|
||||
this.sliderInfo.isMove = false
|
||||
},
|
||||
goViewer(e) {
|
||||
// console.log(this.$refs['sliderBox'].clientHeight)
|
||||
var height = e.offsetY * 100 / this.$refs['sliderBox'].clientHeight
|
||||
this.height = height
|
||||
var index = Math.trunc(this.stack.imageIds.length * this.height / 100)
|
||||
scroll(this.canvas, index)
|
||||
},
|
||||
onClipStopped() {
|
||||
this.toolState.clipPlaying = false
|
||||
},
|
||||
@@ -610,6 +634,7 @@ export default {
|
||||
enabledElement.renderingTools.renderCanvasData = renderCanvasData
|
||||
},
|
||||
scrollPage(offset) {
|
||||
if(this.loading) return
|
||||
var index = this.stack.currentImageIdIndex + offset
|
||||
if (index < 0) index = 0
|
||||
else if (index >= this.stack.imageIds.length) {
|
||||
@@ -621,6 +646,7 @@ export default {
|
||||
},
|
||||
|
||||
toggleClipPlay() {
|
||||
if(this.loading) return
|
||||
if (this.toolState.clipPlaying) {
|
||||
cornerstoneTools.stopClip(this.canvas)
|
||||
this.toolState.clipPlaying = false
|
||||
@@ -675,8 +701,11 @@ export default {
|
||||
},
|
||||
|
||||
resetRotate() {
|
||||
if (this.originalMarkers.length > 0) {
|
||||
this.orientationMarkers = [...this.originalMarkers]
|
||||
this.setMarkers()
|
||||
}
|
||||
|
||||
var viewport = cornerstone.getViewport(this.canvas)
|
||||
viewport.hflip = false
|
||||
viewport.vflip = false
|
||||
@@ -685,6 +714,7 @@ export default {
|
||||
},
|
||||
|
||||
setRotate(hflip, vflip, angle, type) {
|
||||
if (this.orientationMarkers.length > 0) {
|
||||
var markers = [...this.orientationMarkers]
|
||||
if (type === 2) {
|
||||
// 垂直翻转
|
||||
@@ -703,6 +733,7 @@ export default {
|
||||
this.orientationMarkers = [markers[3]].concat(markers.slice(0, 3))
|
||||
}
|
||||
this.setMarkers()
|
||||
}
|
||||
var viewport = cornerstone.getViewport(this.canvas)
|
||||
if (hflip) viewport.hflip = !viewport.hflip
|
||||
if (vflip) viewport.vflip = !viewport.vflip
|
||||
|
||||
@@ -162,6 +162,19 @@
|
||||
<button :title="$t('trials:dicom-show:lens')" class="btn-link" data-tool="Magnify" @click="setToolActive($event,'Magnify')">
|
||||
<svg-icon icon-class="zoom" style="font-size:20px;" />
|
||||
</button>
|
||||
<button :title="$t('trials:reading:button:rotate')" class="btn-link dropdown" data-tool="Rotate">
|
||||
<svg-icon icon-class="rotate" style="font-size:20px;" />
|
||||
<div class="dropdown-content">
|
||||
<div @click.stop="setDicomCanvasRotate(1)">{{ $t('trials:reading:button:rotateDefault') }}</div>
|
||||
<div @click.stop="setDicomCanvasRotate(2)">{{ $t('trials:reading:button:rotateHorizontal') }}</div>
|
||||
<div @click.stop="setDicomCanvasRotate(3)">{{ $t('trials:reading:button:rotateVertical') }}</div>
|
||||
<div @click.stop="setDicomCanvasRotate(4)">{{ $t('trials:reading:button:rotateTurnLeft') }}</div>
|
||||
<div @click.stop="setDicomCanvasRotate(5)">{{ $t('trials:reading:button:rotateTurnRight') }}</div>
|
||||
</div>
|
||||
</button>
|
||||
<button :title="$t('trials:reading:button:move')" class="btn-link" data-tool="Pan" @click="setToolActive($event,'Pan')">
|
||||
<svg-icon icon-class="move" style="font-size:20px;" />
|
||||
</button>
|
||||
<button :title="$t('trials:reading:button:fitWindow')" class="btn-link" data-tool="fitToWindow" @click="fitToType($event,'fitToWindow')">
|
||||
<svg-icon icon-class="fitToWindow" style="font-size:20px;" />
|
||||
</button>
|
||||
@@ -169,19 +182,7 @@
|
||||
<svg-icon icon-class="fitToImage" style="font-size:20px;" />
|
||||
</button>
|
||||
<!-- <button title="旋转" class="btn-link dropdown" data-tool="Rotate" @click="setToolActive($event,'Rotate')"> -->
|
||||
<button :title="$t('trials:reading:button:rotate')" class="btn-link dropdown" data-tool="Rotate">
|
||||
<svg-icon icon-class="rotate" style="font-size:20px;" />
|
||||
<div class="dropdown-content">
|
||||
<p @click.stop="setDicomCanvasRotate(1)">{{ $t('trials:reading:button:rotateDefault') }}</p>
|
||||
<p @click.stop="setDicomCanvasRotate(2)">{{ $t('trials:reading:button:rotateHorizontal') }}</p>
|
||||
<p @click.stop="setDicomCanvasRotate(3)">{{ $t('trials:reading:button:rotateVertical') }}</p>
|
||||
<p @click.stop="setDicomCanvasRotate(4)">{{ $t('trials:reading:button:rotateTurnLeft') }}</p>
|
||||
<p @click.stop="setDicomCanvasRotate(5)">{{ $t('trials:reading:button:rotateTurnRight') }}</p>
|
||||
</div>
|
||||
</button>
|
||||
<button :title="$t('trials:reading:button:move')" class="btn-link" data-tool="Pan" @click="setToolActive($event,'Pan')">
|
||||
<svg-icon icon-class="move" style="font-size:20px;" />
|
||||
</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<!-- 测量标注 -->
|
||||
@@ -247,7 +248,7 @@
|
||||
<svg-icon icon-class="previousframe" style="font-size:20px;" />
|
||||
</button>
|
||||
<!-- 播放 -->
|
||||
<button class="btn-link" :title="$t('trials:dicom-show:play')" @click="currentDicomCanvas.toggleClipPlay()">
|
||||
<button class="btn-link" :title="$t('trials:dicom-show:play')" @click="clipPlay">
|
||||
<svg-icon
|
||||
:icon-class="currentDicomCanvas.toolState.clipPlaying ? 'stop' : 'play'"
|
||||
style="font-size:20px;"
|
||||
@@ -261,9 +262,10 @@
|
||||
<button class="btn-link" :title="$t('trials:dicom-show:lastframe')" @click="currentDicomCanvas.scrollPage(9999)">
|
||||
<svg-icon icon-class="lastframe" style="font-size:20px;" />
|
||||
</button>
|
||||
<select class="sidetool-select" style="width:60px" @change="setDicomCanvasfps($event)">
|
||||
<select v-model="fps" class="sidetool-select" style="width:60px" @change="setDicomCanvasfps($event)">
|
||||
<!-- 默认值 -->
|
||||
<option :value="10">{{ $t('trials:dicom-show:default') }}</option>
|
||||
<option :value="5">5</option>
|
||||
<option :value="10">10</option>
|
||||
<option :value="15">15</option>
|
||||
<option :value="20">20</option>
|
||||
<option :value="30">30</option>
|
||||
@@ -386,20 +388,22 @@ export default {
|
||||
wwwcList: [],
|
||||
layout: null,
|
||||
seriesList: [],
|
||||
customWwc: { visible: false, title: null }
|
||||
customWwc: { visible: false, title: null },
|
||||
fps: 15
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.customWwc = { visible: false, title: this.$t('DicomViewer:data:customWwc') }
|
||||
this.rotateList[0] = '1'
|
||||
this.colorList[0] = ''
|
||||
this.wwwcList[0] = '1'
|
||||
this.wwwcList[0] = '-1'
|
||||
this.colormapsList = cornerstone.colors.getColormapsList()
|
||||
this.currentDicomCanvas = this.$refs['dicomCanvas0']
|
||||
},
|
||||
|
||||
methods: {
|
||||
loadImageStack(dicomSeries) {
|
||||
this.currentDicomCanvas.toolState.clipPlaying = false
|
||||
this.$nextTick(() => {
|
||||
this.currentDicomCanvas.loadImageStack(dicomSeries)
|
||||
})
|
||||
@@ -444,7 +448,7 @@ export default {
|
||||
this.colorList[this.currentDicomCanvasIndex] = ''
|
||||
}
|
||||
if (!this.wwwcList[this.currentDicomCanvasIndex]) {
|
||||
this.wwwcList[this.currentDicomCanvasIndex] = '1'
|
||||
this.wwwcList[this.currentDicomCanvasIndex] = '-1'
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -565,6 +569,10 @@ export default {
|
||||
setDicomCanvasfps(event) {
|
||||
this.currentDicomCanvas.setFps(event.target.value)
|
||||
},
|
||||
clipPlay() {
|
||||
this.currentDicomCanvas.setFps(this.fps)
|
||||
this.currentDicomCanvas.toggleClipPlay()
|
||||
},
|
||||
fitToType(e, type) {
|
||||
const toolButtons = document.querySelectorAll('[data-tool]')
|
||||
Array.from(toolButtons).forEach((toolBtn) => {
|
||||
@@ -879,13 +887,19 @@ export default {
|
||||
background-color: #323232;
|
||||
min-width: 80px;
|
||||
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
|
||||
border: 1px solid #4e4e4e;
|
||||
padding: 5px;
|
||||
}
|
||||
.dicom-wrapper .dropdown:hover .dropdown-content {
|
||||
display: block;
|
||||
}
|
||||
.dicom-wrapper .dropdown-content p{
|
||||
.dicom-wrapper .dropdown-content div{
|
||||
height: 25px;
|
||||
line-height: 25px;
|
||||
cursor:point;
|
||||
}
|
||||
.dicom-wrapper .dropdown-content div:hover{
|
||||
background-color: #16477b90;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
import Vue from "vue";
|
||||
import MFACOMP from "./index.vue";
|
||||
|
||||
const MFAConstructor = Vue.extend(MFACOMP);
|
||||
|
||||
const MFA = options => {
|
||||
const { UserId, username, EMail, callBack, cancelBack, status = 'login' } = options;
|
||||
if (!UserId) throw `UserId is requred.but ${UserId}`
|
||||
const id = `MFA${new Date().getTime()}`;
|
||||
const instance = new MFAConstructor();
|
||||
instance.id = id;
|
||||
instance.vm = instance.$mount();
|
||||
if (instance.vm.visible) return;
|
||||
document.body.appendChild(instance.vm.$el);
|
||||
instance.vm.open({ UserId, username, EMail, status });
|
||||
instance.vm.$on("success", (Id) => {
|
||||
if (callBack) callBack(Id)
|
||||
});
|
||||
instance.vm.$on("closed", () => {
|
||||
if (cancelBack) cancelBack();
|
||||
document.body.removeChild(instance.vm.$el);
|
||||
instance.vm.$destroy();
|
||||
});
|
||||
return instance.vm;
|
||||
}
|
||||
export default MFA;
|
||||
@@ -0,0 +1,7 @@
|
||||
import MFACOMP from "./index.vue";
|
||||
import MFA from "./fun";
|
||||
|
||||
export default Vue => {
|
||||
Vue.component(MFACOMP.name, MFACOMP);
|
||||
Vue.prototype.$MFA = MFA;
|
||||
};
|
||||
@@ -0,0 +1,204 @@
|
||||
<template>
|
||||
<!--MFA-->
|
||||
<el-dialog
|
||||
v-if="visible"
|
||||
:visible.sync="visible"
|
||||
width="540px"
|
||||
:close-on-click-modal="false"
|
||||
append-to-body
|
||||
center
|
||||
:show-close="status === 'login'"
|
||||
@close="cancel"
|
||||
>
|
||||
<div slot="title">
|
||||
{{ status === "login" ? $t("mfa:title") : $t("mfa:lock:title") }}
|
||||
</div>
|
||||
<el-form
|
||||
ref="mfaForm"
|
||||
label-position="right"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
label-width="100px"
|
||||
>
|
||||
<!-- 邮箱 -->
|
||||
<p class="tip">
|
||||
<i class="el-icon-warning" style="color: #409eff"></i>
|
||||
<span>{{ tip }}</span>
|
||||
</p>
|
||||
<!-- 用户名 -->
|
||||
<el-form-item :label="$t('mfa:form:username')" prop="username">
|
||||
<span>{{ form.username }}</span>
|
||||
</el-form-item>
|
||||
<!-- 验证码 -->
|
||||
<el-form-item :label="$t('mfa:form:MFACode')" prop="Code">
|
||||
<el-input
|
||||
:placeholder="$t('mfa:form:input:placeholder:Codes')"
|
||||
v-model="form.Code"
|
||||
style="width: 240px; margin-right: 10px"
|
||||
/>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
@click.stop="sendMFACode"
|
||||
:disabled="flag || sendFlag"
|
||||
>{{ flag ? `${second}s` : $t("mfa:form:sendMFACode") }}</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer">
|
||||
<!-- 取消 -->
|
||||
<!-- <el-button size="small" @click="cancel" v-if="status === 'login'">
|
||||
{{ $t("mfa:button:cancel") }}
|
||||
</el-button> -->
|
||||
<!-- 保存 -->
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="save"
|
||||
:loading="loading"
|
||||
style="width: 80%"
|
||||
>
|
||||
{{
|
||||
status === "login"
|
||||
? $t("mfa:button:save")
|
||||
: $t("mfa:lock:button:save")
|
||||
}}
|
||||
</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script>
|
||||
import { sendMFAEmail, verifyMFACode } from "@/api/user.js";
|
||||
export default {
|
||||
name: "MFA",
|
||||
data() {
|
||||
return {
|
||||
status: "login", // lock
|
||||
tip: null,
|
||||
visible: false,
|
||||
loading: false,
|
||||
timer: null,
|
||||
flag: false,
|
||||
sendFlag: false,
|
||||
second: 60,
|
||||
form: {
|
||||
Code: null,
|
||||
UserId: null,
|
||||
EMail: null,
|
||||
username: null,
|
||||
},
|
||||
rules: {
|
||||
Code: [
|
||||
{
|
||||
required: true,
|
||||
message: this.$t("common:ruleMessage:specify"),
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
EMail: [
|
||||
{
|
||||
required: true,
|
||||
message: this.$t("common:ruleMessage:specify"),
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
username: [
|
||||
{
|
||||
required: true,
|
||||
message: this.$t("common:ruleMessage:specify"),
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
open(data) {
|
||||
let { UserId, status, username, EMail } = data;
|
||||
this.form.UserId = UserId;
|
||||
this.status = status ? status : "login";
|
||||
this.form.username = username;
|
||||
this.form.EMail = EMail;
|
||||
this.visible = true;
|
||||
this.tip = this.$t("mfa:tip").replace("xx", EMail);
|
||||
},
|
||||
cancel() {
|
||||
this.visible = false;
|
||||
this.$emit("closed");
|
||||
},
|
||||
async save() {
|
||||
try {
|
||||
let validate = await this.$refs.mfaForm.validate();
|
||||
if (!validate) return;
|
||||
this.loading = true;
|
||||
let res = await verifyMFACode(this.form);
|
||||
this.loading = false;
|
||||
if (res.IsSuccess) {
|
||||
if (this.status === "login") {
|
||||
this.$message.success(this.$t("mfa:message:verifySuccess"));
|
||||
}
|
||||
this.$emit("success", this.form.UserId);
|
||||
this.cancel();
|
||||
}
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
async sendMFACode() {
|
||||
try {
|
||||
if (this.flag || this.sendFlag) return;
|
||||
this.sendFlag = true;
|
||||
if (this.timer) {
|
||||
clearInterval(this.timer);
|
||||
this.timer = null;
|
||||
}
|
||||
let data = {
|
||||
UserId: this.form.UserId,
|
||||
};
|
||||
if (this.status === "lock") {
|
||||
data.MfaType = 1;
|
||||
}
|
||||
let res = await sendMFAEmail(data);
|
||||
this.sendFlag = false;
|
||||
if (res.IsSuccess) {
|
||||
this.flag = true;
|
||||
this.second = 60;
|
||||
this.timer = setInterval(() => {
|
||||
this.second--;
|
||||
if (this.second <= 0) {
|
||||
clearInterval(this.timer);
|
||||
this.timer = null;
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
this.flag = false;
|
||||
this.sendFlag = false;
|
||||
}
|
||||
},
|
||||
},
|
||||
destroyed() {
|
||||
if (this.timer) {
|
||||
clearInterval(this.timer);
|
||||
this.timer = null;
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.tip {
|
||||
width: 86%;
|
||||
margin: auto;
|
||||
margin-bottom: 20px;
|
||||
text-align: left;
|
||||
padding: 0 10px;
|
||||
line-height: 30px;
|
||||
border-radius: 5px;
|
||||
background-color: #eee;
|
||||
i {
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,22 @@
|
||||
import Vue from "vue";
|
||||
import Preview from "./index.vue";
|
||||
|
||||
const PreviewConstructor = Vue.extend(Preview);
|
||||
|
||||
const preview = options => {
|
||||
const { path, type, title } = options;
|
||||
if (!path) throw `path is requred.but ${path}`
|
||||
const id = `Preview_${new Date().getTime()}`;
|
||||
const instance = new PreviewConstructor();
|
||||
instance.id = id;
|
||||
instance.vm = instance.$mount();
|
||||
if (instance.vm.visible) return;
|
||||
document.body.appendChild(instance.vm.$el);
|
||||
instance.vm.open(path, type, title);
|
||||
instance.vm.$on("closed", () => {
|
||||
document.body.removeChild(instance.vm.$el);
|
||||
instance.vm.$destroy();
|
||||
});
|
||||
return instance.vm;
|
||||
}
|
||||
export default preview;
|
||||
@@ -0,0 +1,7 @@
|
||||
import Preview from "./index.vue";
|
||||
import preview from "./fun";
|
||||
|
||||
export default Vue => {
|
||||
Vue.component(Preview.name, Preview);
|
||||
Vue.prototype.$preview = preview;
|
||||
};
|
||||
@@ -0,0 +1,41 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-if="visible"
|
||||
:visible.sync="visible"
|
||||
:title="title"
|
||||
:fullscreen="true"
|
||||
append-to-body
|
||||
custom-class="base-dialog-wrapper"
|
||||
@close="handleClose"
|
||||
>
|
||||
<div class="base-modal-body" style="border: 2px solid #ccc; padding: 10px">
|
||||
<PreviewFile v-if="visible" :file-path="path" :file-type="type" />
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script>
|
||||
import PreviewFile from "@/components/PreviewFile";
|
||||
export default {
|
||||
name: "preview",
|
||||
components: { PreviewFile },
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
path: null,
|
||||
type: null,
|
||||
title: null,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
open(path, type, title) {
|
||||
this.path = path;
|
||||
this.type = type;
|
||||
this.title = title;
|
||||
this.visible = true;
|
||||
},
|
||||
handleClose() {
|
||||
this.$emit("closed");
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -2,13 +2,13 @@
|
||||
<template>
|
||||
<div class="trialsTab">
|
||||
<el-tabs v-model="trialsTab" @tab-click="clickTab">
|
||||
<el-tab-pane v-for="item of trialsRouter.children.find(v => {return v.name == 'TrialsPanel'}).children" :key="`tab${item.path}`" :disabled="TotalNeedSignTrialDocCount !== 0" :label="$t(item.LanguageMark)" :name="item.path">
|
||||
<el-tab-pane v-for="item of trialsRouter.children.find(v => {return v.name == 'TrialsPanel'}).children" :key="`tab${item.path}`" :disabled="TotalNeedSignTrialDocCount !== 0 && item.path !== '/trials/trials-panel/attachments'" :label="$t(item.LanguageMark)" :name="item.path">
|
||||
<el-tabs v-if="!item.tabHiddn" v-model="trialsTabChild" @tab-click="clickTab">
|
||||
<el-tab-pane
|
||||
v-for="item1 of item.children"
|
||||
v-if="TrialConfig && isShow(item1.path)"
|
||||
:key="`tab1${item1.path}`"
|
||||
:disabled="TotalNeedSignTrialDocCount !== 0 || (TrialStatusStr === 'Initializing' && (item1.path === '/trials/trials-panel/setting/personnel-manage' || item1.path === '/trials/trials-panel/setting/qc-question' || item1.path === '/trials/trials-panel/setting/reading-unit' || item1.path === '/trials/trials-panel/setting/medical-audit' || item1.path === '/trials/trials-panel/setting/email-manage'))"
|
||||
:disabled="TotalNeedSignTrialDocCount !== 0 && item1.path !== '/trials/trials-panel/attachments/self-attachment' || (TrialStatusStr === 'Initializing' && (item1.path === '/trials/trials-panel/setting/personnel-manage' || item1.path === '/trials/trials-panel/setting/qc-question' || item1.path === '/trials/trials-panel/setting/reading-unit' || item1.path === '/trials/trials-panel/setting/medical-audit' || item1.path === '/trials/trials-panel/setting/email-manage'))"
|
||||
:label="$t(item1.LanguageMark)"
|
||||
:name="item1.path"
|
||||
/>
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
:on-exceed="handleExceed"
|
||||
accept=".pdf"
|
||||
>
|
||||
<el-button size="small" type="primary" :disabled="btnDisabled || $route.query.ReviewStatus === '1'" >Upload</el-button>
|
||||
<span slot="tip" class="el-upload__tip">(must be in pdf format. 1/2 pages, please confirm information integrity)</span>
|
||||
<el-button size="small" type="primary" :disabled="btnDisabled || $route.query.ReviewStatus === '1'" >{{ $t('system:GcpCertificate:upload:Upload') }}</el-button>
|
||||
<span slot="tip" class="el-upload__tip">{{$t('system:GcpCertificate:tap:must2') }}</span>
|
||||
</el-upload>
|
||||
</div>
|
||||
</template>
|
||||
@@ -45,6 +45,7 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
initFileList() {
|
||||
if(!this.doctorId) return
|
||||
getAttachmentByType(this.doctorId, this.type)
|
||||
.then(res => {
|
||||
if (res.IsSuccess) {
|
||||
@@ -129,7 +130,7 @@ export default {
|
||||
this.fileList = []
|
||||
this.$emit('getFileList', '', '')
|
||||
this.$message({
|
||||
message: 'Deleted successfully!',
|
||||
message: this.$t('common:message:deletedSuccessfully'),
|
||||
type: 'success'
|
||||
})
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
:file-list="fileList"
|
||||
:accept="accept"
|
||||
>
|
||||
<el-button size="small" type="primary" :disabled="isDisabled">Upload</el-button>
|
||||
<el-button size="small" type="primary" :disabled="isDisabled">{{ $t('common:button:upload') }}</el-button>
|
||||
</el-upload>
|
||||
</div>
|
||||
</template>
|
||||
@@ -39,6 +39,7 @@ export default {
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if(!this.doctorId) return
|
||||
this.initFileList()
|
||||
},
|
||||
methods: {
|
||||
@@ -143,8 +144,7 @@ export default {
|
||||
this.$confirm('Sure to remove?', {
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true,
|
||||
confirmButtonText: 'Ok',
|
||||
cancelButtonText: 'Cancel'
|
||||
|
||||
}).then(() => {
|
||||
deleteAttachment(file.Id, file.Path)
|
||||
.then(res => {
|
||||
@@ -152,7 +152,7 @@ export default {
|
||||
this.fileList.splice(this.fileList.findIndex(item => item.Id === file.Id), 1)
|
||||
this.$emit('getFileList', this.fileList)
|
||||
this.$message({
|
||||
message: 'Deleted successfully!',
|
||||
message: this.$t('common:message:deletedSuccessfully'),
|
||||
type: 'success'
|
||||
})
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
v-if="hasPermi(['trials:trials-panel:visit:crc-upload:upload']) && allowAddOrEdit"
|
||||
v-if="hasPermi(['trials:trials-panel:visit:crc-upload:edit']) && allowAddOrEdit"
|
||||
:label="$t('common:action:action')"
|
||||
min-width="120"
|
||||
>
|
||||
@@ -81,7 +81,6 @@
|
||||
<!-- 移除 -->
|
||||
<el-button
|
||||
v-if="(data.SubmitState*1 < 2 || (data.SubmitState === 2 && data.IsQCConfirmedReupload))"
|
||||
v-hasPermi="['trials:trials-panel:visit:crc-upload:upload']"
|
||||
icon="el-icon-delete"
|
||||
circle
|
||||
:title="$t('common:button:delete')"
|
||||
@@ -127,7 +126,7 @@
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
v-if="hasPermi(['trials:trials-panel:visit:crc-upload:upload']) && allowAddOrEdit"
|
||||
v-if="hasPermi(['trials:trials-panel:visit:crc-upload:edit']) && allowAddOrEdit"
|
||||
:label="$t('common:action:action')"
|
||||
min-width="200"
|
||||
>
|
||||
@@ -144,7 +143,6 @@
|
||||
<!-- 移除 -->
|
||||
<el-button
|
||||
v-if="data.SubmitState*1 < 2 || (data.SubmitState === 2 && data.IsQCConfirmedReupload)"
|
||||
v-hasPermi="['trials:trials-panel:visit:crc-upload:upload']"
|
||||
icon="el-icon-delete"
|
||||
circle
|
||||
:title="$t('common:button:delete')"
|
||||
@@ -200,7 +198,7 @@
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
v-if="hasPermi(['trials:trials-panel:visit:crc-upload:upload']) && allowAddOrEdit"
|
||||
v-if="hasPermi(['trials:trials-panel:visit:crc-upload:edit']) && allowAddOrEdit"
|
||||
:label="$t('common:action:action')"
|
||||
min-width="200"
|
||||
>
|
||||
@@ -237,7 +235,7 @@
|
||||
icon="el-icon-download"
|
||||
size="small"
|
||||
:loading="downloadLoading"
|
||||
@click.native.prevent="handleDownloadTpl(cd.ClinicalDataTrialSetId)"
|
||||
@click.native.prevent="handleDownloadTpl(cd)"
|
||||
>
|
||||
{{ $t('trials:uploadClinicalData:button:downloadTemplate') }}
|
||||
</el-button>
|
||||
@@ -551,11 +549,8 @@ export default {
|
||||
})
|
||||
})
|
||||
},
|
||||
handleDownloadTpl(clinicalDataTrialSetId) {
|
||||
this.downloadLoading = true
|
||||
DownloadTrialClinicalFile(clinicalDataTrialSetId).then(data => {
|
||||
this.downloadLoading = false
|
||||
}).catch(() => { this.downloadLoading = false })
|
||||
handleDownloadTpl(cd) {
|
||||
window.open(this.OSSclientConfig.basePath + cd.Path)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
<template>
|
||||
<base-model :config="model_cfg">
|
||||
<div slot="dialog-body">
|
||||
<el-table :data="modelList" style="width: 100%" height="300">
|
||||
<!--检查编号-->
|
||||
<el-table-column
|
||||
prop="StudyCode"
|
||||
:label="$t('trials:uploadImage:table:StudyCode')"
|
||||
/>
|
||||
<!--检查类型-->
|
||||
<el-table-column
|
||||
prop="ModalityForEdit"
|
||||
:label="$t('trials:uploadImage:table:ModalityForEdit')"
|
||||
/>
|
||||
<!--检查模态-->
|
||||
<el-table-column
|
||||
prop="Modalities"
|
||||
:label="$t('trials:uploadImage:table:Modalities')"
|
||||
/>
|
||||
<!--检查部位-->
|
||||
<el-table-column
|
||||
prop="BodyPartForEdit"
|
||||
:label="$t('trials:uploadImage:table:BodyPartForEdit')"
|
||||
/>
|
||||
<!--序列数量-->
|
||||
<el-table-column
|
||||
prop="SeriesCount"
|
||||
:label="$t('trials:uploadImage:table:SeriesCount')"
|
||||
/>
|
||||
<!--图像数量-->
|
||||
<el-table-column
|
||||
prop="InstanceCount"
|
||||
:label="$t('trials:uploadImage:table:InstanceCount')"
|
||||
/>
|
||||
<!--检查时间-->
|
||||
<el-table-column
|
||||
prop="StudyTime"
|
||||
:label="$t('trials:uploadImage:table:StudyTime')"
|
||||
min-width="130"
|
||||
/>
|
||||
<el-table-column
|
||||
:label="$t('common:action:action')"
|
||||
fixed="right"
|
||||
width="80"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<!--预览--->
|
||||
<el-button
|
||||
circle
|
||||
icon="el-icon-view"
|
||||
:title="$t('trials:uploadImage:button:download')"
|
||||
@click.stop="preview(scope.row)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</base-model>
|
||||
</template>
|
||||
<script>
|
||||
import baseModel from "@/components/BaseModel";
|
||||
import { getToken } from "@/utils/auth";
|
||||
export default {
|
||||
name: "studyView",
|
||||
props: {
|
||||
model_cfg: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {};
|
||||
},
|
||||
},
|
||||
modelList: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return [];
|
||||
},
|
||||
},
|
||||
},
|
||||
components: {
|
||||
"base-model": baseModel,
|
||||
},
|
||||
methods: {
|
||||
// 预览
|
||||
preview(row) {
|
||||
var token = getToken();
|
||||
const routeData = this.$router.resolve({
|
||||
path: `/showdicom?studyId=${row.Id}&TokenKey=${token}&type=Study`,
|
||||
});
|
||||
window.open(routeData.href, "_blank");
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
@@ -0,0 +1,766 @@
|
||||
<template>
|
||||
<div class="uploadList">
|
||||
<el-divider content-position="left">{{
|
||||
$t("trials:uploadImage:button:uploadTableTitle")
|
||||
}}</el-divider>
|
||||
<div class="top" style="margin-bottom: 10px">
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
v-if="!isLoad"
|
||||
style="position: relative;
|
||||
}"
|
||||
>
|
||||
<span style="opacity: 0">{{
|
||||
$t("trials:uploadImage:button:selectFolder")
|
||||
}}</span>
|
||||
<label for="file">
|
||||
{{ $t("trials:uploadImage:button:selectFolder") }}
|
||||
</label>
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
class="el-icon-upload2"
|
||||
@click.stop="notUp"
|
||||
v-else
|
||||
>
|
||||
{{ $t("trials:uploadImage:button:selectFolder") }}
|
||||
</el-button>
|
||||
<input
|
||||
type="file"
|
||||
name="file"
|
||||
id="file"
|
||||
ref="file"
|
||||
style="display: none"
|
||||
webkitdirectory
|
||||
multiple
|
||||
@change="beginScanFiles($event)"
|
||||
/>
|
||||
</div>
|
||||
<!--本地影像检查-->
|
||||
<el-table
|
||||
:data="uploadList"
|
||||
style="width: 100%"
|
||||
v-adaptive="{ bottomOffset: 50 }"
|
||||
>
|
||||
<el-table-column type="index" width="40" />
|
||||
<!--检查信息-->
|
||||
<el-table-column min-width="200" show-overflow-tooltip>
|
||||
<template slot="header">
|
||||
<el-tooltip placement="top">
|
||||
<div slot="content">
|
||||
{{ $t("trials:uploadImage:table:studyDetail1") }}<br />
|
||||
{{ $t("trials:uploadImage:table:studyDetail2") }}<br />
|
||||
{{ $t("trials:uploadedDicoms:table:studyDate") }}
|
||||
</div>
|
||||
<span>{{ $t("trials:uploadImage:table:studyInfo") }}</span>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<template slot-scope="scope">
|
||||
<div style="line-height: 15px">
|
||||
<div>
|
||||
<div>
|
||||
<span>
|
||||
<span style="font-weight: 500">Acc:</span>
|
||||
<span
|
||||
:class="{
|
||||
colorOfRed: !scope.row.dicomInfo.AccessionNumber,
|
||||
}"
|
||||
>{{ scope.row.dicomInfo.AccessionNumber || "N/A" }}</span
|
||||
>
|
||||
</span>
|
||||
</div>
|
||||
<div style="display: inline-block; margin-right: 2px">
|
||||
<span v-if="scope.row.dicomInfo.Modalities.length > 0">
|
||||
{{ scope.row.dicomInfo.Modalities.join("、") }},
|
||||
</span>
|
||||
<span v-else style="color: #f44336">N/A,</span>
|
||||
</div>
|
||||
<div style="display: inline-block; margin-right: 2px">
|
||||
<span v-if="scope.row.SeriesInstanceUidList.length"
|
||||
>{{ scope.row.SeriesInstanceUidList.length }} Series,
|
||||
</span>
|
||||
<span v-else style="color: #f44336">N/A,</span>
|
||||
</div>
|
||||
<div style="display: inline-block">
|
||||
<span v-if="scope.row.count"
|
||||
>{{ scope.row.count }} Instances
|
||||
</span>
|
||||
<span v-else style="color: #f44336">N/A</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div style="display: inline-block; margin-right: 2px">
|
||||
<span v-if="scope.row.dicomInfo.seriesBodyPartExamined">
|
||||
{{ scope.row.dicomInfo.seriesBodyPartExamined }},
|
||||
</span>
|
||||
<span v-else style="color: #f44336">N/A, </span>
|
||||
</div>
|
||||
<div style="display: inline-block">
|
||||
<span v-if="scope.row.dicomInfo.StudyDescription">
|
||||
{{ scope.row.dicomInfo.StudyDescription }}</span
|
||||
>
|
||||
<span v-else style="color: #f44336">N/A</span>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
{{ scope.row.dicomInfo.StudyTime }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!--患者信息-->
|
||||
<el-table-column min-width="130" show-overflow-tooltip>
|
||||
<template slot="header">
|
||||
<el-tooltip placement="top">
|
||||
<div slot="content">
|
||||
{{ $t("trials:uploadImage:table:pId") }}<br />
|
||||
{{ $t("trials:uploadImage:table:patientName") }}<br />
|
||||
{{ $t("trials:uploadImage:table:pInfo") }}
|
||||
</div>
|
||||
<span>{{ $t("trials:uploadImage:table:patientInfo") }}</span>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<template slot-scope="scope">
|
||||
<div style="line-height: 15px">
|
||||
<div>
|
||||
<span v-if="scope.row.dicomInfo.PatientId"
|
||||
><span style="font-weight: 500">PID: </span
|
||||
>{{ scope.row.dicomInfo.PatientId }}</span
|
||||
>
|
||||
<span v-else style="color: #f44336">N/A</span>
|
||||
</div>
|
||||
<div>
|
||||
<span
|
||||
:class="[scope.row.dicomInfo.PatientName ? '' : 'colorOfRed']"
|
||||
>
|
||||
{{ scope.row.dicomInfo.PatientName || "N/A" }}
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<span
|
||||
:class="[scope.row.dicomInfo.PatientSex ? '' : 'colorOfRed']"
|
||||
>
|
||||
{{ scope.row.dicomInfo.PatientSex || "N/A" }},
|
||||
</span>
|
||||
|
||||
<span
|
||||
:class="[scope.row.dicomInfo.PatientAge ? '' : 'colorOfRed']"
|
||||
>
|
||||
{{ scope.row.dicomInfo.PatientAge || "N/A" }},
|
||||
</span>
|
||||
|
||||
<span
|
||||
:class="[
|
||||
scope.row.dicomInfo.PatientBirthDate ? '' : 'colorOfRed',
|
||||
]"
|
||||
>
|
||||
{{ scope.row.dicomInfo.PatientBirthDate || "N/A" }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!--上传进度-->
|
||||
<el-table-column
|
||||
prop="schedule"
|
||||
:label="$t('trials:uploadImage:table:schedule')"
|
||||
min-width="150"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<el-progress
|
||||
color="#409eff"
|
||||
:percentage="scope.row.schedule"
|
||||
v-if="scope.row.schedule || scope.row.schedule === 0"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!--上传状态-->
|
||||
<el-table-column
|
||||
prop="status"
|
||||
:label="$t('trials:uploadImage:table:status')"
|
||||
min-width="120"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<el-tag
|
||||
:type="
|
||||
['warning', 'success', 'danger', 'primary', 'success', 'danger'][
|
||||
scope.row.status
|
||||
]
|
||||
"
|
||||
v-if="scope.row.status || scope.row.status === 0"
|
||||
>{{ $fd("UploadStatus", scope.row.status) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!--已有/成功/失败-->
|
||||
<el-table-column
|
||||
prop="scheduleNum"
|
||||
:label="$t('trials:uploadImage:table:scheduleNum')"
|
||||
min-width="140"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row.count">{{
|
||||
`${scope.row.count} /${scope.row.successCount} / ${scope.row.failCount}`
|
||||
}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('common:action:action')"
|
||||
fixed="right"
|
||||
width="140"
|
||||
>
|
||||
<!-- <template slot-scope="scope">
|
||||
</template> -->
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import {
|
||||
preArchiveDicomStudy,
|
||||
addOrUpdateArchiveTaskStudy,
|
||||
} from "@/api/load.js";
|
||||
import { parseDicom, getThumbnail, dicomToOSS } from "@/utils/parseDicom.js";
|
||||
export default {
|
||||
name: "uploadList",
|
||||
props: {
|
||||
SopInstanceUidList: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return [];
|
||||
},
|
||||
},
|
||||
StudyInstanceUidList: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return [];
|
||||
},
|
||||
},
|
||||
UploadStudyList: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return [];
|
||||
},
|
||||
},
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isLoad: false,
|
||||
uploadList: [], // 待上传文件列表
|
||||
dicomList: [], // 上传的文件列表
|
||||
requestNum: 6,
|
||||
hasOtherStudy: false, // 是否上传文件检查与列表不一致
|
||||
isClose: false,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
isLoad() {
|
||||
if (!this.isLoad) {
|
||||
this.$refs.file.value = null;
|
||||
if (this.dicomList.some((item) => item.isUpload === 3)) {
|
||||
this.$confirm(this.$t("trials:uploadImage:confirm:failUpload"), {
|
||||
type: "warning",
|
||||
distinguishCancelAndClose: true,
|
||||
confirmButtonText: this.$t("common:button:confirm"),
|
||||
cancelButtonText: this.$t("common:button:cancel"),
|
||||
})
|
||||
.then(() => {
|
||||
this.againUpload();
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
// 失败重传
|
||||
againUpload() {
|
||||
for (let i = 0; i < this.uploadList.length; i++) {
|
||||
let item = this.uploadList[i];
|
||||
if (item.status > 2) continue;
|
||||
item.status = 0;
|
||||
item.failCount = 0;
|
||||
item.schedule = Math.floor(
|
||||
((item.successCount + item.failCount) / item.count) * 100
|
||||
);
|
||||
let arr = this.dicomList.filter(
|
||||
(dicom) =>
|
||||
dicom.StudyInstanceUid === item.StudyInstanceUid &&
|
||||
dicom.isUpload === 3
|
||||
);
|
||||
arr.forEach((item) => (item.isUpload = 0));
|
||||
this.setUploadTask(arr);
|
||||
}
|
||||
},
|
||||
async setUploadTask(arr) {
|
||||
let num = arr.length > this.requestNum ? this.requestNum : arr.length;
|
||||
let funArr = [];
|
||||
for (let i = 0; i < num; i++) {
|
||||
funArr.push(this.handleUploadTask(arr, i));
|
||||
}
|
||||
if (funArr.length > 0) {
|
||||
let res = await Promise.all(funArr);
|
||||
}
|
||||
},
|
||||
// 预上传
|
||||
async preArchiveDicomStudy(post, index) {
|
||||
try {
|
||||
let res = await preArchiveDicomStudy(post);
|
||||
if (res.IsSuccess) {
|
||||
let item = this.uploadList[index];
|
||||
item.StudyMonitorId = res.Result;
|
||||
let arr = this.dicomList.filter(
|
||||
(dicom) => dicom.StudyInstanceUid === item.StudyInstanceUid
|
||||
);
|
||||
this.setUploadTask(arr);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
return false;
|
||||
}
|
||||
},
|
||||
// 上传
|
||||
async beginScanFiles(e) {
|
||||
let files = e.target.files;
|
||||
try {
|
||||
this.dicomList = [];
|
||||
this.hasOtherStudy = false;
|
||||
for (var i = 0; i < files.length; ++i) {
|
||||
if (files[i].name.indexOf("DICOMDIR") >= 0) continue;
|
||||
let dicom = await parseDicom(files[i]);
|
||||
if (!dicom) continue;
|
||||
let has = this.dicomList.some(
|
||||
(item) => item.SopInstanceUid === dicom.SopInstanceUid
|
||||
);
|
||||
if (has) continue;
|
||||
has = this.StudyInstanceUidList.some(
|
||||
(item) => item.StudyInstanceUid === dicom.StudyInstanceUid
|
||||
);
|
||||
if (!has) {
|
||||
this.hasOtherStudy = true;
|
||||
continue;
|
||||
}
|
||||
if (this.SopInstanceUidList.includes(dicom.SopInstanceUid)) continue;
|
||||
|
||||
this.isLoad = true;
|
||||
dicom.file = files[i];
|
||||
dicom.isUpload = 0;
|
||||
this.StudyInstanceUidList.some((item) => {
|
||||
if (item.StudyInstanceUid === dicom.StudyInstanceUid) {
|
||||
dicom.params = {
|
||||
TrialId: this.$route.query.trialId,
|
||||
SubjectId: item.SubjectId,
|
||||
VisitTaskId: item.VisitTaskId,
|
||||
SourceSubjectVisitId: item.SourceSubjectVisitId,
|
||||
};
|
||||
let uploadHas = this.uploadList.some((uploadData) => {
|
||||
if (uploadData.StudyInstanceUid === dicom.StudyInstanceUid) {
|
||||
if (uploadData.status > 0) {
|
||||
uploadData.count = 1;
|
||||
uploadData.successCount = 0;
|
||||
uploadData.failCount = 0;
|
||||
uploadData.schedule = 0;
|
||||
uploadData.status = 0;
|
||||
uploadData.FileSize = dicom.file.size;
|
||||
uploadData.SeriesInstanceUidList = [
|
||||
dicom.SeriesInstanceUid,
|
||||
];
|
||||
uploadData.dicomInfo = {
|
||||
AccessionNumber: dicom.AccessionNumber,
|
||||
Modalities: dicom.Modalities,
|
||||
seriesBodyPartExamined: dicom.seriesBodyPartExamined,
|
||||
StudyDescription: dicom.StudyDescription,
|
||||
StudyTime: this.getTime(dicom.StudyDate, dicom.StudyTime),
|
||||
PatientName: dicom.PatientName,
|
||||
PatientId: dicom.PatientId,
|
||||
PatientAge: dicom.PatientAge,
|
||||
PatientSex: dicom.PatientSex,
|
||||
PatientBirthDate: dicom.PatientBirthDate,
|
||||
};
|
||||
} else {
|
||||
uploadData.FileSize += dicom.file.size;
|
||||
uploadData.count++;
|
||||
}
|
||||
if (
|
||||
!uploadData.SeriesInstanceUidList.includes(
|
||||
dicom.SeriesInstanceUid
|
||||
)
|
||||
) {
|
||||
uploadData.SeriesInstanceUidList.push(
|
||||
dicom.SeriesInstanceUid
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return uploadData.StudyInstanceUid === dicom.StudyInstanceUid;
|
||||
});
|
||||
if (!uploadHas) {
|
||||
let uploadData = {
|
||||
TrialId: this.$route.query.trialId,
|
||||
SubjectId: item.SubjectId,
|
||||
SourceSubjectVisitId: item.SourceSubjectVisitId,
|
||||
StudyId: dicom.StudyId,
|
||||
StudyInstanceUid: dicom.StudyInstanceUid,
|
||||
FileSize: dicom.file.size,
|
||||
count: 1,
|
||||
successCount: 0,
|
||||
failCount: 0,
|
||||
schedule: 0,
|
||||
status: 0,
|
||||
SeriesInstanceUidList: [dicom.SeriesInstanceUid],
|
||||
IsDicomReUpload: false,
|
||||
dicomInfo: {
|
||||
AccessionNumber: dicom.AccessionNumber,
|
||||
Modalities: dicom.Modalities,
|
||||
seriesBodyPartExamined: dicom.seriesBodyPartExamined,
|
||||
StudyDescription: dicom.StudyDescription,
|
||||
StudyTime: this.getTime(dicom.StudyDate, dicom.StudyTime),
|
||||
PatientName: dicom.PatientName,
|
||||
PatientId: dicom.PatientId,
|
||||
PatientAge: dicom.PatientAge,
|
||||
PatientSex: dicom.PatientSex,
|
||||
PatientBirthDate: dicom.PatientBirthDate,
|
||||
},
|
||||
};
|
||||
if (
|
||||
this.UploadStudyList.some(
|
||||
(d) => d.StudyInstanceUid === uploadData.StudyInstanceUid
|
||||
)
|
||||
) {
|
||||
uploadData.IsDicomReUpload = true;
|
||||
}
|
||||
this.uploadList.push(uploadData);
|
||||
}
|
||||
}
|
||||
return item.StudyInstanceUid === dicom.StudyInstanceUid;
|
||||
});
|
||||
this.dicomList.push(dicom);
|
||||
}
|
||||
if (this.dicomList.length <= 0 && this.hasOtherStudy) {
|
||||
let confirm = await this.$confirm(
|
||||
this.$t("trials:uploadImage:confirmMessage:failSubject"),
|
||||
{
|
||||
type: "warning",
|
||||
distinguishCancelAndClose: true,
|
||||
confirmButtonText: this.$t("common:button:confirm"),
|
||||
cancelButtonText: this.$t("common:button:cancel"),
|
||||
}
|
||||
);
|
||||
if (confirm !== "confirm") return false;
|
||||
this.$refs.file.click();
|
||||
return false;
|
||||
}
|
||||
let funArr = [];
|
||||
for (let i = 0; i < this.uploadList.length; i++) {
|
||||
let item = this.uploadList[i];
|
||||
let data = {
|
||||
TrialId: item.TrialId,
|
||||
SubjectId: item.SubjectId,
|
||||
SubjectVisitId: item.SourceSubjectVisitId,
|
||||
FileSize: item.FileSize,
|
||||
IsDicomReUpload: item.IsDicomReUpload,
|
||||
FileCount: item.count,
|
||||
};
|
||||
funArr.push(this.preArchiveDicomStudy(data, i));
|
||||
}
|
||||
if (funArr && funArr.length > 0) {
|
||||
let res = await Promise.all(funArr);
|
||||
}
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
this.$refs.file.value = null;
|
||||
}
|
||||
},
|
||||
// 并发上传
|
||||
async handleUploadTask(arr, index) {
|
||||
if (this.isClose) return false;
|
||||
arr[index].isUpload = 1;
|
||||
let path = `/${arr[index].params.TrialId}/TaskImage/${
|
||||
arr[index].params.SubjectId
|
||||
}/${arr[index].params.VisitTaskId}/${
|
||||
arr[index].StudyInstanceUid
|
||||
}/${this.getGuid(
|
||||
arr[index].StudyInstanceUid +
|
||||
arr[index].SeriesInstanceUid +
|
||||
arr[index].SOPInstanceUid +
|
||||
arr[index].params.TrialId +
|
||||
arr[index].params.VisitTaskId
|
||||
)}`;
|
||||
let uploadDicom = this.uploadList.filter(
|
||||
(item) => item.StudyInstanceUid === arr[index].StudyInstanceUid
|
||||
)[0];
|
||||
let res = await dicomToOSS(arr[index].file, path);
|
||||
if (res) {
|
||||
arr[index].path = res;
|
||||
uploadDicom.successCount++;
|
||||
arr[index].isUpload = 2;
|
||||
} else {
|
||||
uploadDicom.status = 2;
|
||||
uploadDicom.failCount++;
|
||||
arr[index].isUpload = 3;
|
||||
}
|
||||
uploadDicom.schedule = Math.floor(
|
||||
((uploadDicom.successCount + uploadDicom.failCount) /
|
||||
uploadDicom.count) *
|
||||
100
|
||||
);
|
||||
if (uploadDicom.schedule >= 100) {
|
||||
if (uploadDicom.successCount === uploadDicom.count) {
|
||||
uploadDicom.status = 1;
|
||||
if (!uploadDicom.Study) {
|
||||
let res = await this.formatDicom(arr, arr[index].StudyInstanceUid);
|
||||
if (res) {
|
||||
uploadDicom.Study = res[arr[index].StudyId];
|
||||
uploadDicom.status = 3;
|
||||
}
|
||||
}
|
||||
try {
|
||||
res = await addOrUpdateArchiveTaskStudy(uploadDicom);
|
||||
if (res.IsSuccess) {
|
||||
uploadDicom.status = 4;
|
||||
this.$emit("getList");
|
||||
let ind = this.uploadList.findIndex(
|
||||
(item) => item.StudyInstanceUid === uploadDicom.StudyInstanceUid
|
||||
);
|
||||
this.uploadList.splice(ind, 1);
|
||||
} else {
|
||||
uploadDicom.status = 5;
|
||||
}
|
||||
let flag = this.dicomList.every((item) => item.isUpload > 1);
|
||||
if (flag) this.isLoad = false;
|
||||
} catch (err) {
|
||||
uploadDicom.status = 5;
|
||||
let flag = this.dicomList.every((item) => item.isUpload > 1);
|
||||
if (flag) this.isLoad = false;
|
||||
}
|
||||
} else if (
|
||||
uploadDicom.count ===
|
||||
uploadDicom.successCount + uploadDicom.failCount
|
||||
) {
|
||||
let flag = this.dicomList.every((item) => item.isUpload > 1);
|
||||
if (flag) this.isLoad = false;
|
||||
}
|
||||
}
|
||||
let ind = arr.findIndex((item) => !item.isUpload);
|
||||
if (ind >= 0) {
|
||||
return this.handleUploadTask(arr, ind);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
// 数据整理
|
||||
async formatDicom(arr, StudyInstanceUid) {
|
||||
let studyObj = {};
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
let dicom = arr[i];
|
||||
if (dicom.StudyInstanceUid !== StudyInstanceUid) continue;
|
||||
let thumbnailPath = `/${dicom.params.TrialId}/TaskImage/${dicom.params.SubjectId}/${dicom.params.VisitTaskId}/${dicom.StudyInstanceUid}/${dicom.SeriesInstanceUid}.png`;
|
||||
if (!studyObj[dicom.StudyId]) {
|
||||
studyObj[dicom.StudyId] = {
|
||||
StudyId: dicom.StudyId,
|
||||
StudyInstanceUid: dicom.StudyInstanceUid,
|
||||
StudyTime: this.getTime(dicom.StudyDate, dicom.StudyTime),
|
||||
Modalities: dicom.Modalities,
|
||||
Description: dicom.StudyDescription,
|
||||
SeriesCount: 1,
|
||||
InstanceCount: 1,
|
||||
InstitutionName: dicom.InstitutionName,
|
||||
PatientId: dicom.PatientId,
|
||||
PatientName: dicom.PatientName,
|
||||
PatientAge: dicom.PatientAge,
|
||||
PatientSex: dicom.PatientSex,
|
||||
AccessionNumber: dicom.AccessionNumber,
|
||||
PatientBirthDate: dicom.PatientBirthDate,
|
||||
AcquisitionTime: dicom.AcquisitionTime,
|
||||
AcquisitionNumber: dicom.AcquisitionNumber,
|
||||
TriggerTime: dicom.TriggerTime,
|
||||
BodyPartExamined: dicom.BodyPartExamined,
|
||||
SeriesList: [
|
||||
{
|
||||
StudyInstanceUid: dicom.StudyInstanceUid,
|
||||
SeriesInstanceUid: dicom.SeriesInstanceUid,
|
||||
SeriesNumber: dicom.SeriesNumber,
|
||||
SeriesTime: this.getTime(dicom.SeriesDate, dicom.SeriesTime),
|
||||
Modality: dicom.Modality,
|
||||
Description: dicom.SeriesDescription,
|
||||
InstanceCount: 1,
|
||||
SliceThickness: dicom.SliceThickness,
|
||||
ImagePositionPatient: dicom.ImagePosition,
|
||||
ImageOrientationPatient: dicom.ImageOrientation,
|
||||
BodyPartExamined: dicom.seriesBodyPartExamined,
|
||||
SequenceName: dicom.SequenceName,
|
||||
ProtocolName: dicom.ProtocolName,
|
||||
ImagerPixelSpacing: dicom.ImagePixelSpacing,
|
||||
AcquisitionTime: dicom.AcquisitionTime,
|
||||
AcquisitionNumber: dicom.AcquisitionNumber,
|
||||
TriggerTime: dicom.TriggerTime,
|
||||
ImageResizePath: await getThumbnail(
|
||||
dicom.file,
|
||||
thumbnailPath,
|
||||
dicom
|
||||
),
|
||||
InstanceList: [
|
||||
{
|
||||
StudyInstanceUid: dicom.StudyInstanceUid,
|
||||
SeriesInstanceUid: dicom.SeriesInstanceUid,
|
||||
SopInstanceUid: dicom.SopInstanceUid,
|
||||
InstanceNumber: dicom.ImageOrInstanceNumber,
|
||||
InstanceTime: this.getTime(
|
||||
dicom.ContentDate,
|
||||
dicom.ContentTime
|
||||
),
|
||||
ImageRows: dicom.Rows || 0,
|
||||
ImageColumns: dicom.Columns || 0,
|
||||
SliceLocation: dicom.SliceLocation,
|
||||
SliceThickness: dicom.SliceThickness,
|
||||
NumberOfFrames: dicom.NumberOfFrames || 0,
|
||||
PixelSpacing: dicom.PixelSpacing,
|
||||
ImagerPixelSpacing: dicom.ImagePixelSpacing,
|
||||
FrameOfReferenceUID: dicom.FrameOfReferenceUID,
|
||||
WindowCenter: dicom.WindowCenter,
|
||||
WindowWidth: dicom.WindowWidth,
|
||||
Path: dicom.path,
|
||||
HtmlPath: "",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
} else {
|
||||
let seriesHas = studyObj[dicom.StudyId].SeriesList.some((item) => {
|
||||
if (item.SeriesInstanceUid === dicom.SeriesInstanceUid) {
|
||||
item.InstanceCount++;
|
||||
let instance = {
|
||||
StudyInstanceUid: dicom.StudyInstanceUid,
|
||||
SeriesInstanceUid: dicom.SeriesInstanceUid,
|
||||
SopInstanceUid: dicom.SopInstanceUid,
|
||||
InstanceNumber: dicom.ImageOrInstanceNumber,
|
||||
InstanceTime: this.getTime(
|
||||
dicom.ContentDate,
|
||||
dicom.ContentTime
|
||||
),
|
||||
ImageRows: dicom.Rows || 0,
|
||||
ImageColumns: dicom.Columns || 0,
|
||||
SliceLocation: dicom.SliceLocation,
|
||||
SliceThickness: dicom.SliceThickness,
|
||||
NumberOfFrames: dicom.NumberOfFrames || 0,
|
||||
PixelSpacing: dicom.PixelSpacing,
|
||||
ImagerPixelSpacing: dicom.ImagePixelSpacing,
|
||||
FrameOfReferenceUID: dicom.FrameOfReferenceUID,
|
||||
WindowCenter: dicom.WindowCenter,
|
||||
WindowWidth: dicom.WindowWidth,
|
||||
Path: dicom.path,
|
||||
HtmlPath: "",
|
||||
};
|
||||
item.InstanceList.push(instance);
|
||||
}
|
||||
return item.SeriesInstanceUid === dicom.SeriesInstanceUid;
|
||||
});
|
||||
if (!seriesHas) {
|
||||
studyObj[dicom.StudyId].SeriesCount++;
|
||||
let series = {
|
||||
StudyInstanceUid: dicom.StudyInstanceUid,
|
||||
SeriesInstanceUid: dicom.SeriesInstanceUid,
|
||||
SeriesNumber: dicom.SeriesNumber,
|
||||
SeriesTime: this.getTime(dicom.SeriesDate, dicom.SeriesTime),
|
||||
Modality: dicom.Modality,
|
||||
Description: dicom.SeriesDescription,
|
||||
InstanceCount: 1,
|
||||
SliceThickness: dicom.SliceThickness,
|
||||
ImagePositionPatient: dicom.ImagePosition,
|
||||
ImageOrientationPatient: dicom.ImageOrientation,
|
||||
BodyPartExamined: dicom.seriesBodyPartExamined,
|
||||
SequenceName: dicom.SequenceName,
|
||||
ProtocolName: dicom.ProtocolName,
|
||||
ImagerPixelSpacing: dicom.ImagePixelSpacing,
|
||||
AcquisitionTime: dicom.AcquisitionTime,
|
||||
AcquisitionNumber: dicom.AcquisitionNumber,
|
||||
TriggerTime: dicom.TriggerTime,
|
||||
ImageResizePath: await getThumbnail(
|
||||
dicom.file,
|
||||
thumbnailPath,
|
||||
dicom
|
||||
),
|
||||
InstanceList: [
|
||||
{
|
||||
StudyInstanceUid: dicom.StudyInstanceUid,
|
||||
SeriesInstanceUid: dicom.SeriesInstanceUid,
|
||||
SopInstanceUid: dicom.SopInstanceUid,
|
||||
InstanceNumber: dicom.ImageOrInstanceNumber,
|
||||
InstanceTime: this.getTime(
|
||||
dicom.ContentDate,
|
||||
dicom.ContentTime
|
||||
),
|
||||
ImageRows: dicom.Rows || 0,
|
||||
ImageColumns: dicom.Columns || 0,
|
||||
SliceLocation: dicom.SliceLocation,
|
||||
SliceThickness: dicom.SliceThickness,
|
||||
NumberOfFrames: dicom.NumberOfFrames || 0,
|
||||
PixelSpacing: dicom.PixelSpacing,
|
||||
ImagerPixelSpacing: dicom.ImagePixelSpacing,
|
||||
FrameOfReferenceUID: dicom.FrameOfReferenceUID,
|
||||
WindowCenter: dicom.WindowCenter,
|
||||
WindowWidth: dicom.WindowWidth,
|
||||
Path: dicom.path,
|
||||
HtmlPath: "",
|
||||
},
|
||||
],
|
||||
};
|
||||
studyObj[dicom.StudyId].SeriesList.push(series);
|
||||
}
|
||||
studyObj[dicom.StudyId].InstanceCount++;
|
||||
}
|
||||
}
|
||||
return studyObj;
|
||||
},
|
||||
// dicom时间转换
|
||||
getTime(date, time) {
|
||||
let studyTime = "";
|
||||
if (date) {
|
||||
date = `${date.substring(0, 4)}-${date.substring(
|
||||
4,
|
||||
6
|
||||
)}-${date.substring(6, 8)}`;
|
||||
}
|
||||
if (time) {
|
||||
time = `${time.substring(0, 2)}:${time.substring(
|
||||
2,
|
||||
4
|
||||
)}:${time.substring(4, 6)}`;
|
||||
}
|
||||
if (date) {
|
||||
studyTime = time ? `${date} ${time}` : `${date} 00:00:00`;
|
||||
}
|
||||
return studyTime;
|
||||
},
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.isClose = true;
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.colorOfRed {
|
||||
color: #f44336;
|
||||
}
|
||||
label {
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
padding: 9px 15px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,271 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:visible.sync="visible"
|
||||
:fullscreen="true"
|
||||
:close-on-click-modal="false"
|
||||
custom-class="upload-dialog"
|
||||
:before-close="beforeClose"
|
||||
class="uploadImage"
|
||||
>
|
||||
<span slot="title">{{ title }}</span>
|
||||
<el-divider content-position="left">{{
|
||||
$t("trials:uploadImage:button:uploadTableTitle1")
|
||||
}}</el-divider>
|
||||
<!--已上传影像检查-->
|
||||
<el-table
|
||||
:data="list"
|
||||
style="width: 100%"
|
||||
height="300"
|
||||
v-adaptive="{ bottomOffset: 50, notAdaptive: isUpload }"
|
||||
:loading="loading"
|
||||
>
|
||||
<!--受试者-->
|
||||
<el-table-column
|
||||
prop="SubjectCode"
|
||||
:label="$t('trials:uploadImage:table:subjectCode')"
|
||||
/>
|
||||
<!--任务名称-->
|
||||
<el-table-column
|
||||
prop="TaskBlindName"
|
||||
:label="$t('trials:uploadImage:table:taskBlindName')"
|
||||
/>
|
||||
<!--原始检查数-->
|
||||
<el-table-column
|
||||
prop="OrginalStudyList"
|
||||
:label="$t('trials:uploadImage:table:orginalStudyListNum')"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<el-button
|
||||
v-if="
|
||||
scope.row.OrginalStudyList &&
|
||||
scope.row.OrginalStudyList.length >= 1
|
||||
"
|
||||
type="text"
|
||||
@click="handleOpenDialog(scope.row, 'OrginalStudyList')"
|
||||
>
|
||||
<span>{{ scope.row.OrginalStudyList.length }}</span>
|
||||
</el-button>
|
||||
<span v-else>0</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!--后处理检查数-->
|
||||
<el-table-column
|
||||
prop="UploadStudyList"
|
||||
:label="$t('trials:uploadImage:table:uploadStudyListNum')"
|
||||
>
|
||||
<template slot-scope="scope">{{
|
||||
scope.row.UploadStudyList && Array.isArray(scope.row.UploadStudyList)
|
||||
? scope.row.UploadStudyList.length
|
||||
: 0
|
||||
}}</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('common:action:action')"
|
||||
fixed="right"
|
||||
width="140"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<!--下载--->
|
||||
<el-button
|
||||
v-if="!isUpload && Criterion.ImageDownloadEnum > 0"
|
||||
circle
|
||||
icon="el-icon-download"
|
||||
:title="$t('trials:uploadImage:button:download')"
|
||||
@click.stop="downloadImage(scope.row)"
|
||||
/>
|
||||
<!--删除--->
|
||||
<el-button
|
||||
v-if="isUpload"
|
||||
circle
|
||||
icon="el-icon-delete"
|
||||
:title="$t('trials:uploadImage:button:delete')"
|
||||
@click.stop="remove(scope.row)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<upload-list
|
||||
v-if="Criterion.ImageUploadEnum > 0 && isUpload"
|
||||
:StudyInstanceUidList="StudyInstanceUidList"
|
||||
:SopInstanceUidList="SopInstanceUidList"
|
||||
:UploadStudyList="UploadStudyList"
|
||||
@getList="getList"
|
||||
/>
|
||||
<study-view
|
||||
v-if="model_cfg.visible"
|
||||
:model_cfg="model_cfg"
|
||||
:modelList="modelList"
|
||||
/>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script>
|
||||
import uploadList from "./components/upload-list.vue";
|
||||
import studyView from "./components/study-view.vue";
|
||||
import { getSubjectImageUploadList, deleteTaskStudy } from "@/api/load.js";
|
||||
import { downloadImage } from "@/utils/uploadZip.js";
|
||||
export default {
|
||||
name: "uploadImage",
|
||||
props: {
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
SubjectId: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
Criterion: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {};
|
||||
},
|
||||
},
|
||||
status: {
|
||||
type: String,
|
||||
default: "upload",
|
||||
},
|
||||
},
|
||||
components: {
|
||||
"upload-list": uploadList,
|
||||
"study-view": studyView,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
list: [],
|
||||
StudyInstanceUidList: [],
|
||||
SopInstanceUidList: [],
|
||||
UploadStudyList: [],
|
||||
|
||||
// 检查数弹框
|
||||
model_cfg: {
|
||||
visible: false,
|
||||
showClose: true,
|
||||
width: "1000px",
|
||||
title: "",
|
||||
appendToBody: true,
|
||||
},
|
||||
modelList: [],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
title() {
|
||||
let str = this.$t("trials:uploadImage:title:uploadImages");
|
||||
if (this.status === "download") {
|
||||
str = this.$t("trials:uploadImage:title:uploadImagesDownLoad");
|
||||
}
|
||||
return str;
|
||||
},
|
||||
isUpload() {
|
||||
return this.status === "upload";
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
beforeClose() {
|
||||
this.$emit("update:visible", false);
|
||||
},
|
||||
notUp() {
|
||||
this.$confirm(this.$t("trials:uploadImage:confirmMessage:notUp"), {
|
||||
type: "warning",
|
||||
distinguishCancelAndClose: true,
|
||||
confirmButtonText: this.$t("common:button:confirm"),
|
||||
cancelButtonText: this.$t("common:button:cancel"),
|
||||
});
|
||||
},
|
||||
// 获取列表
|
||||
async getList() {
|
||||
try {
|
||||
let params = {
|
||||
SubjectId: this.SubjectId,
|
||||
TrialReadingCriterionId: this.Criterion.TrialReadingCriterionId,
|
||||
};
|
||||
this.loading = true;
|
||||
let res = await getSubjectImageUploadList(params);
|
||||
this.loading = false;
|
||||
if (res.IsSuccess) {
|
||||
this.StudyInstanceUidList = [];
|
||||
this.SopInstanceUidList = [];
|
||||
this.UploadStudyList = [];
|
||||
this.list = res.Result;
|
||||
res.Result.forEach((item) => {
|
||||
if (item.OrginalStudyList && Array.isArray(item.OrginalStudyList)) {
|
||||
item.OrginalStudyList.forEach((data) => {
|
||||
data.SubjectId = item.SubejctId;
|
||||
data.VisitTaskId = item.VisitTaskId;
|
||||
data.SourceSubjectVisitId = item.SourceSubjectVisitId;
|
||||
this.StudyInstanceUidList.push(data);
|
||||
});
|
||||
}
|
||||
if (item.UploadStudyList && Array.isArray(item.UploadStudyList)) {
|
||||
item.UploadStudyList.forEach((data) => {
|
||||
data.SopInstanceUidList &&
|
||||
this.SopInstanceUidList.push(...data.SopInstanceUidList);
|
||||
this.UploadStudyList.push(data);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
// 删除
|
||||
async remove(item) {
|
||||
try {
|
||||
let confirm = await this.$confirm(
|
||||
this.$t("trials:uploadImage:confirm:delMessage"),
|
||||
{
|
||||
type: "warning",
|
||||
distinguishCancelAndClose: true,
|
||||
confirmButtonText: this.$t("common:button:confirm"),
|
||||
cancelButtonText: this.$t("common:button:cancel"),
|
||||
}
|
||||
);
|
||||
if (confirm !== "confirm") return;
|
||||
let params = {
|
||||
VisitTaskId: item.VisitTaskId,
|
||||
};
|
||||
let res = await deleteTaskStudy(params);
|
||||
if (res.IsSuccess) {
|
||||
this.getList();
|
||||
this.$message.success(
|
||||
this.$t("trials:uploadImage:message:delSuccess")
|
||||
);
|
||||
}
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
},
|
||||
// 打开弹窗
|
||||
handleOpenDialog(item, list) {
|
||||
this.model_cfg.title = `${item.SubejctCode || ""}>${item.TaskBlindName}`;
|
||||
this.modelList = item[list];
|
||||
this.model_cfg.visible = true;
|
||||
},
|
||||
// 打包下载
|
||||
async downloadImage(item) {
|
||||
try {
|
||||
await downloadImage(
|
||||
this.$route.query.trialId,
|
||||
item.SourceSubjectVisitId
|
||||
);
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
::v-deep .el-dialog {
|
||||
.el-dialog__header {
|
||||
padding-top: 15px;
|
||||
}
|
||||
}
|
||||
.uploadImage {
|
||||
background-color: #fff;
|
||||
}
|
||||
</style>
|
||||
@@ -27,6 +27,7 @@ export default
|
||||
ReadingUnitConfirmation: 108, // 医学审核问题确认
|
||||
MedicalAudit: 215,// 医学审核
|
||||
HeavyReadingApproval: 216,// 重阅审批
|
||||
ResetAndAsyncCriterion: 218, //同步签名
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -9,6 +9,7 @@ const doResize = async(el, binding, vnode) => {
|
||||
const { componentInstance: $table } = await vnode
|
||||
// 获取调用传递过来的数据
|
||||
const { value } = binding
|
||||
if (value && value.notAdaptive) return;
|
||||
// 获取距底部距离(用于展示页码等信息)
|
||||
const bottomOffset = (value && value.bottomOffset) || 40
|
||||
if (!$table) return
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1710814433132" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6202" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M509.48 9.666C232.874 9.666 8.666 233.874 8.666 510.48c0 276.618 224.206 500.818 500.814 500.818 276.618 0 500.818-224.202 500.818-500.818 0-276.606-224.2-500.814-500.818-500.814z m0 896.198c-218.384 0-395.378-176.994-395.378-395.382 0-218.384 176.996-395.378 395.378-395.378 218.388 0 395.382 176.996 395.382 395.378 0.002 218.388-176.992 395.382-395.382 395.382z m26.362-390.848v-189.042c0-29.136-23.578-52.718-52.718-52.718s-52.716 23.582-52.716 52.718v210.87c0 0.18 0.012 0.356 0.014 0.534 0.006 0.686 0.018 1.37 0.052 2.054 0.026 0.52 0.072 1.036 0.112 1.55 0.026 0.334 0.042 0.666 0.076 1 0.06 0.632 0.142 1.258 0.226 1.884 0.028 0.21 0.05 0.422 0.08 0.63 0.102 0.698 0.222 1.388 0.35 2.076 0.026 0.136 0.046 0.276 0.074 0.412 0.142 0.732 0.304 1.458 0.476 2.178 0.022 0.098 0.042 0.196 0.068 0.292 0.182 0.744 0.382 1.48 0.596 2.21l0.068 0.244c0.22 0.74 0.46 1.474 0.71 2.202l0.078 0.228c0.256 0.732 0.532 1.454 0.818 2.17 0.032 0.076 0.06 0.154 0.09 0.23 0.292 0.718 0.602 1.428 0.926 2.13l0.104 0.228c0.334 0.716 0.684 1.424 1.05 2.124 0.032 0.058 0.06 0.12 0.09 0.178 0.386 0.732 0.79 1.454 1.208 2.164l0.044 0.078a52.9 52.9 0 0 0 8.716 11.054l148.508 148.506c20.594 20.598 53.956 20.598 74.548 0 20.586-20.586 20.586-53.95 0-74.542l-133.648-133.642z" fill="#FFFFFF" p-id="6203"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
@@ -23,23 +23,22 @@
|
||||
<div style="margin-left:20px;">
|
||||
<el-dropdown class="dropdown-container" trigger="click">
|
||||
<span class="el-dropdown-link">
|
||||
{{ name }}
|
||||
<span v-if="userTypeShortName">({{ userTypeShortName }})</span>
|
||||
{{ `${name} (${userTypeShortName})` }}
|
||||
<!-- {{ name }}
|
||||
<span v-if="userTypeShortName"> ({{ userTypeShortName }}) </span> -->
|
||||
<i class="el-icon-caret-bottom" />
|
||||
</span>
|
||||
<el-dropdown-menu slot="dropdown" class="user-dropdown">
|
||||
<el-dropdown-item v-if="!isReviewer">
|
||||
<span style="display:block;" @click="editInfo">Edit Info</span>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item>
|
||||
<span style="display:block;" @click="account">Account</span>
|
||||
<span style="display:block;" @click="editInfo">{{$t('system:navbar:button:Profile')}}</span>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item divided>
|
||||
<span style="display:block;" @click="logout">Log Out</span>
|
||||
<span style="display:block;" @click="logout">{{$t('system:navbar:button:Log Out')}}</span>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
<TopLang></TopLang>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -50,12 +49,15 @@ import {mapGetters, mapMutations} from 'vuex'
|
||||
import Breadcrumb from '@/components/Breadcrumb'
|
||||
import Hamburger from '@/components/Hamburger'
|
||||
import Screenfull from '@/components/Screenfull'
|
||||
import TopLang from './topLang'
|
||||
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Breadcrumb,
|
||||
Hamburger,
|
||||
Screenfull
|
||||
Screenfull,
|
||||
TopLang
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -89,9 +91,6 @@ export default {
|
||||
editInfo() {
|
||||
this.$router.push({ name: 'BaiscInfo' })
|
||||
},
|
||||
account() {
|
||||
this.$router.push({ name: 'Account' })
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
<template>
|
||||
<el-dropdown
|
||||
style="height:50px;line-height: 60px;"
|
||||
@command="handleSetLanguage"
|
||||
>
|
||||
|
||||
<span class="el-dropdown-link">
|
||||
<svg-icon icon-class="language" style="font-size:25px;margin:0 10px;" />
|
||||
<!-- {{ language==='zh'?'语言:中文':'Language: English' }} -->
|
||||
<!-- <i class="el-icon-arrow-down el-icon--right" /> -->
|
||||
</span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item
|
||||
:disabled="language==='zh'"
|
||||
command="zh"
|
||||
>中文
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
:disabled="language==='en'"
|
||||
command="en"
|
||||
>English
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters, mapMutations } from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'TopLang',
|
||||
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
language: 'language'
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
...mapMutations({ setLanguage: 'lang/setLanguage' }),
|
||||
handleSetLanguage(lang) {
|
||||
this.$i18n.locale = lang
|
||||
this.setLanguage(lang)
|
||||
this.$updateDictionary()
|
||||
window.location.reload()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
@@ -4,6 +4,7 @@ import 'normalize.css/normalize.css' // A modern alternative to CSS resets
|
||||
|
||||
import ElementUI, { MessageBox } from 'element-ui'
|
||||
import { getBasicDataAllSelect, getFrontInternationalizationList } from '@/api/dictionary/dictionary'
|
||||
import { sendMFAEmail } from "@/api/user.js";
|
||||
import { resetReadingRestTime } from '@/api/trials/reading'
|
||||
// import 'element-ui/lib/theme-chalk/index.css'
|
||||
import './assets/css/theme-blue/index.css' // 浅绿色主题
|
||||
@@ -24,7 +25,6 @@ Vue.use(VueClipboard)
|
||||
// import htmlToPdf from './utils/htmlToPdf'
|
||||
// Vue.use(htmlToPdf)
|
||||
import permission from './utils/permission'
|
||||
import { OSSclient } from './utils/oss'
|
||||
Vue.use(permission)
|
||||
|
||||
import Viewer from 'v-viewer'
|
||||
@@ -57,6 +57,10 @@ Vue.use(hasPermi)
|
||||
// Vue.use(ElementUI, { locale, size: 'medium' })
|
||||
import upload from '@/components/element-ui/upload'
|
||||
Vue.use(upload)
|
||||
import Preview from '@/components/Preview/index'
|
||||
Vue.use(Preview)
|
||||
import MFA from '@/components/MFA/index'
|
||||
Vue.use(MFA)
|
||||
import adaptive from '@/directive/adaptive/index'
|
||||
// 表格自适应指令
|
||||
Vue.use(adaptive)
|
||||
@@ -80,6 +84,7 @@ import DictTag from '@/components/DictTag'
|
||||
import DictData from '@/components/DictData'
|
||||
import { getBasicDataSelect } from '@/api/dictionary/dictionary'
|
||||
import { checkConfig } from '@/const/check/index'
|
||||
import { getTrialBodyPartList } from "@/api/trials/setting";
|
||||
// 全局方法挂载
|
||||
var $q = params
|
||||
Vue.prototype.checkConfig = checkConfig
|
||||
@@ -96,12 +101,14 @@ Vue.prototype.selectDictLabel = selectDictLabel
|
||||
// Vue.prototype.download = download
|
||||
Vue.prototype.handleTree = handleTree
|
||||
Vue.prototype.$getObjectName = (url) => {
|
||||
// console.log(url)
|
||||
var value = url
|
||||
var str = value.split("//"); //https://进行分割,
|
||||
var index = str[1].indexOf("/")+1; //indexOf 获取第一个斜杠的索引,
|
||||
// console.log(str[1].substring(index)); //substring 截取,
|
||||
return '/' + str[1].substring(index)
|
||||
// console.log(url,'url')
|
||||
// console.log(Vue.prototype.OSSclientConfig.viewEndpoint,'url')
|
||||
var value = url;
|
||||
let basePath = Vue.prototype.OSSclientConfig.viewEndpoint;
|
||||
if (Vue.prototype.OSSclientConfig.ObjectStoreUse === 'AliyunOSS') {
|
||||
basePath = Vue.prototype.OSSclientConfig.endPoint.split('https://').length > 1 ? Vue.prototype.OSSclientConfig.endPoint.split('https://')[1] : Vue.prototype.OSSclientConfig.endPoint;
|
||||
}
|
||||
return value.split(basePath)[1];
|
||||
}
|
||||
Vue.prototype.getGuid = (text) => {
|
||||
text = md5(text)
|
||||
@@ -160,10 +167,16 @@ Vue.prototype.fileToBlob = (file) => {
|
||||
var _vm
|
||||
async function VueInit() {
|
||||
var params
|
||||
var res
|
||||
if (~window.location.href.indexOf('/readingDicoms') || ~window.location.href.indexOf('/noneDicomReading') || ~window.location.href.indexOf('/criterionquestions') || ~window.location.href.indexOf('/petct')) {
|
||||
params = $q('TrialReadingCriterionId')
|
||||
res = await getBasicDataAllSelect(params)
|
||||
} else if (~window.location.href.indexOf('/ecrfPreview')) {
|
||||
params = $q('SystemReadingCriterionId')
|
||||
res = await getBasicDataAllSelect(params, true)
|
||||
} else {
|
||||
res = await getBasicDataAllSelect(params)
|
||||
}
|
||||
var res = await getBasicDataAllSelect(params)
|
||||
var Internationalization = await getFrontInternationalizationList()
|
||||
Vue.prototype.$tl = Internationalization.Result
|
||||
let zhMessages = {}, enMessages = {}
|
||||
@@ -173,6 +186,24 @@ async function VueInit () {
|
||||
zhMessages[v.Code] = v.ValueCN
|
||||
enMessages[v.Code] = v.Value
|
||||
})
|
||||
// 获取检查部位
|
||||
Vue.prototype.$getBodyPart = (id) => {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
let params = {
|
||||
TrialId: id
|
||||
}
|
||||
let BodyPart = await getTrialBodyPartList(params)
|
||||
if (BodyPart.IsSuccess) {
|
||||
resolve(BodyPart.Result);
|
||||
} else {
|
||||
reject(BodyPart);
|
||||
}
|
||||
} catch (err) {
|
||||
reject(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
i18n.mergeLocaleMessage('zh', zhMessages)
|
||||
i18n.mergeLocaleMessage('en', enMessages)
|
||||
Vue.use(ElementUI, {
|
||||
@@ -202,15 +233,16 @@ async function VueInit () {
|
||||
return dictInfo
|
||||
}()
|
||||
Vue.prototype.$d = d
|
||||
Vue.prototype.$fd = function (code, v, type) {
|
||||
Vue.prototype.$fd = function (code, v, type, arr, key = 'label') {
|
||||
try {
|
||||
let data = arr || d;
|
||||
type = type || 'value';
|
||||
// code === 'YesOrNo' ? console.log(d) : ''
|
||||
type = type || 'value'
|
||||
return d[code].find(i => {
|
||||
return data[code].find(i => {
|
||||
return i[type] === v
|
||||
}) ? d[code].find(i => {
|
||||
}) ? data[code].find(i => {
|
||||
return i[type] === v
|
||||
}).label : ''
|
||||
})[key] : ''
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
@@ -326,20 +358,27 @@ async function VueInit () {
|
||||
}
|
||||
const h = _vm.$createElement
|
||||
/* eslint-disable */
|
||||
window.VUE_APP_COMPANY_NAME = process.env.VUE_APP_COMPANY_NAME;
|
||||
waitOperate(eval(process.env.VUE_APP_LOGOUT_FOR_PERMISSION) ? () => {
|
||||
var lang = zzSessionStorage.getItem('lang') ? zzSessionStorage.getItem('lang') : 'zh'
|
||||
if ( _vm.$route.path === '/ReviewersResearchForm' || _vm.$route.path === '/ReviewersResearch' || _vm.$route.path === '/login' || _vm.$route.path === '/researchForm' || _vm.$route.path === '/researchLogin' || _vm.$route.path === '/email-recompose' || _vm.$route.path === '/recompose' || _vm.$route.path === '/resetpassword' || _vm.$route.path === '/error') {
|
||||
if (_vm.$store.state.trials.unlock || _vm.$route.path === '/ReviewersResearchForm' || _vm.$route.path === '/ReviewersResearch' || _vm.$route.path === '/login' || _vm.$route.path === '/researchForm' || _vm.$route.path === '/researchLogin' || _vm.$route.path === '/email-recompose' || _vm.$route.path === '/recompose' || _vm.$route.path === '/resetpassword' || _vm.$route.path === '/error') {
|
||||
count = 0;
|
||||
localStorage.setItem('count', '0')
|
||||
return
|
||||
}
|
||||
_vm.$store.dispatch('user/logout').then(res => {
|
||||
window.location.href = `/login`
|
||||
})
|
||||
|
||||
// window.location.href = `/login`
|
||||
_vm.$msgbox.close();
|
||||
isOpen = false
|
||||
isLock = null
|
||||
zzSessionStorage.removeItem('isLock')
|
||||
router.push("/login")
|
||||
}).then(() => {
|
||||
_vm.$alert(lang === 'zh' ? '由于您长时间未操作,为保护您的数据安全已强制将您下线,如果需要继续操作请重新登陆!' : 'No operation for a long time non-operation, you have been forced logout to protect data security. If continue to operate, please login again!', {
|
||||
type: 'warning',
|
||||
})
|
||||
})
|
||||
|
||||
} : () => { }, process.env.VUE_APP_LOGOUT_FOR_TIME,
|
||||
eval(process.env.VUE_APP_LOCK_FOR_PERMISSION) ? () => {
|
||||
var lang = zzSessionStorage.getItem('lang') ? zzSessionStorage.getItem('lang') : 'zh'
|
||||
@@ -374,9 +413,12 @@ async function VueInit () {
|
||||
}
|
||||
var my_username = zzSessionStorage.getItem('my_username')
|
||||
var my_password = zzSessionStorage.getItem('my_password')
|
||||
let my_userid = zzSessionStorage.getItem('userId')
|
||||
let my_EMail = zzSessionStorage.getItem('my_EMail')
|
||||
if (md5(_vm.unlock.my_password) === my_password && my_username === _vm.unlock.my_username) {
|
||||
resetReadingRestTime().then(() => {
|
||||
})
|
||||
const closeLock = (_vm) => {
|
||||
_vm.$message.success(lang === 'zh' ? '解锁成功,请继续操作' : 'Unlocked successfully. Please continue operation.')
|
||||
_vm.unlock = {
|
||||
my_username: null,
|
||||
@@ -392,6 +434,24 @@ async function VueInit () {
|
||||
setTimeout(() => {
|
||||
done()
|
||||
}, 500)
|
||||
}
|
||||
if (eval(process.env.VUE_APP_LOCK_FOR_PERMISSION_MFA)) {
|
||||
sendMFAEmail({ UserId: my_userid, MfaType: 1 }).then((res) => {
|
||||
done();
|
||||
Vue.prototype.$MFA({
|
||||
status: "lock",
|
||||
UserId: my_userid,
|
||||
EMail: my_EMail,
|
||||
username: my_username,
|
||||
callBack: () => {
|
||||
closeLock(_vm)
|
||||
},
|
||||
})
|
||||
})
|
||||
} else {
|
||||
closeLock(_vm)
|
||||
}
|
||||
|
||||
} else {
|
||||
// console.log(111)
|
||||
_vm.$message.error(lang === 'zh' ? '请输入正确用户名密码' : 'Please enter the correct password.')
|
||||
|
||||
@@ -34,7 +34,7 @@ router.beforeEach(async(to, from, next) => {
|
||||
NProgress.done()
|
||||
} else {
|
||||
OSSclient()
|
||||
const hasGetUserInfo = store.getters.name
|
||||
const hasGetUserInfo = store.getters.userId
|
||||
if (hasGetUserInfo) {
|
||||
next()
|
||||
} else {
|
||||
@@ -56,6 +56,9 @@ router.beforeEach(async(to, from, next) => {
|
||||
/* has no token*/
|
||||
if (whiteList.indexOf(to.path) !== -1) {
|
||||
// 在免登录whiteList中,直接进入
|
||||
if (to.path === '/readingDicoms' || to.path === '/noneDicomReading'){
|
||||
OSSclient()
|
||||
}
|
||||
next()
|
||||
} else {
|
||||
if (to.path === '/researchForm') {
|
||||
|
||||
@@ -139,6 +139,13 @@ export const constantRoutes = [
|
||||
hidden: true,
|
||||
component: () => import('@/views/trials/trials-panel/reading/dicoms/components/Fusion/PetCt')
|
||||
},
|
||||
|
||||
{
|
||||
path: '/historyScreenshot',
|
||||
name: 'historyScreenshot',
|
||||
hidden: true,
|
||||
component: () => import('@/views/trials/trials-panel/reading/dicoms/components/Fusion/HistoryScreenshot')
|
||||
},
|
||||
{
|
||||
path: '/visitDicomReview',
|
||||
name: 'visitDicomReview',
|
||||
@@ -242,6 +249,11 @@ export const constantRoutes = [
|
||||
component: () => import('@/views/404'),
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: '/ecrfPreview',
|
||||
component: () => import('@/views/dictionary/template/components/ECRF'),
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: '/editUser',
|
||||
component: Layout,
|
||||
@@ -251,11 +263,6 @@ export const constantRoutes = [
|
||||
path: 'baiscInfo',
|
||||
name: 'BaiscInfo',
|
||||
component: () => import('@/views/user/editInfo')
|
||||
},
|
||||
{
|
||||
path: 'account',
|
||||
name: 'Account',
|
||||
component: () => import('@/views/user/account')
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ const getters = {
|
||||
activeSeries: state => state.reading.activeSeries,
|
||||
lastCanvasTaskId: state => state.reading.lastCanvasTaskId,
|
||||
imageQuality: state => state.reading.imageQuality,
|
||||
imageQualityIssues: state => state.reading.imageQualityIssues,
|
||||
language: state => state.lang.language,
|
||||
TotalNeedSignSystemDocCount: state => state.user.TotalNeedSignSystemDocCount,
|
||||
TotalNeedSignTrialDocCount: state => state.user.TotalNeedSignTrialDocCount,
|
||||
|
||||
@@ -20,8 +20,8 @@ const hangingAgreement = [
|
||||
]
|
||||
const getDefaultState = () => {
|
||||
return {
|
||||
// visitTaskList: [],
|
||||
visitTaskList: sessionStorage.getItem('visitTaskList') ? JSON.parse(sessionStorage.getItem('visitTaskList')) : [],
|
||||
visitTaskList: [],
|
||||
// visitTaskList: sessionStorage.getItem('visitTaskList') ? JSON.parse(sessionStorage.getItem('visitTaskList')) : [],
|
||||
organList: [],
|
||||
seriesStack: [],
|
||||
activeHangingAgreement: hangingAgreement[0],
|
||||
@@ -29,7 +29,8 @@ const getDefaultState = () => {
|
||||
currentReadingTaskState: 2,
|
||||
activeSeries: {},
|
||||
lastCanvasTaskId: '',
|
||||
imageQuality: null
|
||||
imageQuality: null,
|
||||
imageQualityIssues: null
|
||||
}
|
||||
}
|
||||
function getQuestions(questions) {
|
||||
@@ -165,7 +166,7 @@ const actions = {
|
||||
item.IsInit = false
|
||||
})
|
||||
state.visitTaskList = res.Result
|
||||
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
const currentTaskIdx = res.Result.findIndex(item => item.IsCurrentTask)
|
||||
if (currentTaskIdx > -1) {
|
||||
state.currentTaskId = res.Result[currentTaskIdx].VisitTaskId
|
||||
@@ -177,17 +178,19 @@ const actions = {
|
||||
},
|
||||
resetVisitTasks({ state }) {
|
||||
return new Promise(resolve => {
|
||||
sessionStorage.setItem('visitTaskList', '')
|
||||
// sessionStorage.setItem('visitTaskList', '')
|
||||
state.visitTaskList = []
|
||||
state.currentTaskId = ''
|
||||
state.activeSeries = {}
|
||||
state.lastCanvasTaskId = ''
|
||||
state.imageQuality = null
|
||||
state.imageQualityIssues = null
|
||||
resolve()
|
||||
})
|
||||
},
|
||||
getMasterSeries({ state }, obj) {
|
||||
return new Promise(resolve => {
|
||||
console.log('getMasterSeries')
|
||||
var seriesInfo = {}
|
||||
var i = state.visitTaskList.findIndex(i => i.VisitTaskId === obj.visitTaskId)
|
||||
getReadingVisitStudyList(obj.trialId, obj.visitId, obj.visitTaskId).then(res => {
|
||||
@@ -207,14 +210,28 @@ const actions = {
|
||||
var seriesList = []
|
||||
study.SeriesList.forEach((series, index) => {
|
||||
const imageIds = []
|
||||
|
||||
series.InstancePathList.forEach((path) => {
|
||||
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? Vue.prototype.OSSclientConfig.basePath : Vue.prototype.OSSclientConfig.basePath}${path}`)
|
||||
const instanceList = []
|
||||
// series.InstancePathList.forEach((path) => {
|
||||
// imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? Vue.prototype.OSSclientConfig.basePath : Vue.prototype.OSSclientConfig.basePath}${path}`)
|
||||
// })
|
||||
series.InstanceInfoList.forEach(instance => {
|
||||
if (instance.NumberOfFrames && instance.NumberOfFrames > 1) {
|
||||
for (let i = 0; i < instance.NumberOfFrames; i++) {
|
||||
const imageId = `wadouri:${localStorage.getItem('location') !== 'USA' ? Vue.prototype.OSSclientConfig.basePath : Vue.prototype.OSSclientConfig.basePath}${instance.Path}?frame=${i}&instanceId=${instance.Id}&visitTaskId=${obj.visitTaskId}&idx=0|0`
|
||||
imageIds.push(imageId)
|
||||
}
|
||||
} else {
|
||||
const imageId = `wadouri:${localStorage.getItem('location') !== 'USA' ? Vue.prototype.OSSclientConfig.basePath : Vue.prototype.OSSclientConfig.basePath}${instance.Path}?instanceId=${instance.Id}&visitTaskId=${obj.visitTaskId}&idx=0|0`
|
||||
imageIds.push(imageId)
|
||||
}
|
||||
instance.ImageId = `wadouri:${localStorage.getItem('location') !== 'USA' ? Vue.prototype.OSSclientConfig.basePath : Vue.prototype.OSSclientConfig.basePath}${instance.Path}?instanceId=${instance.Id}&visitTaskId=${obj.visitTaskId}&idx=0|0`
|
||||
instanceList.push(instance.Id)
|
||||
})
|
||||
seriesList.push({
|
||||
isDicom: study.IsDicom,
|
||||
imageIds: imageIds,
|
||||
instanceList: series.InstanceList,
|
||||
instanceInfoList: series.InstanceInfoList,
|
||||
instanceList: instanceList,
|
||||
seriesId: series.Id,
|
||||
imageIdIndex: 0,
|
||||
seriesUid: series.SeriesInstanceUid,
|
||||
@@ -285,7 +302,7 @@ const actions = {
|
||||
}
|
||||
}
|
||||
|
||||
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
resolve()
|
||||
}).catch(() => { resolve() })
|
||||
})
|
||||
@@ -301,7 +318,7 @@ const actions = {
|
||||
})
|
||||
})
|
||||
}
|
||||
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
resolve()
|
||||
})
|
||||
},
|
||||
@@ -320,7 +337,7 @@ const actions = {
|
||||
state.visitTaskList[index].Questions = res.Result
|
||||
state.visitTaskList[index].questionsInit = true
|
||||
state.visitTaskList[index].QuestionMarkInfoList = res.OtherInfo.QuestionMarkInfoList
|
||||
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
resolve()
|
||||
}).catch(() => { resolve() })
|
||||
}
|
||||
@@ -338,7 +355,7 @@ const actions = {
|
||||
state.visitTaskList[index].Questions = res.Result
|
||||
state.visitTaskList[index].questionsInit = true
|
||||
state.visitTaskList[index].QuestionMarkInfoList = res.OtherInfo.QuestionMarkInfoList
|
||||
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
resolve()
|
||||
}).catch(() => { resolve() })
|
||||
})
|
||||
@@ -357,7 +374,7 @@ const actions = {
|
||||
var list = getQuestions(res.Result.SinglePage)
|
||||
state.visitTaskList[index].ReadingQuestions = list
|
||||
state.visitTaskList[index].readingQuestionsInit = true
|
||||
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
resolve()
|
||||
}).catch(() => { resolve() })
|
||||
}
|
||||
@@ -374,7 +391,7 @@ const actions = {
|
||||
var list = getQuestions(res.Result.SinglePage)
|
||||
state.visitTaskList[index].ReadingQuestions = list
|
||||
state.visitTaskList[index].readingQuestionsInit = true
|
||||
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
resolve()
|
||||
}).catch(() => { resolve() })
|
||||
})
|
||||
@@ -385,7 +402,7 @@ const actions = {
|
||||
if (index > -1) {
|
||||
state.visitTaskList[index].ReadingQuestions = obj.questions
|
||||
}
|
||||
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
resolve()
|
||||
})
|
||||
},
|
||||
@@ -397,7 +414,7 @@ const actions = {
|
||||
questions = findQuestionAndAddLesion(questions, obj)
|
||||
state.visitTaskList[index].ReadingQuestions = questions
|
||||
}
|
||||
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
resolve()
|
||||
})
|
||||
},
|
||||
@@ -409,7 +426,7 @@ const actions = {
|
||||
questions = findQuestionAndUpdateLesion(questions, obj)
|
||||
state.visitTaskList[index].ReadingQuestions = questions
|
||||
}
|
||||
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
resolve()
|
||||
})
|
||||
},
|
||||
@@ -421,7 +438,7 @@ const actions = {
|
||||
questions = findQuestionAndRemoveLesion(questions, obj)
|
||||
state.visitTaskList[index].ReadingQuestions = questions
|
||||
}
|
||||
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
resolve()
|
||||
})
|
||||
},
|
||||
@@ -442,7 +459,7 @@ const actions = {
|
||||
})
|
||||
state.visitTaskList[index].MeasureData = arr
|
||||
state.visitTaskList[index].measureDataInit = true
|
||||
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
resolve()
|
||||
}).catch(() => { resolve() })
|
||||
}
|
||||
@@ -469,20 +486,22 @@ const actions = {
|
||||
})
|
||||
state.visitTaskList[index].MeasureData = arr
|
||||
state.visitTaskList[index].measureDataInit = true
|
||||
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
resolve()
|
||||
}).catch(() => { resolve() })
|
||||
}
|
||||
})
|
||||
},
|
||||
removeCustomizeMeasuredData({ state }, obj) {
|
||||
|
||||
return new Promise(async resolve => {
|
||||
var index = state.visitTaskList.findIndex(i => i.VisitTaskId === obj.visitTaskId)
|
||||
var measureData = state.visitTaskList[index].MeasureData
|
||||
|
||||
console.log('removeCustomizeMeasuredData',obj, state.visitTaskList[index].MeasureData)
|
||||
// var uuid = obj.measureData.data.uuid
|
||||
// var idx = measureData.findIndex(item => item.MeasureData && item.MeasureData.data && item.MeasureData.data.uuid === uuid)
|
||||
console.log(obj, measureData)
|
||||
// console.log(obj, measureData)
|
||||
if (obj.questionInfo.Id) {
|
||||
var idx = measureData.findIndex(item => item.Id === obj.questionInfo.Id)
|
||||
console.log('idx', idx)
|
||||
if (idx > -1) {
|
||||
@@ -493,10 +512,13 @@ const actions = {
|
||||
measureData.splice(idx, 1)
|
||||
console.log('移除标记成功', idx)
|
||||
}
|
||||
if (obj.questionInfo.Id && state.currentReadingTaskState < 2) {
|
||||
await deleteCustomTag(obj.questionInfo.Id)
|
||||
}
|
||||
state.visitTaskList[index].MeasureData = measureData
|
||||
}
|
||||
} else if (obj.orderMarkName) {
|
||||
const i = measureData.findIndex(item => item.QuestionId === obj.questionId && item.OrderMarkName === obj.orderMarkName)
|
||||
const i = measureData.findIndex(item => item.MeasureData.data.remark === obj.orderMarkName)
|
||||
if (i > -1) {
|
||||
if (measureData[i].FristAddTaskId) {
|
||||
measureData[i].MeasureData = ''
|
||||
@@ -506,10 +528,12 @@ const actions = {
|
||||
console.log('移除标记成功', i)
|
||||
}
|
||||
}
|
||||
if (obj.questionInfo.Id && state.currentReadingTaskState < 2) {
|
||||
await deleteCustomTag(obj.questionInfo.Id)
|
||||
}
|
||||
state.visitTaskList[index].MeasureData = measureData
|
||||
}
|
||||
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
resolve()
|
||||
})
|
||||
},
|
||||
@@ -527,7 +551,7 @@ const actions = {
|
||||
})
|
||||
state.visitTaskList[index].MeasureData = arr
|
||||
state.visitTaskList[index].measureDataInit = true
|
||||
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
resolve()
|
||||
}).catch(() => { resolve() })
|
||||
})
|
||||
@@ -546,7 +570,7 @@ const actions = {
|
||||
})
|
||||
state.visitTaskList[index].MeasureData = arr
|
||||
state.visitTaskList[index].measureDataInit = true
|
||||
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
resolve()
|
||||
}).catch(() => { resolve() })
|
||||
})
|
||||
@@ -578,7 +602,7 @@ const actions = {
|
||||
state.visitTaskList[index].MeasureData.push(obj.data)
|
||||
console.log('新增标记成功')
|
||||
}
|
||||
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
console.log(state.visitTaskList)
|
||||
resolve()
|
||||
})
|
||||
@@ -588,6 +612,7 @@ const actions = {
|
||||
var index = state.visitTaskList.findIndex(i => i.VisitTaskId === obj.visitTaskId)
|
||||
var measureData = state.visitTaskList[index].MeasureData
|
||||
console.log('addOrUpdateNonTargetMeasuredData')
|
||||
// item.MeasureData.data.remark === obj.orderMarkName
|
||||
var idx = measureData.findIndex(item => item.QuestionId === obj.data.QuestionId && item.OrderMarkName === obj.data.OrderMarkName)
|
||||
if (idx > -1) {
|
||||
for (const k in state.visitTaskList[index].MeasureData[idx]) {
|
||||
@@ -600,7 +625,7 @@ const actions = {
|
||||
state.visitTaskList[index].MeasureData.push(obj.data)
|
||||
console.log('新增标记成功')
|
||||
}
|
||||
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
resolve()
|
||||
})
|
||||
},
|
||||
@@ -620,7 +645,7 @@ const actions = {
|
||||
}
|
||||
state.visitTaskList[index].MeasureData = measureData
|
||||
}
|
||||
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
resolve()
|
||||
})
|
||||
},
|
||||
@@ -630,32 +655,42 @@ const actions = {
|
||||
var measureData = state.visitTaskList[index].MeasureData
|
||||
console.log(measureData, obj)
|
||||
// var idx = measureData.findIndex(item => item.MeasureData.uuid === obj.data.MeasureData.data.uuid)
|
||||
if (!obj.questionInfo) {
|
||||
state.visitTaskList[index].MeasureData.push({
|
||||
MeasureData: obj,
|
||||
SeriesId: obj.seriesId,
|
||||
StudyId: obj.studyId,
|
||||
InstanceId: obj.instanceId,
|
||||
Id: obj.Id
|
||||
})
|
||||
console.log('新增标记成功')
|
||||
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
resolve()
|
||||
}
|
||||
var idx = measureData.findIndex(item => item.Id === obj.questionInfo.Id)
|
||||
// if (!obj.questionInfo) {
|
||||
// state.visitTaskList[index].MeasureData.push({
|
||||
// MeasureData: obj,
|
||||
// SeriesId: obj.seriesId,
|
||||
// StudyId: obj.studyId,
|
||||
// InstanceId: obj.instanceId,
|
||||
// Id: obj.Id
|
||||
// })
|
||||
// console.log('新增标记成功')
|
||||
// resolve()
|
||||
// }
|
||||
var idx = measureData.findIndex(item => item.MeasureData.data.remark === obj.measureData.data.remark)
|
||||
if (idx > -1) {
|
||||
for (const k in state.visitTaskList[index].MeasureData[idx]) {
|
||||
if (k !== 'Id' && obj.MeasureData.data[k]) {
|
||||
state.visitTaskList[index].MeasureData[idx][k] = obj.MeasureData.data[k]
|
||||
}
|
||||
}
|
||||
// state.visitTaskList[index].MeasureData[idx].InstanceId = obj.instanceId
|
||||
state.visitTaskList[index].MeasureData[idx].MeasureData = obj.measureData
|
||||
// state.visitTaskList[index].MeasureData[idx].SeriesId = obj.seriesId
|
||||
// state.visitTaskList[index].MeasureData[idx].StudyId = obj.studyId
|
||||
// for (const k in state.visitTaskList[index].MeasureData[idx]) {
|
||||
// if (k !== 'Id' && obj.MeasureData.data[k]) {
|
||||
// state.visitTaskList[index].MeasureData[idx][k] = obj.MeasureData.data[k]
|
||||
// }
|
||||
// }
|
||||
// state.visitTaskList[index].MeasureData[idx].MeasureData = obj.data.MeasureData
|
||||
console.log('更新标记成功', idx)
|
||||
} else {
|
||||
state.visitTaskList[index].MeasureData.push(obj.MeasureData.data)
|
||||
// state.visitTaskList[index].MeasureData.push(obj.MeasureData.data)
|
||||
state.visitTaskList[index].MeasureData.push({
|
||||
MeasureData: obj.measureData ,
|
||||
SeriesId: obj.measureData.seriesId,
|
||||
StudyId: obj.measureData.studyId,
|
||||
InstanceId: obj.measureData.instanceId,
|
||||
Id: obj.id
|
||||
})
|
||||
console.log('新增标记成功')
|
||||
}
|
||||
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
resolve()
|
||||
})
|
||||
},
|
||||
@@ -700,7 +735,7 @@ const actions = {
|
||||
|
||||
// state.visitTaskList[index].MeasureData = measureData
|
||||
// }
|
||||
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
resolve()
|
||||
})
|
||||
},
|
||||
@@ -713,19 +748,18 @@ const actions = {
|
||||
measureData[idx].MeasureData.data.status = obj.status
|
||||
state.visitTaskList[index].MeasureData = measureData
|
||||
}
|
||||
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
resolve()
|
||||
})
|
||||
},
|
||||
getStudyInfo({ state }, obj) {
|
||||
console.log('getStudyInfo')
|
||||
return new Promise(resolve => {
|
||||
var index = state.visitTaskList.findIndex(i => i.VisitTaskId === obj.visitTaskId)
|
||||
if (state.visitTaskList[index].studyListInit) {
|
||||
resolve()
|
||||
} else {
|
||||
var studyList = []
|
||||
// getVisitStudyList
|
||||
// getReadingVisitStudyList
|
||||
getReadingVisitStudyList(obj.trialId, obj.subjectVisitId, obj.visitTaskId).then(res => {
|
||||
res.Result.forEach((study, studyIndex) => {
|
||||
const data = {}
|
||||
@@ -741,19 +775,34 @@ const actions = {
|
||||
var seriesList = []
|
||||
study.SeriesList.forEach((series, seriesIndex) => {
|
||||
const imageIds = []
|
||||
try {
|
||||
// if (~window.location.href.indexOf('3c210000-3e2c-0016-4247-08dabf28e96b')) {
|
||||
series.InstancePathList.forEach((path) => {
|
||||
// var path = id.split('/')[id.split('/').length - 1]
|
||||
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? Vue.prototype.OSSclientConfig.basePath : Vue.prototype.OSSclientConfig.basePath}${path}`)
|
||||
})
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
const instanceList = []
|
||||
// try {
|
||||
// series.InstancePathList.forEach((path) => {
|
||||
// imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? Vue.prototype.OSSclientConfig.basePath : Vue.prototype.OSSclientConfig.basePath}${path}`)
|
||||
// })
|
||||
// } catch (e) {
|
||||
// console.log(e)
|
||||
// }
|
||||
series.InstanceInfoList.forEach(instance => {
|
||||
if (instance.NumberOfFrames && instance.NumberOfFrames > 1) {
|
||||
for (let i = 0; i < instance.NumberOfFrames; i++) {
|
||||
const imageId = `wadouri:${localStorage.getItem('location') !== 'USA' ? Vue.prototype.OSSclientConfig.basePath : Vue.prototype.OSSclientConfig.basePath}${instance.Path}?frame=${i}&instanceId=${instance.Id}&visitTaskId=${obj.visitTaskId}&idx=${studyIndex}|${seriesIndex}`
|
||||
imageIds.push(imageId)
|
||||
}
|
||||
instance.ImageId = `wadouri:${localStorage.getItem('location') !== 'USA' ? Vue.prototype.OSSclientConfig.basePath : Vue.prototype.OSSclientConfig.basePath}${instance.Path}?frame=${0}&instanceId=${instance.Id}&visitTaskId=${obj.visitTaskId}&idx=${studyIndex}|${seriesIndex}`
|
||||
} else {
|
||||
const imageId = `wadouri:${localStorage.getItem('location') !== 'USA' ? Vue.prototype.OSSclientConfig.basePath : Vue.prototype.OSSclientConfig.basePath}${instance.Path}?instanceId=${instance.Id}&visitTaskId=${obj.visitTaskId}&idx=${studyIndex}|${seriesIndex}`
|
||||
imageIds.push(imageId)
|
||||
instance.ImageId = imageId
|
||||
}
|
||||
|
||||
instanceList.push(instance.Id)
|
||||
})
|
||||
seriesList.push({
|
||||
isDicom: study.IsDicom,
|
||||
imageIds: imageIds,
|
||||
instanceList: series.InstanceList,
|
||||
instanceInfoList: series.InstanceInfoList,
|
||||
instanceList: instanceList,
|
||||
seriesId: series.Id,
|
||||
imageIdIndex: 0,
|
||||
seriesUid: series.SeriesInstanceUid,
|
||||
@@ -780,7 +829,8 @@ const actions = {
|
||||
isLoading: false,
|
||||
isBeMark: series.IsBeMark,
|
||||
ww: series.WindowWidth,
|
||||
wc: series.WindowCenter
|
||||
wc: series.WindowCenter,
|
||||
isExistMutiFrames: series.IsExistMutiFrames
|
||||
})
|
||||
})
|
||||
data.SeriesList = seriesList
|
||||
@@ -788,7 +838,7 @@ const actions = {
|
||||
})
|
||||
state.visitTaskList[index].StudyList = studyList
|
||||
state.visitTaskList[index].studyListInit = true
|
||||
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
resolve()
|
||||
}).catch(() => { resolve() })
|
||||
}
|
||||
@@ -821,7 +871,7 @@ const actions = {
|
||||
}
|
||||
}
|
||||
state.visitTaskList[index].StudyList = studyList
|
||||
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
} else {
|
||||
// console.log(obj)
|
||||
}
|
||||
@@ -841,15 +891,21 @@ const actions = {
|
||||
studyList[obj.studyIndex].SeriesList[obj.seriesIndex].loadStatus = true
|
||||
}
|
||||
state.visitTaskList[obj.visitTaskindex].StudyList = studyList
|
||||
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
}
|
||||
resolve()
|
||||
})
|
||||
},
|
||||
setImageloadedInfo({ state }, obj) {
|
||||
var index = state.visitTaskList.findIndex(i => i.VisitTaskId === obj.visitTaskId)
|
||||
let prefetchInstanceCount = state.visitTaskList[index].StudyList[obj.studyIndex].SeriesList[obj.seriesIndex].prefetchInstanceCount
|
||||
state.visitTaskList[index].StudyList[obj.studyIndex].SeriesList[obj.seriesIndex].prefetchInstanceCount = prefetchInstanceCount + 100
|
||||
state.visitTaskList[index].StudyList[obj.studyIndex].SeriesList[obj.seriesIndex].imageloadedArr.push(obj.imageId)
|
||||
},
|
||||
setStatus({ state }, obj) {
|
||||
var index = state.visitTaskList.findIndex(i => i.VisitTaskId === obj.visitTaskId)
|
||||
state.visitTaskList[index].IsInit = true
|
||||
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
},
|
||||
setActiveSeries({ state }, series) {
|
||||
return new Promise(resolve => {
|
||||
@@ -859,7 +915,12 @@ const actions = {
|
||||
},
|
||||
setLastCanvasTaskId({ state }, taskId) {
|
||||
return new Promise(resolve => {
|
||||
var isReadingTaskViewInOrder = localStorage.getItem('isReadingTaskViewInOrder')
|
||||
if (parseInt(isReadingTaskViewInOrder) === 2) {
|
||||
if (!state.lastCanvasTaskId) state.lastCanvasTaskId = taskId
|
||||
} else {
|
||||
state.lastCanvasTaskId = taskId
|
||||
}
|
||||
resolve()
|
||||
})
|
||||
},
|
||||
@@ -875,6 +936,9 @@ const actions = {
|
||||
setImageQuality({ state }, imageQuality) {
|
||||
state.imageQuality = isNaN(parseInt(imageQuality)) ? null : parseInt(imageQuality)
|
||||
},
|
||||
setImageQualityIssues({ state }, imageQualityIssues) {
|
||||
state.imageQualityIssues = isNaN(parseInt(imageQualityIssues)) ? null : parseInt(imageQualityIssues)
|
||||
},
|
||||
addQuestionMeasuredData({ state }, obj) {
|
||||
return new Promise(resolve => {
|
||||
var index = state.visitTaskList.findIndex(i => i.VisitTaskId === obj.visitTaskId)
|
||||
@@ -891,7 +955,7 @@ const actions = {
|
||||
state.visitTaskList[index].QuestionMarkInfoList.push(obj.data)
|
||||
console.log('新增标记成功')
|
||||
}
|
||||
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
resolve()
|
||||
})
|
||||
},
|
||||
@@ -907,7 +971,7 @@ const actions = {
|
||||
}
|
||||
state.visitTaskList[index].QuestionMarkInfoList = measureData
|
||||
}
|
||||
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
resolve()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -6,7 +6,8 @@ const getDefaultState = () => {
|
||||
subjectQuery: null,
|
||||
visitPlanQuery: null,
|
||||
visitPointQuery: null,
|
||||
studyListQuery: null
|
||||
studyListQuery: null,
|
||||
unlock: false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +17,9 @@ const mutations = {
|
||||
RESET_TRIALS: (state) => {
|
||||
Object.assign(state, getDefaultState())
|
||||
},
|
||||
SET_UNLOCK: (state, unlock) => {
|
||||
state.unlock = unlock
|
||||
},
|
||||
SET_ACTIVENAME: (state, activeName) => {
|
||||
state.trialDetailActiveName = activeName
|
||||
},
|
||||
@@ -37,6 +41,9 @@ const mutations = {
|
||||
}
|
||||
|
||||
const actions = {
|
||||
setUnLock({ commit }, unlock) {
|
||||
commit('SET_UNLOCK', unlock)
|
||||
},
|
||||
setActiveName({ commit }, activeName) {
|
||||
commit('SET_ACTIVENAME', activeName)
|
||||
},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { getToken, setToken, removeToken, setName, removeName } from '@/utils/auth'
|
||||
import { login, getUserMenuTree, getUserPermissions } from '@/api/user'
|
||||
import { login, loginOut, getUserMenuTree, getUserPermissions } from '@/api/user'
|
||||
|
||||
import { resetRouter } from '@/router'
|
||||
import md5 from 'js-md5'
|
||||
@@ -78,22 +78,32 @@ const mutations = {
|
||||
}
|
||||
|
||||
const actions = {
|
||||
changeUserName({ commit }, userName) {
|
||||
commit('SET_USERNAME', userName)
|
||||
},
|
||||
// user login
|
||||
login({ commit }, userInfo) {
|
||||
const { username, password } = userInfo
|
||||
const { username, password, UserId } = userInfo
|
||||
return new Promise((resolve, reject) => {
|
||||
login({ UserName: username.trim(), Password: md5(password) }).then(async response => {
|
||||
let data = {
|
||||
UserName: username.trim(), Password: md5(password)
|
||||
}
|
||||
if (UserId) {
|
||||
data.UserId = UserId;
|
||||
}
|
||||
login(data).then(async response => {
|
||||
if (response.IsSuccess) {
|
||||
zzSessionStorage.removeItem('lastWorkbench')
|
||||
zzSessionStorage.setItem('my_username', username.trim())
|
||||
zzSessionStorage.setItem('my_password', md5(password))
|
||||
zzSessionStorage.setItem('my_EMail', response.Result.BasicInfo.EMail)
|
||||
const data = response.Result
|
||||
if (data.BasicInfo.IsFirstAdd) {
|
||||
if (data.BasicInfo.IsFirstAdd || data.BasicInfo.LoginState === 1) {
|
||||
try {
|
||||
zzSessionStorage.setItem('userId', data.BasicInfo.Id)
|
||||
commit('SET_TOKEN', data.JWTStr)
|
||||
setToken(data.JWTStr)
|
||||
resolve(false)
|
||||
resolve(response.Result)
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
@@ -104,6 +114,7 @@ const actions = {
|
||||
zzSessionStorage.setItem('userName', data.BasicInfo.UserName)
|
||||
commit('SET_TOKEN', data.JWTStr)
|
||||
commit('SET_NAME', data.BasicInfo.RealName)
|
||||
zzSessionStorage.setItem('realName', data.BasicInfo.RealName)
|
||||
zzSessionStorage.setItem('isTestUser', data.BasicInfo.IsTestUser)
|
||||
commit('SET_ISTESTUSER', data.BasicInfo.IsTestUser)
|
||||
commit('SET_USERNAME', data.BasicInfo.UserName)
|
||||
@@ -158,7 +169,7 @@ const actions = {
|
||||
commit('SET_PERMISSIONS', JSON.parse(zzSessionStorage.getItem('permissions')))
|
||||
commit('SET_ISTESTUSER', zzSessionStorage.getItem('isTestUser'))
|
||||
const user = JSON.parse(userString)
|
||||
commit('SET_NAME', user.realName)
|
||||
commit('SET_NAME', zzSessionStorage.getItem('realName'))
|
||||
commit('SET_USERID', user.id)
|
||||
commit('SET_USERNAME', zzSessionStorage.getItem('userName'))
|
||||
commit('SET_NEED_SIGN_SYSTEM_DOC_COUNT', parseInt(zzSessionStorage.getItem('TotalNeedSignSystemDocCount')))
|
||||
@@ -175,12 +186,19 @@ const actions = {
|
||||
commit('SET_NAME', zzSessionStorage.getItem('realName'))
|
||||
},
|
||||
// user logout
|
||||
logout({ commit, state }) {
|
||||
async logout({ commit, state }) {
|
||||
try {
|
||||
removeToken() // must remove token first
|
||||
await loginOut({
|
||||
Userd: zzSessionStorage.getItem('userId')
|
||||
})
|
||||
resetRouter()
|
||||
removeName()
|
||||
zzSessionStorage.clear()
|
||||
commit('RESET_STATE')
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
},
|
||||
setToken({ commit }, token) {
|
||||
commit('SET_TOKEN', token)
|
||||
|
||||
@@ -54,11 +54,16 @@ export const anonymization = function (file, config) {
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log(dataset)
|
||||
// console.log(dataset)
|
||||
try {
|
||||
let newDicomFile = dataset.write()
|
||||
const bufferArray = new Uint8Array(newDicomFile)
|
||||
const blob = new Blob([bufferArray], { type: 'application/octet-stream' })
|
||||
resolve({ blob, pixelDataElement })
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
resolve(false);
|
||||
}
|
||||
};
|
||||
reader.readAsArrayBuffer(file);
|
||||
} catch (e) {
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import Vue from 'vue'
|
||||
import { encoder } from './encoder'
|
||||
import { anonymization } from './anonymization'
|
||||
export const dcmUpload = async function (name, file, config) {
|
||||
return new Promise(async resolve => {
|
||||
try {
|
||||
// let blob = await encoder(file, config)
|
||||
// let blob = await fileToBlob(file)
|
||||
let blob = await anonymization(file, config)
|
||||
let blob = await fileToBlob(file)
|
||||
if (config) {
|
||||
blob = await anonymization(file, config)
|
||||
}
|
||||
let res = await Vue.prototype.OSSclient.put(name, blob.blob)
|
||||
resolve({
|
||||
...res,
|
||||
@@ -35,7 +36,7 @@ function fileToBlob(file) {
|
||||
} else {
|
||||
blob = e.target.result
|
||||
}
|
||||
resolve(blob)
|
||||
resolve({ blob })
|
||||
})
|
||||
// FileReader 以 ArrayBuffer 格式 读取 File 对象中数据
|
||||
reader.readAsArrayBuffer(file)
|
||||
|
||||
@@ -8359,6 +8359,7 @@
|
||||
allowInvalidVRLength: false
|
||||
};
|
||||
var allowInvalidVRLength = writeOptions.allowInvalidVRLength;
|
||||
allowInvalidVRLength = true
|
||||
var valid = true,
|
||||
valarr = Array.isArray(value) ? value : [value],
|
||||
total = 0;
|
||||
|
||||
@@ -20,6 +20,7 @@ function blobToBuffer(blob, fileName) {
|
||||
async function ossGenerateSTS() {
|
||||
let res = await GetObjectStoreToken()
|
||||
Vue.prototype.OSSclientConfig = { ...res.Result[res.Result.ObjectStoreUse] }
|
||||
Vue.prototype.OSSclientConfig.ObjectStoreUse = res.Result.ObjectStoreUse;
|
||||
Vue.prototype.OSSclientConfig.basePath = Vue.prototype.OSSclientConfig.viewEndpoint
|
||||
switch (res.Result.ObjectStoreUse) {
|
||||
case 'AliyunOSS':
|
||||
@@ -40,7 +41,7 @@ async function ossGenerateSTS() {
|
||||
if (res && res.url) {
|
||||
resolve({
|
||||
name: objectName,
|
||||
url: Vue.prototype.OSSclientConfig.viewEndpoint + objectName
|
||||
url: res.url
|
||||
})
|
||||
} else {
|
||||
reject()
|
||||
@@ -77,7 +78,7 @@ async function ossGenerateSTS() {
|
||||
} else {
|
||||
resolve({
|
||||
name: objectName,
|
||||
url: 'http://www.abc.com' + objectName
|
||||
url: Vue.prototype.OSSclientConfig.viewEndpoint + decodeUtf8(objectName)
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -112,9 +113,10 @@ async function ossGenerateSTS() {
|
||||
console.log(err)
|
||||
reject()
|
||||
} else {
|
||||
console.log(objectName);
|
||||
resolve({
|
||||
name: objectName,
|
||||
url: 'http://www.abc.com' + objectName
|
||||
url: Vue.prototype.OSSclientConfig.viewEndpoint + decodeUtf8(objectName)
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -129,7 +131,15 @@ async function ossGenerateSTS() {
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
function decodeUtf8(bytes) {
|
||||
let str = bytes.split('?');
|
||||
let str2 = str[0].split('/');
|
||||
let name = str2[str2.length - 1];
|
||||
name = encodeURIComponent(name);
|
||||
str.shift();
|
||||
str2.pop();
|
||||
return str2.join("/") + '/' + name;
|
||||
}
|
||||
|
||||
|
||||
export const OSSclient = ossGenerateSTS
|
||||
|
||||
@@ -0,0 +1,202 @@
|
||||
import * as dicomParser from "dicom-parser";
|
||||
import * as cornerstone from "cornerstone-core";
|
||||
import * as cornerstoneWADOImageLoader from "cornerstone-wado-image-loader";
|
||||
cornerstoneWADOImageLoader.external.dicomParser = dicomParser;
|
||||
cornerstoneWADOImageLoader.external.cornerstone = cornerstone;
|
||||
import { convertBytes } from "@/utils/dicom-character-set";
|
||||
import Vue from 'vue';
|
||||
import { dcmUpload } from "@/utils/dcmUpload/dcmUpload";
|
||||
let dicom = {
|
||||
PatientName: "x00100010", // 患者姓名
|
||||
PatientId: "x00100020", // 患者ID
|
||||
PatientBirthDate: "x00100030", // 患者出生日期
|
||||
PatientBirthTime: "x00100032", // 患者出生时间
|
||||
PatientSex: "x00100040", // 患者性别
|
||||
PatientWeight: "x00101030", // 患者体重
|
||||
PregnancyStatus: "x001021c0", // 怀孕状态
|
||||
PatientAge: "x00101010", // 患者年龄(做检查时刻的患者年龄,而不是此刻患者的真实年龄)
|
||||
AcquisitionTime: "x00080032",
|
||||
AcquisitionNumber: "x00200012",
|
||||
TriggerTime: "x00181060",
|
||||
AccessionNumber: "x00080050", // 检查号
|
||||
StudyId: "x00200010", // 检查ID
|
||||
StudyInstanceUid: "x0020000d", // 检查实例号
|
||||
StudyDate: "x00080020", // 检查日期
|
||||
StudyTime: "x00080030", // 检查时间
|
||||
Modalities: "x00080061", // 一个检查中含有的不同检查类型
|
||||
BodyPartExamined: "x00080015", // 检查的部位
|
||||
StudyDescription: "x00081030", // 检查的描述
|
||||
InstitutionName: "x00080080",
|
||||
SeriesNumber: "x00200011", // 序列号
|
||||
SeriesInstanceUid: "x0020000e", // 序列实例号
|
||||
Modality: "x00080060", // 检查模态
|
||||
SeriesDescription: "x0008103e", // 检查描述和说明
|
||||
SeriesDate: "x00080021", // 检查日期
|
||||
SeriesTime: "x00080031", // 检查时间
|
||||
SequenceName: "x00180024",
|
||||
ProtocolName: "x00181030",
|
||||
ImagePosition: "x00200032", // 图像位置
|
||||
ImageOrientation: "x00200037", // 图像方位
|
||||
ImagePixelSpacing: "x00181164",
|
||||
SliceThickness: "x00180050", // 层厚
|
||||
SpacingBetweenSlices: "x00180088", // 层间距
|
||||
SliceLocation: "x00201041", // 相对位置
|
||||
MRAcquisition: "x00180023",
|
||||
seriesBodyPartExamined: "x00180015", // 身体部位
|
||||
ImageType: "x00080008",
|
||||
SopInstanceUid: "x00080018", // SOP实例UID
|
||||
ContentDate: "x00080023", // 影像拍摄日期
|
||||
ContentTime: "x00080033", // 影像拍摄时间
|
||||
ImageOrInstanceNumber: "x00200013", // 图像码
|
||||
SamplesPerPixel: "x00280002", // 图像采样率
|
||||
PhotometricInterpretation: "x00280004", // 光度计(对于CT图像,用两个枚举值MONOCHROME1,MONOCHROME2 用来判断图像是否是彩色的;MONOCHROME 1/2是灰度图,RGB则是真彩色图)
|
||||
Rows: "x00280010", // 行数
|
||||
Columns: "x00280011", // 列数
|
||||
NumberOfFrames: "x00280008",
|
||||
PixelSpacing: "x00280030", // 像素间距
|
||||
BitsAllocated: "x00280100", // 分配的位数
|
||||
BitsStored: "x00280101", // 存储的位数
|
||||
HighBit: "x00280102", // 高位
|
||||
PixelRepresentation: "x00280103", // 像素数据的表现类型(一个枚举值,分别为十六进制数0000和0001.0000H = 无符号整型,0001H = 2的补码)
|
||||
WindowCenter: "x00281050", // 窗位
|
||||
WindowWidth: "x002811051", // 窗宽
|
||||
RescaleIntercept: "x00281052", // 截距
|
||||
RescaleSlope: "x00281053", // 斜率
|
||||
RescaleType: "x00281054", // 输出值的单位
|
||||
ParsingFormat: "x00080005",
|
||||
FrameOfReferenceUID: "x00200052",
|
||||
};
|
||||
// 需要设置默认值
|
||||
let defaultKey = ['Rows', 'Columns', 'SliceLocation', 'NumberOfFrames'];
|
||||
let uintKey = ['Rows', 'Columns'];
|
||||
let intStringKey = ['SliceLocation', 'NumberOfFrames'];
|
||||
// 需要格式解析
|
||||
let pormatParseKey = ['PatientName', 'SeriesDescription', 'StudyDescription'];
|
||||
// 解析dicom文件
|
||||
export const parseDicom = (file, name = false) => {
|
||||
return new Promise(function (resolve) {
|
||||
let reader = new FileReader();
|
||||
reader.onload = function (e) {
|
||||
try {
|
||||
let data = dicomParser.parseDicom(new Uint8Array(e.target.result));
|
||||
let res = {};
|
||||
if (name && Array.isArray(name)) {
|
||||
name.forEach((item) => {
|
||||
if (dicom[item]) {
|
||||
res[item] = data.string(dicom[item]) || '';
|
||||
}
|
||||
});
|
||||
} else if (name) {
|
||||
if (dicom[name]) {
|
||||
res[name] = data.string(dicom[name]) || '';
|
||||
} else {
|
||||
console.log("name is inexistence");
|
||||
resolve(false)
|
||||
}
|
||||
} else {
|
||||
Object.keys(dicom).forEach((key) => {
|
||||
res[key] = data.string(dicom[key]) || '';
|
||||
});
|
||||
}
|
||||
pormatParseKey.forEach(key => {
|
||||
if (res[key]) {
|
||||
const Element = data.elements[dicom[key]];
|
||||
const Bytes = new Uint8Array(
|
||||
data.byteArray.buffer,
|
||||
Element ? Element.dataOffset : 0,
|
||||
Element ? Element.length : 0
|
||||
);
|
||||
res[key] = convertBytes(
|
||||
res.ParsingFormat,
|
||||
Bytes
|
||||
);
|
||||
}
|
||||
})
|
||||
uintKey.forEach(key => {
|
||||
res[key] = data.uint16(dicom[key])
|
||||
})
|
||||
intStringKey.forEach(key => {
|
||||
res[key] = data.intString(dicom[key])
|
||||
})
|
||||
defaultKey.forEach(key => {
|
||||
if (!res[key] && res.hasOwnProperty(key)) {
|
||||
res[key] = 0;
|
||||
}
|
||||
})
|
||||
resolve(res);
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
resolve(false);
|
||||
}
|
||||
};
|
||||
reader.onerror = function (e) {
|
||||
console.log(e)
|
||||
resolve(false);
|
||||
};
|
||||
reader.readAsArrayBuffer(file);
|
||||
});
|
||||
};
|
||||
// 影像上传
|
||||
// 影像上传
|
||||
export const dicomToOSS = async (file, path) => {
|
||||
try {
|
||||
let res = await dcmUpload(path, file);
|
||||
if (!res || !res.url) return false;
|
||||
return Vue.prototype.$getObjectName(res.url);
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
// 获取缩略图
|
||||
export const getThumbnail = async (file, ossPath, dicomInfo) => {
|
||||
try {
|
||||
if (dicomInfo.modality !== "SR") {
|
||||
let fileId = cornerstoneWADOImageLoader.wadouri.fileManager.add(file);
|
||||
let blob = await dicomToPng(
|
||||
fileId,
|
||||
dicomInfo.Columns,
|
||||
dicomInfo.Rows
|
||||
);
|
||||
if (!blob) return "";
|
||||
let OSSclient = Vue.prototype.OSSclient;
|
||||
let seriesRes = await OSSclient.put(ossPath, blob);
|
||||
if (seriesRes && seriesRes.url) {
|
||||
return Vue.prototype.$getObjectName(seriesRes.url);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
return "";
|
||||
}
|
||||
};
|
||||
const canvasToBlob = (canvas) => {
|
||||
return new Promise((resolve) => {
|
||||
canvas.toBlob((blob) => {
|
||||
resolve(blob);
|
||||
});
|
||||
});
|
||||
};
|
||||
const dicomToPng = (imageId, width, height) => {
|
||||
return new Promise((resolve) => {
|
||||
cornerstone.loadImage(imageId).then(async (image) => {
|
||||
let canvas = document.createElement("canvas");
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
if (image) {
|
||||
cornerstone.renderToCanvas(canvas, image);
|
||||
// 将 Canvas 图像对象转换为 PNG 格式
|
||||
let blob = await canvasToBlob(canvas);
|
||||
resolve(blob);
|
||||
} else {
|
||||
resolve(false);
|
||||
}
|
||||
});
|
||||
}).catch((reason) => {
|
||||
reason();
|
||||
});
|
||||
};
|
||||
@@ -3,6 +3,8 @@ import { Message, MessageBox, Alert } from 'element-ui'
|
||||
import store from '@/store'
|
||||
import router from '@/router'
|
||||
import Vue from 'vue'
|
||||
import moment from 'moment-timezone';
|
||||
console.log(moment.tz.guess())
|
||||
axios.defaults.withCredentials = false
|
||||
const service = axios.create({
|
||||
baseURL: '/api',
|
||||
@@ -19,6 +21,7 @@ service.interceptors.request.use(
|
||||
config.headers['Content-Type'] = 'application/json;charset=UTF-8'
|
||||
var language = zzSessionStorage.getItem('lang')
|
||||
config.headers['Accept-Language'] = language === 'en' ? 'en-US,en;q=0.5' : 'zh-CN,zh;q=0.9'
|
||||
config.headers['TimeZoneId'] = moment.tz.guess()
|
||||
if (store.getters.token) {
|
||||
config.headers.Authorization = `Bearer ${store.getters.token}`
|
||||
}
|
||||
@@ -46,20 +49,24 @@ service.interceptors.request.use(
|
||||
}
|
||||
)
|
||||
|
||||
var isConfirm = true
|
||||
let timer = null;
|
||||
let time = 1000;
|
||||
|
||||
service.interceptors.response.use(
|
||||
response => {
|
||||
const res = response.data
|
||||
if (res.IsSuccess) {
|
||||
isConfirm = true
|
||||
return Promise.resolve(res)
|
||||
} else if (res.IsSuccess === false) {
|
||||
if (res.Code !== 5) {
|
||||
MessageBox.confirm(res.ErrorMessage, {
|
||||
type: 'warning',
|
||||
showCancelButton: false,
|
||||
callback: action => {}
|
||||
callback: action => {
|
||||
if (res.Code === 6) {
|
||||
window.close()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
return Promise.reject(res)
|
||||
@@ -71,7 +78,7 @@ service.interceptors.response.use(
|
||||
var message = ''
|
||||
if (error && error.response) {
|
||||
const status = error.response.status
|
||||
if (error.response.data && error.response.data.Code === -1) {
|
||||
if (error.response.data && (error.response.data.Code === -1 || error.response.data.Code === -2)) {
|
||||
store.dispatch('user/logout').then(() => {
|
||||
router.push(`/login`)
|
||||
this.$i18n.locale = 'zh'
|
||||
@@ -98,11 +105,11 @@ service.interceptors.response.use(
|
||||
if (error.response.status === 401) {
|
||||
if (store.getters.token) {
|
||||
if (message !== '') {
|
||||
Message({
|
||||
setTimer({
|
||||
message: message,
|
||||
type: 'warning',
|
||||
showClose: true
|
||||
})
|
||||
}, 'message')
|
||||
}
|
||||
store.dispatch('user/logout').then(() => {
|
||||
router.push(`/login`)
|
||||
@@ -111,34 +118,52 @@ service.interceptors.response.use(
|
||||
this.$updateDictionary()
|
||||
})
|
||||
} else {
|
||||
Message({
|
||||
setTimer({
|
||||
message: store.state.lang.language === 'en' ? 'You are not authorized to access the interface' : '您无权访问接口',
|
||||
type: 'warning',
|
||||
showClose: true
|
||||
})
|
||||
}, 'message')
|
||||
}
|
||||
} else {
|
||||
if(message !== '' && isConfirm){
|
||||
MessageBox.confirm(message, store.state.lang.language === 'en'? 'Warning' : '警告', {
|
||||
if (message !== '') {
|
||||
setTimer([message, store.state.lang.language === 'en' ? 'Warning' : '警告', {
|
||||
type: 'warning',
|
||||
showCancelButton: false,
|
||||
callback: action => { }
|
||||
})
|
||||
}], 'confirm')
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!window.navigator.onLine && isConfirm) {
|
||||
MessageBox.confirm(store.state.lang.language === 'en'? 'Please check your network,and try again later!' : '请检查网络,稍后重试!', store.state.lang.language === 'en'? 'Warning' : '警告', {
|
||||
if (!window.navigator.onLine) {
|
||||
setTimer(
|
||||
[store.state.lang.language === 'en' ? 'Please check your network,and try again later!' : '请检查网络,稍后重试!', store.state.lang.language === 'en' ? 'Warning' : '警告', {
|
||||
type: 'warning',
|
||||
showCancelButton: false,
|
||||
callback: action => { }
|
||||
})
|
||||
isConfirm = false
|
||||
}], "confirm"
|
||||
)
|
||||
}
|
||||
return Promise.reject(new Error(message || 'Error'))
|
||||
}
|
||||
)
|
||||
|
||||
const setTimer = (obj, type) => {
|
||||
if (timer) {
|
||||
clearTimeout(timer);
|
||||
timer = null;
|
||||
}
|
||||
timer = setTimeout(() => {
|
||||
if (type === 'message') {
|
||||
Message(obj)
|
||||
}
|
||||
if (type === 'confirm') {
|
||||
MessageBox.confirm(...obj)
|
||||
}
|
||||
clearTimeout(timer);
|
||||
timer = null;
|
||||
}, time)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,144 @@
|
||||
import JSZip from "jszip";
|
||||
import axios from "axios";
|
||||
import { saveAs } from "file-saver";
|
||||
import Vue from 'vue';
|
||||
import {
|
||||
requestPackageAndAnonymizImage,
|
||||
} from "@/api/load.js";
|
||||
let flag = {};
|
||||
export const downloadImage = async (id, id2) => {
|
||||
if (flag[id2]) return
|
||||
flag[id2] = true
|
||||
try {
|
||||
let params = {
|
||||
TrialId: id,
|
||||
SubjectVisitId: id2
|
||||
}
|
||||
let res = await requestPackageAndAnonymizImage(params);
|
||||
flag[id2] = false;
|
||||
if (res.IsSuccess) {
|
||||
if (!res.Result) {
|
||||
Vue.prototype.$message.warning(Vue.prototype.$t("trials:upload:message:not"))
|
||||
return 1;
|
||||
}
|
||||
let a = document.createElement("a");
|
||||
let href = Vue.prototype.OSSclientConfig.basePath + res.Result;
|
||||
let fileName =
|
||||
res.Result.split("/")[res.Result.split("/").length - 1];
|
||||
a.download = fileName;
|
||||
a.href = href;
|
||||
a.click();
|
||||
URL.revokeObjectURL(href);
|
||||
let timer = setTimeout(() => {
|
||||
a = null;
|
||||
href = null;
|
||||
timer = null;
|
||||
}, 500)
|
||||
return 2;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} catch (err) {
|
||||
flag[id2] = false;
|
||||
console.log(err);
|
||||
}
|
||||
};
|
||||
const setfolder = async (item) => {
|
||||
const zip = new JSZip(); // 创建实例对象
|
||||
let patientIds = item.PatientList.map(i => i.PatientIdStr);
|
||||
let zipName = `${item.SubjectCode}_${patientIds.join(',')}`;
|
||||
let zipObj = {};
|
||||
const promises = [];
|
||||
for (let visit of item.VisitList) {
|
||||
if (!zipObj[`${visit.VisitName}`]) {
|
||||
zipObj[`${visit.VisitName}`] = zip.folder(visit.VisitName);
|
||||
}
|
||||
for (let study of visit.StudyList) {
|
||||
let date = study.StudyTime.split(" ")[0];
|
||||
for (let series of study.SeriesList) {
|
||||
if (
|
||||
!zipObj[
|
||||
`${visit.VisitName}${series.Modality}`
|
||||
]
|
||||
) {
|
||||
zipObj[
|
||||
`${visit.VisitName}${series.Modality}`
|
||||
] = zipObj[`${visit.VisitName}`].folder(
|
||||
`${date}_${series.Modality}`
|
||||
);
|
||||
}
|
||||
for (let instance of series.InstancePathList) {
|
||||
let obj = {
|
||||
subjectCode: item.SubjectCode,
|
||||
visitName: visit.VisitName,
|
||||
date: study.StudyTime.split(" ")[0],
|
||||
modality: series.Modality,
|
||||
instancePath: instance.Path,
|
||||
dicomName: instance.Path.split("/Dicom/")[1],
|
||||
};
|
||||
const promise = handleBatchDown(
|
||||
obj,
|
||||
zipObj[
|
||||
`${visit.VisitName}${series.Modality}`
|
||||
],
|
||||
);
|
||||
promises.push(promise);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 生成 zip 文件
|
||||
Promise.all(promises)
|
||||
.then(() => {
|
||||
// 生成zip 文件
|
||||
zip
|
||||
.generateAsync({
|
||||
type: "blob",
|
||||
compression: "DEFLATE", // STORE: 默认不压缩, DEFLATE:需要压缩
|
||||
compressionOptions: {
|
||||
level: 9, // 压缩等级 1~9 1 压缩速度最快, 9 最优压缩方式
|
||||
},
|
||||
})
|
||||
.then((res) => {
|
||||
saveAs(res, zipName + ".zip"); // 使用FileSaver.saveAs保存文件,文件名可自定义
|
||||
flag[id2] = false;
|
||||
zipObj = null;
|
||||
});
|
||||
})
|
||||
.catch((reason) => { flag[id2] = false; });
|
||||
};
|
||||
const handleBatchDown = async (item, zip) => {
|
||||
return new Promise((resolve) => {
|
||||
getFileData(
|
||||
Vue.prototype.OSSclientConfig.basePath + item.instancePath
|
||||
).then((res) => {
|
||||
const fileName = item.dicomName + ".dcm";
|
||||
zip.file(fileName, res.data, { binary: true });
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
};
|
||||
const getFileData = (fileUrl) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios(fileUrl, {
|
||||
method: "GET",
|
||||
responseType: "blob", // 返回的数据会被强制转为blob类型 ,转换成arraybuffer 也行
|
||||
})
|
||||
.then((res) => {
|
||||
resolve(res);
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
};
|
||||
export const fileDownload = (content, filename) => {
|
||||
const eleLink = document.createElement("a");
|
||||
eleLink.download = filename;
|
||||
eleLink.style.display = "none";
|
||||
const blob = new Blob([content]);
|
||||
eleLink.href = URL.createObjectURL(blob);
|
||||
document.body.appendChild(eleLink);
|
||||
eleLink.click();
|
||||
document.body.removeChild(eleLink);
|
||||
};
|
||||
@@ -89,18 +89,16 @@ export default {
|
||||
},
|
||||
// 移除菜单
|
||||
remove(node) {
|
||||
this.$confirm('Sure to delete?', {
|
||||
this.$confirm(this.$t('trials:uploadedDicoms:message:deleteMes'), {
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true,
|
||||
confirmButtonText: 'Ok',
|
||||
cancelButtonText: 'Cancel'
|
||||
distinguishCancelAndClose: true
|
||||
})
|
||||
.then(() => {
|
||||
deleteMenuFunction(node.Id)
|
||||
.then(res => {
|
||||
if (res.IsSuccess) {
|
||||
this.getlist()
|
||||
this.$message.success('Deleted successfully!')
|
||||
this.$message.success(this.$t('common:message:deletedSuccessfully'))
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
@@ -89,16 +89,15 @@ export default {
|
||||
})
|
||||
},
|
||||
handleDeleteRole(row) {
|
||||
this.$confirm('Sure to delete?', {
|
||||
this.$confirm(this.$t('trials:uploadedDicoms:message:deleteMes'), {
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true,
|
||||
confirmButtonText: 'Ok',
|
||||
cancelButtonText: 'Cancel'
|
||||
|
||||
}).then(() => {
|
||||
deleteUserTypeRole(row.Id).then((res) => {
|
||||
if (res.IsSuccess) {
|
||||
this.list.splice(this.list.findIndex((item) => item.Id === row.Id), 1)
|
||||
this.$message.success('Deleted successfully!')
|
||||
this.$message.success(this.$t('common:message:deletedSuccessfully'))
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
@@ -20,8 +20,7 @@ export default {
|
||||
this.$confirm('Sure to reset password?', {
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true,
|
||||
confirmButtonText: 'Ok',
|
||||
cancelButtonText: 'Cancel'
|
||||
|
||||
})
|
||||
.then(() => {
|
||||
resetPassword(this.userId).then(res => {
|
||||
|
||||
@@ -113,18 +113,17 @@ export default {
|
||||
},
|
||||
// 删除用户
|
||||
handleDeleteUser(data) {
|
||||
this.$confirm('Sure to delete?', {
|
||||
this.$confirm(this.$t('trials:uploadedDicoms:message:deleteMes'), {
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true,
|
||||
confirmButtonText: 'Ok',
|
||||
cancelButtonText: 'Cancel'
|
||||
|
||||
})
|
||||
.then(() => {
|
||||
deleteSysUser(data.Id)
|
||||
.then(res => {
|
||||
if (res.IsSuccess) {
|
||||
this.users.splice(this.users.findIndex(item => item.Id === data.Id), 1)
|
||||
this.$message.success('Deleted successfully!')
|
||||
this.$message.success(this.$t('common:message:deletedSuccessfully'))
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
@@ -14,27 +14,26 @@
|
||||
<span v-else>{{ employment.RankCN }}</span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item :label="$t('resumeInfo:label:Physician')">
|
||||
<span v-if="isEnglish">{{ employment.Physician }}</span>
|
||||
<span v-else>{{ employment.PhysicianCN }}</span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<!-- <el-col :span="6">-->
|
||||
<!-- <el-form-item :label="$t('resumeInfo:label:Physician')">-->
|
||||
<!-- <span v-if="isEnglish">{{ employment.Physician }}</span>-->
|
||||
<!-- <span v-else>{{ employment.PhysicianCN }}</span>-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- </el-col>-->
|
||||
<el-col :span="6">
|
||||
<el-form-item :label="$t('resumeInfo:label:Position')">
|
||||
<span v-if="isEnglish">{{ employment.Position }}</span>
|
||||
<span v-else>{{ employment.PositionCN }}</span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row>
|
||||
<el-col :span="6">
|
||||
<el-form-item :label="$t('resumeInfo:label:Hospital')">
|
||||
<span v-if="isEnglish">{{ employment.HospitalName }}</span>
|
||||
<span v-else>{{ employment.HospitalNameCN }}</span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="6">
|
||||
<el-form-item :label="$t('resumeInfo:label:Affiliated')">
|
||||
<span v-if="isEnglish">{{ employment.UniversityAffiliated }}</span>
|
||||
|
||||
@@ -90,11 +90,12 @@ export default {
|
||||
this.setLanguage('zh')
|
||||
this.$updateDictionary()
|
||||
}
|
||||
this.title = this.doctorInfo.BasicInfoView?`${this.doctorInfo.BasicInfoView.FirstName} ${this.doctorInfo.BasicInfoView.LastName}${this.$t('resumeInfo:title:Details')}`:''
|
||||
this.title = this.doctorInfo.BasicInfoView?`${this.doctorInfo.BasicInfoView.BlindName}${this.$t('resumeInfo:title:Details')}`:''
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.isEnglish = !!((this.$route.query.isEnglish === true || this.$route.query.isEnglish === 'true'))
|
||||
this.isEnglish = this.$i18n.locale === 'zh' ? false : true
|
||||
this.doctorId = this.$route.query.doctorId
|
||||
this.initForm()
|
||||
},
|
||||
@@ -135,6 +136,7 @@ export default {
|
||||
} else {
|
||||
this.workInfo.Position = this.workInfo.Position
|
||||
this.workInfo.PositionCN = this.workInfo.PositionCN
|
||||
//
|
||||
}
|
||||
this.workInfo.PositionOther = this.workInfo.PositionOther ? 'Other - ' + this.workInfo.PositionOther : 'Other'
|
||||
}
|
||||
@@ -179,7 +181,7 @@ export default {
|
||||
this.holiday = res.Result.InHoliday ? 'Yes' : 'No'
|
||||
this.doctorInfo = res.Result
|
||||
!this.doctorInfo.ResearchPublicationView ? this.doctorInfo.ResearchPublicationView = {} : '';
|
||||
this.title = `${this.doctorInfo.BasicInfoView.BlindName} 's Details`
|
||||
this.title = this.doctorInfo.BasicInfoView?`${this.doctorInfo.BasicInfoView.BlindName}${this.$t('resumeInfo:title:Details')}`:''
|
||||
this.htmlTitle = this.title
|
||||
this.initStatus()
|
||||
this.initEmploymentInfo()
|
||||
|
||||
@@ -126,8 +126,7 @@ export default {
|
||||
this.$confirm('Sure to sign out', {
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true,
|
||||
confirmButtonText: 'Ok',
|
||||
cancelButtonText: 'Cancel'
|
||||
|
||||
})
|
||||
.then(() => {
|
||||
this.$store.dispatch('user/logout').then(res => {
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
import * as dicomParser from 'dicom-parser'
|
||||
import * as cornerstone from 'cornerstone-core'
|
||||
import * as cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader'
|
||||
import dicomStore from '@/utils/dicom-store.js'
|
||||
import dicomStore from '@/utils/dicom-store'
|
||||
import dicomViewer from '@/components/Dicom/DicomViewer'
|
||||
import dicomPreview from '@/components/Dicom/DicomPreview'
|
||||
|
||||
@@ -86,6 +86,10 @@ export default {
|
||||
uid: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
studyList: {
|
||||
type: Array,
|
||||
default: []
|
||||
}
|
||||
},
|
||||
|
||||
@@ -102,7 +106,7 @@ export default {
|
||||
var totalHeight = window.innerHeight || document.body.clientHeight
|
||||
var wrapper = this.$refs['preview-wrapper']
|
||||
wrapper.style.height = (totalHeight - 70) + 'px'
|
||||
if (!dicomStore.studyList || !this.uid) return
|
||||
if (!this.studyList || !this.uid) return
|
||||
this.loadStudy()
|
||||
},
|
||||
|
||||
@@ -120,7 +124,7 @@ export default {
|
||||
return newObj
|
||||
},
|
||||
loadStudy() {
|
||||
var studyList = dicomStore.studyList
|
||||
var studyList = this.studyList
|
||||
var studyUid = this.uid
|
||||
var studyItem = studyList.find(function(item) {
|
||||
return item.dicomInfo.studyUid === studyUid
|
||||
|
||||
@@ -43,45 +43,83 @@
|
||||
fit="fill"
|
||||
>
|
||||
<div class="viewernavitextwrapper">
|
||||
<div v-if="item.keySeries" style="padding: 1px;color:red">
|
||||
<div style="padding: 1px 5px 1px 1px;display: flex;justify-content: space-between;">
|
||||
<div v-if="item.keySeries" style="color:red">
|
||||
Key Images
|
||||
</div>
|
||||
<div v-else style="padding: 1px;">
|
||||
<div v-else>
|
||||
#{{ item.seriesNumber }}
|
||||
</div>
|
||||
<div v-if="item.isExistMutiFrames && item.instanceCount > 1">
|
||||
<el-popover
|
||||
placement="right"
|
||||
trigger="hover"
|
||||
popper-class="instance_frame_wrapper"
|
||||
>
|
||||
<div
|
||||
v-for="(instance, idx) in item.instanceInfoList"
|
||||
:key="instance.Id"
|
||||
class="frame_content"
|
||||
:style="{'margin-bottom':idx<item.instanceInfoList.length-1? '5px':'0px'}"
|
||||
@click="showMultiFrames(item, index, instance)"
|
||||
>
|
||||
<!-- <div>
|
||||
<img
|
||||
class="image-preview"
|
||||
:src="series.previewImageUrl"
|
||||
crossorigin="anonymous"
|
||||
alt=""
|
||||
style="width: 40px;height:40px;"
|
||||
fit="fill"
|
||||
>
|
||||
</div> -->
|
||||
<div>
|
||||
<div>{{ instance.InstanceNumber }}</div>
|
||||
<div>{{ `${instance.NumberOfFrames > 0 ? instance.NumberOfFrames : 1} frame` }}</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<i slot="reference" class="el-icon-connection" style="font-size: 15px;cursor: pointer;" />
|
||||
</el-popover>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div v-show="item.instanceCount" style="padding: 1px;">
|
||||
{{ item.modality }}: {{ item.instanceCount }} image
|
||||
</div>
|
||||
<div v-show="!item.keySeries && item.sliceThickness" style="padding: 1px;">
|
||||
T: {{ item.sliceThickness }}
|
||||
T: {{ parseFloat(item.sliceThickness).toFixed(2) }}
|
||||
</div>
|
||||
<div v-show="!item.keySeries &&item.description" style="width: 120px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;padding: 1x;">
|
||||
{{ item.description }}
|
||||
</div>
|
||||
<div v-if="!item.keySeries" style="padding: 1px;">
|
||||
{{ item.prefetchInstanceCount }}/{{ item.instanceCount }}
|
||||
{{ item.imageloadedArr.length }}/{{ item.instanceCount }}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="showDelete" @click.stop="">
|
||||
<div v-if="showDelete" style="display: flex;flex-direction: row;justify-content: space-between;" @click.stop="">
|
||||
|
||||
<span style="font-size: 12px;">{{ $t('trials:audit:table:isReading') }}</span>
|
||||
<div>
|
||||
<span style="font-size: 12px;margin-right: 5px">{{ $t('trials:audit:table:isReading') }}</span>
|
||||
<el-switch
|
||||
v-model="item.isReading"
|
||||
size="mini"
|
||||
@change="changeReadingStatus($event, item)"
|
||||
/>
|
||||
|
||||
<span style="font-size: 12px;">{{ $t('trials:audit:table:isDelete') }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span style="font-size: 12px;margin-right: 5px">{{ $t('trials:audit:table:isDelete') }}</span>
|
||||
<el-switch
|
||||
v-model="item.isDeleted"
|
||||
size="mini"
|
||||
@change="changeDeleteStatus($event, item)"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="item.prefetchInstanceCount>0 && item.prefetchInstanceCount<item.instanceCount">
|
||||
<el-progress :percentage="parseInt(((item.prefetchInstanceCount/item.instanceCount)*100).toFixed(2))" />
|
||||
</div>
|
||||
<div v-if="item.prefetchInstanceCount>0 && item.prefetchInstanceCount<item.instanceCount * 100">
|
||||
<el-progress :percentage="parseInt((item.prefetchInstanceCount/item.instanceCount).toFixed(2))" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -153,10 +191,12 @@ export default {
|
||||
showDelete: false,
|
||||
loading: false,
|
||||
imageList: [],
|
||||
showSeriesList: []
|
||||
showSeriesList: [],
|
||||
currentLoadIns: []
|
||||
}
|
||||
},
|
||||
created: function() {
|
||||
requestPoolManager.resetRequestPool()
|
||||
this.type = this.$router.currentRoute.query.type ? this.$router.currentRoute.query.type : ''
|
||||
|
||||
this.visitNum = this.$router.currentRoute.query.visitNum ? parseInt(this.$router.currentRoute.query.visitNum) : 0
|
||||
@@ -177,9 +217,18 @@ export default {
|
||||
} else if (this.type === 'Share') {
|
||||
this.loadStudy()
|
||||
}
|
||||
cornerstone.events.addEventListener('cornerstoneimageloadprogress', this.cornerstoneimageloadprogress)
|
||||
window.addEventListener('beforeunload', e => {
|
||||
cornerstone.imageCache.purgeCache()
|
||||
requestPoolManager.resetRequestPool()
|
||||
})
|
||||
},
|
||||
beforeDestroy() {
|
||||
requestPoolManager.stopTaskTimer()
|
||||
window.removeEventListener('beforeunload', e => {
|
||||
cornerstone.imageCache.purgeCache()
|
||||
requestPoolManager.resetRequestPool()
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
loadStudy() {
|
||||
@@ -201,16 +250,16 @@ export default {
|
||||
if (data.IsSuccess) {
|
||||
const { Result } = data
|
||||
var seriesList = []
|
||||
Result.forEach(function(item) {
|
||||
Result.forEach((item, index) => {
|
||||
const imageIds = []
|
||||
// item.InstanceList.forEach(function(id) {
|
||||
// imageIds.push(`wadouri:/api/instance/content/${id}`)
|
||||
// })
|
||||
// item.InstanceList.forEach((id) => {
|
||||
// imageIds.push(`wadouri:http://123.56.94.154:7000/instance/content/${id}`)
|
||||
// })
|
||||
item.InstancePathList.forEach((path) => {
|
||||
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? scope.OSSclientConfig.basePath : scope.OSSclientConfig.basePath}${path}`)
|
||||
item.InstanceInfoList.forEach(i => {
|
||||
if (i.NumberOfFrames && i.NumberOfFrames > 1) {
|
||||
for (let j = 0; j < i.NumberOfFrames; j++) {
|
||||
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? scope.OSSclientConfig.basePath : scope.OSSclientConfig.basePath}${i.Path}?frame=${j}&instanceId=${i.Id}&seriesIndex=${index}`)
|
||||
}
|
||||
} else {
|
||||
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? scope.OSSclientConfig.basePath : scope.OSSclientConfig.basePath}${i.Path}?instanceId=${i.Id}&seriesIndex=${index}`)
|
||||
}
|
||||
})
|
||||
var subjectVisitId = scope.$router.currentRoute.query.subjectVisitId
|
||||
var studyId = scope.$router.currentRoute.query.studyId
|
||||
@@ -220,6 +269,7 @@ export default {
|
||||
subjectVisitId,
|
||||
studyId,
|
||||
imageIds: imageIds,
|
||||
instanceInfoList: item.InstanceInfoList,
|
||||
seriesId: item.Id,
|
||||
seriesUid: item.SeriesInstanceUid,
|
||||
seriesNumber: item.SeriesNumber,
|
||||
@@ -235,7 +285,8 @@ export default {
|
||||
keySeries: item.KeySeries,
|
||||
tpCode: scope.tpCode,
|
||||
loadStatus: false,
|
||||
imageloadedArr: []
|
||||
imageloadedArr: [],
|
||||
isExistMutiFrames: item.IsExistMutiFrames
|
||||
})
|
||||
})
|
||||
scope.seriesList = seriesList
|
||||
@@ -261,29 +312,34 @@ export default {
|
||||
getInstanceList(seriesId).then(res => {
|
||||
if (!res.Result || (res.Result && res.Result.length === 0)) return
|
||||
var seriesInstanceUid = res.Result[0].SeriesInstanceUid
|
||||
var sliceLocation = res.Result[0].SliceLocation
|
||||
var sliceThickness = res.Result[0].SliceThickness
|
||||
var isReading = res.Result[0].IsReading
|
||||
var isDeleted = res.Result[0].IsDeleted
|
||||
var seriesList = []
|
||||
var imageIds = []
|
||||
let isExistMutiFrames = false
|
||||
const instanceInfoList = []
|
||||
res.Result.forEach(instance => {
|
||||
if (instance.NumberOfFrames > 1) {
|
||||
for (let i = 0; i < instance.NumberOfFrames; i++) {
|
||||
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${instance.Path}?frame=${i}`)
|
||||
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${instance.Path}?frame=${i}&instanceId=${instance.Id}&seriesIndex=0`)
|
||||
}
|
||||
isExistMutiFrames = true
|
||||
} else {
|
||||
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${instance.Path}`)
|
||||
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${instance.Path}?instanceId=${instance.Id}&seriesIndex=0`)
|
||||
}
|
||||
instanceInfoList.push({ Id: instance.Id, InstanceNumber: instance.InstanceNumber, NumberOfFrames: instance.NumberOfFrames, Path: instance.Path })
|
||||
})
|
||||
seriesList.push({
|
||||
trialId,
|
||||
subjectVisitId,
|
||||
studyId,
|
||||
imageIds: imageIds,
|
||||
instanceInfoList,
|
||||
seriesId: seriesId,
|
||||
seriesUid: seriesInstanceUid,
|
||||
seriesNumber: seriesNumber,
|
||||
sliceThickness: sliceLocation,
|
||||
sliceThickness: sliceThickness,
|
||||
modality: this.modality,
|
||||
description: this.description,
|
||||
isReading,
|
||||
@@ -292,7 +348,8 @@ export default {
|
||||
instanceCount: res.Result.length,
|
||||
prefetchInstanceCount: 0,
|
||||
loadStatus: false,
|
||||
imageloadedArr: []
|
||||
imageloadedArr: [],
|
||||
isExistMutiFrames: isExistMutiFrames
|
||||
})
|
||||
this.seriesList = seriesList
|
||||
if (this.seriesList.length > 0) {
|
||||
@@ -316,21 +373,37 @@ export default {
|
||||
this.$refs.dicomViewer.loadImageStack(this.seriesList[seriesIndex])
|
||||
if (!series.loadStatus) {
|
||||
requestPoolManager.changePriority(series.seriesId)
|
||||
// var isAddToTakPool = false
|
||||
// if (this.showSeriesList.includes(`${seriesIndex}`)) {
|
||||
// isAddToTakPool = true
|
||||
// } else {
|
||||
// this.showSeriesList.push(`${seriesIndex}`)
|
||||
// }
|
||||
// if (!isAddToTakPool) {
|
||||
// var priority = parseInt(new Date().getTime())
|
||||
// series.isLoading = true
|
||||
// series.imageIds.map((imageId) => {
|
||||
// this.imageList.push({ imageId: imageId, seriesId: series.seriesId, priority })
|
||||
// })
|
||||
// } else {
|
||||
// requestPoolManager.changePriority(series.seriesId)
|
||||
// }
|
||||
}
|
||||
},
|
||||
showMultiFrames(series, seriesIndex, instanceInfo) {
|
||||
this.currentSeriesIndex = seriesIndex
|
||||
const imageIds = []
|
||||
if (instanceInfo.NumberOfFrames && instanceInfo.NumberOfFrames > 1) {
|
||||
for (let j = 0; j < instanceInfo.NumberOfFrames; j++) {
|
||||
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${instanceInfo.Path}?frame=${j}&instanceId=${instanceInfo.Id}&seriesIndex=${seriesIndex}`)
|
||||
}
|
||||
} else {
|
||||
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${instanceInfo.Path}?instanceId=${instanceInfo.Id}&seriesIndex=${seriesIndex}`)
|
||||
}
|
||||
const seriesInfo = {
|
||||
trialId: series.trialId,
|
||||
subjectVisitId: series.subjectVisitId,
|
||||
studyId: series.studyId,
|
||||
imageIds: imageIds,
|
||||
seriesId: series.seriesId,
|
||||
seriesUid: series.seriesUid,
|
||||
seriesNumber: series.seriesNumber,
|
||||
sliceThickness: series.sliceThickness,
|
||||
modality: series.modality,
|
||||
description: series.description,
|
||||
isReading: series.isReading,
|
||||
isDeleted: series.isDeleted,
|
||||
previewImageUrl: series.previewImageUrl,
|
||||
instanceCount: series.instanceCount
|
||||
}
|
||||
this.$refs.dicomViewer.loadImageStack(seriesInfo)
|
||||
if (!series.loadStatus) {
|
||||
requestPoolManager.changePriority(series.seriesId)
|
||||
}
|
||||
},
|
||||
initStudy() {
|
||||
@@ -403,6 +476,7 @@ export default {
|
||||
data.isReading = true
|
||||
}
|
||||
var message = this.$t('trials:audit:message:changeSeriesStatus').replace('xxx', statusStr)
|
||||
message = message.replace('yyy', this.$fd('YesOrNo', !data.isReading))
|
||||
this.$confirm(message, {
|
||||
distinguishCancelAndClose: true,
|
||||
type: 'warning'
|
||||
@@ -430,6 +504,7 @@ export default {
|
||||
data.isDeleted = true
|
||||
}
|
||||
var message = this.$t('trials:audit:message:changeSeriesStatus').replace('xxx', statusStr)
|
||||
message = message.replace('yyy', this.$fd('YesOrNo', !data.isDeleted))
|
||||
this.$confirm(message, {
|
||||
distinguishCancelAndClose: true,
|
||||
type: 'warning'
|
||||
@@ -451,31 +526,44 @@ export default {
|
||||
}).catch(() => {})
|
||||
},
|
||||
loadAllImages() {
|
||||
const seriesIndex = this.seriesList.findIndex(i => i.loadStatus === false)
|
||||
if (seriesIndex === -1) return
|
||||
const series = this.seriesList[seriesIndex]
|
||||
var priority = new Date().getTime()
|
||||
this.seriesList.forEach((series, index) => {
|
||||
series.imageIds.forEach(imageId => {
|
||||
for (let i = 0; i < series.imageIds.length; i++) {
|
||||
const imageId = series.imageIds[i]
|
||||
if (series.isExistMutiFrames) {
|
||||
const params = this.getInstanceInfo(imageId)
|
||||
if (params.frame && params.frame > 0) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
var p = null
|
||||
if (this.firstInstanceId === imageId) {
|
||||
p = priority * 100
|
||||
} else {
|
||||
p = priority - 1
|
||||
}
|
||||
// this.load(imageId, series.seriesId, priority)
|
||||
this.imageList.push({ imageId: imageId, seriesId: series.seriesId, seriesIndex: index, priority: p })
|
||||
})
|
||||
})
|
||||
this.imageList.push({ imageId: imageId, seriesId: series.seriesId, seriesIndex: seriesIndex, priority: p })
|
||||
}
|
||||
if (this.imageList.length > 0) {
|
||||
this.loopLoad()
|
||||
}
|
||||
},
|
||||
getInstanceInfo(imageId) {
|
||||
const params = {}
|
||||
const searchParams = new URLSearchParams(imageId.split('?')[1])
|
||||
for (const [key, value] of searchParams.entries()) {
|
||||
params[key] = value
|
||||
}
|
||||
return params
|
||||
},
|
||||
loopLoad() {
|
||||
if (this.imageList.length > 0) {
|
||||
requestPoolManager.startTaskTimer()
|
||||
console.log('loopLoad')
|
||||
this.imageList.map(image => {
|
||||
requestPoolManager.loadAndCacheImagePlus(image.imageId, image.seriesId, image.priority).then(res => {
|
||||
this.imageLoaded(image, res.data.string('x0020000e'))
|
||||
})
|
||||
requestPoolManager.loadAndCacheImagePlus(image.imageId, image.seriesId, image.priority)
|
||||
})
|
||||
requestPoolManager.sortTaskPool()
|
||||
this.imageList = []
|
||||
@@ -558,6 +646,45 @@ export default {
|
||||
|
||||
return 0
|
||||
},
|
||||
cornerstoneimageloadprogress(e) {
|
||||
const imageId = e.detail.imageId
|
||||
const percentComplete = e.detail.percentComplete
|
||||
const params = {}
|
||||
const searchParams = new URLSearchParams(imageId.split('?')[1])
|
||||
for (const [key, value] of searchParams.entries()) {
|
||||
params[key] = value
|
||||
}
|
||||
if (this.visitTaskId === params.visitTaskId) {
|
||||
const seriesIndex = params.seriesIndex
|
||||
var prefetchInstanceCount = this.seriesList[seriesIndex].prefetchInstanceCount
|
||||
var instanceCount = this.seriesList[seriesIndex].instanceCount
|
||||
if (this.seriesList[seriesIndex].imageloadedArr.indexOf(imageId) < 0) {
|
||||
const i = this.currentLoadIns.findIndex(i => i.imageId === imageId)
|
||||
if (i > -1) {
|
||||
prefetchInstanceCount = prefetchInstanceCount - this.currentLoadIns[i].percentComplete + percentComplete
|
||||
this.currentLoadIns[i].percentComplete = percentComplete
|
||||
if (percentComplete === 100) {
|
||||
this.currentLoadIns.splice(i, 1)
|
||||
}
|
||||
} else {
|
||||
if (percentComplete !== 100) {
|
||||
this.currentLoadIns.push({ imageId, percentComplete })
|
||||
}
|
||||
prefetchInstanceCount = prefetchInstanceCount + percentComplete
|
||||
}
|
||||
this.seriesList[seriesIndex].prefetchInstanceCount = prefetchInstanceCount
|
||||
if (percentComplete >= 100) {
|
||||
this.seriesList[seriesIndex].imageloadedArr.push(imageId)
|
||||
}
|
||||
}
|
||||
if (prefetchInstanceCount >= instanceCount * 100) {
|
||||
this.seriesList[seriesIndex].prefetchInstanceCount = instanceCount * 100
|
||||
// 设置当前序列状态为已下载完成
|
||||
this.seriesList[seriesIndex].loadStatus = true
|
||||
this.loadAllImages()
|
||||
}
|
||||
}
|
||||
},
|
||||
cornerstoneImageLoaded(e) {
|
||||
if (this.firstInstanceId === e.detail.image.imageId && !this.isStartLoad) {
|
||||
// 初始化图像加载完成时,自动下载
|
||||
@@ -751,6 +878,29 @@ export default {
|
||||
color: #D0D0D0;
|
||||
font-size: 13px;
|
||||
}
|
||||
.instance_frame_wrapper{
|
||||
min-width: 120px;
|
||||
background-color: #2c2c2c;
|
||||
border: 1px solid #2c2c2c;
|
||||
padding: 5px;
|
||||
}
|
||||
.frame_content{
|
||||
height: 50px;
|
||||
padding: 5px;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
color: #ddd;
|
||||
font-size: 12px;
|
||||
border: 1px solid #404040;
|
||||
}
|
||||
.frame_content:hover {
|
||||
/* font-weight: bold; */
|
||||
/* box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); */
|
||||
cursor: pointer;
|
||||
/* color: #428bca; */
|
||||
border-color: #213a54 !important;
|
||||
background-color: #213a54;
|
||||
}
|
||||
/* .viewerRightSidePanel {
|
||||
width: 300px;
|
||||
height: 100%;
|
||||
|
||||
@@ -46,13 +46,6 @@
|
||||
@click="showSeriesImage($event,index,i,series)"
|
||||
>
|
||||
<div class="viewernavigatorwrapper">
|
||||
<!-- <el-image
|
||||
class="image-preview"
|
||||
style="height:72px;width:72px;"
|
||||
:src="series.previewImageUrl"
|
||||
fit="fill"
|
||||
/> -->
|
||||
|
||||
<img
|
||||
class="image-preview"
|
||||
:src="series.previewImageUrl"
|
||||
@@ -62,8 +55,41 @@
|
||||
fit="fill"
|
||||
>
|
||||
<div class="viewernavitextwrapper">
|
||||
<div style="padding: 1px;">
|
||||
#{{ series.seriesNumber }}
|
||||
<div style="padding: 1px 5px 1px 1px;display: flex;justify-content: space-between;">
|
||||
<div>#{{ series.seriesNumber }}</div>
|
||||
<div v-if="series.isExistMutiFrames && series.instanceCount > 1">
|
||||
<el-popover
|
||||
placement="right"
|
||||
trigger="hover"
|
||||
popper-class="instance_frame_wrapper"
|
||||
>
|
||||
<div
|
||||
v-for="(instance, idx) in series.instanceInfoList"
|
||||
:key="instance.Id"
|
||||
class="frame_content"
|
||||
:style="{'margin-bottom':idx<series.instanceInfoList.length-1? '5px':'0px'}"
|
||||
@click="showMultiFrames(index,series, i, instance)"
|
||||
>
|
||||
<!-- <div>
|
||||
<img
|
||||
class="image-preview"
|
||||
:src="series.previewImageUrl"
|
||||
crossorigin="anonymous"
|
||||
alt=""
|
||||
style="width: 40px;height:40px;"
|
||||
fit="fill"
|
||||
>
|
||||
</div> -->
|
||||
<div>
|
||||
<div>{{ instance.InstanceNumber }}</div>
|
||||
<div>{{ `${instance.NumberOfFrames > 0 ? instance.NumberOfFrames : 1} frame` }}</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<i slot="reference" class="el-icon-connection" style="font-size: 15px;cursor: pointer;" />
|
||||
</el-popover>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div v-show="series.InstanceCount" style="padding: 1px;">
|
||||
{{ series.modality }}: {{ series.instanceCount }} image
|
||||
@@ -78,20 +104,22 @@
|
||||
</div>
|
||||
</el-tooltip>
|
||||
<div style="padding: 1px;">
|
||||
{{ series.prefetchInstanceCount }}/{{ series.instanceCount }}
|
||||
{{ series.imageloadedArr.length }}/{{ series.instanceCount }}
|
||||
</div>
|
||||
<div />
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="showDelete" style="display: flex;flex-direction: row;justify-content: space-between;" @click.stop="">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="showDelete" @click.stop="">
|
||||
|
||||
<div>
|
||||
<span style="font-size: 12px;">{{ $t('trials:audit:table:isReading') }}</span>
|
||||
<el-switch
|
||||
v-model="series.isReading"
|
||||
size="mini"
|
||||
@change="changeReadingStatus($event, series)"
|
||||
/>
|
||||
|
||||
</div>
|
||||
<div>
|
||||
<span style="font-size: 12px;">{{ $t('trials:audit:table:isDelete') }}</span>
|
||||
<el-switch
|
||||
v-model="series.isDeleted"
|
||||
@@ -99,11 +127,12 @@
|
||||
@change="changeDeleteStatus($event, series)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div style="position: absolute;bottom: -10px;left: 0;width: 100%;">
|
||||
<el-progress v-if="series.prefetchInstanceCount>0 && series.prefetchInstanceCount<series.instanceCount" :percentage="Number(series.prefetchInstanceCount/series.instanceCount)*100" />
|
||||
</div> -->
|
||||
<div v-if="series.prefetchInstanceCount>0 && series.prefetchInstanceCount<series.instanceCount">
|
||||
<el-progress :percentage="parseInt(((series.prefetchInstanceCount/series.instanceCount)*100).toFixed(2))" />
|
||||
<div v-if="series.prefetchInstanceCount>0 && series.prefetchInstanceCount<series.instanceCount * 100">
|
||||
<el-progress :percentage="parseInt((series.prefetchInstanceCount/series.instanceCount).toFixed(2))" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -117,7 +146,7 @@
|
||||
<el-tab-pane :label="$t('trials:dicom-show:relatedVisit')" name="relation-study" class="pane-relation-wrapper">
|
||||
<div class="viewerSidethumbinner">
|
||||
<el-collapse v-model="relationActiveName" @change="handelRelationActiveChange">
|
||||
<el-collapse-item v-for="(study) in relationStudyList" :key="`${study.StudyId}`" :name="`${study.StudyId}`">
|
||||
<el-collapse-item v-for="(study,studyIndex) in relationStudyList" :key="`${study.StudyId}`" :name="`${study.StudyId}`">
|
||||
<template slot="title">
|
||||
|
||||
<div class="text-desc">
|
||||
@@ -160,11 +189,44 @@
|
||||
>
|
||||
|
||||
<div class="viewernavitextwrapper">
|
||||
<div v-if="seriesItem.keySeries" style="padding: 1px;color:red">
|
||||
<div style="padding: 1px 5px 1px 1px;display: flex;justify-content: space-between;">
|
||||
<div v-if="seriesItem.keySeries" style="color:red">
|
||||
Key Images
|
||||
</div>
|
||||
<div v-else style="padding: 1px;">
|
||||
#{{ seriesItem.seriesNumber }}
|
||||
<div v-else>#{{ seriesItem.seriesNumber }}</div>
|
||||
<div v-if="seriesItem.isExistMutiFrames && seriesItem.instanceCount > 1">
|
||||
<el-popover
|
||||
placement="right"
|
||||
trigger="hover"
|
||||
popper-class="instance_frame_wrapper"
|
||||
>
|
||||
<div
|
||||
v-for="(instance, idx) in seriesItem.instanceInfoList"
|
||||
:key="instance.Id"
|
||||
class="frame_content"
|
||||
:style="{'margin-bottom':idx<seriesItem.instanceInfoList.length-1? '5px':'0px'}"
|
||||
@click="showMultiFrames(studyIndex,seriesItem, index, instance)"
|
||||
>
|
||||
<!-- <div>
|
||||
<img
|
||||
class="image-preview"
|
||||
:src="series.previewImageUrl"
|
||||
crossorigin="anonymous"
|
||||
alt=""
|
||||
style="width: 40px;height:40px;"
|
||||
fit="fill"
|
||||
>
|
||||
</div> -->
|
||||
<div>
|
||||
<div>{{ instance.InstanceNumber }}</div>
|
||||
<div>{{ `${instance.NumberOfFrames > 0 ? instance.NumberOfFrames : 1} frame` }}</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<i slot="reference" class="el-icon-connection" style="font-size: 15px;cursor: pointer;" />
|
||||
</el-popover>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div v-show="seriesItem.instanceCount" style="padding: 1px;">
|
||||
{{ seriesItem.modality }}: {{ seriesItem.instanceCount }} image
|
||||
@@ -177,7 +239,6 @@
|
||||
{{ seriesItem.description }}
|
||||
</div>
|
||||
</el-tooltip>
|
||||
|
||||
</div>
|
||||
<!-- <div style="position: absolute;bottom: -10px;left: 0;width: 100%;">
|
||||
<el-progress v-if="seriesItem.prefetchInstanceCount>0 && seriesItem.prefetchInstanceCount<seriesItem.instanceCount" :percentage="Number(seriesItem.prefetchInstanceCount/seriesItem.instanceCount)*100" />
|
||||
@@ -234,10 +295,13 @@ export default {
|
||||
imageList: [],
|
||||
activeNames: [],
|
||||
relationActiveName: [],
|
||||
showSeriesList: []
|
||||
showSeriesList: [],
|
||||
currentLoadIns: []
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
requestPoolManager.resetRequestPool()
|
||||
document.documentElement.style.userSelect = 'none'
|
||||
if (this.$router.currentRoute.query.TokenKey) {
|
||||
store.dispatch('user/setToken', this.$router.currentRoute.query.TokenKey)
|
||||
changeURLStatic('TokenKey', '')
|
||||
@@ -250,16 +314,25 @@ export default {
|
||||
this.showDelete = parseInt(this.$router.currentRoute.query.showDelete)
|
||||
// cornerstone.events.addEventListener('cornerstoneimageloaded', this.cornerstoneImageLoaded)
|
||||
this.getStudiesInfo()
|
||||
cornerstone.events.addEventListener('cornerstoneimageloadprogress', this.cornerstoneimageloadprogress)
|
||||
window.addEventListener('beforeunload', e => {
|
||||
cornerstone.imageCache.purgeCache()
|
||||
requestPoolManager.resetRequestPool()
|
||||
})
|
||||
},
|
||||
beforeDestroy() {
|
||||
requestPoolManager.stopTaskTimer()
|
||||
window.removeEventListener('beforeunload', e => {
|
||||
cornerstone.imageCache.purgeCache()
|
||||
requestPoolManager.resetRequestPool()
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
// 获取某个访视下所有的检查信息
|
||||
getStudiesInfo() {
|
||||
this.studyList = []
|
||||
getVisitStudyList(this.trialId, this.subjectVisitId, this.isReading).then(res => {
|
||||
res.Result.forEach((study) => {
|
||||
res.Result.forEach((study,studyIndex) => {
|
||||
const data = {}
|
||||
data.StudyId = study.StudyId
|
||||
data.StudyCode = study.StudyCode
|
||||
@@ -269,23 +342,23 @@ export default {
|
||||
data.InstanceCount = study.InstanceCount
|
||||
data.PreviewImageCount = 0
|
||||
var seriesList = []
|
||||
study.SeriesList.forEach((series) => {
|
||||
study.SeriesList.forEach((series,seriesIndex) => {
|
||||
const imageIds = []
|
||||
|
||||
// series.InstanceList.forEach((id) => {
|
||||
// imageIds.push(`wadouri:/api/instance/content/${id}`)
|
||||
// })
|
||||
// series.InstanceList.forEach((id) => {
|
||||
// imageIds.push(`wadouri:http://123.56.94.154:7000/instance/content/${id}`)
|
||||
// })
|
||||
series.InstancePathList.forEach((path) => {
|
||||
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${path}`)
|
||||
series.InstanceInfoList.forEach(i => {
|
||||
if (i.NumberOfFrames && i.NumberOfFrames > 1) {
|
||||
for (let j = 0; j < i.NumberOfFrames; j++) {
|
||||
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${i.Path}?frame=${j}&instanceId=${i.Id}&idx=${studyIndex}|${seriesIndex}`)
|
||||
}
|
||||
} else {
|
||||
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${i.Path}?instanceId=${i.Id}&idx=${studyIndex}|${seriesIndex}`)
|
||||
}
|
||||
})
|
||||
seriesList.push({
|
||||
trialId: this.trialId,
|
||||
subjectVisitId: this.subjectVisitId,
|
||||
studyId: study.StudyId,
|
||||
imageIds: imageIds,
|
||||
instanceInfoList: series.InstanceInfoList,
|
||||
seriesId: series.Id,
|
||||
seriesUid: series.SeriesInstanceUid,
|
||||
seriesNumber: series.SeriesNumber,
|
||||
@@ -298,7 +371,8 @@ export default {
|
||||
instanceCount: series.InstanceCount,
|
||||
prefetchInstanceCount: 0,
|
||||
loadStatus: false,
|
||||
imageloadedArr: []
|
||||
imageloadedArr: [],
|
||||
isExistMutiFrames: series.IsExistMutiFrames
|
||||
})
|
||||
})
|
||||
data.SeriesList = seriesList
|
||||
@@ -326,21 +400,37 @@ export default {
|
||||
this.$refs.dicomViewer.loadImageStack(this.studyList[studyIndex].SeriesList[seriesIndex])
|
||||
if (!series.loadStatus) {
|
||||
requestPoolManager.changePriority(series.seriesId)
|
||||
// var isAddToTakPool = false
|
||||
// if (this.showSeriesList.includes(`${studyIndex}_${seriesIndex}`)) {
|
||||
// isAddToTakPool = true
|
||||
// } else {
|
||||
// this.showSeriesList.push(`${studyIndex}_${seriesIndex}`)
|
||||
// }
|
||||
// if (!isAddToTakPool) {
|
||||
// var priority = parseInt(new Date().getTime())
|
||||
// series.isLoading = true
|
||||
// series.imageIds.map((imageId, i) => {
|
||||
// this.imageList.push({ imageId: imageId, seriesId: series.seriesId, priority })
|
||||
// })
|
||||
// } else {
|
||||
// requestPoolManager.changePriority(series.seriesId)
|
||||
// }
|
||||
}
|
||||
},
|
||||
showMultiFrames(studyIndex,series, seriesIndex, instanceInfo) {
|
||||
this.currentSeriesIndex = seriesIndex
|
||||
const imageIds = []
|
||||
if (instanceInfo.NumberOfFrames && instanceInfo.NumberOfFrames > 1) {
|
||||
for (let j = 0; j < instanceInfo.NumberOfFrames; j++) {
|
||||
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${instanceInfo.Path}?frame=${j}&instanceId=${instanceInfo.Id}&idx=${studyIndex}|${seriesIndex}`)
|
||||
}
|
||||
} else {
|
||||
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${instanceInfo.Path}?instanceId=${instanceInfo.Id}&idx=${studyIndex}|${seriesIndex}`)
|
||||
}
|
||||
const seriesInfo = {
|
||||
trialId: series.trialId,
|
||||
subjectVisitId: series.subjectVisitId,
|
||||
studyId: series.studyId,
|
||||
imageIds: imageIds,
|
||||
seriesId: series.seriesId,
|
||||
seriesUid: series.seriesUid,
|
||||
seriesNumber: series.seriesNumber,
|
||||
sliceThickness: series.sliceThickness,
|
||||
modality: series.modality,
|
||||
description: series.description,
|
||||
isReading: series.isReading,
|
||||
isDeleted: series.isDeleted,
|
||||
previewImageUrl: series.previewImageUrl,
|
||||
instanceCount: series.instanceCount
|
||||
}
|
||||
this.$refs.dicomViewer.loadImageStack(seriesInfo)
|
||||
if (!series.loadStatus) {
|
||||
requestPoolManager.changePriority(series.seriesId)
|
||||
}
|
||||
},
|
||||
changeReadingStatus(callback, data) {
|
||||
@@ -353,6 +443,7 @@ export default {
|
||||
data.isReading = true
|
||||
}
|
||||
var message = this.$t('trials:audit:message:changeSeriesStatus').replace('xxx', statusStr)
|
||||
message = message.replace('yyy', this.$fd('YesOrNo', !data.isReading))
|
||||
this.$confirm(message, {
|
||||
distinguishCancelAndClose: true,
|
||||
type: 'warning'
|
||||
@@ -380,6 +471,7 @@ export default {
|
||||
data.isDeleted = true
|
||||
}
|
||||
var message = this.$t('trials:audit:message:changeSeriesStatus').replace('xxx', statusStr)
|
||||
message = message.replace('yyy', this.$fd('YesOrNo', !data.isDeleted))
|
||||
this.$confirm(message, {
|
||||
distinguishCancelAndClose: true,
|
||||
type: 'warning'
|
||||
@@ -443,19 +535,20 @@ export default {
|
||||
if (data.Result != null && data.Result.length > 0) {
|
||||
var seriesList = []
|
||||
const res = data.Result
|
||||
res.forEach(function(item) {
|
||||
res.forEach((item,seriesIndex)=> {
|
||||
const imageIds = []
|
||||
// item.InstanceList.forEach(function(id) {
|
||||
// imageIds.push(`wadouri:/api/instance/content/${id}`)
|
||||
// })
|
||||
// item.InstanceList.forEach((id) => {
|
||||
// imageIds.push(`wadouri:http://123.56.94.154:7000/instance/content/${id}`)
|
||||
// })
|
||||
item.InstancePathList.forEach((path) => {
|
||||
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? scope.OSSclientConfig.basePath : scope.OSSclientConfig.basePath}${path}`)
|
||||
item.InstanceInfoList.forEach(i => {
|
||||
if (i.NumberOfFrames && i.NumberOfFrames > 1) {
|
||||
for (let j = 0; j < i.NumberOfFrames; j++) {
|
||||
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? scope.OSSclientConfig.basePath : scope.OSSclientConfig.basePath}${i.Path}?frame=${j}&instanceId=${i.Id}&idx=${index}|${seriesIndex}`)
|
||||
}
|
||||
} else {
|
||||
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? scope.OSSclientConfig.basePath : scope.OSSclientConfig.basePath}${i.Path}?instanceId=${i.Id}&idx=${index}|${seriesIndex}`)
|
||||
}
|
||||
})
|
||||
seriesList.push({
|
||||
imageIds: imageIds,
|
||||
instanceInfoList: item.InstanceInfoList,
|
||||
seriesId: item.Id,
|
||||
seriesUid: item.SeriesInstanceUid,
|
||||
seriesNumber: item.SeriesNumber,
|
||||
@@ -468,7 +561,8 @@ export default {
|
||||
hasLabel: item.HasLabel,
|
||||
keySeries: item.KeySeries,
|
||||
loadStatus: false,
|
||||
imageloadedArr: []
|
||||
imageloadedArr: [],
|
||||
isExistMutiFrames: item.IsExistMutiFrames
|
||||
})
|
||||
})
|
||||
scope.relationStudyList[index].seriesCount = seriesList.length
|
||||
@@ -497,54 +591,50 @@ export default {
|
||||
}
|
||||
},
|
||||
loadAllImages() {
|
||||
var seriesList = this.studyList.map(s => s.SeriesList).flat()
|
||||
const seriesIndex = seriesList.findIndex(i => i.loadStatus === false)
|
||||
if (seriesIndex === -1) return
|
||||
const series = seriesList[seriesIndex]
|
||||
var priority = parseInt(new Date().getTime())
|
||||
this.studyList.map((study, studyIndex) => {
|
||||
study.SeriesList.map((series, seriesIndex) => {
|
||||
series.imageIds.map(imageId => {
|
||||
for (let i = 0; i < series.imageIds.length; i++) {
|
||||
const imageId = series.imageIds[i]
|
||||
if (series.isExistMutiFrames) {
|
||||
const params = this.getInstanceInfo(imageId)
|
||||
if (params.frame && params.frame > 0) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
var p = null
|
||||
if (this.firstInstanceId === imageId) {
|
||||
p = priority * 100
|
||||
} else {
|
||||
p = priority - 1
|
||||
}
|
||||
this.imageList.push({ imageId: imageId, seriesId: series.seriesId, studyIndex, seriesIndex, priority: p })
|
||||
})
|
||||
// if (!series.loadStatus && series.seriesId !== this.firstSeriesId) {
|
||||
// series.imageIds.map(imageId => {
|
||||
// // imageIds.push({ imageId: image, seriesId: series.seriesId, priority })
|
||||
// this.imageList.push({ imageId: imageId, seriesId: series.seriesId, studyIndex, seriesIndex, priority })
|
||||
// })
|
||||
// }
|
||||
})
|
||||
})
|
||||
this.imageList.push({ imageId: imageId, seriesId: series.seriesId, seriesIndex: seriesIndex, priority: p })
|
||||
}
|
||||
if (this.imageList.length > 0) {
|
||||
this.loopLoad()
|
||||
}
|
||||
// requestPoolManager.setPendingList(imageIds)
|
||||
},
|
||||
getInstanceInfo(imageId) {
|
||||
const params = {}
|
||||
const searchParams = new URLSearchParams(imageId.split('?')[1])
|
||||
for (const [key, value] of searchParams.entries()) {
|
||||
params[key] = value
|
||||
}
|
||||
return params
|
||||
},
|
||||
loopLoad() {
|
||||
if (this.imageList.length > 0) {
|
||||
requestPoolManager.startTaskTimer()
|
||||
this.imageList.map(image => {
|
||||
requestPoolManager.loadAndCacheImagePlus(image.imageId, image.seriesId, image.priority).then(res => {
|
||||
this.imageLoaded(image, res.data.string('x0020000e'))
|
||||
})
|
||||
requestPoolManager.loadAndCacheImagePlus(image.imageId, image.seriesId, image.priority)
|
||||
})
|
||||
requestPoolManager.sortTaskPool()
|
||||
this.imageList = []
|
||||
}
|
||||
},
|
||||
load(imageId, seriesId, priority = 999) {
|
||||
return new Promise((resolve, reject) => {
|
||||
requestPoolManager.loadAndCacheImagePlus(imageId, seriesId, priority).then(res => {
|
||||
if (!res) return
|
||||
this.imageLoaded(imageId, res.data.string('x0020000e'))
|
||||
resolve(res)
|
||||
}).catch(e => {
|
||||
reject(e)
|
||||
})
|
||||
})
|
||||
},
|
||||
// load(imageId, priority = 999) {
|
||||
// return new Promise((resolve, reject) => {
|
||||
// const imageTask = this.buildImageRequestTask(imageId, { priority })
|
||||
@@ -587,47 +677,43 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
// instance下载成功回调
|
||||
cornerstoneImageLoaded(e) {
|
||||
if (e.detail.image.imageId.includes(this.firstInstanceId) && !this.isStartLoad) {
|
||||
// 初始化图像加载完成时,自动下载
|
||||
this.loadAllImages()
|
||||
this.isStartLoad = true
|
||||
// requestPoolManager.executeTask()
|
||||
cornerstoneimageloadprogress(e){
|
||||
const imageId = e.detail.imageId
|
||||
const percentComplete = e.detail.percentComplete
|
||||
const params = {}
|
||||
const searchParams = new URLSearchParams(imageId.split('?')[1])
|
||||
for (const [key, value] of searchParams.entries()) {
|
||||
params[key] = value
|
||||
}
|
||||
const uri = e.detail.image.sharedCacheKey
|
||||
const index = this.cachedImages.findIndex(item => item.uri === uri)
|
||||
if (index === -1) {
|
||||
this.cachedImages.push({ uri: uri, timestamp: new Date().getTime() })
|
||||
} else {
|
||||
this.cachedImages[index].timestamp = new Date().getTime()
|
||||
}
|
||||
var imageId = e.detail.image.imageId
|
||||
var seriesUid = e.detail.image.data.string('x0020000e')
|
||||
var studyIndex = -1
|
||||
var seriesIndex = -1
|
||||
for (let i = 0; i < this.studyList.length; ++i) {
|
||||
for (let j = 0; j < this.studyList[i].SeriesList.length; ++j) {
|
||||
if (this.studyList[i].SeriesList[j].seriesUid === seriesUid) {
|
||||
studyIndex = i
|
||||
seriesIndex = j
|
||||
break
|
||||
}
|
||||
}
|
||||
if (studyIndex > 0) break
|
||||
}
|
||||
if (seriesIndex < 0) return
|
||||
|
||||
const imageIdIndex = this.studyList[studyIndex].SeriesList[seriesIndex].imageIds.indexOf(imageId)
|
||||
if (imageIdIndex < 0) return
|
||||
if (this.visitTaskId === params.visitTaskId) {
|
||||
const studyIndex = params.idx.split('|')[0]
|
||||
const seriesIndex = params.idx.split('|')[1]
|
||||
var prefetchInstanceCount = this.studyList[studyIndex].SeriesList[seriesIndex].prefetchInstanceCount
|
||||
var instanceCount = this.studyList[studyIndex].SeriesList[seriesIndex].instanceCount
|
||||
if (this.studyList[studyIndex].SeriesList[seriesIndex].imageloadedArr.indexOf(imageId) < 0) {
|
||||
++this.studyList[studyIndex].SeriesList[seriesIndex].prefetchInstanceCount
|
||||
const i = this.currentLoadIns.findIndex(i => i.imageId === imageId)
|
||||
if (i > -1) {
|
||||
prefetchInstanceCount = prefetchInstanceCount - this.currentLoadIns[i].percentComplete + percentComplete
|
||||
this.currentLoadIns[i].percentComplete = percentComplete
|
||||
if (percentComplete === 100) {
|
||||
this.currentLoadIns.splice(i, 1)
|
||||
}
|
||||
} else {
|
||||
if (percentComplete !== 100) {
|
||||
this.currentLoadIns.push({ imageId, percentComplete })
|
||||
}
|
||||
prefetchInstanceCount = prefetchInstanceCount + percentComplete
|
||||
}
|
||||
this.studyList[studyIndex].SeriesList[seriesIndex].prefetchInstanceCount = prefetchInstanceCount
|
||||
if (percentComplete >= 100) {
|
||||
this.studyList[studyIndex].SeriesList[seriesIndex].imageloadedArr.push(imageId)
|
||||
|
||||
if (this.studyList[studyIndex].SeriesList[seriesIndex].prefetchInstanceCount >= this.studyList[studyIndex].SeriesList[seriesIndex].instanceCount) {
|
||||
this.studyList[studyIndex].SeriesList[seriesIndex].prefetchInstanceCount = this.studyList[studyIndex].SeriesList[seriesIndex].instanceCount
|
||||
}
|
||||
}
|
||||
if (prefetchInstanceCount >= instanceCount * 100) {
|
||||
this.studyList[studyIndex].SeriesList[seriesIndex].prefetchInstanceCount = instanceCount * 100
|
||||
// 设置当前序列状态为已下载完成
|
||||
this.studyList[studyIndex].SeriesList[seriesIndex].loadStatus = true
|
||||
this.loadAllImages()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -689,9 +775,9 @@ export default {
|
||||
padding: 5px;
|
||||
/* height: 95%; */
|
||||
height: 99%;
|
||||
overflow: hidden;
|
||||
text-overflow: clip;
|
||||
white-space: nowrap;
|
||||
/* overflow: hidden;
|
||||
text-overflow: clip; */
|
||||
/* white-space: nowrap; */
|
||||
}
|
||||
.viewerContainer .viewerContentWrapper>div {
|
||||
display: inline-block;
|
||||
@@ -808,6 +894,29 @@ export default {
|
||||
height: 40px;
|
||||
line-height: 20px;
|
||||
}
|
||||
.instance_frame_wrapper{
|
||||
min-width: 120px;
|
||||
background-color: #2c2c2c;
|
||||
border: 1px solid #2c2c2c;
|
||||
padding: 5px;
|
||||
}
|
||||
.frame_content{
|
||||
height: 50px;
|
||||
padding: 5px;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
color: #ddd;
|
||||
font-size: 12px;
|
||||
border: 1px solid #404040;
|
||||
}
|
||||
.frame_content:hover {
|
||||
/* font-weight: bold; */
|
||||
/* box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); */
|
||||
cursor: pointer;
|
||||
/* color: #428bca; */
|
||||
border-color: #213a54 !important;
|
||||
background-color: #213a54;
|
||||
}
|
||||
|
||||
/* .viewerRightSidePanel {
|
||||
width: 300px;
|
||||
|
||||
@@ -244,8 +244,7 @@ export default {
|
||||
this.$confirm('是否确认废除此文件?', {
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true,
|
||||
confirmButtonText: 'Ok',
|
||||
cancelButtonText: 'Cancel'
|
||||
|
||||
})
|
||||
.then(() => {
|
||||
this.loading = true
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
<el-table-column prop="ModuleTypeValueCN" label="模块" show-overflow-tooltip align="left" min-width="230px" />
|
||||
<el-table-column prop="Description" label="操作名称" :show-overflow-tooltip="true" min-width="200px">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.Description }}({{scope.row.DescriptionCN}})</span>
|
||||
<span>{{ scope.row.DescriptionCN }}({{scope.row.Description}})</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="DescriptionCN" label="其他" :show-overflow-tooltip="true" min-width="140px">
|
||||
@@ -513,12 +513,27 @@
|
||||
</el-col>
|
||||
<el-col v-show="form.ConfigType === 'C' && title !== '复制' && form.EnumType === 'Dictionary'" :span="12">
|
||||
<el-form-item label="字典表名">
|
||||
<el-input v-model="form.DictionaryCode" placeholder="请输入字典表名" />
|
||||
<!-- <el-input v-model="form.DictionaryCode" placeholder="请输入字典表名" /> -->
|
||||
<el-autocomplete
|
||||
clearable
|
||||
class="inline-input"
|
||||
v-model="form.DictionaryCode"
|
||||
:fetch-suggestions="querySearch"
|
||||
placeholder="请输入字典表名"
|
||||
></el-autocomplete>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col v-show="form.ConfigType === 'C' && title !== '复制' && form.EnumType === 'Dictionary'" :span="12">
|
||||
<el-form-item label="翻译字段">
|
||||
<el-input v-model="form.DictionaryType" placeholder="请输入翻译字段" />
|
||||
<!-- <el-input v-model="form.DictionaryType" placeholder="请输入翻译字段" /> -->
|
||||
<el-select v-model="form.DictionaryType" clearable placeholder="请选择翻译字段">
|
||||
<el-option
|
||||
v-for="item in $d.DictionaryType"
|
||||
:key="item.id"
|
||||
:label="item.label"
|
||||
:value="item.label">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col v-show="form.ConfigType === 'C' && title !== '复制' && form.EnumType === 'Date'" :span="24">
|
||||
@@ -608,11 +623,11 @@
|
||||
<div style="padding: 0 40px;display: flex;flex-direction: column">
|
||||
<div style="text-align: right;height: 50px;">
|
||||
<el-select v-model="copeParams.FromItemId" collapse-tags filterable placeholder="完全拷贝对象" clearable size="small">
|
||||
<el-option v-for="item of list" v-if="drawer_cfg.drawerChild && item.ConfigType === 'M' && item.ObjectTypeId === selectRow.ObjectTypeId && item.OptTypeId && item.ChildrenTypeId " :value="item.Id" :label="item.Description" />
|
||||
<el-option v-for="item of list" v-if="drawer_cfg.drawerChild && item.ConfigType === 'M' && item.ObjectTypeId === selectRow.ObjectTypeId && item.OptTypeId && item.ChildrenTypeId " :value="item.Id" :label="item.DescriptionCN" />
|
||||
</el-select>
|
||||
<el-button type="primary" size="mini" style="margin-right: 10px" @click="handleOverCope(selectRow)">完全拷贝</el-button>
|
||||
<el-select v-model="copeParams.DataSourceGuids" multiple collapse-tags filterable placeholder="拷贝对象" clearable size="small">
|
||||
<el-option v-for="item of list" v-if="drawer_cfg.drawerChild && item.ConfigType === 'M' && item.ObjectTypeId === selectRow.ObjectTypeId && item.OptTypeId && item.ChildrenTypeId " :value="item.Id" :label="item.Description" />
|
||||
<el-option v-for="item of list" v-if="drawer_cfg.drawerChild && item.ConfigType === 'M' && item.ObjectTypeId === selectRow.ObjectTypeId && item.OptTypeId && item.ChildrenTypeId " :value="item.Id" :label="item.DescriptionCN" />
|
||||
</el-select>
|
||||
<el-button type="primary" size="mini" @click="handleCope(selectRow)">拷贝</el-button>
|
||||
<el-button type="primary" size="mini" @click="handleAdd(selectRow)">新建</el-button>
|
||||
@@ -668,6 +683,12 @@
|
||||
<el-table-column prop="TrialConfigRelyFieldName" label="依赖字段" min-width="120px" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="操作" align="center" min-width="180" class-name="small-padding fixed-width">
|
||||
<template slot-scope="scope">
|
||||
<el-button
|
||||
size="mini"
|
||||
type="text"
|
||||
icon="el-icon-edit"
|
||||
@click="handleCopyData(scope.row)"
|
||||
>复制</el-button>
|
||||
<el-button
|
||||
size="mini"
|
||||
type="text"
|
||||
@@ -690,7 +711,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { fullyReplicated, changeFrontAuditSort, copyFrontAuditConfigItem, getFrontAuditConfigList, addOrUpdateFrontAuditConfig, deleteFrontAuditConfig, copyOtherToThisItem, getAuditConfigChildList, setDictionaryValue } from '@/api/dictionary/checkConfig'
|
||||
import { fullyReplicated, changeFrontAuditSort, copyFrontAuditConfigItem, getFrontAuditConfigList, addOrUpdateFrontAuditConfig, deleteFrontAuditConfig, copyOtherToThisItem, getAuditConfigChildList, getDictionaryCodeList } from '@/api/dictionary/checkConfig'
|
||||
import Treeselect from '@riophae/vue-treeselect'
|
||||
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
|
||||
import Sortable from 'sortablejs'
|
||||
@@ -743,13 +764,41 @@ export default {
|
||||
},
|
||||
ChildGroup: null,
|
||||
tableShow: false,
|
||||
rowDrop2TableIsShow: true
|
||||
rowDrop2TableIsShow: true,
|
||||
DictionaryCodeList:[]
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getList()
|
||||
this.getList();
|
||||
this.getDictionaryCodeList();
|
||||
},
|
||||
methods: {
|
||||
querySearch(queryString, cb) {
|
||||
var DictionaryCodeList = this.DictionaryCodeList;
|
||||
var results = queryString ? DictionaryCodeList.filter(this.createFilter(queryString)) : DictionaryCodeList;
|
||||
// 调用 callback 返回建议列表的数据
|
||||
cb(results);
|
||||
},
|
||||
createFilter(queryString) {
|
||||
return (DictionaryCodeList) => {
|
||||
return (DictionaryCodeList.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0);
|
||||
};
|
||||
},
|
||||
// 获取字典表名
|
||||
async getDictionaryCodeList(){
|
||||
try{
|
||||
let res = await getDictionaryCodeList();
|
||||
if(res.IsSuccess){
|
||||
this.DictionaryCodeList = res.Result.map(item=>{
|
||||
return {
|
||||
value:item
|
||||
}
|
||||
});
|
||||
}
|
||||
}catch(err){
|
||||
console.log(err);
|
||||
}
|
||||
},
|
||||
addParameter() {
|
||||
this.form.UrlConfig.ParameterList.push({
|
||||
UrlParameterName: null,
|
||||
@@ -1146,6 +1195,16 @@ export default {
|
||||
this.title = '修改'
|
||||
this.rowDrop2()
|
||||
},
|
||||
handleCopyData (row) {
|
||||
this.$confirm('确定复制该条记录到当前稽查下吗?').then(() => {
|
||||
let params = {...row}
|
||||
delete params.Id
|
||||
addOrUpdateFrontAuditConfig(params).then(() => {
|
||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||
this.getList()
|
||||
})
|
||||
})
|
||||
},
|
||||
/** 提交按钮 */
|
||||
submitForm: function() {
|
||||
this.$refs['form'].validate(valid => {
|
||||
|
||||
@@ -125,18 +125,17 @@ export default {
|
||||
},
|
||||
// 删除字典表配置信息
|
||||
handleDelete(row) {
|
||||
this.$confirm('Sure to delete?', {
|
||||
this.$confirm(this.$t('trials:uploadedDicoms:message:deleteMes'), {
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true,
|
||||
confirmButtonText: 'Ok',
|
||||
cancelButtonText: 'Cancel'
|
||||
|
||||
})
|
||||
.then(() => {
|
||||
deleteDictionary(row.Id)
|
||||
.then(res => {
|
||||
if (res.IsSuccess) {
|
||||
this.list.splice(this.list.findIndex(item => item.Id === row.Id), 1)
|
||||
this.$message.success('Deleted successfully!')
|
||||
this.$message.success(this.$t('common:message:deletedSuccessfully'))
|
||||
this.$store.dispatch('global/setDictionary', {})
|
||||
}
|
||||
})
|
||||
|
||||
@@ -239,18 +239,17 @@ export default {
|
||||
},
|
||||
// 删除
|
||||
handleDelete(row) {
|
||||
this.$confirm('Sure to delete?', {
|
||||
this.$confirm(this.$t('trials:uploadedDicoms:message:deleteMes'), {
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true,
|
||||
confirmButtonText: 'Ok',
|
||||
cancelButtonText: 'Cancel'
|
||||
|
||||
})
|
||||
.then(() => {
|
||||
deleteEmailNoticeConfig(row.Id)
|
||||
.then(res => {
|
||||
if (res.IsSuccess) {
|
||||
this.list.splice(this.list.findIndex(item => item.Id === row.Id), 1)
|
||||
this.$message.success('Deleted successfully!')
|
||||
this.$message.success(this.$t('common:message:deletedSuccessfully'))
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
@@ -3,21 +3,29 @@
|
||||
<div class="search">
|
||||
<el-form :inline="true" size="small" class="base-search-form">
|
||||
<el-form-item label="CRO Name:">
|
||||
<el-input v-model="searchData.CROName" style="width:100px;" />
|
||||
<el-input v-model="searchData.CROName" style="width: 100px" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" @click="handleSearch">Search</el-button>
|
||||
<el-button type="primary" icon="el-icon-refresh-left" @click="handleReset">Reset</el-button>
|
||||
<el-button type="primary" icon="el-icon-search" @click="handleSearch"
|
||||
>Search</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
icon="el-icon-refresh-left"
|
||||
@click="handleReset"
|
||||
>Reset</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span style="margin-left:auto;">
|
||||
<span style="margin-left: auto">
|
||||
<el-button
|
||||
size="small"
|
||||
type="primary"
|
||||
style="margin-left:auto;"
|
||||
style="margin-left: auto"
|
||||
icon="el-icon-plus"
|
||||
@click="handleAddCro"
|
||||
>New</el-button>
|
||||
>New</el-button
|
||||
>
|
||||
</span>
|
||||
</div>
|
||||
<el-table
|
||||
@@ -50,6 +58,16 @@
|
||||
show-overflow-tooltip
|
||||
sortable="custom"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="IsTrialLevel"
|
||||
label="Level"
|
||||
show-overflow-tooltip
|
||||
sortable="custom"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ $fd("IsTrialLevel", String(scope.row.IsTrialLevel)) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="Action" min-width="200">
|
||||
<template slot-scope="scope">
|
||||
<el-button
|
||||
@@ -68,7 +86,13 @@
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 分页组件 -->
|
||||
<pagination class="page" :total="total" :page.sync="searchData.PageIndex" :limit.sync="searchData.PageSize" @pagination="getList" />
|
||||
<pagination
|
||||
class="page"
|
||||
:total="total"
|
||||
:page.sync="searchData.PageIndex"
|
||||
:limit.sync="searchData.PageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
|
||||
<el-dialog
|
||||
v-if="editVisible"
|
||||
@@ -78,26 +102,32 @@
|
||||
width="600px"
|
||||
custom-class="base-dialog-wrapper"
|
||||
>
|
||||
<CroForm v-if="editVisible" :data="rowData" @close="close" @getList="getList" />
|
||||
<CroForm
|
||||
v-if="editVisible"
|
||||
:data="rowData"
|
||||
:IsTrialLevel="rowData.IsTrialLevel"
|
||||
@close="close"
|
||||
@getList="getList"
|
||||
/>
|
||||
</el-dialog>
|
||||
</box-content>
|
||||
</template>
|
||||
<script>
|
||||
import { getCROPageList, deleteCROCompany } from '@/api/dictionary'
|
||||
import BoxContent from '@/components/BoxContent'
|
||||
import Pagination from '@/components/Pagination'
|
||||
import CroForm from './CroForm'
|
||||
import { getCROPageList, deleteCROCompany } from "@/api/dictionary";
|
||||
import BoxContent from "@/components/BoxContent";
|
||||
import Pagination from "@/components/Pagination";
|
||||
import CroForm from "./CroForm";
|
||||
const searchDataDefault = () => {
|
||||
return {
|
||||
CROName: '',
|
||||
CROName: "",
|
||||
PageIndex: 1,
|
||||
PageSize: 20,
|
||||
Asc: true,
|
||||
SortField: ''
|
||||
}
|
||||
}
|
||||
SortField: "",
|
||||
};
|
||||
};
|
||||
export default {
|
||||
name: 'Cros',
|
||||
name: "Cros",
|
||||
components: { BoxContent, Pagination, CroForm },
|
||||
data() {
|
||||
return {
|
||||
@@ -107,85 +137,90 @@ export default {
|
||||
loading: false,
|
||||
rowData: {},
|
||||
editVisible: false,
|
||||
title: ''
|
||||
}
|
||||
title: "",
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.getList()
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
// 获取CRO列表信息
|
||||
getList() {
|
||||
this.loading = true
|
||||
getCROPageList(this.searchData).then(res => {
|
||||
this.loading = false
|
||||
this.list = res.Result.CurrentPageData
|
||||
this.total = res.Result.TotalCount
|
||||
}).catch(() => {
|
||||
this.loading = false
|
||||
this.loading = true;
|
||||
getCROPageList(this.searchData)
|
||||
.then((res) => {
|
||||
this.loading = false;
|
||||
this.list = res.Result.CurrentPageData;
|
||||
this.total = res.Result.TotalCount;
|
||||
})
|
||||
.catch(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
// 新增CRO
|
||||
handleAddCro() {
|
||||
this.rowData = {}
|
||||
this.title = 'Add'
|
||||
this.editVisible = true
|
||||
this.rowData = {};
|
||||
this.title = "Add";
|
||||
this.editVisible = true;
|
||||
},
|
||||
// 编辑CRO
|
||||
handleEdit(row) {
|
||||
this.rowData = row
|
||||
this.title = 'Edit'
|
||||
this.editVisible = true
|
||||
this.rowData = row;
|
||||
this.title = "Edit";
|
||||
this.editVisible = true;
|
||||
},
|
||||
// 删除CRO
|
||||
handleDelete(row) {
|
||||
this.$confirm('Sure to delete?', {
|
||||
type: 'warning',
|
||||
this.$confirm(this.$t("trials:uploadedDicoms:message:deleteMes"), {
|
||||
type: "warning",
|
||||
distinguishCancelAndClose: true,
|
||||
confirmButtonText: 'Ok',
|
||||
cancelButtonText: 'Cancel'
|
||||
})
|
||||
.then(() => {
|
||||
this.loading = true
|
||||
}).then(() => {
|
||||
this.loading = true;
|
||||
deleteCROCompany(row.Id)
|
||||
.then(res => {
|
||||
this.loading = false
|
||||
.then((res) => {
|
||||
this.loading = false;
|
||||
if (res.IsSuccess) {
|
||||
this.list.splice(this.list.findIndex(item => item.Id === row.Id), 1)
|
||||
this.$message.success('Deleted successfully!')
|
||||
this.list.splice(
|
||||
this.list.findIndex((item) => item.Id === row.Id),
|
||||
1
|
||||
);
|
||||
this.$message.success(
|
||||
this.$t("common:message:deletedSuccessfully")
|
||||
);
|
||||
}
|
||||
}).catch(() => {
|
||||
this.loading = false
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
});
|
||||
},
|
||||
// 重置列表
|
||||
handleReset() {
|
||||
this.searchData = searchDataDefault()
|
||||
this.getList()
|
||||
this.searchData = searchDataDefault();
|
||||
this.getList();
|
||||
},
|
||||
// 查询
|
||||
handleSearch() {
|
||||
this.searchData.PageIndex = 1
|
||||
this.getList()
|
||||
this.searchData.PageIndex = 1;
|
||||
this.getList();
|
||||
},
|
||||
// 指定排序字段,对列表进行排序
|
||||
handleSortByColumn(column) {
|
||||
if (column.order === 'ascending') {
|
||||
this.searchData.Asc = true
|
||||
if (column.order === "ascending") {
|
||||
this.searchData.Asc = true;
|
||||
} else {
|
||||
this.searchData.Asc = false
|
||||
this.searchData.Asc = false;
|
||||
}
|
||||
this.searchData.SortField = column.prop
|
||||
this.searchData.PageIndex = 1
|
||||
this.getList()
|
||||
this.searchData.SortField = column.prop;
|
||||
this.searchData.PageIndex = 1;
|
||||
this.getList();
|
||||
},
|
||||
// 关闭模态框
|
||||
close() {
|
||||
this.editVisible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
this.editVisible = false;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.cros {
|
||||
|
||||
@@ -17,70 +17,98 @@
|
||||
<el-form-item label="CRO Code: " prop="CROCode">
|
||||
<el-input v-model="form.CROCode" />
|
||||
</el-form-item>
|
||||
<el-form-item label="Level: ">
|
||||
<el-switch
|
||||
:disabled="!IsTrialLevel"
|
||||
v-model="form.IsTrialLevel"
|
||||
:active-text="$fd('IsTrialLevel', 'true')"
|
||||
:inactive-text="$fd('IsTrialLevel', 'false')"
|
||||
>
|
||||
</el-switch>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="base-dialog-footer" style="text-align:right;margin-top:10px;">
|
||||
<div class="base-dialog-footer" style="text-align: right; margin-top: 10px">
|
||||
<el-form-item>
|
||||
<el-button :disabled="btnLoading" type="primary" @click="handleCancel">Cancel</el-button>
|
||||
<el-button type="primary" :loading="btnLoading" @click="handleSave">Save</el-button>
|
||||
<el-button :disabled="btnLoading" type="primary" @click="handleCancel"
|
||||
>Cancel</el-button
|
||||
>
|
||||
<el-button type="primary" :loading="btnLoading" @click="handleSave"
|
||||
>Save</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-form>
|
||||
</template>
|
||||
<script>
|
||||
import { addOrUpdateCro } from '@/api/dictionary'
|
||||
import { addOrUpdateCro } from "@/api/dictionary";
|
||||
export default {
|
||||
name: 'CroForm',
|
||||
name: "CroForm",
|
||||
props: {
|
||||
data: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
return {};
|
||||
},
|
||||
},
|
||||
IsTrialLevel: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
btnLoading: false,
|
||||
form: {
|
||||
Id: '',
|
||||
CROName: '',
|
||||
CRONameCN: '',
|
||||
CROCode: ''
|
||||
Id: "",
|
||||
CROName: "",
|
||||
CRONameCN: "",
|
||||
CROCode: "",
|
||||
IsTrialLevel: true,
|
||||
},
|
||||
rules: {
|
||||
CROName: [{ required: true, message: 'Please specify', trigger: 'blur' }, { max: 50, message: 'The maximum length is 50' }],
|
||||
CRONameCN: [{ required: true, message: 'Please specify', trigger: 'blur' }, { max: 50, message: 'The maximum length is 50' }],
|
||||
CROCode: [{ required: true, message: 'Please specify', trigger: 'blur' }, { max: 50, message: 'The maximum length is 50' }]
|
||||
}
|
||||
}
|
||||
CROName: [
|
||||
{ required: true, message: "Please specify", trigger: "blur" },
|
||||
{ max: 500, message: "The maximum length is 500" },
|
||||
],
|
||||
CRONameCN: [
|
||||
{ required: true, message: "Please specify", trigger: "blur" },
|
||||
{ max: 500, message: "The maximum length is 500" },
|
||||
],
|
||||
CROCode: [
|
||||
{ required: true, message: "Please specify", trigger: "blur" },
|
||||
{ max: 50, message: "The maximum length is 50" },
|
||||
],
|
||||
},
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
if (Object.keys(this.data).length && this.data.Id) {
|
||||
this.form = { ...this.data }
|
||||
this.form = { ...this.data };
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleSave() {
|
||||
this.$refs.CROForm.validate(valid => {
|
||||
if (!valid) return
|
||||
this.btnLoading = true
|
||||
addOrUpdateCro(this.form).then(res => {
|
||||
this.btnLoading = false
|
||||
this.$refs.CROForm.validate((valid) => {
|
||||
if (!valid) return;
|
||||
this.btnLoading = true;
|
||||
addOrUpdateCro(this.form)
|
||||
.then((res) => {
|
||||
this.btnLoading = false;
|
||||
if (res.IsSuccess) {
|
||||
this.$message.success('Saved successfully')
|
||||
this.$refs['CROForm'].resetFields()
|
||||
this.$emit('getList')
|
||||
this.$emit('close')
|
||||
this.$message.success("Saved successfully");
|
||||
this.$refs["CROForm"].resetFields();
|
||||
this.$emit("getList");
|
||||
this.$emit("close");
|
||||
}
|
||||
}).catch(() => {
|
||||
this.btnLoading = false
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
this.btnLoading = false;
|
||||
});
|
||||
});
|
||||
},
|
||||
handleCancel() {
|
||||
this.$emit('close')
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
this.$emit("close");
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -8,12 +8,15 @@
|
||||
label-width="170px"
|
||||
>
|
||||
<div class="base-dialog-body">
|
||||
<el-form-item label="Hospital CN: " prop="SiteId">
|
||||
<el-select v-model="form.SiteId" style="width: 100%" filterable @change="siteChange">
|
||||
<el-form-item label="Site: ">
|
||||
<el-select v-model="form.SiteId" style="width: 100%" clearable filterable @change="siteChange">
|
||||
<el-option v-for="item of siteList" :value="item.Id" :key="item.Id" :label="item.SiteName">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="Hospital CN: " prop="HospitalNameCN">
|
||||
<el-input v-model="form.HospitalNameCN" />
|
||||
</el-form-item>
|
||||
<el-form-item label="Hospital EN: " prop="HospitalName">
|
||||
<el-input v-model="form.HospitalName" />
|
||||
</el-form-item>
|
||||
@@ -88,9 +91,7 @@ export default {
|
||||
},
|
||||
siteList: [],
|
||||
rules: {
|
||||
SiteId: [{ required: true, message: 'Please specify', trigger: 'blur' },
|
||||
{ max: 50, message: 'The maximum length is 50' }],
|
||||
HospitalName: [{ required: true, message: 'Please specify', trigger: 'blur' }, { max: 50, message: 'The maximum length is 50' }],
|
||||
HospitalNameCN: [{ required: true, message: 'Please specify', trigger: 'blur' }, { max: 50, message: 'The maximum length is 50' }],
|
||||
UniversityAffiliated: [{ max: 100, message: 'The maximum length is 100' }],
|
||||
UniversityAffiliatedCN: [{ max: 100, message: 'The maximum length is 100' }],
|
||||
Country: [{ required: true, message: 'Please specify', trigger: 'blur' },
|
||||
@@ -116,7 +117,8 @@ export default {
|
||||
this.siteList.forEach(o => {
|
||||
if (o.Id === v) {
|
||||
this.form.CityCN = o.City
|
||||
this.form.HospitalNameCN = o.SiteName
|
||||
this.form.HospitalNameCN = o.SiteNameCN
|
||||
this.form.HospitalName = o.SiteName
|
||||
this.form.ProvinceCN = o.Province
|
||||
this.form.CountryCN = o.Country
|
||||
}
|
||||
|
||||
@@ -201,11 +201,10 @@ export default {
|
||||
},
|
||||
// 删除医院信息
|
||||
handleDelete(row) {
|
||||
this.$confirm('Sure to delete?', {
|
||||
this.$confirm(this.$t('trials:uploadedDicoms:message:deleteMes'), {
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true,
|
||||
confirmButtonText: 'Ok',
|
||||
cancelButtonText: 'Cancel'
|
||||
|
||||
})
|
||||
.then(() => {
|
||||
this.loading = true
|
||||
@@ -213,7 +212,7 @@ export default {
|
||||
.then(res => {
|
||||
if (res.IsSuccess) {
|
||||
this.list.splice(this.list.findIndex(item => item.Id === row.Id), 1)
|
||||
this.$message.success('Deleted successfully!')
|
||||
this.$message.success(this.$t('common:message:deletedSuccessfully'))
|
||||
}
|
||||
this.loading = false
|
||||
}).catch(() => {
|
||||
|
||||
@@ -3,29 +3,46 @@
|
||||
<div class="search">
|
||||
<el-form :inline="true" size="small" class="base-search-form">
|
||||
<el-form-item label="Site Name:">
|
||||
<el-input v-model="searchData.SiteName" style="width:120px;" />
|
||||
<el-input v-model="searchData.SiteName" style="width: 120px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="Alias Name:">
|
||||
<el-input v-model="searchData.AliasName" style="width:120px;" />
|
||||
<el-input v-model="searchData.AliasName" style="width: 120px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="Country:">
|
||||
<el-input v-model="searchData.Country" style="width:120px;" />
|
||||
<el-input v-model="searchData.Country" style="width: 120px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="City:">
|
||||
<el-input v-model="searchData.City" style="width:120px;" />
|
||||
<el-input v-model="searchData.City" style="width: 120px" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" @click="handleSearch">Search</el-button>
|
||||
<el-button type="primary" icon="el-icon-refresh-left" @click="handleReset">Reset</el-button>
|
||||
<el-button type="primary" icon="el-icon-search" @click="handleSearch"
|
||||
>Search</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
icon="el-icon-refresh-left"
|
||||
@click="handleReset"
|
||||
>Reset</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div style="margin-left: auto">
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
style="margin-left:auto;"
|
||||
icon="el-icon-plus"
|
||||
@click="handleAddSystemSite"
|
||||
>{{ $t("trial:dictionary:institutions:site:addSystemSite") }}
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
style="margin-left: 10px"
|
||||
icon="el-icon-plus"
|
||||
@click="handleAddSite"
|
||||
>New</el-button>
|
||||
>New
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
@@ -120,6 +137,13 @@
|
||||
show-overflow-tooltip
|
||||
sortable="custom"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="CreateTime"
|
||||
label="CreateTime"
|
||||
min-width="160"
|
||||
show-overflow-tooltip
|
||||
sortable="custom"
|
||||
/>
|
||||
<el-table-column label="Action" fixed="right" width="150">
|
||||
<template slot-scope="scope">
|
||||
<el-button
|
||||
@@ -138,129 +162,359 @@
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 分页组件 -->
|
||||
<pagination class="page" :total="total" :page.sync="searchData.PageIndex" :limit.sync="searchData.PageSize" @pagination="getList" />
|
||||
<pagination
|
||||
class="page"
|
||||
:total="total"
|
||||
:page.sync="searchData.PageIndex"
|
||||
:limit.sync="searchData.PageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
<el-dialog
|
||||
v-if="editVisible"
|
||||
:visible.sync="editVisible"
|
||||
:close-on-click-modal="false"
|
||||
:title="title"
|
||||
width="600px"
|
||||
width="800px"
|
||||
custom-class="base-dialog-wrapper"
|
||||
>
|
||||
<site-form v-if="editVisible" :data="rowData" @close="close" @getList="getList" />
|
||||
<site-form
|
||||
v-if="editVisible"
|
||||
:data="rowData"
|
||||
@close="close"
|
||||
@getList="getList"
|
||||
/>
|
||||
</el-dialog>
|
||||
|
||||
<base-model
|
||||
v-if="addSystemSite_model.visible"
|
||||
:config="addSystemSite_model"
|
||||
>
|
||||
<template slot="dialog-body">
|
||||
<div class="search">
|
||||
<el-form :inline="true" size="small" class="base-search-form">
|
||||
<el-form-item
|
||||
:label="
|
||||
$t(
|
||||
'trial:dictionary:institutions:site:table:addSystemSite:TrialCode'
|
||||
)
|
||||
"
|
||||
>
|
||||
<el-input
|
||||
v-model="addSystemSiteSearchData.TrialCode"
|
||||
style="width: 100px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
:label="
|
||||
$t(
|
||||
'trial:dictionary:institutions:site:table:addSystemSite:TrialSiteName'
|
||||
)
|
||||
"
|
||||
>
|
||||
<el-input
|
||||
v-model="addSystemSiteSearchData.TrialSiteName"
|
||||
style="width: 100px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
:label="
|
||||
$t(
|
||||
'trial:dictionary:institutions:site:table:addSystemSite:TrialSiteAliasName'
|
||||
)
|
||||
"
|
||||
>
|
||||
<el-input
|
||||
v-model="addSystemSiteSearchData.TrialSiteAliasName"
|
||||
style="width: 100px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button
|
||||
type="primary"
|
||||
icon="el-icon-search"
|
||||
@click="getTrialSiteList"
|
||||
>{{ $t("trial:dictionary:institutions:site:button:sreach") }}
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
icon="el-icon-refresh-left"
|
||||
@click="handleResetAddSite"
|
||||
>{{ $t("trial:dictionary:institutions:site:button:reset") }}
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<el-table
|
||||
v-loading="addSystemSiteLoading"
|
||||
:data="addSystemSiteList"
|
||||
stripe
|
||||
height="300"
|
||||
@sort-change="handleSortByColumnAddSite"
|
||||
>
|
||||
<el-table-column type="index" width="40" />
|
||||
<el-table-column
|
||||
prop="TrialCode"
|
||||
:label="
|
||||
$t(
|
||||
'trial:dictionary:institutions:site:table:addSystemSite:TrialCode'
|
||||
)
|
||||
"
|
||||
show-overflow-tooltip
|
||||
sortable="custom"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="TrialSiteName"
|
||||
:label="
|
||||
$t(
|
||||
'trial:dictionary:institutions:site:table:addSystemSite:TrialSiteName'
|
||||
)
|
||||
"
|
||||
show-overflow-tooltip
|
||||
sortable="custom"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="TrialSiteAliasName"
|
||||
:label="
|
||||
$t(
|
||||
'trial:dictionary:institutions:site:table:addSystemSite:TrialSiteAliasName'
|
||||
)
|
||||
"
|
||||
show-overflow-tooltip
|
||||
sortable="custom"
|
||||
/>
|
||||
<el-table-column
|
||||
:label="
|
||||
$t(
|
||||
'trial:dictionary:institutions:site:table:addSystemSite:Action'
|
||||
)
|
||||
"
|
||||
fixed="right"
|
||||
width="80"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<el-button
|
||||
circle
|
||||
type="text"
|
||||
:title="$t('trial:dictionary:institutions:site:button:add')"
|
||||
@click="addSystemSite(scope.row)"
|
||||
>{{
|
||||
$t("trial:dictionary:institutions:site:button:add")
|
||||
}}</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 分页组件 -->
|
||||
<pagination
|
||||
class="page"
|
||||
style="float: right"
|
||||
:total="addSystemSiteSearchDataTotal"
|
||||
:page.sync="addSystemSiteSearchData.PageIndex"
|
||||
:limit.sync="addSystemSiteSearchData.PageSize"
|
||||
@pagination="getTrialSiteList"
|
||||
/>
|
||||
</template>
|
||||
</base-model>
|
||||
</box-content>
|
||||
</template>
|
||||
<script>
|
||||
import { getSiteList, deleteSite } from '@/api/dictionary'
|
||||
|
||||
import BoxContent from '@/components/BoxContent'
|
||||
import Pagination from '@/components/Pagination'
|
||||
import SiteForm from './SiteForm'
|
||||
import {
|
||||
getSiteList,
|
||||
deleteSite,
|
||||
addOrUpdateSite,
|
||||
getTrialSiteList,
|
||||
} from "@/api/dictionary";
|
||||
import BaseModel from "@/components/BaseModel";
|
||||
import BoxContent from "@/components/BoxContent";
|
||||
import Pagination from "@/components/Pagination";
|
||||
import SiteForm from "./SiteForm";
|
||||
const searchDataDefault = () => {
|
||||
return {
|
||||
SiteName: '',
|
||||
SiteName: "",
|
||||
PageIndex: 1,
|
||||
PageSize: 20,
|
||||
Asc: false,
|
||||
SortField: "CreateTime",
|
||||
AliasName: "",
|
||||
Country: null,
|
||||
City: null,
|
||||
};
|
||||
};
|
||||
const searchSiteDataDefault = () => {
|
||||
return {
|
||||
// SiteName: "",
|
||||
PageIndex: 1,
|
||||
PageSize: 20,
|
||||
Asc: true,
|
||||
SortField: '',
|
||||
AliasName: '',
|
||||
Country: null,
|
||||
City: null
|
||||
}
|
||||
}
|
||||
SortField: "",
|
||||
TrialCode: null,
|
||||
TrialSiteName: null,
|
||||
TrialSiteAliasName: null,
|
||||
};
|
||||
};
|
||||
export default {
|
||||
name: 'Sites',
|
||||
components: { BoxContent, Pagination, SiteForm },
|
||||
name: "Sites",
|
||||
components: { BoxContent, Pagination, SiteForm, BaseModel },
|
||||
data() {
|
||||
return {
|
||||
editVisible: false,
|
||||
title: 'Add',
|
||||
title: "Add",
|
||||
searchData: searchDataDefault(),
|
||||
list: [],
|
||||
total: 0,
|
||||
loading: false,
|
||||
rowData: {}
|
||||
}
|
||||
rowData: {},
|
||||
addSystemSite_model: {
|
||||
visible: false,
|
||||
title: this.$t("trial:dictionary:institutions:site:addSystemSite"),
|
||||
width: "800px",
|
||||
appendToBody: true,
|
||||
},
|
||||
addSystemSiteLoading: false,
|
||||
addSystemSiteList: [],
|
||||
addSystemSiteSearchData: searchSiteDataDefault(),
|
||||
addSystemSiteSearchDataTotal: 0,
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.getList()
|
||||
this.getList();
|
||||
this.getTrialSiteList();
|
||||
},
|
||||
methods: {
|
||||
// 获取项目级别列表
|
||||
async getTrialSiteList() {
|
||||
try {
|
||||
this.addSystemSiteLoading = true;
|
||||
let res = await getTrialSiteList(this.addSystemSiteSearchData);
|
||||
if (res.IsSuccess) {
|
||||
this.addSystemSiteLoading = false;
|
||||
this.addSystemSiteList = res.Result.CurrentPageData;
|
||||
this.addSystemSiteSearchDataTotal = res.Result.TotalCount;
|
||||
}
|
||||
} catch (err) {
|
||||
this.addSystemSiteLoading = false;
|
||||
console.log(err);
|
||||
}
|
||||
},
|
||||
// 将项目级别中心转换为系统级别中心
|
||||
async addSystemSite(item) {
|
||||
try {
|
||||
let data = {
|
||||
SiteName: item.TrialSiteName,
|
||||
SiteNameCN: item.TrialSiteName,
|
||||
AliasName: item.TrialSiteAliasName,
|
||||
SiteCode: item.TrialCode,
|
||||
TrialSiteId: item.TrialSiteId,
|
||||
};
|
||||
this.addSystemSiteLoading = true;
|
||||
let res = await addOrUpdateSite(data);
|
||||
if (res.IsSuccess) {
|
||||
this.getTrialSiteList();
|
||||
this.getList();
|
||||
}
|
||||
} catch (err) {
|
||||
this.addSystemSiteLoading = false;
|
||||
console.log(err);
|
||||
}
|
||||
},
|
||||
handleAddSystemSite() {
|
||||
this.addSystemSite_model.visible = true;
|
||||
this.addSystemSiteSearchData = searchSiteDataDefault();
|
||||
this.addSystemSiteList = [];
|
||||
this.addSystemSiteSearchDataTotal = 0;
|
||||
this.getTrialSiteList();
|
||||
},
|
||||
// 获取Site列表信息
|
||||
getList() {
|
||||
this.loading = true
|
||||
getSiteList(this.searchData).then(res => {
|
||||
this.loading = false
|
||||
this.list = res.Result.CurrentPageData
|
||||
this.total = res.Result.TotalCount
|
||||
}).catch(() => {
|
||||
this.loading = false
|
||||
this.loading = true;
|
||||
getSiteList(this.searchData)
|
||||
.then((res) => {
|
||||
this.loading = false;
|
||||
this.list = res.Result.CurrentPageData;
|
||||
this.total = res.Result.TotalCount;
|
||||
})
|
||||
.catch(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
// 新增Site信息
|
||||
handleAddSite() {
|
||||
this.rowData = {}
|
||||
this.title = 'Add'
|
||||
this.editVisible = true
|
||||
this.rowData = {};
|
||||
this.title = "Add";
|
||||
this.editVisible = true;
|
||||
},
|
||||
// 编辑Site信息
|
||||
handleEdit(row) {
|
||||
this.rowData = row
|
||||
this.title = 'Edit'
|
||||
this.editVisible = true
|
||||
this.rowData = row;
|
||||
this.title = "Edit";
|
||||
this.editVisible = true;
|
||||
},
|
||||
// 删除Site
|
||||
handleDelete(row) {
|
||||
this.$confirm('Sure to delete?', {
|
||||
type: 'warning',
|
||||
this.$confirm(this.$t("trials:uploadedDicoms:message:deleteMes"), {
|
||||
type: "warning",
|
||||
distinguishCancelAndClose: true,
|
||||
confirmButtonText: 'Ok',
|
||||
cancelButtonText: 'Cancel'
|
||||
})
|
||||
.then(() => {
|
||||
this.loading = true
|
||||
}).then(() => {
|
||||
this.loading = true;
|
||||
deleteSite(row.Id)
|
||||
.then(res => {
|
||||
this.loading = false
|
||||
.then((res) => {
|
||||
this.loading = false;
|
||||
if (res.IsSuccess) {
|
||||
this.list.splice(this.list.findIndex(item => item.Id === row.Id), 1)
|
||||
this.$store.dispatch('global/setSite', {})
|
||||
this.$message.success('Deleted successfully!')
|
||||
this.list.splice(
|
||||
this.list.findIndex((item) => item.Id === row.Id),
|
||||
1
|
||||
);
|
||||
this.$store.dispatch("global/setSite", {});
|
||||
this.$message.success(
|
||||
this.$t("common:message:deletedSuccessfully")
|
||||
);
|
||||
}
|
||||
}).catch(() => {
|
||||
this.loading = false
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
});
|
||||
},
|
||||
// 重置列表
|
||||
handleReset() {
|
||||
this.searchData = searchDataDefault()
|
||||
this.getList()
|
||||
this.searchData = searchDataDefault();
|
||||
this.getList();
|
||||
},
|
||||
handleResetAddSite() {
|
||||
this.addSystemSiteSearchData = searchSiteDataDefault();
|
||||
this.getTrialSiteList();
|
||||
},
|
||||
// 查询
|
||||
handleSearch() {
|
||||
this.searchData.PageIndex = 1
|
||||
this.getList()
|
||||
this.searchData.PageIndex = 1;
|
||||
this.getList();
|
||||
},
|
||||
// 指定排序字段,对列表进行排序
|
||||
handleSortByColumn(column) {
|
||||
if (column.order === 'ascending') {
|
||||
this.searchData.Asc = true
|
||||
if (column.order === "ascending") {
|
||||
this.searchData.Asc = true;
|
||||
} else {
|
||||
this.searchData.Asc = false
|
||||
this.searchData.Asc = false;
|
||||
}
|
||||
this.searchData.SortField = column.prop
|
||||
this.searchData.PageIndex = 1
|
||||
this.getList()
|
||||
this.searchData.SortField = column.prop;
|
||||
this.searchData.PageIndex = 1;
|
||||
this.getList();
|
||||
},
|
||||
handleSortByColumnAddSite(column) {
|
||||
if (column.order === "ascending") {
|
||||
this.addSystemSiteSearchData.Asc = true;
|
||||
} else {
|
||||
this.addSystemSiteSearchData.Asc = false;
|
||||
}
|
||||
this.addSystemSiteSearchData.SortField = column.prop;
|
||||
this.addSystemSiteSearchData.PageIndex = 1;
|
||||
this.getTrialSiteList();
|
||||
},
|
||||
// 关闭模态框
|
||||
close() {
|
||||
this.editVisible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
this.editVisible = false;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.Sites {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<template>
|
||||
|
||||
<el-form
|
||||
ref="sponsorForm"
|
||||
:model="form"
|
||||
@@ -15,73 +14,109 @@
|
||||
<el-form-item label="Sponsor NameCN: " prop="SponsorName">
|
||||
<el-input v-model="form.SponsorNameCN" />
|
||||
</el-form-item>
|
||||
<el-form-item label="Sponsor Code: " prop="SponsorName">
|
||||
<el-form-item label="Sponsor Code: " prop="SponsorCode">
|
||||
<el-input v-model="form.SponsorCode" />
|
||||
</el-form-item>
|
||||
<el-form-item label="Level: ">
|
||||
<el-switch
|
||||
:disabled="!IsTrialLevel"
|
||||
v-model="form.IsTrialLevel"
|
||||
:active-text="$fd('IsTrialLevel', 'true')"
|
||||
:inactive-text="$fd('IsTrialLevel', 'false')"
|
||||
>
|
||||
</el-switch>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="base-dialog-footer" style="text-align:right;margin-top:10px;">
|
||||
<div class="base-dialog-footer" style="text-align: right; margin-top: 10px">
|
||||
<el-form-item>
|
||||
<el-button :disabled="btnLoading" size="small" type="primary" @click="handleCancel">Cancel</el-button>
|
||||
<el-button size="small" type="primary" :loading="btnLoading" @click="handleSave">Save</el-button>
|
||||
<el-button
|
||||
:disabled="btnLoading"
|
||||
size="small"
|
||||
type="primary"
|
||||
@click="handleCancel"
|
||||
>Cancel</el-button
|
||||
>
|
||||
<el-button
|
||||
size="small"
|
||||
type="primary"
|
||||
:loading="btnLoading"
|
||||
@click="handleSave"
|
||||
>Save</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-form>
|
||||
</template>
|
||||
<script>
|
||||
import { addOrUpdateSponsor } from '@/api/dictionary'
|
||||
import { addOrUpdateSponsor } from "@/api/dictionary";
|
||||
export default {
|
||||
name: 'SponsorForm',
|
||||
name: "SponsorForm",
|
||||
props: {
|
||||
data: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
return {};
|
||||
},
|
||||
},
|
||||
IsTrialLevel: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
btnLoading: false,
|
||||
form: {
|
||||
Id: '',
|
||||
SponsorName: '',
|
||||
SponsorNameCN: '',
|
||||
SponsorCode: '',
|
||||
Id: "",
|
||||
SponsorName: "",
|
||||
SponsorNameCN: "",
|
||||
SponsorCode: "",
|
||||
IsTrialLevel: true,
|
||||
},
|
||||
rules: {
|
||||
SponsorName: [{ required: true, message: 'Please specify', trigger: 'blur' }, { max: 50, message: 'The maximum length is 50' }],
|
||||
SponsorNameCN: [{ required: true, message: 'Please specify', trigger: 'blur' }, { max: 50, message: 'The maximum length is 50' }],
|
||||
SponsorCode: [{ required: true, message: 'Please specify', trigger: 'blur' }, { max: 50, message: 'The maximum length is 50' }]
|
||||
}
|
||||
}
|
||||
SponsorName: [
|
||||
{ required: true, message: "Please specify", trigger: "blur" },
|
||||
{ max: 500, message: "The maximum length is 500" },
|
||||
],
|
||||
SponsorNameCN: [
|
||||
{ required: true, message: "Please specify", trigger: "blur" },
|
||||
{ max: 500, message: "The maximum length is 500" },
|
||||
],
|
||||
SponsorCode: [
|
||||
{ required: true, message: "Please specify", trigger: "blur" },
|
||||
{ max: 50, message: "The maximum length is 50" },
|
||||
],
|
||||
},
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
if (Object.keys(this.data).length && this.data.Id) {
|
||||
this.form = { ...this.data }
|
||||
this.form = { ...this.data };
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleSave() {
|
||||
this.$refs.sponsorForm.validate(valid => {
|
||||
if (!valid) return
|
||||
this.btnLoading = true
|
||||
addOrUpdateSponsor(this.form).then(res => {
|
||||
this.btnLoading = false
|
||||
this.$refs.sponsorForm.validate((valid) => {
|
||||
if (!valid) return;
|
||||
this.btnLoading = true;
|
||||
addOrUpdateSponsor(this.form)
|
||||
.then((res) => {
|
||||
this.btnLoading = false;
|
||||
if (res.IsSuccess) {
|
||||
this.$message.success('Saved successfully')
|
||||
this.$refs['sponsorForm'].resetFields()
|
||||
this.$emit('getList')
|
||||
this.$emit('close')
|
||||
this.$message.success("Saved successfully");
|
||||
this.$refs["sponsorForm"].resetFields();
|
||||
this.$emit("getList");
|
||||
this.$emit("close");
|
||||
}
|
||||
}).catch(() => {
|
||||
this.btnLoading = false
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
this.btnLoading = false;
|
||||
});
|
||||
});
|
||||
},
|
||||
handleCancel() {
|
||||
this.$emit('close')
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
this.$emit("close");
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -3,21 +3,29 @@
|
||||
<div class="search">
|
||||
<el-form :inline="true" size="small" class="base-search-form">
|
||||
<el-form-item label="Sponsor Name:">
|
||||
<el-input v-model="searchData.SponsorName" style="width:100px;" />
|
||||
<el-input v-model="searchData.SponsorName" style="width: 100px" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" @click="handleSearch">Search</el-button>
|
||||
<el-button type="primary" icon="el-icon-refresh-left" @click="handleReset">Reset</el-button>
|
||||
<el-button type="primary" icon="el-icon-search" @click="handleSearch"
|
||||
>Search</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
icon="el-icon-refresh-left"
|
||||
@click="handleReset"
|
||||
>Reset</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span style="margin-left:auto;">
|
||||
<span style="margin-left: auto">
|
||||
<el-button
|
||||
size="small"
|
||||
type="primary"
|
||||
style="margin-left:auto;"
|
||||
style="margin-left: auto"
|
||||
icon="el-icon-plus"
|
||||
@click="handleAddSponsor"
|
||||
>New</el-button>
|
||||
>New</el-button
|
||||
>
|
||||
</span>
|
||||
</div>
|
||||
<el-table
|
||||
@@ -50,6 +58,16 @@
|
||||
show-overflow-tooltip
|
||||
sortable="custom"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="IsTrialLevel"
|
||||
label="Level"
|
||||
show-overflow-tooltip
|
||||
sortable="custom"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ $fd("IsTrialLevel", String(scope.row.IsTrialLevel)) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="Action" min-width="150">
|
||||
<template slot-scope="scope">
|
||||
<el-button
|
||||
@@ -68,7 +86,13 @@
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 分页组件 -->
|
||||
<pagination class="page" :total="total" :page.sync="searchData.PageIndex" :limit.sync="searchData.PageSize" @pagination="getList" />
|
||||
<pagination
|
||||
class="page"
|
||||
:total="total"
|
||||
:page.sync="searchData.PageIndex"
|
||||
:limit.sync="searchData.PageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
|
||||
<el-dialog
|
||||
v-if="editVisible"
|
||||
@@ -78,26 +102,32 @@
|
||||
width="600px"
|
||||
custom-class="base-dialog-wrapper"
|
||||
>
|
||||
<sponsor-form v-if="editVisible" :data="rowData" @close="close" @getList="getList" />
|
||||
<sponsor-form
|
||||
v-if="editVisible"
|
||||
:IsTrialLevel="rowData.IsTrialLevel"
|
||||
:data="rowData"
|
||||
@close="close"
|
||||
@getList="getList"
|
||||
/>
|
||||
</el-dialog>
|
||||
</box-content>
|
||||
</template>
|
||||
<script>
|
||||
import { getSponsorPageList, deleteSponsor } from '@/api/dictionary'
|
||||
import BoxContent from '@/components/BoxContent'
|
||||
import Pagination from '@/components/Pagination'
|
||||
import SponsorForm from './SponsorForm'
|
||||
import { getSponsorPageList, deleteSponsor } from "@/api/dictionary";
|
||||
import BoxContent from "@/components/BoxContent";
|
||||
import Pagination from "@/components/Pagination";
|
||||
import SponsorForm from "./SponsorForm";
|
||||
const searchDataDefault = () => {
|
||||
return {
|
||||
SponsorName: '',
|
||||
SponsorName: "",
|
||||
PageIndex: 1,
|
||||
PageSize: 20,
|
||||
Asc: true,
|
||||
SortField: ''
|
||||
}
|
||||
}
|
||||
SortField: "",
|
||||
};
|
||||
};
|
||||
export default {
|
||||
name: 'Sponsors',
|
||||
name: "Sponsors",
|
||||
components: { BoxContent, Pagination, SponsorForm },
|
||||
data() {
|
||||
return {
|
||||
@@ -107,85 +137,90 @@ export default {
|
||||
loading: false,
|
||||
rowData: {},
|
||||
editVisible: false,
|
||||
title: ''
|
||||
}
|
||||
title: "",
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.getList()
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
// 获取Sponsors列表
|
||||
getList() {
|
||||
this.loading = true
|
||||
getSponsorPageList(this.searchData).then(res => {
|
||||
this.loading = false
|
||||
this.list = res.Result.CurrentPageData
|
||||
this.total = res.Result.TotalCount
|
||||
}).catch(() => {
|
||||
this.loading = false
|
||||
this.loading = true;
|
||||
getSponsorPageList(this.searchData)
|
||||
.then((res) => {
|
||||
this.loading = false;
|
||||
this.list = res.Result.CurrentPageData;
|
||||
this.total = res.Result.TotalCount;
|
||||
})
|
||||
.catch(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
// 新增Sponsor
|
||||
handleAddSponsor() {
|
||||
this.rowData = {}
|
||||
this.title = 'Add'
|
||||
this.editVisible = true
|
||||
this.rowData = {};
|
||||
this.title = "Add";
|
||||
this.editVisible = true;
|
||||
},
|
||||
// 编辑Sponsor
|
||||
handleEdit(row) {
|
||||
this.rowData = row
|
||||
this.title = 'Edit'
|
||||
this.editVisible = true
|
||||
this.rowData = row;
|
||||
this.title = "Edit";
|
||||
this.editVisible = true;
|
||||
},
|
||||
// 删除Sponsor
|
||||
handleDelete(row) {
|
||||
this.$confirm('Sure to delete?', {
|
||||
type: 'warning',
|
||||
this.$confirm(this.$t("trials:uploadedDicoms:message:deleteMes"), {
|
||||
type: "warning",
|
||||
distinguishCancelAndClose: true,
|
||||
confirmButtonText: 'Ok',
|
||||
cancelButtonText: 'Cancel'
|
||||
})
|
||||
.then(() => {
|
||||
this.loading = true
|
||||
}).then(() => {
|
||||
this.loading = true;
|
||||
deleteSponsor(row.Id)
|
||||
.then(res => {
|
||||
this.loading = false
|
||||
.then((res) => {
|
||||
this.loading = false;
|
||||
if (res.IsSuccess) {
|
||||
this.list.splice(this.list.findIndex(item => item.Id === row.Id), 1)
|
||||
this.$message.success('Deleted successfully!')
|
||||
this.list.splice(
|
||||
this.list.findIndex((item) => item.Id === row.Id),
|
||||
1
|
||||
);
|
||||
this.$message.success(
|
||||
this.$t("common:message:deletedSuccessfully")
|
||||
);
|
||||
}
|
||||
}).catch(() => {
|
||||
this.loading = false
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
});
|
||||
},
|
||||
// 重置列表
|
||||
handleReset() {
|
||||
this.searchData = searchDataDefault()
|
||||
this.getList()
|
||||
this.searchData = searchDataDefault();
|
||||
this.getList();
|
||||
},
|
||||
// 查询
|
||||
handleSearch() {
|
||||
this.searchData.PageIndex = 1
|
||||
this.getList()
|
||||
this.searchData.PageIndex = 1;
|
||||
this.getList();
|
||||
},
|
||||
// 指定排序字段,对列表进行排序
|
||||
handleSortByColumn(column) {
|
||||
if (column.order === 'ascending') {
|
||||
this.searchData.Asc = true
|
||||
if (column.order === "ascending") {
|
||||
this.searchData.Asc = true;
|
||||
} else {
|
||||
this.searchData.Asc = false
|
||||
this.searchData.Asc = false;
|
||||
}
|
||||
this.searchData.SortField = column.prop
|
||||
this.searchData.PageIndex = 1
|
||||
this.getList()
|
||||
this.searchData.SortField = column.prop;
|
||||
this.searchData.PageIndex = 1;
|
||||
this.getList();
|
||||
},
|
||||
// 关闭模态框
|
||||
close() {
|
||||
this.editVisible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
this.editVisible = false;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.sponsors {
|
||||
|
||||
@@ -182,11 +182,10 @@ export default {
|
||||
})
|
||||
},
|
||||
handleDelete(row) {
|
||||
this.$confirm('Sure to delete?', {
|
||||
this.$confirm(this.$t('trials:uploadedDicoms:message:deleteMes'), {
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true,
|
||||
confirmButtonText: 'Ok',
|
||||
cancelButtonText: 'Cancel'
|
||||
|
||||
})
|
||||
.then(() => {
|
||||
this.loading = true
|
||||
@@ -195,7 +194,7 @@ export default {
|
||||
this.loading = false
|
||||
if (res.IsSuccess) {
|
||||
this.list.splice(this.list.findIndex(item => item.Id === row.Id), 1)
|
||||
this.$message.success('Deleted successfully!')
|
||||
this.$message.success(this.$t('common:message:deletedSuccessfully'))
|
||||
}
|
||||
}).catch(() => { this.loading = false })
|
||||
})
|
||||
|
||||
@@ -154,11 +154,10 @@ export default {
|
||||
})
|
||||
},
|
||||
handleDelete(row) {
|
||||
this.$confirm('Sure to delete?', {
|
||||
this.$confirm(this.$t('trials:uploadedDicoms:message:deleteMes'), {
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true,
|
||||
confirmButtonText: 'Ok',
|
||||
cancelButtonText: 'Cancel'
|
||||
|
||||
})
|
||||
.then(() => {
|
||||
this.loading = true
|
||||
@@ -167,7 +166,7 @@ export default {
|
||||
this.loading = false
|
||||
if (res.IsSuccess) {
|
||||
this.list.splice(this.list.findIndex(item => item.Id === row.Id), 1)
|
||||
this.$message.success('Deleted successfully!')
|
||||
this.$message.success(this.$t('common:message:deletedSuccessfully'))
|
||||
}
|
||||
}).catch(() => { this.loading = false })
|
||||
})
|
||||
|
||||
@@ -183,11 +183,10 @@ export default {
|
||||
})
|
||||
},
|
||||
handleDelete(row) {
|
||||
this.$confirm('Sure to delete?', {
|
||||
this.$confirm(this.$t('trials:uploadedDicoms:message:deleteMes'), {
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true,
|
||||
confirmButtonText: 'Ok',
|
||||
cancelButtonText: 'Cancel'
|
||||
|
||||
})
|
||||
.then(() => {
|
||||
this.loading = true
|
||||
@@ -196,7 +195,7 @@ export default {
|
||||
this.loading = false
|
||||
if (res.IsSuccess) {
|
||||
this.list.splice(this.list.findIndex(item => item.Id === row.Id), 1)
|
||||
this.$message.success('Deleted successfully!')
|
||||
this.$message.success(this.$t('common:message:deletedSuccessfully'))
|
||||
}
|
||||
}).catch(() => { this.loading = false })
|
||||
})
|
||||
|
||||
@@ -182,11 +182,10 @@ export default {
|
||||
})
|
||||
},
|
||||
handleDelete(row) {
|
||||
this.$confirm('Sure to delete?', {
|
||||
this.$confirm(this.$t('trials:uploadedDicoms:message:deleteMes'), {
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true,
|
||||
confirmButtonText: 'Ok',
|
||||
cancelButtonText: 'Cancel'
|
||||
|
||||
})
|
||||
.then(() => {
|
||||
this.loading = true
|
||||
@@ -195,7 +194,7 @@ export default {
|
||||
this.loading = false
|
||||
if (res.IsSuccess) {
|
||||
this.list.splice(this.list.findIndex(item => item.Id === row.Id), 1)
|
||||
this.$message.success('Deleted successfully!')
|
||||
this.$message.success(this.$t('common:message:deletedSuccessfully'))
|
||||
}
|
||||
}).catch(() => { this.loading = false })
|
||||
})
|
||||
|
||||
@@ -153,11 +153,10 @@ export default {
|
||||
})
|
||||
},
|
||||
handleDelete(row) {
|
||||
this.$confirm('Sure to delete?', {
|
||||
this.$confirm(this.$t('trials:uploadedDicoms:message:deleteMes'), {
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true,
|
||||
confirmButtonText: 'Ok',
|
||||
cancelButtonText: 'Cancel'
|
||||
|
||||
})
|
||||
.then(() => {
|
||||
this.loading = true
|
||||
@@ -166,7 +165,7 @@ export default {
|
||||
this.loading = false
|
||||
if (res.IsSuccess) {
|
||||
this.list.splice(this.list.findIndex(item => item.Id === row.Id), 1)
|
||||
this.$message.success('Deleted successfully!')
|
||||
this.$message.success(this.$t('common:message:deletedSuccessfully'))
|
||||
}
|
||||
}).catch(() => { this.loading = false })
|
||||
})
|
||||
|
||||
@@ -206,11 +206,10 @@ export default {
|
||||
})
|
||||
},
|
||||
handleDelete(row) {
|
||||
this.$confirm('Sure to delete?', {
|
||||
this.$confirm(this.$t('trials:uploadedDicoms:message:deleteMes'), {
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true,
|
||||
confirmButtonText: 'Ok',
|
||||
cancelButtonText: 'Cancel'
|
||||
|
||||
})
|
||||
.then(() => {
|
||||
this.loading = true
|
||||
@@ -219,7 +218,7 @@ export default {
|
||||
this.loading = false
|
||||
if (res.IsSuccess) {
|
||||
this.list.splice(this.list.findIndex(item => item.Id === row.Id), 1)
|
||||
this.$message.success('Deleted successfully!')
|
||||
this.$message.success(this.$t('common:message:deletedSuccessfully'))
|
||||
}
|
||||
}).catch(() => { this.loading = false })
|
||||
})
|
||||
|
||||
@@ -183,11 +183,10 @@ export default {
|
||||
})
|
||||
},
|
||||
handleDelete(row) {
|
||||
this.$confirm('Sure to delete?', {
|
||||
this.$confirm(this.$t('trials:uploadedDicoms:message:deleteMes'), {
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true,
|
||||
confirmButtonText: 'Ok',
|
||||
cancelButtonText: 'Cancel'
|
||||
|
||||
})
|
||||
.then(() => {
|
||||
this.loading = true
|
||||
@@ -196,7 +195,7 @@ export default {
|
||||
this.loading = false
|
||||
if (res.IsSuccess) {
|
||||
this.list.splice(this.list.findIndex(item => item.Id === row.Id), 1)
|
||||
this.$message.success('Deleted successfully!')
|
||||
this.$message.success(this.$t('common:message:deletedSuccessfully'))
|
||||
}
|
||||
}).catch(() => { this.loading = false })
|
||||
})
|
||||
|
||||
@@ -122,11 +122,10 @@ export default {
|
||||
})
|
||||
},
|
||||
handleDelete(row) {
|
||||
this.$confirm('Sure to delete?', {
|
||||
this.$confirm(this.$t('trials:uploadedDicoms:message:deleteMes'), {
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true,
|
||||
confirmButtonText: 'Ok',
|
||||
cancelButtonText: 'Cancel'
|
||||
|
||||
})
|
||||
.then(() => {
|
||||
this.loading = true
|
||||
@@ -135,7 +134,7 @@ export default {
|
||||
this.loading = false
|
||||
if (res.IsSuccess) {
|
||||
this.list.splice(this.list.findIndex(item => item.Id === row.Id), 1)
|
||||
this.$message.success('Deleted successfully!')
|
||||
this.$message.success(this.$t('common:message:deletedSuccessfully'))
|
||||
}
|
||||
}).catch(() => { this.loading = false })
|
||||
})
|
||||
|
||||
@@ -137,18 +137,17 @@ export default {
|
||||
},
|
||||
// 删除
|
||||
handleDelete(row) {
|
||||
this.$confirm('Sure to delete?', {
|
||||
this.$confirm(this.$t('trials:uploadedDicoms:message:deleteMes'), {
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true,
|
||||
confirmButtonText: 'Ok',
|
||||
cancelButtonText: 'Cancel'
|
||||
|
||||
})
|
||||
.then(() => {
|
||||
deleteSystemBasicData(row.Id)
|
||||
.then(res => {
|
||||
if (res.IsSuccess) {
|
||||
this.list.splice(this.list.findIndex(item => item.Id === row.Id), 1)
|
||||
this.$message.success('Deleted successfully!')
|
||||
this.$message.success(this.$t('common:message:deletedSuccessfully'))
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
@@ -178,18 +178,17 @@ export default {
|
||||
},
|
||||
// 删除
|
||||
handleDelete(row) {
|
||||
this.$confirm('Sure to delete?', {
|
||||
this.$confirm(this.$t('trials:uploadedDicoms:message:deleteMes'), {
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true,
|
||||
confirmButtonText: 'Ok',
|
||||
cancelButtonText: 'Cancel'
|
||||
|
||||
})
|
||||
.then(() => {
|
||||
deleteSystemBasicData(row.Id)
|
||||
.then(res => {
|
||||
if (res.IsSuccess) {
|
||||
this.list.splice(this.list.findIndex(item => item.Id === row.Id), 1)
|
||||
this.$message.success('Deleted successfully!')
|
||||
this.$message.success(this.$t('common:message:deletedSuccessfully'))
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
@@ -162,11 +162,10 @@ export default {
|
||||
})
|
||||
},
|
||||
handleDelete(row) {
|
||||
this.$confirm('Sure to delete?', {
|
||||
this.$confirm(this.$t('trials:uploadedDicoms:message:deleteMes'), {
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true,
|
||||
confirmButtonText: 'Ok',
|
||||
cancelButtonText: 'Cancel'
|
||||
|
||||
})
|
||||
.then(() => {
|
||||
this.loading = true
|
||||
@@ -175,7 +174,7 @@ export default {
|
||||
this.loading = false
|
||||
if (res.IsSuccess) {
|
||||
this.list.splice(this.list.findIndex(item => item.Id === row.Id), 1)
|
||||
this.$message.success('Deleted successfully!')
|
||||
this.$message.success(this.$t('common:message:deletedSuccessfully'))
|
||||
}
|
||||
}).catch(() => { this.loading = false })
|
||||
})
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
<el-button
|
||||
size="mini"
|
||||
type="primary"
|
||||
:disabled="isCompleteConfig"
|
||||
@click="handleAdd"
|
||||
style="margin-right: 10px;"
|
||||
>
|
||||
@@ -59,12 +60,13 @@
|
||||
show-overflow-tooltip
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<el-button size="small" type="primary" @click="openChildren(scope.row)">
|
||||
<el-button size="small" :disabled="isCompleteConfig" type="primary" @click="openChildren(scope.row)">
|
||||
配置
|
||||
</el-button>
|
||||
<el-button
|
||||
type="danger"
|
||||
size="small"
|
||||
:disabled="isCompleteConfig"
|
||||
@click="handleDelete(scope.row)"
|
||||
>
|
||||
删除
|
||||
@@ -151,6 +153,10 @@ export default {
|
||||
criterionId: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
isCompleteConfig: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
components: {
|
||||
|
||||
@@ -19,6 +19,52 @@
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="form.Type === 'group'"
|
||||
label="分组名称"
|
||||
prop="GroupName"
|
||||
>
|
||||
<el-input v-model="form.GroupName" />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
label="分组标识"
|
||||
v-if="form.Type === 'group'"
|
||||
prop="GroupClassify"
|
||||
>
|
||||
<el-select
|
||||
v-model="form.GroupClassify"
|
||||
clearable
|
||||
>
|
||||
<el-option
|
||||
v-for="item of groupClassifyList"
|
||||
:key="item.Id"
|
||||
:value="parseInt(item.Code)"
|
||||
:label="item.ValueCN"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="form.Type === 'group'"
|
||||
label="分组名称(EN)"
|
||||
prop="GroupEnName"
|
||||
>
|
||||
<el-input v-model="form.GroupEnName" />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="form.Type !== 'group'"
|
||||
label="问题名称"
|
||||
prop="QuestionName"
|
||||
>
|
||||
<el-input v-model="form.QuestionName" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item
|
||||
v-if="form.Type !== 'group'"
|
||||
label="问题名称(EN)"
|
||||
prop="QuestionEnName"
|
||||
>
|
||||
<el-input v-model="form.QuestionEnName" />
|
||||
</el-form-item>
|
||||
<!-- 数值类型 -->
|
||||
<el-form-item
|
||||
v-if="form.Type === 'number' || form.Type === 'calculation'"
|
||||
@@ -75,52 +121,6 @@
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="form.Type === 'group'"
|
||||
label="分组名称"
|
||||
prop="GroupName"
|
||||
>
|
||||
<el-input v-model="form.GroupName" />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
label="分组标识"
|
||||
prop="GroupClassify"
|
||||
>
|
||||
<el-select
|
||||
v-model="form.GroupClassify"
|
||||
clearable
|
||||
>
|
||||
<el-option
|
||||
v-for="item of groupClassifyList"
|
||||
:key="item.Id"
|
||||
:value="parseInt(item.Code)"
|
||||
:label="item.ValueCN"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="form.Type === 'group'"
|
||||
label="分组名称(EN)"
|
||||
prop="GroupEnName"
|
||||
>
|
||||
<el-input v-model="form.GroupEnName" />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="form.Type !== 'group'"
|
||||
label="问题名称"
|
||||
prop="QuestionName"
|
||||
>
|
||||
<el-input v-model="form.QuestionName" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item
|
||||
v-if="form.Type !== 'group'"
|
||||
label="问题名称(EN)"
|
||||
prop="QuestionEnName"
|
||||
>
|
||||
<el-input v-model="form.QuestionEnName" />
|
||||
</el-form-item>
|
||||
|
||||
<!-- <el-form-item
|
||||
v-if="form.Type === 'select' || form.Type === 'radio'"
|
||||
label="选项"
|
||||
@@ -170,7 +170,7 @@
|
||||
placeholder="选项请用‘|’分割多个选项"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="问题分类">
|
||||
<el-form-item label="问题分类" v-if="form.Type !== 'group'">
|
||||
<!-- <el-radio-group v-model="form.QuestionClassify">
|
||||
<el-radio v-for="item of $d.QuestionClassify" :key="item.id" :label="item.value">{{ item.label }}</el-radio>
|
||||
</el-radio-group> -->
|
||||
@@ -406,6 +406,7 @@
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
label="问题标识"
|
||||
v-if="form.Type !== 'group'"
|
||||
prop="QuestionType"
|
||||
>
|
||||
<el-select
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="criterion-config">
|
||||
<el-tabs v-model="activeName">
|
||||
<el-tab-pane label="访视阅片" name="0">
|
||||
<el-tab-pane :label="'访视阅片'" name="0">
|
||||
<div class="search-form" style="display:flex;justify-content: space-between;">
|
||||
<el-form :inline="true" size="mini" class="base-search-form">
|
||||
<el-form-item label="名称">
|
||||
@@ -18,7 +18,7 @@
|
||||
:disabled="list.length === 0"
|
||||
size="mini"
|
||||
type="primary"
|
||||
@click="preview.visible = true"
|
||||
@click="handlePreview"
|
||||
>
|
||||
预览
|
||||
</el-button>
|
||||
@@ -200,7 +200,7 @@
|
||||
v-if="addOrEdit.visible"
|
||||
:visible.sync="addOrEdit.visible"
|
||||
:close-on-click-modal="false"
|
||||
:title="addOrEdit.title"
|
||||
:title="`${addOrEdit.title}`"
|
||||
width="600px"
|
||||
append-to-body
|
||||
custom-class="base-dialog-wrapper"
|
||||
@@ -303,6 +303,9 @@ export default {
|
||||
this.getList()
|
||||
},
|
||||
methods: {
|
||||
handlePreview() {
|
||||
window.open(`/ecrfPreview?SystemReadingCriterionId=${this.criterionId}&lang=${this.$i18n.locale}`)
|
||||
},
|
||||
getList() {
|
||||
this.loading = true
|
||||
this.searchData.ReadingQuestionCriterionSystemId = this.criterionId
|
||||
|
||||
@@ -104,6 +104,7 @@
|
||||
<el-button
|
||||
type="danger"
|
||||
size="mini"
|
||||
:disabled="scope.row.IsCompleteConfig"
|
||||
@click="handleDelete(scope.row)"
|
||||
>
|
||||
删除
|
||||
@@ -133,7 +134,7 @@
|
||||
|
||||
<el-dialog
|
||||
v-if="configVisible"
|
||||
title="eCRF"
|
||||
:title="'eCRF' + `(${rowData.CriterionName})`"
|
||||
:visible.sync="configVisible"
|
||||
:close-on-click-modal="false"
|
||||
:fullscreen="true"
|
||||
@@ -145,7 +146,7 @@
|
||||
|
||||
<el-dialog
|
||||
v-if="configBaseDataVisible"
|
||||
title="基础数据配置"
|
||||
:title="'基础数据配置' + `(${rowData.CriterionName})`"
|
||||
:visible.sync="configBaseDataVisible"
|
||||
:close-on-click-modal="false"
|
||||
:fullscreen="true"
|
||||
@@ -190,6 +191,7 @@ export default {
|
||||
addDialog: { title: '', visible: false }
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.getList()
|
||||
},
|
||||
|
||||
@@ -137,11 +137,10 @@ export default {
|
||||
})
|
||||
},
|
||||
handleDelete(row) {
|
||||
this.$confirm('Sure to delete?', {
|
||||
this.$confirm(this.$t('trials:uploadedDicoms:message:deleteMes'), {
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true,
|
||||
confirmButtonText: 'Ok',
|
||||
cancelButtonText: 'Cancel'
|
||||
|
||||
})
|
||||
.then(() => {
|
||||
this.loading = true
|
||||
@@ -150,7 +149,7 @@ export default {
|
||||
this.loading = false
|
||||
if (res.IsSuccess) {
|
||||
this.list.splice(this.list.findIndex(item => item.Id === row.Id), 1)
|
||||
this.$message.success('Deleted successfully!')
|
||||
this.$message.success(this.$t('common:message:deletedSuccessfully'))
|
||||
}
|
||||
}).catch(() => { this.loading = false })
|
||||
})
|
||||
|
||||