Compare commits
971 Commits
v2.1.1
...
v3.7.0_all
| Author | SHA1 | Date | |
|---|---|---|---|
| c30218f17a | |||
| 21711e5f0c | |||
| 4368b4ce1e | |||
| 03f922376e | |||
| 0325e34dcb | |||
| bb918b742e | |||
| 56da1a23c2 | |||
| d3c5a58db9 | |||
| d44945f688 | |||
| f370855683 | |||
| c582efd115 | |||
| c687c7a916 | |||
| 8e44080b00 | |||
| 56ca53cc93 | |||
| 0075ec6751 | |||
| 7e31341f1a | |||
| d4ca2eb934 | |||
| 84946888ad | |||
| d276c3d8ad | |||
| 7dccaf2ec8 | |||
| ae1b8d4654 | |||
| 49f709a32a | |||
| 335c369546 | |||
| 1a446007c7 | |||
| 76f9575140 | |||
| fd7783644f | |||
| f6a3e11aa2 | |||
| c2768cea85 | |||
| 2d37b166a2 | |||
| cff5ec5a40 | |||
| 0947a199b6 | |||
| 2ecfe74b33 | |||
| 6147e923de | |||
| 3a07d5a983 | |||
| 2747868ea7 | |||
| dcc27d71b4 | |||
| 30c0482b6d | |||
| 641298b32d | |||
| 09a536f549 | |||
| 35ab818741 | |||
| e00358859c | |||
| aa24978d2b | |||
| ee497a8d1e | |||
| 935575576f | |||
| b45e75007b | |||
| 52ae0c359e | |||
| 06e6594b75 | |||
| 73d62b484c | |||
| 0ff93a220d | |||
| 2071b5bcc4 | |||
| e1378f4ee5 | |||
| a6b6e7c9d4 | |||
| 857fb53fa1 | |||
| 9db6c1a7ac | |||
| fd0461644e | |||
| 10263720d4 | |||
| 7548f3aa60 | |||
| ad3d2eb3fc | |||
| d0406fcd83 | |||
| 9159b55096 | |||
| faebdee755 | |||
| 2fc672dfab | |||
| 4dc4e87900 | |||
| 13d00a8bb4 | |||
| fb95cf7f2f | |||
| 78f048fda5 | |||
| 200adb8490 | |||
| f1496b5084 | |||
| 7b06715bff | |||
| 3091d5b6f0 | |||
| c117abb2d4 | |||
| dbc3f13c65 | |||
| ea6927a2a7 | |||
| b69a716b04 | |||
| 7e71fa26d7 | |||
| 4fed40ff7d | |||
| ee4ff35c90 | |||
| c9b92decaf | |||
| eed3bc346d | |||
| 6edef14f07 | |||
| ab49983759 | |||
| 5a09a6fb4a | |||
| ac93bf7d6b | |||
| c9c6dd5c1d | |||
| e3e1cd6b0d | |||
| f3cf90bd28 | |||
| 70847d17f1 | |||
| 2cfc39b23f | |||
| c8676b3040 | |||
| 73bd04d04a | |||
| 0ca4badb77 | |||
| 80b92ca132 | |||
| 58865bef28 | |||
| 9fd40d0973 | |||
| 266ebd9122 | |||
| fee729e16c | |||
| 10a3e9c6ba | |||
| 990f79fdfe | |||
| 6360aee0ff | |||
| 685b81e5ec | |||
| e38e395436 | |||
| 39af6e25ee | |||
| b15e6e0422 | |||
| 8f99a80352 | |||
| 936a87e738 | |||
| 2af165b201 | |||
| 3d5efc07ad | |||
| 21e8d640d2 | |||
| b0ce456909 | |||
| b8e1306955 | |||
| 37a38ad288 | |||
| 9ee05c9510 | |||
| 275a68bb6a | |||
| f3f70e8549 | |||
| e15e9d80c4 | |||
| f7538c1ed8 | |||
| a9dba08a8d | |||
| acf0713385 | |||
| cee872000a | |||
| 4a857680d0 | |||
| a47d0984dc | |||
| e333b126b6 | |||
| 3618842f44 | |||
| fd8c848c9e | |||
| 09614a0239 | |||
| 6fe8f1d81a | |||
| 0bd7f715c4 | |||
| 041d88161e | |||
| 79a62aa056 | |||
| b86b4d9676 | |||
| aeaac80012 | |||
| e0ef20cf08 | |||
| 169a66f5dd | |||
| 7e39b31123 | |||
| 18765450a6 | |||
| dff8c84d9c | |||
| d962c34846 | |||
| cd9794d818 | |||
| 5034b7cf18 | |||
| fdde84c68a | |||
| 4c54ff6f52 | |||
| de3285dc1b | |||
| 7f0c035c4c | |||
| 43593e8def | |||
| 48b0b608d8 | |||
| 69287a772b | |||
| 337d5a9489 | |||
| cfeb81ee1e | |||
| 09f92f01aa | |||
| 6d1094936b | |||
| 8836a2793a | |||
| c36ece8923 | |||
| a82213b90c | |||
| 98facdd2ee | |||
| d080b0b5ea | |||
| 338902ca0c | |||
| 7ae6a11cf0 | |||
| cdbe1cb1a9 | |||
| 232037ec58 | |||
| b18c1120ab | |||
| f6a7831963 | |||
| 08a4473bbc | |||
| 9008ddafa4 | |||
| 7012ed4c2c | |||
| 1d8c8c30d0 | |||
| 090f790df4 | |||
| 82d051f388 | |||
| 5a3631c332 | |||
| c00b5526c3 | |||
| 2e35abd3a3 | |||
| 9bc3f6c56e | |||
| 5588912b62 | |||
| 37cf913d6d | |||
| 94ba767090 | |||
| a406c7cd81 | |||
| 480878a3db | |||
| a85499119d | |||
| 4cbe9cad8e | |||
| 2dfc06c679 | |||
| a591ad9fed | |||
| 5420e69b59 | |||
| f157c96f65 | |||
| 9588ace87f | |||
| cc57ac379b | |||
| 074920552a | |||
| 2a00a24058 | |||
| 06cc4ec0fe | |||
| decea393a5 | |||
| 65b0fab80d | |||
| 1d4098ae14 | |||
| 5c4f303a0d | |||
| 8dcc5bdf8a | |||
| b3e4a73a34 | |||
| 60b4a038f6 | |||
| 4e3738100a | |||
| 8216889078 | |||
| 6ab4ee6a91 | |||
| a8dde73a8c | |||
| b2b11611c1 | |||
| 04c55fa3ba | |||
| 4957330c1c | |||
| ea9dfd6ea7 | |||
| 60f7191659 | |||
| 6f560c1cd7 | |||
| 524cd4a3d1 | |||
| f342c93eec | |||
| a364025bd2 | |||
| 5fa6a5e686 | |||
| 6d34164a16 | |||
| e15335ddab | |||
| b373a80498 | |||
| f0fb3ed5ff | |||
| 411deee8af | |||
| b2942e0323 | |||
| 78e371ab9f | |||
| ffeb607ad3 | |||
| 7dd68068a1 | |||
| 51d7f3b06b | |||
| a060db5530 | |||
| 30caf045ed | |||
| 6264b2ec70 | |||
| 9d1f73b3f7 | |||
| d557aa4cc0 | |||
| 81351aeb7a | |||
| ee1a568bed | |||
| e721668eb0 | |||
| 5edb30c51f | |||
| 9c5bd7193f | |||
| 3e9b7ccfc1 | |||
| f1717c7000 | |||
| 946d535f68 | |||
| 1a326cb70f | |||
| 5a9344b190 | |||
| 4eaebd658b | |||
| 581047c569 | |||
| 87677df925 | |||
| 56e81fbf7b | |||
| 473875a9d2 | |||
| 44952c79c2 | |||
| 58aebdbba4 | |||
| 2411d85af4 | |||
| 572ea6dd69 | |||
| 6e417a22ba | |||
| 3478e8f7bc | |||
| f9982a9132 | |||
| d3238205e1 | |||
| ff083361d4 | |||
| 9c038a979d | |||
| 5974a2e8a4 | |||
| 30151a2324 | |||
| 28293aba7d | |||
| d36caf8c69 | |||
| e6bd2d5009 | |||
| baf4b96b3f | |||
| acb48179ab | |||
| 20889e8724 | |||
| 751b81c7bf | |||
| 0bc7e0967d | |||
| 05181754bb | |||
| 5ab62d5d3b | |||
| 83d96bf89e | |||
| 0b2c966a72 | |||
| ffda530daa | |||
| 4c0641f374 | |||
| 54c7c034a4 | |||
| 7167668c2a | |||
| 1a722fcb07 | |||
| 648e66d5ef | |||
| e6e6902e85 | |||
| 04dd6b056f | |||
| 96b3ba6e9a | |||
| 8d22362fff | |||
| 436bfbced9 | |||
| 5273b81f94 | |||
| 6134db4984 | |||
| 6e7d9e8e5d | |||
| 741dc958f1 | |||
| 101ffd91af | |||
| cecbc3f628 | |||
| dd7bf104e7 | |||
| 6e85584c43 | |||
| c579dbb24d | |||
| 452132ca38 | |||
| ebc396340e | |||
| 5946aa79c3 | |||
| 2bc20aaa5e | |||
| 793295a8fe | |||
| eaf3e32fdd | |||
| ba40a797df | |||
| 545679f999 | |||
| 1a74dd1a2e | |||
| 9dd8b05fd7 | |||
| e273008b37 | |||
| 53684d224e | |||
| f9e843571c | |||
| 14e9adb3af | |||
| fedb7bf46f | |||
| ce520be8ca | |||
| 9d92c316c1 | |||
| f077cafcfe | |||
| fd7d0b7202 | |||
| 96586517bd | |||
| 5b5a2c0180 | |||
| b089bb96f1 | |||
| 9da4850bd7 | |||
| a6bcb376fc | |||
| 7abc07424b | |||
| e9f2bbca23 | |||
| b0ede05cf4 | |||
| ca1218f792 | |||
| 8ed2da601b | |||
| 08696dbb5f | |||
| 645ea40bfd | |||
| b970af00c1 | |||
| 5fe9508428 | |||
| a302fcd963 | |||
| 5258228d3b | |||
| 1c00be39f0 | |||
| cf1fe01d03 | |||
| 4c78bad14f | |||
| ebcddad130 | |||
| 42589cd1dc | |||
| d81fa1f908 | |||
| 217fe0dce4 | |||
| fffa7f327b | |||
| 5417f1285a | |||
| b75cbcc911 | |||
| a68f304307 | |||
| 0a00bd8a7c | |||
| e90efbb52f | |||
| 3c320a5769 | |||
| 98472b5c35 | |||
| 3f2354a8ac | |||
| 8a94c40e0e | |||
| 42eedcd3b3 | |||
| 3c2038ac0e | |||
| c8323540cc | |||
| ec80530afc | |||
| c76e7f344c | |||
| 5aca8260dc | |||
| c4baa2ecb8 | |||
| 420375ecab | |||
| f07e1c02e9 | |||
| eb054736a5 | |||
| 9d771b5d9b | |||
| d0a6282ce9 | |||
| d84cf92b03 | |||
| b679fb75ba | |||
| a3c0127a7a | |||
| c46ec2415b | |||
| f0e060f12e | |||
| 65a0d3b9df | |||
| 1a48fb86bc | |||
| 0fc374de47 | |||
| f94c5e1f3f | |||
| 352bd3e98f | |||
| 22fe4475d0 | |||
| 7a3d1f1a58 | |||
| 3159c822c7 | |||
| fa0ce6e7e1 | |||
| c29794d07b | |||
| 6ba5536554 | |||
| e6b93c2fca | |||
| b362147577 | |||
| 347b13beb4 | |||
| 16b8aac08f | |||
| b0b517e71e | |||
| cf3d746d63 | |||
| 0fdbf642d8 | |||
| 0ebd1df81d | |||
| 6f90a09558 | |||
| f3b77442fc | |||
| 47c6a9ba6a | |||
| 3e96c7e376 | |||
| 1a902d94c9 | |||
| fb1cef7cd3 | |||
| 83f909daca | |||
| 036b51cee6 | |||
| 8da82d8269 | |||
| c981c45a14 | |||
| 91848b98b7 | |||
| ec262cff53 | |||
| 9745b7e3ee | |||
| 97736e4b5d | |||
| 12991c83cb | |||
| 2a99fa2ecb | |||
| 4a1ed660ca | |||
| 8632a835c2 | |||
| 958cf01649 | |||
| 01602bd60a | |||
| 14c69fa533 | |||
| 9f6c89a983 | |||
| 51e2227bfe | |||
| ff77973a6c | |||
| f18ced524c | |||
| d34614c422 | |||
| c5e54f66a0 | |||
| 422dea8ddf | |||
| 31ba9e8343 | |||
| 5a303dfc4a | |||
| d7269976e9 | |||
| 3eab5ee9e6 | |||
| fb8afcda7d | |||
| feb7dddd65 | |||
| ab81c8d3a7 | |||
| 7c1daee18c | |||
| 578940aa40 | |||
| 92ea7282e6 | |||
| 4667e9db40 | |||
| 5558c30223 | |||
| 97842dc619 | |||
| a7c3e6e3dd | |||
| 3c489e3d98 | |||
| 951c7ebc79 | |||
| c321002504 | |||
| 708579b36d | |||
| 949f1e8e33 | |||
| 1725fc56f3 | |||
| ee493c2728 | |||
| af68147848 | |||
| 5dab553e3b | |||
| 6aa9fff66d | |||
| 63af9e4ca9 | |||
| 3e146061dd | |||
| 3580f50b07 | |||
| 99e5160436 | |||
| 5c00114d7c | |||
| 394c0e2caf | |||
| cb8adfb236 | |||
| d5ef6106db | |||
| 04486dca56 | |||
| c78c5dda4d | |||
| 06bea53726 | |||
| fbfe4962b3 | |||
| 28f007c13c | |||
| ae74abe727 | |||
| 47d6af5c46 | |||
| 091ec832a0 | |||
| 1478bb4c17 | |||
| 1595b94d59 | |||
| b4ac531d59 | |||
| 5937097778 | |||
| 5149d69f60 | |||
| 4cd59179bd | |||
| 0ee38b7f4a | |||
| 8dc91c33e5 | |||
| f1d62a418f | |||
| 8059b07ddc | |||
| fb2c06a334 | |||
| 9dc50c1418 | |||
| f6fc896982 | |||
| 0079050109 | |||
| a781606512 | |||
| e142f4d3dd | |||
| 4a26a31746 | |||
| 948de9468b | |||
| 53b670befd | |||
| 7690f0798a | |||
| e091944e5d | |||
| c154ead0d1 | |||
| a18ce77c59 | |||
| fe833717cd | |||
| 5c888f761f | |||
| 9100fca57a | |||
| c18dfa7f92 | |||
| 11d241bcd1 | |||
| c9af500e3b | |||
| 2a9faa62b6 | |||
| 38b4a880f2 | |||
| 04462c14d0 | |||
| dcfaaa37ab | |||
| 3d09762848 | |||
| 1c8b458cac | |||
| e4539b40de | |||
| 6bd68fb263 | |||
| 515936f018 | |||
| 8d28f88114 | |||
| 8ec13295bc | |||
| f61cc91955 | |||
| 3c7c0e20b5 | |||
| 4b19f25111 | |||
| 5f88b0e216 | |||
| f00829ed90 | |||
| afd6efd02e | |||
| cf1eef7447 | |||
| 9358acb84c | |||
| 9a00b61b1a | |||
| bad23add8c | |||
| 17d42c8d63 | |||
| f36bebb19a | |||
| c300bcd04f | |||
| a9c2079c79 | |||
| 50ac6c4977 | |||
| d25915f663 | |||
| c0a95521e4 | |||
| e2af6826b4 | |||
| db4793faad | |||
| dc073c6a4d | |||
| 079b415e80 | |||
| be7744a0da | |||
| 80e26d2b94 | |||
| a2b8777d3d | |||
| a54192ebaf | |||
| 04a8fe7e50 | |||
| 71bbf0f303 | |||
| 94b89f2135 | |||
| d3c139ab5d | |||
| 0e749d830b | |||
| 5158e6e5ec | |||
| 1832b9a636 | |||
| db8bd1e464 | |||
| 372adbd580 | |||
| 0cbdc092d1 | |||
| 55201e82eb | |||
| e4673ecdaa | |||
| 71de6bec63 | |||
| ce704c8e2a | |||
| 64569f8898 | |||
| 8d3e1282a4 | |||
| d5e829bbcf | |||
| f5d4843c55 | |||
| 1b5616282e | |||
| 9e774a457c | |||
| d5ce6a409a | |||
| b972eb1068 | |||
| efd17cdd60 | |||
| 63505e8f6e | |||
| bd4814581a | |||
| c7840a7382 | |||
| c3e049cbd0 | |||
| a6ae4080cb | |||
| 2e90f73da2 | |||
| 85b26230d1 | |||
| fa70a83391 | |||
| bbf85093d5 | |||
| d712776c46 | |||
| 9710b8bc7d | |||
| 3909eb5610 | |||
| cd5fd2f4d4 | |||
| c8a26d73e3 | |||
| e89423c666 | |||
| 67d8cdbc6c | |||
| c14a793906 | |||
| 7f87042e59 | |||
| 4aac17a5e2 | |||
| 5f1d0dafa4 | |||
| 727b67a50d | |||
| dfbbd1bd1f | |||
| 2d9de317c4 | |||
| 56912b766d | |||
| 8baced93a3 | |||
| 0c545517b6 | |||
| a3d6e0ce08 | |||
| 9dcff93372 | |||
| 948e1668b6 | |||
| b17908b581 | |||
| 3bfe099e21 | |||
| 93e755a09c | |||
| 6196f0a463 | |||
| 1481b86fb3 | |||
| eacaa7ed81 | |||
| bc711932f7 | |||
| 44d6f3228f | |||
| dad784228b | |||
| ce02dbbd30 | |||
| d4c2c02602 | |||
| 7935ce86de | |||
| 1224660d1d | |||
| 1b9fc77ec4 | |||
| 4a21f16ade | |||
| a9e6d2ec0c | |||
| e00ac210fe | |||
| cdc245699e | |||
| 9de7f261bb | |||
| ae434bfce4 | |||
| 0ee985da5a | |||
| dbba190980 | |||
| 07c538a1b2 | |||
| 472bf3f35a | |||
| b66fff6c42 | |||
| 2be616ee49 | |||
| 51c63e8057 | |||
| 758c347eb0 | |||
| 7bdc1b06d3 | |||
| e364b950ca | |||
| 3690a6e014 | |||
| 897dcbca78 | |||
| f8c7ddd223 | |||
| 8c143f35f8 | |||
| a5f30ec51f | |||
| 9226ae0aeb | |||
| baefc1338d | |||
| bb6ec4cc2f | |||
| 94053034b4 | |||
| bdbc714233 | |||
| 84f3ce8340 | |||
| b6219301e1 | |||
| a4603a2963 | |||
| 5bfa15d628 | |||
| a39bb0ce5f | |||
| a43ccf6f31 | |||
| 1e2a74a65f | |||
| 6c362861a0 | |||
| 2a5ec11660 | |||
| 509be1e382 | |||
| 80601e0ccd | |||
| 435f467646 | |||
| 644c6801a0 | |||
| 1f75c124f1 | |||
| bcbdd383ae | |||
| 7a1d4cda96 | |||
| 8bae42049c | |||
| 09a63610cf | |||
| 46e024bfbc | |||
| c767f094fc | |||
| 42e0a938da | |||
| 3f4b40ea74 | |||
| f210df80e6 | |||
| 0f79e8efef | |||
| d6251419e6 | |||
| 7db5f7f3e9 | |||
| cd79eb7597 | |||
| 812cbce06b | |||
| 3b92086047 | |||
| 0fa24b8518 | |||
| 7e7ea37857 | |||
| e550843fd1 | |||
| 3cb20a6a43 | |||
| 0acea1abff | |||
| 9760185bf6 | |||
| 75be8dd5b1 | |||
| a7893c4941 | |||
| ef97f700ab | |||
| 6fb01abbc5 | |||
| fe1b58ade2 | |||
| 1998867ca6 | |||
| a351204865 | |||
| 4da1948cb0 | |||
| 55ebea88af | |||
| 4b830b37c9 | |||
| 537cc05601 | |||
| 8f9f27c550 | |||
| 57f72dd4d0 | |||
| e2e19fa456 | |||
| 98a5148e52 | |||
| c2ae049ad7 | |||
| b44acde9b5 | |||
| db467f22a7 | |||
| 53c91fc349 | |||
| 92028a7e44 | |||
| 8ce40fa3d4 | |||
| 05c7f76484 | |||
| 71a1e9a63b | |||
| 0606aa560a | |||
| 1bbca48ba8 | |||
| d0c15f2302 | |||
| c9ff5d51b4 | |||
| cce5d785e4 | |||
| 234022d905 | |||
| ab529aaf6c | |||
| 07c6d1a23d | |||
| 8f780e180e | |||
| 87f17b9fc5 | |||
| 5a93d001b4 | |||
| d822552e0c | |||
| 832fa30cc9 | |||
| 3af1b390f1 | |||
| a3695151dc | |||
| c269d7637f | |||
| 664413e5d7 | |||
| 986f909628 | |||
| 221940cc5f | |||
| 2a392fb738 | |||
| 2b47cd0c34 | |||
| 1900f3fe77 | |||
| 37fe6fea69 | |||
| 3fbb5ee4ad | |||
| b1958fd295 | |||
| 8b3d83ae0b | |||
| 081c2615be | |||
| f97c675771 | |||
| 1beddbf8e8 | |||
| 8921e84303 | |||
| 43329545d8 | |||
| 50333488a5 | |||
| 624444e3b9 | |||
| 1cd0f2627d | |||
| 18007b0524 | |||
| d92861ad77 | |||
| 8a6181b108 | |||
| 6840772959 | |||
| 1bc7ee3345 | |||
| 5f25f726c2 | |||
| 9b14d2d6a5 | |||
| 130f2bc4be | |||
| 832bc376be | |||
| 432385fc14 | |||
| 4d5ac2b518 | |||
| b83c26b8fd | |||
| b59fc67696 | |||
| af3afc7263 | |||
| 63c3dd26f5 | |||
| 892196fe9a | |||
| bbda918cde | |||
| 003ec82f48 | |||
| 4992faf66c | |||
| 34c612d9e4 | |||
| 844f1e228c | |||
| cf5fde80d4 | |||
| 49ea36c50f | |||
| f6e2b67c61 | |||
| 69a4a7df6d | |||
| 649f99664e | |||
| ef762ff21f | |||
| 02abd5c803 | |||
| 5e7342b27d | |||
| ca95d7090c | |||
| cdec71999a | |||
| 7990eff7a4 | |||
| 280f8c26ac | |||
| 4e05eaa4c5 | |||
| c6645ed800 | |||
| a674340c5e | |||
| cbd8890cb3 | |||
| b25fb55d10 | |||
| 88646bea1b | |||
| 9915b84808 | |||
| 35c1214de3 | |||
| 434b1a7e63 | |||
| 5c7d84117c | |||
| 4b9890205e | |||
| d5898139b5 | |||
| bf438069e2 | |||
| c5965b10d8 | |||
| da5ace3397 | |||
| 4674097078 | |||
| fea1607f1b | |||
| d2336bc5e1 | |||
| cf0d29557a | |||
| bb4c3c86b0 | |||
| 84a6e28677 | |||
| 5b70c1d8b8 | |||
| f942abe09b | |||
| ad4eb300f0 | |||
| 064a5c4a0e | |||
| 6d688a157b | |||
| d612af5e3b | |||
| e1c0b0fa38 | |||
| ac0979c824 | |||
| 78ba7ccba8 | |||
| b8ff5ebd43 | |||
| 5eb2541834 | |||
| 462b0d17b1 | |||
| 7cc54084dc | |||
| 32297110d9 | |||
| b7717d0461 | |||
| 97c078c46a | |||
| 17019e6261 | |||
| 4a49479985 | |||
| e49d76bc80 | |||
| d6cf2b502b | |||
| c741d779f2 | |||
| 7f847c9721 | |||
| fa2c5ecb73 | |||
| eb1578ada3 | |||
| 90758f3b2a | |||
| 766c48bdbf | |||
| d16520cc59 | |||
| 0252213b6e | |||
| ce44147e6e | |||
| 0ea4ac910a | |||
| 4f61f0ad48 | |||
| 4a5ff61ef7 | |||
| 88a0bb2d2d | |||
| b153669b69 | |||
| 449a7759be | |||
| 337920964d | |||
| 2a7946ae42 | |||
| c233f95f5f | |||
| f87cc2d97f | |||
| 02bb521b8f | |||
| 53e84ae34b | |||
| d6feeef7b5 | |||
| 18fc7b146a | |||
| 3792f46388 | |||
| f35236609c | |||
| e46b653bc4 | |||
| 4437c749ca | |||
| 74ebac4967 | |||
| a9f21795cb | |||
| a5ca8183cd | |||
| e7970e52bc | |||
| 74a9e10ce6 | |||
| df5c106d94 | |||
| ae0f9edb27 | |||
| 3d4bb704f1 | |||
| 85efec3730 | |||
| 8b0ee2d0a2 | |||
| 41c1572ad8 | |||
| 5d555158fe | |||
| 1fd0b5d4db | |||
| 693d86cf00 | |||
| 9a3f872d63 | |||
| 5b82a1aa06 | |||
| 3cb88452dc | |||
| 2fa1c7c17b | |||
| b6a3085083 | |||
| 8a7fc033cd | |||
| e0cf946d18 | |||
| c5b33b6bd1 | |||
| aec00d9ba2 | |||
| 341830c5a0 | |||
| ff45fe4858 | |||
| c13ed675a7 | |||
| 6917e91398 | |||
| 18a5c247d8 | |||
| 51bf9a7c14 | |||
| 8278041aeb | |||
| 39bb7a46fd | |||
| 1c234fbaff | |||
| ca1f5872be | |||
| 2ae3844d5e | |||
| c2db7691d1 | |||
| 543a49fcb6 | |||
| df6cf7137c | |||
| d7450cab04 | |||
| 496d85265b | |||
| b4b1162ea0 | |||
| 33e39941fb | |||
| 1b5ba9f56b | |||
| 0aadc70e74 | |||
| 94aed3ade4 | |||
| 9657eac673 | |||
| 680a8b3c42 | |||
| 6e6f88620a | |||
| 14f4f92d84 | |||
| 2c4597c0a9 | |||
| 757f1cd5a8 | |||
| 3c62a58d64 | |||
| bec39867a9 | |||
| dca8713a2e | |||
| a004acee4b | |||
| 35ef0eff90 | |||
| c70fd3383e | |||
| 3e2f640b68 | |||
| bf6c5f4623 | |||
| df259385ec | |||
| c5f51a17da | |||
| 94c0610496 | |||
| ccf4946b70 | |||
| 3b4a65ba04 | |||
| 3a8ae4c089 | |||
| 88eb98c0e6 | |||
| 63048d8c64 | |||
| e8a18fc642 | |||
| fa0c930886 | |||
| 708aa54f3a | |||
| 57337f7980 | |||
| 89f4d122dd | |||
| b92bec3eed | |||
| 72f32e47a0 | |||
| 43908013e3 | |||
| 80bd1a3f23 | |||
| de60ea050c | |||
| 7cb3dce262 | |||
| 416c8df729 | |||
| b13a4b01df | |||
| 075c3532dc | |||
| fa40b08049 | |||
| 55c0a4e051 | |||
| 0795808075 | |||
| 0fa6316f52 | |||
| 9cd111ca58 | |||
| 2c18182dd0 | |||
| 36cad9373e | |||
| fcbed695b0 | |||
| 5a01d8587b | |||
| 4570a21a63 | |||
| 8775472470 | |||
| bb72341519 | |||
| 78afc86411 | |||
| 91ff6a7aa2 | |||
| b3ec97ffcc | |||
| 24fe9e425c | |||
| 09d9e79f40 | |||
| 7f30a186df | |||
| 65d1e6a879 | |||
| e963603d22 | |||
| 3b68f4d4d9 | |||
| 4fd30c495f | |||
| 37158397be | |||
| b4bdb0b3f7 | |||
| cd6cbf8c26 | |||
| bb5fe95d30 | |||
| 1c63f74a6d | |||
| 0094b17ec2 | |||
| 80f377ecd6 | |||
| 55ce5ce919 | |||
| a09fa134f8 | |||
| f2854b29aa | |||
| 1ff06c2bc3 | |||
| 604ca8b312 | |||
| e6bb5eb0a1 | |||
| 109a95a96b | |||
| cb7ae9ca6f | |||
| e4b4898e27 | |||
| 5066ef526d | |||
| 088ff85dcc | |||
| 96cfb8a2b2 | |||
| 32ee9f040c | |||
| dadf6a78a1 | |||
| 8a8e92cda3 | |||
| 4566e50dd2 | |||
| 01ce2e8dab | |||
| dc804d9372 | |||
| 9c64b9a8ed | |||
| d52979621f | |||
| 5ffc3e4d13 | |||
| ea7ac65814 | |||
| cdfa6f8ac6 | |||
| 6ce3a892b6 | |||
| 28e9a0ddfb | |||
| 1f27948814 | |||
| 3bff16a446 | |||
| d5bfccdeb0 | |||
| 9e046a07d4 | |||
| 046831e700 | |||
| e7ad502390 | |||
| 9f1a2b89b7 | |||
| 5878fcb12b | |||
| 27e280bd97 | |||
| 91594ddb1a | |||
| 4c0c0945a1 | |||
| 2b3e157d88 | |||
| e2d4bb29db | |||
| 865ace6db0 | |||
| 7bc3931e1a | |||
| 94a945291d | |||
| 49a303d5e8 | |||
| 1cabc94cea | |||
| 760f8e9f46 | |||
| 38e6586c84 | |||
| d7ca307fa2 | |||
| 188cec1646 | |||
| 4a4f236772 | |||
| 06847cd801 | |||
| 365810d4e6 | |||
| ed83135062 | |||
| beabf9b6dd | |||
| 238b4898c7 | |||
| 4372773924 | |||
| d399ec904a | |||
| 8ecc971940 | |||
| 66b3b290fb | |||
| a9c7f3e547 | |||
| b54dada91e | |||
| 3ead7c3ae1 | |||
| 9c44ffaa8e | |||
| ea5ef384f2 | |||
| 73f7acfd5a | |||
| 728d62f851 | |||
| cd471735d7 | |||
| 30b35af000 | |||
| 3372c88607 | |||
| ce95008fdd | |||
| bb54b20734 | |||
| bd790ee24b | |||
| 11018ab29f | |||
| 67c4f7b3d9 | |||
| 9bd67f9905 | |||
| 283be0480e |
1
.gitattributes
vendored
@ -2,3 +2,4 @@
|
||||
*.css linguist-language=Java
|
||||
*.html linguist-language=Java
|
||||
*.vue linguist-language=Java
|
||||
*.sql linguist-language=Java
|
||||
|
||||
9
.github/ISSUE_TEMPLATE.md
vendored
@ -1,12 +1,13 @@
|
||||
##### 版本号:
|
||||
|
||||
|
||||
##### 问题描述:
|
||||
|
||||
|
||||
##### 截图&代码:
|
||||
##### 错误截图:
|
||||
|
||||
|
||||
|
||||
|
||||
友情提示: 未按格式要求发帖,会直接删掉。
|
||||
#### 友情提示:
|
||||
- 未按格式要求发帖、描述过于简抽象的,会被直接删掉;
|
||||
- 请确保问题描述清楚,方便我们理解并一次性调查解决问题;
|
||||
- 如果使用的不是master,请说明你使用的那个分支
|
||||
15
.gitignore
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
## ide
|
||||
**/.idea
|
||||
*.iml
|
||||
rebel.xml
|
||||
|
||||
## backend
|
||||
**/target
|
||||
**/logs
|
||||
|
||||
## front
|
||||
**/*.lock
|
||||
os_del.cmd
|
||||
os_del_doc.cmd
|
||||
.svn
|
||||
derby.log
|
||||
19
LICENSE
@ -186,7 +186,7 @@
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright (c) 2019 <a href="http://www.jeecg.org">Jeecg Boot</a> All rights reserved.
|
||||
Copyright (c) 2019 <a href="http://www.jeecg.com">Jeecg Boot</a> All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -198,4 +198,19 @@
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
limitations under the License.
|
||||
|
||||
In any case, you must not make any such use of this software as to develop software which may be considered competitive with this software.
|
||||
|
||||
开源协议补充
|
||||
JeecgBoot 是由 北京国炬信息技术有限公司 发行的软件。 总部位于北京,地址:中国·北京·朝阳区科荟前街1号院奥林佳泰大厦。邮箱:jeecgos@163.com
|
||||
本软件受适用的国家软件著作权法(包括国际条约)和双重保护许可。
|
||||
|
||||
1.允许基于本平台软件开展业务系统开发。
|
||||
2.JeecgBoot底层依赖的非开源功能:online lib依赖、仪表盘lib依赖等,统一采用LGPL开源协议(不二次改造、不拆分出jeecgboot之外使用,就不产生侵权)
|
||||
3.不得基于该平台软件的基础,修改包装成一个与JeecgBoot平台软件功能类似的产品进行发布、销售,或与JeecgBoot参与同类软件产品市场的竞争。
|
||||
违反此条款属于侵权行为,须赔偿侵权经济损失,同时立即停止著作权侵权行为。
|
||||
|
||||
总结:在遵循Apache开源协议和开源协议补充条款下,允许商用使用,不会造成侵权行为!
|
||||
解释权归:http://www.jeecg.com
|
||||
|
||||
545
README-EN.md
Normal file
@ -0,0 +1,545 @@
|
||||
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
JEECG BOOT Low Code Development Platform
|
||||
===============
|
||||
|
||||
当前最新版本: 3.7.0(发布日期:2024-06-17)
|
||||
|
||||
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot/blob/master/LICENSE)
|
||||
[](http://www.jeecg.com)
|
||||
[](https://jeecg.blog.csdn.net)
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot)
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot)
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot)
|
||||
|
||||
|
||||
|
||||
Project introduction
|
||||
-----------------------------------
|
||||
|
||||
<h3 align="center">Java Low Code Platform for Enterprise web applications</h3>
|
||||
|
||||
JeecgBoot is a `low code development platform` based on code `generators`! Front and back end separation architecture SpringBoot2.x, SpringCloud, Ant Design&Vue, Mybatis plus, Shiro, JWT, support for microservices. The powerful code generator makes the front and back end of the code generation, low code development! JeecgBoot leads a new low-code development paradigm (OnlineCoding-> Code Generator -> Manual MERGE) that helps resolve 70% of the duplication in Java projects and makes development more business-focused. Not only can quickly improve efficiency, save research and development costs, but also do not lose flexibility!
|
||||
|
||||
JeecgBoot provides a series of low code modules to make Online development truly zero code: Online form development, online reports, report configuration capabilities, online chart design, large screen design, mobile configuration capabilities, form designer, online design flow, process automation configuration, plug-in capabilities (pluggable) and more!
|
||||
|
||||
|
||||
The purpose of JEECG is: simple functions are implemented by OnlineCoding configuration, so that zero code development; Complex functions are generated by code generator and manually Merge to achieve low code development, which ensures both intelligence and flexibility. The implementation of low code development and support flexible coding at the same time, to solve the current low code products are generally not flexible drawbacks!
|
||||
|
||||
JEECG Business process: Using workflow to implement and extend the task interface for developing and writing business logic, forms provides a variety of solutions: form designer, online configuration form, and coding form. At the same time, the separation design of process and form (loose coupling) is realized, and the flexible configuration of task nodes is supported, which not only ensures the confidentiality of the company's process, but also reduces the workload of developers.
|
||||
|
||||
|
||||
Technical support
|
||||
-----------------------------------
|
||||
|
||||
Problems or bugs in use can be found in [Making on the Issues](https://github.com/jeecgboot/JeecgBoot/issues/new)
|
||||
|
||||
Official Support: http://jeecg.com/doc/help
|
||||
|
||||
|
||||
|
||||
##### Project description
|
||||
|
||||
| Project | description |
|
||||
|--------------------|------------------------|
|
||||
| `jeecg-boot` | SpringBoot background source code (support microservices) |
|
||||
| `jeecgboot-vue3` | Vue3+TS new front-end source code|
|
||||
| `jeecg-uniapp` | [APP development framework, a code multi terminal adaptation, and support APP, small program, H5](https://github.com/jeecgboot/jeecg-uniapp) |
|
||||
|
||||
|
||||
|
||||
Download other source code
|
||||
-----------------------------------
|
||||
- APP SourceCode:https://github.com/jeecgboot/jeecg-uniapp
|
||||
|
||||
|
||||
|
||||
For the project
|
||||
-----------------------------------
|
||||
Jeecg-Boot low code development platform can be applied in the development of any J2EE project, especially for SAAS projects, enterprise information management system (MIS), internal office system (OA), enterprise resource planning system (ERP), customer relationship management system (CRM), etc. Its semi-intelligent manual Merge development method, Can significantly improve the development efficiency of more than 70%, greatly reduce the development cost.
|
||||
|
||||
|
||||
|
||||
Docker starts the project
|
||||
-----------------------------------
|
||||
|
||||
- [Docker starts the monomer background](https://help.jeecg.com/java/setup/docker/up.html)
|
||||
- [Docker starts the front-end](http://help.jeecg.com/publish/docker.html)
|
||||
- [Docker starts the micro-service background](https://help.jeecg.com/java/springcloud/docker.html)
|
||||
- [ChatGPT AI Config](https://help.jeecg.com/java/chatgpt.html)
|
||||
|
||||
|
||||
|
||||
Technical documentation
|
||||
-----------------------------------
|
||||
|
||||
- Website: [http://www.jeecg.com](http://www.jeecg.com)
|
||||
- Doc: [http://help.jeecg.com](http://help.jeecg.com)
|
||||
- Newbie guide: [Quick start](http://www.jeecg.com/doc/quickstart) | [video](https://space.bilibili.com/454617261/channel/series) | [Q&A ](http://www.jeecg.com/doc/qa) | [help](http://jeecg.com/doc/help) | [1 minute experience](https://my.oschina.net/jeecg/blog/3083313)
|
||||
- Microservice Development: [Monomer upgrade to microservice](https://help.jeecg.com/java/springcloud/switchcloud/monomer.html)
|
||||
- QQ group : ⑨808791225、⑧825232878、⑦791696430、⑥730954414(full)、683903138(full)、⑤860162132(full)、④774126647(full)、③816531124(full)、②769925425(full)、①284271917(full)
|
||||
- Demo : [OnlineDemo](http://boot3.jeecg.com) | [APP](http://jeecg.com/appIndex)
|
||||
> [please click obtain account password to obtain](http://jeecg.com/doc/demo)
|
||||
|
||||
|
||||
Star charts
|
||||
-----------------------------------
|
||||
|
||||
[](https://star-history.com/#jeecgboot/jeecg-boot)
|
||||
|
||||
|
||||
|
||||
|
||||
Background directory Structure
|
||||
-----------------------------------
|
||||
```
|
||||
project structure
|
||||
├─jeecg-boot-parent
|
||||
│ ├─jeecg-boot-base-core
|
||||
│ ├─jeecg-module-demo
|
||||
│ ├─jeecg-module-system
|
||||
│ │ ├─jeecg-system-biz
|
||||
│ │ ├─jeecg-system-start system (8080)
|
||||
│ │ ├─jeecg-system-api
|
||||
│ │ │ ├─jeecg-system-cloud-api
|
||||
│ │ │ ├─jeecg-system-local-api
|
||||
│ ├─jeecg-server-cloud
|
||||
├─jeecg-cloud-gateway (9999)
|
||||
├─jeecg-cloud-nacos --Nacos(8848)
|
||||
├─jeecg-system-cloud-start --System(7001)
|
||||
├─jeecg-demo-cloud-start --Demo(7002)
|
||||
├─jeecg-visual
|
||||
├─jeecg-cloud-monitor -- (9111)
|
||||
├─jeecg-cloud-xxljob -- (9080)
|
||||
├─jeecg-cloud-sentinel --sentinel (9000)
|
||||
├─jeecg-cloud-test
|
||||
├─jeecg-cloud-test-more
|
||||
├─jeecg-cloud-test-rabbitmq
|
||||
├─jeecg-cloud-test-seata
|
||||
├─jeecg-cloud-test-shardingsphere
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
Why JeecgBoot?
|
||||
-----------------------------------
|
||||
* Adopt the latest mainstream front and back separation framework (Springboot+Mybatis+antd), easy to use; Code generator has low dependency, flexible expansion ability, and can quickly realize secondary development;
|
||||
* Support microservices SpringCloud Alibaba(Nacos, Gateway, Sentinel, Skywalking), and provide switching mechanism to support free switching between single and microservices
|
||||
* High development efficiency, using code generator, single table, tree list, one-to-many, one-to-one and other data models, add, delete, change and search function one-key generation, menu configuration directly use;
|
||||
* Code generator provides powerful template mechanism, support custom template, currently provide four sets of style template (single table two sets, tree model one set, one to many three sets)
|
||||
* Code generator is very intelligent, online business modeling, online configuration, WYSIWYG support 23 kinds of controls, a key to generate front and back end code, greatly improve the development efficiency, no longer worry about repeated work.
|
||||
* Low code ability: Online online form (without coding, through online configuration of the form, to achieve the addition, deletion, change and check of the form, support single table, tree, one-to-many, one-to-one model, to achieve everyone can code)
|
||||
* Low code ability: Online online report (without coding, through online configuration, to achieve data report, can quickly extract data, reduce development pressure, to achieve everyone can code)
|
||||
* Low code ability: Online online chart (without coding, through online configuration, to achieve graphs, bar graphs, data reports, etc., support custom layout, to achieve everyone can code)
|
||||
* Complete encapsulation of user, role, menu, organization, data dictionary, online scheduled tasks and other basic functions, support access authorization, button permission, data permission and other functions
|
||||
* Commonly used common package, various tools (scheduled task, SMS interface, email sending,Excel import and export, etc.), basically meeting 80% of project requirements
|
||||
* Easy Excel import and export, support single table export and one-to-many table mode export, generated code with import and export function
|
||||
* Integrated simple report tools, image report and data export is very convenient, can be extremely convenient to generate graphical reports, pdf, excel, word and other reports;
|
||||
* Before and after the separation technology, the page UI style is exquisite, for the commonly used components to do the encapsulation: time, row table control, interception display control, report component, editor and so on
|
||||
* Query filter: query function automatically generated, the background dynamic spell SQL additional query conditions; Supports multiple matching modes (full matching, fuzzy query, included query, and unmatched query).
|
||||
* Data permission (fine data permission control, control to row level, list level, form field level, realize different people see different data, different people operate different fields on the same page
|
||||
* Page verification automatically generated (must be input, digital verification, amount verification, time and space, etc.);
|
||||
* Support SAAS service model and provide SaaS multi-tenant architecture solution.
|
||||
* Distributed file service, integration of minio, Ali OSS and other excellent third parties, to provide convenient file upload and management, but also support local storage.
|
||||
* Mainstream database compatibility, a set of code is fully compatible with Mysql, Postgresql, Oracle, Sqlserver, MariaDB, dream and other mainstream databases.
|
||||
* Integrate workflow flowable and realize only the configuration of flow direction in the page, which can greatly simplify the development of bpm workflow; Using bpm's process designer to draw the flow direction, a workflow is basically complete with a small amount of java code;
|
||||
* Low code ability: online process design, using open source Activiti process engine, to achieve online drawing process, custom form, form attachment, business flow
|
||||
* Multi-data source: its simple way of use, online configuration of data source configuration, convenient to grab data from other data;
|
||||
* Provide single sign-on CAS integration solution, and complete docking code has been provided in the project
|
||||
* Low code ability: form designer, support user custom form layout, support single table, one to many forms, support select, radio, checkbox, textarea, date, popup, list, macro and other controls
|
||||
* Professional interface docking mechanism, unified using restful interface, integrated swagger-ui online interface documentation, Jwt token security verification, convenient client docking
|
||||
* Interface security mechanism, can be refined control interface authorization, very simple to realize different clients only see their own data control
|
||||
* Advanced combination query function, online configuration support primary and sub-table associated query, can save the query history
|
||||
* Provide a variety of system monitoring, real-time tracking system running conditions (monitoring Redis, Tomcat, jvm, server information, request tracking, SQL monitoring)
|
||||
* Message center (support SMS, email, wechat push, etc.)
|
||||
* Integrate Websocket message notification mechanism
|
||||
* Excellent mobile adaptive effect, providing APP release scheme:
|
||||
* Support multiple languages and provide internationalization solutions;
|
||||
* Data change record log, can record each change of data content, through the version comparison function to view historical changes
|
||||
* The platform UI is powerful and mobile adaptation is implemented
|
||||
* Platform home page style, provide a variety of combination mode, support custom style
|
||||
* Provide easy to use print plug-in, support Google, Firefox, IE11+ and other browsers
|
||||
* Rich sample code, provide a lot of learning case reference
|
||||
* Using maven module development method
|
||||
* Support dynamic menu routing
|
||||
* RBAC (Role-Based Access Control) is used for permission control.
|
||||
* Provide new row edit table JVXETable, easily meet a variety of complex ERP layout, with higher performance, more flexible extension, more powerful functions
|
||||
|
||||
|
||||
|
||||
|
||||
Technical Architecture:
|
||||
-----------------------------------
|
||||
|
||||
#### Development Environment
|
||||
|
||||
- Language: Java 8+ (less than 17)
|
||||
|
||||
- IDE(JAVA) : IDEA (lombok plug-in must be installed)
|
||||
|
||||
- IDE(front-end) : Vscode, WebStorm, IDEA
|
||||
|
||||
- Dependency management: Maven
|
||||
|
||||
- Cache: Redis
|
||||
|
||||
- Database: MySQL5.7 + & Oracle 11 g & Sqlserver2017 [More Databases](https://my.oschina.net/jeecg/blog/4905722)
|
||||
|
||||
|
||||
#### backend
|
||||
|
||||
- Basic framework: Spring Boot 2.6.14
|
||||
|
||||
- Microservice framework: Spring Cloud Alibaba 2021.0.1.0
|
||||
|
||||
- Persistence layer framework: MybatisPlus 3.5.1
|
||||
|
||||
- Report tool: JimuReport 1.5.8
|
||||
|
||||
- Security framework: Apache Shiro 1.10.0, Jwt 3.11.0
|
||||
|
||||
- Microservice technology stack: Spring Cloud Alibaba, Nacos, Gateway, Sentinel, Skywalking
|
||||
|
||||
- Database connection pool: Alibaba Druid 1.1.22
|
||||
|
||||
- Log printing: logback
|
||||
|
||||
- Others: autopoi, fastjson, poi, Swagger-ui, quartz, lombok (simplified code), etc.
|
||||
|
||||
|
||||
#### The front end
|
||||
|
||||
- TechnologyStack:`Vue3.0+TypeScript+Vite+AntDesignVue+pinia+echarts`
|
||||
|
||||
#### Support library
|
||||
|
||||
| database | support |
|
||||
| --- | --- |
|
||||
| MySQL | √ |
|
||||
| Oracle11g | √ |
|
||||
| Sqlserver2017 | √ |
|
||||
| PostgreSQL | √ |
|
||||
| MariaDB | √ |
|
||||
| 达梦、人大金仓 | √ |
|
||||
|
||||
|
||||
|
||||
## Microservice solutions
|
||||
|
||||
|
||||
1. Service registration and discovery Nacos √
|
||||
|
||||
2. Nacos √
|
||||
|
||||
3. Route gateway gateway(Three loading modes) √
|
||||
|
||||
4. Distributed http feign √
|
||||
|
||||
5. fuse degrade current limiting Sentinel √
|
||||
|
||||
6. Distributed files Minio and Alioss √
|
||||
|
||||
7. Unified permission control
|
||||
|
||||
8. Service monitoring SpringBootAdmin√
|
||||
|
||||
9. link tracking Skywalking [reference document](https://help.jeecg.com/java/springcloud/super/skywarking.html)
|
||||
|
||||
10. Messaging middleware RabbitMQ √
|
||||
|
||||
11. Distributed task xxl-job √
|
||||
|
||||
12. Distributed Transaction Seata
|
||||
|
||||
13. Distributed log elk + kafka
|
||||
|
||||
14. Support docker-compose, k8s, jenkins
|
||||
|
||||
15. CAS SSO √
|
||||
|
||||
16. Route traffic limiting √
|
||||
|
||||
|
||||
#### Microservice architecture diagram
|
||||

|
||||
|
||||
### Jeecg Boot product functionality blueprint
|
||||

|
||||
|
||||
|
||||
|
||||
|
||||
### Function module
|
||||
```
|
||||
├─系统管理
|
||||
│ ├─用户管理
|
||||
│ ├─角色管理
|
||||
│ ├─菜单管理
|
||||
│ ├─权限设置(支持按钮权限、数据权限)
|
||||
│ ├─表单权限(控制字段禁用、隐藏)
|
||||
│ ├─部门管理
|
||||
│ ├─我的部门(二级管理员)
|
||||
│ └─字典管理
|
||||
│ └─分类字典
|
||||
│ └─系统公告
|
||||
│ └─职务管理
|
||||
│ └─通讯录
|
||||
│ └─多租户管理
|
||||
├─消息中心
|
||||
│ ├─消息管理
|
||||
│ ├─模板管理
|
||||
├─代码生成器(低代码)
|
||||
│ ├─代码生成器功能(一键生成前后端代码,生成后无需修改直接用,绝对是后端开发福音)
|
||||
│ ├─代码生成器模板(提供4套模板,分别支持单表和一对多模型,不同风格选择)
|
||||
│ ├─代码生成器模板(生成代码,自带excel导入导出)
|
||||
│ ├─查询过滤器(查询逻辑无需编码,系统根据页面配置自动生成)
|
||||
│ ├─高级查询器(弹窗自动组合查询条件)
|
||||
│ ├─Excel导入导出工具集成(支持单表,一对多 导入导出)
|
||||
│ ├─平台移动自适应支持
|
||||
├─系统监控
|
||||
│ ├─Gateway路由网关
|
||||
│ ├─性能扫描监控
|
||||
│ │ ├─监控 Redis
|
||||
│ │ ├─Tomcat
|
||||
│ │ ├─jvm
|
||||
│ │ ├─服务器信息
|
||||
│ │ ├─请求追踪
|
||||
│ │ ├─磁盘监控
|
||||
│ ├─定时任务
|
||||
│ ├─系统日志
|
||||
│ ├─消息中心(支持短信、邮件、微信推送等等)
|
||||
│ ├─数据日志(记录数据快照,可对比快照,查看数据变更情况)
|
||||
│ ├─系统通知
|
||||
│ ├─SQL监控
|
||||
│ ├─swagger-ui(在线接口文档)
|
||||
│─报表示例
|
||||
│ ├─曲线图
|
||||
│ └─饼状图
|
||||
│ └─柱状图
|
||||
│ └─折线图
|
||||
│ └─面积图
|
||||
│ └─雷达图
|
||||
│ └─仪表图
|
||||
│ └─进度条
|
||||
│ └─排名列表
|
||||
│ └─等等
|
||||
│─大屏模板
|
||||
│ ├─作战指挥中心大屏
|
||||
│ └─物流服务中心大屏
|
||||
│─常用示例
|
||||
│ ├─自定义组件
|
||||
│ ├─对象存储(对接阿里云)
|
||||
│ ├─JVXETable示例(各种复杂ERP布局示例)
|
||||
│ ├─单表模型例子
|
||||
│ └─一对多模型例子
|
||||
│ └─打印例子
|
||||
│ └─一对多TAB例子
|
||||
│ └─内嵌table例子
|
||||
│ └─常用选择组件
|
||||
│ └─异步树table
|
||||
│ └─接口模拟测试
|
||||
│ └─表格合计示例
|
||||
│ └─异步树列表示例
|
||||
│ └─一对多JEditable
|
||||
│ └─JEditable组件示例
|
||||
│ └─图片拖拽排序
|
||||
│ └─图片翻页
|
||||
│ └─图片预览
|
||||
│ └─PDF预览
|
||||
│ └─分屏功能
|
||||
│─封装通用组件
|
||||
│ ├─行编辑表格JEditableTable
|
||||
│ └─省略显示组件
|
||||
│ └─时间控件
|
||||
│ └─高级查询
|
||||
│ └─用户选择组件
|
||||
│ └─报表组件封装
|
||||
│ └─字典组件
|
||||
│ └─下拉多选组件
|
||||
│ └─选人组件
|
||||
│ └─选部门组件
|
||||
│ └─通过部门选人组件
|
||||
│ └─封装曲线、柱状图、饼状图、折线图等等报表的组件(经过封装,使用简单)
|
||||
│ └─在线code编辑器
|
||||
│ └─上传文件组件
|
||||
│ └─验证码组件
|
||||
│ └─树列表组件
|
||||
│ └─表单禁用组件
|
||||
│ └─等等
|
||||
│─更多页面模板
|
||||
│ ├─各种高级表单
|
||||
│ ├─各种列表效果
|
||||
│ └─结果页面
|
||||
│ └─异常页面
|
||||
│ └─个人页面
|
||||
├─高级功能
|
||||
│ ├─系统编码规则
|
||||
│ ├─提供单点登录CAS集成方案
|
||||
│ ├─提供APP发布方案
|
||||
│ ├─集成Websocket消息通知机制
|
||||
├─Online在线开发(低代码)
|
||||
│ ├─Online在线表单 - 功能已开放
|
||||
│ ├─Online代码生成器 - 功能已开放
|
||||
│ ├─Online在线报表 - 功能已开放
|
||||
│ ├─Online在线图表(未开源)
|
||||
│ ├─Online图表模板配置(未开源)
|
||||
│ ├─Online布局设计(未开源)
|
||||
│ ├─多数据源管理 - 功能已开放
|
||||
├─积木报表设计器(低代码)
|
||||
│ ├─打印设计器
|
||||
│ ├─数据报表设计
|
||||
│ ├─图形报表设计(支持echart)
|
||||
│ ├─大屏设计器(未开源)
|
||||
│─流程模块功能 (未开源)
|
||||
│ ├─流程设计器
|
||||
│ ├─表单设计器
|
||||
├─大屏设计器
|
||||
├─门户设计/仪表盘设计器
|
||||
│ └─我的任务
|
||||
│ └─历史流程
|
||||
│ └─历史流程
|
||||
│ └─流程实例管理
|
||||
│ └─流程监听管理
|
||||
│ └─流程表达式
|
||||
│ └─我发起的流程
|
||||
│ └─我的抄送
|
||||
│ └─流程委派、抄送、跳转
|
||||
│ └─。。。
|
||||
│─OA办公组件 (未开源)
|
||||
│ ├─更多功能
|
||||
│ └─。。。
|
||||
└─其他模块
|
||||
└─更多功能开发中。。
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### Effect of system
|
||||
|
||||
##### ChatGPT AI Dialog
|
||||
> Go to the JeecgBoot background home page and click "AI Assistant" in the middle of the right side of the home page. The AI Assistant dialog screen is displayed.
|
||||

|
||||
|
||||
|
||||
##### PC
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
##### interactive
|
||||

|
||||
|
||||

|
||||
|
||||
|
||||
##### process Designer
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
##### min process
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
##### dashboard Designer
|
||||

|
||||
|
||||

|
||||
|
||||
##### report Designer
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
##### form Designer
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
##### bigscreen Designer
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
##### uniapp
|
||||

|
||||
|
||||

|
||||
|
||||
##### low app
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
##### app
|
||||

|
||||

|
||||
|
||||
##### PAD
|
||||

|
||||

|
||||

|
||||
|
||||
|
||||
##### chart
|
||||

|
||||
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
##### swagger
|
||||

|
||||

|
||||
|
||||
|
||||
## donation
|
||||
|
||||
If so, buy the author a cup of coffee ☺
|
||||
|
||||

|
||||
531
README.md
@ -1,108 +1,139 @@
|
||||
|
||||
2019年度最受欢迎中国开源软件评选
|
||||
请给JeecgBoot 投票,谢谢支持。
|
||||
https://www.oschina.net/p/jeecg-boot
|
||||
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
Jeecg-Boot 快速开发平台(前后端分离版本)
|
||||
JeecgBoot 低代码开发平台
|
||||
===============
|
||||
|
||||
当前最新版本: 2.1.1(发布日期:20191021)
|
||||
当前最新版本: 3.7.0(发布日期:2024-06-17)
|
||||
|
||||
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot/blob/master/LICENSE)
|
||||
[](http://www.jeecg.com)
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot)
|
||||
[](http://jeecg.com/aboutusIndex)
|
||||
[](https://jeecg.blog.csdn.net)
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot)
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot)
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot)
|
||||
|
||||
|
||||
|
||||
项目介绍:
|
||||
项目介绍
|
||||
-----------------------------------
|
||||
|
||||
<h3 align="center">Java RAD framework for enterprise web applications</h3>
|
||||
<h3 align="center">Java Low Code Platform for Enterprise web applications</h3>
|
||||
|
||||
JeecgBoot 是一款基于代码生成器的J2EE快速开发平台!采用前后端分离架构:SpringBoot2.x,Ant Design&Vue,Mybatis-plus,Shiro,JWT。强大的代码生成器让前后端代码一键生成,无需写任何代码! JeecgBoot引领新的开发模式(Online Coding模式-> 代码生成器模式-> 手工MERGE智能开发), 帮助解决Java项目70%的重复工作,让开发更多关注业务逻辑。既能快速提高开发效率,帮助公司节省成本,同时又不失灵活性!JeecgBoot还独创在线开发模式(No代码概念):在线表单配置(表单设计器)、移动配置能力、工作流配置(在线设计流程)、报表配置能力、在线图表配置、插件能力(可插拔)等等!
|
||||
JeecgBoot 是一款基于代码生成器的`低代码开发平台`!前后端分离架构 SpringBoot2.x和3.x,SpringCloud,Ant Design&Vue,Mybatis-plus,Shiro,JWT,支持微服务。强大的代码生成器让前后端代码一键生成,实现低代码开发! JeecgBoot 引领新的低代码开发模式(OnlineCoding-> 代码生成器-> 手工MERGE), 帮助解决Java项目70%的重复工作,让开发更多关注业务。既能快速提高效率,节省研发成本,同时又不失灵活性!
|
||||
|
||||
JeecgBoot 提供了一系列`低代码模块`,实现在线开发`真正的零代码`:Online表单开发、Online报表、报表配置能力、在线图表设计、仪表盘设计、大屏设计、移动配置能力、表单设计器、在线设计流程、流程自动化配置、插件能力(可插拔)等等!
|
||||
|
||||
|
||||
JEECG宗旨是: 简单功能由Online Coding配置实现(在线配置表单、在线配置报表、在线图表设计、在线设计流程、在线设计表单),复杂功能由代码生成器生成进行手工Merge,既保证了智能又兼顾了灵活;
|
||||
业务流程采用工作流来实现、扩展出任务接口,供开发编写业务逻辑,表单提供多种解决方案: 表单设计器、online配置表单、编码表单。同时实现了流程与表单的分离设计(松耦合)、并支持任务节点灵活配置,既保证了公司流程的保密性,又减少了开发人员的工作量。
|
||||
`JEECG宗旨是:` 简单功能由OnlineCoding配置实现,做到`零代码开发`;复杂功能由代码生成器生成进行手工Merge 实现`低代码开发`,既保证了`智能`又兼顾`灵活`;实现了低代码开发的同时又支持灵活编码,解决了当前低代码产品普遍不灵活的弊端!
|
||||
|
||||
`JEECG业务流程:` 采用工作流来实现、扩展出任务接口,供开发编写业务逻辑,表单提供多种解决方案: 表单设计器、online配置表单、编码表单。同时实现了流程与表单的分离设计(松耦合)、并支持任务节点灵活配置,既保证了公司流程的保密性,又减少了开发人员的工作量。
|
||||
|
||||
|
||||
适用项目
|
||||
-----------------------------------
|
||||
Jeecg-Boot快速开发平台,可以应用在任何J2EE项目的开发中,尤其适合企业信息管理系统(MIS)、内部办公系统(OA)、企业资源计划系统(ERP)、客户关系管理系统(CRM)等,其半智能手工Merge的开发方式,可以显著提高开发效率70%以上,极大降低开发成本。
|
||||
Jeecg-Boot低代码开发平台,可以应用在任何J2EE项目的开发中,支持信创国产化(默认适配达梦和人大金仓)。尤其适合SAAS项目、企业信息管理系统(MIS)、内部办公系统(OA)、企业资源计划系统(ERP)、客户关系管理系统(CRM)等,其半智能手工Merge的开发方式,可以显著提高开发效率70%以上,极大降低开发成本。
|
||||
|
||||
|
||||
|
||||
#### 项目说明
|
||||
|
||||
| 项目名 | 说明 |
|
||||
|--------------------|------------------------|
|
||||
| `jeecg-boot` | 后端源码JAVA(SpringBoot微服务架构) |
|
||||
| `jeecgboot-vue3` | 前端源码VUE3(vue3+vite5+ts最新技术栈) |
|
||||
| `jeecg-uniapp` | APP框架,一份代码多终端适配,支持APP、小程序、H5 |
|
||||
|
||||
|
||||
其他源码
|
||||
-----------------------------------
|
||||
- APP源码地址:https://github.com/jeecgboot/jeecg-uniapp
|
||||
|
||||
|
||||
技术支持
|
||||
-----------------------------------
|
||||
|
||||
关闭gitee的issue通道,使用中遇到问题或者BUG可以在 [Github上提Issues](https://github.com/jeecgboot/JeecgBoot/issues/new)
|
||||
|
||||
|
||||
快速启动项目
|
||||
-----------------------------------
|
||||
|
||||
- [前端项目快速启动](http://help.jeecg.com/setup/startup.html)
|
||||
- [通过IDEA启动前后端项目](https://help.jeecg.com/java/setup/idea/startup.html)
|
||||
|
||||
|
||||
|
||||
Docker启动项目
|
||||
-----------------------------------
|
||||
|
||||
- [Docker启动前端](http://help.jeecg.com/publish/docker.html)
|
||||
- [Docker启动后台](https://help.jeecg.com/java/setup/docker/up.html)
|
||||
|
||||
|
||||
微服务方式启动
|
||||
-----------------------------------
|
||||
|
||||
- [单体快速切换微服务](https://help.jeecg.com/java/springcloud/switchcloud/monomer.html)
|
||||
- [Docker启动微服务后台](https://help.jeecg.com/java/springcloud/docker.html)
|
||||
|
||||
|
||||
技术文档
|
||||
-----------------------------------
|
||||
|
||||
- 在线演示 : [http://boot.jeecg.com](http://boot.jeecg.com)
|
||||
- 产品官网: [http://www.jeecg.com](http://www.jeecg.com)
|
||||
- 开发文档: [https://help.jeecg.com](https://help.jeecg.com)
|
||||
- 新手指南: [快速入门](http://www.jeecg.com/doc/quickstart) | [常见问题 ](http://www.jeecg.com/doc/qa) | [视频教程](https://space.bilibili.com/454617261/channel/series) | [1分钟低代码体验](https://my.oschina.net/jeecg/blog/3083313)
|
||||
- AI助手配置: https://help.jeecg.com/java/chatgpt.html
|
||||
|
||||
- 技术官网: [http://www.jeecg.com](http://www.jeecg.com)
|
||||
|
||||
- 开发文档: [http://doc.jeecg.com/1273753](http://doc.jeecg.com/1273753)
|
||||
|
||||
- 视频教程 :[JeecgBoot入门系列视频](https://space.bilibili.com/454617261/channel/detail?cid=84186)
|
||||
|
||||
- 常见问题: [入门常见问题大全](http://www.jeecg.org/forum.php?mod=viewthread&tid=7816&extra=page%3D1)
|
||||
|
||||
- 更新日志: [版本日志](http://www.jeecg.com/#/doc/changelog)
|
||||
- 在线演示 : [在线演示](http://boot3.jeecg.com) | [APP演示](http://jeecg.com/appIndex)
|
||||
> 演示系统的登录账号密码,请点击 [获取账号密码](http://jeecg.com/doc/demo) 获取
|
||||
>
|
||||
- QQ交流群 : ⑨808791225、⑧825232878、⑦791696430(满)、⑥730954414(满)、683903138(满)、⑤860162132(满)、④774126647(满)、③816531124(满)、②769925425(满)、①284271917(满)
|
||||
|
||||
|
||||
|
||||
交流互动
|
||||
为什么选择JeecgBoot?
|
||||
-----------------------------------
|
||||
|
||||
- QQ交流群 : ②769925425、①284271917(满)
|
||||
|
||||
- 反馈问题: [反馈问题,请按格式发Issues](https://github.com/zhangdaiscott/jeecg-boot/issues/new)
|
||||
|
||||
- 参与开源: [欢迎加入JEECG开源团队,共同进步!!](http://www.jeecg.com/#/doc/canyu-os)
|
||||
|
||||
- Online一分钟: [1分钟快速学习](https://my.oschina.net/jeecg/blog/3083313)
|
||||
|
||||
|
||||
为什么选择JEECG-BOOT?
|
||||
-----------------------------------
|
||||
* 1.采用最新主流前后分离框架(Springboot+Mybatis+antd),容易上手; 代码生成器依赖性低,灵活的扩展能力,可灵活实现二次开发;
|
||||
* 2.开发效率很高,采用代码生成器,单表数据模型和一对多(父子表)数据模型,增删改查功能自动生成,菜单配置直接使用;
|
||||
* 3.代码生成器提供强大模板机制,支持自定义模板风格。目前提供四套风格模板(单表两套、一对多两套)
|
||||
* 4.封装完善的用户、角色、菜单、组织机构、数据字典、在线定时任务等基础功能,支持访问授权、按钮权限、数据权限等功能
|
||||
* 5.常用共通封装,各种工具类(定时任务,短信接口,邮件发送,Excel导入导出等),基本满足80%项目需求
|
||||
* 6.简易Excel导入导出,支持单表导出和一对多表模式导出,生成的代码自带导入导出功能
|
||||
* 7.集成简易报表工具,图像报表和数据导出非常方便,可极其方便的生成图形报表、pdf、excel、word等报表;
|
||||
* 8.采用前后分离技术,页面UI风格精美,针对常用组件做了封装:时间、行表格控件、截取显示控件、报表组件,编辑器等等
|
||||
* 9.查询过滤器:查询功能自动生成,后台动态拼SQL追加查询条件;支持多种匹配方式(全匹配/模糊查询/包含查询/不匹配查询);
|
||||
* 10.数据权限(精细化数据权限控制,控制到行级,列表级,表单字段级,实现不同人看不同数据,不同人对同一个页面操作不同字段
|
||||
* 11.在线配置报表(无需编码,通过在线配置方式,实现曲线图,柱状图,数据等报表)
|
||||
* 12.页面校验自动生成(必须输入、数字校验、金额校验、时间空间等);
|
||||
* 13.集成工作流activiti,并实现了只需在页面配置流程转向,可极大的简化bpm工作流的开发;用bpm的流程设计器画出了流程走向,一个工作流基本就完成了,只需写很少量的java代码;
|
||||
* 14.在线流程设计,采用开源Activiti流程引擎,实现在线画流程,自定义表单,表单挂靠,业务流转
|
||||
* 15.多数据源:及其简易的使用方式,在线配置数据源配置,便捷的从其他数据抓取数据;
|
||||
* 16.提供单点登录CAS集成方案,项目中已经提供完善的对接代码
|
||||
* 17.表单设计器,支持用户自定义表单布局,支持单表,一对多表单、支持select、radio、checkbox、textarea、date、popup、列表、宏等控件
|
||||
* 18.专业接口对接机制,统一采用restful接口方式,集成swagger-ui在线接口文档,Jwt token安全验证,方便客户端对接
|
||||
* 19.接口安全机制,可细化控制接口授权,非常简便实现不同客户端只看自己数据等控制
|
||||
* 20.高级组合查询功能,在线配置支持主子表关联查询,可保存查询历史
|
||||
* 21.提供各种系统监控,实时跟踪系统运行情况(监控 Redis、Tomcat、jvm、服务器信息、请求追踪、SQL监控)
|
||||
* 22.消息中心(支持短信、邮件、微信推送等等)
|
||||
* 21.集成Websocket消息通知机制
|
||||
* 22.提供APP发布方案国际化:
|
||||
* 23.支持多语言,提供国际化方案;
|
||||
* 24.数据变更记录日志,可记录数据每次变更内容,通过版本对比功能查看历史变化
|
||||
* 25.平台UI强大,实现了移动自适应
|
||||
* 26.平台首页风格,提供多种组合模式,支持自定义风格
|
||||
* 27.提供简单易用的打印插件,支持谷歌、IE浏览器等各种浏览器
|
||||
* 28.示例代码丰富,提供很多学习案例参考
|
||||
* 29.采用maven分模块开发方式
|
||||
* 30.支持菜单动态路由
|
||||
* 31.权限控制采用 RBAC(Role-Based Access Control,基于角色的访问控制)
|
||||
* 1.采用最新主流前后分离框架(Springboot+Mybatis+antd),容易上手; 代码生成器依赖性低,灵活的扩展能力,可快速实现二次开发;
|
||||
* 2.支持微服务SpringCloud Alibaba(Nacos、Gateway、Sentinel、Skywalking),提供切换机制支持单体和微服务自由切换
|
||||
* 3.开发效率高,采用代码生成器,单表、树列表、一对多、一对一等数据模型,增删改查功能一键生成,菜单配置直接使用;
|
||||
* 4.代码生成器提供强大模板机制,支持自定义模板,目前提供四套风格模板(单表两套、树模型一套、一对多三套)
|
||||
* 5.代码生成器非常智能,在线业务建模、在线配置、所见即所得支持23种类控件,一键生成前后端代码,大幅度提升开发效率,不再为重复工作发愁。
|
||||
* 6.低代码能力:Online在线表单(无需编码,通过在线配置表单,实现表单的增删改查,支持单表、树、一对多、一对一等模型,实现人人皆可编码)
|
||||
* 7.低代码能力:Online在线报表(无需编码,通过在线配置方式,实现数据报表,可以快速抽取数据,减轻开发压力,实现人人皆可编码)
|
||||
* 8.低代码能力:Online在线图表(无需编码,通过在线配置方式,实现曲线图,柱状图,数据报表等,支持自定义排版布局,实现人人皆可编码)
|
||||
* 9.封装完善的用户、角色、菜单、组织机构、数据字典、在线定时任务等基础功能,支持访问授权、按钮权限、数据权限等功能
|
||||
* 10.常用共通封装,各种工具类(定时任务,短信接口,邮件发送,Excel导入导出等),基本满足80%项目需求
|
||||
* 11.简易Excel导入导出,支持单表导出和一对多表模式导出,生成的代码自带导入导出功能
|
||||
* 12.集成简易报表工具,图像报表和数据导出非常方便,可极其方便的生成图形报表、pdf、excel、word等报表;
|
||||
* 13.采用前后分离技术,页面UI风格精美,针对常用组件做了封装:时间、行表格控件、截取显示控件、报表组件,编辑器等等
|
||||
* 14.查询过滤器:查询功能自动生成,后台动态拼SQL追加查询条件;支持多种匹配方式(全匹配/模糊查询/包含查询/不匹配查询);
|
||||
* 15.数据权限(精细化数据权限控制,控制到行级,列表级,表单字段级,实现不同人看不同数据,不同人对同一个页面操作不同字段
|
||||
* 16.页面校验自动生成(必须输入、数字校验、金额校验、时间空间等);
|
||||
* 17.支持SAAS服务模式,提供SaaS多租户架构方案。
|
||||
* 18.分布式文件服务,集成minio、阿里OSS等优秀的第三方,提供便捷的文件上传与管理,同时也支持本地存储。
|
||||
* 19.主流数据库兼容,一套代码完全兼容Mysql、Postgresql、Oracle、Sqlserver、MariaDB、达梦等主流数据库。
|
||||
* 20.集成工作流flowable,并实现了只需在页面配置流程转向,可极大的简化bpm工作流的开发;用bpm的流程设计器画出了流程走向,一个工作流基本就完成了,只需写很少量的java代码;
|
||||
* 21.低代码能力:在线流程设计,采用开源flowable流程引擎,实现在线画流程,自定义表单,表单挂靠,业务流转
|
||||
* 22.多数据源:及其简易的使用方式,在线配置数据源配置,便捷的从其他数据抓取数据;
|
||||
* 23.提供单点登录CAS集成方案,项目中已经提供完善的对接代码
|
||||
* 24.低代码能力:表单设计器,支持用户自定义表单布局,支持单表,一对多表单、支持select、radio、checkbox、textarea、date、popup、列表、宏等控件
|
||||
* 25.专业接口对接机制,统一采用restful接口方式,集成swagger-ui在线接口文档,Jwt token安全验证,方便客户端对接
|
||||
* 26.接口安全机制,可细化控制接口授权,非常简便实现不同客户端只看自己数据等控制
|
||||
* 27.高级组合查询功能,在线配置支持主子表关联查询,可保存查询历史
|
||||
* 28.提供各种系统监控,实时跟踪系统运行情况(监控 Redis、Tomcat、jvm、服务器信息、请求追踪、SQL监控)
|
||||
* 29.消息中心(支持短信、邮件、微信推送等等)
|
||||
* 30.集成Websocket消息通知机制
|
||||
* 31.移动自适应效果优秀,提供APP发布方案:
|
||||
* 32.支持多语言,提供国际化方案;
|
||||
* 33.数据变更记录日志,可记录数据每次变更内容,通过版本对比功能查看历史变化
|
||||
* 34.平台UI强大,实现了移动自适应
|
||||
* 35.平台首页风格,提供多种组合模式,支持自定义风格
|
||||
* 36.提供简单易用的打印插件,支持谷歌、火狐、IE11+ 等各种浏览器
|
||||
* 37.示例代码丰富,提供很多学习案例参考
|
||||
* 38.采用maven分模块开发方式
|
||||
* 39.支持菜单动态路由
|
||||
* 40.权限控制采用 RBAC(Role-Based Access Control,基于角色的访问控制)
|
||||
* 41.提供新行编辑表格JVXETable,轻松满足各种复杂ERP布局,拥有更高的性能、更灵活的扩展、更强大的功能
|
||||
|
||||
|
||||
|
||||
@ -111,52 +142,116 @@ Jeecg-Boot快速开发平台,可以应用在任何J2EE项目的开发中,尤
|
||||
-----------------------------------
|
||||
#### 开发环境
|
||||
|
||||
- 语言:Java 8
|
||||
- 语言:Java 8+ (小于17)
|
||||
|
||||
- IDE(JAVA): IDEA / Eclipse安装lombok插件
|
||||
- IDE(JAVA): IDEA (必须安装lombok插件 )
|
||||
|
||||
- IDE(前端): WebStorm 或者 IDEA
|
||||
- IDE(前端): Vscode、WebStorm、IDEA
|
||||
|
||||
- 依赖管理:Maven
|
||||
|
||||
- 数据库:MySQL5.7+ & Oracle 11g & Sqlserver2017
|
||||
|
||||
- 缓存:Redis
|
||||
|
||||
- 数据库脚本:MySQL5.7+ (其他数据库,[需要自己转](https://my.oschina.net/jeecg/blog/4905722))
|
||||
|
||||
|
||||
#### 后端
|
||||
- 基础框架:Spring Boot 2.1.3.RELEASE
|
||||
|
||||
- 持久层框架:Mybatis-plus_3.1.2
|
||||
- 基础框架:Spring Boot 2.6.14
|
||||
|
||||
- 安全框架:Apache Shiro 1.4.0,Jwt_3.7.0
|
||||
- 微服务框架: Spring Cloud Alibaba 2021.0.1.0
|
||||
|
||||
- 数据库连接池:阿里巴巴Druid 1.1.10
|
||||
- 持久层框架:MybatisPlus 3.5.1
|
||||
|
||||
- 缓存框架:redis
|
||||
- 报表工具: JimuReport 1.5.8
|
||||
|
||||
- 安全框架:Apache Shiro 1.10.0,Jwt 3.11.0
|
||||
|
||||
- 微服务技术栈:Spring Cloud Alibaba、Nacos、Gateway、Sentinel、Skywalking
|
||||
|
||||
- 数据库连接池:阿里巴巴Druid 1.1.22
|
||||
|
||||
- 日志打印:logback
|
||||
|
||||
- 其他:fastjson,poi,Swagger-ui,quartz, lombok(简化代码)等。
|
||||
- 其他:autopoi, fastjson,poi,Swagger-ui,quartz, lombok(简化代码)等。
|
||||
|
||||
|
||||
#### 前端
|
||||
|
||||
- [Vue 2.6.10](https://cn.vuejs.org/),[Vuex](https://vuex.vuejs.org/zh/),[Vue Router](https://router.vuejs.org/zh/)
|
||||
- [Axios](https://github.com/axios/axios)
|
||||
- [ant-design-vue](https://vuecomponent.github.io/ant-design-vue/docs/vue/introduce-cn/)
|
||||
- [webpack](https://www.webpackjs.com/),[yarn](https://yarnpkg.com/zh-Hans/)
|
||||
- [vue-cropper](https://github.com/xyxiao001/vue-cropper) - 头像裁剪组件
|
||||
- [@antv/g2](https://antv.alipay.com/zh-cn/index.html) - Alipay AntV 数据可视化图表
|
||||
- [Viser-vue](https://viserjs.github.io/docs.html#/viser/guide/installation) - antv/g2 封装实现
|
||||
- eslint,[@vue/cli 3.2.1](https://cli.vuejs.org/zh/guide)
|
||||
- vue-print-nb - 打印
|
||||
|
||||
- 技术栈:`Vue3.0 + TypeScript + Vite5 + ant-design-vue4 + pinia + echarts + unocss + vxe-table + qiankun + es6` 等最新技术栈
|
||||
|
||||
#### 支持库
|
||||
|
||||
| 数据库 | 支持 |
|
||||
| --- | --- |
|
||||
| MySQL | √ |
|
||||
| Oracle11g | √ |
|
||||
| Sqlserver2017 | √ |
|
||||
| PostgreSQL | √ |
|
||||
| MariaDB | √ |
|
||||
| 达梦、人大金仓 | √ |
|
||||
|
||||
|
||||
|
||||
## 微服务解决方案
|
||||
|
||||
|
||||
1、服务注册和发现 Nacos √
|
||||
|
||||
2、统一配置中心 Nacos √
|
||||
|
||||
3、路由网关 gateway(三种加载方式) √
|
||||
|
||||
4、分布式 http feign √
|
||||
|
||||
5、熔断降级限流 Sentinel √
|
||||
|
||||
6、分布式文件 Minio、阿里OSS √
|
||||
|
||||
7、统一权限控制 JWT + Shiro √
|
||||
|
||||
8、服务监控 SpringBootAdmin√
|
||||
|
||||
9、链路跟踪 Skywalking [参考文档](https://help.jeecg.com/java/springcloud/super/skywarking.html)
|
||||
|
||||
10、消息中间件 RabbitMQ √
|
||||
|
||||
11、分布式任务 xxl-job √
|
||||
|
||||
12、分布式事务 Seata
|
||||
|
||||
13、分布式日志 elk + kafka
|
||||
|
||||
14、支持 docker-compose、k8s、jenkins
|
||||
|
||||
15、CAS 单点登录 √
|
||||
|
||||
16、路由限流 √
|
||||
|
||||
|
||||
#### 微服务架构图
|
||||

|
||||
|
||||
### Jeecg Boot 产品功能蓝图
|
||||

|
||||
|
||||
|
||||
|
||||
|
||||
### 功能模块
|
||||
```
|
||||
├─Online在线开发(低代码)
|
||||
│ ├─Online在线表单
|
||||
│ ├─Online代码生成器
|
||||
│ ├─Online在线报表
|
||||
│ ├─仪表盘设计器
|
||||
│ ├─AI助手
|
||||
│ ├─系统编码规则
|
||||
│ ├─系统校验规则
|
||||
├─积木报表设计器
|
||||
│ ├─打印设计器
|
||||
│ ├─数据报表设计
|
||||
│ ├─图形报表设计(支持echart)
|
||||
├─系统管理
|
||||
│ ├─用户管理
|
||||
│ ├─角色管理
|
||||
@ -164,14 +259,18 @@ Jeecg-Boot快速开发平台,可以应用在任何J2EE项目的开发中,尤
|
||||
│ ├─权限设置(支持按钮权限、数据权限)
|
||||
│ ├─表单权限(控制字段禁用、隐藏)
|
||||
│ ├─部门管理
|
||||
│ ├─我的部门(二级管理员)
|
||||
│ └─字典管理
|
||||
│ └─树分类字典
|
||||
│ └─分类字典
|
||||
│ └─系统公告
|
||||
│ └─我的组织机构
|
||||
│ └─职务管理
|
||||
│ └─通讯录
|
||||
│ ├─多数据源管理
|
||||
│ └─多租户管理(租户管理、租户角色、我的租户)
|
||||
├─消息中心
|
||||
│ ├─消息管理
|
||||
│ ├─模板管理
|
||||
├─智能化功能
|
||||
├─代码生成器(低代码)
|
||||
│ ├─代码生成器功能(一键生成前后端代码,生成后无需修改直接用,绝对是后端开发福音)
|
||||
│ ├─代码生成器模板(提供4套模板,分别支持单表和一对多模型,不同风格选择)
|
||||
│ ├─代码生成器模板(生成代码,自带excel导入导出)
|
||||
@ -180,6 +279,7 @@ Jeecg-Boot快速开发平台,可以应用在任何J2EE项目的开发中,尤
|
||||
│ ├─Excel导入导出工具集成(支持单表,一对多 导入导出)
|
||||
│ ├─平台移动自适应支持
|
||||
├─系统监控
|
||||
│ ├─Gateway路由网关
|
||||
│ ├─性能扫描监控
|
||||
│ │ ├─监控 Redis
|
||||
│ │ ├─Tomcat
|
||||
@ -205,7 +305,13 @@ Jeecg-Boot快速开发平台,可以应用在任何J2EE项目的开发中,尤
|
||||
│ └─进度条
|
||||
│ └─排名列表
|
||||
│ └─等等
|
||||
│─大屏模板
|
||||
│ ├─作战指挥中心大屏
|
||||
│ └─物流服务中心大屏
|
||||
│─常用示例
|
||||
│ ├─自定义组件
|
||||
│ ├─对象存储(对接阿里云)
|
||||
│ ├─JVXETable示例(各种复杂ERP布局示例)
|
||||
│ ├─单表模型例子
|
||||
│ └─一对多模型例子
|
||||
│ └─打印例子
|
||||
@ -214,7 +320,10 @@ Jeecg-Boot快速开发平台,可以应用在任何J2EE项目的开发中,尤
|
||||
│ └─常用选择组件
|
||||
│ └─异步树table
|
||||
│ └─接口模拟测试
|
||||
│ └─表格合计示例
|
||||
│ └─异步树列表示例
|
||||
│ └─一对多JEditable
|
||||
│ └─JEditable组件示例
|
||||
│ └─图片拖拽排序
|
||||
│ └─图片翻页
|
||||
│ └─图片预览
|
||||
@ -249,16 +358,10 @@ Jeecg-Boot快速开发平台,可以应用在任何J2EE项目的开发中,尤
|
||||
│ ├─提供单点登录CAS集成方案
|
||||
│ ├─提供APP发布方案
|
||||
│ ├─集成Websocket消息通知机制
|
||||
├─Online在线开发(暂未开源)
|
||||
│ ├─Online在线表单 - 功能已开放
|
||||
│ ├─在线代码生成器 - 功能已开放
|
||||
│ ├─Online在线图表
|
||||
│ ├─Online图表模板配置
|
||||
│ ├─Online在线报表
|
||||
│ ├─高级表单设计器
|
||||
│─流程模块功能 (暂不开源)
|
||||
│─更多商业功能
|
||||
│ ├─流程设计器
|
||||
│ ├─在线表单设计
|
||||
│ ├─表单设计器
|
||||
│ ├─大屏设计器
|
||||
│ └─我的任务
|
||||
│ └─历史流程
|
||||
│ └─历史流程
|
||||
@ -268,98 +371,82 @@ Jeecg-Boot快速开发平台,可以应用在任何J2EE项目的开发中,尤
|
||||
│ └─我发起的流程
|
||||
│ └─我的抄送
|
||||
│ └─流程委派、抄送、跳转
|
||||
│ └─OA办公组件
|
||||
│ └─。。。
|
||||
└─其他模块
|
||||
└─更多功能开发中。。
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
后台开发环境和依赖
|
||||
----
|
||||
- java
|
||||
- maven
|
||||
- jdk8
|
||||
- mysql
|
||||
- redis
|
||||
- 数据库脚步:jeecg-boot\docs\jeecg-boot-mysql.sql
|
||||
- 默认登录账号: admin/123456
|
||||
|
||||
|
||||
前端开发环境和依赖
|
||||
----
|
||||
- node
|
||||
- yarn
|
||||
- webpack
|
||||
- eslint
|
||||
- @vue/cli 3.2.1
|
||||
- [ant-design-vue](https://github.com/vueComponent/ant-design-vue) - Ant Design Of Vue 实现
|
||||
- [vue-cropper](https://github.com/xyxiao001/vue-cropper) - 头像裁剪组件
|
||||
- [@antv/g2](https://antv.alipay.com/zh-cn/index.html) - Alipay AntV 数据可视化图表
|
||||
- [Viser-vue](https://viserjs.github.io/docs.html#/viser/guide/installation) - antv/g2 封装实现
|
||||
- [jeecg-boot-angular 版本](https://gitee.com/dangzhenghui/jeecg-boot)
|
||||
|
||||
项目下载和运行
|
||||
----
|
||||
|
||||
- 拉取项目代码
|
||||
```bash
|
||||
git clone https://github.com/zhangdaiscott/jeecg-boot.git
|
||||
cd jeecg-boot/ant-design-jeecg-vue
|
||||
后台目录结构
|
||||
-----------------------------------
|
||||
```
|
||||
|
||||
1. 安装node.js
|
||||
2. 切换到ant-design-jeecg-vue文件夹下
|
||||
```
|
||||
# 安装yarn
|
||||
npm install -g yarn
|
||||
|
||||
# 下载依赖
|
||||
yarn install
|
||||
|
||||
# 启动
|
||||
yarn run serve
|
||||
|
||||
# 编译项目
|
||||
yarn run build
|
||||
|
||||
# Lints and fixes files
|
||||
yarn run lint
|
||||
项目结构
|
||||
├─jeecg-boot-parent(父POM: 项目依赖、modules组织)
|
||||
│ ├─jeecg-boot-base-core(共通模块: 工具类、config、权限、查询过滤器、注解等)
|
||||
│ ├─jeecg-module-demo 示例代码
|
||||
│ ├─jeecg-module-system System系统管理目录
|
||||
│ │ ├─jeecg-system-biz System系统管理权限等功能
|
||||
│ │ ├─jeecg-system-start System单体启动项目(8080)
|
||||
│ │ ├─jeecg-system-api System系统管理模块对外api
|
||||
│ │ │ ├─jeecg-system-cloud-api System模块对外提供的微服务接口
|
||||
│ │ │ ├─jeecg-system-local-api System模块对外提供的单体接口
|
||||
│ ├─jeecg-server-cloud --微服务模块
|
||||
├─jeecg-cloud-gateway --微服务网关模块(9999)
|
||||
├─jeecg-cloud-nacos --Nacos服务模块(8848)
|
||||
├─jeecg-system-cloud-start --System微服务启动项目(7001)
|
||||
├─jeecg-demo-cloud-start --Demo微服务启动项目(7002)
|
||||
├─jeecg-visual
|
||||
├─jeecg-cloud-monitor --微服务监控模块 (9111)
|
||||
├─jeecg-cloud-xxljob --微服务xxljob定时任务服务端 (9080)
|
||||
├─jeecg-cloud-sentinel --sentinel服务端 (9000)
|
||||
├─jeecg-cloud-test -- 微服务测试示例(各种例子)
|
||||
├─jeecg-cloud-test-more -- 微服务测试示例(feign、熔断降级、xxljob、分布式锁)
|
||||
├─jeecg-cloud-test-rabbitmq -- 微服务测试示例(rabbitmq)
|
||||
├─jeecg-cloud-test-seata -- 微服务测试示例(seata分布式事务)
|
||||
├─jeecg-cloud-test-shardingsphere -- 微服务测试示例(分库分表)
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
系统效果
|
||||
----
|
||||
### 系统效果
|
||||
|
||||
##### PC端
|
||||

|
||||
|
||||

|
||||

|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
##### 系统交互
|
||||

|
||||
|
||||
##### 在线接口文档
|
||||

|
||||

|
||||

|
||||
|
||||
##### AI助手
|
||||

|
||||
|
||||
|
||||
##### 报表
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
##### 仪表盘设计器
|
||||

|
||||
|
||||
##### 流程
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
##### 报表设计器
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
|
||||
##### 手机端
|
||||
@ -369,60 +456,76 @@ yarn run lint
|
||||
##### PAD端
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
|
||||
其他说明
|
||||
----
|
||||
##### 图表示例
|
||||

|
||||
|
||||
- 项目使用的 [vue-cli3](https://cli.vuejs.org/guide/), 请更新您的 cli
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
- 关闭 Eslint (不推荐) 移除 `package.json` 中 `eslintConfig` 整个节点代码
|
||||
##### 在线接口文档
|
||||

|
||||

|
||||
|
||||
- 修改 Ant Design 配色,在文件 `vue.config.js` 中,其他 less 变量覆盖参考 [ant design](https://ant.design/docs/react/customize-theme-cn) 官方说明
|
||||
```ecmascript 6
|
||||
css: {
|
||||
loaderOptions: {
|
||||
less: {
|
||||
modifyVars: {
|
||||
/* less 变量覆盖,用于自定义 ant design 主题 */
|
||||
|
||||
'primary-color': '#F5222D',
|
||||
'link-color': '#F5222D',
|
||||
'border-radius-base': '4px',
|
||||
},
|
||||
javascriptEnabled: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
##### UNIAPP效果
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
|
||||
##### 大屏设计器
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
|
||||
##### 流程设计
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
附属文档
|
||||
----
|
||||
- [Ant Design Vue](https://vuecomponent.github.io/ant-design-vue/docs/vue/introduce-cn)
|
||||
##### 表单设计器
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
- [报表 viser-vue](https://viserjs.github.io/demo.html#/viser/bar/basic-bar)
|
||||
|
||||
- [Vue](https://cn.vuejs.org/v2/guide)
|
||||
|
||||
- [路由/菜单说明](https://github.com/zhangdaiscott/jeecg-boot/tree/master/ant-design-jeecg-vue/src/router/README.md)
|
||||
|
||||
- [ANTD 默认配置项](https://github.com/zhangdaiscott/jeecg-boot/tree/master/ant-design-jeecg-vue/src/defaultSettings.js)
|
||||
|
||||
- 其他待补充...
|
||||
|
||||
|
||||
备注
|
||||
----
|
||||
|
||||
> @vue/cli 升级后,eslint 规则更新了。由于影响到全部 .vue 文件,需要逐个验证。既暂时关闭部分原本不验证的规则,后期维护时,在逐步修正这些 rules
|
||||
|
||||
|
||||
## 捐赠
|
||||
|
||||
如果觉得还不错,请作者喝杯咖啡吧 ☺
|
||||
|
||||

|
||||

|
||||
|
||||
|
||||
### 流程引擎推荐
|
||||
|
||||
大家在使用本开源项目时,如果想进一步集成流程引擎,推荐结合贺波老师的书 [《深入Activiti流程引擎:核心原理与高阶实战》](https://item.m.jd.com/product/13928958.html?gx=RnAomTM2bmCImZxDqYAkVCoIHuIYVqc)
|
||||
|
||||
<img src="https://jeecgos.oss-cn-beijing.aliyuncs.com/files/tuijian20231220161656.png" width="25%" height="auto">
|
||||
@ -1,39 +0,0 @@
|
||||
[*]
|
||||
charset=utf-8
|
||||
end_of_line=crlf
|
||||
insert_final_newline=false
|
||||
indent_style=space
|
||||
indent_size=2
|
||||
|
||||
[{*.ng,*.sht,*.html,*.shtm,*.shtml,*.htm}]
|
||||
indent_style=space
|
||||
indent_size=2
|
||||
|
||||
[{*.jhm,*.xslt,*.xul,*.rng,*.xsl,*.xsd,*.ant,*.tld,*.fxml,*.jrxml,*.xml,*.jnlp,*.wsdl}]
|
||||
indent_style=space
|
||||
indent_size=2
|
||||
|
||||
[{.babelrc,.stylelintrc,jest.config,.eslintrc,.prettierrc,*.json,*.jsb3,*.jsb2,*.bowerrc}]
|
||||
indent_style=space
|
||||
indent_size=2
|
||||
|
||||
[*.svg]
|
||||
indent_style=space
|
||||
indent_size=2
|
||||
|
||||
[*.js.map]
|
||||
indent_style=space
|
||||
indent_size=2
|
||||
|
||||
[*.less]
|
||||
indent_style=space
|
||||
indent_size=2
|
||||
|
||||
[*.vue]
|
||||
indent_style=space
|
||||
indent_size=2
|
||||
|
||||
[{.analysis_options,*.yml,*.yaml}]
|
||||
indent_style=space
|
||||
indent_size=2
|
||||
|
||||
@ -1 +0,0 @@
|
||||
/src
|
||||
1
ant-design-vue-jeecg/.gitattributes
vendored
@ -1 +0,0 @@
|
||||
public/* linguist-vendored
|
||||
21
ant-design-vue-jeecg/.gitignore
vendored
@ -1,21 +0,0 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
/dist
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Log files
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw*
|
||||
@ -1,5 +0,0 @@
|
||||
{
|
||||
"printWidth": 120,
|
||||
"semi": false,
|
||||
"singleQuote": true
|
||||
}
|
||||
@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 DaiHao Zhang
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@ -1,106 +0,0 @@
|
||||
Ant Design Jeecg Vue
|
||||
====
|
||||
|
||||
当前最新版本: 2.0.2(发布日期:20190708)
|
||||
|
||||
Overview
|
||||
----
|
||||
|
||||
基于 [Ant Design of Vue](https://vuecomponent.github.io/ant-design-vue/docs/vue/introduce-cn/) 实现的 Ant Design Pro Vue 版
|
||||
Jeecg-boot 的前段UI框架,采用前后端分离方案,提供强大代码生成器的快速开发平台。
|
||||
前端页面代码和后端功能代码一键生成,不需要写任何代码,保持jeecg一贯的强大!!
|
||||
|
||||
|
||||
|
||||
#### 前端技术
|
||||
|
||||
- 基础框架:[ant-design-vue](https://github.com/vueComponent/ant-design-vue) - Ant Design Of Vue 实现
|
||||
- JavaScript框架:Vue
|
||||
- Webpack
|
||||
- node
|
||||
- yarn
|
||||
- eslint
|
||||
- @vue/cli 3.2.1
|
||||
- [vue-cropper](https://github.com/xyxiao001/vue-cropper) - 头像裁剪组件
|
||||
- [@antv/g2](https://antv.alipay.com/zh-cn/index.html) - Alipay AntV 数据可视化图表
|
||||
- [Viser-vue](https://viserjs.github.io/docs.html#/viser/guide/installation) - antv/g2 封装实现
|
||||
|
||||
|
||||
|
||||
项目下载和运行
|
||||
----
|
||||
|
||||
- 拉取项目代码
|
||||
```bash
|
||||
git clone https://github.com/zhangdaiscott/jeecg-boot.git
|
||||
cd jeecg-boot/ant-design-jeecg-vue
|
||||
```
|
||||
|
||||
- 安装依赖
|
||||
```
|
||||
yarn install
|
||||
```
|
||||
|
||||
- 开发模式运行
|
||||
```
|
||||
yarn run serve
|
||||
```
|
||||
|
||||
- 编译项目
|
||||
```
|
||||
yarn run build
|
||||
```
|
||||
|
||||
- Lints and fixes files
|
||||
```
|
||||
yarn run lint
|
||||
```
|
||||
|
||||
|
||||
|
||||
其他说明
|
||||
----
|
||||
|
||||
- 项目使用的 [vue-cli3](https://cli.vuejs.org/guide/), 请更新您的 cli
|
||||
|
||||
- 关闭 Eslint (不推荐) 移除 `package.json` 中 `eslintConfig` 整个节点代码
|
||||
|
||||
- 修改 Ant Design 配色,在文件 `vue.config.js` 中,其他 less 变量覆盖参考 [ant design](https://ant.design/docs/react/customize-theme-cn) 官方说明
|
||||
```ecmascript 6
|
||||
css: {
|
||||
loaderOptions: {
|
||||
less: {
|
||||
modifyVars: {
|
||||
/* less 变量覆盖,用于自定义 ant design 主题 */
|
||||
|
||||
'primary-color': '#F5222D',
|
||||
'link-color': '#F5222D',
|
||||
'border-radius-base': '4px',
|
||||
},
|
||||
javascriptEnabled: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
附属文档
|
||||
----
|
||||
- [Ant Design Vue](https://vuecomponent.github.io/ant-design-vue/docs/vue/introduce-cn)
|
||||
|
||||
- [报表 viser-vue](https://viserjs.github.io/demo.html#/viser/bar/basic-bar)
|
||||
|
||||
- [Vue](https://cn.vuejs.org/v2/guide)
|
||||
|
||||
- [路由/菜单说明](https://github.com/zhangdaiscott/jeecg-boot/tree/master/ant-design-jeecg-vue/src/router/README.md)
|
||||
|
||||
- [ANTD 默认配置项](https://github.com/zhangdaiscott/jeecg-boot/tree/master/ant-design-jeecg-vue/src/defaultSettings.js)
|
||||
|
||||
- 其他待补充...
|
||||
|
||||
|
||||
备注
|
||||
----
|
||||
|
||||
> @vue/cli 升级后,eslint 规则更新了。由于影响到全部 .vue 文件,需要逐个验证。既暂时关闭部分原本不验证的规则,后期维护时,在逐步修正这些 rules
|
||||
@ -1,5 +0,0 @@
|
||||
module.exports = {
|
||||
presets: [
|
||||
'@vue/app'
|
||||
]
|
||||
}
|
||||
@ -1,24 +0,0 @@
|
||||
'use strict'
|
||||
const path = require('path')
|
||||
|
||||
function resolve (dir) {
|
||||
return path.join(__dirname, '.', dir)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
context: path.resolve(__dirname, './'),
|
||||
resolve: {
|
||||
extensions: ['.js', '.vue', '.json'],
|
||||
alias: {
|
||||
'config': resolve('config'),
|
||||
'@': resolve('src'),
|
||||
'@views': resolve('src/views'),
|
||||
'@comp': resolve('src/components'),
|
||||
'@core': resolve('src/core'),
|
||||
'@utils': resolve('src/utils'),
|
||||
'@entry': resolve('src/entry'),
|
||||
'@router': resolve('src/router'),
|
||||
'@store': resolve('src/store')
|
||||
}
|
||||
},
|
||||
}
|
||||
17277
ant-design-vue-jeecg/package-lock.json
generated
@ -1,108 +0,0 @@
|
||||
{
|
||||
"name": "vue-antd-jeecg",
|
||||
"version": "2.1.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"pre": "cnpm install || yarn --registry https://registry.npm.taobao.org || npm install --registry https://registry.npm.taobao.org ",
|
||||
"serve": "vue-cli-service serve",
|
||||
"build": "vue-cli-service build",
|
||||
"lint": "vue-cli-service lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"@antv/data-set": "^0.10.2",
|
||||
"@jeecg/antd-online": "1.2.0",
|
||||
"@tinymce/tinymce-vue": "^2.0.0",
|
||||
"ant-design-vue": "^1.4.0",
|
||||
"apexcharts": "^3.6.5",
|
||||
"axios": "^0.18.0",
|
||||
"clipboard": "^2.0.4",
|
||||
"codemirror": "^5.46.0",
|
||||
"dayjs": "^1.8.0",
|
||||
"enquire.js": "^2.1.6",
|
||||
"js-cookie": "^2.2.0",
|
||||
"lodash.get": "^4.4.2",
|
||||
"lodash.pick": "^4.4.0",
|
||||
"md5": "^2.2.1",
|
||||
"nprogress": "^0.2.0",
|
||||
"tinymce": "^5.0.2",
|
||||
"viser-vue": "^2.4.4",
|
||||
"vue": "^2.6.10",
|
||||
"vue-apexcharts": "^1.3.2",
|
||||
"vue-class-component": "^6.0.0",
|
||||
"vue-cropper": "^0.4.8",
|
||||
"vue-i18n": "^8.7.0",
|
||||
"vue-loader": "^15.7.0",
|
||||
"vue-ls": "^3.2.0",
|
||||
"vue-photo-preview": "^1.1.3",
|
||||
"vue-print-nb-jeecg": "^1.0.8",
|
||||
"vue-property-decorator": "^7.3.0",
|
||||
"vue-router": "^3.0.1",
|
||||
"vue-splitpane": "^1.0.4",
|
||||
"vuedraggable": "^2.20.0",
|
||||
"vuex": "^3.0.1",
|
||||
"vuex-class": "^0.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/polyfill": "^7.2.5",
|
||||
"@vue/cli-plugin-babel": "^3.3.0",
|
||||
"@vue/cli-plugin-eslint": "^3.3.0",
|
||||
"@vue/cli-service": "^3.3.0",
|
||||
"@vue/eslint-config-standard": "^4.0.0",
|
||||
"babel-eslint": "^10.0.1",
|
||||
"eslint": "^5.16.0",
|
||||
"eslint-plugin-vue": "^5.1.0",
|
||||
"less": "^3.9.0",
|
||||
"less-loader": "^4.1.0",
|
||||
"node-sass": "^4.11.0",
|
||||
"sass-loader": "^7.0.1",
|
||||
"vue-template-compiler": "^2.6.10"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"root": true,
|
||||
"env": {
|
||||
"node": true
|
||||
},
|
||||
"extends": [
|
||||
"plugin:vue/strongly-recommended",
|
||||
"eslint:recommended"
|
||||
],
|
||||
"parserOptions": {
|
||||
"parser": "babel-eslint"
|
||||
},
|
||||
"rules": {
|
||||
"generator-star-spacing": "off",
|
||||
"no-mixed-operators": 0,
|
||||
"vue/max-attributes-per-line": [
|
||||
2,
|
||||
{
|
||||
"singleline": 5,
|
||||
"multiline": {
|
||||
"max": 1,
|
||||
"allowFirstLine": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"vue/attribute-hyphenation": 0,
|
||||
"vue/html-self-closing": 0,
|
||||
"vue/component-name-in-template-casing": 0,
|
||||
"vue/html-closing-bracket-spacing": 0,
|
||||
"vue/singleline-html-element-content-newline": 0,
|
||||
"vue/no-unused-components": 0,
|
||||
"vue/multiline-html-element-content-newline": 0,
|
||||
"vue/no-use-v-if-with-v-for": 0,
|
||||
"vue/html-closing-bracket-newline": 0,
|
||||
"vue/no-parsing-error": 0,
|
||||
"no-console": 0
|
||||
}
|
||||
},
|
||||
"postcss": {
|
||||
"plugins": {
|
||||
"autoprefixer": {}
|
||||
}
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
"last 2 versions",
|
||||
"not ie <= 8"
|
||||
]
|
||||
}
|
||||
|
Before Width: | Height: | Size: 78 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
@ -1,268 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-cmn-Hans">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<title>Jeecg-Boot 快速开发平台</title>
|
||||
<link rel="icon" href="<%= BASE_URL %>logo.png">
|
||||
<script src="https://cdn.bootcss.com/babel-polyfill/7.6.0/polyfill.js"></script>
|
||||
<style>
|
||||
html,
|
||||
body,
|
||||
#app {
|
||||
height: 100%;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
.chromeframe {
|
||||
margin: 0.2em 0;
|
||||
background: #ccc;
|
||||
color: #000;
|
||||
padding: 0.2em 0;
|
||||
}
|
||||
#loader-wrapper {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 999999;
|
||||
}
|
||||
#loader {
|
||||
display: block;
|
||||
position: relative;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
margin: -75px 0 0 -75px;
|
||||
border-radius: 50%;
|
||||
border: 3px solid transparent;
|
||||
/* COLOR 1 */
|
||||
border-top-color: #FFF;
|
||||
-webkit-animation: spin 2s linear infinite;
|
||||
/* Chrome, Opera 15+, Safari 5+ */
|
||||
-ms-animation: spin 2s linear infinite;
|
||||
/* Chrome, Opera 15+, Safari 5+ */
|
||||
-moz-animation: spin 2s linear infinite;
|
||||
/* Chrome, Opera 15+, Safari 5+ */
|
||||
-o-animation: spin 2s linear infinite;
|
||||
/* Chrome, Opera 15+, Safari 5+ */
|
||||
animation: spin 2s linear infinite;
|
||||
/* Chrome, Firefox 16+, IE 10+, Opera */
|
||||
z-index: 1001;
|
||||
}
|
||||
#loader:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
left: 5px;
|
||||
right: 5px;
|
||||
bottom: 5px;
|
||||
border-radius: 50%;
|
||||
border: 3px solid transparent;
|
||||
/* COLOR 2 */
|
||||
border-top-color: #FFF;
|
||||
-webkit-animation: spin 3s linear infinite;
|
||||
/* Chrome, Opera 15+, Safari 5+ */
|
||||
-moz-animation: spin 3s linear infinite;
|
||||
/* Chrome, Opera 15+, Safari 5+ */
|
||||
-o-animation: spin 3s linear infinite;
|
||||
/* Chrome, Opera 15+, Safari 5+ */
|
||||
-ms-animation: spin 3s linear infinite;
|
||||
/* Chrome, Opera 15+, Safari 5+ */
|
||||
animation: spin 3s linear infinite;
|
||||
/* Chrome, Firefox 16+, IE 10+, Opera */
|
||||
}
|
||||
#loader:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
left: 15px;
|
||||
right: 15px;
|
||||
bottom: 15px;
|
||||
border-radius: 50%;
|
||||
border: 3px solid transparent;
|
||||
border-top-color: #FFF;
|
||||
/* COLOR 3 */
|
||||
-moz-animation: spin 1.5s linear infinite;
|
||||
/* Chrome, Opera 15+, Safari 5+ */
|
||||
-o-animation: spin 1.5s linear infinite;
|
||||
/* Chrome, Opera 15+, Safari 5+ */
|
||||
-ms-animation: spin 1.5s linear infinite;
|
||||
/* Chrome, Opera 15+, Safari 5+ */
|
||||
-webkit-animation: spin 1.5s linear infinite;
|
||||
/* Chrome, Opera 15+, Safari 5+ */
|
||||
animation: spin 1.5s linear infinite;
|
||||
/* Chrome, Firefox 16+, IE 10+, Opera */
|
||||
}
|
||||
@-webkit-keyframes spin {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
/* Chrome, Opera 15+, Safari 3.1+ */
|
||||
-ms-transform: rotate(0deg);
|
||||
/* IE 9 */
|
||||
transform: rotate(0deg);
|
||||
/* Firefox 16+, IE 10+, Opera */
|
||||
}
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
/* Chrome, Opera 15+, Safari 3.1+ */
|
||||
-ms-transform: rotate(360deg);
|
||||
/* IE 9 */
|
||||
transform: rotate(360deg);
|
||||
/* Firefox 16+, IE 10+, Opera */
|
||||
}
|
||||
}
|
||||
@keyframes spin {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
/* Chrome, Opera 15+, Safari 3.1+ */
|
||||
-ms-transform: rotate(0deg);
|
||||
/* IE 9 */
|
||||
transform: rotate(0deg);
|
||||
/* Firefox 16+, IE 10+, Opera */
|
||||
}
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
/* Chrome, Opera 15+, Safari 3.1+ */
|
||||
-ms-transform: rotate(360deg);
|
||||
/* IE 9 */
|
||||
transform: rotate(360deg);
|
||||
/* Firefox 16+, IE 10+, Opera */
|
||||
}
|
||||
}
|
||||
#loader-wrapper .loader-section {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
width: 51%;
|
||||
height: 100%;
|
||||
background: #49a9ee;
|
||||
/* Old browsers */
|
||||
z-index: 1000;
|
||||
-webkit-transform: translateX(0);
|
||||
/* Chrome, Opera 15+, Safari 3.1+ */
|
||||
-ms-transform: translateX(0);
|
||||
/* IE 9 */
|
||||
transform: translateX(0);
|
||||
/* Firefox 16+, IE 10+, Opera */
|
||||
}
|
||||
#loader-wrapper .loader-section.section-left {
|
||||
left: 0;
|
||||
}
|
||||
#loader-wrapper .loader-section.section-right {
|
||||
right: 0;
|
||||
}
|
||||
/* Loaded */
|
||||
.loaded #loader-wrapper .loader-section.section-left {
|
||||
-webkit-transform: translateX(-100%);
|
||||
/* Chrome, Opera 15+, Safari 3.1+ */
|
||||
-ms-transform: translateX(-100%);
|
||||
/* IE 9 */
|
||||
transform: translateX(-100%);
|
||||
/* Firefox 16+, IE 10+, Opera */
|
||||
-webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);
|
||||
transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);
|
||||
}
|
||||
.loaded #loader-wrapper .loader-section.section-right {
|
||||
-webkit-transform: translateX(100%);
|
||||
/* Chrome, Opera 15+, Safari 3.1+ */
|
||||
-ms-transform: translateX(100%);
|
||||
/* IE 9 */
|
||||
transform: translateX(100%);
|
||||
/* Firefox 16+, IE 10+, Opera */
|
||||
-webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);
|
||||
transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);
|
||||
}
|
||||
.loaded #loader {
|
||||
opacity: 0;
|
||||
-webkit-transition: all 0.3s ease-out;
|
||||
transition: all 0.3s ease-out;
|
||||
}
|
||||
.loaded #loader-wrapper {
|
||||
visibility: hidden;
|
||||
-webkit-transform: translateY(-100%);
|
||||
/* Chrome, Opera 15+, Safari 3.1+ */
|
||||
-ms-transform: translateY(-100%);
|
||||
/* IE 9 */
|
||||
transform: translateY(-100%);
|
||||
/* Firefox 16+, IE 10+, Opera */
|
||||
-webkit-transition: all 0.3s 1s ease-out;
|
||||
transition: all 0.3s 1s ease-out;
|
||||
}
|
||||
/* JavaScript Turned Off */
|
||||
.no-js #loader-wrapper {
|
||||
display: none;
|
||||
}
|
||||
.no-js h1 {
|
||||
color: #222222;
|
||||
}
|
||||
#loader-wrapper .load_title {
|
||||
font-family: 'Open Sans';
|
||||
color: #FFF;
|
||||
font-size: 14px;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
z-index: 9999999999999;
|
||||
position: absolute;
|
||||
top: 60%;
|
||||
opacity: 1;
|
||||
line-height: 30px;
|
||||
}
|
||||
#loader-wrapper .load_title span {
|
||||
font-weight: normal;
|
||||
font-style: italic;
|
||||
font-size: 14px;
|
||||
color: #FFF;
|
||||
opacity: 0.5;
|
||||
}
|
||||
/* 滚动条优化 start */
|
||||
::-webkit-scrollbar{
|
||||
width:8px;
|
||||
height:8px;
|
||||
}
|
||||
::-webkit-scrollbar-track{
|
||||
background: #f6f6f6;
|
||||
border-radius:2px;
|
||||
}
|
||||
::-webkit-scrollbar-thumb{
|
||||
background: #cdcdcd;
|
||||
border-radius:2px;
|
||||
}
|
||||
::-webkit-scrollbar-thumb:hover{
|
||||
background: #747474;
|
||||
}
|
||||
::-webkit-scrollbar-corner {
|
||||
background: #f6f6f6;
|
||||
}
|
||||
/* 滚动条优化 end */
|
||||
</style>
|
||||
<!-- 全局配置 -->
|
||||
<script>
|
||||
window._CONFIG = {};
|
||||
window._CONFIG['domianURL'] = 'http://127.0.0.1:8080/jeecg-boot';
|
||||
window._CONFIG['casPrefixUrl'] = 'http://cas.example.org:8443/cas';
|
||||
window._CONFIG['imgDomainURL'] = window._CONFIG['domianURL'] + '/sys/common/view';
|
||||
window._CONFIG['downloadUrl'] = window._CONFIG['domianURL'] + '/sys/common/download';
|
||||
window._CONFIG['pdfDomainURL'] = window._CONFIG['domianURL'] + '/sys/common/pdf/pdfPreviewIframe';
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- built files will be auto injected -->
|
||||
<div id="app">
|
||||
<div id="loader-wrapper">
|
||||
<div id="loader"></div>
|
||||
<div class="loader-section section-left"></div>
|
||||
<div class="loader-section section-right"></div>
|
||||
<div class="load_title">正在加载 Jeecg-Boot 快速开发平台,请耐心等待
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
Before Width: | Height: | Size: 8.7 KiB |
@ -1,261 +0,0 @@
|
||||
tinymce.addI18n('zh_CN',{
|
||||
"Redo": "\u91cd\u590d",
|
||||
"Undo": "\u64a4\u6d88",
|
||||
"Cut": "\u526a\u5207",
|
||||
"Copy": "\u590d\u5236",
|
||||
"Paste": "\u7c98\u8d34",
|
||||
"Select all": "\u5168\u9009",
|
||||
"New document": "\u65b0\u6587\u6863",
|
||||
"Ok": "\u786e\u5b9a",
|
||||
"Cancel": "\u53d6\u6d88",
|
||||
"Visual aids": "\u7f51\u683c\u7ebf",
|
||||
"Bold": "\u7c97\u4f53",
|
||||
"Italic": "\u659c\u4f53",
|
||||
"Underline": "\u4e0b\u5212\u7ebf",
|
||||
"Strikethrough": "\u5220\u9664\u7ebf",
|
||||
"Superscript": "\u4e0a\u6807",
|
||||
"Subscript": "\u4e0b\u6807",
|
||||
"Clear formatting": "\u6e05\u9664\u683c\u5f0f",
|
||||
"Align left": "\u5de6\u5bf9\u9f50",
|
||||
"Align center": "\u5c45\u4e2d",
|
||||
"Align right": "\u53f3\u5bf9\u9f50",
|
||||
"Justify": "\u4e24\u7aef\u5bf9\u9f50",
|
||||
"Bullet list": "\u9879\u76ee\u7b26\u53f7",
|
||||
"Numbered list": "\u7f16\u53f7\u5217\u8868",
|
||||
"Decrease indent": "\u51cf\u5c11\u7f29\u8fdb",
|
||||
"Increase indent": "\u589e\u52a0\u7f29\u8fdb",
|
||||
"Close": "\u5173\u95ed",
|
||||
"Formats": "\u683c\u5f0f",
|
||||
"Your browser doesn't support direct access to the clipboard. Please use the Ctrl+X\/C\/V keyboard shortcuts instead.": "\u4f60\u7684\u6d4f\u89c8\u5668\u4e0d\u652f\u6301\u5bf9\u526a\u8d34\u677f\u7684\u8bbf\u95ee\uff0c\u8bf7\u4f7f\u7528Ctrl+X\/C\/V\u952e\u8fdb\u884c\u590d\u5236\u7c98\u8d34\u3002",
|
||||
"Headers": "\u6807\u9898",
|
||||
"Header 1": "\u6807\u98981",
|
||||
"Header 2": "\u6807\u98982",
|
||||
"Header 3": "\u6807\u98983",
|
||||
"Header 4": "\u6807\u98984",
|
||||
"Header 5": "\u6807\u98985",
|
||||
"Header 6": "\u6807\u98986",
|
||||
"Headings": "\u6807\u9898",
|
||||
"Heading 1": "\u6807\u98981",
|
||||
"Heading 2": "\u6807\u98982",
|
||||
"Heading 3": "\u6807\u98983",
|
||||
"Heading 4": "\u6807\u98984",
|
||||
"Heading 5": "\u6807\u98985",
|
||||
"Heading 6": "\u6807\u98986",
|
||||
"Preformatted": "\u9884\u683c\u5f0f\u5316",
|
||||
"Div": "Div\u533a\u5757",
|
||||
"Pre": "\u9884\u683c\u5f0f\u6587\u672c",
|
||||
"Code": "\u4ee3\u7801",
|
||||
"Paragraph": "\u6bb5\u843d",
|
||||
"Blockquote": "\u5f15\u7528",
|
||||
"Inline": "\u6587\u672c",
|
||||
"Blocks": "\u533a\u5757",
|
||||
"Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.": "\u5f53\u524d\u4e3a\u7eaf\u6587\u672c\u7c98\u8d34\u6a21\u5f0f\uff0c\u518d\u6b21\u70b9\u51fb\u53ef\u4ee5\u56de\u5230\u666e\u901a\u7c98\u8d34\u6a21\u5f0f\u3002",
|
||||
"Font Family": "\u5b57\u4f53",
|
||||
"Font Sizes": "\u5b57\u53f7",
|
||||
"Class": "Class",
|
||||
"Browse for an image": "\u6d4f\u89c8\u56fe\u50cf",
|
||||
"OR": "\u6216",
|
||||
"Drop an image here": "\u62d6\u653e\u4e00\u5f20\u56fe\u50cf\u81f3\u6b64",
|
||||
"Upload": "\u4e0a\u4f20",
|
||||
"Block": "\u5757",
|
||||
"Align": "\u5bf9\u9f50",
|
||||
"Default": "\u9ed8\u8ba4",
|
||||
"Circle": "\u7a7a\u5fc3\u5706",
|
||||
"Disc": "\u5b9e\u5fc3\u5706",
|
||||
"Square": "\u65b9\u5757",
|
||||
"Lower Alpha": "\u5c0f\u5199\u82f1\u6587\u5b57\u6bcd",
|
||||
"Lower Greek": "\u5c0f\u5199\u5e0c\u814a\u5b57\u6bcd",
|
||||
"Lower Roman": "\u5c0f\u5199\u7f57\u9a6c\u5b57\u6bcd",
|
||||
"Upper Alpha": "\u5927\u5199\u82f1\u6587\u5b57\u6bcd",
|
||||
"Upper Roman": "\u5927\u5199\u7f57\u9a6c\u5b57\u6bcd",
|
||||
"Anchor": "\u951a\u70b9",
|
||||
"Name": "\u540d\u79f0",
|
||||
"Id": "\u6807\u8bc6\u7b26",
|
||||
"Id should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores.": "\u6807\u8bc6\u7b26\u5e94\u8be5\u4ee5\u5b57\u6bcd\u5f00\u5934\uff0c\u540e\u8ddf\u5b57\u6bcd\u3001\u6570\u5b57\u3001\u7834\u6298\u53f7\u3001\u70b9\u3001\u5192\u53f7\u6216\u4e0b\u5212\u7ebf\u3002",
|
||||
"You have unsaved changes are you sure you want to navigate away?": "\u4f60\u8fd8\u6709\u6587\u6863\u5c1a\u672a\u4fdd\u5b58\uff0c\u786e\u5b9a\u8981\u79bb\u5f00\uff1f",
|
||||
"Restore last draft": "\u6062\u590d\u4e0a\u6b21\u7684\u8349\u7a3f",
|
||||
"Special character": "\u7279\u6b8a\u7b26\u53f7",
|
||||
"Source code": "\u6e90\u4ee3\u7801",
|
||||
"Insert\/Edit code sample": "\u63d2\u5165\/\u7f16\u8f91\u4ee3\u7801\u793a\u4f8b",
|
||||
"Language": "\u8bed\u8a00",
|
||||
"Code sample": "\u4ee3\u7801\u793a\u4f8b",
|
||||
"Color": "\u989c\u8272",
|
||||
"R": "R",
|
||||
"G": "G",
|
||||
"B": "B",
|
||||
"Left to right": "\u4ece\u5de6\u5230\u53f3",
|
||||
"Right to left": "\u4ece\u53f3\u5230\u5de6",
|
||||
"Emoticons": "\u8868\u60c5",
|
||||
"Document properties": "\u6587\u6863\u5c5e\u6027",
|
||||
"Title": "\u6807\u9898",
|
||||
"Keywords": "\u5173\u952e\u8bcd",
|
||||
"Description": "\u63cf\u8ff0",
|
||||
"Robots": "\u673a\u5668\u4eba",
|
||||
"Author": "\u4f5c\u8005",
|
||||
"Encoding": "\u7f16\u7801",
|
||||
"Fullscreen": "\u5168\u5c4f",
|
||||
"Action": "\u64cd\u4f5c",
|
||||
"Shortcut": "\u5feb\u6377\u952e",
|
||||
"Help": "\u5e2e\u52a9",
|
||||
"Address": "\u5730\u5740",
|
||||
"Focus to menubar": "\u79fb\u52a8\u7126\u70b9\u5230\u83dc\u5355\u680f",
|
||||
"Focus to toolbar": "\u79fb\u52a8\u7126\u70b9\u5230\u5de5\u5177\u680f",
|
||||
"Focus to element path": "\u79fb\u52a8\u7126\u70b9\u5230\u5143\u7d20\u8def\u5f84",
|
||||
"Focus to contextual toolbar": "\u79fb\u52a8\u7126\u70b9\u5230\u4e0a\u4e0b\u6587\u83dc\u5355",
|
||||
"Insert link (if link plugin activated)": "\u63d2\u5165\u94fe\u63a5 (\u5982\u679c\u94fe\u63a5\u63d2\u4ef6\u5df2\u6fc0\u6d3b)",
|
||||
"Save (if save plugin activated)": "\u4fdd\u5b58(\u5982\u679c\u4fdd\u5b58\u63d2\u4ef6\u5df2\u6fc0\u6d3b)",
|
||||
"Find (if searchreplace plugin activated)": "\u67e5\u627e(\u5982\u679c\u67e5\u627e\u66ff\u6362\u63d2\u4ef6\u5df2\u6fc0\u6d3b)",
|
||||
"Plugins installed ({0}):": "\u5df2\u5b89\u88c5\u63d2\u4ef6 ({0}):",
|
||||
"Premium plugins:": "\u4f18\u79c0\u63d2\u4ef6\uff1a",
|
||||
"Learn more...": "\u4e86\u89e3\u66f4\u591a...",
|
||||
"You are using {0}": "\u4f60\u6b63\u5728\u4f7f\u7528 {0}",
|
||||
"Plugins": "\u63d2\u4ef6",
|
||||
"Handy Shortcuts": "\u5feb\u6377\u952e",
|
||||
"Horizontal line": "\u6c34\u5e73\u5206\u5272\u7ebf",
|
||||
"Insert\/edit image": "\u63d2\u5165\/\u7f16\u8f91\u56fe\u7247",
|
||||
"Image description": "\u56fe\u7247\u63cf\u8ff0",
|
||||
"Source": "\u5730\u5740",
|
||||
"Dimensions": "\u5927\u5c0f",
|
||||
"Constrain proportions": "\u4fdd\u6301\u7eb5\u6a2a\u6bd4",
|
||||
"General": "\u666e\u901a",
|
||||
"Advanced": "\u9ad8\u7ea7",
|
||||
"Style": "\u6837\u5f0f",
|
||||
"Vertical space": "\u5782\u76f4\u8fb9\u8ddd",
|
||||
"Horizontal space": "\u6c34\u5e73\u8fb9\u8ddd",
|
||||
"Border": "\u8fb9\u6846",
|
||||
"Insert image": "\u63d2\u5165\u56fe\u7247",
|
||||
"Image": "\u56fe\u7247",
|
||||
"Image list": "\u56fe\u7247\u5217\u8868",
|
||||
"Rotate counterclockwise": "\u9006\u65f6\u9488\u65cb\u8f6c",
|
||||
"Rotate clockwise": "\u987a\u65f6\u9488\u65cb\u8f6c",
|
||||
"Flip vertically": "\u5782\u76f4\u7ffb\u8f6c",
|
||||
"Flip horizontally": "\u6c34\u5e73\u7ffb\u8f6c",
|
||||
"Edit image": "\u7f16\u8f91\u56fe\u7247",
|
||||
"Image options": "\u56fe\u7247\u9009\u9879",
|
||||
"Zoom in": "\u653e\u5927",
|
||||
"Zoom out": "\u7f29\u5c0f",
|
||||
"Crop": "\u88c1\u526a",
|
||||
"Resize": "\u8c03\u6574\u5927\u5c0f",
|
||||
"Orientation": "\u65b9\u5411",
|
||||
"Brightness": "\u4eae\u5ea6",
|
||||
"Sharpen": "\u9510\u5316",
|
||||
"Contrast": "\u5bf9\u6bd4\u5ea6",
|
||||
"Color levels": "\u989c\u8272\u5c42\u6b21",
|
||||
"Gamma": "\u4f3d\u9a6c\u503c",
|
||||
"Invert": "\u53cd\u8f6c",
|
||||
"Apply": "\u5e94\u7528",
|
||||
"Back": "\u540e\u9000",
|
||||
"Insert date\/time": "\u63d2\u5165\u65e5\u671f\/\u65f6\u95f4",
|
||||
"Date\/time": "\u65e5\u671f\/\u65f6\u95f4",
|
||||
"Insert link": "\u63d2\u5165\u94fe\u63a5",
|
||||
"Insert\/edit link": "\u63d2\u5165\/\u7f16\u8f91\u94fe\u63a5",
|
||||
"Text to display": "\u663e\u793a\u6587\u5b57",
|
||||
"Url": "\u5730\u5740",
|
||||
"Target": "\u6253\u5f00\u65b9\u5f0f",
|
||||
"None": "\u65e0",
|
||||
"New window": "\u5728\u65b0\u7a97\u53e3\u6253\u5f00",
|
||||
"Remove link": "\u5220\u9664\u94fe\u63a5",
|
||||
"Anchors": "\u951a\u70b9",
|
||||
"Link": "\u94fe\u63a5",
|
||||
"Paste or type a link": "\u7c98\u8d34\u6216\u8f93\u5165\u94fe\u63a5",
|
||||
"The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?": "\u4f60\u6240\u586b\u5199\u7684URL\u5730\u5740\u4e3a\u90ae\u4ef6\u5730\u5740\uff0c\u9700\u8981\u52a0\u4e0amailto:\u524d\u7f00\u5417\uff1f",
|
||||
"The URL you entered seems to be an external link. Do you want to add the required http:\/\/ prefix?": "\u4f60\u6240\u586b\u5199\u7684URL\u5730\u5740\u5c5e\u4e8e\u5916\u90e8\u94fe\u63a5\uff0c\u9700\u8981\u52a0\u4e0ahttp:\/\/:\u524d\u7f00\u5417\uff1f",
|
||||
"Link list": "\u94fe\u63a5\u5217\u8868",
|
||||
"Insert video": "\u63d2\u5165\u89c6\u9891",
|
||||
"Insert\/edit video": "\u63d2\u5165\/\u7f16\u8f91\u89c6\u9891",
|
||||
"Insert\/edit media": "\u63d2\u5165\/\u7f16\u8f91\u5a92\u4f53",
|
||||
"Alternative source": "\u955c\u50cf",
|
||||
"Poster": "\u5c01\u9762",
|
||||
"Paste your embed code below:": "\u5c06\u5185\u5d4c\u4ee3\u7801\u7c98\u8d34\u5728\u4e0b\u9762:",
|
||||
"Embed": "\u5185\u5d4c",
|
||||
"Media": "\u5a92\u4f53",
|
||||
"Nonbreaking space": "\u4e0d\u95f4\u65ad\u7a7a\u683c",
|
||||
"Page break": "\u5206\u9875\u7b26",
|
||||
"Paste as text": "\u7c98\u8d34\u4e3a\u6587\u672c",
|
||||
"Preview": "\u9884\u89c8",
|
||||
"Print": "\u6253\u5370",
|
||||
"Save": "\u4fdd\u5b58",
|
||||
"Find": "\u67e5\u627e",
|
||||
"Replace with": "\u66ff\u6362\u4e3a",
|
||||
"Replace": "\u66ff\u6362",
|
||||
"Replace all": "\u5168\u90e8\u66ff\u6362",
|
||||
"Prev": "\u4e0a\u4e00\u4e2a",
|
||||
"Next": "\u4e0b\u4e00\u4e2a",
|
||||
"Find and replace": "\u67e5\u627e\u548c\u66ff\u6362",
|
||||
"Could not find the specified string.": "\u672a\u627e\u5230\u641c\u7d22\u5185\u5bb9.",
|
||||
"Match case": "\u533a\u5206\u5927\u5c0f\u5199",
|
||||
"Whole words": "\u5168\u5b57\u5339\u914d",
|
||||
"Spellcheck": "\u62fc\u5199\u68c0\u67e5",
|
||||
"Ignore": "\u5ffd\u7565",
|
||||
"Ignore all": "\u5168\u90e8\u5ffd\u7565",
|
||||
"Finish": "\u5b8c\u6210",
|
||||
"Add to Dictionary": "\u6dfb\u52a0\u5230\u5b57\u5178",
|
||||
"Insert table": "\u63d2\u5165\u8868\u683c",
|
||||
"Table properties": "\u8868\u683c\u5c5e\u6027",
|
||||
"Delete table": "\u5220\u9664\u8868\u683c",
|
||||
"Cell": "\u5355\u5143\u683c",
|
||||
"Row": "\u884c",
|
||||
"Column": "\u5217",
|
||||
"Cell properties": "\u5355\u5143\u683c\u5c5e\u6027",
|
||||
"Merge cells": "\u5408\u5e76\u5355\u5143\u683c",
|
||||
"Split cell": "\u62c6\u5206\u5355\u5143\u683c",
|
||||
"Insert row before": "\u5728\u4e0a\u65b9\u63d2\u5165",
|
||||
"Insert row after": "\u5728\u4e0b\u65b9\u63d2\u5165",
|
||||
"Delete row": "\u5220\u9664\u884c",
|
||||
"Row properties": "\u884c\u5c5e\u6027",
|
||||
"Cut row": "\u526a\u5207\u884c",
|
||||
"Copy row": "\u590d\u5236\u884c",
|
||||
"Paste row before": "\u7c98\u8d34\u5230\u4e0a\u65b9",
|
||||
"Paste row after": "\u7c98\u8d34\u5230\u4e0b\u65b9",
|
||||
"Insert column before": "\u5728\u5de6\u4fa7\u63d2\u5165",
|
||||
"Insert column after": "\u5728\u53f3\u4fa7\u63d2\u5165",
|
||||
"Delete column": "\u5220\u9664\u5217",
|
||||
"Cols": "\u5217",
|
||||
"Rows": "\u884c",
|
||||
"Width": "\u5bbd",
|
||||
"Height": "\u9ad8",
|
||||
"Cell spacing": "\u5355\u5143\u683c\u5916\u95f4\u8ddd",
|
||||
"Cell padding": "\u5355\u5143\u683c\u5185\u8fb9\u8ddd",
|
||||
"Caption": "\u6807\u9898",
|
||||
"Left": "\u5de6\u5bf9\u9f50",
|
||||
"Center": "\u5c45\u4e2d",
|
||||
"Right": "\u53f3\u5bf9\u9f50",
|
||||
"Cell type": "\u5355\u5143\u683c\u7c7b\u578b",
|
||||
"Scope": "\u8303\u56f4",
|
||||
"Alignment": "\u5bf9\u9f50\u65b9\u5f0f",
|
||||
"H Align": "\u6c34\u5e73\u5bf9\u9f50",
|
||||
"V Align": "\u5782\u76f4\u5bf9\u9f50",
|
||||
"Top": "\u9876\u90e8\u5bf9\u9f50",
|
||||
"Middle": "\u5782\u76f4\u5c45\u4e2d",
|
||||
"Bottom": "\u5e95\u90e8\u5bf9\u9f50",
|
||||
"Header cell": "\u8868\u5934\u5355\u5143\u683c",
|
||||
"Row group": "\u884c\u7ec4",
|
||||
"Column group": "\u5217\u7ec4",
|
||||
"Row type": "\u884c\u7c7b\u578b",
|
||||
"Header": "\u8868\u5934",
|
||||
"Body": "\u8868\u4f53",
|
||||
"Footer": "\u8868\u5c3e",
|
||||
"Border color": "\u8fb9\u6846\u989c\u8272",
|
||||
"Insert template": "\u63d2\u5165\u6a21\u677f",
|
||||
"Templates": "\u6a21\u677f",
|
||||
"Template": "\u6a21\u677f",
|
||||
"Text color": "\u6587\u5b57\u989c\u8272",
|
||||
"Background color": "\u80cc\u666f\u8272",
|
||||
"Custom...": "\u81ea\u5b9a\u4e49...",
|
||||
"Custom color": "\u81ea\u5b9a\u4e49\u989c\u8272",
|
||||
"No color": "\u65e0",
|
||||
"Table of Contents": "\u5185\u5bb9\u5217\u8868",
|
||||
"Show blocks": "\u663e\u793a\u533a\u5757\u8fb9\u6846",
|
||||
"Show invisible characters": "\u663e\u793a\u4e0d\u53ef\u89c1\u5b57\u7b26",
|
||||
"Words: {0}": "\u5b57\u6570\uff1a{0}",
|
||||
"{0} words": "{0} \u5b57",
|
||||
"File": "\u6587\u4ef6",
|
||||
"Edit": "\u7f16\u8f91",
|
||||
"Insert": "\u63d2\u5165",
|
||||
"View": "\u89c6\u56fe",
|
||||
"Format": "\u683c\u5f0f",
|
||||
"Table": "\u8868\u683c",
|
||||
"Tools": "\u5de5\u5177",
|
||||
"Powered by {0}": "\u7531{0}\u9a71\u52a8",
|
||||
"Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help": "\u5728\u7f16\u8f91\u533a\u6309ALT-F9\u6253\u5f00\u83dc\u5355\uff0c\u6309ALT-F10\u6253\u5f00\u5de5\u5177\u680f\uff0c\u6309ALT-0\u67e5\u770b\u5e2e\u52a9"
|
||||
});
|
||||
@ -1,554 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
|
||||
* Licensed under the LGPL or a commercial license.
|
||||
* For LGPL see License.txt in the project root for license information.
|
||||
* For commercial licenses see https://www.tiny.cloud/
|
||||
*/
|
||||
.mce-content-body .mce-item-anchor {
|
||||
background: transparent url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D'8'%20height%3D'12'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%3E%3Cpath%20d%3D'M0%200L8%200%208%2012%204.09117821%209%200%2012z'%2F%3E%3C%2Fsvg%3E%0A") no-repeat center;
|
||||
cursor: default;
|
||||
display: inline-block;
|
||||
height: 12px !important;
|
||||
padding: 0 2px;
|
||||
-webkit-user-modify: read-only;
|
||||
-moz-user-modify: read-only;
|
||||
-webkit-user-select: all;
|
||||
-moz-user-select: all;
|
||||
-ms-user-select: all;
|
||||
user-select: all;
|
||||
width: 8px !important;
|
||||
}
|
||||
.mce-content-body .mce-item-anchor[data-mce-selected] {
|
||||
outline-offset: 1px;
|
||||
}
|
||||
.tox-comments-visible .tox-comment {
|
||||
background-color: #fff0b7;
|
||||
}
|
||||
.tox-comments-visible .tox-comment--active {
|
||||
background-color: #ffe168;
|
||||
}
|
||||
.tox-checklist > li:not(.tox-checklist--hidden) {
|
||||
list-style: none;
|
||||
margin: .25em 0;
|
||||
position: relative;
|
||||
}
|
||||
.tox-checklist > li:not(.tox-checklist--hidden)::before {
|
||||
background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2216%22%20height%3D%2216%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cg%20id%3D%22checklist-unchecked%22%20fill%3D%22none%22%20fill-rule%3D%22evenodd%22%3E%3Crect%20id%3D%22Rectangle%22%20width%3D%2215%22%20height%3D%2215%22%20x%3D%22.5%22%20y%3D%22.5%22%20fill-rule%3D%22nonzero%22%20stroke%3D%22%234C4C4C%22%20rx%3D%222%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E%0A");
|
||||
background-size: 100%;
|
||||
content: '';
|
||||
cursor: pointer;
|
||||
height: 1em;
|
||||
left: -1.5em;
|
||||
position: absolute;
|
||||
top: .125em;
|
||||
width: 1em;
|
||||
}
|
||||
.tox-checklist li:not(.tox-checklist--hidden).tox-checklist--checked::before {
|
||||
background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2216%22%20height%3D%2216%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cg%20id%3D%22checklist-checked%22%20fill%3D%22none%22%20fill-rule%3D%22evenodd%22%3E%3Crect%20id%3D%22Rectangle%22%20width%3D%2216%22%20height%3D%2216%22%20fill%3D%22%234099FF%22%20fill-rule%3D%22nonzero%22%20rx%3D%222%22%2F%3E%3Cpath%20id%3D%22Path%22%20fill%3D%22%23FFF%22%20fill-rule%3D%22nonzero%22%20d%3D%22M11.5703186%2C3.14417309%20C11.8516238%2C2.73724603%2012.4164781%2C2.62829933%2012.83558%2C2.89774797%20C13.260121%2C3.17069355%2013.3759736%2C3.72932262%2013.0909105%2C4.14168582%20L7.7580587%2C11.8560195%20C7.43776896%2C12.3193404%206.76483983%2C12.3852142%206.35607322%2C11.9948725%20L3.02491697%2C8.8138662%20C2.66090143%2C8.46625845%202.65798871%2C7.89594698%203.01850234%2C7.54483354%20C3.373942%2C7.19866177%203.94940006%2C7.19592841%204.30829608%2C7.5386474%20L6.85276923%2C9.9684299%20L11.5703186%2C3.14417309%20Z%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E%0A");
|
||||
}
|
||||
/* stylelint-disable */
|
||||
/* http://prismjs.com/ */
|
||||
/**
|
||||
* prism.js default theme for JavaScript, CSS and HTML
|
||||
* Based on dabblet (http://dabblet.com)
|
||||
* @author Lea Verou
|
||||
*/
|
||||
code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
color: black;
|
||||
text-shadow: 0 1px white;
|
||||
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
|
||||
font-size: .875rem;
|
||||
direction: ltr;
|
||||
text-align: left;
|
||||
white-space: pre;
|
||||
word-spacing: normal;
|
||||
word-break: normal;
|
||||
word-wrap: normal;
|
||||
line-height: 1.5;
|
||||
-moz-tab-size: 4;
|
||||
tab-size: 4;
|
||||
-webkit-hyphens: none;
|
||||
-ms-hyphens: none;
|
||||
hyphens: none;
|
||||
}
|
||||
pre[class*="language-"]::-moz-selection,
|
||||
pre[class*="language-"] ::-moz-selection,
|
||||
code[class*="language-"]::-moz-selection,
|
||||
code[class*="language-"] ::-moz-selection {
|
||||
text-shadow: none;
|
||||
background: #b3d4fc;
|
||||
}
|
||||
pre[class*="language-"]::selection,
|
||||
pre[class*="language-"] ::selection,
|
||||
code[class*="language-"]::selection,
|
||||
code[class*="language-"] ::selection {
|
||||
text-shadow: none;
|
||||
background: #b3d4fc;
|
||||
}
|
||||
@media print {
|
||||
code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
text-shadow: none;
|
||||
}
|
||||
}
|
||||
/* Code blocks */
|
||||
pre[class*="language-"] {
|
||||
padding: 1em;
|
||||
margin: .5em 0;
|
||||
overflow: auto;
|
||||
}
|
||||
:not(pre) > code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
background: transparent !important;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
/* Inline code */
|
||||
:not(pre) > code[class*="language-"] {
|
||||
padding: .1em;
|
||||
border-radius: .3em;
|
||||
}
|
||||
.token.comment,
|
||||
.token.prolog,
|
||||
.token.doctype,
|
||||
.token.cdata {
|
||||
color: slategray;
|
||||
}
|
||||
.token.punctuation {
|
||||
color: #999;
|
||||
}
|
||||
.namespace {
|
||||
opacity: .7;
|
||||
}
|
||||
.token.property,
|
||||
.token.tag,
|
||||
.token.boolean,
|
||||
.token.number,
|
||||
.token.constant,
|
||||
.token.symbol,
|
||||
.token.deleted {
|
||||
color: #905;
|
||||
}
|
||||
.token.selector,
|
||||
.token.attr-name,
|
||||
.token.string,
|
||||
.token.char,
|
||||
.token.builtin,
|
||||
.token.inserted {
|
||||
color: #690;
|
||||
}
|
||||
.token.operator,
|
||||
.token.entity,
|
||||
.token.url,
|
||||
.language-css .token.string,
|
||||
.style .token.string {
|
||||
color: #a67f59;
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
.token.atrule,
|
||||
.token.attr-value,
|
||||
.token.keyword {
|
||||
color: #07a;
|
||||
}
|
||||
.token.function {
|
||||
color: #DD4A68;
|
||||
}
|
||||
.token.regex,
|
||||
.token.important,
|
||||
.token.variable {
|
||||
color: #e90;
|
||||
}
|
||||
.token.important,
|
||||
.token.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
.token.italic {
|
||||
font-style: italic;
|
||||
}
|
||||
.token.entity {
|
||||
cursor: help;
|
||||
}
|
||||
/* stylelint-enable */
|
||||
.mce-content-body .mce-visual-caret {
|
||||
background-color: black;
|
||||
background-color: currentcolor;
|
||||
position: absolute;
|
||||
}
|
||||
.mce-content-body .mce-visual-caret-hidden {
|
||||
display: none;
|
||||
}
|
||||
.mce-content-body *[data-mce-caret] {
|
||||
left: -1000px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
right: auto;
|
||||
top: 0;
|
||||
}
|
||||
.mce-content-body .mce-offscreen-selection {
|
||||
left: -9999999999px;
|
||||
max-width: 1000000px;
|
||||
position: absolute;
|
||||
}
|
||||
.mce-content-body *[contentEditable=false] {
|
||||
cursor: default;
|
||||
}
|
||||
.mce-content-body *[contentEditable=true] {
|
||||
cursor: text;
|
||||
}
|
||||
.tox-cursor-format-painter {
|
||||
cursor: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%3E%0A%20%20%3Cg%20fill%3D%22none%22%20fill-rule%3D%22evenodd%22%3E%0A%20%20%20%20%3Cpath%20fill%3D%22%23000%22%20fill-rule%3D%22nonzero%22%20d%3D%22M15%2C6%20C15%2C5.45%2014.55%2C5%2014%2C5%20L6%2C5%20C5.45%2C5%205%2C5.45%205%2C6%20L5%2C10%20C5%2C10.55%205.45%2C11%206%2C11%20L14%2C11%20C14.55%2C11%2015%2C10.55%2015%2C10%20L15%2C9%20L16%2C9%20L16%2C12%20L9%2C12%20L9%2C19%20C9%2C19.55%209.45%2C20%2010%2C20%20L11%2C20%20C11.55%2C20%2012%2C19.55%2012%2C19%20L12%2C14%20L18%2C14%20L18%2C7%20L15%2C7%20L15%2C6%20Z%22%2F%3E%0A%20%20%20%20%3Cpath%20fill%3D%22%23000%22%20fill-rule%3D%22nonzero%22%20d%3D%22M1%2C1%20L8.25%2C1%20C8.66421356%2C1%209%2C1.33578644%209%2C1.75%20L9%2C1.75%20C9%2C2.16421356%208.66421356%2C2.5%208.25%2C2.5%20L2.5%2C2.5%20L2.5%2C8.25%20C2.5%2C8.66421356%202.16421356%2C9%201.75%2C9%20L1.75%2C9%20C1.33578644%2C9%201%2C8.66421356%201%2C8.25%20L1%2C1%20Z%22%2F%3E%0A%20%20%3C%2Fg%3E%0A%3C%2Fsvg%3E%0A"), default;
|
||||
}
|
||||
.mce-content-body figure.align-left {
|
||||
float: left;
|
||||
}
|
||||
.mce-content-body figure.align-right {
|
||||
float: right;
|
||||
}
|
||||
.mce-content-body figure.image.align-center {
|
||||
display: table;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
.mce-preview-object {
|
||||
border: 1px solid gray;
|
||||
display: inline-block;
|
||||
line-height: 0;
|
||||
margin: 0 2px 0 2px;
|
||||
position: relative;
|
||||
}
|
||||
.mce-preview-object .mce-shim {
|
||||
background: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7);
|
||||
height: 100%;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
.mce-preview-object[data-mce-selected="2"] .mce-shim {
|
||||
display: none;
|
||||
}
|
||||
.mce-object {
|
||||
background: transparent url("data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%3E%3Cpath%20d%3D%22M4%203h16a1%201%200%200%201%201%201v16a1%201%200%200%201-1%201H4a1%201%200%200%201-1-1V4a1%201%200%200%201%201-1zm1%202v14h14V5H5zm4.79%202.565l5.64%204.028a.5.5%200%200%201%200%20.814l-5.64%204.028a.5.5%200%200%201-.79-.407V7.972a.5.5%200%200%201%20.79-.407z%22%2F%3E%3C%2Fsvg%3E%0A") no-repeat center;
|
||||
border: 1px dashed #aaa;
|
||||
}
|
||||
.mce-pagebreak {
|
||||
border: 1px dashed #aaa;
|
||||
cursor: default;
|
||||
display: block;
|
||||
height: 5px;
|
||||
margin-top: 15px;
|
||||
page-break-before: always;
|
||||
width: 100%;
|
||||
}
|
||||
@media print {
|
||||
.mce-pagebreak {
|
||||
border: 0;
|
||||
}
|
||||
}
|
||||
.tiny-pageembed .mce-shim {
|
||||
background: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7);
|
||||
height: 100%;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
.tiny-pageembed[data-mce-selected="2"] .mce-shim {
|
||||
display: none;
|
||||
}
|
||||
.tiny-pageembed {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
}
|
||||
.tiny-pageembed--21by9,
|
||||
.tiny-pageembed--16by9,
|
||||
.tiny-pageembed--4by3,
|
||||
.tiny-pageembed--1by1 {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
.tiny-pageembed--21by9::before,
|
||||
.tiny-pageembed--16by9::before,
|
||||
.tiny-pageembed--4by3::before,
|
||||
.tiny-pageembed--1by1::before {
|
||||
content: "";
|
||||
display: block;
|
||||
}
|
||||
.tiny-pageembed--21by9::before {
|
||||
padding-top: 42.857143%;
|
||||
}
|
||||
.tiny-pageembed--16by9::before {
|
||||
padding-top: 56.25%;
|
||||
}
|
||||
.tiny-pageembed--4by3::before {
|
||||
padding-top: 75%;
|
||||
}
|
||||
.tiny-pageembed--1by1::before {
|
||||
padding-top: 100%;
|
||||
}
|
||||
.tiny-pageembed--21by9 iframe,
|
||||
.tiny-pageembed--16by9 iframe,
|
||||
.tiny-pageembed--4by3 iframe,
|
||||
.tiny-pageembed--1by1 iframe {
|
||||
border: 0;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
.mce-content-body div.mce-resizehandle {
|
||||
background-color: #4099ff;
|
||||
border-color: #4099ff;
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
box-sizing: border-box;
|
||||
height: 10px;
|
||||
position: absolute;
|
||||
width: 10px;
|
||||
z-index: 10000;
|
||||
}
|
||||
.mce-content-body div.mce-resizehandle:hover {
|
||||
background-color: #4099ff;
|
||||
}
|
||||
.mce-content-body div.mce-resizehandle:nth-of-type(1) {
|
||||
cursor: nwse-resize;
|
||||
}
|
||||
.mce-content-body div.mce-resizehandle:nth-of-type(2) {
|
||||
cursor: nesw-resize;
|
||||
}
|
||||
.mce-content-body div.mce-resizehandle:nth-of-type(3) {
|
||||
cursor: nwse-resize;
|
||||
}
|
||||
.mce-content-body div.mce-resizehandle:nth-of-type(4) {
|
||||
cursor: nesw-resize;
|
||||
}
|
||||
.mce-content-body .mce-clonedresizable {
|
||||
opacity: .5;
|
||||
outline: 1px dashed black;
|
||||
position: absolute;
|
||||
z-index: 10000;
|
||||
}
|
||||
.mce-content-body .mce-resize-helper {
|
||||
background: #555;
|
||||
background: rgba(0, 0, 0, 0.75);
|
||||
border: 1px;
|
||||
border-radius: 3px;
|
||||
color: white;
|
||||
display: none;
|
||||
font-family: sans-serif;
|
||||
font-size: 12px;
|
||||
line-height: 14px;
|
||||
margin: 5px 10px;
|
||||
padding: 5px;
|
||||
position: absolute;
|
||||
white-space: nowrap;
|
||||
z-index: 10001;
|
||||
}
|
||||
.mce-match-marker {
|
||||
background: #aaa;
|
||||
color: #fff;
|
||||
}
|
||||
.mce-match-marker-selected {
|
||||
background: #39f;
|
||||
color: #fff;
|
||||
}
|
||||
.mce-content-body img[data-mce-selected],
|
||||
.mce-content-body table[data-mce-selected] {
|
||||
outline: 3px solid #b4d7ff;
|
||||
}
|
||||
.mce-content-body hr[data-mce-selected] {
|
||||
outline: 3px solid #b4d7ff;
|
||||
outline-offset: 1px;
|
||||
}
|
||||
.mce-content-body *[contentEditable=false] *[contentEditable=true]:focus {
|
||||
outline: 3px solid #b4d7ff;
|
||||
}
|
||||
.mce-content-body *[contentEditable=false] *[contentEditable=true]:hover {
|
||||
outline: 3px solid #b4d7ff;
|
||||
}
|
||||
.mce-content-body *[contentEditable=false][data-mce-selected] {
|
||||
cursor: not-allowed;
|
||||
outline: 3px solid #b4d7ff;
|
||||
}
|
||||
.mce-content-body.mce-content-readonly *[contentEditable=true]:focus,
|
||||
.mce-content-body.mce-content-readonly *[contentEditable=true]:hover {
|
||||
outline: none;
|
||||
}
|
||||
.mce-content-body *[data-mce-selected="inline-boundary"] {
|
||||
background-color: #b4d7ff;
|
||||
}
|
||||
.mce-content-body .mce-edit-focus {
|
||||
outline: 3px solid #b4d7ff;
|
||||
}
|
||||
.mce-content-body td[data-mce-selected],
|
||||
.mce-content-body th[data-mce-selected] {
|
||||
background-color: #b4d7ff !important;
|
||||
}
|
||||
.mce-content-body td[data-mce-selected]::-moz-selection,
|
||||
.mce-content-body th[data-mce-selected]::-moz-selection {
|
||||
background: none;
|
||||
}
|
||||
.mce-content-body td[data-mce-selected]::selection,
|
||||
.mce-content-body th[data-mce-selected]::selection {
|
||||
background: none;
|
||||
}
|
||||
.mce-content-body td[data-mce-selected] *,
|
||||
.mce-content-body th[data-mce-selected] * {
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
.mce-content-body img::-moz-selection {
|
||||
background: none;
|
||||
}
|
||||
.mce-content-body img::selection {
|
||||
background: none;
|
||||
}
|
||||
.ephox-snooker-resizer-bar {
|
||||
background-color: #b4d7ff;
|
||||
opacity: 0;
|
||||
}
|
||||
.ephox-snooker-resizer-cols {
|
||||
cursor: col-resize;
|
||||
}
|
||||
.ephox-snooker-resizer-rows {
|
||||
cursor: row-resize;
|
||||
}
|
||||
.ephox-snooker-resizer-bar.ephox-snooker-resizer-bar-dragging {
|
||||
opacity: 1;
|
||||
}
|
||||
.mce-spellchecker-word {
|
||||
background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D'4'%20height%3D'4'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%3E%3Cpath%20stroke%3D'%23ff0000'%20fill%3D'none'%20stroke-linecap%3D'round'%20stroke-opacity%3D'.5'%20d%3D'M0%203L2%201%204%203'%2F%3E%3C%2Fsvg%3E%0A");
|
||||
background-position: 0 calc(100% + 1px);
|
||||
background-repeat: repeat-x;
|
||||
background-size: auto 6px;
|
||||
cursor: default;
|
||||
height: 2rem;
|
||||
}
|
||||
.mce-spellchecker-grammar {
|
||||
background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D'4'%20height%3D'4'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%3E%3Cpath%20stroke%3D'%23008800'%20fill%3D'none'%20stroke-linecap%3D'round'%20d%3D'M0%203L2%201%204%203'%2F%3E%3C%2Fsvg%3E%0A");
|
||||
background-position: 0 calc(100% + 1px);
|
||||
background-repeat: repeat-x;
|
||||
background-size: auto 6px;
|
||||
cursor: default;
|
||||
}
|
||||
.mce-toc {
|
||||
border: 1px solid gray;
|
||||
}
|
||||
.mce-toc h2 {
|
||||
margin: 4px;
|
||||
}
|
||||
.mce-toc li {
|
||||
list-style-type: none;
|
||||
}
|
||||
.mce-item-table,
|
||||
.mce-item-table td,
|
||||
.mce-item-table th,
|
||||
.mce-item-table caption {
|
||||
border: 1px dashed #bbb;
|
||||
}
|
||||
.mce-visualblocks p,
|
||||
.mce-visualblocks h1,
|
||||
.mce-visualblocks h2,
|
||||
.mce-visualblocks h3,
|
||||
.mce-visualblocks h4,
|
||||
.mce-visualblocks h5,
|
||||
.mce-visualblocks h6,
|
||||
.mce-visualblocks div:not([data-mce-bogus]),
|
||||
.mce-visualblocks section,
|
||||
.mce-visualblocks article,
|
||||
.mce-visualblocks blockquote,
|
||||
.mce-visualblocks address,
|
||||
.mce-visualblocks pre,
|
||||
.mce-visualblocks figure,
|
||||
.mce-visualblocks figcaption,
|
||||
.mce-visualblocks hgroup,
|
||||
.mce-visualblocks aside,
|
||||
.mce-visualblocks ul,
|
||||
.mce-visualblocks ol,
|
||||
.mce-visualblocks dl {
|
||||
background-repeat: no-repeat;
|
||||
border: 1px dashed #bbb;
|
||||
margin-left: 3px;
|
||||
padding-top: 10px;
|
||||
}
|
||||
.mce-visualblocks p {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhCQAJAJEAAAAAAP///7u7u////yH5BAEAAAMALAAAAAAJAAkAAAIQnG+CqCN/mlyvsRUpThG6AgA7);
|
||||
}
|
||||
.mce-visualblocks h1 {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhDQAKAIABALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybGu1JuxHoAfRNRW3TWXyF2YiRUAOw==);
|
||||
}
|
||||
.mce-visualblocks h2 {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8Hybbx4oOuqgTynJd6bGlWg3DkJzoaUAAAOw==);
|
||||
}
|
||||
.mce-visualblocks h3 {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIZjI8Hybbx4oOuqgTynJf2Ln2NOHpQpmhAAQA7);
|
||||
}
|
||||
.mce-visualblocks h4 {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8HybbxInR0zqeAdhtJlXwV1oCll2HaWgAAOw==);
|
||||
}
|
||||
.mce-visualblocks h5 {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8HybbxIoiuwjane4iq5GlW05GgIkIZUAAAOw==);
|
||||
}
|
||||
.mce-visualblocks h6 {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8HybbxIoiuwjan04jep1iZ1XRlAo5bVgAAOw==);
|
||||
}
|
||||
.mce-visualblocks div:not([data-mce-bogus]) {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhEgAKAIABALu7u////yH5BAEAAAEALAAAAAASAAoAAAIfjI9poI0cgDywrhuxfbrzDEbQM2Ei5aRjmoySW4pAAQA7);
|
||||
}
|
||||
.mce-visualblocks section {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhKAAKAIABALu7u////yH5BAEAAAEALAAAAAAoAAoAAAI5jI+pywcNY3sBWHdNrplytD2ellDeSVbp+GmWqaDqDMepc8t17Y4vBsK5hDyJMcI6KkuYU+jpjLoKADs=);
|
||||
}
|
||||
.mce-visualblocks article {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhKgAKAIABALu7u////yH5BAEAAAEALAAAAAAqAAoAAAI6jI+pywkNY3wG0GBvrsd2tXGYSGnfiF7ikpXemTpOiJScasYoDJJrjsG9gkCJ0ag6KhmaIe3pjDYBBQA7);
|
||||
}
|
||||
.mce-visualblocks blockquote {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhPgAKAIABALu7u////yH5BAEAAAEALAAAAAA+AAoAAAJPjI+py+0Knpz0xQDyuUhvfoGgIX5iSKZYgq5uNL5q69asZ8s5rrf0yZmpNkJZzFesBTu8TOlDVAabUyatguVhWduud3EyiUk45xhTTgMBBQA7);
|
||||
}
|
||||
.mce-visualblocks address {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhLQAKAIABALu7u////yH5BAEAAAEALAAAAAAtAAoAAAI/jI+pywwNozSP1gDyyZcjb3UaRpXkWaXmZW4OqKLhBmLs+K263DkJK7OJeifh7FicKD9A1/IpGdKkyFpNmCkAADs=);
|
||||
}
|
||||
.mce-visualblocks pre {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhFQAKAIABALu7uwAAACH5BAEAAAEALAAAAAAVAAoAAAIjjI+ZoN0cgDwSmnpz1NCueYERhnibZVKLNnbOq8IvKpJtVQAAOw==);
|
||||
}
|
||||
.mce-visualblocks figure {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhJAAKAIAAALu7u////yH5BAEAAAEALAAAAAAkAAoAAAI0jI+py+2fwAHUSFvD3RlvG4HIp4nX5JFSpnZUJ6LlrM52OE7uSWosBHScgkSZj7dDKnWAAgA7);
|
||||
}
|
||||
.mce-visualblocks figcaption {
|
||||
border: 1px dashed #bbb;
|
||||
}
|
||||
.mce-visualblocks hgroup {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhJwAKAIABALu7uwAAACH5BAEAAAEALAAAAAAnAAoAAAI3jI+pywYNI3uB0gpsRtt5fFnfNZaVSYJil4Wo03Hv6Z62uOCgiXH1kZIIJ8NiIxRrAZNMZAtQAAA7);
|
||||
}
|
||||
.mce-visualblocks aside {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhHgAKAIABAKqqqv///yH5BAEAAAEALAAAAAAeAAoAAAItjI+pG8APjZOTzgtqy7I3f1yehmQcFY4WKZbqByutmW4aHUd6vfcVbgudgpYCADs=);
|
||||
}
|
||||
.mce-visualblocks ul {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhDQAKAIAAALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybGuYnqUVSjvw26DzzXiqIDlVwAAOw==);
|
||||
}
|
||||
.mce-visualblocks ol {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhDQAKAIABALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybH6HHt0qourxC6CvzXieHyeWQAAOw==);
|
||||
}
|
||||
.mce-visualblocks dl {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhDQAKAIABALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybEOnmOvUoWznTqeuEjNSCqeGRUAOw==);
|
||||
}
|
||||
.mce-nbsp,
|
||||
.mce-shy {
|
||||
background: #aaa;
|
||||
}
|
||||
.mce-shy::after {
|
||||
content: '-';
|
||||
}
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
@ -1,44 +0,0 @@
|
||||
<template>
|
||||
<a-locale-provider :locale="locale">
|
||||
<div id="app">
|
||||
<router-view/>
|
||||
</div>
|
||||
</a-locale-provider>
|
||||
</template>
|
||||
<script>
|
||||
import zhCN from 'ant-design-vue/lib/locale-provider/zh_CN'
|
||||
import enquireScreen from '@/utils/device'
|
||||
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
locale: zhCN,
|
||||
}
|
||||
},
|
||||
created () {
|
||||
let that = this
|
||||
enquireScreen(deviceType => {
|
||||
// tablet
|
||||
if (deviceType === 0) {
|
||||
that.$store.commit('TOGGLE_DEVICE', 'mobile')
|
||||
that.$store.dispatch('setSidebar', false)
|
||||
}
|
||||
// mobile
|
||||
else if (deviceType === 1) {
|
||||
that.$store.commit('TOGGLE_DEVICE', 'mobile')
|
||||
that.$store.dispatch('setSidebar', false)
|
||||
}
|
||||
else {
|
||||
that.$store.commit('TOGGLE_DEVICE', 'desktop')
|
||||
that.$store.dispatch('setSidebar', true)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
#app {
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
@ -1,149 +0,0 @@
|
||||
import { getAction,deleteAction,putAction,postAction} from '@/api/manage'
|
||||
|
||||
////根路径
|
||||
// const doMian = "/jeecg-boot/";
|
||||
////图片预览请求地址
|
||||
// const imgView = "http://localhost:8080/jeecg-boot/sys/common/view/";
|
||||
|
||||
//角色管理
|
||||
const addRole = (params)=>postAction("/sys/role/add",params);
|
||||
const editRole = (params)=>putAction("/sys/role/edit",params);
|
||||
// const getRoleList = (params)=>getAction("/sys/role/list",params);
|
||||
// const deleteRole = (params)=>deleteAction("/sys/role/delete",params);
|
||||
// const deleteRoleList = (params)=>deleteAction("/sys/role/deleteBatch",params);
|
||||
const checkRoleCode = (params)=>getAction("/sys/role/checkRoleCode",params);
|
||||
const queryall = (params)=>getAction("/sys/role/queryall",params);
|
||||
|
||||
//用户管理
|
||||
const addUser = (params)=>postAction("/sys/user/add",params);
|
||||
const editUser = (params)=>putAction("/sys/user/edit",params);
|
||||
const queryUserRole = (params)=>getAction("/sys/user/queryUserRole",params);
|
||||
const getUserList = (params)=>getAction("/sys/user/list",params);
|
||||
// const deleteUser = (params)=>deleteAction("/sys/user/delete",params);
|
||||
// const deleteUserList = (params)=>deleteAction("/sys/user/deleteBatch",params);
|
||||
const frozenBatch = (params)=>putAction("/sys/user/frozenBatch",params);
|
||||
//验证用户是否存在
|
||||
const checkOnlyUser = (params)=>getAction("/sys/user/checkOnlyUser",params);
|
||||
//改变密码
|
||||
const changPassword = (params)=>putAction("/sys/user/changPassword",params);
|
||||
|
||||
//权限管理
|
||||
const addPermission= (params)=>postAction("/sys/permission/add",params);
|
||||
const editPermission= (params)=>putAction("/sys/permission/edit",params);
|
||||
const getPermissionList = (params)=>getAction("/sys/permission/list",params);
|
||||
/*update_begin author:wuxianquan date:20190908 for:添加查询一级菜单和子菜单查询api */
|
||||
const getSystemMenuList = (params)=>getAction("/sys/permission/getSystemMenuList",params);
|
||||
const getSystemSubmenu = (params)=>getAction("/sys/permission/getSystemSubmenu",params);
|
||||
/*update_end author:wuxianquan date:20190908 for:添加查询一级菜单和子菜单查询api */
|
||||
|
||||
// const deletePermission = (params)=>deleteAction("/sys/permission/delete",params);
|
||||
// const deletePermissionList = (params)=>deleteAction("/sys/permission/deleteBatch",params);
|
||||
const queryTreeList = (params)=>getAction("/sys/permission/queryTreeList",params);
|
||||
const queryTreeListForRole = (params)=>getAction("/sys/role/queryTreeList",params);
|
||||
const queryListAsync = (params)=>getAction("/sys/permission/queryListAsync",params);
|
||||
const queryRolePermission = (params)=>getAction("/sys/permission/queryRolePermission",params);
|
||||
const saveRolePermission = (params)=>postAction("/sys/permission/saveRolePermission",params);
|
||||
//const queryPermissionsByUser = (params)=>getAction("/sys/permission/queryByUser",params);
|
||||
const queryPermissionsByUser = (params)=>getAction("/sys/permission/getUserPermissionByToken",params);
|
||||
const loadAllRoleIds = (params)=>getAction("/sys/permission/loadAllRoleIds",params);
|
||||
const getPermissionRuleList = (params)=>getAction("/sys/permission/getPermRuleListByPermId",params);
|
||||
const queryPermissionRule = (params)=>getAction("/sys/permission/queryPermissionRule",params);
|
||||
|
||||
// 部门管理
|
||||
const queryDepartTreeList = (params)=>getAction("/sys/sysDepart/queryTreeList",params);
|
||||
const queryIdTree = (params)=>getAction("/sys/sysDepart/queryIdTree",params);
|
||||
const queryParentName = (params)=>getAction("/sys/sysDepart/queryParentName",params);
|
||||
const searchByKeywords = (params)=>getAction("/sys/sysDepart/searchBy",params);
|
||||
const deleteByDepartId = (params)=>deleteAction("/sys/sysDepart/delete",params);
|
||||
|
||||
//日志管理
|
||||
//const getLogList = (params)=>getAction("/sys/log/list",params);
|
||||
const deleteLog = (params)=>deleteAction("/sys/log/delete",params);
|
||||
const deleteLogList = (params)=>deleteAction("/sys/log/deleteBatch",params);
|
||||
|
||||
//数据字典
|
||||
const addDict = (params)=>postAction("/sys/dict/add",params);
|
||||
const editDict = (params)=>putAction("/sys/dict/edit",params);
|
||||
//const getDictList = (params)=>getAction("/sys/dict/list",params);
|
||||
const treeList = (params)=>getAction("/sys/dict/treeList",params);
|
||||
// const delDict = (params)=>deleteAction("/sys/dict/delete",params);
|
||||
//const getDictItemList = (params)=>getAction("/sys/dictItem/list",params);
|
||||
const addDictItem = (params)=>postAction("/sys/dictItem/add",params);
|
||||
const editDictItem = (params)=>putAction("/sys/dictItem/edit",params);
|
||||
//const delDictItem = (params)=>deleteAction("/sys/dictItem/delete",params);
|
||||
//const delDictItemList = (params)=>deleteAction("/sys/dictItem/deleteBatch",params);
|
||||
|
||||
//字典标签专用(通过code获取字典数组)
|
||||
export const ajaxGetDictItems = (code, params)=>getAction(`/sys/dict/getDictItems/${code}`,params);
|
||||
|
||||
//系统通告
|
||||
const doReleaseData = (params)=>getAction("/sys/annountCement/doReleaseData",params);
|
||||
const doReovkeData = (params)=>getAction("/sys/annountCement/doReovkeData",params);
|
||||
//获取系统访问量
|
||||
const getLoginfo = (params)=>getAction("/sys/loginfo",params);
|
||||
const getVisitInfo = (params)=>getAction("/sys/visitInfo",params);
|
||||
//数据日志访问
|
||||
// const getDataLogList = (params)=>getAction("/sys/dataLog/list",params);
|
||||
|
||||
// 根据部门主键查询用户信息
|
||||
const queryUserByDepId = (params)=>getAction("/sys/user/queryUserByDepId",params);
|
||||
|
||||
// 查询用户角色表里的所有信息
|
||||
const queryUserRoleMap = (params)=>getAction("/sys/user/queryUserRoleMap",params);
|
||||
// 重复校验
|
||||
const duplicateCheck = (params)=>getAction("/sys/duplicate/check",params);
|
||||
// 加载分类字典
|
||||
const loadCategoryData = (params)=>getAction("/sys/category/loadAllData",params);
|
||||
|
||||
export {
|
||||
// imgView,
|
||||
// doMian,
|
||||
addRole,
|
||||
editRole,
|
||||
checkRoleCode,
|
||||
addUser,
|
||||
editUser,
|
||||
queryUserRole,
|
||||
getUserList,
|
||||
queryall,
|
||||
frozenBatch,
|
||||
checkOnlyUser,
|
||||
changPassword,
|
||||
getPermissionList,
|
||||
addPermission,
|
||||
editPermission,
|
||||
queryTreeList,
|
||||
queryListAsync,
|
||||
queryRolePermission,
|
||||
saveRolePermission,
|
||||
queryPermissionsByUser,
|
||||
loadAllRoleIds,
|
||||
getPermissionRuleList,
|
||||
queryPermissionRule,
|
||||
queryDepartTreeList,
|
||||
queryIdTree,
|
||||
queryParentName,
|
||||
searchByKeywords,
|
||||
deleteByDepartId,
|
||||
deleteLog,
|
||||
deleteLogList,
|
||||
addDict,
|
||||
editDict,
|
||||
treeList,
|
||||
addDictItem,
|
||||
editDictItem,
|
||||
doReleaseData,
|
||||
doReovkeData,
|
||||
getLoginfo,
|
||||
getVisitInfo,
|
||||
queryUserByDepId,
|
||||
queryUserRoleMap,
|
||||
duplicateCheck,
|
||||
queryTreeListForRole,
|
||||
getSystemMenuList,
|
||||
getSystemSubmenu,
|
||||
loadCategoryData
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1,10 +0,0 @@
|
||||
const api = {
|
||||
Login: '/sys/login',
|
||||
Logout: '/sys/logout',
|
||||
ForgePassword: '/auth/forge-password',
|
||||
Register: '/auth/register',
|
||||
SendSms: '/account/sms',
|
||||
// get my info
|
||||
UserInfo: '/user/info'
|
||||
}
|
||||
export default api
|
||||
@ -1,58 +0,0 @@
|
||||
import api from './index'
|
||||
import { axios } from '@/utils/request'
|
||||
|
||||
/**
|
||||
* login func
|
||||
* parameter: {
|
||||
* username: '',
|
||||
* password: '',
|
||||
* remember_me: true,
|
||||
* captcha: '12345'
|
||||
* }
|
||||
* @param parameter
|
||||
* @returns {*}
|
||||
*/
|
||||
export function login(parameter) {
|
||||
return axios({
|
||||
url: '/sys/login',
|
||||
method: 'post',
|
||||
data: parameter
|
||||
})
|
||||
}
|
||||
|
||||
export function phoneLogin(parameter) {
|
||||
return axios({
|
||||
url: '/sys/phoneLogin',
|
||||
method: 'post',
|
||||
data: parameter
|
||||
})
|
||||
}
|
||||
|
||||
export function getSmsCaptcha(parameter) {
|
||||
return axios({
|
||||
url: api.SendSms,
|
||||
method: 'post',
|
||||
data: parameter
|
||||
})
|
||||
}
|
||||
|
||||
export function getInfo() {
|
||||
return axios({
|
||||
url: '/api/user/info',
|
||||
method: 'get',
|
||||
headers: {
|
||||
'Content-Type': 'application/json;charset=UTF-8'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export function logout(logoutToken) {
|
||||
return axios({
|
||||
url: '/sys/logout',
|
||||
method: 'post',
|
||||
headers: {
|
||||
'Content-Type': 'application/json;charset=UTF-8',
|
||||
'X-Access-Token': logoutToken
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -1,114 +0,0 @@
|
||||
import { axios } from '@/utils/request'
|
||||
|
||||
const api = {
|
||||
user: '/api/user',
|
||||
role: '/api/role',
|
||||
service: '/api/service',
|
||||
permission: '/api/permission',
|
||||
permissionNoPager: '/api/permission/no-pager'
|
||||
}
|
||||
|
||||
export default api
|
||||
|
||||
//post
|
||||
export function postAction(url,parameter) {
|
||||
return axios({
|
||||
url: url,
|
||||
method:'post' ,
|
||||
data: parameter
|
||||
})
|
||||
}
|
||||
|
||||
//post method= {post | put}
|
||||
export function httpAction(url,parameter,method) {
|
||||
return axios({
|
||||
url: url,
|
||||
method:method ,
|
||||
data: parameter
|
||||
})
|
||||
}
|
||||
|
||||
//put
|
||||
export function putAction(url,parameter) {
|
||||
return axios({
|
||||
url: url,
|
||||
method:'put',
|
||||
data: parameter
|
||||
})
|
||||
}
|
||||
|
||||
//get
|
||||
export function getAction(url,parameter) {
|
||||
return axios({
|
||||
url: url,
|
||||
method: 'get',
|
||||
params: parameter
|
||||
})
|
||||
}
|
||||
|
||||
//deleteAction
|
||||
export function deleteAction(url,parameter) {
|
||||
return axios({
|
||||
url: url,
|
||||
method: 'delete',
|
||||
params: parameter
|
||||
})
|
||||
}
|
||||
|
||||
export function getUserList(parameter) {
|
||||
return axios({
|
||||
url: api.user,
|
||||
method: 'get',
|
||||
params: parameter
|
||||
})
|
||||
}
|
||||
|
||||
export function getRoleList(parameter) {
|
||||
return axios({
|
||||
url: api.role,
|
||||
method: 'get',
|
||||
params: parameter
|
||||
})
|
||||
}
|
||||
|
||||
export function getServiceList(parameter) {
|
||||
return axios({
|
||||
url: api.service,
|
||||
method: 'get',
|
||||
params: parameter
|
||||
})
|
||||
}
|
||||
|
||||
export function getPermissions(parameter) {
|
||||
return axios({
|
||||
url: api.permissionNoPager,
|
||||
method: 'get',
|
||||
params: parameter
|
||||
})
|
||||
}
|
||||
|
||||
// id == 0 add post
|
||||
// id != 0 update put
|
||||
export function saveService(parameter) {
|
||||
return axios({
|
||||
url: api.service,
|
||||
method: parameter.id == 0 ? 'post' : 'put',
|
||||
data: parameter
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载文件 用于excel导出
|
||||
* @param url
|
||||
* @param parameter
|
||||
* @returns {*}
|
||||
*/
|
||||
export function downFile(url,parameter){
|
||||
return axios({
|
||||
url: url,
|
||||
params: parameter,
|
||||
method:'get' ,
|
||||
responseType: 'blob'
|
||||
})
|
||||
}
|
||||
|
||||
@ -1,69 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="1361px" height="609px" viewBox="0 0 1361 609" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 46.2 (44496) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>Group 21</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs></defs>
|
||||
<g id="Ant-Design-Pro-3.0" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="账户密码登录-校验" transform="translate(-79.000000, -82.000000)">
|
||||
<g id="Group-21" transform="translate(77.000000, 73.000000)">
|
||||
<g id="Group-18" opacity="0.8" transform="translate(74.901416, 569.699158) rotate(-7.000000) translate(-74.901416, -569.699158) translate(4.901416, 525.199158)">
|
||||
<ellipse id="Oval-11" fill="#CFDAE6" opacity="0.25" cx="63.5748792" cy="32.468367" rx="21.7830479" ry="21.766008"></ellipse>
|
||||
<ellipse id="Oval-3" fill="#CFDAE6" opacity="0.599999964" cx="5.98746479" cy="13.8668601" rx="5.2173913" ry="5.21330997"></ellipse>
|
||||
<path d="M38.1354514,88.3520215 C43.8984227,88.3520215 48.570234,83.6838647 48.570234,77.9254015 C48.570234,72.1669383 43.8984227,67.4987816 38.1354514,67.4987816 C32.3724801,67.4987816 27.7006688,72.1669383 27.7006688,77.9254015 C27.7006688,83.6838647 32.3724801,88.3520215 38.1354514,88.3520215 Z" id="Oval-3-Copy" fill="#CFDAE6" opacity="0.45"></path>
|
||||
<path d="M64.2775582,33.1704963 L119.185836,16.5654915" id="Path-12" stroke="#CFDAE6" stroke-width="1.73913043" stroke-linecap="round" stroke-linejoin="round"></path>
|
||||
<path d="M42.1431708,26.5002681 L7.71190162,14.5640702" id="Path-16" stroke="#E0B4B7" stroke-width="0.702678964" opacity="0.7" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="1.405357899873153,2.108036953469981"></path>
|
||||
<path d="M63.9262187,33.521561 L43.6721326,69.3250951" id="Path-15" stroke="#BACAD9" stroke-width="0.702678964" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="1.405357899873153,2.108036953469981"></path>
|
||||
<g id="Group-17" transform="translate(126.850922, 13.543654) rotate(30.000000) translate(-126.850922, -13.543654) translate(117.285705, 4.381889)" fill="#CFDAE6">
|
||||
<ellipse id="Oval-4" opacity="0.45" cx="9.13482653" cy="9.12768076" rx="9.13482653" ry="9.12768076"></ellipse>
|
||||
<path d="M18.2696531,18.2553615 C18.2696531,13.2142826 14.1798519,9.12768076 9.13482653,9.12768076 C4.08980114,9.12768076 0,13.2142826 0,18.2553615 L18.2696531,18.2553615 Z" id="Oval-4" transform="translate(9.134827, 13.691521) scale(-1, -1) translate(-9.134827, -13.691521) "></path>
|
||||
</g>
|
||||
</g>
|
||||
<g id="Group-14" transform="translate(216.294700, 123.725600) rotate(-5.000000) translate(-216.294700, -123.725600) translate(106.294700, 35.225600)">
|
||||
<ellipse id="Oval-2" fill="#CFDAE6" opacity="0.25" cx="29.1176471" cy="29.1402439" rx="29.1176471" ry="29.1402439"></ellipse>
|
||||
<ellipse id="Oval-2" fill="#CFDAE6" opacity="0.3" cx="29.1176471" cy="29.1402439" rx="21.5686275" ry="21.5853659"></ellipse>
|
||||
<ellipse id="Oval-2-Copy" stroke="#CFDAE6" opacity="0.4" cx="179.019608" cy="138.146341" rx="23.7254902" ry="23.7439024"></ellipse>
|
||||
<ellipse id="Oval-2" fill="#BACAD9" opacity="0.5" cx="29.1176471" cy="29.1402439" rx="10.7843137" ry="10.7926829"></ellipse>
|
||||
<path d="M29.1176471,39.9329268 L29.1176471,18.347561 C23.1616351,18.347561 18.3333333,23.1796097 18.3333333,29.1402439 C18.3333333,35.1008781 23.1616351,39.9329268 29.1176471,39.9329268 Z" id="Oval-2" fill="#BACAD9"></path>
|
||||
<g id="Group-9" opacity="0.45" transform="translate(172.000000, 131.000000)" fill="#E6A1A6">
|
||||
<ellipse id="Oval-2-Copy-2" cx="7.01960784" cy="7.14634146" rx="6.47058824" ry="6.47560976"></ellipse>
|
||||
<path d="M0.549019608,13.6219512 C4.12262681,13.6219512 7.01960784,10.722722 7.01960784,7.14634146 C7.01960784,3.56996095 4.12262681,0.670731707 0.549019608,0.670731707 L0.549019608,13.6219512 Z" id="Oval-2-Copy-2" transform="translate(3.784314, 7.146341) scale(-1, 1) translate(-3.784314, -7.146341) "></path>
|
||||
</g>
|
||||
<ellipse id="Oval-10" fill="#CFDAE6" cx="218.382353" cy="138.685976" rx="1.61764706" ry="1.61890244"></ellipse>
|
||||
<ellipse id="Oval-10-Copy-2" fill="#E0B4B7" opacity="0.35" cx="179.558824" cy="175.381098" rx="1.61764706" ry="1.61890244"></ellipse>
|
||||
<ellipse id="Oval-10-Copy" fill="#E0B4B7" opacity="0.35" cx="180.098039" cy="102.530488" rx="2.15686275" ry="2.15853659"></ellipse>
|
||||
<path d="M28.9985381,29.9671598 L171.151018,132.876024" id="Path-11" stroke="#CFDAE6" opacity="0.8"></path>
|
||||
</g>
|
||||
<g id="Group-10" opacity="0.799999952" transform="translate(1054.100635, 36.659317) rotate(-11.000000) translate(-1054.100635, -36.659317) translate(1026.600635, 4.659317)">
|
||||
<ellipse id="Oval-7" stroke="#CFDAE6" stroke-width="0.941176471" cx="43.8135593" cy="32" rx="11.1864407" ry="11.2941176"></ellipse>
|
||||
<g id="Group-12" transform="translate(34.596774, 23.111111)" fill="#BACAD9">
|
||||
<ellipse id="Oval-7" opacity="0.45" cx="9.18534718" cy="8.88888889" rx="8.47457627" ry="8.55614973"></ellipse>
|
||||
<path d="M9.18534718,17.4450386 C13.8657264,17.4450386 17.6599235,13.6143199 17.6599235,8.88888889 C17.6599235,4.16345787 13.8657264,0.332739156 9.18534718,0.332739156 L9.18534718,17.4450386 Z" id="Oval-7"></path>
|
||||
</g>
|
||||
<path d="M34.6597385,24.809694 L5.71666084,4.76878945" id="Path-2" stroke="#CFDAE6" stroke-width="0.941176471"></path>
|
||||
<ellipse id="Oval" stroke="#CFDAE6" stroke-width="0.941176471" cx="3.26271186" cy="3.29411765" rx="3.26271186" ry="3.29411765"></ellipse>
|
||||
<ellipse id="Oval-Copy" fill="#F7E1AD" cx="2.79661017" cy="61.1764706" rx="2.79661017" ry="2.82352941"></ellipse>
|
||||
<path d="M34.6312443,39.2922712 L5.06366663,59.785082" id="Path-10" stroke="#CFDAE6" stroke-width="0.941176471"></path>
|
||||
</g>
|
||||
<g id="Group-19" opacity="0.33" transform="translate(1282.537219, 446.502867) rotate(-10.000000) translate(-1282.537219, -446.502867) translate(1142.537219, 327.502867)">
|
||||
<g id="Group-17" transform="translate(141.333539, 104.502742) rotate(275.000000) translate(-141.333539, -104.502742) translate(129.333539, 92.502742)" fill="#BACAD9">
|
||||
<circle id="Oval-4" opacity="0.45" cx="11.6666667" cy="11.6666667" r="11.6666667"></circle>
|
||||
<path d="M23.3333333,23.3333333 C23.3333333,16.8900113 18.1099887,11.6666667 11.6666667,11.6666667 C5.22334459,11.6666667 0,16.8900113 0,23.3333333 L23.3333333,23.3333333 Z" id="Oval-4" transform="translate(11.666667, 17.500000) scale(-1, -1) translate(-11.666667, -17.500000) "></path>
|
||||
</g>
|
||||
<circle id="Oval-5-Copy-6" fill="#CFDAE6" cx="201.833333" cy="87.5" r="5.83333333"></circle>
|
||||
<path d="M143.5,88.8126685 L155.070501,17.6038544" id="Path-17" stroke="#BACAD9" stroke-width="1.16666667"></path>
|
||||
<path d="M17.5,37.3333333 L127.466252,97.6449735" id="Path-18" stroke="#BACAD9" stroke-width="1.16666667"></path>
|
||||
<polyline id="Path-19" stroke="#CFDAE6" stroke-width="1.16666667" points="143.902597 120.302281 174.935455 231.571342 38.5 147.510847 126.366941 110.833333"></polyline>
|
||||
<path d="M159.833333,99.7453842 L195.416667,89.25" id="Path-20" stroke="#E0B4B7" stroke-width="1.16666667" opacity="0.6"></path>
|
||||
<path d="M205.333333,82.1372105 L238.719406,36.1666667" id="Path-24" stroke="#BACAD9" stroke-width="1.16666667"></path>
|
||||
<path d="M266.723424,132.231988 L207.083333,90.4166667" id="Path-25" stroke="#CFDAE6" stroke-width="1.16666667"></path>
|
||||
<circle id="Oval-5" fill="#C1D1E0" cx="156.916667" cy="8.75" r="8.75"></circle>
|
||||
<circle id="Oval-5-Copy-3" fill="#C1D1E0" cx="39.0833333" cy="148.75" r="5.25"></circle>
|
||||
<circle id="Oval-5-Copy-2" fill-opacity="0.6" fill="#D1DEED" cx="8.75" cy="33.25" r="8.75"></circle>
|
||||
<circle id="Oval-5-Copy-4" fill-opacity="0.6" fill="#D1DEED" cx="243.833333" cy="30.3333333" r="5.83333333"></circle>
|
||||
<circle id="Oval-5-Copy-5" fill="#E0B4B7" cx="175.583333" cy="232.75" r="5.25"></circle>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 8.7 KiB |
@ -1,42 +0,0 @@
|
||||
|
||||
/*列表上方操作按钮区域*/
|
||||
.ant-card-body .table-operator {
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
/** Button按钮间距 */
|
||||
.table-operator .ant-btn {
|
||||
margin-right: 6px
|
||||
}
|
||||
/*列表td的padding设置 可以控制列表大小*/
|
||||
.ant-table-tbody .ant-table-row td {
|
||||
padding-top: 15px;
|
||||
padding-bottom: 15px;
|
||||
}
|
||||
|
||||
/*列表页面弹出modal*/
|
||||
.ant-modal-cust-warp {
|
||||
height: 100%
|
||||
}
|
||||
|
||||
/*弹出modal Y轴滚动条*/
|
||||
.ant-modal-cust-warp .ant-modal-body {
|
||||
height: calc(100% - 110px) !important;
|
||||
overflow-y: auto
|
||||
}
|
||||
|
||||
/*弹出modal 先有content后有body 故滚动条控制在body上*/
|
||||
.ant-modal-cust-warp .ant-modal-content {
|
||||
height: 90% !important;
|
||||
overflow-y: hidden
|
||||
}
|
||||
/*列表中有图片的加这个样式 参考用户管理*/
|
||||
.anty-img-wrap {
|
||||
height: 25px;
|
||||
position: relative;
|
||||
}
|
||||
.anty-img-wrap > img {
|
||||
max-height: 100%;
|
||||
}
|
||||
/*列表中范围查询样式*/
|
||||
.query-group-cust{width: calc(50% - 10px)}
|
||||
.query-group-split-cust:before{content:"~";width: 20px;display: inline-block;text-align: center}
|
||||
@ -1,28 +0,0 @@
|
||||
/**
|
||||
* 列表查询通用样式,移动端自适应
|
||||
*/
|
||||
.search{
|
||||
margin-bottom: 54px;
|
||||
}
|
||||
.fold{
|
||||
width: calc(100% - 216px);
|
||||
display: inline-block
|
||||
}
|
||||
.operator{
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
@media screen and (max-width: 900px) {
|
||||
.fold {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
.operator button {
|
||||
margin-right: 5px;
|
||||
}
|
||||
i {
|
||||
cursor: pointer;
|
||||
}
|
||||
.trcolor{
|
||||
background-color: rgba(255, 192, 203, 0.31);
|
||||
color:red;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 8.7 KiB |
@ -1,172 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="293px" height="293px" viewBox="0 0 293 293" enable-background="new 0 0 293 293" xml:space="preserve"> <image id="image0" width="293" height="293" x="0" y="0"
|
||||
href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASUAAAElCAQAAAAIbjz8AAAABGdBTUEAALGOfPtRkwAAACBjSFJN
|
||||
AAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAAAmJLR0QA/4ePzL8AAAAJcEhZ
|
||||
cwAACxMAAAsTAQCanBgAAAAHdElNRQfjBgUEFBDQiqnzAAAkNUlEQVR42u2dfXwU1bnHz+zbZDfJ
|
||||
ErJsAmQDJLBAIQQUbgS0UbQNasVKxZbeaFtTFajFWkRtMRWwkVZFaqUWUBvbq7mXVixWrEpaRVMF
|
||||
zAWFELjAQgJkAyTLhrBJdjP7ev+YO3d2ZmdmZ7PzcmZzvnz4ZHZ2dvec2d+e85znPOc5WAwgEFKg
|
||||
U7sAiEwBSQkhEUhKCIlAUkJIBJISQiKQlBASgaSEkAgkJYREICn9H26H2iXQOpgU3m6X0+niOt9S
|
||||
fmAOAADYPYt2qV3RZPgtH97ksQMAAE44XRXNXNe4HY1VZH1u+tDiV7vEyWiucDkJHAAAHO7ZB21e
|
||||
uT8vQUovPrR3vriXXh7Zn0Me6SMjrmQPsJ8PG3rzAmYA9BFzYORluSuSPj5rf05ET9Ynp9/qS6xP
|
||||
Xy5ZY3Mgr9cQVru8yRjI7s8JmshjcyC3Tx9hl5m6Qh/J6bf4xdZo0a7qBq7zCVIqbessUvsmIGDm
|
||||
ms//898d7sTzyFZCSASSEkIiDLxPhLMGAQAghglZ5jGM/o/F6GtjGABk74nFJLHsJYIsp/AVMYws
|
||||
PVUDZo3gqk/8neavD3VVfJ2oM2R9xNQpYCYtST54pfSV/zkwB4Dmit68ace4ekaalvKTk31Wrmfs
|
||||
nqu+FH6t0ric7SWjL5a3CF9zeCZffaYe5x6rqoXb0VYKwPSjQuMzr+3o9I5icizHBCeKO4RfG8+4
|
||||
c90F8ZJkYxB6cXNFaxkABB4wC93A8hbyP/y4nM0VBO6xC5fX6eKubWNVsh+V0nhtx6a5HQAMZlU1
|
||||
8l9l81Y2KVEaXilF9G6Hy1lTL+ZNtCEkfpGIQwnfTGrYvEISUhpes1sfMQdwQu3iwQRsQoINgRGc
|
||||
zTvzsNrFQ2gHQWcAXCYmAm6QXwkhEUhKCIlAUkJIBJISQiKQlBASgaSEkAgkJYREICkhJIIlJb9F
|
||||
7QIhtApLSp9ep3aBEFqFJSWfVTi8CYHggyUlAkdSQgyNBCkJxckhEPwkjOCQlBBDAzkDEBLBkFJz
|
||||
hdrFQWgXhpTKWunlzcj8hoOmSrVLIBaGlCz+ufupFVHUanOEupyapHYJxMJaceJwU1IKG/wW+LN1
|
||||
qMOOJZ9cL9+7B8xeW18u1StMOSFu1Y/6MKTktdm8xhB5HMNay7hTwyCWbleu+//0uq3L1a6vOBgd
|
||||
3N75Lif96Nw4r03t4iG0A6NV8th91pCReuSzopVf6gNXhgIhWLYS8nangilY2ibNO0X0AOgj8Wdc
|
||||
TrITjWFemzmgBauVISWrz2dFUhJPccf/fEWK93E7EnMR2D2XRpFHpydqw2Zl2EozD086RT/SyshB
|
||||
67gdX16VeJbu2LoKtWGzMlolp6uoE/4ci5mGwy2cH0UrNitrDk58ckuEUnBlRoIRgUwmahdtOONy
|
||||
RjU30c5bYDJ9IEIdDs+knaBasVlRqwQldGC0dvxKmmtGEbCCpAQldL497fj5GFJqKVe7OAiSimZd
|
||||
VO0ypArDr3RxtFYSlGYS9TUAAGD1LdhD+4+cLu05ZRhSKmlXuziZgcv5p+8zz9TVkn/pGDCv7Tc/
|
||||
BQCAKyMujCFN7LfvKOqkQny+/Rf+Vqm2DgAACrqrG+ByXbK83WoXJzN4/pHX7o1/fMPH5F+349i0
|
||||
rMExF5wut6OsNWDme73VR0mPawT33KMAAGDxm4LLt6pd03iQ2S07N3y8eyEAALicX17ldpyadHjm
|
||||
jiXTjgkJidyXjgSLeW3NFfP2Wfw4Qf5Tuz4U7JlBw9DeBiEWSkhe2/GppETOTFi/lj9yPrcvXkgA
|
||||
kLsBnJkA37INdveKpCQrlJBoevKfepJfSNkDh2axz00/qo2lAqiDk5F4Idm8U49bfT35Tz3JPz2b
|
||||
PbB5ZVsp81zIqA0hISnJCLtFKuokcGEhbVxN4N0FzA2hNeqiREgHV9e2Ygu/kHL6ty/FCQAI/Ng0
|
||||
Me+PxUxBterGHV+FpCQLiULy2mYcEWqR3r9l9EWrDycI3GeNX/fDDRa78aOl29WuJRNkdssAtXLN
|
||||
bwmYyXGO1zbpFH9yxpz+5x51OalF9j7r8an5PZdH8r8/Fvv6P7Ytg23pAJKSbLic7SUAlLQXdfbk
|
||||
zzjCL6TsgW3LfFYC91kJnPQa+az/9t/8g38sduNHf/yBep5uenkbEyQlmXA7yG1TPXYAHnyJ3yGZ
|
||||
23du3KlJZ8d77AROBd/W1p0fy3c9Fvv6P9QQkt9CiZvvR4GkJAt+S1spuf/uhTFCozbSs13eUtR5
|
||||
emJXIemc/OUvhIR0y/uv3qdGi9RZRI0lwzyaQVKSAb+lsyiv1+H22IWFlD1AebZtXpvX7Wgr7S54
|
||||
9DkYheS1JY/nRFKSgVOTzo4ff3b2wT0LhIX08gNeGy0Mhzu/Z9YhISHd8XZ9jTrG9tHpya9BUpKc
|
||||
lvIjMwC4OBqA+18Rdkj6rAdnX/cpLY5/+++z4/mu10W/+Te1hATAqUk4Qa2B4YukQn4lifHaTk4m
|
||||
cAJvK73+E6HhP+mQ9Fk7i6hzQnNtuuidb6knJADiV+PxlQJJSWLMAasPgP6cx54VEtKeBXm9pG+7
|
||||
vYQM1hASkj5y51svP8D8CpO7MaWGapWo8Dw2SEoSY/FPOxY01dYJTZE89+iRGV2FAABA4B776YnC
|
||||
QjKE376DLaQdS+54mwzkhQdkK0mOw/3PrwkLiZQQ6Y4k8K7CKSfOTOB/vz0L2JlMdix54GVls4Xa
|
||||
PewoqkRQqyQD/CubR1zZP9fhpkREnnvoRSEhGcJcQhrIVjZioLArefQmapVkIKef+3xeb1chAEWd
|
||||
pyadHe+zklISckgCAAB7uUBD9crNA9lK12jiabJDBoA/DTeSkmKQQgLA4ie92+fGEbjQFAkX6giJ
|
||||
DNyjlv6jOTiVoYREYvPavCMvL9ytDSEBAEBRJ+Xt5rMDka2UJuJWNDOFRHLL+7RPiY0hnNfLPldf
|
||||
o56QALD4kyUkQVJKC68t0T+d6E/K6U8U0uSTHcV872oI71nA9inX1zzyvHpCiodvOhdJKS1s3sIu
|
||||
9rkDc/pz4h/n9L/4EHsjoskn+adIDOHE4f/W5as2wb6vMZJSmpS1ss90FPfk049y+p97lMCZ6fRT
|
||||
FVJt3c9+zR/xpAzxeejWr+W6AkkpTRJnpAicdh6OuPJf3yXP0XPrqQpp1aaNq9UWEgDNFZQTQBfl
|
||||
njpBUpIc2pmX2/fF1aMv4gROEHhHMTlrlqqQIvqXHoRhAROBU60SX2IMJCXJcbrMAQAAyOl/9rEv
|
||||
r+rNs3sAICdu/ZZUhQTnvnzcLlgkpZRxOYVbiYrmEVeouTaPvaOYmr3yWacfTVVI8ED+IEiCpoZq
|
||||
jhqoXUStQQa2CZPTP+LKZ9deGNNdQE2PAADAwy/wT4mmLiSna/5eJes9fy/lnggbBrK53JSoVUqJ
|
||||
5oqTk+nbyDc3X1PfXeB0VTbNPGz3UJbTk0+lJiSmQ4HNpFO/+7GyGfpsXuSilBDSs0Ob1SEjt6+b
|
||||
koXTNX9vcYfVhxOpCmnVpsEs/nKUtm1ZoV5naAhnD3CeV6tAWsTir2gee57ONRLRn5ws3DbYvJVN
|
||||
bse1n6UqpJce5H/P0rZtyyqb1LwLE87Q23XH1US9ImkT5uY25Fo3YW786OJovue0JyQAjKHJJ+N3
|
||||
6KKAoIPjGg3ATfIM/3Rim9QdknALCQAA8nu4lgqoLqWGaq3sLJSIIcwXW0h1gsJC2jcvNSEVd6gn
|
||||
pOQb+KguJatPK9vBJJI1OOMI9zPdBS3lyYXEtrOSCam+Rr0Wqb0kmc9dZSk1VC/apW4J0kEX5TO6
|
||||
Cfzs+NK2zBESAB471FKqr6luUPPz5YPAV2wRCmxLVUhFnb//kbo2UvINulWVkna7NiHqa+prhP1I
|
||||
qQrp6i+2Lq9qjD/jtS3Ys2OJ2jVl1UvtAmQiOxdLKaQ5Bz67lnnGb7n6i4FsasdvZZh0KtkGPqqb
|
||||
3ZkHl/uOInUh6aKJQipr7SpUOmJg+tFkLhAkJcmZeZh7YmEoQkrMG+K3lLWeH6t8BJPNi1olxXG6
|
||||
EleLADA0IbFRS0hiQLaSQnAJaflW5g5NyfBbyltgFRJqlRQidSElJsTyW8pb3A5YhYSkpAipC2nO
|
||||
AXYnCbuQkJQUYChCYo/aAJh1CG4hISnJTupC+uq/EoU05URHMdxCQma3zAxFSP/8GvvcqEsD2cnm
|
||||
5dUHSUlGpBBSDLN5heO8YQF6rWsXaVqksEEbQkJSkg1phIS2Fhz2SCUkfqy+0ja1a8kESUkGZh1K
|
||||
X0jCZnb2wNr1zLAT9UFmtwws35p4JjUh+S1CWwtmD2xYA1+sF2qVFCB1ITnc/DZS9sCGNYliVR8k
|
||||
JdkRFtJNH3IJiT9VIKxCQlKSnWRCeu9W5hmvTZtCQraSzKQupImn+TO8wSwk1CrJynASEpKSjEgr
|
||||
JHNg3TqYhYSkJBtSC6m27qEX1a6TMMNaSm5HfApkKZFWSFZfbd3qjcxz973aVKnUfRLHEMzulnJl
|
||||
843Jh8PdWJU1KP2q163LUxVSSXuyDeSZzNt3ZsKcA+rnNIlnCK3SgTlqF1o63A7+3SGHzqFZ/M/d
|
||||
+l5qQsJiiUKqbDo8E778L0OQEnwue+1w63s7FzPPCAuJa6fayqYDc2BMwTysbSUAcCL57ovSkbqQ
|
||||
ElmwRyoh0enEpCFBSmMukJlQPfbGKmk/CkaqG4aSS4Xa0LSjmDsFxLhzXAKddOrnv2Ke8dqu/iLZ
|
||||
Drgh4+PP0I8W7qY3iEiXtlJpxTTMWyXlmHTqtXuZOd68tqu/6Crkm7blWla9cPen14Ulm5+Q2mhH
|
||||
UlKExPTIwkIyB0ZeZp+TVkgAABCfoDV9BKTkdrB3MUMMjcRkpMmE9NSTBd3Mc2whxbCefHE7ZCoF
|
||||
r5TChrZScq8gRHoMRUhsz3ZiixTDLoxJvkWGkvA2mFHdlRHw+S60hxRCmnGkrZTdtUV1fblwpV9M
|
||||
kBL8S/e0hBRCeuNuZfO7DZUE4dC7yFv8XDnjEeJJFJLfkqqQYlh3AffViblO1IUlJa8tZCQrqouW
|
||||
tMM1x6M1uIRU1pqakADgXwk3+qLaNWTCktLpiVSfbAgXdapdOC3DLST+RFt8QuJDF2WP8dSGISW/
|
||||
pauQtpWUnFLINObtk1dIAGAxU1DtWjJhmN2dRWJ2EkIkY82GNRuYZ4SFxBVq21Es/BnJt+xRGkar
|
||||
pP4W5JlJ6kJauJvcxlBLoKG/7AxFSJ9epz2njOYKrDWGJiRp59qUgSElc0Dt4mQa8gkJvmQ5DCnl
|
||||
98RvqoCmTdJFzhYphiWLdFIahpRs3hFXqDiZsAGN5tJD3q4tqoMtGxzLVhpzgZJSVHdhjNqF0zLy
|
||||
20iwzcyxpOR04QTlsTg/Vu3CaRfhLSSkMbZh6zUSRnB0ICg9sYtIDeHM/1KN2mAb5SVIKXGxDCJV
|
||||
Xni4u2A4DP+ZIL+SomSukASkpIta/GoXLtOQUki6aG5ffY3aNWKUiO8JFGQiNdK2SFhs1KWyVrXr
|
||||
FI9ABzf1uNqFyySk7tqwWGEXXFLKgD5aC3AJKf21/3CZIMjsVgB5hAQbSEqyMzyEJCClGAabN1Wb
|
||||
yCUk6OfgaMKGMxO0F8kHG/K1SFHd+bFwrZ4WaJU89s4itYunbeTt2nry20tg+rEnSIkOBA0ZhbZs
|
||||
QSRDfhuJwGGKxheYzrX4ExOzIMQiv5AM4RFXYIp75fUr6aIOt9OldvG0yqhLjz0r96jN5i1tg8mz
|
||||
xCslNHEydG579+EX2F+y1ELSR4o6pU21lS4CmUzQ6tyhkpjXXHo/EnyrcxNspcEstYuUeWSiQzIR
|
||||
gREcQhqGh5BQFKXsDBchISnJzPARkqBfCZEuw0lIGo8M8FuaK7jz+cPA8BKSxkPfLP6yVmqTCNgY
|
||||
bkLSeKsEgMUP5950w09ImpaS2wHTvHg8G1cfmjXchKThDq6heteivN6aeubOIUrDne0FthwjyqBR
|
||||
KdXXAPCXb8ewv37r3duUFxO18haLocklGk12cPU1APz4dzEMAI/95g+U346YWnCki8bnoxruaFJK
|
||||
Vt/r91BBX5dHfuuvSu9ARE0u6aKwjh/VQINScjkLuj+5nn7stS3Yo6yYKCmZgmMuqH034EGDUnK6
|
||||
Fu5m5gnpyb/hYyXFRH16YZcSwYGwZegezDo2jWvsrEEpLdiTGAhzeWRlk/IbIfJ1b5mXmcpvaSmn
|
||||
LMSA+fjUT69LvEZzUmqu+PgG6nj+XjqvwZUR1362dbkyJaBapbxe7iuujEg/fy1cGXAt/iMzKE9Z
|
||||
VPfQi1WNiddoTkrXfkYdlbT/8A+PPnfTh9TjsOFHv2fHU8vBj39HHXGHLLucPflwCUEKkudL1piU
|
||||
ph+lmlmcuONtAKy+LSueeJp6NoZtWzbzsNw+8ONTyb+6KLeldHimlOtmsRhsthIfmpJSfc2xaeQR
|
||||
Frv+k7JWnBh3rqizrvbNu+jb3VLucMtrNVFSNQdueZ/r+cxcIG/1UeFHfAumNCWl+1+hjiad+s6f
|
||||
ccLpKmu1+AFYsuPEFH2Eeu7yyHn71q+VqwxNlZTN4HQp42eHo1WafJK6w3wLpjQhJXKgX9hF+XMs
|
||||
/uoGq48SEgAAOF1hQ04/dX1Ut27dnAPydHTf+TN1NOUE3zVSOi7hEBIA5S3JgiI1IaWz47222jpq
|
||||
D1ksdsv78/bNPFzRzPx99OXGB5wcnF3Q3VglfVm6Csm/WYP8+2lnDaYrAC3GFWhASvU1HvvR6RvW
|
||||
UI/nHHjyqdkHuUzewzPjv96B7Js/uPsNacuyfCs1Npt1aNEu7musvvSXX2txBAi9lMgssLR/u6jz
|
||||
r98qb7F5ua9+4+7dC2mrKYY1VJuCUnqbXn6A/KuL8gkJAJxIf6kFLSVYOrjkQC8lAAD4/Y8o/7Y+
|
||||
UlsnvLy5qjFsmHaMfhwyrthS0C3NmC6nn/qKy1vYW5rSEHhmjuFo3A6us5BLyeXEiYujD86mHt/x
|
||||
thgn5NHp8W0TAB77NZ/PPMx9A8SzcPdANnmkj9z7Gv91Pmt/TrodFB0Rxd8qQb/QGy7MAZxYu556
|
||||
NPH0f3xP3OtGXxx5mWmxtJQXd0w/OvQ8aZVNtBF/w8fCu29fHimdrcM3boJvkRnkUgqY12yg/du/
|
||||
/pnYJDB3vdmfE9FPPc6U07Fpk09OPjmUGILpR//1Veq4qPPP3xG+2mtLT0r0+I2/TVI6gtPlTJYC
|
||||
AGop+S1/+ybdjizdvmSHuNfd/UZnUVQHQFtpSftjzxrCzFsy87AhvGSH1ya2FI1VWYOUlx0Ac6C+
|
||||
hs/op+jLTU9K9JfGLyWlW6X2kmR1glpKnUWPP0Mdl7X+8QfiXtVY9fdvUGEepya9deeHN/3wD8wb
|
||||
H9G/deeoSzhx9xvJBOVyWn0Ld9NTmRb/23dwzYozGchOT0pixm+6qLKtktuh4VappbyyiSq+OfD8
|
||||
I2Jft3xrfIbGjuJ7Xv/m3yL6LSvYtz5oaqgedUkXtfpWbUr0jN/9RvaALjr5ZF8ufW70xX3zhIXk
|
||||
tTVWAeC3SGMrCRndyttKmpVSU+WmVRdHk8dY7Id/SN4WkNz6Xlch84u8OPre1xqql28dzOooTgwL
|
||||
iWF9ub/5afYAFmP+a6hmCgKLLdt2YQzpT+cfC9q8sw+mm1go/tVC4ze1ligMZh2bxjV8gVRKDdWn
|
||||
JtGjtXn7Nq8U97odS/bOT9yApi932bZVmwBwuN2OGPbE06lncBx5+YObaVenkGfL5m2uSG93NzFG
|
||||
NwBZg3yBd3ITMLeUc/npoJRSfQ2B/+S3VJuQ27dlhdhXPvwCd9a6kHHLCsrUrqsdyI5hTzwtdnoj
|
||||
r/fNu3ryqVYx+STxF1en1yqJ83RnDyi72oVuA6O6gWyuQDgopQTA6/dQ4WO66EMvis0LUNnEH78Y
|
||||
1b172y3v046Aulq/JYbFsKpGPvMVi+X1rlsXwy6PjB85tpYlK8XZ8elMxsYLScgeyu3L7xn6p6SK
|
||||
3zL5JLM0idsaQrg6t6EaJ+jFSQv21NWKe92GNcIr9WPY4Zm3vL91OXP2bPdC6qipsr7m8MzBLACm
|
||||
Hl+/lk++wjFKfssLD6eXlp3uHIXjJ/N6lZSSxV/eQs0f6KLZA1ZfQTf7GgildP0nk09Sv027R2zn
|
||||
5rVtXpl8rf6lUd/9rzve/u1PuDxDlU2VTemWvbWsoTq99SZiJ3ILu5TO2U1HUZa3TDuWKGQIO7gV
|
||||
W6jftT7y2LNiV5rd+FFvnpgheMj45l3XfC5HJBMAALxze0dxOpaS2O4Ni6m3mDNrcNoxhztRyNBJ
|
||||
yeX8+zeo41veX71R3KtWbWorFf8VdhQv2bFys9RRlvU19TXptkliuzdTsLBL2tKnD3RSKmulfpkT
|
||||
ziSb66JwOf/je6kloiHwV+4vb5G6bdq1yGNXYvQGQE7/qEvSll0YMdNMkElp3j5KEqZgXa1Ya+C2
|
||||
d6nwD/HEsI7ixTsX7k439ISiofri6E+uT69Nol+ti8YHySQy8vK4c9KUWxw2r9eW7EcCldm9Y8n+
|
||||
udTx4p38sdNMqMnb1AkbPr5h1qGVm+kwltRprjg3jsABwInf/iTdLlN87KTDPfZ8ep+VKgdna2g6
|
||||
1+1Yup06droS/RbcNFa9d2s6bUFf7q9+Pv7sxtVDfX1Z6+STVp/Vt2pTusu74+2kZDNs048qvVVO
|
||||
8q4bIilVNFNeoazB5x8R27nd/0r6bcHF0U88bfMu3T6Uzs7iL28h8Pte7S5Idwo3PrREuFXCiQln
|
||||
0vus1NHQQu+mygtjqOO5+/mD8Jks2nVplDSz8P05OxdPPT7zcOqvvPuNe18T54gQgm5ZsZiwnQRA
|
||||
Xm9JuxR1TgW7J1lLCY2tNP2oPkK1Sp9cv3KzmAnchup/fTW9qVMmIePxqThh8U879rNfc4vZa9s7
|
||||
32Mnjx3urMEXH/roRmlCSuLtpGSWUnEHncFFKaYeT1YqSKTkcjpdZyaMO0fe0Bj20oMW/zOPC7/G
|
||||
b3nsWTm2HPNbDsxZssMcKOiecuIbf7/pw/we2jdu8xZ2EbjP2pO/f+7+uclHNWJJpU0CYMYR5fcP
|
||||
LerUSKvkdAHgcB+aNesQJaaNqy1+4ZHVzR9IGY7PJmA+O/7s+MYqXdQYwglTECeyBwxhAAay+3IH
|
||||
soMmKT85qqPfTRdN9us3huIXZylFctsVEimRlLd8cPPNH5C3Nap76kljiH+12dblyqRZj+oIPLnJ
|
||||
mR50J53MnwQAAKMvKt+9iQEas5ukqvHV+6jjqO4Xv6SXdzPx2tavzZRE6/GuDDFhtnP3X/ep2mXm
|
||||
Ik0pDX1dGR819U8/QR3zi0ns5C38RPTxnVtyKRlD7LQbsJCmlOQw/9ZsWLeOOuYW0+PPpDJ5Czfx
|
||||
4bfJOzcARl+cdUjseyu7BwyUX8ja9XRSwKiuto65uNvl/MMPM7Fz00fEpJqYu198VJWyrReUUgKg
|
||||
rnbZNuo4hm1bRiczHdrkLZyEjKl1bgBkD9z4kdql5gNSKQGwdfmWFfSvdO/8knZyWuMHfxzq5C1s
|
||||
hA3xbknmGmI+ylrFLuJSHoi/lOVbD82if6lnJkw50VjVVPnO7ZmRYD1siJ9zE2MlAWAI3/6O0tO4
|
||||
4oHKr8SmvCWiNwUp6fgtt76X0y+Hf1t54oUEgD4ibq3thDPpR5/LB8StEknQNPIydRzRXxkh5Zyb
|
||||
WjCFZAiLE5Iu+u2/qLuRYpLyqV2A5PTkzz5IP4roQ0Zt20rM8osVEgATznDnCYcFTXwpB+bER1TG
|
||||
sLBBixlkSeJHbeK7NgD0kXteh7lN0oiUAHjj7jfvir/pWm2bmNPA+og4cxsAAKacuO1dtUsvjGa+
|
||||
jiU7Ivr4eOYYFjZoy26K6piOVUNYvJCMoeoGscvd1UIzUgIAgM6ip5+I9whHdUGTVtqmkJEpfPE2
|
||||
EgAAVDYJJVJNl8YqKaZYNPJFUKzZENUxM3iEDUzrA0aiOmbHhsWMoVSENOPIwy8kS1qYDiXtUkyx
|
||||
aExKAAAQMMeP6ACIYSFjvOcYNtjtERYzhFNJ7I7FDsyR08fdVMm9r12qaFBKAByYs24d81cd1cEp
|
||||
p5CRHW+pjxhDqe0QcNWX8pZx+lFppn01KSUA1q5/5nF2qirY5BQ2sGWExYwh8aY2SX7PI8/zP+u1
|
||||
tZQ3VwgvwxaOKXM7pOo6BaRE4NIHtknH6o2v3jfyMtviiOpCRhjcBGFD4oAg9fYIAJz4+a/4U0x7
|
||||
bUenH5nhcgqLQTimTLo5PYGb7rFTW3vCSXXD9qU2L06wv54YFjYETWq1T1FdyJgoI1009fYIAF30
|
||||
+3/i37fAbzk9sbuAwMUuiJcbASkFTXKHx6dLVeNn1xZ0m4KmYOKvnfxKlfWKh4xcEtZFjaHUDG0S
|
||||
LPa1f9LxpNwQeE29kjUUQsDJV9QJ58qGeJyu41Ov+fzUJGOIPUlKEtFH9OQ6Djk3w4phfG1gqqO1
|
||||
eGYf3LRKqOuy+CeehmkqRaBVwgnlF+6ljsV/ZMbNHxjCABjCpiB3J0K2UHJ0ehF9yBg0cXu2dFFj
|
||||
KHXriGLyyd/8NNn9l9PXlDqqG6hSsHPxE09nDwAAgD5iCvK3A5SkgqZ0TPMYFjZQ7xO/XoQGixnC
|
||||
QuVITnHHSw/C1OKIISOkBMCaDZ9fU9RJfnW6qDGU7IskTXNKVmFDRM8tCvpqSjykDPmv1UeModR8
|
||||
2YlMO/bXb8Ec5MaNpiZEhXC62koX72ysojzLZNh9VCckEZIYRl6RnomOxcQHjAi/z7x9r98Db9gt
|
||||
PxnSKpHsXPzyAyOuxLdGZAuVbishDNmdSfMZ+sjS7X//hhaFlGFSAqC64cyEq75kG9/kl20KmoLS
|
||||
jeSwmD5iDJmCUgoVJx5/5o8/gHPtbXIyTEoAWPz75tXWkUZ4ItTXbwoawrpo8kxGTGj5mILGkNQO
|
||||
BrunoTqdrJhqw7CVvDa4hpdDZc2G295dtq2lXCg0TtwSRqXQRRfsefkBbXZs/1+H+AenJ6pdHGnw
|
||||
2s6Ov/+Vx56dcAYmufAz4sozj793q7aFxGqVzo0be179qdD0sXkX7QKgvubJp86O37asuwDmOhlD
|
||||
t7370oOZ0BswbvKSHcemaXctB5uaegKfc+CLq3/xy/weOadNho4uOvnkRzduX5oJQkowuz122Kdw
|
||||
U6Gm3mM/PfHhFy6MWb0xeYZXpRl7/tX7jszQmk+bH5aUCFxbqziSUd1Q0dyTD0Bdrduxe+GcA8aQ
|
||||
2iUCAAAsZvM+/UR7CSzhIdLAYUXAE4coDQ43uZ6isumza/tzHnjZ5lWzuzOGZhx55/bzY8XuKaUd
|
||||
EqQEs4k6VOKdfptXnh/7zu0zjijfPmExu+fBl86OlzfoXz0yqjsTS1XjdZ+2lr1154c3nR3flyt/
|
||||
K4zFcvpnH3zuUdgXRaYHS0p8WxJnGj3558ZNOTHlBAB2zxdX71rUXjKQLYekDOGRl+fu/9XPtRD5
|
||||
lXZdmQ/tHrULpAwONx18v2jX2vUAuB2bV354U0dxX2767hAsZgravLMO1dSL3aslE2BJqaSdSmQX
|
||||
0WeSWyA5Dje1EcaOJf/82rlx3QU9+QPZBC4uPlwXNYayBrMHbN6y1q//Y/FOrU7JpgNLSk4XFTIW
|
||||
1VHbwgw3luxIXC7ktfXkB8yDWYNZzKxzeb1jz+f3DEfhJJJgdlMjmxh2cbTahYMHmzczPNJywhr6
|
||||
t5TTx1dGqF04hJZgSenIDNpCUjYXPULrcEycZJq3G6EMw8LbjVAClnAcbtjmzzMf4Twk2oElpdkH
|
||||
udbfI+QkU8aGLCnZvLSPBHlLEKnAaxnpotKklUMMF3ilpI/EpzZGIJLBKyUsZvWpXTiElkBDf4RE
|
||||
ICkhJAJJCSERLCllirsMoTwsKZkDahcIoVUYUvJbkFsSMVQYUkJCQgwdZHYjJAJJCSERSEoIiYBY
|
||||
Sn5LY5XaZUCIB+KF3hZ/SbvaZZCb+hoAcMLuKWnP7zk6vaOYwAFwuGcf1GIME8RSSrb9lPbwW1rL
|
||||
zo3zWXGiuKO07fzYc+MAAIDA3Q6ftaA7a9Dq89gBcDvyes0B7Y2meaXksX/7L+oH5/bkp3J1fo/a
|
||||
5U1OVBfVAUBm5yWTz5PR9OS9po5Tzd2rBAGz8AISXilF9AGz2oUfPukwtASfMiA2uxFw4re0l3Cd
|
||||
R1JCpEjQ1FLeXJF4PqFL3rHkg5uZKRbkJ2wYyAYgYA6aqDP6iClo8eOEIQzAYFZfLtmk5vRbfVSm
|
||||
lcEsAg+aAmYAzIHcPkOYOg8DYQOBEzizIzAFzYHsAbI+fkvAHNHz1ccUzO0jaw4Pg1l+S0RPZnVp
|
||||
quS+BgrrrqX87Pipx/N7Tk88N47AqaXmdk9h18TTNi8Absf+uT4rAHbP/L3xw2S/pbPo8kjyGphw
|
||||
O45Ny+sde74n/+x4Oh+M1VfQXdrmcAPgte2d77EDYPVNPhmfCc5v6SwKmIs6YauP13Z6IgATT/fk
|
||||
t5fwJz9UXUp+y6lJmZ1YT+t4bQdnux1s2SeiupQQcOO3HJjTUSxmu2dkdiOSkNcLgJh9w1GrhJAI
|
||||
1CohJAJJCSERSEoIifhfYiLpk0SDlz8AAAAldEVYdGRhdGU6Y3JlYXRlADIwMTktMDYtMDRUMjA6
|
||||
MjA6MTYrMDg6MDBOMzq8AAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE5LTA2LTA0VDIwOjIwOjE2KzA4
|
||||
OjAwP26CAAAAAABJRU5ErkJggg==" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 13 KiB |
@ -1,73 +0,0 @@
|
||||
import Vue from 'vue'
|
||||
import { ACCESS_TOKEN } from "@/store/mutation-types"
|
||||
import store from '@/store'
|
||||
/**
|
||||
* 单点登录
|
||||
*/
|
||||
const init = (callback) => {
|
||||
console.log("-------单点登录开始-------");
|
||||
let token = Vue.ls.get(ACCESS_TOKEN);
|
||||
let st = getUrlParam("ticket");
|
||||
var sevice = "http://"+window.location.host+"/";
|
||||
if(token){
|
||||
loginSuccess(callback);
|
||||
}else{
|
||||
if(st){
|
||||
validateSt(st,sevice,callback);
|
||||
}else{
|
||||
var serviceUrl = encodeURIComponent(sevice);
|
||||
window.location.href = window._CONFIG['casPrefixUrl']+"/login?service="+serviceUrl;
|
||||
}
|
||||
}
|
||||
console.log("-------单点登录结束-------");
|
||||
};
|
||||
const SSO = {
|
||||
init: init
|
||||
};
|
||||
|
||||
function getUrlParam(paraName) {
|
||||
var url = document.location.toString();
|
||||
var arrObj = url.split("?");
|
||||
|
||||
if (arrObj.length > 1) {
|
||||
var arrPara = arrObj[1].split("&");
|
||||
var arr;
|
||||
|
||||
for (var i = 0; i < arrPara.length; i++) {
|
||||
arr = arrPara[i].split("=");
|
||||
|
||||
if (arr != null && arr[0] == paraName) {
|
||||
return arr[1];
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
function validateSt(ticket,service,callback){
|
||||
let params = {
|
||||
ticket: ticket,
|
||||
service:service
|
||||
};
|
||||
store.dispatch('ValidateLogin',params).then(res => {
|
||||
//this.departConfirm(res)
|
||||
if(res.success){
|
||||
loginSuccess(callback);
|
||||
}else{
|
||||
var sevice = "http://"+window.location.host+"/";
|
||||
var serviceUrl = encodeURIComponent(sevice);
|
||||
window.location.href = window._CONFIG['casPrefixUrl']+"/login?service="+serviceUrl;
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.log(err);
|
||||
//that.requestFailed(err);
|
||||
});
|
||||
}
|
||||
|
||||
function loginSuccess (callback) {
|
||||
callback();
|
||||
}
|
||||
export default SSO;
|
||||
@ -1,46 +0,0 @@
|
||||
<template>
|
||||
<tooltip v-if="tips !== ''">
|
||||
<template slot="title">{{ tips }}</template>
|
||||
<avatar :size="avatarSize" :src="src" />
|
||||
</tooltip>
|
||||
<avatar v-else :size="avatarSize" :src="src" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Avatar from 'ant-design-vue/es/avatar'
|
||||
import Tooltip from 'ant-design-vue/es/tooltip'
|
||||
|
||||
export default {
|
||||
name: "AvatarItem",
|
||||
components: {
|
||||
Avatar,
|
||||
Tooltip
|
||||
},
|
||||
props: {
|
||||
tips: {
|
||||
type: String,
|
||||
default: '',
|
||||
required: false
|
||||
},
|
||||
src: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
size: this.$parent.size
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
avatarSize () {
|
||||
return this.size !== 'mini' && this.size || 20
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'$parent.size' (val) {
|
||||
this.size = val
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -1,100 +0,0 @@
|
||||
<!--
|
||||
<template>
|
||||
<div :class="[prefixCls]">
|
||||
<ul>
|
||||
<slot></slot>
|
||||
<template v-for="item in filterEmpty($slots.default).slice(0, 3)"></template>
|
||||
|
||||
|
||||
<template v-if="maxLength > 0 && filterEmpty($slots.default).length > maxLength">
|
||||
<avatar-item :size="size">
|
||||
<avatar :size="size !== 'mini' && size || 20" :style="excessItemsStyle">{{ `+${maxLength}` }}</avatar>
|
||||
</avatar-item>
|
||||
</template>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
-->
|
||||
|
||||
<script>
|
||||
import Avatar from 'ant-design-vue/es/avatar'
|
||||
import AvatarItem from './Item'
|
||||
import { filterEmpty } from '@/components/_util/util'
|
||||
|
||||
export default {
|
||||
AvatarItem,
|
||||
name: "AvatarList",
|
||||
components: {
|
||||
Avatar,
|
||||
AvatarItem
|
||||
},
|
||||
props: {
|
||||
prefixCls: {
|
||||
type: String,
|
||||
default: 'ant-pro-avatar-list'
|
||||
},
|
||||
/**
|
||||
* 头像大小 类型: large、small 、mini, default
|
||||
* 默认值: default
|
||||
*/
|
||||
size: {
|
||||
type: [String, Number],
|
||||
default: 'default'
|
||||
},
|
||||
/**
|
||||
* 要显示的最大项目
|
||||
*/
|
||||
maxLength: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
/**
|
||||
* 多余的项目风格
|
||||
*/
|
||||
excessItemsStyle: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {
|
||||
color: '#f56a00',
|
||||
backgroundColor: '#fde3cf'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {}
|
||||
},
|
||||
methods: {
|
||||
getItems(items) {
|
||||
const classString = {
|
||||
[`${this.prefixCls}-item`]: true,
|
||||
[`${this.size}`]: true
|
||||
}
|
||||
|
||||
if (this.maxLength > 0) {
|
||||
items = items.slice(0, this.maxLength)
|
||||
items.push((<Avatar size={ this.size } style={ this.excessItemsStyle }>{`+${this.maxLength}`}</Avatar>))
|
||||
}
|
||||
const itemList = items.map((item) => (
|
||||
<li class={ classString }>{ item }</li>
|
||||
))
|
||||
return itemList
|
||||
}
|
||||
},
|
||||
render () {
|
||||
const { prefixCls, size } = this.$props
|
||||
const classString = {
|
||||
[`${prefixCls}`]: true,
|
||||
[`${size}`]: true,
|
||||
}
|
||||
const items = filterEmpty(this.$slots.default)
|
||||
const itemsDom = items && items.length ? <ul class={`${prefixCls}-items`}>{ this.getItems(items) }</ul> : null
|
||||
|
||||
return (
|
||||
<div class={ classString }>
|
||||
{ itemsDom }
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -1,4 +0,0 @@
|
||||
import AvatarList from './List'
|
||||
import "./index.less"
|
||||
|
||||
export default AvatarList
|
||||
@ -1,60 +0,0 @@
|
||||
@import "../index";
|
||||
|
||||
@avatar-list-prefix-cls: ~"@{ant-pro-prefix}-avatar-list";
|
||||
@avatar-list-item-prefix-cls: ~"@{ant-pro-prefix}-avatar-list-item";
|
||||
|
||||
.@{avatar-list-prefix-cls} {
|
||||
display: inline-block;
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
display: inline-block;
|
||||
padding: 0;
|
||||
margin: 0 0 0 8px;
|
||||
font-size: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.@{avatar-list-item-prefix-cls} {
|
||||
display: inline-block;
|
||||
font-size: @font-size-base;
|
||||
margin-left: -8px;
|
||||
width: @avatar-size-base;
|
||||
height: @avatar-size-base;
|
||||
|
||||
:global {
|
||||
.ant-avatar {
|
||||
border: 1px solid #fff;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
&.large {
|
||||
width: @avatar-size-lg;
|
||||
height: @avatar-size-lg;
|
||||
}
|
||||
|
||||
&.small {
|
||||
width: @avatar-size-sm;
|
||||
height: @avatar-size-sm;
|
||||
}
|
||||
|
||||
&.mini {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
|
||||
:global {
|
||||
.ant-avatar {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
|
||||
.ant-avatar-string {
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,103 +0,0 @@
|
||||
<template>
|
||||
<span>
|
||||
{{ lastTime | format }}
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
function fixedZero(val) {
|
||||
return val * 1 < 10 ? `0${val}` : val;
|
||||
}
|
||||
|
||||
export default {
|
||||
name: "CountDown",
|
||||
props: {
|
||||
format: {
|
||||
type: Function,
|
||||
default: undefined
|
||||
},
|
||||
target: {
|
||||
type: [Date, Number],
|
||||
required: true,
|
||||
},
|
||||
onEnd: {
|
||||
type: Function,
|
||||
default: () => {
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dateTime: '0',
|
||||
originTargetTime: 0,
|
||||
lastTime: 0,
|
||||
timer: 0,
|
||||
interval: 1000
|
||||
}
|
||||
},
|
||||
filters: {
|
||||
format(time) {
|
||||
const hours = 60 * 60 * 1000;
|
||||
const minutes = 60 * 1000;
|
||||
|
||||
const h = Math.floor(time / hours);
|
||||
const m = Math.floor((time - h * hours) / minutes);
|
||||
const s = Math.floor((time - h * hours - m * minutes) / 1000);
|
||||
return `${fixedZero(h)}:${fixedZero(m)}:${fixedZero(s)}`
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.initTime()
|
||||
this.tick()
|
||||
},
|
||||
methods: {
|
||||
initTime() {
|
||||
let lastTime = 0;
|
||||
let targetTime = 0;
|
||||
this.originTargetTime = this.target
|
||||
try {
|
||||
if (Object.prototype.toString.call(this.target) === '[object Date]') {
|
||||
targetTime = this.target
|
||||
} else {
|
||||
targetTime = new Date(this.target).getTime()
|
||||
}
|
||||
} catch (e) {
|
||||
throw new Error('invalid target prop')
|
||||
}
|
||||
|
||||
lastTime = targetTime - new Date().getTime();
|
||||
|
||||
this.lastTime = lastTime < 0 ? 0 : lastTime
|
||||
},
|
||||
tick() {
|
||||
const {onEnd} = this
|
||||
|
||||
this.timer = setTimeout(() => {
|
||||
if (this.lastTime < this.interval) {
|
||||
clearTimeout(this.timer)
|
||||
this.lastTime = 0
|
||||
if (typeof onEnd === 'function') {
|
||||
onEnd();
|
||||
}
|
||||
} else {
|
||||
this.lastTime -= this.interval
|
||||
this.tick()
|
||||
}
|
||||
}, this.interval)
|
||||
}
|
||||
},
|
||||
beforeUpdate () {
|
||||
if (this.originTargetTime !== this.target) {
|
||||
this.initTime()
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
clearTimeout(this.timer)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@ -1,3 +0,0 @@
|
||||
import CountDown from './CountDown'
|
||||
|
||||
export default CountDown
|
||||
@ -1,63 +0,0 @@
|
||||
<script>
|
||||
import Tooltip from 'ant-design-vue/es/tooltip'
|
||||
import { cutStrByFullLength, getStrFullLength } from '@/components/_util/StringUtil'
|
||||
/*
|
||||
const isSupportLineClamp = document.body.style.webkitLineClamp !== undefined;
|
||||
|
||||
const TooltipOverlayStyle = {
|
||||
overflowWrap: 'break-word',
|
||||
wordWrap: 'break-word',
|
||||
};
|
||||
*/
|
||||
|
||||
export default {
|
||||
name: 'Ellipsis',
|
||||
components: {
|
||||
Tooltip
|
||||
},
|
||||
props: {
|
||||
prefixCls: {
|
||||
type: String,
|
||||
default: 'ant-pro-ellipsis'
|
||||
},
|
||||
tooltip: {
|
||||
type: Boolean
|
||||
},
|
||||
length: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
lines: {
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
fullWidthRecognition: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getStrDom (str) {
|
||||
return (
|
||||
<span>{ cutStrByFullLength(str, this.length) + '...' }</span>
|
||||
)
|
||||
},
|
||||
getTooltip ( fullStr) {
|
||||
return (
|
||||
<Tooltip>
|
||||
<template slot="title">{ fullStr }</template>
|
||||
{ this.getStrDom(fullStr) }
|
||||
</Tooltip>
|
||||
)
|
||||
}
|
||||
},
|
||||
render () {
|
||||
const { tooltip, length } = this.$props
|
||||
let str = this.$slots.default.map(vNode => vNode.text).join("")
|
||||
const strDom = tooltip && getStrFullLength(str) > length ? this.getTooltip(str) : this.getStrDom(str);
|
||||
return (
|
||||
strDom
|
||||
)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -1,3 +0,0 @@
|
||||
import Ellipsis from './Ellipsis'
|
||||
|
||||
export default Ellipsis
|
||||
@ -1,54 +0,0 @@
|
||||
<template>
|
||||
<div :class="[prefixCls]">
|
||||
<slot name="subtitle">
|
||||
<div :class="[`${prefixCls}-subtitle`]">{{ typeof subTitle === 'string' ? subTitle : subTitle() }}</div>
|
||||
</slot>
|
||||
<div class="number-info-value">
|
||||
<span>{{ total }}</span>
|
||||
<span class="sub-total">
|
||||
{{ subTotal }}
|
||||
<icon :type="`caret-${status}`" />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Icon from 'ant-design-vue/es/icon'
|
||||
|
||||
export default {
|
||||
name: 'NumberInfo',
|
||||
props: {
|
||||
prefixCls: {
|
||||
type: String,
|
||||
default: 'ant-pro-number-info'
|
||||
},
|
||||
total: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
subTotal: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
subTitle: {
|
||||
type: [String, Function],
|
||||
default: ''
|
||||
},
|
||||
status: {
|
||||
type: String,
|
||||
default: 'up'
|
||||
}
|
||||
},
|
||||
components: {
|
||||
Icon
|
||||
},
|
||||
data () {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
@import "index";
|
||||
</style>
|
||||
@ -1,3 +0,0 @@
|
||||
import NumberInfo from './NumberInfo'
|
||||
|
||||
export default NumberInfo
|
||||
@ -1,55 +0,0 @@
|
||||
@import "../index";
|
||||
|
||||
@numberInfo-prefix-cls: ~"@{ant-pro-prefix}-number-info";
|
||||
|
||||
.@{numberInfo-prefix-cls} {
|
||||
|
||||
.ant-pro-number-info-subtitle {
|
||||
color: @text-color-secondary;
|
||||
font-size: @font-size-base;
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
word-break: break-all;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.number-info-value {
|
||||
margin-top: 4px;
|
||||
font-size: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
word-break: break-all;
|
||||
white-space: nowrap;
|
||||
|
||||
& > span {
|
||||
color: @heading-color;
|
||||
display: inline-block;
|
||||
line-height: 32px;
|
||||
height: 32px;
|
||||
font-size: 24px;
|
||||
margin-right: 32px;
|
||||
}
|
||||
|
||||
.sub-total {
|
||||
color: @text-color-secondary;
|
||||
font-size: @font-size-lg;
|
||||
vertical-align: top;
|
||||
margin-right: 0;
|
||||
i {
|
||||
font-size: 12px;
|
||||
transform: scale(0.82);
|
||||
margin-left: 4px;
|
||||
}
|
||||
:global {
|
||||
.anticon-caret-up {
|
||||
color: @red-6;
|
||||
}
|
||||
.anticon-caret-down {
|
||||
color: @green-6;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,43 +0,0 @@
|
||||
####1._util包:存放自定义函数 详细见代码注释
|
||||
####2.AvatarList:显示头像群并支持tip,用法参考src\views\Home.vue(如下图)
|
||||

|
||||
####3.chart包:存放各种图表相关的组件,条形图柱形图折线图等等 具体用法参考首页
|
||||
####4.countDown包:一个倒计时组件,用法参考home页,简单描述,该组件有3个属性,
|
||||
target(时间/毫秒数)必填,
|
||||
format(function,该方法接收一个毫秒数的参数,用于格式化显示当前倒计时时间)非必填,
|
||||
onEnd倒计时结束触发函数
|
||||

|
||||
####5.dict包:数据字典专用,用法参考文件夹下readme文件
|
||||
####6.Ellipsis包:字符串截取组件,可以指定字符串的显示长度,并将全部内容显示到tip中,简单使用参考src\views\system\PermissionList.vue
|
||||
####7.jeecg包:该包下自定义了很多列表/表单中用到的组件 参考包下readme文件
|
||||
####8.jeecgbiz包:该包下定义了一些业务相关的组件,比如选择用户弹框,根据部门选择用户等等
|
||||
####9.layouts+page包:系统页面布局相关组件,比如登陆进去之后页面顶部显示什么,底部显示什么,菜单点击触发多个tab的布局等等 一般情况不需要修改
|
||||
####10.menun包:菜单组件,俩个,一个折叠菜单一个正常显示的菜单
|
||||
####11.NumberInfo:数字信息显示组件 如下图
|
||||

|
||||
####12.online包:该包下封装了online表单的相关组件,用于展示表单各种控件,验证表单等等,相关用法参考readme
|
||||
####13.setting包:该包下封装了首页风格切换等功能如下图
|
||||

|
||||
####14.table包:一个二次封装的table组件,用于展示列表,参考readme
|
||||
####15.tools包:
|
||||
Breadcrumb.vue:面包屑二次封装,支持路由跳转
|
||||
DetailList.vue:详情展示用法参考src\views\profile\advanced\Advanced.vue(效果如下图)
|
||||

|
||||
````
|
||||
个人认为该页面代码有两点值得学习:
|
||||
1.vue provide/inject的使用
|
||||
2.该页面css定义方式,只定义一个顶层class,其余样式都定义在其下,这样只要顶层class不和别的页面冲突,整个页面的样式都是唯一生效的
|
||||
````
|
||||
FooterToolBar.vue:fixed定位的底部,通过是否定义内部控件的属性slot="extra"决定是左浮动或是右浮动
|
||||
HeaderNotice.vue:首页通知(如下图)
|
||||

|
||||
HeaderInfo.vue:上下文字布局(如下图)
|
||||

|
||||
Logo.vue:首页左上侧的log图
|
||||

|
||||
UserMenu.vue:首页右上侧的内容
|
||||

|
||||
####16.trend包 趋势显示组件(如下图)
|
||||

|
||||

|
||||

|
||||
@ -1,41 +0,0 @@
|
||||
<template>
|
||||
<div :class="[prefixCls, reverseColor && 'reverse-color' ]">
|
||||
<span>
|
||||
<slot name="term"></slot>
|
||||
<span class="item-text">
|
||||
<slot></slot>
|
||||
</span>
|
||||
</span>
|
||||
<span :class="[flag]"><a-icon :type="`caret-${flag}`"/></span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "Trend",
|
||||
props: {
|
||||
prefixCls: {
|
||||
type: String,
|
||||
default: 'ant-pro-trend'
|
||||
},
|
||||
/**
|
||||
* 上升下降标识:up|down
|
||||
*/
|
||||
flag: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
/**
|
||||
* 颜色反转
|
||||
*/
|
||||
reverseColor: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
@import "index";
|
||||
</style>
|
||||
@ -1,3 +0,0 @@
|
||||
import Trend from './Trend.vue'
|
||||
|
||||
export default Trend
|
||||
@ -1,42 +0,0 @@
|
||||
@import "../index";
|
||||
|
||||
@trend-prefix-cls: ~"@{ant-pro-prefix}-trend";
|
||||
|
||||
.@{trend-prefix-cls} {
|
||||
display: inline-block;
|
||||
font-size: @font-size-base;
|
||||
line-height: 22px;
|
||||
|
||||
.up,
|
||||
.down {
|
||||
margin-left: 4px;
|
||||
position: relative;
|
||||
top: 1px;
|
||||
|
||||
i {
|
||||
font-size: 12px;
|
||||
transform: scale(0.83);
|
||||
}
|
||||
}
|
||||
|
||||
.item-text {
|
||||
display: inline-block;
|
||||
margin-left: 8px;
|
||||
color: rgba(0,0,0,.85);
|
||||
}
|
||||
|
||||
.up {
|
||||
color: @red-6;
|
||||
}
|
||||
.down {
|
||||
color: @green-6;
|
||||
top: -1px;
|
||||
}
|
||||
|
||||
&.reverse-color .up {
|
||||
color: @green-6;
|
||||
}
|
||||
&.reverse-color .down {
|
||||
color: @red-6;
|
||||
}
|
||||
}
|
||||
@ -1,35 +0,0 @@
|
||||
/**
|
||||
* 获取字符串的长度ascii长度为1 中文长度为2
|
||||
* @param str
|
||||
* @returns {number}
|
||||
*/
|
||||
export const getStrFullLength = (str = '') =>
|
||||
str.split('').reduce((pre, cur) => {
|
||||
const charCode = cur.charCodeAt(0)
|
||||
if (charCode >= 0 && charCode <= 128) {
|
||||
return pre + 1
|
||||
}
|
||||
return pre + 2
|
||||
}, 0)
|
||||
|
||||
/**
|
||||
* 给定一个字符串和一个长度,将此字符串按指定长度截取
|
||||
* @param str
|
||||
* @param maxLength
|
||||
* @returns {string}
|
||||
*/
|
||||
export const cutStrByFullLength = (str = '', maxLength) => {
|
||||
let showLength = 0
|
||||
return str.split('').reduce((pre, cur) => {
|
||||
const charCode = cur.charCodeAt(0)
|
||||
if (charCode >= 0 && charCode <= 128) {
|
||||
showLength += 1
|
||||
} else {
|
||||
showLength += 2
|
||||
}
|
||||
if (showLength <= maxLength) {
|
||||
return pre + cur
|
||||
}
|
||||
return pre
|
||||
}, '')
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
/**
|
||||
* components util
|
||||
*/
|
||||
|
||||
/**
|
||||
* 清理空值,对象
|
||||
* @param children
|
||||
* @returns {*[]}
|
||||
*/
|
||||
export function filterEmpty (children = []) {
|
||||
return children.filter(c => c.tag || (c.text && c.text.trim() !== ''))
|
||||
}
|
||||
@ -1,88 +0,0 @@
|
||||
<template>
|
||||
<div :style="{ padding: '0' }">
|
||||
<h4 :style="{ marginBottom: '20px' }">{{ title }}</h4>
|
||||
|
||||
<v-chart ref="chart" :forceFit="true" :height="height" :data="dataSource" :scale="scale">
|
||||
<v-tooltip :shared="false"/>
|
||||
<v-axis/>
|
||||
<v-line position="x*y" :size="lineSize" :color="lineColor"/>
|
||||
<v-area position="x*y" :color="color"/>
|
||||
</v-chart>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { triggerWindowResizeEvent } from '@/utils/util'
|
||||
|
||||
export default {
|
||||
name: 'AreaChartTy',
|
||||
props: {
|
||||
// 图表数据
|
||||
dataSource: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
// 图表标题
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
// x 轴别名
|
||||
x: {
|
||||
type: String,
|
||||
default: 'x'
|
||||
},
|
||||
// y 轴别名
|
||||
y: {
|
||||
type: String,
|
||||
default: 'y'
|
||||
},
|
||||
// Y轴最小值
|
||||
min: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
// Y轴最大值
|
||||
max: {
|
||||
type: Number,
|
||||
default: null
|
||||
},
|
||||
// 图表高度
|
||||
height: {
|
||||
type: Number,
|
||||
default: 254
|
||||
},
|
||||
// 线的粗细
|
||||
lineSize: {
|
||||
type: Number,
|
||||
default: 2
|
||||
},
|
||||
// 面积的颜色
|
||||
color: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
// 线的颜色
|
||||
lineColor: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
scale() {
|
||||
return [
|
||||
{ dataKey: 'x', title: this.x, alias: this.x },
|
||||
{ dataKey: 'y', title: this.y, alias: this.y, min: this.min, max: this.max }
|
||||
]
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
triggerWindowResizeEvent()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "chart";
|
||||
</style>
|
||||
@ -1,50 +0,0 @@
|
||||
<template>
|
||||
<div :style="{ padding: '0 0 32px 32px' }">
|
||||
<h4 :style="{ marginBottom: '20px' }">{{ title }}</h4>
|
||||
<v-chart :forceFit="true" :height="height" :data="dataSource" :scale="scale" :padding="padding">
|
||||
<v-tooltip/>
|
||||
<v-axis/>
|
||||
<v-bar position="x*y"/>
|
||||
</v-chart>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { triggerWindowResizeEvent } from '@/utils/util'
|
||||
|
||||
export default {
|
||||
name: 'Bar',
|
||||
props: {
|
||||
dataSource: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
yaxisText: {
|
||||
type: String,
|
||||
default: 'y'
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
height: {
|
||||
type: Number,
|
||||
default: 254
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return { padding: ['auto', 'auto', '40', '50'] }
|
||||
},
|
||||
computed: {
|
||||
scale() {
|
||||
return [{
|
||||
dataKey: 'y',
|
||||
alias: this.yaxisText
|
||||
}]
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
triggerWindowResizeEvent()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -1,57 +0,0 @@
|
||||
<template>
|
||||
<div :style="{ padding: '0 0 32px 32px' }">
|
||||
<h4 :style="{ marginBottom: '20px' }">{{ title }}</h4>
|
||||
<v-chart :forceFit="true" :height="height" :data="data" :scale="scale">
|
||||
<v-tooltip/>
|
||||
<v-legend/>
|
||||
<v-axis/>
|
||||
<v-bar position="type*bar"/>
|
||||
<v-line position="type*line" color="#2fc25b" :size="3"/>
|
||||
</v-chart>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: 'BarMultid',
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
dataSource: {
|
||||
type: Array,
|
||||
default: () => [
|
||||
{ type: '10:10', bar: 2, line: 2 },
|
||||
{ type: '10:15', bar: 6, line: 3 },
|
||||
{ type: '10:20', bar: 2, line: 5 },
|
||||
{ type: '10:25', bar: 9, line: 1 },
|
||||
{ type: '10:30', bar: 2, line: 3 },
|
||||
{ type: '10:35', bar: 2, line: 1 },
|
||||
{ type: '10:40', bar: 1, line: 2 }
|
||||
]
|
||||
},
|
||||
height: {
|
||||
type: Number,
|
||||
default: 400
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
scale: [{
|
||||
dataKey: 'bar',
|
||||
min: 0
|
||||
}, {
|
||||
dataKey: 'line',
|
||||
min: 0
|
||||
}]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
data() {
|
||||
return this.dataSource
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -1,72 +0,0 @@
|
||||
<template>
|
||||
<div :style="{ padding: '0 0 32px 32px' }">
|
||||
<h4 :style="{ marginBottom: '20px' }">{{ title }}</h4>
|
||||
<v-chart :forceFit="true" :height="height" :data="data">
|
||||
<v-tooltip />
|
||||
<v-axis />
|
||||
<v-legend />
|
||||
<v-bar position="x*y" color="type" :adjust="adjust" />
|
||||
</v-chart>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { DataSet } from '@antv/data-set'
|
||||
|
||||
export default {
|
||||
name: 'BarMultid',
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
dataSource:{
|
||||
type: Array,
|
||||
default: () => [
|
||||
{ type: 'Jeecg', 'Jan.': 18.9, 'Feb.': 28.8, 'Mar.': 39.3, 'Apr.': 81.4, 'May': 47, 'Jun.': 20.3, 'Jul.': 24, 'Aug.': 35.6 },
|
||||
{ type: 'Jeebt', 'Jan.': 12.4, 'Feb.': 23.2, 'Mar.': 34.5, 'Apr.': 99.7, 'May': 52.6, 'Jun.': 35.5, 'Jul.': 37.4, 'Aug.': 42.4 }
|
||||
]
|
||||
},
|
||||
fields:{
|
||||
type: Array,
|
||||
default: () => ['Jan.', 'Feb.', 'Mar.', 'Apr.', 'May', 'Jun.', 'Jul.', 'Aug.']
|
||||
},
|
||||
height: {
|
||||
type: Number,
|
||||
default: 254
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
adjust: [{
|
||||
type: 'dodge',
|
||||
marginRatio: 1 / 32
|
||||
}]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
data() {
|
||||
const dv = new DataSet.View().source(this.dataSource)
|
||||
dv.transform({
|
||||
type: 'fold',
|
||||
fields: this.fields,
|
||||
key: 'x',
|
||||
value: 'y'
|
||||
})
|
||||
|
||||
// bar 使用不了 - 和 / 所以替换下
|
||||
return dv.rows.map(row => {
|
||||
if (typeof row.x === 'string') {
|
||||
row.x = row.x.replace(/[-/]/g, '_')
|
||||
}
|
||||
return row
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@ -1,187 +0,0 @@
|
||||
<template>
|
||||
<div :style="{ padding: '0 0 32px 32px' }">
|
||||
<v-chart :forceFit="true" :height="350" :data="chartData" :scale="scale">
|
||||
<v-coord type="polar" :startAngle="-202.5" :endAngle="22.5" :radius="0.75"></v-coord>
|
||||
<v-axis
|
||||
dataKey="value"
|
||||
:zIndex="2"
|
||||
:line="null"
|
||||
:label="axisLabel"
|
||||
:subTickCount="4"
|
||||
:subTickLine="axisSubTickLine"
|
||||
:tickLine="axisTickLine"
|
||||
:grid="null"
|
||||
></v-axis>
|
||||
<v-axis dataKey="1" :show="false"></v-axis>
|
||||
<v-series
|
||||
gemo="point"
|
||||
position="value*1"
|
||||
shape="pointer"
|
||||
color="#1890FF"
|
||||
:active="false"
|
||||
></v-series>
|
||||
<v-guide
|
||||
type="arc"
|
||||
:zIndex="0"
|
||||
:top="false"
|
||||
:start="arcGuide1Start"
|
||||
:end="arcGuide1End"
|
||||
:vStyle="arcGuide1Style"
|
||||
></v-guide>
|
||||
<v-guide
|
||||
type="arc"
|
||||
:zIndex="1"
|
||||
:start="arcGuide2Start"
|
||||
:end="getArcGuide2End()"
|
||||
:vStyle="arcGuide2Style"
|
||||
></v-guide>
|
||||
<v-guide
|
||||
type="html"
|
||||
:position="htmlGuidePosition"
|
||||
:html="getHtmlGuideHtml()"
|
||||
></v-guide>
|
||||
</v-chart>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { registerShape } from 'viser-vue';
|
||||
|
||||
registerShape('point', 'pointer', {
|
||||
draw(cfg, container) {
|
||||
let point = cfg.points[0];
|
||||
point = this.parsePoint(point);
|
||||
const center = this.parsePoint({
|
||||
x: 0,
|
||||
y: 0,
|
||||
});
|
||||
container.addShape('line', {
|
||||
attrs: {
|
||||
x1: center.x,
|
||||
y1: center.y,
|
||||
x2: point.x,
|
||||
y2: point.y + 15,
|
||||
stroke: cfg.color,
|
||||
lineWidth: 5,
|
||||
lineCap: 'round',
|
||||
}
|
||||
});
|
||||
return container.addShape('circle', {
|
||||
attrs: {
|
||||
x: center.x,
|
||||
y: center.y,
|
||||
r: 9.75,
|
||||
stroke: cfg.color,
|
||||
lineWidth: 4.5,
|
||||
fill: '#fff',
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const scale = [{
|
||||
dataKey: 'value',
|
||||
min: 0,
|
||||
max: 9,
|
||||
tickInterval: 1,
|
||||
nice: false,
|
||||
}];
|
||||
|
||||
const data = [
|
||||
{ value: 0},
|
||||
];
|
||||
|
||||
export default {
|
||||
name:"DashChartDemo",
|
||||
props:{
|
||||
datasource:{
|
||||
type: Number,
|
||||
default:0
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
created(){
|
||||
if(!this.datasource){
|
||||
this.chartData = data;
|
||||
}else{
|
||||
this.chartData = [
|
||||
{ value: this.datasource },
|
||||
];
|
||||
}
|
||||
this.getChartData()
|
||||
},
|
||||
watch: {
|
||||
'datasource': function (val) {
|
||||
this.chartData = [
|
||||
{ value: val},
|
||||
];
|
||||
this.getChartData();
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
getChartData(){
|
||||
if(this.chartData && this.chartData.length>0){
|
||||
this.abcd = this.chartData[0].value * 10
|
||||
}else{
|
||||
this.abcd = 70
|
||||
}
|
||||
},
|
||||
getHtmlGuideHtml(){
|
||||
return '<div style="width: 300px;text-align: center;">\n' +
|
||||
'<p style="font-size: 14px;color: #545454;margin: 0;">'+this.title+'</p>\n' +
|
||||
'<p style="font-size: 36px;color: #545454;margin: 0;">'+this.abcd+'%</p>\n' +
|
||||
'</div>'
|
||||
},
|
||||
getArcGuide2End(){
|
||||
return [this.chartData[0].value, 0.945]
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
chartData:[],
|
||||
height: 400,
|
||||
scale: scale,
|
||||
abcd:70,
|
||||
axisLabel: {
|
||||
offset: -16,
|
||||
textStyle: {
|
||||
fontSize: 18,
|
||||
textAlign: 'center',
|
||||
textBaseline: 'middle'
|
||||
}
|
||||
},
|
||||
axisSubTickLine: {
|
||||
length: -8,
|
||||
stroke: '#fff',
|
||||
strokeOpacity: 1,
|
||||
},
|
||||
axisTickLine: {
|
||||
length: -17,
|
||||
stroke: '#fff',
|
||||
strokeOpacity: 1,
|
||||
},
|
||||
arcGuide1Start: [0, 0.945],
|
||||
arcGuide1End: [9, 0.945],
|
||||
arcGuide1Style: {
|
||||
stroke: '#CBCBCB',
|
||||
lineWidth: 18,
|
||||
},
|
||||
arcGuide2Start: [0, 0.945],
|
||||
arcGuide2Style: {
|
||||
stroke: '#1890FF',
|
||||
lineWidth: 18,
|
||||
},
|
||||
htmlGuidePosition: ['50%', '100%'],
|
||||
htmlGuideHtml: `
|
||||
<div style="width: 300px;text-align: center;">
|
||||
<p style="font-size: 14px;color: #545454;margin: 0;">${this.title}</p>
|
||||
<p style="font-size: 36px;color: #545454;margin: 0;">${this.abcd}%</p>
|
||||
</div>
|
||||
`,
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@ -1,77 +0,0 @@
|
||||
<template>
|
||||
<div :style="{ padding: '0 0 32px 32px' }">
|
||||
<h4 :style="{ marginBottom: '20px' }">{{ title }}</h4>
|
||||
<v-chart :force-fit="true" :height="height" :data="data" :scale="scale">
|
||||
<v-tooltip/>
|
||||
<v-axis/>
|
||||
<v-legend/>
|
||||
<v-line position="type*y" color="x"/>
|
||||
<v-point position="type*y" color="x" :size="4" :v-style="style" :shape="'circle'"/>
|
||||
</v-chart>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { DataSet } from '@antv/data-set'
|
||||
|
||||
export default {
|
||||
name: 'LineChartMultid',
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
dataSource: {
|
||||
type: Array,
|
||||
default: () => [
|
||||
{ type: 'Jan', jeecg: 7.0, jeebt: 3.9 },
|
||||
{ type: 'Feb', jeecg: 6.9, jeebt: 4.2 },
|
||||
{ type: 'Mar', jeecg: 9.5, jeebt: 5.7 },
|
||||
{ type: 'Apr', jeecg: 14.5, jeebt: 8.5 },
|
||||
{ type: 'May', jeecg: 18.4, jeebt: 11.9 },
|
||||
{ type: 'Jun', jeecg: 21.5, jeebt: 15.2 },
|
||||
{ type: 'Jul', jeecg: 25.2, jeebt: 17.0 },
|
||||
{ type: 'Aug', jeecg: 26.5, jeebt: 16.6 },
|
||||
{ type: 'Sep', jeecg: 23.3, jeebt: 14.2 },
|
||||
{ type: 'Oct', jeecg: 18.3, jeebt: 10.3 },
|
||||
{ type: 'Nov', jeecg: 13.9, jeebt: 6.6 },
|
||||
{ type: 'Dec', jeecg: 9.6, jeebt: 4.8 }
|
||||
]
|
||||
},
|
||||
fields: {
|
||||
type: Array,
|
||||
default: () => ['jeecg', 'jeebt']
|
||||
},
|
||||
height: {
|
||||
type: Number,
|
||||
default: 254
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
scale: [{
|
||||
dataKey: 'x',
|
||||
min: 0,
|
||||
max: 1
|
||||
}],
|
||||
style: { stroke: '#fff', lineWidth: 1 }
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
data() {
|
||||
const dv = new DataSet.View().source(this.dataSource)
|
||||
dv.transform({
|
||||
type: 'fold',
|
||||
fields: this.fields,
|
||||
key: 'x',
|
||||
value: 'y'
|
||||
})
|
||||
return dv.rows
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@ -1,80 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<v-chart
|
||||
:forceFit="true"
|
||||
:height="height"
|
||||
:width="width"
|
||||
:data="data"
|
||||
:scale="scale"
|
||||
:padding="0">
|
||||
<v-tooltip/>
|
||||
<v-interval
|
||||
:shape="['liquid-fill-gauge']"
|
||||
position="transfer*value"
|
||||
color=""
|
||||
:v-style="{
|
||||
lineWidth: 8,
|
||||
opacity: 0.75
|
||||
}"
|
||||
:tooltip="[
|
||||
'transfer*value',
|
||||
(transfer, value) => {
|
||||
return {
|
||||
name: transfer,
|
||||
value,
|
||||
};
|
||||
},
|
||||
]"
|
||||
></v-interval>
|
||||
<v-guide
|
||||
v-for="(row, index) in data"
|
||||
:key="index"
|
||||
type="text"
|
||||
:top="true"
|
||||
:position="{
|
||||
gender: row.transfer,
|
||||
value: 45
|
||||
}"
|
||||
:content="row.value + '%'"
|
||||
:v-style="{
|
||||
fontSize: 100,
|
||||
textAlign: 'center',
|
||||
opacity: 0.75,
|
||||
}"
|
||||
/>
|
||||
</v-chart>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
const sourceDataConst = [
|
||||
{ transfer: '一月', value: 813 },
|
||||
{ transfer: '二月', value: 233 },
|
||||
{ transfer: '三月', value: 561 }
|
||||
]
|
||||
|
||||
export default {
|
||||
name: 'Liquid',
|
||||
props: {
|
||||
height: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
width: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
data: sourceDataConst,
|
||||
scale: []
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@ -1,69 +0,0 @@
|
||||
<template>
|
||||
<div class="antv-chart-mini">
|
||||
<div class="chart-wrapper" :style="{ height: 46 }">
|
||||
<v-chart :force-fit="true" :height="height" :data="data" :scale="scale" :padding="[36, 0, 18, 0]">
|
||||
<v-tooltip/>
|
||||
<v-smooth-area position="x*y"/>
|
||||
</v-chart>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import moment from 'dayjs'
|
||||
|
||||
const sourceData = []
|
||||
const beginDay = new Date().getTime()
|
||||
|
||||
for (let i = 0; i < 10; i++) {
|
||||
sourceData.push({
|
||||
x: moment(new Date(beginDay + 1000 * 60 * 60 * 24 * i)).format('YYYY-MM-DD'),
|
||||
y: Math.round(Math.random() * 10)
|
||||
})
|
||||
}
|
||||
|
||||
export default {
|
||||
name: 'MiniArea',
|
||||
props: {
|
||||
dataSource: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
// x 轴别名
|
||||
x: {
|
||||
type: String,
|
||||
default: 'x'
|
||||
},
|
||||
// y 轴别名
|
||||
y: {
|
||||
type: String,
|
||||
default: 'y'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
data: [],
|
||||
height: 100
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
scale() {
|
||||
return [
|
||||
{ dataKey: 'x', title: this.x, alias: this.x },
|
||||
{ dataKey: 'y', title: this.y, alias: this.y }
|
||||
]
|
||||
}
|
||||
},
|
||||
created() {
|
||||
if (this.dataSource.length === 0) {
|
||||
this.data = sourceData
|
||||
} else {
|
||||
this.data = this.dataSource
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "chart";
|
||||
</style>
|
||||
@ -1,76 +0,0 @@
|
||||
<template>
|
||||
<div :style="{'width':width==null?'auto':width+'px'}">
|
||||
<v-chart :forceFit="width==null" :height="height" :data="data" padding="0">
|
||||
<v-tooltip/>
|
||||
<v-bar position="x*y"/>
|
||||
</v-chart>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import moment from 'dayjs'
|
||||
|
||||
const sourceData = []
|
||||
const beginDay = new Date().getTime()
|
||||
|
||||
for (let i = 0; i < 10; i++) {
|
||||
sourceData.push({
|
||||
x: moment(new Date(beginDay + 1000 * 60 * 60 * 24 * i)).format('YYYY-MM-DD'),
|
||||
y: Math.round(Math.random() * 10)
|
||||
})
|
||||
}
|
||||
|
||||
const tooltip = [
|
||||
'x*y',
|
||||
(x, y) => ({
|
||||
name: x,
|
||||
value: y
|
||||
})
|
||||
]
|
||||
|
||||
const scale = [{
|
||||
dataKey: 'x',
|
||||
min: 2
|
||||
}, {
|
||||
dataKey: 'y',
|
||||
title: '时间',
|
||||
min: 1,
|
||||
max: 30
|
||||
}]
|
||||
|
||||
export default {
|
||||
name: 'MiniBar',
|
||||
props: {
|
||||
dataSource: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
width: {
|
||||
type: Number,
|
||||
default: null
|
||||
},
|
||||
height: {
|
||||
type: Number,
|
||||
default: 200
|
||||
}
|
||||
},
|
||||
created() {
|
||||
if (this.dataSource.length === 0) {
|
||||
this.data = sourceData
|
||||
} else {
|
||||
this.data = this.dataSource
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tooltip,
|
||||
data: [],
|
||||
scale
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "chart";
|
||||
</style>
|
||||
@ -1,75 +0,0 @@
|
||||
<template>
|
||||
<div class="chart-mini-progress">
|
||||
<div class="target" :style="{ left: target + '%'}">
|
||||
<span :style="{ backgroundColor: color }"/>
|
||||
<span :style="{ backgroundColor: color }"/>
|
||||
</div>
|
||||
<div class="progress-wrapper">
|
||||
<div class="progress" :style="{ backgroundColor: color, width: percentage + '%', height: height+'px' }"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'MiniProgress',
|
||||
props: {
|
||||
target: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
height: {
|
||||
type: Number,
|
||||
default: 10
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
default: '#13C2C2'
|
||||
},
|
||||
percentage: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.chart-mini-progress {
|
||||
padding: 5px 0;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
|
||||
.target {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
|
||||
span {
|
||||
border-radius: 100px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 4px;
|
||||
width: 2px;
|
||||
|
||||
&:last-child {
|
||||
top: auto;
|
||||
bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
.progress-wrapper {
|
||||
background-color: #f5f5f5;
|
||||
position: relative;
|
||||
|
||||
.progress {
|
||||
transition: all .4s cubic-bezier(.08, .82, .17, 1) 0s;
|
||||
border-radius: 1px 0 0 1px;
|
||||
background-color: #1890ff;
|
||||
width: 0;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -1,67 +0,0 @@
|
||||
<template>
|
||||
<v-chart :forceFit="true" :height="height" :data="data" :scale="scale">
|
||||
<v-tooltip :showTitle="false" dataKey="item*percent"/>
|
||||
<v-axis/>
|
||||
<v-legend dataKey="item"/>
|
||||
<v-pie position="percent" color="item" :v-style="pieStyle" :label="labelConfig"/>
|
||||
<v-coord type="theta"/>
|
||||
</v-chart>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const DataSet = require('@antv/data-set')
|
||||
|
||||
export default {
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
height: {
|
||||
type: Number,
|
||||
default: 254
|
||||
},
|
||||
dataSource: {
|
||||
type: Array,
|
||||
default: () => [
|
||||
{ item: '示例一', count: 40 },
|
||||
{ item: '示例二', count: 21 },
|
||||
{ item: '示例三', count: 17 },
|
||||
{ item: '示例四', count: 13 },
|
||||
{ item: '示例五', count: 9 }
|
||||
]
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
scale: [{
|
||||
dataKey: 'percent',
|
||||
min: 0,
|
||||
formatter: '.0%'
|
||||
}],
|
||||
pieStyle: {
|
||||
stroke: '#fff',
|
||||
lineWidth: 1
|
||||
},
|
||||
labelConfig: ['percent', {
|
||||
formatter: (val, item) => {
|
||||
return item.point.item + ': ' + val
|
||||
}
|
||||
}]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
data() {
|
||||
let dv = new DataSet.View().source(this.dataSource)
|
||||
// 计算数据百分比
|
||||
dv.transform({
|
||||
type: 'percent',
|
||||
field: 'count',
|
||||
dimension: 'item',
|
||||
as: 'percent'
|
||||
})
|
||||
return dv.rows
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -1,367 +0,0 @@
|
||||
# 报表组件文档
|
||||
|
||||
## 柱状图
|
||||
|
||||
##### 引用方式
|
||||
|
||||
```js
|
||||
import Bar from '@/components/chart/Bar'
|
||||
```
|
||||
|
||||
##### 参数列表
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|------------|--------|----|------------|
|
||||
| title | string | | 报表标题 |
|
||||
| dataSource | array | ✔️ | 报表数据源 |
|
||||
| height | number | | 报表高度,默认254 |
|
||||
|
||||
##### dataSource 示例
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"x": "1月",
|
||||
"y": 320
|
||||
},
|
||||
{
|
||||
"x": "2月",
|
||||
"y": 457
|
||||
},
|
||||
{
|
||||
"x": "3月",
|
||||
"y": 182
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
##### 代码示例
|
||||
|
||||
```html
|
||||
<template>
|
||||
<bar title="柱状图" :dataSource="dataSource" :height="420"/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Bar from '@/components/chart/Bar'
|
||||
|
||||
export default {
|
||||
name: 'ChartDemo',
|
||||
components: {
|
||||
Bar
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dataSource: [
|
||||
{
|
||||
"x": "1月",
|
||||
"y": 320
|
||||
},
|
||||
{
|
||||
"x": "2月",
|
||||
"y": 457
|
||||
},
|
||||
{
|
||||
"x": "3月",
|
||||
"y": 182
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
```
|
||||
|
||||
## 多列柱状图
|
||||
|
||||
##### 引用方式
|
||||
|
||||
```js
|
||||
import BarMultid from '@/components/chart/BarMultid'
|
||||
```
|
||||
|
||||
##### 参数列表
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|------------|--------|----|------------|
|
||||
| title | string | | 报表标题 |
|
||||
| fields | array | | 主列字段列表 |
|
||||
| dataSource | array | | 报表数据源 |
|
||||
| height | number | | 报表高度,默认254 |
|
||||
|
||||
##### fields 示例
|
||||
|
||||
```json
|
||||
["Jan.", "Feb.", "Mar.", "Apr.", "May", "Jun.", "Jul.", "Aug."]
|
||||
```
|
||||
|
||||
##### dataSource 示例
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"type": "Jeecg", // 列名
|
||||
"Jan.": 18.9,
|
||||
"Feb.": 28.8,
|
||||
"Mar.": 39.3,
|
||||
"Apr.": 81.4,
|
||||
"May": 47,
|
||||
"Jun.": 20.3,
|
||||
"Jul.": 24,
|
||||
"Aug.": 35.6
|
||||
},
|
||||
{
|
||||
"type": "Jeebt",
|
||||
"Jan.": 12.4,
|
||||
"Feb.": 23.2,
|
||||
"Mar.": 34.5,
|
||||
"Apr.": 99.7,
|
||||
"May": 52.6,
|
||||
"Jun.": 35.5,
|
||||
"Jul.": 37.4,
|
||||
"Aug.": 42.4
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## 迷你柱状图
|
||||
|
||||
不带标题和数据轴的柱状图
|
||||
|
||||
##### 引用方式
|
||||
|
||||
```js
|
||||
import MiniBar from '@/components/chart/MiniBar'
|
||||
```
|
||||
|
||||
##### 参数列表
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|------------|--------|----|---------------|
|
||||
| width | number | | 报表宽度度,默认自适应宽度 |
|
||||
| height | number | | 报表高度,默认200 |
|
||||
| dataSource | array | | 报表数据源 |
|
||||
|
||||
##### dataSource 示例
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"x": "1月",
|
||||
"y": 320
|
||||
},
|
||||
{
|
||||
"x": "2月",
|
||||
"y": 457
|
||||
},
|
||||
{
|
||||
"x": "3月",
|
||||
"y": 182
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## 面积图
|
||||
|
||||
##### 引用方式
|
||||
|
||||
```js
|
||||
import AreaChartTy from '@/components/chart/AreaChartTy'
|
||||
```
|
||||
|
||||
##### 参数列表
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|------------|--------|----|------------|
|
||||
| title | string | | 报表标题 |
|
||||
| dataSource | array | ✔️ | 报表数据源 |
|
||||
| height | number | | 报表高度,默认254 |
|
||||
| lineSize | number | | 线的粗细,默认2 |
|
||||
|
||||
##### dataSource 示例
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"x": "1月",
|
||||
"y": 320
|
||||
},
|
||||
{
|
||||
"x": "2月",
|
||||
"y": 457
|
||||
},
|
||||
{
|
||||
"x": "3月",
|
||||
"y": 182
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## 多行折线图
|
||||
|
||||
##### 引用方式
|
||||
|
||||
```js
|
||||
import LineChartMultid from '@/components/chart/LineChartMultid'
|
||||
```
|
||||
|
||||
##### 参数列表
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|------------|--------|----|------------|
|
||||
| title | string | | 报表标题 |
|
||||
| fields | array | | 主列字段列表 |
|
||||
| dataSource | array | | 报表数据源 |
|
||||
| height | number | | 报表高度,默认254 |
|
||||
|
||||
##### fields 示例
|
||||
|
||||
```json
|
||||
["jeecg", "jeebt"]
|
||||
```
|
||||
|
||||
##### dataSource 示例
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"type": "Jan", // 列名
|
||||
"jeecg": 7,
|
||||
"jeebt": 3.9
|
||||
},
|
||||
{ "type": "Feb", "jeecg": 6.9, "jeebt": 4.2 },
|
||||
{ "type": "Mar", "jeecg": 9.5, "jeebt": 5.7 },
|
||||
{ "type": "Apr", "jeecg": 14.5, "jeebt": 8.5 },
|
||||
{ "type": "May", "jeecg": 18.4, "jeebt": 11.9 },
|
||||
{ "type": "Jun", "jeecg": 21.5, "jeebt": 15.2 },
|
||||
{ "type": "Jul", "jeecg": 25.2, "jeebt": 17 },
|
||||
{ "type": "Aug", "jeecg": 26.5, "jeebt": 16.6 },
|
||||
{ "type": "Sep", "jeecg": 23.3, "jeebt": 14.2 },
|
||||
{ "type": "Oct", "jeecg": 18.3, "jeebt": 10.3 },
|
||||
{ "type": "Nov", "jeecg": 13.9, "jeebt": 6.6 },
|
||||
{ "type": "Dec", "jeecg": 9.6, "jeebt": 4.8 }
|
||||
]
|
||||
```
|
||||
|
||||
## 饼状图
|
||||
|
||||
##### 引用方式
|
||||
|
||||
```js
|
||||
import Pie from '@/components/chart/Pie'
|
||||
```
|
||||
|
||||
##### 参数列表
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|------------|--------|----|------------|
|
||||
| dataSource | array | | 报表数据源 |
|
||||
| height | number | | 报表高度,默认254 |
|
||||
|
||||
##### dataSource 示例
|
||||
|
||||
```json
|
||||
[
|
||||
// 所有的 percent 相加等于 100
|
||||
{ "item": "一月", "percent": 40 },
|
||||
{ "item": "二月", "percent": 21 },
|
||||
{ "item": "三月", "percent": 17 },
|
||||
{ "item": "四月", "percent": 13 },
|
||||
{ "item": "五月", "percent": 9 }
|
||||
]
|
||||
```
|
||||
|
||||
## 雷达图
|
||||
|
||||
##### 引用方式
|
||||
|
||||
```js
|
||||
import Radar from '@/components/chart/Radar'
|
||||
```
|
||||
|
||||
##### 参数列表
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|------------|--------|----|------------|
|
||||
| dataSource | array | | 报表数据源 |
|
||||
| height | number | | 报表高度,默认254 |
|
||||
|
||||
##### dataSource 示例
|
||||
|
||||
```json
|
||||
[
|
||||
// score 最小值为 0,最大值为 100
|
||||
{ "item": "一月", "score": 40 },
|
||||
{ "item": "二月", "score": 20 },
|
||||
{ "item": "三月", "score": 67 },
|
||||
{ "item": "四月", "score": 43 },
|
||||
{ "item": "五月", "score": 90 }
|
||||
]
|
||||
```
|
||||
|
||||
## 进度条
|
||||
|
||||
##### 引用方式
|
||||
|
||||
```js
|
||||
import MiniProgress from '@/components/chart/MiniProgress'
|
||||
```
|
||||
|
||||
##### 参数列表
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|------------|--------|----|-------------------|
|
||||
| percentage | number | | 当前进度百分比,默认0,最高100 |
|
||||
| target | number | | 目标值,默认10 |
|
||||
| height | number | | 进度条高度,默认10 |
|
||||
| color | string | | 进度条颜色,默认 #13C2C2 |
|
||||
|
||||
## 仪表盘
|
||||
|
||||
##### 引用方式
|
||||
|
||||
```js
|
||||
import DashChartDemo from '@/components/chart/DashChartDemo'
|
||||
```
|
||||
|
||||
##### 参数列表
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|--------|----|----------------|
|
||||
| title | string | | 报表标题 |
|
||||
| value | number | | 当前值,默认6.7,最大为9 |
|
||||
| height | number | | 报表高度,默认254 |
|
||||
|
||||
## 排名列表
|
||||
|
||||
##### 引用方式
|
||||
|
||||
```js
|
||||
import RankList from '@/components/chart/RankList'
|
||||
```
|
||||
|
||||
##### 参数列表
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|--------|----|--------------|
|
||||
| title | string | | 报表标题 |
|
||||
| list | array | | 排名列表数据 |
|
||||
| height | number | | 报表高度,默认自适应高度 |
|
||||
|
||||
##### list 示例
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"name": "北京朝阳 1 号店",
|
||||
"total": 1981
|
||||
},
|
||||
{ "name": "北京朝阳 2 号店", "total": 1359 },
|
||||
{ "name": "北京朝阳 3 号店", "total": 1354 },
|
||||
{ "name": "北京朝阳 4 号店", "total": 263 },
|
||||
{ "name": "北京朝阳 5 号店", "total": 446 },
|
||||
{ "name": "北京朝阳 6 号店", "total": 796 }
|
||||
]
|
||||
```
|
||||
@ -1,90 +0,0 @@
|
||||
<template>
|
||||
<v-chart :forceFit="true" :height="height" :data="data" :padding="[20, 20, 95, 20]" :scale="scale">
|
||||
<v-tooltip></v-tooltip>
|
||||
<v-axis :dataKey="axis1Opts.dataKey" :line="axis1Opts.line" :tickLine="axis1Opts.tickLine" :grid="axis1Opts.grid"/>
|
||||
<v-axis :dataKey="axis2Opts.dataKey" :line="axis2Opts.line" :tickLine="axis2Opts.tickLine" :grid="axis2Opts.grid"/>
|
||||
<v-legend dataKey="user" marker="circle" :offset="30"/>
|
||||
<v-coord type="polar" radius="0.8"/>
|
||||
<v-line position="item*score" color="user" :size="2"/>
|
||||
<v-point position="item*score" color="user" :size="4" shape="circle"/>
|
||||
</v-chart>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const axis1Opts = {
|
||||
dataKey: 'item',
|
||||
line: null,
|
||||
tickLine: null,
|
||||
grid: {
|
||||
lineStyle: {
|
||||
lineDash: null
|
||||
},
|
||||
hideFirstLine: false
|
||||
}
|
||||
}
|
||||
const axis2Opts = {
|
||||
dataKey: 'score',
|
||||
line: null,
|
||||
tickLine: null,
|
||||
grid: {
|
||||
type: 'polygon',
|
||||
lineStyle: {
|
||||
lineDash: null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const scale = [
|
||||
{
|
||||
dataKey: 'score',
|
||||
min: 0,
|
||||
max: 100
|
||||
}, {
|
||||
dataKey: 'user',
|
||||
alias: '类型'
|
||||
}
|
||||
]
|
||||
|
||||
const sourceData = [
|
||||
{ item: '示例一', score: 40 },
|
||||
{ item: '示例二', score: 20 },
|
||||
{ item: '示例三', score: 67 },
|
||||
{ item: '示例四', score: 43 },
|
||||
{ item: '示例五', score: 90 }
|
||||
]
|
||||
|
||||
export default {
|
||||
name: 'Radar',
|
||||
props: {
|
||||
height: {
|
||||
type: Number,
|
||||
default: 254
|
||||
},
|
||||
dataSource: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
axis1Opts,
|
||||
axis2Opts,
|
||||
scale,
|
||||
data: sourceData
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
dataSource(newVal) {
|
||||
if (newVal.length === 0) {
|
||||
this.data = sourceData
|
||||
} else {
|
||||
this.data = newVal
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@ -1,66 +0,0 @@
|
||||
<template>
|
||||
<div :style="{ padding: '0 0 32px 32px' }">
|
||||
<h4 :style="{ marginBottom: '20px' }">{{ title }}</h4>
|
||||
<v-chart
|
||||
:height="height"
|
||||
:data="data"
|
||||
:scale="scale"
|
||||
:forceFit="true"
|
||||
:padding="['auto', 'auto', '40', '50']">
|
||||
<v-tooltip/>
|
||||
<v-axis/>
|
||||
<v-bar position="x*y"/>
|
||||
</v-chart>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: 'Bar',
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
x: {
|
||||
type: String,
|
||||
default: 'x'
|
||||
},
|
||||
y: {
|
||||
type: String,
|
||||
default: 'y'
|
||||
},
|
||||
data: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
height: {
|
||||
type: Number,
|
||||
default: 254
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
computed: {
|
||||
scale() {
|
||||
return [
|
||||
{ dataKey: 'x', title: this.x, alias: this.x },
|
||||
{ dataKey: 'y', title: this.y, alias: this.y }
|
||||
]
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// this.getMonthBar()
|
||||
},
|
||||
methods: {
|
||||
// getMonthBar() {
|
||||
// this.$http.get('/analysis/month-bar')
|
||||
// .then(res => {
|
||||
// this.data = res.result
|
||||
// })
|
||||
// }
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -1,84 +0,0 @@
|
||||
<template>
|
||||
<div class="chart-trend">
|
||||
{{ term }}
|
||||
<span>{{ rate }}%</span>
|
||||
<span :class="['trend-icon', trend]"><a-icon :type="'caret-' + trend"/></span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "Trend",
|
||||
props: {
|
||||
// 同title
|
||||
term: {
|
||||
type: String,
|
||||
default: '',
|
||||
required: true
|
||||
},
|
||||
// 百分比
|
||||
percentage: {
|
||||
type: Number,
|
||||
default: null
|
||||
},
|
||||
type: {
|
||||
type: Boolean,
|
||||
default: null
|
||||
},
|
||||
target: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
value: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
fixed: {
|
||||
type: Number,
|
||||
default: 2
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
trend: this.type && 'up' || 'down',
|
||||
rate: this.percentage
|
||||
}
|
||||
},
|
||||
created () {
|
||||
let type = this.type === null ? this.value >= this.target : this.type
|
||||
this.trend = type ? 'up' : 'down';
|
||||
this.rate = (this.percentage === null ? Math.abs(this.value - this.target) * 100 / this.target : this.percentage).toFixed(this.fixed)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.chart-trend {
|
||||
display: inline-block;
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
|
||||
.trend-icon {
|
||||
font-size: 12px;
|
||||
|
||||
&.up, &.down {
|
||||
margin-left: 4px;
|
||||
position: relative;
|
||||
top: 1px;
|
||||
|
||||
i {
|
||||
font-size: 12px;
|
||||
transform: scale(.83);
|
||||
}
|
||||
}
|
||||
|
||||
&.up {
|
||||
color: #f5222d;
|
||||
}
|
||||
&.down {
|
||||
color: #52c41a;
|
||||
top: -1px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -1,13 +0,0 @@
|
||||
.antv-chart-mini {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
|
||||
.chart-wrapper {
|
||||
position: absolute;
|
||||
bottom: -28px;
|
||||
width: 100%;
|
||||
|
||||
/* margin: 0 -5px;
|
||||
overflow: hidden;*/
|
||||
}
|
||||
}
|
||||
@ -1,88 +0,0 @@
|
||||
<template>
|
||||
<a-radio-group v-if="tagType=='radio'" @change="handleInput" :value="value" :disabled="disabled">
|
||||
<a-radio v-for="(item, key) in dictOptions" :key="key" :value="item.value">{{ item.text }}</a-radio>
|
||||
</a-radio-group>
|
||||
|
||||
<a-select v-else-if="tagType=='select'" :placeholder="placeholder" :disabled="disabled" :value="value" @change="handleInput">
|
||||
<a-select-option value="">请选择</a-select-option>
|
||||
<a-select-option v-for="(item, key) in dictOptions" :key="key" :value="item.value">
|
||||
<span style="display: inline-block;width: 100%" :title=" item.text || item.label ">
|
||||
{{ item.text || item.label }}
|
||||
</span>
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {ajaxGetDictItems} from '@/api/api'
|
||||
|
||||
export default {
|
||||
name: "JDictSelectTag",
|
||||
props: {
|
||||
dictCode: String,
|
||||
placeholder: String,
|
||||
triggerChange: Boolean,
|
||||
disabled: Boolean,
|
||||
value: String,
|
||||
type: String
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dictOptions: [],
|
||||
tagType:""
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
dictCode:{
|
||||
immediate:true,
|
||||
handler() {
|
||||
this.initDictData()
|
||||
},
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// console.log(this.dictCode);
|
||||
if(!this.type || this.type==="list"){
|
||||
this.tagType = "select"
|
||||
}else{
|
||||
this.tagType = this.type
|
||||
}
|
||||
//获取字典数据
|
||||
// this.initDictData();
|
||||
},
|
||||
methods: {
|
||||
initDictData() {
|
||||
//根据字典Code, 初始化字典数组
|
||||
ajaxGetDictItems(this.dictCode, null).then((res) => {
|
||||
if (res.success) {
|
||||
// console.log(res.result);
|
||||
this.dictOptions = res.result;
|
||||
}
|
||||
})
|
||||
},
|
||||
handleInput(e) {
|
||||
let val;
|
||||
if(this.tagType=="radio"){
|
||||
val = e.target.value
|
||||
}else{
|
||||
val = e
|
||||
}
|
||||
console.log(val);
|
||||
if(this.triggerChange){
|
||||
this.$emit('change', val);
|
||||
}else{
|
||||
this.$emit('input', val);
|
||||
}
|
||||
},
|
||||
setCurrentDictOptions(dictOptions){
|
||||
this.dictOptions = dictOptions
|
||||
},
|
||||
getCurrentDictOptions(){
|
||||
return this.dictOptions
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
@ -1,87 +0,0 @@
|
||||
/**
|
||||
* 字典 util
|
||||
* author: scott
|
||||
* date: 20190109
|
||||
*/
|
||||
|
||||
import {ajaxGetDictItems} from '@/api/api'
|
||||
import {getAction} from '@/api/manage'
|
||||
|
||||
/**
|
||||
* 获取字典数组
|
||||
* @param dictCode 字典Code
|
||||
* @return List<Map>
|
||||
*/
|
||||
export async function initDictOptions(dictCode) {
|
||||
if (!dictCode) {
|
||||
return '字典Code不能为空!';
|
||||
}
|
||||
//获取字典数组
|
||||
let res = await ajaxGetDictItems(dictCode);
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字典值替换文本通用方法
|
||||
* @param dictOptions 字典数组
|
||||
* @param text 字典值
|
||||
* @return String
|
||||
*/
|
||||
export function filterDictText(dictOptions, text) {
|
||||
let re = "";
|
||||
dictOptions.forEach(function (option) {
|
||||
if (text === option.value) {
|
||||
re = option.text;
|
||||
}
|
||||
});
|
||||
return re;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字典值替换文本通用方法(多选)
|
||||
* @param dictOptions 字典数组
|
||||
* @param text 字典值
|
||||
* @return String
|
||||
*/
|
||||
export function filterMultiDictText(dictOptions, text) {
|
||||
if(!text || !dictOptions || dictOptions.length==0){
|
||||
return ""
|
||||
}
|
||||
let re = "";
|
||||
let arr = text.split(",")
|
||||
dictOptions.forEach(function (option) {
|
||||
for(let i=0;i<arr.length;i++){
|
||||
if (arr[i] === option.value) {
|
||||
re += option.text+",";
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
if(re==""){
|
||||
return "";
|
||||
}
|
||||
return re.substring(0,re.length-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 翻译字段值对应的文本
|
||||
* @param children
|
||||
* @returns string
|
||||
*/
|
||||
export async function ajaxFilterDictText(dictCode, key) {
|
||||
if (!dictCode) {
|
||||
return '字典Code不能为空!';
|
||||
}
|
||||
//console.log(`key : ${key}`);
|
||||
if (!key) {
|
||||
return '';
|
||||
}
|
||||
//通过请求读取字典文本
|
||||
let res = await getAction(`/sys/dict/getDictText/${dictCode}/${key}`);
|
||||
if (res.success) {
|
||||
// console.log('restult: '+ res.result);
|
||||
return res.result;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
@ -1,95 +0,0 @@
|
||||
<template>
|
||||
<a-checkbox-group v-if="tagType=='checkbox'" @change="onChange" :value="arrayValue" :disabled="disabled">
|
||||
<a-checkbox v-for="(item, key) in dictOptions" :key="key" :value="item.value">{{ item.text || item.label }}</a-checkbox>
|
||||
</a-checkbox-group>
|
||||
|
||||
<a-select
|
||||
v-else-if="tagType=='select'"
|
||||
:value="arrayValue"
|
||||
@change="onChange"
|
||||
:disabled="disabled"
|
||||
mode="multiple"
|
||||
:placeholder="placeholder"
|
||||
allowClear>
|
||||
<a-select-option
|
||||
v-for="(item,index) in dictOptions"
|
||||
:key="index"
|
||||
:value="item.value">
|
||||
<span style="display: inline-block;width: 100%" :title=" item.text || item.label ">
|
||||
{{ item.text || item.label }}
|
||||
</span>
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {ajaxGetDictItems} from '@/api/api'
|
||||
export default {
|
||||
name: 'JMultiSelectTag',
|
||||
props: {
|
||||
dictCode: String,
|
||||
placeholder: String,
|
||||
disabled: Boolean,
|
||||
value: String,
|
||||
type: String,
|
||||
options:Array
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dictOptions: [],
|
||||
tagType:"",
|
||||
arrayValue:!this.value?[]:this.value.split(",")
|
||||
}
|
||||
},
|
||||
created() {
|
||||
if(!this.type || this.type==="list_multi"){
|
||||
this.tagType = "select"
|
||||
}else{
|
||||
this.tagType = this.type
|
||||
}
|
||||
//获取字典数据
|
||||
this.initDictData();
|
||||
},
|
||||
watch:{
|
||||
options: function(val){
|
||||
this.setCurrentDictOptions(val);
|
||||
},
|
||||
value (val) {
|
||||
if(!val){
|
||||
this.arrayValue = []
|
||||
}else{
|
||||
this.arrayValue = this.value.split(",")
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
initDictData() {
|
||||
if(this.options && this.options.length>0){
|
||||
this.dictOptions = [...this.options]
|
||||
}else{
|
||||
//根据字典Code, 初始化字典数组
|
||||
ajaxGetDictItems(this.dictCode, null).then((res) => {
|
||||
if (res.success) {
|
||||
this.dictOptions = res.result;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
},
|
||||
onChange (selectedValue) {
|
||||
this.$emit('change', selectedValue.join(","));
|
||||
},
|
||||
setCurrentDictOptions(dictOptions){
|
||||
this.dictOptions = dictOptions
|
||||
},
|
||||
getCurrentDictOptions(){
|
||||
return this.dictOptions
|
||||
}
|
||||
},
|
||||
model: {
|
||||
prop: 'value',
|
||||
event: 'change'
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -1,176 +0,0 @@
|
||||
<template>
|
||||
|
||||
<a-select
|
||||
v-if="async"
|
||||
showSearch
|
||||
labelInValue
|
||||
@search="loadData"
|
||||
:placeholder="placeholder"
|
||||
v-model="selectedAsyncValue"
|
||||
style="width: 100%"
|
||||
:filterOption="false"
|
||||
@change="handleAsyncChange"
|
||||
allowClear
|
||||
:notFoundContent="loading ? undefined : null"
|
||||
>
|
||||
<a-spin v-if="loading" slot="notFoundContent" size="small"/>
|
||||
<a-select-option v-for="d in options" :key="d.value" :value="d.value">{{ d.text }}</a-select-option>
|
||||
</a-select>
|
||||
|
||||
<a-select
|
||||
v-else
|
||||
showSearch
|
||||
:placeholder="placeholder"
|
||||
optionFilterProp="children"
|
||||
style="width: 100%"
|
||||
@change="handleChange"
|
||||
:filterOption="filterOption"
|
||||
v-model="selectedValue"
|
||||
allowClear
|
||||
:notFoundContent="loading ? undefined : null">
|
||||
<a-spin v-if="loading" slot="notFoundContent" size="small"/>
|
||||
<a-select-option v-for="d in options" :key="d.value" :value="d.value">{{ d.text }}</a-select-option>
|
||||
</a-select>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ajaxGetDictItems } from '@/api/api'
|
||||
import debounce from 'lodash/debounce';
|
||||
import { getAction } from '../../api/manage'
|
||||
|
||||
export default {
|
||||
name: 'JSearchSelectTag',
|
||||
props:{
|
||||
disabled: Boolean,
|
||||
value: String,
|
||||
dict: String,
|
||||
dictOptions: Array,
|
||||
async: Boolean,
|
||||
placeholder:{
|
||||
type:String,
|
||||
default:"请选择",
|
||||
required:false
|
||||
}
|
||||
},
|
||||
data(){
|
||||
this.loadData = debounce(this.loadData, 800);//消抖
|
||||
this.lastLoad = 0;
|
||||
return {
|
||||
loading:false,
|
||||
selectedValue:[],
|
||||
selectedAsyncValue:[],
|
||||
options: [],
|
||||
}
|
||||
},
|
||||
created(){
|
||||
this.initDictData();
|
||||
},
|
||||
watch:{
|
||||
"value":{
|
||||
immediate:true,
|
||||
handler(val){
|
||||
if(!val){
|
||||
this.selectedValue=[]
|
||||
this.selectedAsyncValue=[]
|
||||
}else{
|
||||
this.initSelectValue()
|
||||
}
|
||||
}
|
||||
},
|
||||
"dict":{
|
||||
handler(){
|
||||
this.initDictData()
|
||||
}
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
initSelectValue(){
|
||||
if(this.async){
|
||||
if(!this.selectedAsyncValue || !this.selectedAsyncValue.key || this.selectedAsyncValue.key!=this.value){
|
||||
console.log("这才请求后台")
|
||||
getAction(`/sys/dict/loadDictItem/${this.dict}`,{key:this.value}).then(res=>{
|
||||
if(res.success){
|
||||
let obj = {
|
||||
key:this.value,
|
||||
label:res.result
|
||||
}
|
||||
this.selectedAsyncValue = {...obj}
|
||||
}
|
||||
})
|
||||
}
|
||||
}else{
|
||||
this.selectedValue = this.value
|
||||
}
|
||||
},
|
||||
loadData(value){
|
||||
console.log("数据加载",value)
|
||||
this.lastLoad +=1
|
||||
const currentLoad = this.lastLoad
|
||||
this.options = []
|
||||
this.loading=true
|
||||
// 字典code格式:table,text,code
|
||||
getAction(`/sys/dict/loadDict/${this.dict}`,{keyword:value}).then(res=>{
|
||||
this.loading=false
|
||||
if(res.success){
|
||||
if(currentLoad!=this.lastLoad){
|
||||
return
|
||||
}
|
||||
this.options = res.result
|
||||
console.log("我是第一个",res)
|
||||
}else{
|
||||
this.$message.warning(res.message)
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
},
|
||||
initDictData(){
|
||||
if(!this.async){
|
||||
//如果字典项集合有数据
|
||||
if(this.dictOptions && this.dictOptions.length>0){
|
||||
this.options = [...this.dictOptions]
|
||||
}else{
|
||||
//根据字典Code, 初始化字典数组
|
||||
ajaxGetDictItems(this.dict, null).then((res) => {
|
||||
if (res.success) {
|
||||
this.options = res.result;
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
filterOption(input, option) {
|
||||
return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
},
|
||||
handleChange (selectedValue) {
|
||||
console.log("selectedValue",selectedValue)
|
||||
this.selectedValue = selectedValue
|
||||
this.callback()
|
||||
},
|
||||
handleAsyncChange(selectedObj){
|
||||
this.selectedAsyncValue = selectedObj
|
||||
this.selectedValue = selectedObj.key
|
||||
this.callback()
|
||||
},
|
||||
callback(){
|
||||
this.$emit('change', this.selectedValue);
|
||||
},
|
||||
setCurrentDictOptions(dictOptions){
|
||||
this.options = dictOptions
|
||||
},
|
||||
getCurrentDictOptions(){
|
||||
return this.options
|
||||
}
|
||||
|
||||
},
|
||||
model: {
|
||||
prop: 'value',
|
||||
event: 'change'
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@ -1,181 +0,0 @@
|
||||
# JDictSelectTag 组件用法
|
||||
----
|
||||
- 从字典表获取数据,dictCode格式说明: 字典code
|
||||
```html
|
||||
<j-dict-select-tag v-model="queryParam.sex" placeholder="请输入用户性别"
|
||||
dictCode="sex"/>
|
||||
```
|
||||
|
||||
v-decorator用法:
|
||||
```html
|
||||
<j-dict-select-tag v-decorator="['sex', {}]" :triggerChange="true" placeholder="请输入用户性别"
|
||||
dictCode="sex"/>
|
||||
```
|
||||
|
||||
- 从数据库表获取字典数据,dictCode格式说明: 表名,文本字段,取值字段
|
||||
```html
|
||||
<j-dict-select-tag v-model="queryParam.username" placeholder="请选择用户名称"
|
||||
dictCode="sys_user,realname,id"/>
|
||||
```
|
||||
|
||||
|
||||
|
||||
# JDictSelectUtil.js 列表字典函数用法
|
||||
----
|
||||
|
||||
- 第一步: 引入依赖方法
|
||||
```html
|
||||
import {initDictOptions, filterDictText} from '@/components/dict/JDictSelectUtil'
|
||||
```
|
||||
|
||||
- 第二步: 在created()初始化方法执行字典配置方法
|
||||
```html
|
||||
//初始化字典配置
|
||||
this.initDictConfig();
|
||||
```
|
||||
|
||||
- 第三步: 实现initDictConfig方法,加载列表所需要的字典(列表上有多个字典项,就执行多次initDictOptions方法)
|
||||
|
||||
```html
|
||||
initDictConfig() {
|
||||
//初始化字典 - 性别
|
||||
initDictOptions('sex').then((res) => {
|
||||
if (res.success) {
|
||||
this.sexDictOptions = res.result;
|
||||
}
|
||||
});
|
||||
},
|
||||
```
|
||||
|
||||
- 第四步: 实现字段的customRender方法
|
||||
```html
|
||||
customRender: (text, record, index) => {
|
||||
//字典值替换通用方法
|
||||
return filterDictText(this.sexDictOptions, text);
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
# JMultiSelectTag 多选组件
|
||||
下拉/checkbox
|
||||
|
||||
## 参数配置
|
||||
| 参数 | 类型 | 必填 |说明|
|
||||
|--------------|---------|----|---------|
|
||||
| placeholder |string | | placeholder |
|
||||
| disabled |Boolean | | 是否禁用 |
|
||||
| type |string | | 多选类型 select/checkbox 默认是select |
|
||||
| dictCode |string | | 数据字典编码或者表名,显示字段名,存储字段名拼接而成的字符串,如果提供了options参数 则此参数可不填|
|
||||
| options |Array | | 多选项,如果dictCode参数未提供,可以设置此参数加载多选项 |
|
||||
|
||||
使用示例
|
||||
----
|
||||
```vue
|
||||
<template>
|
||||
<a-form>
|
||||
<a-form-item label="下拉多选" style="width: 300px">
|
||||
<j-multi-select-tag
|
||||
v-model="selectValue"
|
||||
:options="dictOptions"
|
||||
placeholder="请做出你的选择">
|
||||
</j-multi-select-tag>
|
||||
{{ selectValue }}
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="checkbox">
|
||||
<j-multi-select-tag
|
||||
v-model="checkboxValue"
|
||||
:options="dictOptions"
|
||||
type="checkbox">
|
||||
</j-multi-select-tag>
|
||||
{{ checkboxValue }}
|
||||
</a-form-item>
|
||||
</a-form >
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import JMultiSelectTag from '@/components/dict/JMultiSelectTag'
|
||||
export default {
|
||||
components: {JMultiSelectTag},
|
||||
data() {
|
||||
return {
|
||||
selectValue:"",
|
||||
checkboxValue:"",
|
||||
dictOptions:[{
|
||||
label:"选项一",
|
||||
value:"1"
|
||||
},{
|
||||
label:"选项二",
|
||||
value:"2"
|
||||
},{
|
||||
label:"选项三",
|
||||
value:"3"
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
# JSearchSelectTag 字典表的搜索组件
|
||||
下拉搜索组件,支持异步加载,异步加载用于大数据量的字典表
|
||||
|
||||
## 参数配置
|
||||
| 参数 | 类型 | 必填 |说明|
|
||||
|--------------|---------|----|---------|
|
||||
| placeholder |string | | placeholder |
|
||||
| disabled |Boolean | | 是否禁用 |
|
||||
| dict |string | | 表名,显示字段名,存储字段名拼接而成的字符串,如果提供了dictOptions参数 则此参数可不填|
|
||||
| dictOptions |Array | | 多选项,如果dict参数未提供,可以设置此参数加载多选项 |
|
||||
| async |Boolean | | 是否支持异步加载,设置成true,则通过输入的内容加载远程数据,否则在本地过滤数据,默认false|
|
||||
|
||||
使用示例
|
||||
----
|
||||
```vue
|
||||
<template>
|
||||
<a-form>
|
||||
<a-form-item label="下拉搜索" style="width: 300px">
|
||||
<j-search-select-tag
|
||||
placeholder="请做出你的选择"
|
||||
v-model="selectValue"
|
||||
:dictOptions="dictOptions">
|
||||
</j-search-select-tag>
|
||||
{{ selectValue }}
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="异步加载" style="width: 300px">
|
||||
<j-search-select-tag
|
||||
placeholder="请做出你的选择"
|
||||
v-model="asyncSelectValue"
|
||||
dict="sys_depart,depart_name,id"
|
||||
:async="true">
|
||||
</j-search-select-tag>
|
||||
{{ asyncSelectValue }}
|
||||
</a-form-item>
|
||||
</a-form >
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import JSearchSelectTag from '@/components/dict/JSearchSelectTag'
|
||||
export default {
|
||||
components: {JSearchSelectTag},
|
||||
data() {
|
||||
return {
|
||||
selectValue:"",
|
||||
asyncSelectValue:"",
|
||||
dictOptions:[{
|
||||
text:"选项一",
|
||||
value:"1"
|
||||
},{
|
||||
text:"选项二",
|
||||
value:"2"
|
||||
},{
|
||||
text:"选项三",
|
||||
value:"3"
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
@ -1,7 +0,0 @@
|
||||
import T from './JDictSelectTag.vue'
|
||||
const JDictSelectTag = {
|
||||
install: function (Vue) {
|
||||
Vue.component('JDictSelectTag',T);
|
||||
}
|
||||
}
|
||||
export default JDictSelectTag;
|
||||
@ -1,4 +0,0 @@
|
||||
@import "~ant-design-vue/lib/style/index";
|
||||
|
||||
// The prefix to use on all css classes from ant-pro.
|
||||
@ant-pro-prefix : ant-pro;
|
||||
@ -1,240 +0,0 @@
|
||||
<template>
|
||||
<a-tree-select
|
||||
allowClear
|
||||
labelInValue
|
||||
style="width: 100%"
|
||||
:disabled="disabled"
|
||||
:dropdownStyle="{ maxHeight: '400px', overflow: 'auto' }"
|
||||
:placeholder="placeholder"
|
||||
:loadData="asyncLoadTreeData"
|
||||
:value="treeValue"
|
||||
:treeData="treeData"
|
||||
:multiple="multiple"
|
||||
@change="onChange">
|
||||
</a-tree-select>
|
||||
</template>
|
||||
<script>
|
||||
|
||||
import { getAction } from '@/api/manage'
|
||||
|
||||
export default {
|
||||
name: 'JCategorySelect',
|
||||
props: {
|
||||
value:{
|
||||
type: String,
|
||||
required: false
|
||||
},
|
||||
placeholder:{
|
||||
type: String,
|
||||
default: '请选择',
|
||||
required: false
|
||||
},
|
||||
disabled:{
|
||||
type:Boolean,
|
||||
default:false,
|
||||
required:false
|
||||
},
|
||||
condition:{
|
||||
type:String,
|
||||
default:'',
|
||||
required:false
|
||||
},
|
||||
// 是否支持多选
|
||||
multiple: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
loadTriggleChange:{
|
||||
type: Boolean,
|
||||
default: false,
|
||||
required:false
|
||||
},
|
||||
pid:{
|
||||
type:String,
|
||||
default:'',
|
||||
required:false
|
||||
},
|
||||
pcode:{
|
||||
type:String,
|
||||
default:'',
|
||||
required:false
|
||||
},
|
||||
back:{
|
||||
type:String,
|
||||
default:'',
|
||||
required:false
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
treeValue:"",
|
||||
treeData:[],
|
||||
url:"/sys/category/loadTreeData",
|
||||
view:'/sys/category/loadDictItem/',
|
||||
tableName:"",
|
||||
text:"",
|
||||
code:"",
|
||||
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
value () {
|
||||
this.loadItemByCode()
|
||||
},
|
||||
pcode(){
|
||||
this.loadRoot();
|
||||
}
|
||||
},
|
||||
created(){
|
||||
this.validateProp().then(()=>{
|
||||
this.loadRoot()
|
||||
this.loadItemByCode()
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
/**加载一级节点 */
|
||||
loadRoot(){
|
||||
let param = {
|
||||
pid:this.pid,
|
||||
pcode:this.pcode,
|
||||
condition:this.condition
|
||||
}
|
||||
getAction(this.url,param).then(res=>{
|
||||
if(res.success && res.result){
|
||||
for(let i of res.result){
|
||||
i.value = i.key
|
||||
if(i.leaf==false){
|
||||
i.isLeaf=false
|
||||
}else if(i.leaf==true){
|
||||
i.isLeaf=true
|
||||
}
|
||||
}
|
||||
this.treeData = [...res.result]
|
||||
}else{
|
||||
console.log("树一级节点查询结果-else",res)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
/** 数据回显*/
|
||||
loadItemByCode(){
|
||||
if(!this.value || this.value=="0"){
|
||||
this.treeValue = ""
|
||||
}else{
|
||||
getAction(this.view,{ids:this.value}).then(res=>{
|
||||
console.log(124345)
|
||||
console.log(124345,res)
|
||||
if(res.success){
|
||||
let values = this.value.split(',')
|
||||
this.treeValue = res.result.map((item, index) => ({
|
||||
key: values[index],
|
||||
value: values[index],
|
||||
label: item
|
||||
}))
|
||||
this.onLoadTriggleChange(res.result[0]);
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
onLoadTriggleChange(text){
|
||||
//只有单选才会触发
|
||||
if(!this.multiple && this.loadTriggleChange){
|
||||
this.backValue(this.value,text)
|
||||
}
|
||||
},
|
||||
backValue(value,label){
|
||||
let obj = {}
|
||||
if(this.back){
|
||||
obj[this.back] = label
|
||||
}
|
||||
this.$emit('change', value, obj)
|
||||
},
|
||||
asyncLoadTreeData (treeNode) {
|
||||
return new Promise((resolve) => {
|
||||
if (treeNode.$vnode.children) {
|
||||
resolve()
|
||||
return
|
||||
}
|
||||
let pid = treeNode.$vnode.key
|
||||
let param = {
|
||||
pid:pid,
|
||||
condition:this.condition
|
||||
}
|
||||
getAction(this.url,param).then(res=>{
|
||||
if(res.success){
|
||||
for(let i of res.result){
|
||||
i.value = i.key
|
||||
if(i.leaf==false){
|
||||
i.isLeaf=false
|
||||
}else if(i.leaf==true){
|
||||
i.isLeaf=true
|
||||
}
|
||||
}
|
||||
this.addChildren(pid,res.result,this.treeData)
|
||||
this.treeData = [...this.treeData]
|
||||
}
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
},
|
||||
addChildren(pid,children,treeArray){
|
||||
if(treeArray && treeArray.length>0){
|
||||
for(let item of treeArray){
|
||||
if(item.key == pid){
|
||||
if(!children || children.length==0){
|
||||
item.isLeaf=true
|
||||
}else{
|
||||
item.children = children
|
||||
}
|
||||
break
|
||||
}else{
|
||||
this.addChildren(pid,children,item.children)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
onChange(value){
|
||||
if(!value){
|
||||
this.$emit('change', '');
|
||||
this.treeValue = ''
|
||||
} else if (value instanceof Array) {
|
||||
//this.$emit('change', value.map(item => item.value).join(','))
|
||||
//this.treeValue = value
|
||||
} else {
|
||||
this.backValue(value.value,value.label)
|
||||
this.treeValue = value
|
||||
}
|
||||
},
|
||||
getCurrTreeData(){
|
||||
return this.treeData
|
||||
},
|
||||
validateProp(){
|
||||
let mycondition = this.condition
|
||||
return new Promise((resolve,reject)=>{
|
||||
if(!mycondition){
|
||||
resolve();
|
||||
}else{
|
||||
try {
|
||||
let test=JSON.parse(mycondition);
|
||||
if(typeof test == 'object' && test){
|
||||
resolve()
|
||||
}else{
|
||||
this.$message.error("组件JTreeSelect-condition传值有误,需要一个json字符串!")
|
||||
reject()
|
||||
}
|
||||
} catch(e) {
|
||||
this.$message.error("组件JTreeSelect-condition传值有误,需要一个json字符串!")
|
||||
reject()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
//2.2新增 在组件内定义 指定父组件调用时候的传值属性和事件类型 这个牛逼
|
||||
model: {
|
||||
prop: 'value',
|
||||
event: 'change'
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -1,43 +0,0 @@
|
||||
<template>
|
||||
<a-checkbox-group :options="options" :value="checkboxArray" v-bind="$attrs" @change="onChange" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'JCheckbox',
|
||||
props: {
|
||||
value:{
|
||||
type: String,
|
||||
required: false
|
||||
},
|
||||
/*label value*/
|
||||
options:{
|
||||
type: Array,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
checkboxArray:!this.value?[]:this.value.split(",")
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
value (val) {
|
||||
if(!val){
|
||||
this.checkboxArray = []
|
||||
}else{
|
||||
this.checkboxArray = this.value.split(",")
|
||||
}
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
onChange (checkedValues) {
|
||||
this.$emit('change', checkedValues.join(","));
|
||||
},
|
||||
},
|
||||
model: {
|
||||
prop: 'value',
|
||||
event: 'change'
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -1,418 +0,0 @@
|
||||
<template>
|
||||
<div v-bind="fullScreenParentProps">
|
||||
<a-icon v-if="fullScreen" class="full-screen-icon" type="fullscreen" @click="()=>fullCoder=!fullCoder"/>
|
||||
|
||||
<div class="code-editor-cust full-screen-child">
|
||||
<textarea ref="textarea"></textarea>
|
||||
<span @click="nullTipClick" class="null-tip" :class="{'null-tip-hidden':hasCode}" :style="nullTipStyle">{{ placeholderShow }}</span>
|
||||
<template v-if="languageChange">
|
||||
<a-select v-model="mode" size="small" class="code-mode-select" @change="changeMode" placeholder="请选择主题">
|
||||
<a-select-option
|
||||
v-for="mode in modes"
|
||||
:key="mode.value"
|
||||
:value="mode.value">
|
||||
{{ mode.label }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</template>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script type="text/ecmascript-6">
|
||||
// 引入全局实例
|
||||
import _CodeMirror from 'codemirror'
|
||||
|
||||
// 核心样式
|
||||
import 'codemirror/lib/codemirror.css'
|
||||
// 引入主题后还需要在 options 中指定主题才会生效 darcula gruvbox-dark hopscotch monokai
|
||||
import 'codemirror/theme/panda-syntax.css'
|
||||
//提示css
|
||||
import "codemirror/addon/hint/show-hint.css";
|
||||
|
||||
// 需要引入具体的语法高亮库才会有对应的语法高亮效果
|
||||
// codemirror 官方其实支持通过 /addon/mode/loadmode.js 和 /mode/meta.js 来实现动态加载对应语法高亮库
|
||||
// 但 vue 貌似没有无法在实例初始化后再动态加载对应 JS ,所以此处才把对应的 JS 提前引入
|
||||
import 'codemirror/mode/javascript/javascript.js'
|
||||
import 'codemirror/mode/css/css.js'
|
||||
import 'codemirror/mode/xml/xml.js'
|
||||
import 'codemirror/mode/clike/clike.js'
|
||||
import 'codemirror/mode/markdown/markdown.js'
|
||||
import 'codemirror/mode/python/python.js'
|
||||
import 'codemirror/mode/r/r.js'
|
||||
import 'codemirror/mode/shell/shell.js'
|
||||
import 'codemirror/mode/sql/sql.js'
|
||||
import 'codemirror/mode/swift/swift.js'
|
||||
import 'codemirror/mode/vue/vue.js'
|
||||
|
||||
// 尝试获取全局实例
|
||||
const CodeMirror = window.CodeMirror || _CodeMirror
|
||||
|
||||
export default {
|
||||
name: 'JCodeEditor',
|
||||
props: {
|
||||
// 外部传入的内容,用于实现双向绑定
|
||||
value: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
// 外部传入的语法类型
|
||||
language: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
languageChange:{
|
||||
type: Boolean,
|
||||
default:false,
|
||||
required:false
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
// 显示行号
|
||||
lineNumbers: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// 是否显示全屏按钮
|
||||
fullScreen: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 全屏以后的z-index
|
||||
zIndex: {
|
||||
type: [Number, String],
|
||||
default: 999
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
// 内部真实的内容
|
||||
code: '',
|
||||
hasCode:false,
|
||||
// 默认的语法类型
|
||||
mode: 'javascript',
|
||||
// 编辑器实例
|
||||
coder: null,
|
||||
// 默认配置
|
||||
options: {
|
||||
// 缩进格式
|
||||
tabSize: 2,
|
||||
// 主题,对应主题库 JS 需要提前引入
|
||||
theme: 'panda-syntax',
|
||||
line: true,
|
||||
// extraKeys: {'Ctrl': 'autocomplete'},//自定义快捷键
|
||||
hintOptions: {
|
||||
tables: {
|
||||
users: ['name', 'score', 'birthDate'],
|
||||
countries: ['name', 'population', 'size']
|
||||
}
|
||||
},
|
||||
},
|
||||
// 支持切换的语法高亮类型,对应 JS 已经提前引入
|
||||
// 使用的是 MIME-TYPE ,不过作为前缀的 text/ 在后面指定时写死了
|
||||
modes: [{
|
||||
value: 'css',
|
||||
label: 'CSS'
|
||||
}, {
|
||||
value: 'javascript',
|
||||
label: 'Javascript'
|
||||
}, {
|
||||
value: 'html',
|
||||
label: 'XML/HTML'
|
||||
}, {
|
||||
value: 'x-java',
|
||||
label: 'Java'
|
||||
}, {
|
||||
value: 'x-objectivec',
|
||||
label: 'Objective-C'
|
||||
}, {
|
||||
value: 'x-python',
|
||||
label: 'Python'
|
||||
}, {
|
||||
value: 'x-rsrc',
|
||||
label: 'R'
|
||||
}, {
|
||||
value: 'x-sh',
|
||||
label: 'Shell'
|
||||
}, {
|
||||
value: 'x-sql',
|
||||
label: 'SQL'
|
||||
}, {
|
||||
value: 'x-swift',
|
||||
label: 'Swift'
|
||||
}, {
|
||||
value: 'x-vue',
|
||||
label: 'Vue'
|
||||
}, {
|
||||
value: 'markdown',
|
||||
label: 'Markdown'
|
||||
}],
|
||||
// code 编辑器 是否全屏
|
||||
fullCoder: false
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
// value: {
|
||||
// immediate: false,
|
||||
// handler(value) {
|
||||
// this._getCoder().then(() => {
|
||||
// this.coder.setValue(value)
|
||||
// })
|
||||
// }
|
||||
// },
|
||||
language: {
|
||||
immediate: true,
|
||||
handler(language) {
|
||||
this._getCoder().then(() => {
|
||||
// 尝试从父容器获取语法类型
|
||||
if (language) {
|
||||
// 获取具体的语法类型对象
|
||||
let modeObj = this._getLanguage(language)
|
||||
|
||||
// 判断父容器传入的语法是否被支持
|
||||
if (modeObj) {
|
||||
this.mode = modeObj.label
|
||||
this.coder.setOption('mode', `text/${modeObj.value}`)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
placeholderShow() {
|
||||
if (this.placeholder == null) {
|
||||
return `请在此输入${this.language}代码`
|
||||
} else {
|
||||
return this.placeholder
|
||||
}
|
||||
},
|
||||
nullTipStyle(){
|
||||
if (this.lineNumbers) {
|
||||
return { left: '36px' }
|
||||
} else {
|
||||
return { left: '12px' }
|
||||
}
|
||||
},
|
||||
// coder 配置
|
||||
coderOptions() {
|
||||
return {
|
||||
tabSize: this.options.tabSize,
|
||||
theme: this.options.theme,
|
||||
lineNumbers: this.lineNumbers,
|
||||
line: true,
|
||||
hintOptions: this.options.hintOptions
|
||||
}
|
||||
},
|
||||
fullScreenParentProps(){
|
||||
let props = {
|
||||
class: ['full-screen-parent', this.fullCoder ? 'full-screen' : ''],
|
||||
style: {}
|
||||
}
|
||||
if (this.fullCoder) {
|
||||
props.style['z-index'] = this.zIndex
|
||||
}
|
||||
return props
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
// 初始化
|
||||
this._initialize()
|
||||
},
|
||||
methods: {
|
||||
// 初始化
|
||||
_initialize () {
|
||||
// 初始化编辑器实例,传入需要被实例化的文本域对象和默认配置
|
||||
this.coder = CodeMirror.fromTextArea(this.$refs.textarea, this.coderOptions)
|
||||
// 编辑器赋值
|
||||
if(this.value||this.code){
|
||||
this.hasCode=true
|
||||
this.coder.setValue(this.value || this.code)
|
||||
}else{
|
||||
this.coder.setValue('')
|
||||
this.hasCode=false
|
||||
}
|
||||
// 支持双向绑定
|
||||
this.coder.on('change', (coder) => {
|
||||
this.code = coder.getValue()
|
||||
if(this.code){
|
||||
this.hasCode=true
|
||||
}else{
|
||||
this.hasCode=false
|
||||
}
|
||||
if (this.$emit) {
|
||||
this.$emit('input', this.code)
|
||||
}
|
||||
})
|
||||
this.coder.on('focus', () => {
|
||||
this.hasCode=true
|
||||
})
|
||||
this.coder.on('blur', () => {
|
||||
if(this.code){
|
||||
this.hasCode=true
|
||||
}else{
|
||||
this.hasCode=false
|
||||
}
|
||||
})
|
||||
|
||||
/* this.coder.on('cursorActivity',()=>{
|
||||
this.coder.showHint()
|
||||
})*/
|
||||
|
||||
},
|
||||
getCodeContent(){
|
||||
return this.code
|
||||
},
|
||||
setCodeContent(val){
|
||||
setTimeout(()=>{
|
||||
if(!val){
|
||||
this.coder.setValue('')
|
||||
}else{
|
||||
this.coder.setValue(val)
|
||||
}
|
||||
},300)
|
||||
},
|
||||
// 获取当前语法类型
|
||||
_getLanguage (language) {
|
||||
// 在支持的语法类型列表中寻找传入的语法类型
|
||||
return this.modes.find((mode) => {
|
||||
// 所有的值都忽略大小写,方便比较
|
||||
let currentLanguage = language.toLowerCase()
|
||||
let currentLabel = mode.label.toLowerCase()
|
||||
let currentValue = mode.value.toLowerCase()
|
||||
|
||||
// 由于真实值可能不规范,例如 java 的真实值是 x-java ,所以讲 value 和 label 同时和传入语法进行比较
|
||||
return currentLabel === currentLanguage || currentValue === currentLanguage
|
||||
})
|
||||
},
|
||||
_getCoder() {
|
||||
let _this = this
|
||||
return new Promise((resolve) => {
|
||||
(function get() {
|
||||
if (_this.coder) {
|
||||
resolve(_this.coder)
|
||||
} else {
|
||||
setTimeout(get, 10)
|
||||
}
|
||||
})()
|
||||
})
|
||||
},
|
||||
// 更改模式
|
||||
changeMode (val) {
|
||||
// 修改编辑器的语法配置
|
||||
this.coder.setOption('mode', `text/${val}`)
|
||||
|
||||
// 获取修改后的语法
|
||||
let label = this._getLanguage(val).label.toLowerCase()
|
||||
|
||||
// 允许父容器通过以下函数监听当前的语法值
|
||||
this.$emit('language-change', label)
|
||||
},
|
||||
nullTipClick(){
|
||||
this.coder.focus()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.code-editor-cust{
|
||||
flex-grow:1;
|
||||
display:flex;
|
||||
position:relative;
|
||||
height:100%;
|
||||
.CodeMirror{
|
||||
flex-grow:1;
|
||||
z-index:1;
|
||||
.CodeMirror-code{
|
||||
line-height:19px;
|
||||
}
|
||||
|
||||
}
|
||||
.code-mode-select{
|
||||
position:absolute;
|
||||
z-index:2;
|
||||
right:10px;
|
||||
top:10px;
|
||||
max-width:130px;
|
||||
}
|
||||
.CodeMirror{
|
||||
height: auto;
|
||||
min-height:100%;
|
||||
}
|
||||
.null-tip{
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
left: 36px;
|
||||
z-index: 10;
|
||||
color: #ffffffc9;
|
||||
line-height: initial;
|
||||
}
|
||||
.null-tip-hidden{
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* 全屏样式 */
|
||||
.full-screen-parent {
|
||||
position: relative;
|
||||
|
||||
.full-screen-icon {
|
||||
opacity: 0;
|
||||
color: black;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
line-height: 24px;
|
||||
background-color: white;
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
right: 2px;
|
||||
z-index: 9;
|
||||
cursor: pointer;
|
||||
transition: opacity 0.3s;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.full-screen-icon {
|
||||
opacity: 1;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(255, 255, 255, 0.88);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.full-screen {
|
||||
position: fixed;
|
||||
top: 10px;
|
||||
left: 10px;
|
||||
width: calc(100% - 20px);
|
||||
height: calc(100% - 20px);
|
||||
padding: 10px;
|
||||
background-color: #f5f5f5;
|
||||
|
||||
.full-screen-icon {
|
||||
top: 12px;
|
||||
right: 12px;
|
||||
}
|
||||
.full-screen-child {
|
||||
height: 100%;
|
||||
max-height: 100%;
|
||||
min-height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.full-screen-child {
|
||||
min-height: 120px;
|
||||
max-height: 320px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.CodeMirror-cursor{
|
||||
height:18.4px !important;
|
||||
}
|
||||
</style>
|
||||
@ -1,65 +0,0 @@
|
||||
<template>
|
||||
<div class="components-input-demo-presuffix">
|
||||
<a-input @click="openModal" placeholder="corn表达式" v-model="cron" @change="handleOK">
|
||||
<a-icon slot="prefix" type="schedule" title="corn控件"/>
|
||||
<a-icon v-if="cron" slot="suffix" type="close-circle" @click="handleEmpty" title="清空"/>
|
||||
</a-input>
|
||||
<JCronModal ref="innerVueCron" :data="cron" @ok="handleOK"></JCronModal>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import JCronModal from "./modal/JCronModal";
|
||||
export default {
|
||||
name: 'JCron',
|
||||
components: {
|
||||
JCronModal
|
||||
},
|
||||
props: {
|
||||
value: {
|
||||
required: false,
|
||||
type: String,
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
cron: this.value,
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
value(val){
|
||||
this.cron = val
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
openModal(){
|
||||
this.$refs.innerVueCron.show();
|
||||
},
|
||||
handleOK(val){
|
||||
this.cron = val;
|
||||
this.$emit("change", this.cron);
|
||||
//this.$emit("change", Object.assign({}, this.cron));
|
||||
},
|
||||
handleEmpty(){
|
||||
this.handleOK('')
|
||||
}
|
||||
},
|
||||
model: {
|
||||
prop: 'value',
|
||||
event: 'change'
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
.components-input-demo-presuffix .anticon-close-circle {
|
||||
cursor: pointer;
|
||||
color: #ccc;
|
||||
transition: color 0.3s;
|
||||
font-size: 12px;
|
||||
}
|
||||
.components-input-demo-presuffix .anticon-close-circle:hover {
|
||||
color: #f5222d;
|
||||
}
|
||||
.components-input-demo-presuffix .anticon-close-circle:active {
|
||||
color: #666;
|
||||
}
|
||||
</style>
|
||||
@ -1,85 +0,0 @@
|
||||
<template>
|
||||
<a-date-picker
|
||||
:disabled="disabled || readOnly"
|
||||
:placeholder="placeholder"
|
||||
@change="handleDateChange"
|
||||
:value="momVal"
|
||||
:showTime="showTime"
|
||||
:format="dateFormat"
|
||||
:getCalendarContainer="getCalendarContainer"
|
||||
/>
|
||||
</template>
|
||||
<script>
|
||||
import moment from 'moment'
|
||||
export default {
|
||||
name: 'JDate',
|
||||
props: {
|
||||
placeholder:{
|
||||
type: String,
|
||||
default: '',
|
||||
required: false
|
||||
},
|
||||
value:{
|
||||
type: String,
|
||||
required: false
|
||||
},
|
||||
dateFormat:{
|
||||
type: String,
|
||||
default: 'YYYY-MM-DD',
|
||||
required: false
|
||||
},
|
||||
//此属性可以被废弃了
|
||||
triggerChange:{
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
readOnly:{
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
disabled:{
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
showTime:{
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
getCalendarContainer: {
|
||||
type: Function,
|
||||
default: () => document.body
|
||||
}
|
||||
},
|
||||
data () {
|
||||
let dateStr = this.value;
|
||||
return {
|
||||
decorator:"",
|
||||
momVal:!dateStr?null:moment(dateStr,this.dateFormat)
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
value (val) {
|
||||
if(!val){
|
||||
this.momVal = null
|
||||
}else{
|
||||
this.momVal = moment(val,this.dateFormat)
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
moment,
|
||||
handleDateChange(mom,dateStr){
|
||||
this.$emit('change', dateStr);
|
||||
}
|
||||
},
|
||||
//2.2新增 在组件内定义 指定父组件调用时候的传值属性和事件类型 这个牛逼
|
||||
model: {
|
||||
prop: 'value',
|
||||
event: 'change'
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -1,101 +0,0 @@
|
||||
<template>
|
||||
<div class="tinymce-editor">
|
||||
<editor
|
||||
v-model="myValue"
|
||||
:init="init"
|
||||
:disabled="disabled"
|
||||
@onClick="onClick">
|
||||
</editor>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import tinymce from 'tinymce/tinymce'
|
||||
import Editor from '@tinymce/tinymce-vue'
|
||||
import 'tinymce/themes/silver/theme'
|
||||
import 'tinymce/plugins/image'
|
||||
import 'tinymce/plugins/media'
|
||||
import 'tinymce/plugins/table'
|
||||
import 'tinymce/plugins/lists'
|
||||
import 'tinymce/plugins/contextmenu'
|
||||
import 'tinymce/plugins/wordcount'
|
||||
import 'tinymce/plugins/colorpicker'
|
||||
import 'tinymce/plugins/textcolor'
|
||||
import 'tinymce/plugins/fullscreen'
|
||||
export default {
|
||||
components: {
|
||||
Editor
|
||||
},
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
required:false
|
||||
},
|
||||
triggerChange:{
|
||||
type: Boolean,
|
||||
default: false,
|
||||
required:false
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
plugins: {
|
||||
type: [String, Array],
|
||||
default: 'lists image media table textcolor wordcount contextmenu fullscreen'
|
||||
},
|
||||
toolbar: {
|
||||
type: [String, Array],
|
||||
default: 'undo redo | formatselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | lists image media table | removeformat | fullscreen'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
//初始化配置
|
||||
init: {
|
||||
language_url: '/tinymce/langs/zh_CN.js',
|
||||
language: 'zh_CN',
|
||||
skin_url: '/tinymce/skins/lightgray',
|
||||
height: 300,
|
||||
plugins: this.plugins,
|
||||
toolbar: this.toolbar,
|
||||
branding: false,
|
||||
menubar: false,
|
||||
images_upload_handler: (blobInfo, success) => {
|
||||
const img = 'data:image/jpeg;base64,' + blobInfo.base64()
|
||||
success(img)
|
||||
}
|
||||
},
|
||||
myValue: this.value
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
tinymce.init({})
|
||||
},
|
||||
methods: {
|
||||
|
||||
onClick(e) {
|
||||
this.$emit('onClick', e, tinymce)
|
||||
},
|
||||
//可以添加一些自己的自定义事件,如清空内容
|
||||
clear() {
|
||||
this.myValue = ''
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
value(newValue) {
|
||||
this.myValue = (newValue == null ? '' : newValue)
|
||||
},
|
||||
myValue(newValue) {
|
||||
if(this.triggerChange){
|
||||
this.$emit('change', newValue)
|
||||
}else{
|
||||
this.$emit('input', newValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
||||
@ -1,29 +0,0 @@
|
||||
<template>
|
||||
<a-tooltip placement="topLeft">
|
||||
<template slot="title">
|
||||
<span>{{value}}</span>
|
||||
</template>
|
||||
{{ value | ellipsis(length) }}
|
||||
</a-tooltip>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'JEllipsis',
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
required: false,
|
||||
},
|
||||
length: {
|
||||
type: Number,
|
||||
required: false,
|
||||
default: 25,
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@ -1,49 +0,0 @@
|
||||
<template>
|
||||
<div :class="disabled?'jeecg-form-container-disabled':''">
|
||||
<fieldset disabled>
|
||||
<slot name="detail"></slot>
|
||||
</fieldset>
|
||||
<slot name="edit"></slot>
|
||||
<fieldset disabled>
|
||||
<slot></slot>
|
||||
</fieldset>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/**
|
||||
* 使用方法
|
||||
* 在form下直接写这个组件就行了,
|
||||
*<a-form layout="inline" :form="form" >
|
||||
* <j-form-container :disabled="true">
|
||||
* <!-- 表单内容省略..... -->
|
||||
* </j-form-container>
|
||||
*</a-form>
|
||||
*/
|
||||
export default {
|
||||
name: 'JFormContainer',
|
||||
props:{
|
||||
disabled:{
|
||||
type:Boolean,
|
||||
default:false,
|
||||
required:false
|
||||
}
|
||||
},
|
||||
mounted(){
|
||||
console.log("我是表单禁用专用组件,但是我并不支持表单中iframe的内容禁用")
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.jeecg-form-container-disabled{
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.jeecg-form-container-disabled fieldset[disabled] {
|
||||
-ms-pointer-events: none;
|
||||
pointer-events: none;
|
||||
}
|
||||
.jeecg-form-container-disabled .ant-select{
|
||||
-ms-pointer-events: none;
|
||||
pointer-events: none;
|
||||
}
|
||||
</style>
|
||||
@ -1,203 +0,0 @@
|
||||
<template>
|
||||
<div class="gc-canvas" @click="reloadPic">
|
||||
<canvas id="gc-canvas" :width="contentWidth" :height="contentHeight"></canvas>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getAction } from '@/api/manage'
|
||||
|
||||
export default {
|
||||
name: 'JGraphicCode',
|
||||
props: {
|
||||
length:{
|
||||
type: Number,
|
||||
default: 4
|
||||
},
|
||||
fontSizeMin: {
|
||||
type: Number,
|
||||
default: 20
|
||||
},
|
||||
fontSizeMax: {
|
||||
type: Number,
|
||||
default: 45
|
||||
},
|
||||
backgroundColorMin: {
|
||||
type: Number,
|
||||
default: 180
|
||||
},
|
||||
backgroundColorMax: {
|
||||
type: Number,
|
||||
default: 240
|
||||
},
|
||||
colorMin: {
|
||||
type: Number,
|
||||
default: 50
|
||||
},
|
||||
colorMax: {
|
||||
type: Number,
|
||||
default: 160
|
||||
},
|
||||
lineColorMin: {
|
||||
type: Number,
|
||||
default: 40
|
||||
},
|
||||
lineColorMax: {
|
||||
type: Number,
|
||||
default: 180
|
||||
},
|
||||
dotColorMin: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
dotColorMax: {
|
||||
type: Number,
|
||||
default: 255
|
||||
},
|
||||
contentWidth: {
|
||||
type: Number,
|
||||
default:136
|
||||
},
|
||||
contentHeight: {
|
||||
type: Number,
|
||||
default: 38
|
||||
},
|
||||
remote:{
|
||||
type:Boolean,
|
||||
default:false,
|
||||
required:false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 生成一个随机数
|
||||
randomNum (min, max) {
|
||||
return Math.floor(Math.random() * (max - min) + min)
|
||||
},
|
||||
// 生成一个随机的颜色
|
||||
randomColor (min, max) {
|
||||
let r = this.randomNum(min, max)
|
||||
let g = this.randomNum(min, max)
|
||||
let b = this.randomNum(min, max)
|
||||
return 'rgb(' + r + ',' + g + ',' + b + ')'
|
||||
},
|
||||
drawPic () {
|
||||
this.randomCode().then(()=>{
|
||||
let canvas = document.getElementById('gc-canvas')
|
||||
let ctx = canvas.getContext('2d')
|
||||
ctx.textBaseline = 'bottom'
|
||||
// 绘制背景
|
||||
ctx.fillStyle = this.randomColor(this.backgroundColorMin, this.backgroundColorMax)
|
||||
ctx.fillRect(0, 0, this.contentWidth, this.contentHeight)
|
||||
// 绘制文字
|
||||
for (let i = 0; i < this.code.length; i++) {
|
||||
this.drawText(ctx, this.code[i], i)
|
||||
}
|
||||
this.drawLine(ctx)
|
||||
this.drawDot(ctx)
|
||||
this.$emit("success",this.code)
|
||||
})
|
||||
},
|
||||
drawText (ctx, txt, i) {
|
||||
ctx.fillStyle = this.randomColor(this.colorMin, this.colorMax)
|
||||
let fontSize = this.randomNum(this.fontSizeMin, this.fontSizeMax)
|
||||
ctx.font = fontSize + 'px SimHei'
|
||||
let padding = 10;
|
||||
let offset = (this.contentWidth-40)/(this.code.length-1)
|
||||
let x=padding;
|
||||
if(i>0){
|
||||
x = padding+(i*offset)
|
||||
}
|
||||
//let x = (i + 1) * (this.contentWidth / (this.code.length + 1))
|
||||
let y = this.randomNum(this.fontSizeMax, this.contentHeight - 5)
|
||||
if(fontSize>40){
|
||||
y=40
|
||||
}
|
||||
var deg = this.randomNum(-10,10)
|
||||
// 修改坐标原点和旋转角度
|
||||
ctx.translate(x, y)
|
||||
ctx.rotate(deg * Math.PI / 180)
|
||||
ctx.fillText(txt, 0, 0)
|
||||
// 恢复坐标原点和旋转角度
|
||||
ctx.rotate(-deg * Math.PI / 180)
|
||||
ctx.translate(-x, -y)
|
||||
},
|
||||
drawLine (ctx) {
|
||||
// 绘制干扰线
|
||||
for (let i = 0; i <1; i++) {
|
||||
ctx.strokeStyle = this.randomColor(this.lineColorMin, this.lineColorMax)
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(this.randomNum(0, this.contentWidth), this.randomNum(0, this.contentHeight))
|
||||
ctx.lineTo(this.randomNum(0, this.contentWidth), this.randomNum(0, this.contentHeight))
|
||||
ctx.stroke()
|
||||
}
|
||||
},
|
||||
drawDot (ctx) {
|
||||
// 绘制干扰点
|
||||
for (let i = 0; i < 100; i++) {
|
||||
ctx.fillStyle = this.randomColor(0, 255)
|
||||
ctx.beginPath()
|
||||
ctx.arc(this.randomNum(0, this.contentWidth), this.randomNum(0, this.contentHeight), 1, 0, 2 * Math.PI)
|
||||
ctx.fill()
|
||||
}
|
||||
},
|
||||
reloadPic(){
|
||||
this.drawPic()
|
||||
},
|
||||
randomCode(){
|
||||
return new Promise((resolve)=>{
|
||||
if(this.remote==true){
|
||||
getAction("/sys/getCheckCode").then(res=>{
|
||||
console.log("aaaaa",res)
|
||||
if(res.success){
|
||||
this.checkKey = res.result.key
|
||||
this.code = res.result.code
|
||||
resolve();
|
||||
}else{
|
||||
this.$message.error("生成验证码错误,请联系系统管理员")
|
||||
this.code = 'BUG'
|
||||
resolve();
|
||||
}
|
||||
}).catch(()=>{
|
||||
console.log("生成验证码连接服务器异常")
|
||||
this.code = 'BUG'
|
||||
resolve();
|
||||
})
|
||||
}else{
|
||||
this.randomLocalCode();
|
||||
resolve();
|
||||
}
|
||||
})
|
||||
},
|
||||
randomLocalCode(){
|
||||
let random = ''
|
||||
//去掉了I l i o O
|
||||
let str = "QWERTYUPLKJHGFDSAZXCVBNMqwertyupkjhgfdsazxcvbnm1234567890"
|
||||
for(let i = 0; i < this.length; i++) {
|
||||
let index = Math.floor(Math.random()*57);
|
||||
random += str[index];
|
||||
}
|
||||
this.code = random
|
||||
},
|
||||
getLoginParam(){
|
||||
return {
|
||||
checkCode:this.code,
|
||||
checkKey:this.checkKey
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.drawPic()
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
code:"",
|
||||
checkKey:""
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@ -1,110 +0,0 @@
|
||||
<template>
|
||||
<a-modal
|
||||
title="导入EXCEL"
|
||||
:width="600"
|
||||
:visible="visible"
|
||||
:confirmLoading="uploading"
|
||||
@cancel="handleClose">
|
||||
|
||||
<a-upload
|
||||
name="file"
|
||||
:multiple="true"
|
||||
accept=".xls,.xlsx"
|
||||
:fileList="fileList"
|
||||
:remove="handleRemove"
|
||||
:beforeUpload="beforeUpload">
|
||||
<a-button>
|
||||
<a-icon type="upload" />
|
||||
选择导入文件
|
||||
</a-button>
|
||||
</a-upload>
|
||||
|
||||
<template slot="footer">
|
||||
<a-button @click="handleClose">关闭</a-button>
|
||||
<a-button
|
||||
type="primary"
|
||||
@click="handleImport"
|
||||
:disabled="fileList.length === 0"
|
||||
:loading="uploading">
|
||||
{{ uploading ? '上传中...' : '开始上传' }}
|
||||
</a-button>
|
||||
</template>
|
||||
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { postAction } from '@/api/manage'
|
||||
export default {
|
||||
name: 'JImportModal',
|
||||
props:{
|
||||
url:{
|
||||
type: String,
|
||||
default: '',
|
||||
required: false
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
visible:false,
|
||||
uploading:false,
|
||||
fileList:[],
|
||||
uploadAction:''
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
url (val) {
|
||||
if(val){
|
||||
this.uploadAction = window._CONFIG['domianURL']+val
|
||||
}
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.uploadAction = window._CONFIG['domianURL']+this.url
|
||||
},
|
||||
|
||||
methods:{
|
||||
handleClose(){
|
||||
this.visible=false
|
||||
},
|
||||
show(){
|
||||
this.fileList = []
|
||||
this.uploading = false
|
||||
this.visible = true
|
||||
},
|
||||
handleRemove(file) {
|
||||
const index = this.fileList.indexOf(file);
|
||||
const newFileList = this.fileList.slice();
|
||||
newFileList.splice(index, 1);
|
||||
this.fileList = newFileList
|
||||
},
|
||||
beforeUpload(file) {
|
||||
this.fileList = [...this.fileList, file]
|
||||
return false;
|
||||
},
|
||||
handleImport() {
|
||||
const { fileList } = this;
|
||||
const formData = new FormData();
|
||||
fileList.forEach((file) => {
|
||||
formData.append('files[]', file);
|
||||
});
|
||||
this.uploading = true
|
||||
postAction(this.uploadAction, formData).then((res) => {
|
||||
this.uploading = false
|
||||
if(res.success){
|
||||
this.$message.success(res.message)
|
||||
this.visible=false
|
||||
this.$emit('ok')
|
||||
}else{
|
||||
this.$message.warning(res.message)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@ -1,95 +0,0 @@
|
||||
<template>
|
||||
<a-input :placeholder="placeholder" :value="inputVal" @input="backValue"></a-input>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const JINPUT_QUERY_LIKE = 'like';
|
||||
const JINPUT_QUERY_NE = 'ne';
|
||||
const JINPUT_QUERY_GE = 'ge'; //大于等于
|
||||
const JINPUT_QUERY_LE = 'le'; //小于等于
|
||||
|
||||
export default {
|
||||
name: 'JInput',
|
||||
props:{
|
||||
value:{
|
||||
type:String,
|
||||
required:false
|
||||
},
|
||||
type:{
|
||||
type:String,
|
||||
required:false,
|
||||
default:JINPUT_QUERY_LIKE
|
||||
},
|
||||
placeholder:{
|
||||
type:String,
|
||||
required:false,
|
||||
default:''
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
value:{
|
||||
immediate:true,
|
||||
handler:function(){
|
||||
this.initVal();
|
||||
}
|
||||
}
|
||||
},
|
||||
model: {
|
||||
prop: 'value',
|
||||
event: 'change'
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
inputVal:''
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
initVal(){
|
||||
if(!this.value){
|
||||
this.inputVal = ''
|
||||
}else{
|
||||
let text = this.value
|
||||
switch (this.type) {
|
||||
case JINPUT_QUERY_LIKE:
|
||||
text = text.substring(1,text.length-1);
|
||||
break;
|
||||
case JINPUT_QUERY_NE:
|
||||
text = text.substring(1);
|
||||
break;
|
||||
case JINPUT_QUERY_GE:
|
||||
text = text.substring(2);
|
||||
break;
|
||||
case JINPUT_QUERY_LE:
|
||||
text = text.substring(2);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
this.inputVal = text
|
||||
}
|
||||
},
|
||||
backValue(e){
|
||||
let text = e.target.value
|
||||
switch (this.type) {
|
||||
case JINPUT_QUERY_LIKE:
|
||||
text = "*"+text+"*";
|
||||
break;
|
||||
case JINPUT_QUERY_NE:
|
||||
text = "!"+text;
|
||||
break;
|
||||
case JINPUT_QUERY_GE:
|
||||
text = ">="+text;
|
||||
break;
|
||||
case JINPUT_QUERY_LE:
|
||||
text = "<="+text;
|
||||
break;
|
||||
default:
|
||||
}
|
||||
this.$emit("change",text)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@ -1,66 +0,0 @@
|
||||
<template>
|
||||
<a-select :value="arrayValue" @change="onChange" mode="multiple" :placeholder="placeholder">
|
||||
<a-select-option
|
||||
v-for="(item,index) in options"
|
||||
:key="index"
|
||||
:value="item.value">
|
||||
{{ item.text || item.label }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
//option {label:,value:}
|
||||
export default {
|
||||
name: 'JSelectMultiple',
|
||||
props: {
|
||||
placeholder:{
|
||||
type: String,
|
||||
default:'',
|
||||
required: false
|
||||
},
|
||||
value:{
|
||||
type: String,
|
||||
required: false
|
||||
},
|
||||
readOnly:{
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
options:{
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
triggerChange:{
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
arrayValue:!this.value?[]:this.value.split(",")
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
value (val) {
|
||||
if(!val){
|
||||
this.arrayValue = []
|
||||
}else{
|
||||
this.arrayValue = this.value.split(",")
|
||||
}
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
onChange (selectedValue) {
|
||||
if(this.triggerChange){
|
||||
this.$emit('change', selectedValue.join(","));
|
||||
}else{
|
||||
this.$emit('input', selectedValue.join(","));
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
}
|
||||
</script>
|
||||
@ -1,116 +0,0 @@
|
||||
<template>
|
||||
<div class="drag" ref="dragDiv">
|
||||
<div class="drag_bg"></div>
|
||||
<div class="drag_text">{{confirmWords}}</div>
|
||||
<div ref="moveDiv" @mousedown="mousedownFn($event)" :class="{'handler_ok_bg':confirmSuccess}" class="handler handler_bg" style="border: 0.5px solid #fff;height: 34px;position: absolute;top: 0px;left: 0px;"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name:"JSlider",
|
||||
data(){
|
||||
return {
|
||||
beginClientX:0, /*距离屏幕左端距离*/
|
||||
mouseMoveStata:false, /*触发拖动状态 判断*/
|
||||
maxwidth:'', /*拖动最大宽度,依据滑块宽度算出来的*/
|
||||
confirmWords:'拖动滑块验证', /*滑块文字*/
|
||||
confirmSuccess:false /*验证成功判断*/
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
isSuccess(){
|
||||
return this.confirmSuccess
|
||||
},
|
||||
mousedownFn:function (e) {
|
||||
if(!this.confirmSuccess){
|
||||
e.preventDefault && e.preventDefault(); //阻止文字选中等 浏览器默认事件
|
||||
this.mouseMoveStata = true;
|
||||
this.beginClientX = e.clientX;
|
||||
}
|
||||
}, //mousedoen 事件
|
||||
successFunction(){
|
||||
this.confirmSuccess = true
|
||||
this.confirmWords = '验证通过';
|
||||
if(window.addEventListener){
|
||||
document.getElementsByTagName('html')[0].removeEventListener('mousemove',this.mouseMoveFn);
|
||||
document.getElementsByTagName('html')[0].removeEventListener('mouseup',this.moseUpFn);
|
||||
}else {
|
||||
document.getElementsByTagName('html')[0].removeEventListener('mouseup',()=>{});
|
||||
}
|
||||
document.getElementsByClassName('drag_text')[0].style.color = '#fff'
|
||||
document.getElementsByClassName('handler')[0].style.left = this.maxwidth + 'px';
|
||||
document.getElementsByClassName('drag_bg')[0].style.width = this.maxwidth + 'px';
|
||||
|
||||
this.$emit("onSuccess",true)
|
||||
}, //验证成功函数
|
||||
mouseMoveFn(e){
|
||||
if(this.mouseMoveStata){
|
||||
let width = e.clientX - this.beginClientX;
|
||||
if(width>0 && width<=this.maxwidth){
|
||||
document.getElementsByClassName('handler')[0].style.left = width + 'px';
|
||||
document.getElementsByClassName('drag_bg')[0].style.width = width + 'px';
|
||||
}else if(width>this.maxwidth){
|
||||
this.successFunction();
|
||||
}
|
||||
}
|
||||
}, //mousemove事件
|
||||
moseUpFn(e){
|
||||
this.mouseMoveStata = false;
|
||||
var width = e.clientX - this.beginClientX;
|
||||
if(width<this.maxwidth){
|
||||
// ---- update-begin- author:sunjianlei --- date:20191009 --- for: 修复获取不到 handler 的时候报错 ----
|
||||
let handler = document.getElementsByClassName('handler')[0]
|
||||
if (handler) {
|
||||
handler.style.left = 0 + 'px'
|
||||
document.getElementsByClassName('drag_bg')[0].style.width = 0 + 'px'
|
||||
}
|
||||
// ---- update-end- author:sunjianlei --- date:20191009 --- for: 修复获取不到 handler 的时候报错 ----
|
||||
}
|
||||
} //mouseup事件
|
||||
},
|
||||
mounted(){
|
||||
this.maxwidth = this.$refs.dragDiv.clientWidth - this.$refs.moveDiv.clientWidth;
|
||||
document.getElementsByTagName('html')[0].addEventListener('mousemove',this.mouseMoveFn);
|
||||
document.getElementsByTagName('html')[0].addEventListener('mouseup',this.moseUpFn)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.drag{
|
||||
position: relative;
|
||||
background-color: #e8e8e8;
|
||||
width: 100%;
|
||||
height: 34px;
|
||||
line-height: 34px;
|
||||
text-align: center;
|
||||
}
|
||||
.handler{
|
||||
width: 40px;
|
||||
height: 32px;
|
||||
border: 1px solid #ccc;
|
||||
cursor: move;
|
||||
}
|
||||
.handler_bg{
|
||||
background: #fff url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA3hpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NTc3MiwgMjAxNC8wMS8xMy0xOTo0NDowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo0ZDhlNWY5My05NmI0LTRlNWQtOGFjYi03ZTY4OGYyMTU2ZTYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NTEyNTVEMURGMkVFMTFFNEI5NDBCMjQ2M0ExMDQ1OUYiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NTEyNTVEMUNGMkVFMTFFNEI5NDBCMjQ2M0ExMDQ1OUYiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTQgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo2MTc5NzNmZS02OTQxLTQyOTYtYTIwNi02NDI2YTNkOWU5YmUiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NGQ4ZTVmOTMtOTZiNC00ZTVkLThhY2ItN2U2ODhmMjE1NmU2Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+YiRG4AAAALFJREFUeNpi/P//PwMlgImBQkA9A+bOnfsIiBOxKcInh+yCaCDuByoswaIOpxwjciACFegBqZ1AvBSIS5OTk/8TkmNEjwWgQiUgtQuIjwAxUF3yX3xyGIEIFLwHpKyAWB+I1xGSwxULIGf9A7mQkBwTlhBXAFLHgPgqEAcTkmNCU6AL9d8WII4HOvk3ITkWJAXWUMlOoGQHmsE45ViQ2KuBuASoYC4Wf+OUYxz6mQkgwAAN9mIrUReCXgAAAABJRU5ErkJggg==") no-repeat center;
|
||||
}
|
||||
.handler_ok_bg{
|
||||
background: #fff url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA3hpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NTc3MiwgMjAxNC8wMS8xMy0xOTo0NDowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo0ZDhlNWY5My05NmI0LTRlNWQtOGFjYi03ZTY4OGYyMTU2ZTYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NDlBRDI3NjVGMkQ2MTFFNEI5NDBCMjQ2M0ExMDQ1OUYiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NDlBRDI3NjRGMkQ2MTFFNEI5NDBCMjQ2M0ExMDQ1OUYiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTQgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDphNWEzMWNhMC1hYmViLTQxNWEtYTEwZS04Y2U5NzRlN2Q4YTEiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NGQ4ZTVmOTMtOTZiNC00ZTVkLThhY2ItN2U2ODhmMjE1NmU2Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+k+sHwwAAASZJREFUeNpi/P//PwMyKD8uZw+kUoDYEYgloMIvgHg/EM/ptHx0EFk9I8wAoEZ+IDUPiIMY8IN1QJwENOgj3ACo5gNAbMBAHLgAxA4gQ5igAnNJ0MwAVTsX7IKyY7L2UNuJAf+AmAmJ78AEDTBiwGYg5gbifCSxFCZoaBMCy4A4GOjnH0D6DpK4IxNSVIHAfSDOAeLraJrjgJp/AwPbHMhejiQnwYRmUzNQ4VQgDQqXK0ia/0I17wJiPmQNTNBEAgMlQIWiQA2vgWw7QppBekGxsAjIiEUSBNnsBDWEAY9mEFgMMgBk00E0iZtA7AHEctDQ58MRuA6wlLgGFMoMpIG1QFeGwAIxGZo8GUhIysmwQGSAZgwHaEZhICIzOaBkJkqyM0CAAQDGx279Jf50AAAAAABJRU5ErkJggg==") no-repeat center;
|
||||
}
|
||||
.drag_bg{
|
||||
background-color: #7ac23c;
|
||||
height: 34px;
|
||||
width: 0px;
|
||||
}
|
||||
.drag_text{
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
width: 100%;text-align: center;
|
||||
-moz-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
user-select: none;
|
||||
-o-user-select:none;
|
||||
-ms-user-select:none;
|
||||
}
|
||||
</style>
|
||||
@ -1,353 +0,0 @@
|
||||
<template>
|
||||
<a-modal
|
||||
title="高级查询构造器"
|
||||
:width="1000"
|
||||
:visible="visible"
|
||||
@cancel="handleCancel"
|
||||
:mask="false"
|
||||
wrapClassName="ant-modal-cust-warp"
|
||||
class="j-super-query-modal"
|
||||
style="top:5%;max-height: 95%;">
|
||||
|
||||
<template slot="footer">
|
||||
<div style="float: left">
|
||||
<a-button :loading="loading" @click="handleReset">重置</a-button>
|
||||
<a-button :loading="loading" @click="handleSave">保存查询条件</a-button>
|
||||
</div>
|
||||
<a-button :loading="loading" @click="handleCancel">关闭</a-button>
|
||||
<a-button :loading="loading" type="primary" @click="handleOk">查询</a-button>
|
||||
</template>
|
||||
|
||||
<a-spin :spinning="loading">
|
||||
<a-row>
|
||||
<a-col :sm="24" :md="24-5">
|
||||
|
||||
<a-empty v-if="queryParamsModel.length === 0">
|
||||
<div slot="description">
|
||||
<span>没有任何查询条件</span>
|
||||
<a-divider type="vertical"/>
|
||||
<a @click="handleAdd">点击新增</a>
|
||||
</div>
|
||||
</a-empty>
|
||||
|
||||
<a-form v-else layout="inline">
|
||||
|
||||
<a-form-item label="过滤条件匹配" style="margin-bottom: 12px;">
|
||||
<a-select v-model="selectValue">
|
||||
<a-select-option value="and">AND(所有条件都要求匹配)</a-select-option>
|
||||
<a-select-option value="or">OR(条件中的任意一个匹配)</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
|
||||
<a-row type="flex" style="margin-bottom:10px" :gutter="16" v-for="(item, index) in queryParamsModel" :key="index">
|
||||
|
||||
<a-col :span="8">
|
||||
<a-select placeholder="选择查询字段" v-model="item.field" @select="(val,option)=>handleSelected(option,item)">
|
||||
<a-select-option v-for="(f,fIndex) in fieldList" :key=" 'field'+fIndex" :value="f.value" :data-idx="fIndex">{{ f.text }}</a-select-option>
|
||||
</a-select>
|
||||
</a-col>
|
||||
|
||||
<a-col :span="4">
|
||||
<a-select placeholder="匹配规则" v-model="item.rule">
|
||||
<a-select-option value="eq">等于</a-select-option>
|
||||
<a-select-option value="ne">不等于</a-select-option>
|
||||
<a-select-option value="gt">大于</a-select-option>
|
||||
<a-select-option value="ge">大于等于</a-select-option>
|
||||
<a-select-option value="lt">小于</a-select-option>
|
||||
<a-select-option value="le">小于等于</a-select-option>
|
||||
<a-select-option value="right_like">以..开始</a-select-option>
|
||||
<a-select-option value="left_like">以..结尾</a-select-option>
|
||||
<a-select-option value="like">包含</a-select-option>
|
||||
<a-select-option value="in">在...中</a-select-option>
|
||||
</a-select>
|
||||
</a-col>
|
||||
|
||||
<a-col :span="8">
|
||||
<j-dict-select-tag v-if="item.dictCode" v-model="item.val" :dictCode="item.dictCode" placeholder="请选择"/>
|
||||
<j-date v-else-if=" item.type=='date' " v-model="item.val" placeholder="请选择日期" style="width: 100%"></j-date>
|
||||
<j-date v-else-if=" item.type=='datetime' " v-model="item.val" placeholder="请选择时间" :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" style="width: 100%"></j-date>
|
||||
<a-input-number v-else-if=" item.type=='int'||item.type=='number' " style="width: 100%" placeholder="请输入数值" v-model="item.val"/>
|
||||
<a-input v-else v-model="item.val" placeholder="请输入值"/>
|
||||
</a-col>
|
||||
|
||||
<a-col :span="4">
|
||||
<a-button @click="handleAdd" icon="plus"></a-button>
|
||||
<a-button @click="handleDel( index )" icon="minus"></a-button>
|
||||
</a-col>
|
||||
|
||||
</a-row>
|
||||
|
||||
</a-form>
|
||||
</a-col>
|
||||
<a-col :sm="24" :md="5">
|
||||
<!-- 查询记录 -->
|
||||
|
||||
<a-card class="j-super-query-history-card" :bordered="true">
|
||||
<div slot="title">
|
||||
保存的查询
|
||||
</div>
|
||||
<a-tree
|
||||
class="j-super-query-history-tree"
|
||||
showIcon
|
||||
:treeData="treeData"
|
||||
@select="handleTreeSelect"
|
||||
@rightClick="handleTreeRightClick"
|
||||
>
|
||||
</a-tree>
|
||||
</a-card>
|
||||
|
||||
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
|
||||
</a-spin>
|
||||
|
||||
<a-modal title="请输入保存的名称" :visible="prompt.visible" @cancel="prompt.visible=false" @ok="handlePromptOk">
|
||||
<a-input v-model="prompt.value"></a-input>
|
||||
</a-modal>
|
||||
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as utils from '@/utils/util'
|
||||
import JDate from '@/components/jeecg/JDate.vue'
|
||||
|
||||
export default {
|
||||
name: 'JSuperQuery',
|
||||
components: { JDate },
|
||||
props: {
|
||||
/*
|
||||
fieldList: [{
|
||||
value:'',
|
||||
text:'',
|
||||
type:'',
|
||||
dictCode:'' // 只要 dictCode 有值,无论 type 是什么,都显示为字典下拉框
|
||||
}]
|
||||
type:date datetime int number string
|
||||
* */
|
||||
fieldList: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
/*
|
||||
* 这个回调函数接收一个数组参数 即查询条件
|
||||
* */
|
||||
callback: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'handleSuperQuery'
|
||||
},
|
||||
|
||||
// 当前是否在加载中
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
|
||||
// 保存查询条件的唯一 code,通过该 code 区分
|
||||
saveCode: {
|
||||
type: String,
|
||||
default: 'testSaveCode'
|
||||
}
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
prompt: {
|
||||
visible: false,
|
||||
value: ''
|
||||
},
|
||||
|
||||
visible: false,
|
||||
queryParamsModel: [{}],
|
||||
treeIcon: <a-icon type="file-text"/>,
|
||||
treeData: [],
|
||||
// 保存查询条件的前缀名
|
||||
saveCodeBefore: 'JSuperQuerySaved_',
|
||||
selectValue: 'and',
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
// 当 saveCode 变化时,重新查询已保存的条件
|
||||
saveCode: {
|
||||
immediate: true,
|
||||
handler(val) {
|
||||
let list = this.$ls.get(this.saveCodeBefore + val)
|
||||
if (list instanceof Array) {
|
||||
this.treeData = list.map(item => {
|
||||
item.icon = this.treeIcon
|
||||
return item
|
||||
})
|
||||
}
|
||||
console.log({ list })
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
show() {
|
||||
if (!this.queryParamsModel || this.queryParamsModel.length == 0) {
|
||||
this.queryParamsModel = [{}]
|
||||
}
|
||||
this.visible = true
|
||||
},
|
||||
handleOk() {
|
||||
console.log('---高级查询参数--->', this.queryParamsModel)
|
||||
if (!this.isNullArray(this.queryParamsModel)) {
|
||||
let event = {
|
||||
matchType: this.selectValue,
|
||||
params: this.removeEmptyObject(utils.cloneObject(this.queryParamsModel))
|
||||
}
|
||||
this.$emit(this.callback, event.params, event.matchType)
|
||||
} else {
|
||||
this.$emit(this.callback)
|
||||
}
|
||||
},
|
||||
handleCancel() {
|
||||
this.close()
|
||||
},
|
||||
close() {
|
||||
this.$emit('close')
|
||||
this.visible = false
|
||||
},
|
||||
handleAdd() {
|
||||
this.queryParamsModel.push({})
|
||||
},
|
||||
handleDel(index) {
|
||||
this.queryParamsModel.splice(index, 1)
|
||||
},
|
||||
handleSelected(option, item) {
|
||||
let index = option.data.attrs['data-idx']
|
||||
|
||||
let { type, dictCode } = this.fieldList[index]
|
||||
item['type'] = type
|
||||
item['dictCode'] = dictCode
|
||||
},
|
||||
handleReset() {
|
||||
this.queryParamsModel = [{}]
|
||||
this.$emit(this.callback)
|
||||
},
|
||||
handleSave() {
|
||||
let queryParams = this.removeEmptyObject(utils.cloneObject(this.queryParamsModel))
|
||||
if (this.isNullArray(queryParams)) {
|
||||
this.$message.warning('空条件不能保存')
|
||||
} else {
|
||||
this.prompt.value = ''
|
||||
this.prompt.visible = true
|
||||
}
|
||||
},
|
||||
handlePromptOk() {
|
||||
|
||||
let { value } = this.prompt
|
||||
// 判断有没有重名
|
||||
|
||||
let filterList = this.treeData.filter(i => i.title === value)
|
||||
if (filterList.length > 0) {
|
||||
this.$confirm({
|
||||
content: `${value} 已存在,是否覆盖?`,
|
||||
onOk: () => {
|
||||
this.prompt.visible = false
|
||||
filterList[0].records = this.removeEmptyObject(utils.cloneObject(this.queryParamsModel))
|
||||
this.saveToLocalStore()
|
||||
this.$message.success('保存成功')
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.prompt.visible = false
|
||||
this.treeData.push({
|
||||
title: value,
|
||||
icon: this.treeIcon,
|
||||
records: this.removeEmptyObject(utils.cloneObject(this.queryParamsModel))
|
||||
})
|
||||
this.saveToLocalStore()
|
||||
this.$message.success('保存成功')
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
handleTreeSelect(idx, event) {
|
||||
if (event.selectedNodes[0]) {
|
||||
this.queryParamsModel = utils.cloneObject(event.selectedNodes[0].data.props.records)
|
||||
}
|
||||
},
|
||||
handleTreeRightClick(args) {
|
||||
this.$confirm({
|
||||
content: '是否删除当前查询?',
|
||||
onOk: () => {
|
||||
let { node: { eventKey } } = args
|
||||
this.treeData.splice(Number.parseInt(eventKey.substring(2)), 1)
|
||||
this.saveToLocalStore()
|
||||
this.$message.success('删除成功')
|
||||
},
|
||||
})
|
||||
},
|
||||
|
||||
// 将查询保存到 LocalStore 里
|
||||
saveToLocalStore() {
|
||||
this.$ls.set(this.saveCodeBefore + this.saveCode, this.treeData.map(item => {
|
||||
return { title: item.title, records: item.records }
|
||||
}))
|
||||
},
|
||||
|
||||
isNullArray(array) {
|
||||
//判断是不是空数组对象
|
||||
if (!array || array.length === 0) {
|
||||
return true
|
||||
}
|
||||
if (array.length === 1) {
|
||||
let obj = array[0]
|
||||
if (!obj.field || !obj.val || !obj.rule) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
},
|
||||
// 去掉数组中的空对象
|
||||
removeEmptyObject(array) {
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
let item = array[i]
|
||||
if (item == null || Object.keys(item).length <= 0) {
|
||||
array.splice(i--, 1)
|
||||
}
|
||||
}
|
||||
return array
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
.j-super-query-modal {
|
||||
|
||||
/deep/ {
|
||||
}
|
||||
|
||||
.j-super-query-history-card /deep/ {
|
||||
.ant-card-body,
|
||||
.ant-card-head-title {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.ant-card-head {
|
||||
padding: 4px 8px;
|
||||
min-height: initial;
|
||||
}
|
||||
}
|
||||
|
||||
.j-super-query-history-tree /deep/ {
|
||||
.ant-tree-switcher {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ant-tree-node-content-wrapper {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
</style>
|
||||
@ -1,195 +0,0 @@
|
||||
<template>
|
||||
<a-tree-select
|
||||
allowClear
|
||||
labelInValue
|
||||
style="width: 100%"
|
||||
:disabled="disabled"
|
||||
:dropdownStyle="{ maxHeight: '400px', overflow: 'auto' }"
|
||||
:placeholder="placeholder"
|
||||
:loadData="asyncLoadTreeData"
|
||||
:value="treeValue"
|
||||
:treeData="treeData"
|
||||
@change="onChange"
|
||||
@search="onSearch">
|
||||
</a-tree-select>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getAction } from '@/api/manage'
|
||||
|
||||
export default {
|
||||
name: 'JTreeDict',
|
||||
data(){
|
||||
return {
|
||||
treeData:[],
|
||||
treeValue:"",
|
||||
url_root:"/sys/category/loadTreeRoot",
|
||||
url_children:"/sys/category/loadTreeChildren",
|
||||
url_view:'/sys/category/loadOne',
|
||||
}
|
||||
},
|
||||
props:{
|
||||
value:{
|
||||
type: String,
|
||||
required: false
|
||||
},
|
||||
placeholder:{
|
||||
type: String,
|
||||
default: '请选择',
|
||||
required: false
|
||||
},
|
||||
parentCode:{
|
||||
type: String,
|
||||
default: '',
|
||||
required: false
|
||||
},
|
||||
field:{
|
||||
type: String,
|
||||
default: 'id',
|
||||
required: false
|
||||
},
|
||||
root:{
|
||||
type:Object,
|
||||
required:false,
|
||||
default:()=>{
|
||||
return {
|
||||
pid:'0'
|
||||
}
|
||||
}
|
||||
},
|
||||
async:{
|
||||
type:Boolean,
|
||||
default:false,
|
||||
required:false
|
||||
},
|
||||
disabled:{
|
||||
type:Boolean,
|
||||
default:false,
|
||||
required:false
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
root:{
|
||||
handler(val){
|
||||
console.log("root-change",val)
|
||||
},
|
||||
deep:true
|
||||
},
|
||||
parentCode:{
|
||||
handler(){
|
||||
this.loadRoot()
|
||||
}
|
||||
},
|
||||
value:{
|
||||
handler(){
|
||||
this.loadViewInfo()
|
||||
}
|
||||
}
|
||||
},
|
||||
created(){
|
||||
this.loadRoot()
|
||||
this.loadViewInfo()
|
||||
},
|
||||
model: {
|
||||
prop: 'value',
|
||||
event: 'change'
|
||||
},
|
||||
methods:{
|
||||
loadViewInfo(){
|
||||
if(!this.value || this.value=="0"){
|
||||
this.treeValue = ""
|
||||
}else{
|
||||
let param = {
|
||||
field:this.field,
|
||||
val:this.value
|
||||
}
|
||||
getAction(this.url_view,param).then(res=>{
|
||||
if(res.success){
|
||||
this.treeValue = {
|
||||
value:this.value,
|
||||
label:res.result.name
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
loadRoot(){
|
||||
let param = {
|
||||
async:this.async,
|
||||
pcode:this.parentCode
|
||||
}
|
||||
getAction(this.url_root,param).then(res=>{
|
||||
if(res.success){
|
||||
this.handleTreeNodeValue(res.result)
|
||||
console.log("aaaa",res.result)
|
||||
this.treeData = [...res.result]
|
||||
}else{
|
||||
this.$message.error(res.message)
|
||||
}
|
||||
})
|
||||
},
|
||||
asyncLoadTreeData (treeNode) {
|
||||
return new Promise((resolve) => {
|
||||
if(!this.async){
|
||||
resolve()
|
||||
return
|
||||
}
|
||||
if (treeNode.$vnode.children) {
|
||||
resolve()
|
||||
return
|
||||
}
|
||||
let pid = treeNode.$vnode.key
|
||||
let param = {
|
||||
pid:pid
|
||||
}
|
||||
getAction(this.url_children,param).then(res=>{
|
||||
if(res.success){
|
||||
this.handleTreeNodeValue(res.result)
|
||||
this.addChildren(pid,res.result,this.treeData)
|
||||
this.treeData = [...this.treeData]
|
||||
}
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
},
|
||||
addChildren(pid,children,treeArray){
|
||||
if(treeArray && treeArray.length>0){
|
||||
for(let item of treeArray){
|
||||
if(item.key == pid){
|
||||
if(!children || children.length==0){
|
||||
item.leaf = true
|
||||
}else{
|
||||
item.children = children
|
||||
}
|
||||
break
|
||||
}else{
|
||||
this.addChildren(pid,children,item.children)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
handleTreeNodeValue(result){
|
||||
let storeField = this.field=='code'?'code':'key'
|
||||
for(let i of result){
|
||||
i.value = i[storeField]
|
||||
i.isLeaf = (!i.leaf)?false:true
|
||||
if(i.children && i.children.length>0){
|
||||
this.handleTreeNodeValue(i.children)
|
||||
}
|
||||
}
|
||||
},
|
||||
onChange(value){
|
||||
console.log(value)
|
||||
this.$emit('change', value.value);
|
||||
this.treeValue = value
|
||||
},
|
||||
onSearch(value){
|
||||
console.log(value)
|
||||
},
|
||||
getCurrTreeData(){
|
||||
return this.treeData
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
@ -1,259 +0,0 @@
|
||||
<template>
|
||||
<a-tree-select
|
||||
allowClear
|
||||
labelInValue
|
||||
style="width: 100%"
|
||||
:disabled="disabled"
|
||||
:dropdownStyle="{ maxHeight: '400px', overflow: 'auto' }"
|
||||
:placeholder="placeholder"
|
||||
:loadData="asyncLoadTreeData"
|
||||
:value="treeValue"
|
||||
:treeData="treeData"
|
||||
:multiple="multiple"
|
||||
@change="onChange"
|
||||
@search="onSearch">
|
||||
</a-tree-select>
|
||||
</template>
|
||||
<script>
|
||||
|
||||
/*
|
||||
* 异步树加载组件 通过传入表名 显示字段 存储字段 加载一个树控件
|
||||
* <j-tree-select dict="aa_tree_test,aad,id" pid-field="pid" ></j-tree-select>
|
||||
* */
|
||||
import { getAction } from '@/api/manage'
|
||||
|
||||
export default {
|
||||
name: 'JTreeSelect',
|
||||
props: {
|
||||
value:{
|
||||
type: String,
|
||||
required: false
|
||||
},
|
||||
placeholder:{
|
||||
type: String,
|
||||
default: '请选择',
|
||||
required: false
|
||||
},
|
||||
dict:{
|
||||
type: String,
|
||||
default: '',
|
||||
required: false
|
||||
},
|
||||
pidField:{
|
||||
type: String,
|
||||
default: 'pid',
|
||||
required: false
|
||||
},
|
||||
pidValue:{
|
||||
type: String,
|
||||
default: '',
|
||||
required: false
|
||||
},
|
||||
disabled:{
|
||||
type:Boolean,
|
||||
default:false,
|
||||
required:false
|
||||
},
|
||||
hasChildField:{
|
||||
type: String,
|
||||
default: '',
|
||||
required: false
|
||||
},
|
||||
condition:{
|
||||
type:String,
|
||||
default:'',
|
||||
required:false
|
||||
},
|
||||
// 是否支持多选
|
||||
multiple: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
loadTriggleChange:{
|
||||
type: Boolean,
|
||||
default: false,
|
||||
required:false
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
treeValue:"",
|
||||
treeData:[],
|
||||
url:"/sys/dict/loadTreeData",
|
||||
view:'/sys/dict/loadDictItem/',
|
||||
tableName:"",
|
||||
text:"",
|
||||
code:"",
|
||||
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
value () {
|
||||
this.loadItemByCode()
|
||||
},
|
||||
dict(){
|
||||
this.initDictInfo()
|
||||
this.loadRoot();
|
||||
}
|
||||
},
|
||||
created(){
|
||||
this.validateProp().then(()=>{
|
||||
this.initDictInfo()
|
||||
this.loadRoot()
|
||||
this.loadItemByCode()
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
loadItemByCode(){
|
||||
if(!this.value || this.value=="0"){
|
||||
this.treeValue = ""
|
||||
}else{
|
||||
getAction(`${this.view}${this.dict}`,{key:this.value}).then(res=>{
|
||||
if(res.success){
|
||||
let values = this.value.split(',')
|
||||
this.treeValue = res.result.map((item, index) => ({
|
||||
key: values[index],
|
||||
value: values[index],
|
||||
label: item
|
||||
}))
|
||||
this.onLoadTriggleChange(res.result[0]);
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
onLoadTriggleChange(text){
|
||||
//只有单选才会触发
|
||||
if(!this.multiple && this.loadTriggleChange){
|
||||
this.$emit('change', this.value,text)
|
||||
}
|
||||
},
|
||||
initDictInfo(){
|
||||
let arr = this.dict.split(",")
|
||||
this.tableName = arr[0]
|
||||
this.text = arr[1]
|
||||
this.code = arr[2]
|
||||
},
|
||||
asyncLoadTreeData (treeNode) {
|
||||
return new Promise((resolve) => {
|
||||
if (treeNode.$vnode.children) {
|
||||
resolve()
|
||||
return
|
||||
}
|
||||
let pid = treeNode.$vnode.key
|
||||
let param = {
|
||||
pid:pid,
|
||||
tableName:this.tableName,
|
||||
text:this.text,
|
||||
code:this.code,
|
||||
pidField:this.pidField,
|
||||
hasChildField:this.hasChildField,
|
||||
condition:this.condition
|
||||
}
|
||||
getAction(this.url,param).then(res=>{
|
||||
if(res.success){
|
||||
for(let i of res.result){
|
||||
i.value = i.key
|
||||
if(i.leaf==false){
|
||||
i.isLeaf=false
|
||||
}else if(i.leaf==true){
|
||||
i.isLeaf=true
|
||||
}
|
||||
}
|
||||
this.addChildren(pid,res.result,this.treeData)
|
||||
this.treeData = [...this.treeData]
|
||||
}
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
},
|
||||
addChildren(pid,children,treeArray){
|
||||
if(treeArray && treeArray.length>0){
|
||||
for(let item of treeArray){
|
||||
if(item.key == pid){
|
||||
if(!children || children.length==0){
|
||||
item.isLeaf=true
|
||||
}else{
|
||||
item.children = children
|
||||
}
|
||||
break
|
||||
}else{
|
||||
this.addChildren(pid,children,item.children)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
loadRoot(){
|
||||
let param = {
|
||||
pid:this.pidValue,
|
||||
tableName:this.tableName,
|
||||
text:this.text,
|
||||
code:this.code,
|
||||
pidField:this.pidField,
|
||||
hasChildField:this.hasChildField,
|
||||
condition:this.condition
|
||||
}
|
||||
getAction(this.url,param).then(res=>{
|
||||
if(res.success && res.result){
|
||||
for(let i of res.result){
|
||||
i.value = i.key
|
||||
if(i.leaf==false){
|
||||
i.isLeaf=false
|
||||
}else if(i.leaf==true){
|
||||
i.isLeaf=true
|
||||
}
|
||||
}
|
||||
this.treeData = [...res.result]
|
||||
}else{
|
||||
console.log("数根节点查询结果-else",res)
|
||||
}
|
||||
})
|
||||
},
|
||||
onChange(value){
|
||||
if(!value){
|
||||
this.$emit('change', '');
|
||||
this.treeValue = ''
|
||||
} else if (value instanceof Array) {
|
||||
this.$emit('change', value.map(item => item.value).join(','))
|
||||
this.treeValue = value
|
||||
} else {
|
||||
this.$emit('change', value.value,value.label)
|
||||
this.treeValue = value
|
||||
}
|
||||
|
||||
},
|
||||
onSearch(value){
|
||||
console.log(value)
|
||||
},
|
||||
getCurrTreeData(){
|
||||
return this.treeData
|
||||
},
|
||||
validateProp(){
|
||||
let mycondition = this.condition
|
||||
return new Promise((resolve,reject)=>{
|
||||
if(!mycondition){
|
||||
resolve();
|
||||
}else{
|
||||
try {
|
||||
let test=JSON.parse(mycondition);
|
||||
console.log("aaaaasdsdd",typeof test)
|
||||
if(typeof test == 'object' && test){
|
||||
resolve()
|
||||
}else{
|
||||
this.$message.error("组件JTreeSelect-condition传值有误,需要一个json字符串!")
|
||||
reject()
|
||||
}
|
||||
} catch(e) {
|
||||
this.$message.error("组件JTreeSelect-condition传值有误,需要一个json字符串!")
|
||||
reject()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
//2.2新增 在组件内定义 指定父组件调用时候的传值属性和事件类型 这个牛逼
|
||||
model: {
|
||||
prop: 'value',
|
||||
event: 'change'
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -1,180 +0,0 @@
|
||||
<template>
|
||||
<a-table
|
||||
:rowKey="rowKey"
|
||||
:columns="columns"
|
||||
:dataSource="dataSource"
|
||||
:expandedRowKeys="expandedRowKeys"
|
||||
v-bind="tableAttrs"
|
||||
v-on="$listeners"
|
||||
@expand="handleExpand"
|
||||
@expandedRowsChange="expandedRowKeys=$event">
|
||||
|
||||
<template v-for="(slotItem) of slots" :slot="slotItem" slot-scope="text, record, index">
|
||||
<slot :name="slotItem" v-bind="{text,record,index}"></slot>
|
||||
</template>
|
||||
|
||||
</a-table>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getAction } from '@/api/manage'
|
||||
|
||||
export default {
|
||||
name: 'JTreeTable',
|
||||
props: {
|
||||
rowKey: {
|
||||
type: String,
|
||||
default: 'id'
|
||||
},
|
||||
// 根据什么查询,如果传递 id 就根据 id 查询
|
||||
queryKey: {
|
||||
type: String,
|
||||
default: 'parentId'
|
||||
},
|
||||
queryParams: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
// 查询顶级时的值,如果顶级为0,则传0
|
||||
topValue: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
columns: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
url: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
childrenUrl: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
tableProps: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
/** 是否在创建组件的时候就查询数据 */
|
||||
immediateRequest: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
condition:{
|
||||
type:String,
|
||||
default:'',
|
||||
required:false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dataSource: [],
|
||||
expandedRowKeys: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
getChildrenUrl() {
|
||||
if (this.childrenUrl) {
|
||||
return this.childrenUrl
|
||||
} else {
|
||||
return this.url
|
||||
}
|
||||
},
|
||||
slots() {
|
||||
let slots = []
|
||||
for (let column of this.columns) {
|
||||
if (column.scopedSlots && column.scopedSlots.customRender) {
|
||||
slots.push(column.scopedSlots.customRender)
|
||||
}
|
||||
}
|
||||
return slots
|
||||
},
|
||||
tableAttrs() {
|
||||
return Object.assign(this.$attrs, this.tableProps)
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
queryParams: {
|
||||
deep: true,
|
||||
handler() {
|
||||
this.loadData()
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
if (this.immediateRequest) this.loadData()
|
||||
},
|
||||
methods: {
|
||||
|
||||
/** 加载数据*/
|
||||
loadData(id = this.topValue, first = true, url = this.url) {
|
||||
this.$emit('requestBefore', { first })
|
||||
|
||||
if (first) {
|
||||
this.expandedRowKeys = []
|
||||
}
|
||||
|
||||
let params = Object.assign({}, this.queryParams || {})
|
||||
params[this.queryKey] = id
|
||||
if(this.condition && this.condition.length>0){
|
||||
params['condition'] = this.condition
|
||||
}
|
||||
|
||||
return getAction(url, params).then(res => {
|
||||
let list = []
|
||||
if (res.result instanceof Array) {
|
||||
list = res.result
|
||||
} else if (res.result.records instanceof Array) {
|
||||
list = res.result.records
|
||||
} else {
|
||||
throw '返回数据类型不识别'
|
||||
}
|
||||
let dataSource = list.map(item => {
|
||||
// 判断是否标记了带有子级
|
||||
if (item.hasChildren === true) {
|
||||
// 查找第一个带有dataIndex的值的列
|
||||
let firstColumn
|
||||
for (let column of this.columns) {
|
||||
firstColumn = column.dataIndex
|
||||
if (firstColumn) break
|
||||
}
|
||||
// 定义默认展开时显示的loading子级,实际子级数据只在展开时加载
|
||||
let loadChild = { id: `${item.id}_loadChild`, [firstColumn]: 'loading...', isLoading: true }
|
||||
item.children = [loadChild]
|
||||
}
|
||||
return item
|
||||
})
|
||||
if (first) {
|
||||
this.dataSource = dataSource
|
||||
}
|
||||
this.$emit('requestSuccess', { first, dataSource, res })
|
||||
return Promise.resolve(dataSource)
|
||||
}).finally(() => this.$emit('requestFinally', { first }))
|
||||
},
|
||||
|
||||
/** 点击展开图标时触发 */
|
||||
handleExpand(expanded, record) {
|
||||
// 判断是否是展开状态
|
||||
if (expanded) {
|
||||
// 判断子级的首个项的标记是否是“正在加载中”,如果是就加载数据
|
||||
if (record.children[0].isLoading === true) {
|
||||
this.loadData(record.id, false, this.getChildrenUrl).then(dataSource => {
|
||||
// 处理好的数据可直接赋值给children
|
||||
if (dataSource.length === 0) {
|
||||
record.children = null
|
||||
} else {
|
||||
record.children = dataSource
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@ -1,185 +0,0 @@
|
||||
<template>
|
||||
<a-upload
|
||||
name="file"
|
||||
:multiple="true"
|
||||
:action="uploadAction"
|
||||
:headers="headers"
|
||||
:data="{'isup':1,'bizPath':bizPath}"
|
||||
:fileList="fileList"
|
||||
:beforeUpload="beforeUpload"
|
||||
@change="handleChange"
|
||||
:disabled="disabled">
|
||||
<a-button>
|
||||
<a-icon type="upload" />{{ text }}
|
||||
</a-button>
|
||||
</a-upload>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import Vue from 'vue'
|
||||
import { ACCESS_TOKEN } from "@/store/mutation-types"
|
||||
|
||||
const FILE_TYPE_ALL = "all"
|
||||
const FILE_TYPE_IMG = "image"
|
||||
const FILE_TYPE_TXT = "file"
|
||||
const uidGenerator=()=>{
|
||||
return '-'+parseInt(Math.random()*10000+1,10);
|
||||
}
|
||||
const getFileName=(path)=>{
|
||||
if(path.lastIndexOf("\\")>=0){
|
||||
let reg=new RegExp("\\\\","g");
|
||||
path = path.replace(reg,"/");
|
||||
}
|
||||
return path.substring(path.lastIndexOf("/")+1);
|
||||
}
|
||||
export default {
|
||||
name: 'JUpload',
|
||||
data(){
|
||||
return {
|
||||
uploadAction:window._CONFIG['domianURL']+"/sys/common/upload",
|
||||
urlDownload:window._CONFIG['domianURL'] + "/sys/common/download/",
|
||||
headers:{},
|
||||
fileList: []
|
||||
}
|
||||
},
|
||||
props:{
|
||||
text:{
|
||||
type:String,
|
||||
required:false,
|
||||
default:"点击上传"
|
||||
},
|
||||
fileType:{
|
||||
type:String,
|
||||
required:false,
|
||||
default:FILE_TYPE_ALL
|
||||
},
|
||||
/*这个属性用于控制文件上传的业务路径*/
|
||||
bizPath:{
|
||||
type:String,
|
||||
required:false,
|
||||
default:"temp"
|
||||
},
|
||||
value:{
|
||||
type:String,
|
||||
required:false
|
||||
},
|
||||
// update-begin- --- author:wangshuai ------ date:20190929 ---- for:Jupload组件增加是否能够点击
|
||||
disabled:{
|
||||
type:Boolean,
|
||||
required:false,
|
||||
default: false
|
||||
},
|
||||
// update-end- --- author:wangshuai ------ date:20190929 ---- for:Jupload组件增加是否能够点击
|
||||
//此属性被废弃了
|
||||
triggerChange:{
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
},
|
||||
watch:{
|
||||
value(val){
|
||||
this.initFileList(val)
|
||||
}
|
||||
},
|
||||
created(){
|
||||
const token = Vue.ls.get(ACCESS_TOKEN);
|
||||
this.headers = {"X-Access-Token":token}
|
||||
},
|
||||
|
||||
methods:{
|
||||
initFileList(paths){
|
||||
if(!paths || paths.length==0){
|
||||
//return [];
|
||||
// update-begin- --- author:os_chengtgen ------ date:20190729 ---- for:issues:326,Jupload组件初始化bug
|
||||
this.fileList = [];
|
||||
return;
|
||||
// update-end- --- author:os_chengtgen ------ date:20190729 ---- for:issues:326,Jupload组件初始化bug
|
||||
}
|
||||
let fileList = [];
|
||||
let arr = paths.split(",")
|
||||
for(var a=0;a<arr.length;a++){
|
||||
fileList.push({
|
||||
uid:uidGenerator(),
|
||||
name:getFileName(arr[a]),
|
||||
status: 'done',
|
||||
url: this.urlDownload+arr[a],
|
||||
response:{
|
||||
status:"history",
|
||||
message:arr[a]
|
||||
}
|
||||
})
|
||||
}
|
||||
this.fileList = fileList
|
||||
},
|
||||
handlePathChange(){
|
||||
let uploadFiles = this.fileList
|
||||
let path = ''
|
||||
if(!uploadFiles || uploadFiles.length==0){
|
||||
path = ''
|
||||
}
|
||||
let arr = [];
|
||||
|
||||
for(var a=0;a<uploadFiles.length;a++){
|
||||
arr.push(uploadFiles[a].response.message)
|
||||
}
|
||||
if(arr.length>0){
|
||||
path = arr.join(",")
|
||||
}
|
||||
this.$emit('change', path);
|
||||
},
|
||||
beforeUpload(file){
|
||||
var fileType = file.type;
|
||||
if(fileType===FILE_TYPE_IMG){
|
||||
if(fileType.indexOf('image')<0){
|
||||
this.$message.warning('请上传图片');
|
||||
return false;
|
||||
}
|
||||
}else if(fileType===FILE_TYPE_TXT){
|
||||
if(fileType.indexOf('image')>=0){
|
||||
this.$message.warning('请上传文件');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//TODO 扩展功能验证文件大小
|
||||
return true
|
||||
},
|
||||
handleChange(info) {
|
||||
console.log("--文件列表改变--")
|
||||
let fileList = info.fileList
|
||||
if(info.file.status==='done'){
|
||||
if(info.file.response.success){
|
||||
fileList = fileList.map((file) => {
|
||||
if (file.response) {
|
||||
file.url = this.urlDownload+file.response.message;
|
||||
}
|
||||
return file;
|
||||
});
|
||||
}
|
||||
this.$message.success(`${info.file.name} 上传成功!`);
|
||||
}else if (info.file.status === 'error') {
|
||||
this.$message.error(`${info.file.name} 上传失败.`);
|
||||
}else if(info.file.status === 'removed'){
|
||||
this.handleDelete(info.file)
|
||||
}
|
||||
this.fileList = fileList
|
||||
if(info.file.status==='done' || info.file.status === 'removed'){
|
||||
this.handlePathChange()
|
||||
}
|
||||
},
|
||||
handleDelete(file){
|
||||
//如有需要新增 删除逻辑
|
||||
console.log(file)
|
||||
},
|
||||
},
|
||||
model: {
|
||||
prop: 'value',
|
||||
event: 'change'
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@ -1,512 +0,0 @@
|
||||
# JDate 日期组件 使用文档
|
||||
|
||||
###### 说明: antd-vue日期组件需要用moment中转一下,用起来不是很方便,特二次封装,使用时只需要传字符串即可
|
||||
## 参数配置
|
||||
| 参数 | 类型 | 必填 |说明|
|
||||
|--------------|---------|----|---------|
|
||||
| placeholder |string | | placeholder |
|
||||
| readOnly | boolean | | true/false 默认false |
|
||||
| value | string | | 绑定v-model或是v-decorator后不需要设置 |
|
||||
| showTime | boolean | | 是否展示时间true/false 默认false |
|
||||
| dateFormat | string | |日期格式 默认'YYYY-MM-DD' 若showTime设置为true则需要将其设置成对应的时间格式(如:YYYY-MM-DD HH:mm:ss) |
|
||||
| triggerChange | string | |触发组件值改变的事件是否是change,当使用v-decorator时且没有设置decorator的option.trigger为input需要设置该值为true |
|
||||
使用示例
|
||||
----
|
||||
1.组件带有v-model的使用方法
|
||||
```vue
|
||||
<j-date v-model="dateStr"></j-date>
|
||||
```
|
||||
|
||||
2.组件带有v-decorator的使用方法
|
||||
a).设置trigger-change属性为true
|
||||
```vue
|
||||
<j-date :trigger-change="true" v-decorator="['dateStr',{}]"></j-date>
|
||||
```
|
||||
|
||||
b).设置decorator的option.trigger为input
|
||||
```vue
|
||||
<j-date v-decorator="['dateStr',{trigger:'input'}]"></j-date>
|
||||
```
|
||||
|
||||
3.其他使用
|
||||
添加style
|
||||
```vue
|
||||
<j-date v-model="dateStr" style="width:100%"></j-date>
|
||||
```
|
||||
添加placeholder
|
||||
```vue
|
||||
<j-date v-model="dateStr" placeholder="请输入dateStr"></j-date>
|
||||
```
|
||||
添加readOnly
|
||||
```vue
|
||||
<j-date v-model="dateStr" :read-only="true"></j-date>
|
||||
```
|
||||
|
||||
备注:
|
||||
script内需引入jdate
|
||||
```vue
|
||||
<script>
|
||||
import JDate from '@/components/jeecg/JDate'
|
||||
export default {
|
||||
name: "demo",
|
||||
components: {
|
||||
JDate
|
||||
}
|
||||
//...
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
# JSuperQuery 高级查询 使用文档
|
||||
## 参数配置
|
||||
| 参数 | 类型 | 必填 | 说明 |
|
||||
|--------------|---------|----|----------------------|
|
||||
| fieldList | array |✔| 需要查询的列集合示例如下,type类型有:date/datetime/string/int/number |
|
||||
| callback | array | | 回调函数名称(非必须)默认handleSuperQuery |
|
||||
|
||||
fieldList结构示例:
|
||||
```vue
|
||||
const superQueryFieldList=[{
|
||||
type:"date",
|
||||
value:"birthday",
|
||||
text:"生日"
|
||||
},{
|
||||
type:"string",
|
||||
value:"name",
|
||||
text:"用户名"
|
||||
},{
|
||||
type:"int",
|
||||
value:"age",
|
||||
text:"年龄"
|
||||
}]
|
||||
```
|
||||
页面代码概述:
|
||||
----
|
||||
1.import之后再components之内声明
|
||||
```vue
|
||||
import JSuperQuery from '@/components/jeecg/JSuperQuery.vue';
|
||||
export default {
|
||||
name: "JeecgDemoList",
|
||||
components: {
|
||||
JSuperQuery
|
||||
},
|
||||
|
||||
```
|
||||
2.页面引用
|
||||
```vue
|
||||
<!-- 高级查询区域 -->
|
||||
<j-super-query :fieldList="fieldList" ref="superQueryModal" @handleSuperQuery="handleSuperQuery"></j-super-query>
|
||||
```
|
||||
3.list页面data中需要定义三个属性:
|
||||
```vue
|
||||
fieldList:superQueryFieldList,
|
||||
superQueryFlag:false,
|
||||
superQueryParams:""
|
||||
```
|
||||
4.list页面声明回调事件handleSuperQuery(与组件的callback对应即可)
|
||||
```vue
|
||||
//高级查询方法
|
||||
handleSuperQuery(arg) {
|
||||
if(!arg){
|
||||
this.superQueryParams=''
|
||||
this.superQueryFlag = false
|
||||
}else{
|
||||
this.superQueryFlag = true
|
||||
this.superQueryParams=JSON.stringify(arg)
|
||||
}
|
||||
this.loadData()
|
||||
},
|
||||
```
|
||||
5.改造list页面方法
|
||||
```vue
|
||||
// 获取查询条件
|
||||
getQueryParams() {
|
||||
let sqp = {}
|
||||
if(this.superQueryParams){
|
||||
sqp['superQueryParams']=encodeURI(this.superQueryParams)
|
||||
}
|
||||
var param = Object.assign(sqp, this.queryParam, this.isorter);
|
||||
param.field = this.getQueryField();
|
||||
param.pageNo = this.ipagination.current;
|
||||
param.pageSize = this.ipagination.pageSize;
|
||||
return filterObj(param);
|
||||
},
|
||||
```
|
||||
6.打开弹框调用show方法:
|
||||
```vue
|
||||
this.$refs.superQueryModal.show();
|
||||
```
|
||||
|
||||
# JEllipsis 字符串超长截取省略号显示
|
||||
|
||||
###### 说明: 遇到超长文本展示,通过此标签可以截取省略号显示,鼠标放置会提示全文本
|
||||
## 参数配置
|
||||
| 参数 | 类型 | 必填 | 说明 |
|
||||
|--------|---------|----|----------------|
|
||||
| value |string | 必填 | 字符串文本|
|
||||
| length | number | 非必填 | 默认25 |
|
||||
使用示例
|
||||
----
|
||||
1.组件带有v-model的使用方法
|
||||
```vue
|
||||
<j-ellipsis :value="text"/>
|
||||
|
||||
|
||||
# Modal弹框实现最大化功能
|
||||
|
||||
1.定义modal的宽度:
|
||||
```vue
|
||||
<a-modal
|
||||
:width="modalWidth"
|
||||
|
||||
|
||||
/>
|
||||
```
|
||||
2.自定义modal的title,居右显示切换图标
|
||||
```vue
|
||||
<template slot="title">
|
||||
<div style="width: 100%;">
|
||||
<span>{{ title }}</span>
|
||||
<span style="display:inline-block;width:calc(100% - 51px);padding-right:10px;text-align: right">
|
||||
<a-button @click="toggleScreen" icon="appstore" style="height:20px;width:20px;border:0px"></a-button>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
3.定义toggleScreen事件,用于切换modal宽度
|
||||
```vue
|
||||
toggleScreen(){
|
||||
if(this.modaltoggleFlag){
|
||||
this.modalWidth = window.innerWidth;
|
||||
}else{
|
||||
this.modalWidth = 800;
|
||||
}
|
||||
this.modaltoggleFlag = !this.modaltoggleFlag;
|
||||
},
|
||||
```
|
||||
4.data中声明上述用到的属性
|
||||
```vue
|
||||
data () {
|
||||
return {
|
||||
modalWidth:800,
|
||||
modaltoggleFlag:true,
|
||||
```
|
||||
|
||||
# <a-select/> 下拉选项滚动错位的解决方法
|
||||
|
||||
## 问题描述
|
||||
|
||||
当使用了 `a-modal` 或其他带有滚动条的组件时,使用`a-select`组件并打开下拉框时滚动滚动条,就会导致错位的问题产生。
|
||||
|
||||
## 解决方法
|
||||
|
||||
大多数情况下,在 `a-select` 上添加一个 `getPopupContainer` 属性,值为`node => node.parentNode`即可解决。
|
||||
但是如果遇到 `a-select` 标签层级过深的情况,可能仍然会显示异常,只需要多加几个`.parentNode` (例:node => node.parentNode.parentNode.parentNode)多尝试几次直到解决问题即可。
|
||||
|
||||
### 代码示例
|
||||
|
||||
```html
|
||||
<a-select
|
||||
placeholder="请选择展示模板"
|
||||
:options="dicts.displayTemplate"
|
||||
:getPopupContainer="node => node.parentNode"
|
||||
/>
|
||||
```
|
||||
|
||||
# JAsyncTreeList 异步数列表组件使用说明
|
||||
|
||||
## 引入组件
|
||||
|
||||
```js
|
||||
import JTreeTable from '@/components/jeecg/JTreeTable'
|
||||
export default {
|
||||
components: { JTreeTable }
|
||||
}
|
||||
```
|
||||
|
||||
## 所需参数
|
||||
|
||||
| 参数 | 类型 | 必填 | 说明 |
|
||||
|-------------|--------|--------|--------------------------------------------------------------|
|
||||
| rowKey | String | 非必填 | 表格行 key 的取值,默认为"id" |
|
||||
| columns | Array | 必填 | 表格列的配置描述,具体见Antd官方文档 |
|
||||
| url | String | 必填 | 数据查询url |
|
||||
| childrenUrl | String | 非必填 | 查询子级时的url,若不填则使用url参数查询子级 |
|
||||
| queryKey | String | 非必填 | 根据某个字段查询,如果传递 id 就根据 id 查询,默认为parentId |
|
||||
| queryParams | Object | 非必填 | 查询参数,当查询参数改变的时候会自动重新查询,默认为{} |
|
||||
| topValue | String | 非必填 | 查询顶级时的值,如果顶级为0,则传0,默认为null |
|
||||
| tableProps | Object | 非必填 | 自定义给内部table绑定的props |
|
||||
|
||||
## 代码示例
|
||||
|
||||
```html
|
||||
<template>
|
||||
<a-card :bordered="false">
|
||||
<j-tree-table :url="url" :columns="columns" :tableProps="tableProps"/>
|
||||
</a-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import JTreeTable from '@/components/jeecg/JTreeTable'
|
||||
|
||||
export default {
|
||||
name: 'AsyncTreeTable',
|
||||
components: { JTreeTable },
|
||||
data() {
|
||||
return {
|
||||
url: '/api/asynTreeList',
|
||||
columns: [
|
||||
{ title: '菜单名称', dataIndex: 'name' },
|
||||
{ title: '组件', dataIndex: 'component' },
|
||||
{ title: '排序', dataIndex: 'orderNum' }
|
||||
],
|
||||
selectedRowKeys: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
tableProps() {
|
||||
let _this = this
|
||||
return {
|
||||
// 列表项是否可选择
|
||||
// 配置项见:https://vue.ant.design/components/table-cn/#rowSelection
|
||||
rowSelection: {
|
||||
selectedRowKeys: _this.selectedRowKeys,
|
||||
onChange: (selectedRowKeys) => _this.selectedRowKeys = selectedRowKeys
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
# JCheckbox 使用文档
|
||||
|
||||
###### 说明: antd-vue checkbox组件处理的是数组,用起来不是很方便,特二次封装,使用时只需处理字符串即可
|
||||
## 参数配置
|
||||
| 参数 | 类型 | 必填 |说明|
|
||||
|--------------|---------|----|---------|
|
||||
| options |array |✔| checkbox需要配置的项,是个数组,数组中每个对象包含两个属性:label(用于显示)和value(用于存储) |
|
||||
|
||||
使用示例
|
||||
----
|
||||
```vue
|
||||
<template>
|
||||
<a-form :form="form">
|
||||
<a-form-item label="v-model式用法">
|
||||
<j-checkbox v-model="sport" :options="sportOptions"></j-checkbox><span>{{ sport }}</span>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="v-decorator式用法">
|
||||
<j-checkbox v-decorator="['sport']" :options="sportOptions"></j-checkbox><span>{{ getFormFieldValue('sport') }}</span>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import JCheckbox from '@/components/jeecg/JCheckbox'
|
||||
export default {
|
||||
components: {JCheckbox},
|
||||
data() {
|
||||
return {
|
||||
form: this.$form.createForm(this),
|
||||
sport:'',
|
||||
sportOptions:[
|
||||
{
|
||||
label:"足球",
|
||||
value:"1"
|
||||
},{
|
||||
label:"篮球",
|
||||
value:"2"
|
||||
},{
|
||||
label:"乒乓球",
|
||||
value:"3"
|
||||
}]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getFormFieldValue(field){
|
||||
return this.form.getFieldValue(field)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
# JCodeEditor 使用文档
|
||||
|
||||
###### 说明: 一个简易版的代码编辑器,支持语法高亮
|
||||
## 参数配置
|
||||
| 参数 | 类型 | 必填 |说明|
|
||||
|--------------|---------|----|---------|
|
||||
| language |string | | 表示当前编写代码的类型 javascript/html/css/sql |
|
||||
| placeholder |string | | placeholder |
|
||||
| lineNumbers |Boolean | | 是否显示行号 |
|
||||
| fullScreen |Boolean | | 是否显示全屏按钮 |
|
||||
| zIndex |string | | 全屏以后的z-index |
|
||||
|
||||
使用示例
|
||||
----
|
||||
```vue
|
||||
<template>
|
||||
<div>
|
||||
<j-code-editor
|
||||
language="javascript"
|
||||
v-model="editorValue"
|
||||
:fullScreen="true"
|
||||
style="min-height: 100px"/>
|
||||
{{ editorValue }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import JCodeEditor from '@/components/jeecg/JCodeEditor'
|
||||
export default {
|
||||
components: {JCodeEditor},
|
||||
data() {
|
||||
return {
|
||||
form: this.$form.createForm(this),
|
||||
editorValue:'',
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
# JFormContainer 使用文档
|
||||
|
||||
###### 说明: 暂用于表单禁用
|
||||
|
||||
使用示例
|
||||
----
|
||||
```vue
|
||||
<!-- 在form下直接写这个组件,设置disabled为true就能将此form中的控件禁用 -->
|
||||
<a-form layout="inline" :form="form" >
|
||||
<j-form-container disabled>
|
||||
<!-- 表单内容省略..... -->
|
||||
</j-form-container>
|
||||
</a-form>
|
||||
```
|
||||
|
||||
# JImportModal 使用文档
|
||||
|
||||
###### 说明: 用于列表页面导入excel功能
|
||||
|
||||
使用示例
|
||||
----
|
||||
```vue
|
||||
|
||||
<template>
|
||||
<!-- 此处省略部分代码...... -->
|
||||
<a-button @click="handleImportXls" type="primary" icon="upload">导入</a-button>
|
||||
<!-- 此处省略部分代码...... -->
|
||||
<j-import-modal ref="importModal" :url="getImportUrl()" @ok="importOk"></j-import-modal>
|
||||
<!-- 此处省略部分代码...... -->
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import JCodeEditor from '@/components/jeecg/JCodeEditor'
|
||||
export default {
|
||||
components: {JCodeEditor},
|
||||
data() {
|
||||
return {
|
||||
//省略代码......
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
//省略部分代码......
|
||||
handleImportXls(){
|
||||
this.$refs.importModal.show()
|
||||
},
|
||||
getImportUrl(){
|
||||
return '你自己处理上传业务的后台地址'
|
||||
},
|
||||
importOk(){
|
||||
this.loadData(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
# JSelectMultiple 多选下拉组件
|
||||
online用 实际开发请使用components/dict/JMultiSelectTag
|
||||
|
||||
# JSlider 滑块验证码
|
||||
|
||||
使用示例
|
||||
----
|
||||
```vue
|
||||
<template>
|
||||
<div style="width: 300px">
|
||||
<j-slider @onSuccess="sliderSuccess"></j-slider>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import JSlider from '@/components/jeecg/JSlider'
|
||||
export default {
|
||||
components: {JSlider},
|
||||
data() {
|
||||
return {
|
||||
form: this.$form.createForm(this),
|
||||
editorValue:'',
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
sliderSuccess(){
|
||||
console.log("验证完成")
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
|
||||
# JTreeSelect 树形下拉组件
|
||||
异步加载的树形下拉组件
|
||||
|
||||
## 参数配置
|
||||
| 参数 | 类型 | 必填 |说明|
|
||||
|--------------|---------|----|---------|
|
||||
| placeholder |string | | placeholder |
|
||||
| dict |string | ✔| 表名,显示字段名,存储字段名拼接的字符串 |
|
||||
| pidField |string | ✔| 父ID的字段名 |
|
||||
| pidValue |string | | 根节点父ID的值 默认'0' 不可以设置为空,如果想使用此组件,而数据库根节点父ID为空,请修改之 |
|
||||
| multiple |boolean | |是否支持多选 |
|
||||
|
||||
使用示例
|
||||
----
|
||||
```vue
|
||||
<template>
|
||||
<a-form>
|
||||
<a-form-item label="树形下拉测试" style="width: 300px">
|
||||
<j-tree-select
|
||||
v-model="departId"
|
||||
placeholder="请选择部门"
|
||||
dict="sys_depart,depart_name,id"
|
||||
pidField="parent_id">
|
||||
</j-tree-select>
|
||||
{{ departId }}
|
||||
</a-form-item>
|
||||
</a-form >
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import JTreeSelect from '@/components/jeecg/JTreeSelect'
|
||||
export default {
|
||||
components: {JTreeSelect},
|
||||
data() {
|
||||
return {
|
||||
departId:""
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
|
||||
@ -1,577 +0,0 @@
|
||||
# JEditableTable 帮助文档
|
||||
|
||||
## 参数配置
|
||||
|
||||
| 参数 | 类型 | 必填 | 说明 |
|
||||
|--------------|---------|------|---------------------------------------------------------------------------------|
|
||||
| columns | array | ✔️ | 表格列的配置描述,具体项见下表 |
|
||||
| dataSource | array | ✔️ | 表格数据 |
|
||||
| loading | boolean | | 是否正在加载,加载中不会显示任何行,默认false |
|
||||
| actionButton | boolean | | 是否显示操作按钮,包括"新增"、"删除",默认false |
|
||||
| rowNumber | boolean | | 是否显示行号,默认false |
|
||||
| rowSelection | boolean | | 是否可选择行,默认false |
|
||||
| dragSort | boolean | | 是否可拖动排序,默认false |
|
||||
| dragSortKey | string | | 拖动排序存储的Key,无需定义在columns内也能在getValues()时获取到值,默认orderNum |
|
||||
| maxHeight | number | | 设定最大高度(px),默认400 |
|
||||
| disabledRows | object | | 设定禁用的行,被禁用的行无法被选择和编辑,配置方法可以查看示例 |
|
||||
| disabled | boolean | | 是否禁用所有行,默认false |
|
||||
|
||||
### columns 参数详解
|
||||
|
||||
| 参数 | 类型 | 必填 | 说明 |
|
||||
|---------------|---------|------|--------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| title | string | ✔️ | 表格列头显示的问题 |
|
||||
| key | string | ✔️ | 列数据在数据项中对应的 key,必须是唯一的 |
|
||||
| type | string | ✔️ | 表单的类型,可以通过`JEditableTableUtil.FormTypes`赋值 |
|
||||
| width | string | | 列的宽度,可以是百分比,也可以是`px`或其他单位,建议设置为百分比,且每一列的宽度加起来不应超过100%,否则可能会不能达到预期的效果。留空会自动计算百分比 |
|
||||
| placeholder | string | | 表单预期值的提示信息,可以使用`${...}`变量替换文本(详见`${...} 变量使用方式`) |
|
||||
| defaultValue | string | | 默认值,在新增一行时生效 |
|
||||
| validateRules | array | | 表单验证规则,配置方式见[validateRules 配置规则](#validaterules-配置规则) |
|
||||
| props | object | | 设置添加给表单元素的自定义属性,例如:`props:{title: 'show title'}` |
|
||||
| disabled | boolean | | 是否禁用当前列,默认false |
|
||||
|
||||
#### 当 type=checkbox 时所需的参数
|
||||
|
||||
| 参数 | 类型 | 必填 | 说明 |
|
||||
|----------------|---------|------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| defaultChecked | boolean | | 默认值是否选中 |
|
||||
| customValue | array | | 自定义值,checkbox需要的是boolean值,如果数据是其他值(例如`'Y' or 'N'`)时,就会导致错误,所以提供了该属性进行转换,例:`customValue: ['Y','N']`,会将`true`转换为`'Y'`,`false`转换为`'N'`,反之亦然 |
|
||||
|
||||
#### 当 type=select 时所需的参数
|
||||
|
||||
| 参数 | 类型 | 必填 | 说明 |
|
||||
|------------|---------|------|----------------------------------------------------|
|
||||
| options | array | ✔️ | 下拉选项列表,详见下表 |
|
||||
| allowInput | boolean | | 是否允许用户输入内容,并创建新的内容 |
|
||||
| dictCode | String | | 数据字典Code,若options也有值,则拼接在options后面 |
|
||||
|
||||
##### options 所需参数
|
||||
|
||||
| 参数 | 类型 | 必填 | 说明 |
|
||||
|-----------|------------|------|----------------------------------------------------------------------|
|
||||
| text | string | ✔️ | 显示标题 |
|
||||
| value | string | ✔️ | 真实值 |
|
||||
| ~~title~~ | ~~string~~ | | ~~显示标题(已废弃,若同时填写了 title 和 text 那么优先使用 text)~~ |
|
||||
|
||||
#### 当 type=upload 时所需的参数
|
||||
|
||||
| 参数 | 类型 | 必填 | 说明 |
|
||||
|--------------|---------|------|--------------------------------------------------------------------------------------|
|
||||
| action | string | ✔️ | 上传文件路径 |
|
||||
| token | boolean | | 上传的时候是否传递token |
|
||||
| responseName | string | ✔️ | 若要从上传成功后从response中取出返回的文件名,那么这里填后台返回的包含文件名的字段名 |
|
||||
|
||||
#### 当 type=slot 时所需的参数
|
||||
|
||||
| 参数 | 类型 | 必填 | 说明 |
|
||||
|----------|--------|------|------------|
|
||||
| slotName | string | ✔️ | slot的名称 |
|
||||
|
||||
### validateRules 配置规则
|
||||
|
||||
`validateRules` 需要的是一个数组,数组里每项都是一个规则,规则是object类型,规则的各个参数如下
|
||||
|
||||
- `required` 是否必填,可选值为`true`or`false`
|
||||
- `pattern` 正则表达式验证,只有成功匹配该正则的值才能成功通过验证
|
||||
- `handler` 自定义函数校验,使用方法请见[示例五](#示例五)
|
||||
- `message` 当验证未通过时显示的提示文本,可以使用`${...}`变量替换文本(详见`${...} 变量使用方式`)
|
||||
- 配置示例请看[示例二](#示例二)
|
||||
|
||||
## 事件
|
||||
|
||||
| 事件名 | 触发时机 | 参数 |
|
||||
|-----------------|----------------------------------------------------|--------------------------------------------------|
|
||||
| added | 当添加行操作完成后触发 | |
|
||||
| deleted | 当删除行操作完成后触发(批量删除操作只会触发一次) | `deleteIds` 被逻辑删除的id |
|
||||
| selectRowChange | 当行被选中或取消选中时触发 | `selectedRowIds` 被选中行的id |
|
||||
| valueChange | 当数据发生改变的时候触发的事件 | `{ type, row, column, value, target }` Event对象 |
|
||||
|
||||
## 方法
|
||||
|
||||
关于方法的如何调用的问题,请在**FAQ**中查看[方法如何调用](#方法如何调用)
|
||||
|
||||
### initialize
|
||||
|
||||
用于初始化表格(清空表格)
|
||||
|
||||
- `参数:` 无
|
||||
- `返回值:` 无
|
||||
|
||||
### resetScrollTop
|
||||
|
||||
重置滚动条Top位置
|
||||
|
||||
- `参数:`
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|--------|------|--------------------------------------------------------------------------------------------------------|
|
||||
| top | number | | 新top位置,留空则滚动到上次记录的位置,用于解决切换tab选项卡时导致白屏以及自动将滚动条滚动到顶部的问题 |
|
||||
|
||||
- `返回值:` 无
|
||||
|
||||
### add
|
||||
|
||||
主动添加行,默认情况下,当用户的滚动条已经在底部的时候,会将滚动条固定在底部,即添加后无需用户手动滚动,而会自动滚动到底部
|
||||
|
||||
- `参数:`
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|---------------------|---------|------|---------------------------------------------------------------------|
|
||||
| num | number | | 添加几行,默认为1 |
|
||||
| forceScrollToBottom | boolean | | 是否在添加后无论用户的滚动条在什么位置都强制滚动到底部,默认为false |
|
||||
|
||||
- `返回值:` 无
|
||||
|
||||
### removeRows
|
||||
|
||||
主动删除一行或多行
|
||||
|
||||
- `参数:`
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|-----------------|------|--------------------------------------------------------------------------------------------|
|
||||
| id | string 或 array | ✔️ | 被删除行的id。如果要删除一个,可以直接传id,如果要删除多个,需要将多个id封装成一个数组传入 |
|
||||
|
||||
- `返回值:` 无
|
||||
|
||||
### removeSelectedRows
|
||||
|
||||
主动删除被选中的行
|
||||
|
||||
- `参数:` 无
|
||||
- `返回值:` 无
|
||||
|
||||
### getValues
|
||||
|
||||
用于获取表格里所有表单的值,可进行表单验证
|
||||
|
||||
- `参数:`
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|----------|----------|------|-----------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| callback | function | ✔️ | 获取值的回调方法,会传入`error`和`values`两个参数。`error`:未通过验证的数量,当等于`0`时代表验证通过;`values`:获取的值(即使未通过验证该字段也有数据) |
|
||||
| validate | boolean | | 是否进行表单验证,默认为`true`,设为`false`则代表忽略表单验证 |
|
||||
| rowIds | array | | 默认返回所有行的数据,如果传入了`rowIds`,那么就会只返回与该`rowIds`相匹配的数据,如果没有匹配的数据,就会返回空数组 |
|
||||
|
||||
- `返回值:` 无
|
||||
|
||||
|
||||
### getValuesSync
|
||||
|
||||
`getValues`的同步版,会直接将获取到的数据返回
|
||||
|
||||
- `参数:`
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|---------|--------|------|------------------------|
|
||||
| options | object | | 选项,详见下方所需参数 |
|
||||
|
||||
- - `options` 所需参数
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|----------|---------|------|----------------------------------------------------------------------------------------------------------------------|
|
||||
| validate | boolean | | 是否进行表单验证,默认为`true`,设为`false`则代表忽略表单验证 |
|
||||
| rowIds | array | | 默认返回所有行的数据,如果传入了`rowIds`,那么就会只返回与该`rowIds`相匹配的数据,如果没有匹配的数据,就会返回空数组 |
|
||||
|
||||
- `返回值:` object
|
||||
- `error` 未通过验证的数量,当等于`0`时代表验证通过
|
||||
- `values` 获取的值(即使未通过验证该字段也有数据)
|
||||
|
||||
- `使用示例`
|
||||
|
||||
```js
|
||||
let { error, values } = this.$refs.editableTable.getValuesSync({ validate: true, rowIds: ['rowId1', 'rowId2'] })
|
||||
if (error === 0) {
|
||||
console.log('表单验证通过,数据:', values);
|
||||
} else {
|
||||
console.log('未通过表单验证,数据:', values);
|
||||
}
|
||||
```
|
||||
|
||||
### getValuesPromise
|
||||
|
||||
`getValues`的promise版,会在`resolve`中传入获取到的值,会在`reject`中传入失败原因,例如`VALIDATE_NO_PASSED`
|
||||
|
||||
- `参数:`
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|----------|---------|------|----------------------------------------------------------------------------------------------------------------------|
|
||||
| validate | boolean | | 同`getValues`的`validate`参数 |
|
||||
| rowIds | array | | 默认返回所有行的数据,如果传入了`rowIds`,那么就会只返回与该`rowIds`相匹配的数据,如果没有匹配的数据,就会返回空数组 |
|
||||
|
||||
- `返回值:` Promise
|
||||
|
||||
### getDeleteIds
|
||||
|
||||
用于获取被逻辑删除的行的id,返回一个数组,用户可将该数组传入后台,并进行批量删除
|
||||
|
||||
- `参数:` 无
|
||||
- `返回值:` array
|
||||
|
||||
### getAll
|
||||
|
||||
获取所有的数据,包括values、deleteIds
|
||||
会在`resolve`中传入获取到的值:`{values, deleteIds}`
|
||||
会在`reject`中传入失败原因,例如`VALIDATE_NO_PASSED`
|
||||
|
||||
- `参数:`
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|----------|---------|------|-------------------------------|
|
||||
| validate | boolean | | 同`getValues`的`validate`参数 |
|
||||
|
||||
- `返回值:` Promise
|
||||
|
||||
### setValues
|
||||
|
||||
主动设置表格中某行某列的值
|
||||
|
||||
- `参数:`
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|-------|------|------------------------------------------------------------|
|
||||
| values | array | | 传入一个数组,数组中的每项都是一行的新值,具体见下面的示例 |
|
||||
|
||||
- `返回值:` 无
|
||||
- `示例:`
|
||||
|
||||
```js
|
||||
setValues([
|
||||
{
|
||||
rowKey: id1, // 行的id
|
||||
values: { // 在这里 values 中的 name 是你 columns 中配置的 key
|
||||
'name': 'zhangsan',
|
||||
'age': '20'
|
||||
}
|
||||
},
|
||||
{
|
||||
rowKey: id2,
|
||||
values: {
|
||||
'name': 'lisi',
|
||||
'age': '23'
|
||||
}
|
||||
}
|
||||
])
|
||||
```
|
||||
### clearSelection
|
||||
|
||||
主动清空选择的行
|
||||
|
||||
- `参数:` 无
|
||||
- `返回值:` 无
|
||||
|
||||
## 内置插槽
|
||||
|
||||
| 插槽名 | 说明 |
|
||||
|--------------|------------------------------------------------------|
|
||||
| buttonBefore | 在操作按钮的**前面**插入插槽,不受`actionButton`属性的影响 |
|
||||
| buttonAfter | 在操作按钮的**后面**插入插槽,不受`actionButton`属性的影响 |
|
||||
|
||||
## ${...} 变量使用方式
|
||||
|
||||
在`placeholder`和`message`这两个属性中可以使用`${...}`变量来替换文本
|
||||
在[示例二](#示例二)中,配置了`title`为`名称`的一列,而`placeholder`配置成了`请输入${title}`,那么最终显示效果为`请输入名称`
|
||||
这就是`${...}`变量的使用方式,在`${}`中可以使用的变量有`title`、`key`、`defaultValue`这三个属性的值
|
||||
|
||||
## JEditableTableUtil 使用说明
|
||||
|
||||
在之前配置`columns`时提到过`JEditableTableUtil`这个工具类,那么如果想要知道详细的使用说明就请看这里
|
||||
|
||||
### export 的常量
|
||||
|
||||
#### FormTypes
|
||||
|
||||
这是配置`columns.type`时用到的常量值,其中包括
|
||||
|
||||
- `normal` 默认,直接显示值,不渲染表单
|
||||
- `input` 显示输入框
|
||||
- `inputNumber` 显示数字输入框
|
||||
- `checkbox` 显示多选框
|
||||
- `select` 显示选择器(下拉框)
|
||||
- `date` 日期选择器
|
||||
- `datetime` 日期时间选择器
|
||||
- `upload` 上传组件(文件域)
|
||||
- `slot` 自定义插槽
|
||||
|
||||
### VALIDATE_NO_PASSED
|
||||
|
||||
在判断表单验证是否通过时使用,如果 reject 的值 === VALIDATE_NO_PASSED 则代表表单验证未通过,你可以做相应的其他处理,反之则可能是发生了报错,可以使用 `console.error` 输出
|
||||
|
||||
### 封装的方法
|
||||
|
||||
#### validateTables
|
||||
|
||||
当你的页面中存在多个JEditableTable实例的时候,如果要获取每个实例的值、判断表单验证是否通过,就会让代码变得极其冗余、繁琐,于是我们就将该操作封装成了一个函数供你调用,它可以同时获取并验证多个JEditableTable实例的值,只有当所有实例的表单验证都通过后才会返回值,否则将会告诉你具体哪个实例没有通过验证。具体使用方法请看下面的示例
|
||||
|
||||
- `参数:`
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|-------|------|--------------------------------------------------------|
|
||||
| cases | array | | 传入一个数组,数组中的每项都是一个JEditableTable的实例 |
|
||||
|
||||
- `返回值:` Promise
|
||||
- `示例:`
|
||||
|
||||
```js
|
||||
import { validateTables, VALIDATE_NO_PASSED } from '@/utils/JEditableTableUtil'
|
||||
// 封装cases
|
||||
let cases = []
|
||||
cases.push(this.$refs.editableTable1)
|
||||
cases.push(this.$refs.editableTable2)
|
||||
cases.push(this.$refs.editableTable3)
|
||||
cases.push(this.$refs.editableTable4)
|
||||
cases.push(this.$refs.editableTable5)
|
||||
// 同时验证并获取多个实例的值
|
||||
validateTables(cases).then((all) => {
|
||||
// all 是一个数组,每项都对应传入cases的下标,包含values和deleteIds
|
||||
console.log('所有实例的值:', all)
|
||||
}).catch((e = {}) => {
|
||||
// 判断表单验证是否未通过
|
||||
if (e.error === VALIDATE_NO_PASSED) {
|
||||
console.log('未通过验证的实例下标:', e.index)
|
||||
} else {
|
||||
console.error('发生异常:', e)
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
## FAQ
|
||||
|
||||
### 方法如何调用?
|
||||
|
||||
在[示例一](#示例一)中,设定了一个 `ref="editableTable"` 的属性,那么在vue中就可以使用`this.$refs.editableTable`获取到该表格的实例,并调取其中的方法。
|
||||
假如我要调取`initialize`方法,就可以这么写:`this.$refs.editableTable.initialize()`
|
||||
|
||||
### 如何获取表单的值?
|
||||
|
||||
使用`getValue`方法进行获取,详见[示例三](#示例三)
|
||||
|
||||
### 如何进行表单验证?
|
||||
|
||||
在获取值的时候默认会进行表单验证操作,用户在输入的时候也会对正在输入的表单进行验证,只要配置好规则就可以了
|
||||
|
||||
### 如何添加或删除一行?
|
||||
|
||||
该功能已封装到组件中,你只需要将 `actionButton` 设置为 `true` 即可,当然你也可以在代码中主动调用新增方法或修改,具体见上方的方法介绍。
|
||||
|
||||
### 为什么使用了ATab组件后,切换选项卡会导致白屏或滚动条位置会归零?
|
||||
|
||||
在ATab组件中确实会导致滚动条位置归零,且不会触发`onscroll`方法,所以无法动态加载行,导致白屏的问题出现。
|
||||
解决方法是在ATab组件的`onChange`事件触发时执行实例提供的`resetScrollTop()`方法即可,但是需要注意的是:代码主动改变ATab的`activeKey`不会触发`onChange`事件,还需要你手动调用下。
|
||||
|
||||
- `示例`
|
||||
|
||||
```html
|
||||
<template>
|
||||
<a-tabs @change="handleChangeTab">
|
||||
<a-tab-pane tab="表格1" :forceRender="true" key="1">
|
||||
<j-editable-table
|
||||
ref="editableTable1"
|
||||
:loading="tab1.loading"
|
||||
:columns="tab1.columns"
|
||||
:dataSource="tab1.dataSource"/>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane tab="表格2" :forceRender="true" key="2">
|
||||
<j-editable-table
|
||||
ref="editableTable2"
|
||||
:loading="tab2.loading"
|
||||
:columns="tab2.columns"
|
||||
:dataSource="tab2.dataSource"/>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</template>
|
||||
```
|
||||
|
||||
```js
|
||||
/*--- 忽略部分代码片段 ---*/
|
||||
methods: {
|
||||
|
||||
/** 切换tab选项卡的时候重置editableTable的滚动条状态 */
|
||||
handleChangeTab(key) {
|
||||
this.$refs[`editableTable${key}`].resetScrollTop()
|
||||
}
|
||||
|
||||
}
|
||||
/*--- 忽略部分代码片段 ---*/
|
||||
```
|
||||
|
||||
### slot(自定义插槽)如何使用?
|
||||
|
||||
代码示例请看:[示例四(slot)](#示例四(slot))
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
## 示例一
|
||||
|
||||
```html
|
||||
<j-editable-table
|
||||
ref="editableTable"
|
||||
:loading="loading"
|
||||
:columns="columns"
|
||||
:dataSource="dataSource"
|
||||
:rowNumber="true"
|
||||
:rowSelection="true"
|
||||
:actionButton="true"
|
||||
style="margin-top: 8px;"
|
||||
@selectRowChange="handleSelectRowChange"/>
|
||||
```
|
||||
|
||||
## 示例二
|
||||
|
||||
```js
|
||||
|
||||
import { FormTypes } from '@/utils/JEditableTableUtil'
|
||||
|
||||
/*--- 忽略部分代码片断 ---*/
|
||||
columns: [
|
||||
{
|
||||
title: '名称',
|
||||
key: 'name',
|
||||
type: FormTypes.input,
|
||||
placeholder: '请输入${title}',
|
||||
defaultValue: '称名',
|
||||
// 表单验证规则
|
||||
validateRules: [
|
||||
{
|
||||
required: true, // 必填
|
||||
message: '${title}不能为空' // 提示的文本
|
||||
},
|
||||
{
|
||||
pattern: /^[a-z|A-Z][a-z|A-Z\d_-]{0,}$/, // 正则
|
||||
message: '${title}必须以字母开头,可包含数字、下划线、横杠'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: '年龄',
|
||||
key: 'age',
|
||||
type: FormTypes.inputNumber,
|
||||
placeholder: '请输入${title}',
|
||||
defaultValue: 18,
|
||||
validateRules: [{required: true, message: '${title}不能为空'}]
|
||||
}
|
||||
]
|
||||
/*--- 忽略部分代码片断 ---*/
|
||||
```
|
||||
|
||||
## 示例三
|
||||
|
||||
```js
|
||||
// 获取被逻辑删除的字段id
|
||||
let deleteIds = this.$refs.editableTable.getDeleteIds();
|
||||
// 获取所有表单的值,并进行验证
|
||||
this.$refs.editableTable.getValues((error, values) => {
|
||||
// 错误数 = 0 则代表验证通过
|
||||
if (error === 0) {
|
||||
this.$message.success('验证通过')
|
||||
// 将通过后的数组提交到后台或自行进行其他处理
|
||||
console.log(deleteIds, values)
|
||||
} else {
|
||||
this.$message.error('验证未通过')
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
## 示例四(slot)
|
||||
|
||||
```html
|
||||
<template>
|
||||
<j-editable-table :columns="columns" :dataSource="dataSource">
|
||||
<!-- 定义插槽 -->
|
||||
<!-- 这种定义插槽的写法是vue推荐的新版写法(https://cn.vuejs.org/v2/guide/components-slots.html#具名插槽),旧版已被废弃的写法不再支持 -->
|
||||
<!-- 若webstorm这样写报错,请看这篇文章:https://blog.csdn.net/lxq_9532/article/details/81870651 -->
|
||||
<template v-slot:action="props">
|
||||
<a @click="handleDelete(props)">删除</a>
|
||||
</template>
|
||||
</j-editable-table>
|
||||
</template>
|
||||
<script>
|
||||
import { FormTypes } from '@/utils/JEditableTableUtil'
|
||||
import JEditableTable from '@/components/jeecg/JEditableTable'
|
||||
export default {
|
||||
components: { JEditableTable },
|
||||
data() {
|
||||
return {
|
||||
columns: [
|
||||
// ...
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
width: '8%',
|
||||
type: FormTypes.slot, // 定义该列为 自定义插值列
|
||||
slotName: 'action' // slot 的名称,对应 v-slot 冒号后面和等号前面的内容
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/* a 标签的点击事件,删除当前选中的行 */
|
||||
handleDelete(props) {
|
||||
// 参数解释
|
||||
// props.index :当前行的下标
|
||||
// props.text :当前值,可能是defaultValue定义的值,也可能是从dataSource中取出的值
|
||||
// props.rowId :当前选中行的id,如果是新增行则是临时id
|
||||
// props.column :当前操作的列
|
||||
// props.getValue :这是一个function,执行后可以获取当前行的所有值(禁止在template中使用)
|
||||
// 例:const value = props.getValue()
|
||||
// props.target :触发当前事件的实例,可直接调用该实例内的方法(禁止在template中使用)
|
||||
// 例:target.add()
|
||||
|
||||
// 使用实例:删除当前操作的行
|
||||
let { rowId, target } = props
|
||||
target.removeRows(rowId)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
## 示例五
|
||||
|
||||
```js
|
||||
// 该示例是自定义函数校验
|
||||
columns: [
|
||||
{
|
||||
title: '字段名称',
|
||||
key: 'dbFieldName',
|
||||
type: FormTypes.input,
|
||||
defaultValue: '',
|
||||
validateRules: [
|
||||
{
|
||||
// 自定义函数校验 handler
|
||||
handler(type, value, row, column, callback, target) {
|
||||
// type 触发校验的类型(input、change、blur)
|
||||
// value 当前校验的值
|
||||
// callback(flag, message) 方法必须执行且只能执行一次
|
||||
// flag = 是否通过了校验,不填写或者填写 null 代表不进行任何操作
|
||||
// message = 提示的类型,默认使用配置的 message
|
||||
// target 行编辑的实例对象
|
||||
|
||||
if (type === 'blur') {
|
||||
|
||||
if (value === 'abc') {
|
||||
callback(false, '${title}不能是abc') // false = 未通过,可以跟自定义提示
|
||||
return
|
||||
}
|
||||
|
||||
let { values } = target.getValuesSync({ validate: false })
|
||||
let count = 0
|
||||
for (let val of values) {
|
||||
if (val['dbFieldName'] === value) {
|
||||
if (++count >= 2) {
|
||||
callback(false, '${title}不能重复')
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
callback(true) // true = 通过验证
|
||||
} else {
|
||||
callback() // 不填写或者填写 null 代表不进行任何操作
|
||||
}
|
||||
},
|
||||
message: '${title}默认提示'
|
||||
}
|
||||
]
|
||||
},
|
||||
]
|
||||
```
|
||||
@ -1,5 +0,0 @@
|
||||
import T from './JFormContainer.vue'
|
||||
let install = function (Vue) {
|
||||
Vue.component('JFormContainer',T);
|
||||
}
|
||||
export default { install };
|
||||