Compare commits
727 Commits
V1.0.0(测试版
...
main
Author | SHA1 | Date |
---|---|---|
朱浩 | 27c7033522 | |
朱浩 | 4c66cc90c0 | |
lyc | c2b54714ac | |
lyc | cafea2d719 | |
yangws | d5afede36c | |
朱浩 | 03e61c8440 | |
朱浩 | 79b9a0726a | |
朱浩 | 0ccde18f00 | |
朱浩 | 274c80ad0a | |
yangws | 923006eab1 | |
yangws | a64ba24742 | |
lyc | df1f8737bd | |
lyc | 19a3b948c5 | |
朱浩 | 622cdfe0fe | |
朱浩 | 78b795bf4f | |
lyc | 92667a7d25 | |
lyc | 71f7e4e5a1 | |
朱浩 | 3cced30959 | |
朱浩 | ef9fe838a3 | |
zhangxuelin | 9ff824e082 | |
zhangxuelin | 8975784ce0 | |
lyc | e586755b75 | |
lyc | ef771f4e0b | |
朱浩 | 049768c8b6 | |
朱浩 | ac599a2c39 | |
lyc | 00871797bf | |
lyc | fa7a44472b | |
lyc | 85529ad81f | |
lyc | f9a87143aa | |
zhengdegang | 17ef183741 | |
zdg | d5833f6f03 | |
zdg | c93eeeb308 | |
zhengdegang | 0d48111e50 | |
zdg | ca57e72e9c | |
zhengdegang | 928a1401db | |
zdg | e0d3a6da6a | |
zdg | 1a9b426ec3 | |
lyc | d4cfedf883 | |
lyc | b5fd1f2a9d | |
lyc | c6477d5ca9 | |
lyc | 27ec047981 | |
zhengdegang | 7da4defed4 | |
zdg | 51cb1989a1 | |
zdg | 4ab4d5dff2 | |
lyc | 80d6e1c59c | |
lyc | 75c6777933 | |
朱浩 | a75f151b19 | |
朱浩 | 2531c25d7c | |
朱浩 | 9e5527d822 | |
朱浩 | e002ef5f7d | |
朱浩 | 2ca637072d | |
baigl | bd7f6f765f | |
白了个白 | ef6c3d2a2b | |
白了个白 | 9ea05568e1 | |
zhengdegang | 93a061ca78 | |
zdg | c5075af2fc | |
zdg | 7da60f0815 | |
zdg | 02a25db5e2 | |
yangws | 59de30b6b2 | |
yangws | 746cb150c4 | |
lyc | 893be27671 | |
lyc | b0b429c7aa | |
lyc | dbfa1a4037 | |
lyc | ce8b2e6ab0 | |
baigl | a082b437b7 | |
白了个白 | 9eb6d991c1 | |
白了个白 | 0cbb513a60 | |
lyc | be765b21b6 | |
lyc | 34c1c66b31 | |
lyc | 5f06657b09 | |
白了个白 | 3ec25f07b4 | |
zhengdegang | aa35621b59 | |
zdg | 49de9ee9c2 | |
zdg | 0ef5ef424f | |
baigl | 89ae43a458 | |
白了个白 | 9d7aad1946 | |
lyc | db2be260a7 | |
baigl | b06ad0f411 | |
白了个白 | 129f875469 | |
白了个白 | 2c6da76cf7 | |
ekooo | 499e428138 | |
朱浩 | 81f873bcc3 | |
lyc | c58322ca0b | |
lyc | 08dad41e4d | |
zhengdegang | 675613bbee | |
zdg | 9188df0d94 | |
zdg | 4e8560b033 | |
“zouyf” | 4e835cac82 | |
朱浩 | 7303128334 | |
yangws | d047e85d03 | |
yangws | acd66c11fa | |
朱浩 | f90e2548c6 | |
yangws | c32bd6eef4 | |
yangws | 3b9877e788 | |
朱浩 | fb48984e7f | |
lyc | aaa2aef3ca | |
lyc | 5cfd5747a1 | |
lyc | 04263cd519 | |
lyc | aee945f90f | |
白了个白 | bae24601ef | |
白了个白 | 980e4d66e8 | |
lyc | 7439c9759a | |
lyc | ddd53943b8 | |
ekooo | 70ba70df45 | |
baigl | 7ae8547d41 | |
zhengdegang | c5c28b4bf5 | |
zdg | 67d7395c47 | |
白了个白 | 46adf4c058 | |
zdg | f615efbd88 | |
zdg | 741e7336f3 | |
朱浩 | a67f801356 | |
朱浩 | 1c89217fbf | |
朱浩 | 3a20f453c6 | |
朱浩 | dfa5c7d99b | |
lyc | e144fbe36a | |
lyc | b279d36c89 | |
lyc | 8013b1c2cc | |
baigl | 610aac6985 | |
白了个白 | 6c85654608 | |
白了个白 | a5b6cd3516 | |
lyc | 01718f573b | |
lyc | ec9c673b5a | |
白了个白 | 578fc9feba | |
白了个白 | f49cba5e36 | |
lyc | a92176174a | |
lyc | 8063783284 | |
lyc | eadc6f1440 | |
lyc | 8753951796 | |
白了个白 | 490add5467 | |
白了个白 | 634ae460f3 | |
白了个白 | 1cc7007852 | |
朱浩 | 502cf13168 | |
朱浩 | a4fa5be295 | |
yangws | e907a1c07a | |
yangws | 1afaed082a | |
lyc | 69362a6153 | |
lyc | 1da3ca0ee0 | |
lyc | d4a6f74cfc | |
zouyf | f57c67aab2 | |
“zouyf” | 63ad74c77f | |
“zouyf” | d171117f03 | |
lyc | 0426b85d3f | |
lyc | 17b8ce1dda | |
zhangxuelin | 0fa3c84f5e | |
zhangxuelin | 490536654a | |
zhangxuelin | 2efb870a16 | |
yangws | 5778a8955d | |
朱浩 | e4e23e7508 | |
yangws | 6a33ea8023 | |
朱浩 | bc0579fa32 | |
yangws | 3357cf8a78 | |
yangws | 3fdf500366 | |
zhengdegang | e985417675 | |
zdg | 1978d1bac1 | |
zdg | b9014b950a | |
lyc | 03ecbb1d50 | |
lyc | ec3b978185 | |
zdg | 3632beebfa | |
zdg | f0e87338fb | |
lyc | 54266f8a37 | |
lyc | 82bed1be03 | |
lyc | 8a74f17266 | |
lyc | 40c6e1303b | |
yangws | ee196b6eb8 | |
yangws | 6c60cd4442 | |
baigl | 471d73a224 | |
白了个白 | d7761883f2 | |
baigl | d4b1e547de | |
白了个白 | b34182eb39 | |
白了个白 | 300093cf74 | |
yangws | aaf03eb60d | |
yangws | 08075746c0 | |
yangws | 8ec93353bc | |
yangws | 68df866db5 | |
朱浩 | add564c4ed | |
朱浩 | 77e76fcf7d | |
朱浩 | 0268f1af36 | |
朱浩 | 278dfd4d93 | |
lyc | db6ebbdbaf | |
lyc | e2017c3553 | |
lyc | 0be3d131e2 | |
yangws | 8ec738de46 | |
yangws | 076a510109 | |
zhangxuelin | ee9e5d1326 | |
zhangxuelin | 7ed7b2efd2 | |
zhangxuelin | eaf2d82ead | |
朱浩 | 786c6816ec | |
朱浩 | 1b504a1653 | |
朱浩 | 85c61ca802 | |
zhangxuelin | 7da1d97939 | |
baigl | 3603c4e0f2 | |
白了个白 | cb1c3c23fe | |
白了个白 | de1dee7380 | |
zhangxuelin | 151cdbb1a1 | |
朱浩 | a2c962e94d | |
朱浩 | 9cad353d36 | |
朱浩 | 53f43019e9 | |
baigl | 4996af57c7 | |
白了个白 | 7a4cc9eb64 | |
白了个白 | fd6aa2a56a | |
zdg | ad2e6b92db | |
白了个白 | 6be4b3526e | |
zhangxuelin | bbe4037a71 | |
白了个白 | 0b6b0c318d | |
zouyf | d896209948 | |
“zouyf” | c618ec04c7 | |
zhangxuelin | c79e7966ee | |
lyc | 3a1cf6224a | |
白了个白 | 2d89ef8de3 | |
白了个白 | 44002ae78d | |
白了个白 | 0e88eb8226 | |
白了个白 | 5bda6cfad2 | |
朱浩 | 280313e638 | |
朱浩 | ed7a8a124e | |
zouyf | 4b71008bee | |
“zouyf” | aab477999e | |
“zouyf” | d1b7101ba5 | |
白了个白 | 7cb84ffe37 | |
lyc | 47f3202444 | |
lyc | 3cd8c51aae | |
lyc | be187e1a2d | |
白了个白 | 0c506a09f2 | |
白了个白 | 04ac5dc8b5 | |
zhangxuelin | aca464fddd | |
zhangxuelin | 25d026bd13 | |
lyc | 119e07bcea | |
“zouyf” | 555960b8bd | |
“zouyf” | d709753534 | |
朱浩 | 78ac6e5ca6 | |
朱浩 | acc29b02e4 | |
zhengdegang | 12da4ac2c0 | |
zdg | 5ecba3fb62 | |
zdg | f5f33eaa63 | |
zhengdegang | 090bc5997c | |
zdg | 1c69d10263 | |
zdg | b794d55cd7 | |
zdg | 28b5a131fd | |
zdg | e740cb0c7e | |
zdg | 3a83a31970 | |
zhangxuelin | 30f7b9d5b3 | |
zhangxuelin | 37810586b7 | |
zhangxuelin | e31858a3fe | |
zdg | 3a6b78bc76 | |
zhengdegang | 10a1342b95 | |
zdg | 70e99e69ba | |
lyc | 3171c0b3f9 | |
lyc | 33e84ca006 | |
lyc | 28a815169d | |
zhengdegang | eace8b56d8 | |
zdg | e03e385dbc | |
zdg | 2aaa15230a | |
zdg | 7894214859 | |
朱浩 | fe41a63b2d | |
朱浩 | cdf12cf213 | |
yangws | 7bb8d2afeb | |
yangws | cfac2086e6 | |
朱浩 | 59ca00d6d1 | |
zdg | b6504e114f | |
lyc | 931ed531ab | |
zhengdegang | 5433e47d0b | |
zdg | eb3778dde2 | |
lyc | a6bda302af | |
zhengdegang | 411ef757e2 | |
zdg | 0201385e75 | |
zdg | ea9af1440e | |
zdg | b4c2751e8c | |
yangws | c5257b760a | |
yangws | 22239090ea | |
zdg | 1d808950b5 | |
zhengdegang | cb0d60b93e | |
zdg | d65af70a34 | |
zdg | 3f4e9c35b0 | |
zhengdegang | a133c322f3 | |
zdg | b5d41050ae | |
朱浩 | 0e5ca5eff2 | |
lyc | eb481e265b | |
zdg | fa77c6cc6b | |
lyc | ff97a2bef6 | |
lyc | 05c567d1cd | |
lyc | 1a6abfaa50 | |
zhengdegang | 2ae200cc9e | |
zdg | 177df96d69 | |
zdg | 571bfc98f7 | |
yangws | b249df2dff | |
yangws | 1871e7e565 | |
lyc | bb56c3fdab | |
lyc | df8f4fcf92 | |
lyc | d6b4ae011d | |
yangws | bf7f740aaf | |
yangws | e6a0859f87 | |
zhengdegang | 3d8dc4320d | |
zdg | 1518d9c3ae | |
lyc | 23878f5843 | |
lyc | 144da0ace9 | |
zhengdegang | 46098aa733 | |
zdg | 13e755bb9a | |
zdg | b5ce949172 | |
zdg | d033c217d6 | |
yangws | edfdf8b9ad | |
yangws | 59be0c07d1 | |
朱浩 | e985c2e7af | |
朱浩 | 0ea628d174 | |
朱浩 | d4982d47c7 | |
yangws | 0ad99e9ac2 | |
yangws | be222a2ba6 | |
lyc | b922219602 | |
lyc | 386c4e09c6 | |
zhengdegang | b738ade9a4 | |
zdg | 6f6d56b37b | |
zdg | c1f81a8e5c | |
lyc | d003ecf8ce | |
lyc | 146784bf26 | |
yangws | 88e63f376c | |
yangws | 99ee438fd7 | |
lyc | 2279bbb904 | |
lyc | b0d969546a | |
lyc | 8ec96996c6 | |
zhengdegang | 968b5d3e43 | |
zdg | c0fd0ae9d3 | |
zdg | 86cd50b8a3 | |
zhengdegang | 9240c055f4 | |
zdg | 6d77d54bc1 | |
zdg | c57f21461a | |
lyc | d669b6ee42 | |
lyc | 13598615c7 | |
zdg | a80a3b006c | |
zdg | a2e72b855b | |
zhangxuelin | 1e0ff00503 | |
zhangxuelin | d30b4a230a | |
zhangxuelin | b8ea091bb5 | |
zdg | 04a03b0c43 | |
zdg | f7ad8d4c71 | |
朱浩 | f38a14bc0b | |
朱浩 | f98fa5a3f3 | |
zdg | 6fb7369ce5 | |
zdg | 49c4c7245a | |
朱浩 | 5f6839058a | |
朱浩 | 0ff0cd42bc | |
朱浩 | 6dfb2d4a8a | |
zhengdegang | 4fd47d2f2f | |
zhangxuelin | 44bec9fab4 | |
zhangxuelin | 56483a9a49 | |
zhengdegang | 4f6c7f157c | |
zdg | 631fcf38f7 | |
zdg | cf477398c9 | |
zdg | e3e704d95d | |
yangws | f8eece2ff6 | |
yangws | 7fc7135d73 | |
朱浩 | 88177d610e | |
zhengdegang | 6bc2579c2e | |
朱浩 | 57b7d3d601 | |
zdg | 75caf13d8b | |
zdg | 7fb98309fb | |
zdg | a3b7248977 | |
zdg | 6ae7c2c4b7 | |
朱浩 | c19631eb89 | |
朱浩 | b8896bf53d | |
朱浩 | 6f5eee4289 | |
朱浩 | aec8e9a21f | |
朱浩 | de909adccb | |
yangws | f7b00b1ccd | |
yangws | c94563fd43 | |
lyc | c1a34c61c9 | |
lyc | a68b2a2805 | |
lyc | 0d1a96b202 | |
yangws | 71fe8a0a8f | |
yangws | b8f95eb20f | |
lyc | 5328607ce1 | |
lyc | a17be49850 | |
yangws | 2a4dac58ac | |
yangws | 0fe264054c | |
lyc | f632bab6b3 | |
lyc | ae52510c7c | |
lyc | 86d5f33119 | |
zhangxuelin | 2ed62802ce | |
zhangxuelin | 2ee5e24e6f | |
lyc | cf3129ed66 | |
lyc | 97e035398c | |
lyc | 6e8c96ce2e | |
zhangxuelin | 3448a029c6 | |
lyc | decfb09eb4 | |
zhangxuelin | 1dce3f6f70 | |
lyc | 2a84455f05 | |
zhangxuelin | d9ae544022 | |
zhangxuelin | b520858f3f | |
zdg | 758a4b09c9 | |
lyc | ba9b381b69 | |
zdg | 716c16928e | |
zdg | 0da2b25586 | |
朱浩 | 6616ac640e | |
朱浩 | f3619817f9 | |
zdg | bb1d5da104 | |
zdg | 69f54a217b | |
lyc | 4754ed641c | |
yangws | c64fbe49e9 | |
yangws | 3c2dbb722a | |
zdg | 1c67ce1b8f | |
yangws | acbd36ca88 | |
yangws | 1e52abc170 | |
yangws | 1a1f20d175 | |
朱浩 | 1aded1d50a | |
lyc | 94ae78bffc | |
lyc | c72d103082 | |
lyc | 22f35a6638 | |
lyc | bf783cf940 | |
lyc | b255e48be5 | |
lyc | 41b0660559 | |
朱浩 | 0964cc0965 | |
朱浩 | 219e4abdc0 | |
朱浩 | c3709bf0c7 | |
朱浩 | e6a06a67b8 | |
朱浩 | ea4afb409f | |
朱浩 | 79055dc1c2 | |
yangws | e3a04c0add | |
yangws | f6bf811ee5 | |
朱浩 | 3b872f371f | |
朱浩 | 7fc04faad1 | |
lyc | d18c47994a | |
lyc | 7b804f9e62 | |
yangws | 62367c13d3 | |
朱浩 | 8f50174595 | |
lyc | bc9c6a3c89 | |
lyc | e2d9b61fbe | |
lyc | bc5a6e961d | |
lyc | 2b5acf272d | |
lyc | 9dda6b934c | |
zhangxuelin | 799dbed676 | |
yangws | 3b52f9acc4 | |
lyc | a1e00ba716 | |
lyc | acc4d7c81e | |
zhangxuelin | f80e7dee2a | |
yangws | 1f9788498a | |
白了个白 | 9ab62f180e | |
yangws | f60fdbafa0 | |
yangws | 776be8eaac | |
朱浩 | 67320f897e | |
朱浩 | 2cdc33d706 | |
朱浩 | f334adfda9 | |
朱浩 | fe26d348fc | |
yangws | 444daa3cec | |
yangws | c7d2eba5bb | |
zhangxuelin | 2bf82dc294 | |
zhangxuelin | cc5c823071 | |
zdg | 8df3871f7d | |
zdg | 0ffa45313b | |
lyc | c4e82017e5 | |
lyc | d4fc68c902 | |
朱浩 | 732e4c9a64 | |
yangws | 6c717ea345 | |
yangws | c4c4bca54a | |
朱浩 | e89ffd4416 | |
lyc | cc1faa7f88 | |
lyc | 0b67ca30f8 | |
zhangxuelin | 7d3007bbf2 | |
zhangxuelin | bf99c4dd00 | |
朱浩 | d690a4ae70 | |
朱浩 | 974aaf3522 | |
lyc | 524eedc451 | |
lyc | 9d38f715a1 | |
朱浩 | b4c9db619e | |
朱浩 | 7cf3487bfb | |
朱浩 | 74275ac327 | |
朱浩 | c29a3d7a77 | |
朱浩 | b8325d336b | |
朱浩 | c2876ff983 | |
zhengdegang | 6035803db1 | |
zdg | f9de8514ed | |
zdg | cc8ea2b043 | |
lyc | 9e0e2a41f2 | |
lyc | 3fcd0cdb21 | |
lyc | 815b2b15cb | |
lyc | eb17167feb | |
朱浩 | ae500c94ce | |
lyc | 258a99bc36 | |
朱浩 | e5845a6714 | |
朱浩 | 1c1ec2be71 | |
朱浩 | 572bdb5fec | |
朱浩 | 7974aeabe4 | |
zhangxuelin | c11b9765e6 | |
lyc | 0e34b6a1e9 | |
lyc | b10be40ddc | |
zhangxuelin | 964e99c186 | |
zhangxuelin | e1e9f171e0 | |
zhangxuelin | a8f9c828d7 | |
朱浩 | c56039270c | |
朱浩 | 32c64d073b | |
lyc | 1498b9bc9f | |
lyc | 9a8d0e61d5 | |
lyc | d4b24f8d71 | |
lyc | ccf4211f44 | |
朱浩 | aaa75df73b | |
lyc | 6ddd172bb9 | |
lyc | 00d23f4b31 | |
朱浩 | 54d9f6d782 | |
朱浩 | 5db876ebfa | |
zhengdegang | 6b1ec46360 | |
zdg | 8fc1339419 | |
zdg | 0c8af75e2a | |
zhengdegang | b8f2eb24e2 | |
zdg | 618618f736 | |
zdg | 43afd575de | |
zhengdegang | 8c2362ff4f | |
zhangxuelin | 4687d62b90 | |
zhangxuelin | 2a78cb40dc | |
zdg | d12b5bb29f | |
zdg | 5430cb8c50 | |
zdg | 6f890843ab | |
朱浩 | bd2024eed2 | |
朱浩 | 9f510187c0 | |
zhangxuelin | dca4eaae91 | |
zhangxuelin | d64122775a | |
zhangxuelin | 29ad68e5ab | |
zdg | 4e2512ed77 | |
zdg | c9d377aa74 | |
zdg | 7221a203e9 | |
朱浩 | 3bcb0a2ef3 | |
朱浩 | 9018abb673 | |
朱浩 | a55a662ce9 | |
朱浩 | 528e7876a9 | |
朱浩 | 82456a7f96 | |
zdg | 7dfa51f5dc | |
lyc | 74b0cf5fdb | |
lyc | df7658a17d | |
zhangxuelin | db496ee154 | |
lyc | 8a9fa83c04 | |
lyc | 9a6f37528c | |
zhangxuelin | a6fff59601 | |
zhangxuelin | 2a670c1447 | |
zhengdegang | d64b469ac8 | |
zdg | 19901d802f | |
zdg | 22a92ee84b | |
zdg | 8d558c47f5 | |
lyc | 9ab5f65409 | |
lyc | 95e9fc528a | |
lyc | e38235fd6b | |
lyc | 26c46e33c7 | |
lyc | ce274237dc | |
lyc | d46d312b37 | |
lyc | fb84977321 | |
zhangxuelin | 1d4cad94c1 | |
zhangxuelin | da78c7e1e8 | |
朱浩 | 2ef129d5c1 | |
朱浩 | 6b8c6c8c7f | |
zhengdegang | fa5e132c2d | |
zdg | 99c6fe85d4 | |
zdg | 05074f3145 | |
lyc | 34b35d8beb | |
lyc | 921ce6ecb0 | |
lyc | 1be862a0f2 | |
lyc | 9ef553f8eb | |
lyc | e53eab0c31 | |
朱浩 | 1a51af93f6 | |
朱浩 | ae4f7d3b49 | |
lyc | 0ba717de6e | |
lyc | 6e29229e95 | |
lyc | df84893509 | |
zhengdegang | f32dd848cc | |
zdg | bb02f92bb2 | |
zdg | dbf6b665a8 | |
朱浩 | 43d75f94dd | |
朱浩 | 62a5339d04 | |
朱浩 | 191ead45cb | |
朱浩 | cac9490256 | |
lyc | d46b01cca2 | |
lyc | 57aa718711 | |
lyc | 0d41a5a62f | |
lyc | 510258361f | |
zdg | ee53207d31 | |
zdg | 24c2540436 | |
zdg | e788174a3a | |
zdg | 89ef820366 | |
朱浩 | 4248fd4504 | |
朱浩 | 241b0d3f24 | |
朱浩 | ede8dfd533 | |
朱浩 | 8f54d17439 | |
朱浩 | 15f6b5dcbd | |
zdg | b4e7867922 | |
zdg | ba64ff931b | |
朱浩 | 955d3a6d7d | |
朱浩 | b7f45bbd33 | |
yangws | 8f3925f57a | |
yangws | 370396e2b8 | |
lyc | 0eb047b3f2 | |
lyc | 9f5115f4a3 | |
lyc | 12332348b0 | |
yangws | 51943f0595 | |
yangws | 9edc6d6e2b | |
yangws | 2a9b39f5e9 | |
yangws | 04eca3435e | |
yangws | 1e79807a4b | |
yangws | 594f380785 | |
yangws | 817ea8790e | |
zhengdegang | b317471e66 | |
zdg | f35c6a97b7 | |
zdg | 45770d15c1 | |
zdg | 604a20b9b0 | |
lyc | d5165fa3b0 | |
lyc | b65cd95558 | |
lyc | d6c302fc04 | |
lyc | 277a5ec873 | |
lyc | 77c1ca7d50 | |
lyc | 2565f86260 | |
zdg | b2b95db8fb | |
zhangxuelin | d7ecb2d547 | |
lyc | 1f0b02ea61 | |
lyc | 71a380f9e0 | |
朱浩 | f057320625 | |
朱浩 | 2f4d48a8c0 | |
zhengdegang | 529197c9dc | |
zdg | 5ac36dd569 | |
zdg | 8b7e64765b | |
zdg | 4d17465c24 | |
zhangxuelin | 3097491df2 | |
朱浩 | 3ad5871505 | |
朱浩 | 71aff5d1f8 | |
朱浩 | 14428f2706 | |
lyc | e3016b5aff | |
lyc | 1da1db8378 | |
zdg | dd577385af | |
yangws | fb607c6f83 | |
yangws | 52dfb52161 | |
lyc | ef77069329 | |
lyc | 0cfc352c5a | |
lyc | 9fa06cfabb | |
朱浩 | 7d4f9bdbf9 | |
朱浩 | 67bc54765c | |
yangws | 0d53cabbed | |
yangws | e6a08c857a | |
yangws | 4e6e11ac2c | |
yangws | a857912c83 | |
zhangxuelin | 0d2fe7655f | |
朱浩 | 51c8c79b17 | |
朱浩 | 53e34dc515 | |
lyc | 18be8cc96a | |
lyc | f6e5511e94 | |
zhangxuelin | b3bf366134 | |
zhangxuelin | 705dbf3832 | |
朱浩 | 03ce0df516 | |
yangws | ccf16176c6 | |
zhangxuelin | ca61976291 | |
zhangxuelin | af6236a751 | |
yangws | 828abbbcb7 | |
zdg | 6c6c08abf6 | |
lyc | 7b87b5a6e3 | |
lyc | 80ee3c0f11 | |
lyc | f2ff4ac7d6 | |
lyc | 479131ef21 | |
朱浩 | c25978d30e | |
zhangxuelin | 1004567103 | |
lyc | b85bb9b9cc | |
lyc | 3ae303322a | |
lyc | df68c47cd3 | |
zdg | beca8c21b6 | |
zdg | e6a854b1a2 | |
zdg | d50d4722aa | |
yangws | e6431c6ac6 | |
yangws | d2f57fd18e | |
zhangxuelin | 81fa22690e | |
zhangxuelin | 22a678940d | |
lyc | 03bcade299 | |
lyc | 8c7468ef7f | |
lyc | 7e3978d532 | |
zhangxuelin | 925db8b743 | |
zhangxuelin | baa41d00eb | |
lyc | 01d972f18e | |
lyc | c0c3324d9d | |
zhangxuelin | 4e2ac7c92e | |
lyc | daaddfaaf2 | |
lyc | 5fea7e094d | |
朱浩 | 9f9a611f89 | |
lyc | e221bedb81 | |
lyc | 0ec1a7327a | |
zdg | fe21b676a8 | |
zdg | d2a2510e09 | |
lyc | ed9f3d4189 | |
lyc | af20ff4931 | |
朱浩 | 1b45ab4579 | |
朱浩 | 0a641fee06 | |
lyc | 08c365b0ed | |
lyc | 212d5be4d4 | |
朱浩 | e032d8514e | |
朱浩 | 415a4c17c1 | |
朱浩 | 88e306e8a2 | |
朱浩 | e5c55cefda | |
lyc | 78e666d6c1 | |
lyc | 580ab2ee5b | |
lyc | cda6e3e2c4 | |
zhangxuelin | fd7686af9a | |
zhangxuelin | ae86b1aa60 | |
zdg | 79d36ea6ba | |
lyc | 75595562db | |
lyc | ea5a069f85 | |
lyc | bf9e7c96ff | |
朱浩 | d0bf9c0768 | |
朱浩 | eff5688e42 | |
朱浩 | 4e9c93da15 | |
lyc | e6da6ef65f | |
zdg | 666c4becd2 | |
lyc | a618032d25 | |
朱浩 | a25be335e6 | |
朱浩 | 62248dfafa | |
朱浩 | 2926b4bd63 | |
lyc | ac5cafe1e8 | |
lyc | 0086ce4236 | |
朱浩 | af941a22b7 | |
朱浩 | 4dc180a26f | |
lyc | 3487cabc02 | |
lyc | 5712e77a29 | |
朱浩 | 7106d75964 | |
朱浩 | 4c635e9fe3 | |
lyc | 4a5fb04362 | |
lyc | d91f08d398 | |
朱浩 | 5afa31b8c3 | |
朱浩 | c8f1047124 | |
朱浩 | e1fc883870 | |
lyc | c81b74b9de | |
lyc | 2fbc3e272b | |
lyc | 125962b859 | |
zdg | 7782de699f | |
zdg | df87aafca4 | |
lyc | 5f05ad8bea | |
lyc | 3dc478e724 | |
lyc | d72d0ae956 | |
lyc | cefb6ae5a7 | |
lyc | 7b09c8ec81 | |
lyc | de1e0c5a2e | |
baigl | 954f43d8b3 |
|
@ -7,7 +7,10 @@ VITE_APP_ENV = 'development'
|
|||
# AIx融合数字管理系统/开发环境
|
||||
VITE_APP_BASE_API = '/dev-api'
|
||||
|
||||
VITE_APP_UPLOAD_API = 'http://192.168.2.52:7863'
|
||||
VITE_APP_DOMAIN = 'file.ysaix.com'
|
||||
|
||||
VITE_APP_UPLOAD_API = 'https://file.ysaix.com:7868/prod-api'
|
||||
#VITE_APP_UPLOAD_API = 'http://192.168.2.52:7863'
|
||||
|
||||
VITE_APP_RES_FILE_PATH = 'https://file.ysaix.com:7868/src/assets/textbook/booktxt/'
|
||||
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
# 页面标题
|
||||
VITE_APP_TITLE = 文枢课堂
|
||||
|
||||
# 生产环境配置
|
||||
VITE_APP_ENV = 'production'
|
||||
|
||||
# AIx融合数字管理系统/生产环境
|
||||
VITE_APP_BASE_API = 'https://prev.ysaix.com:7868/prod-api'
|
||||
|
||||
VITE_APP_DOMAIN = 'prev.ysaix.com'
|
||||
|
||||
VITE_APP_UPLOAD_API = 'https://prev.ysaix.com:7868/prod-api'
|
||||
|
||||
# 是否在打包时开启压缩,支持 gzip 和 brotli
|
||||
VITE_BUILD_COMPRESS = gzip
|
||||
|
||||
VITE_APP_RES_FILE_PATH = 'https://prev.ysaix.com:7868/src/assets/textbook/booktxt/'
|
||||
|
||||
VITE_APP_BUILD_BASE_PATH = 'https://prev.ysaix.com:7868/'
|
|
@ -1,17 +1,19 @@
|
|||
# 页面标题
|
||||
VITE_APP_TITLE = AIx数字平台
|
||||
VITE_APP_TITLE = AIX智慧课堂
|
||||
|
||||
# 生产环境配置
|
||||
VITE_APP_ENV = 'production'
|
||||
|
||||
# AIx融合数字管理系统/生产环境
|
||||
VITE_APP_BASE_API = 'https://file.ysaix.com:7868/prod-api'
|
||||
VITE_APP_BASE_API = 'https://prev.ysaix.com:7868/prod-api'
|
||||
|
||||
VITE_APP_UPLOAD_API = 'https://file.ysaix.com:7868/prod-api'
|
||||
VITE_APP_DOMAIN = 'prev.ysaix.com'
|
||||
|
||||
VITE_APP_UPLOAD_API = 'https://prev.ysaix.com:7868/prod-api'
|
||||
|
||||
# 是否在打包时开启压缩,支持 gzip 和 brotli
|
||||
VITE_BUILD_COMPRESS = gzip
|
||||
|
||||
VITE_APP_RES_FILE_PATH = 'https://file.ysaix.com:7868/src/assets/textbook/booktxt/'
|
||||
VITE_APP_RES_FILE_PATH = 'https://prev.ysaix.com:7868/src/assets/textbook/booktxt/'
|
||||
|
||||
VITE_APP_BUILD_BASE_PATH = 'https://file.ysaix.com:7868/'
|
||||
VITE_APP_BUILD_BASE_PATH = 'https://prev.ysaix.com:7868/'
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
# 页面标题
|
||||
VITE_APP_TITLE = AIx数字平台(测试版)
|
||||
|
||||
# 生产环境配置
|
||||
VITE_APP_ENV = 'production'
|
||||
|
||||
# AIx融合数字管理系统/生产环境
|
||||
VITE_APP_BASE_API = 'https://file.ysaix.com:7868/prod-api'
|
||||
|
||||
VITE_APP_DOMAIN = 'file.ysaix.com'
|
||||
|
||||
VITE_APP_UPLOAD_API = 'https://file.ysaix.com:7868/prod-api'
|
||||
|
||||
# 是否在打包时开启压缩,支持 gzip 和 brotli
|
||||
VITE_BUILD_COMPRESS = gzip
|
||||
|
||||
VITE_APP_RES_FILE_PATH = 'https://file.ysaix.com:7868/src/assets/textbook/booktxt/'
|
||||
|
||||
VITE_APP_BUILD_BASE_PATH = 'https://file.ysaix.com:7868/'
|
|
@ -10,6 +10,7 @@ module.exports = {
|
|||
],
|
||||
rules: {
|
||||
'vue/require-default-prop': 'off',
|
||||
'vue/multi-word-component-names': 'off'
|
||||
'vue/multi-word-component-names': 'off',
|
||||
'prettier/prettier': 'off'
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
provider: generic
|
||||
url: https://example.com/auto-updates
|
||||
url: http://localhost:3000/
|
||||
updaterCacheDirName: electron-app-updater
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
appId: com.electron.app
|
||||
productName: 文枢课堂
|
||||
directories:
|
||||
output: dist
|
||||
buildResources: build
|
||||
win:
|
||||
executableName: 文枢课堂
|
||||
icon: resources/logo2.ico
|
||||
files:
|
||||
- '!**/.vscode/*'
|
||||
- '!src/*'
|
||||
- '!electron.vite.config.{js,ts,mjs,cjs}'
|
||||
- '!{.eslintignore,.eslintrc.cjs,.prettierignore,.prettierrc.yaml,dev-app-update.yml,CHANGELOG.md,README.md}'
|
||||
- '!{.env,.env.*,.npmrc,pnpm-lock.yaml}'
|
||||
asarUnpack:
|
||||
- resources/**
|
||||
nsis:
|
||||
oneClick: false
|
||||
allowToChangeInstallationDirectory: true
|
||||
artifactName: ${name}-${version}-setup.${ext}
|
||||
shortcutName: ${productName}
|
||||
uninstallDisplayName: ${productName}
|
||||
createDesktopShortcut: always
|
||||
mac:
|
||||
entitlementsInherit: build/entitlements.mac.plist
|
||||
extendInfo:
|
||||
- NSCameraUsageDescription: Application requests access to the device's camera.
|
||||
- NSMicrophoneUsageDescription: Application requests access to the device's microphone.
|
||||
- NSDocumentsFolderUsageDescription: Application requests access to the user's Documents folder.
|
||||
- NSDownloadsFolderUsageDescription: Application requests access to the user's Downloads folder.
|
||||
notarize: false
|
||||
dmg:
|
||||
artifactName: ${name}-${version}.${ext}
|
||||
linux:
|
||||
target:
|
||||
- AppImage
|
||||
- snap
|
||||
- deb
|
||||
maintainer: electronjs.org
|
||||
category: Utility
|
||||
appImage:
|
||||
artifactName: ${name}-${version}.${ext}
|
||||
npmRebuild: false
|
||||
publish:
|
||||
provider: generic
|
||||
url: https://prev.ysaix.com:7868/src/assets/smarttalk/
|
||||
electronDownload:
|
||||
mirror: https://npmmirror.com/mirrors/electron/
|
||||
# 额外依赖打包到输出目录
|
||||
extraFiles:
|
||||
- from: ./node_modules/im_electron_sdk/lib/
|
||||
to: ./resources
|
||||
filter:
|
||||
- '**/*'
|
|
@ -0,0 +1,54 @@
|
|||
appId: com.electron.app
|
||||
productName: AIx
|
||||
directories:
|
||||
output: dist
|
||||
buildResources: build
|
||||
win:
|
||||
executableName: AIx
|
||||
icon: resources/logo2.ico
|
||||
files:
|
||||
- '!**/.vscode/*'
|
||||
- '!src/*'
|
||||
- '!electron.vite.config.{js,ts,mjs,cjs}'
|
||||
- '!{.eslintignore,.eslintrc.cjs,.prettierignore,.prettierrc.yaml,dev-app-update.yml,CHANGELOG.md,README.md}'
|
||||
- '!{.env,.env.*,.npmrc,pnpm-lock.yaml}'
|
||||
asarUnpack:
|
||||
- resources/**
|
||||
nsis:
|
||||
oneClick: false
|
||||
allowToChangeInstallationDirectory: true
|
||||
artifactName: ${name}-${version}-setup.${ext}
|
||||
shortcutName: ${productName}
|
||||
uninstallDisplayName: ${productName}
|
||||
createDesktopShortcut: always
|
||||
mac:
|
||||
entitlementsInherit: build/entitlements.mac.plist
|
||||
extendInfo:
|
||||
- NSCameraUsageDescription: Application requests access to the device's camera.
|
||||
- NSMicrophoneUsageDescription: Application requests access to the device's microphone.
|
||||
- NSDocumentsFolderUsageDescription: Application requests access to the user's Documents folder.
|
||||
- NSDownloadsFolderUsageDescription: Application requests access to the user's Downloads folder.
|
||||
notarize: false
|
||||
dmg:
|
||||
artifactName: ${name}-${version}.${ext}
|
||||
linux:
|
||||
target:
|
||||
- AppImage
|
||||
- snap
|
||||
- deb
|
||||
maintainer: electronjs.org
|
||||
category: Utility
|
||||
appImage:
|
||||
artifactName: ${name}-${version}.${ext}
|
||||
npmRebuild: false
|
||||
publish:
|
||||
provider: generic
|
||||
url: https://prev.ysaix.com:7868/src/assets/smarttalk/
|
||||
electronDownload:
|
||||
mirror: https://npmmirror.com/mirrors/electron/
|
||||
# 额外依赖打包到输出目录
|
||||
extraFiles:
|
||||
- from: ./node_modules/im_electron_sdk/lib/
|
||||
to: ./resources
|
||||
filter:
|
||||
- '**/*'
|
|
@ -0,0 +1,53 @@
|
|||
appId: com.electron.app
|
||||
productName: AIx
|
||||
directories:
|
||||
buildResources: build
|
||||
files:
|
||||
- '!**/.vscode/*'
|
||||
- '!src/*'
|
||||
- '!electron.vite.config.{js,ts,mjs,cjs}'
|
||||
- '!{.eslintignore,.eslintrc.cjs,.prettierignore,.prettierrc.yaml,dev-app-update.yml,CHANGELOG.md,README.md}'
|
||||
- '!{.env,.env.*,.npmrc,pnpm-lock.yaml}'
|
||||
asarUnpack:
|
||||
- resources/**
|
||||
win:
|
||||
executableName: AIx
|
||||
icon: resources/logo2.ico
|
||||
nsis:
|
||||
oneClick: false
|
||||
allowToChangeInstallationDirectory: true
|
||||
artifactName: ${name}-${version}-setup.${ext}
|
||||
shortcutName: ${productName}
|
||||
uninstallDisplayName: ${productName}
|
||||
createDesktopShortcut: always
|
||||
mac:
|
||||
entitlementsInherit: build/entitlements.mac.plist
|
||||
extendInfo:
|
||||
- NSCameraUsageDescription: Application requests access to the device's camera.
|
||||
- NSMicrophoneUsageDescription: Application requests access to the device's microphone.
|
||||
- NSDocumentsFolderUsageDescription: Application requests access to the user's Documents folder.
|
||||
- NSDownloadsFolderUsageDescription: Application requests access to the user's Downloads folder.
|
||||
notarize: false
|
||||
dmg:
|
||||
artifactName: ${name}-${version}.${ext}
|
||||
linux:
|
||||
target:
|
||||
- AppImage
|
||||
- snap
|
||||
- deb
|
||||
maintainer: electronjs.org
|
||||
category: Utility
|
||||
appImage:
|
||||
artifactName: ${name}-${version}.${ext}
|
||||
npmRebuild: false
|
||||
publish:
|
||||
provider: generic
|
||||
url: http://localhost:3000
|
||||
electronDownload:
|
||||
mirror: https://npmmirror.com/mirrors/electron/
|
||||
# 额外依赖打包到输出目录
|
||||
extraFiles:
|
||||
- from: ./node_modules/im_electron_sdk/lib/
|
||||
to: ./resources
|
||||
filter:
|
||||
- '**/*'
|
|
@ -12,7 +12,8 @@ asarUnpack:
|
|||
- resources/**
|
||||
win:
|
||||
executableName: AIx
|
||||
nsis:
|
||||
icon: resources/logo2.ico
|
||||
nsis:
|
||||
oneClick: false
|
||||
allowToChangeInstallationDirectory: true
|
||||
artifactName: ${name}-${version}-setup.${ext}
|
||||
|
@ -41,6 +42,12 @@ appImage:
|
|||
npmRebuild: false
|
||||
publish:
|
||||
provider: generic
|
||||
url: https://example.com/auto-updates
|
||||
url: https://file.ysaix.com:7868/src/assets/smarttalk/
|
||||
electronDownload:
|
||||
mirror: https://npmmirror.com/mirrors/electron/
|
||||
# 额外依赖打包到输出目录
|
||||
extraFiles:
|
||||
- from: ./node_modules/im_electron_sdk/lib/
|
||||
to: ./resources
|
||||
filter:
|
||||
- '**/*'
|
||||
|
|
|
@ -3,7 +3,14 @@ import path from 'path'
|
|||
import { defineConfig, externalizeDepsPlugin } from 'electron-vite'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
import WindiCSS from "vite-plugin-windicss"
|
||||
|
||||
/*import electron from 'vite-plugin-electron'
|
||||
plugins: [electron({
|
||||
main: {
|
||||
builderOptions: {
|
||||
asar: false
|
||||
}
|
||||
}
|
||||
})],*/
|
||||
export default defineConfig({
|
||||
main: {
|
||||
plugins: [externalizeDepsPlugin()]
|
||||
|
@ -17,21 +24,19 @@ export default defineConfig({
|
|||
// '@': resolve('./src/renderer/src'),
|
||||
// '@': path.resolve(__dirname, 'src/renderer/src'),
|
||||
'@': path.join(__dirname, './src/renderer/src'),
|
||||
'@root': path.join(__dirname, '.'),
|
||||
|
||||
}
|
||||
},
|
||||
server: {
|
||||
proxy: {
|
||||
'/dev-api': {
|
||||
// target: 'http://27.128.240.72:7865',
|
||||
target: 'http://192.168.2.52:7863',
|
||||
target: 'http://27.128.240.72:7865',
|
||||
// target: 'http://36.134.181.164:7863',
|
||||
// target: 'http://192.168.2.52:7863',
|
||||
changeOrigin: true,
|
||||
rewrite: (p) => p.replace(/^\/dev-api/, '')
|
||||
},
|
||||
'/profile': {
|
||||
target: 'http://192.168.2.52:7863',
|
||||
ws: true,
|
||||
changeOrigin: true
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
plugins: [vue(), WindiCSS()],
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
"paths": {
|
||||
"@/*":[
|
||||
"src/renderer/src/*"
|
||||
]
|
||||
],
|
||||
"@root/*":["./*"]
|
||||
}
|
||||
},
|
||||
"exclude": [
|
||||
|
|
36
package.json
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "electron-app",
|
||||
"version": "1.0.0",
|
||||
"description": "An Electron application with Vue",
|
||||
"name": "aix-win",
|
||||
"version": "2.0.6",
|
||||
"description": "",
|
||||
"main": "./out/main/index.js",
|
||||
"author": "example.com",
|
||||
"homepage": "https://electron-vite.org",
|
||||
|
@ -13,25 +13,49 @@
|
|||
"build": "electron-vite build",
|
||||
"postinstall": "electron-builder install-app-deps",
|
||||
"build:unpack": "npm run build && electron-builder --dir",
|
||||
"build:win": "npm run build && electron-builder --win",
|
||||
"build:dev": "npm run build && electron-builder --win --config ./electron-builder-test.yml",
|
||||
"build:test": "electron-vite build --mode test && electron-builder --win --config ./electron-builder.yml",
|
||||
"build:prod": "electron-vite build --mode production && electron-builder --win --config ./electron-builder-prod.yml",
|
||||
"build:lt": "electron-vite build --mode lt && electron-builder --win --config ./electron-builder-lt.yml",
|
||||
"build:mac": "npm run build && electron-builder --mac",
|
||||
"build:linux": "npm run build && electron-builder --linux"
|
||||
},
|
||||
"dependencies": {
|
||||
"@electron-toolkit/preload": "^3.0.1",
|
||||
"@electron-toolkit/utils": "^3.0.0",
|
||||
"@electron/remote": "^2.1.2",
|
||||
"@element-plus/icons-vue": "^2.3.1",
|
||||
"@vitejs/plugin-vue-jsx": "^4.0.0",
|
||||
"@vue-office/docx": "^1.6.2",
|
||||
"@vue-office/excel": "^1.7.11",
|
||||
"@vue-office/pdf": "^2.0.2",
|
||||
"@vueuse/core": "^10.11.0",
|
||||
"circular-json": "^0.5.9",
|
||||
"cropperjs": "^1.6.2",
|
||||
"crypto-js": "^4.2.0",
|
||||
"echarts": "^5.5.1",
|
||||
"electron-dl-manager": "^3.0.0",
|
||||
"electron-log": "^5.1.7",
|
||||
"electron-store": "8.0.0",
|
||||
"electron-updater": "^6.1.7",
|
||||
"element-china-area-data": "^6.1.0",
|
||||
"element-plus": "^2.7.6",
|
||||
"fabric": "^5.3.0",
|
||||
"im_electron_sdk": "^8.0.5904",
|
||||
"js-cookie": "^3.0.5",
|
||||
"jsencrypt": "^3.3.2",
|
||||
"jsondiffpatch": "0.6.0",
|
||||
"lodash": "^4.17.21",
|
||||
"node-addon-api": "^8.1.0",
|
||||
"pdfjs-dist": "4.4.168",
|
||||
"pinia": "^2.1.7",
|
||||
"pinia-plugin-persistedstate": "^3.2.1",
|
||||
"vue-cropper": "^1.0.3",
|
||||
"vue-router": "^4.4.0"
|
||||
"spark-md5": "^3.0.2",
|
||||
"vite-plugin-electron": "^0.28.8",
|
||||
"vue-qr": "^4.0.9",
|
||||
"vue-router": "^4.4.0",
|
||||
"xgplayer": "^3.0.19",
|
||||
"xlsx": "^0.18.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@electron-toolkit/eslint-config": "^1.0.2",
|
||||
|
|
After Width: | Height: | Size: 57 KiB |
After Width: | Height: | Size: 48 KiB |
After Width: | Height: | Size: 59 KiB |
After Width: | Height: | Size: 65 KiB |
|
@ -0,0 +1,20 @@
|
|||
/**
|
||||
* @description 腾讯云-即时通讯-sdkID
|
||||
*/
|
||||
// import { ipcMain } from 'electron'
|
||||
// const TimMain = require('im_electron_sdk/dist/main')
|
||||
import TimMain from 'im_electron_sdk/dist/main'
|
||||
// import {TIMErrCode} from 'im_electron_sdk/dist/enumbers'
|
||||
const sdkappidDef = 1600034736 // 可以去腾讯云即时通信IM控制台申请
|
||||
|
||||
// 初始化
|
||||
function init(sdkappid = sdkappidDef) {
|
||||
return new TimMain({sdkappid})
|
||||
}
|
||||
export function initialize(){
|
||||
// ipcMain.handle('im-chat:init', (event, sdkappid) => {
|
||||
// return init(sdkappid)
|
||||
// })
|
||||
return init()
|
||||
}
|
||||
export default { initialize, init }
|
304
src/main/file.js
|
@ -1,16 +1,116 @@
|
|||
import CryptoJS from 'crypto-js'
|
||||
|
||||
import SparkMD5 from 'spark-md5'
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
import { ElectronDownloadManager } from 'electron-dl-manager'
|
||||
import { dialog } from 'electron'
|
||||
import axios from 'axios'
|
||||
const uploadUrl = import.meta.env.VITE_APP_UPLOAD_API + '/smarttalk/file/upload'
|
||||
const asyncUploadUrl = import.meta.env.VITE_APP_UPLOAD_API + '/smarttalk/file/asyncUpload'
|
||||
const manager = new ElectronDownloadManager()
|
||||
export default async function ({ app, shell, BrowserWindow, ipcMain }) {
|
||||
const userDataPath = app.getPath('userData')
|
||||
const appRootFilePath = userDataPath + '\\selfFile\\'
|
||||
const appTempFilePath = userDataPath + '\\tempFile\\'
|
||||
let Spark = new SparkMD5.ArrayBuffer()
|
||||
|
||||
ipcMain.on('upload-file-change', (e, { id, fileNewName, cookie, fileType }) => {
|
||||
let filePath = appRootFilePath + fileNewName
|
||||
//执行更新,上传文件
|
||||
let formData = new FormData()
|
||||
formData.append('id', id)
|
||||
uploadFileByFS({
|
||||
url: asyncUploadUrl,
|
||||
path: filePath,
|
||||
name: fileNewName,
|
||||
cookie,
|
||||
fileType,
|
||||
formData,
|
||||
success: (response) => {
|
||||
e.reply('upload-file-change-success' + fileNewName, {
|
||||
data: response.data,
|
||||
md5: formData.md5
|
||||
})
|
||||
},
|
||||
error: (err) => {
|
||||
console.error('Error uploading file:', err)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
/*监听文件改变,如果有改变则返回触发*/
|
||||
ipcMain.on('listen-file-change', (e, { id, fileNewName, md5, cookie, fileType }) => {
|
||||
let filePath = appRootFilePath + fileNewName
|
||||
let uploadId = null
|
||||
let isOn = false
|
||||
let lastMTime = fs.statSync(filePath).mtime.getTime()
|
||||
console.log(lastMTime)
|
||||
setInterval(() => {
|
||||
getFileMsg(filePath).then((msg) => {
|
||||
if (msg !== lastMTime) {
|
||||
lastMTime = msg
|
||||
if (uploadId) {
|
||||
clearTimeout(uploadId)
|
||||
}
|
||||
if (isOn === false) {
|
||||
console.log(fileNewName)
|
||||
e.reply('listen-file-change-on' + fileNewName)
|
||||
isOn = true
|
||||
}
|
||||
//倒数十秒提交更改,十秒之内有继续修改则重置倒数
|
||||
uploadId = setTimeout(() => {
|
||||
console.log(223)
|
||||
//执行更新,上传文件
|
||||
let formData = new FormData()
|
||||
formData.append('id', id)
|
||||
uploadFileByFS({
|
||||
url: asyncUploadUrl,
|
||||
path: filePath,
|
||||
name: fileNewName,
|
||||
cookie,
|
||||
fileType,
|
||||
formData,
|
||||
success: (response) => {
|
||||
e.reply('listen-file-change-success' + fileNewName, {
|
||||
data: response.data,
|
||||
md5: formData.md5
|
||||
})
|
||||
clearTimeout(uploadId)
|
||||
isOn = false
|
||||
},
|
||||
error: (err) => {
|
||||
console.error('Error uploading file:', err)
|
||||
}
|
||||
})
|
||||
}, 5000)
|
||||
}
|
||||
})
|
||||
}, 1000)
|
||||
})
|
||||
|
||||
function getFileMsg(path) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const stats = fs.statSync(path)
|
||||
return resolve(stats.mtime.getTime())
|
||||
})
|
||||
}
|
||||
|
||||
function getFileMD5(path) {
|
||||
return new Promise((resolve, reject) => {
|
||||
fs.readFile(path, (err, dataFile) => {
|
||||
if (err) {
|
||||
reject(err)
|
||||
return console.error(err)
|
||||
}
|
||||
Spark.append(dataFile)
|
||||
let md5 = Spark.end()
|
||||
resolve(md5)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/*
|
||||
* 判断是否有本地文件
|
||||
* */
|
||||
ipcMain.on('is-have-local-file', (e, fileNewName) => {
|
||||
let filePath = appRootFilePath + fileNewName
|
||||
fs.access(filePath, fs.constants.F_OK, (err) => {
|
||||
|
@ -21,14 +121,44 @@ export default async function ({ app, shell, BrowserWindow, ipcMain }) {
|
|||
e.reply('is-have-local-file-reply' + fileNewName, true)
|
||||
})
|
||||
})
|
||||
|
||||
/*
|
||||
* 判断是需要同步本地文件
|
||||
* */
|
||||
ipcMain.on('is-async-local-file', (e, { fileNewName, lastModifyTime, md5 }) => {
|
||||
let filePath = appRootFilePath + fileNewName
|
||||
fs.access(filePath, fs.constants.F_OK, (err) => {
|
||||
if (err) {
|
||||
e.reply('is-async-local-file-reply' + fileNewName, { isAsync: true, type: 'down' })
|
||||
return
|
||||
}
|
||||
getFileMsg(filePath).then((msg) => {
|
||||
let time = new Date(lastModifyTime).getTime();
|
||||
msg = parseInt(msg/1000)*1000;
|
||||
if (msg == time) {
|
||||
e.reply('is-async-local-file-reply' + fileNewName, { isAsync: false, type: '' })
|
||||
} else {
|
||||
const stats = fs.statSync(filePath)
|
||||
//如果线上时间大于线下时间,就需要从线上下载,否则则需要上传
|
||||
if (time > stats.mtime.getTime()) {
|
||||
e.reply('is-async-local-file-reply' + fileNewName, { isAsync: true, type: 'down' })
|
||||
} else if (time < stats.mtime.getTime()) {
|
||||
e.reply('is-async-local-file-reply' + fileNewName, { isAsync: true, type: 'upload' })
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
//默认浏览器打开url
|
||||
ipcMain.on('open-url-browser', (e, url) => {
|
||||
shell.openPath(url)
|
||||
})
|
||||
|
||||
//使用默认应用打开本地文件
|
||||
ipcMain.on('open-path-app', (e, destination) => {
|
||||
let path = appRootFilePath + destination
|
||||
shell.openExternal(path).catch((error) => {
|
||||
shell.openPath(path).catch((error) => {
|
||||
console.log(error)
|
||||
})
|
||||
})
|
||||
|
@ -40,65 +170,75 @@ export default async function ({ app, shell, BrowserWindow, ipcMain }) {
|
|||
})
|
||||
})
|
||||
|
||||
//复制文件
|
||||
//导出文件
|
||||
ipcMain.on('export-file-default', (e, list) => {
|
||||
exportFile(list, (res) => {
|
||||
e.reply('export-file-default-reply', res)
|
||||
})
|
||||
})
|
||||
|
||||
function getFileMD5(file) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const fileReader = new FileReader()
|
||||
fileReader.onload = (e) => {
|
||||
const buffer = e.target.result
|
||||
let md5 = CryptoJS.MD5(buffer).toString()
|
||||
resolve(md5)
|
||||
function uploadFileByFS({ url, path, name, cookie, fileType, formData, success, error }) {
|
||||
fs.readFile(path, (err, data) => {
|
||||
if (err) {
|
||||
return console.error(err)
|
||||
}
|
||||
fileReader.readAsArrayBuffer(file)
|
||||
// 配置上传的请求
|
||||
const config = {
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data', // 或者其他适合上传文件的Content-Type
|
||||
Authorization: 'Bearer ' + cookie
|
||||
}
|
||||
}
|
||||
Spark.append(data)
|
||||
let md5 = Spark.end()
|
||||
// 使用axios上传文件
|
||||
let file = new File([data], name, {
|
||||
type: fileType
|
||||
})
|
||||
const stats = fs.statSync(path)
|
||||
formData.append('file', file)
|
||||
formData.append('md5', md5)
|
||||
formData.append('lastModifyTime', stats.mtime.toLocaleString())
|
||||
axios
|
||||
.post(url, formData, config)
|
||||
.then((response) => {
|
||||
success(response)
|
||||
})
|
||||
.catch((errorMsg) => {
|
||||
error(errorMsg)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/*创建新的ppt文件*/
|
||||
ipcMain.on('creat-file-default', (e, { name, uploadData, cookie }) => {
|
||||
createFolder('tempFile').then(() => {
|
||||
let path = appTempFilePath + name
|
||||
let path = appTempFilePath + name.replace(/[\\/:*?"<>|]/, '')
|
||||
console.log(path)
|
||||
fs.writeFileSync(path, '', 'utf-8')
|
||||
// 读取文件
|
||||
fs.readFile(path, (err, data) => {
|
||||
if (err) {
|
||||
return console.error(err)
|
||||
let fileType = 'application/vnd.openxmlformats-officedocument.presentationml.presentation'
|
||||
let formData = new FormData()
|
||||
for (let key in uploadData) {
|
||||
if (Object.prototype.hasOwnProperty.call(uploadData, key)) {
|
||||
// 检查是否是对象自身的属性
|
||||
formData.append(key, uploadData[key])
|
||||
}
|
||||
// 配置上传的请求
|
||||
const config = {
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data', // 或者其他适合上传文件的Content-Type
|
||||
Authorization: 'Bearer ' + cookie
|
||||
}
|
||||
}
|
||||
formData.append('fileFlag', '课件')
|
||||
uploadFileByFS({
|
||||
url: uploadUrl,
|
||||
path,
|
||||
name,
|
||||
cookie,
|
||||
fileType,
|
||||
formData,
|
||||
success: (response) => {
|
||||
e.reply('creat-file-default-reply', response.data)
|
||||
console.log('File uploaded successfully:', response.data)
|
||||
},
|
||||
error: (err) => {
|
||||
console.error('Error uploading file:', err)
|
||||
}
|
||||
let md5 = CryptoJS.MD5(data).toString()
|
||||
let formData = new FormData()
|
||||
// 使用axios上传文件
|
||||
let file = new File([data], name, {
|
||||
type: 'application/vnd.openxmlformats-officedocument.presentationml.presentation'
|
||||
})
|
||||
formData.append('file', file)
|
||||
formData.append('md5',md5)
|
||||
|
||||
for (let key in uploadData) {
|
||||
if (uploadData.hasOwnProperty(key)) { // 检查是否是对象自身的属性
|
||||
formData.append(key,uploadData[key])
|
||||
}
|
||||
}
|
||||
formData.append("fileFlag","教案")
|
||||
axios
|
||||
.post(uploadUrl, formData, config)
|
||||
.then((response) => {
|
||||
e.reply('creat-file-default-reply', response.data)
|
||||
console.log('File uploaded successfully:', response.data)
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Error uploading file:', error)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -110,37 +250,43 @@ export default async function ({ app, shell, BrowserWindow, ipcMain }) {
|
|||
|
||||
//下载文件
|
||||
ipcMain.on('download-file-default', (e, { url, fileName }) => {
|
||||
createFolder('selfFile').then(async () => {
|
||||
const browserWindow = BrowserWindow.fromId(e.sender.id)
|
||||
const id = await manager.download({
|
||||
window: browserWindow,
|
||||
url: url,
|
||||
saveAsFilename: fileName,
|
||||
directory: appRootFilePath,
|
||||
callbacks: {
|
||||
onDownloadStarted: async ({ id, item, webContents }) => {
|
||||
// Do something with the download id
|
||||
},
|
||||
onDownloadProgress: async ({ id, item, percentCompleted }) => {},
|
||||
onDownloadCompleted: async ({ id, item }) => {
|
||||
console.log('完成')
|
||||
e.reply('download-file-default' + fileName, true)
|
||||
},
|
||||
onDownloadCancelled: async () => {
|
||||
console.log('取消')
|
||||
e.reply('download-file-default' + fileName, false)
|
||||
},
|
||||
onDownloadInterrupted: async () => {
|
||||
console.log('中断')
|
||||
e.reply('download-file-default' + fileName, false)
|
||||
},
|
||||
onError: (err, data) => {
|
||||
console.log(err.toString())
|
||||
e.reply('download-file-default' + fileName, false)
|
||||
createFolder('selfFile')
|
||||
.then(async () => {
|
||||
const browserWindow = BrowserWindow.getFocusedWindow()
|
||||
const id = await manager.download({
|
||||
window: browserWindow,
|
||||
url: url,
|
||||
saveAsFilename: fileName,
|
||||
directory: appRootFilePath,
|
||||
callbacks: {
|
||||
onDownloadStarted: async ({ id, item, webContents }) => {
|
||||
// Do something with the download id
|
||||
},
|
||||
onDownloadProgress: async ({ id, item, percentCompleted }) => {
|
||||
e.reply('download-file-default-prog' + fileName, percentCompleted)
|
||||
},
|
||||
onDownloadCompleted: async ({ id, item }) => {
|
||||
console.log('完成')
|
||||
e.reply('download-file-default' + fileName, true)
|
||||
},
|
||||
onDownloadCancelled: async () => {
|
||||
console.log('取消')
|
||||
e.reply('download-file-default' + fileName, false)
|
||||
},
|
||||
onDownloadInterrupted: async () => {
|
||||
console.log('中断')
|
||||
e.reply('download-file-default' + fileName, false)
|
||||
},
|
||||
onError: (err, data) => {
|
||||
console.log(err.toString())
|
||||
e.reply('download-file-default' + fileName, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
.catch((error) => {
|
||||
e.reply('download-file-default' + fileName, false)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
/**另存为...
|
||||
|
@ -191,6 +337,7 @@ export default async function ({ app, shell, BrowserWindow, ipcMain }) {
|
|||
})
|
||||
})
|
||||
|
||||
/*导出文件*/
|
||||
function exportFile(list, callback) {
|
||||
let win = BrowserWindow.getFocusedWindow()
|
||||
//通过扩展名识别文件类型
|
||||
|
@ -220,10 +367,12 @@ export default async function ({ app, shell, BrowserWindow, ipcMain }) {
|
|||
})
|
||||
}
|
||||
|
||||
/*文件是否已经存在*/
|
||||
function isHaveFile(path) {
|
||||
return fs.existsSync(path)
|
||||
}
|
||||
|
||||
/*判断是否已经存在这个名字的文件,如果已经存在则递增导出*/
|
||||
function filterCopyFile(path, index = 0) {
|
||||
if (isHaveFile(path) === true) {
|
||||
index++
|
||||
|
@ -234,6 +383,7 @@ export default async function ({ app, shell, BrowserWindow, ipcMain }) {
|
|||
}
|
||||
}
|
||||
|
||||
/*复制文件*/
|
||||
function copyRelFile(source, destination, callback) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const readStream = fs.createReadStream(source)
|
||||
|
@ -256,6 +406,7 @@ export default async function ({ app, shell, BrowserWindow, ipcMain }) {
|
|||
})
|
||||
}
|
||||
|
||||
/*复制文件*/
|
||||
function copyFile(source, destination, callback) {
|
||||
let path = appRootFilePath + destination
|
||||
createFolder('selfFile').then(() => {
|
||||
|
@ -276,6 +427,7 @@ export default async function ({ app, shell, BrowserWindow, ipcMain }) {
|
|||
})
|
||||
}
|
||||
|
||||
/*创建文件夹*/
|
||||
function createFolder(folderName) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const folderPath = path.join(userDataPath, folderName)
|
||||
|
|
|
@ -1,72 +1,253 @@
|
|||
import { app, shell, BrowserWindow, ipcMain } from 'electron'
|
||||
import { app, shell, BrowserWindow, ipcMain, session, BrowserView } from 'electron'
|
||||
import { join } from 'path'
|
||||
import { electronApp, optimizer, is } from '@electron-toolkit/utils'
|
||||
import icon from '../../resources/icon.png?asset'
|
||||
import File from './file'
|
||||
import Logger from './logger' // 日志封装
|
||||
import chat from './chat' // chat封装
|
||||
import Store from './store' // Store封装
|
||||
import updateInit from './update'
|
||||
// 代理 electron/remote
|
||||
// 第一步:引入remote
|
||||
import remote from '@electron/remote/main'
|
||||
// 第二步: 初始化remote
|
||||
remote.initialize()
|
||||
// 日志配置-初始化(日志直接绑定到console上)
|
||||
if(!is.dev) Logger.initialize()
|
||||
// 持久化数据-初始化
|
||||
Store.initialize()
|
||||
|
||||
File({ app, shell, BrowserWindow, ipcMain })
|
||||
function createWindow() {
|
||||
// Create the browser window.
|
||||
const mainWindow = new BrowserWindow({
|
||||
process.env['ELECTRON_DISABLE_SECURITY_WARNINGS'] = 'true'
|
||||
let mainWindow, loginWindow
|
||||
|
||||
const additionalData = {myKey:'ys_axi_smarttalk'}
|
||||
const gotTheLock = app.requestSingleInstanceLock(additionalData)
|
||||
|
||||
if(!gotTheLock){
|
||||
app.quit()
|
||||
}else{
|
||||
app.on('second-instance',(event,commandLine,workingDirectory,additionalData)=>{
|
||||
//输入从第二个实例中接收到的数据
|
||||
console.log(additionalData)
|
||||
//有人试图运行第二个实例,我们应该关注我们的窗口
|
||||
if(mainWindow){
|
||||
if(mainWindow.isMinimized()) mainWindow.restore()
|
||||
mainWindow.focus()
|
||||
}
|
||||
if(loginWindow){
|
||||
if(loginWindow.isMinimized()) loginWindow.restore()
|
||||
loginWindow.focus()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
//登录窗口
|
||||
function createLoginWindow() {
|
||||
if (loginWindow) return
|
||||
loginWindow = new BrowserWindow({
|
||||
width: 888,
|
||||
height: 520,
|
||||
show: false,
|
||||
frame: false,
|
||||
autoHideMenuBar: true,
|
||||
maximizable: false,
|
||||
resizable: false,
|
||||
icon: join(__dirname, '../../resources/logo2.ico'),
|
||||
...(process.platform === 'linux' ? { icon } : {}),
|
||||
webPreferences: {
|
||||
defaultEncoding: 'utf-8',
|
||||
preload: join(__dirname, '../preload/index.js'),
|
||||
sandbox: false,
|
||||
nodeIntegration: true
|
||||
nodeIntegration: true,
|
||||
contextIsolation: false // 沙箱取消
|
||||
}
|
||||
})
|
||||
loginWindow.type = 'login' // 唯一标识
|
||||
// handleUpdate(loginWindow,ipcMain)
|
||||
// const loginURL = is.dev ? `http://localhost:5173/#/login` : `file://${__dirname}/index.html/#/login`
|
||||
// loginWindow.loadURL(loginURL)
|
||||
if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
|
||||
loginWindow.loadURL('http://localhost:5173/#/login')
|
||||
} else {
|
||||
loginWindow.loadFile(join(__dirname, '../renderer/index.html'), { hash: 'login' })
|
||||
updateInit(loginWindow)
|
||||
}
|
||||
|
||||
// loginWindow.webContents.openDevTools()
|
||||
loginWindow.once('ready-to-show', () => {
|
||||
loginWindow.show()
|
||||
})
|
||||
|
||||
loginWindow.on('closed', () => {
|
||||
loginWindow = null
|
||||
})
|
||||
|
||||
remote.enable(loginWindow.webContents)
|
||||
}
|
||||
//主窗口
|
||||
function createMainWindow() {
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 1200,
|
||||
minWidth: 1350,
|
||||
height: 700,
|
||||
show: false,
|
||||
frame: false, // 无边框
|
||||
autoHideMenuBar: true,
|
||||
maximizable: false,
|
||||
icon: join(__dirname, '../../resources/logo2.ico'),
|
||||
...(process.platform === 'linux' ? { icon } : {}),
|
||||
webPreferences: {
|
||||
defaultEncoding: 'utf-8',
|
||||
preload: join(__dirname, '../preload/index.js'),
|
||||
sandbox: false,
|
||||
// nodeIntegration: true,
|
||||
nodeIntegration: true, // nodeApi调用
|
||||
contextIsolation: false // 沙箱取消
|
||||
// webSecurity: false // 跨域关闭
|
||||
}
|
||||
})
|
||||
mainWindow.type = 'main' // 唯一标识
|
||||
mainWindow.on('ready-to-show', () => {
|
||||
mainWindow.show()
|
||||
})
|
||||
|
||||
|
||||
|
||||
mainWindow.on('closed', () => {
|
||||
setTimeout(() => {
|
||||
// 延迟销毁
|
||||
mainWindow = null
|
||||
}, 1000)
|
||||
// app.quit() // 主窗口关闭-结束所有进程
|
||||
})
|
||||
mainWindow.webContents.setWindowOpenHandler((details) => {
|
||||
shell.openExternal(details.url)
|
||||
return { action: 'deny' }
|
||||
})
|
||||
mainWindow.webContents.openDevTools()
|
||||
// HMR for renderer base on electron-vite cli.
|
||||
// Load the remote URL for development or the local html file for production.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
|
||||
mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL'])
|
||||
|
||||
// mainWindow.loadURL('https://file.ysaix.com:7868/')
|
||||
|
||||
} else {
|
||||
// mainWindow.loadURL('https://file.ysaix.com:7868/')
|
||||
mainWindow.loadFile(join(__dirname, '../renderer/index.html'))
|
||||
}
|
||||
// mainWindow.setAlwaysOnTop(true, "screen-saver") // 将窗口设置为顶层窗口
|
||||
// mainWindow.setVisibleOnAllWorkspaces(true) // 如果窗口在所有工作区都可见
|
||||
// 第三步: 开启remote服务
|
||||
remote.enable(mainWindow.webContents)
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(() => {
|
||||
// Set app user model id for windows
|
||||
// 打开外部链接窗口
|
||||
let linkWin = {}
|
||||
async function createLinkWin(data) {
|
||||
if (linkWin[data.key]) return
|
||||
|
||||
linkWin[data.key] = new BrowserWindow({
|
||||
show: false,
|
||||
frame: true,
|
||||
maximizable: true,
|
||||
autoHideMenuBar: true,
|
||||
...(process.platform === 'linux' ? { icon } : {}),
|
||||
webPreferences: {
|
||||
defaultEncoding: 'utf-8',
|
||||
sandbox: false,
|
||||
nodeIntegration: true,
|
||||
worldSafeExecuteJavaScript: true,
|
||||
contextIsolation: true
|
||||
}
|
||||
})
|
||||
linkWin[data.key].type = 'link'+data.key // 唯一标识
|
||||
|
||||
let cookieDetails = { ...data.cookieData }
|
||||
await linkWin[data.key].webContents.session.cookies
|
||||
.set(cookieDetails)
|
||||
.then(() => {})
|
||||
.catch((error) => {})
|
||||
data.fullPath = data.fullPath.replaceAll('//', '/')
|
||||
if (data.fullPath.indexOf('?') !== -1) {
|
||||
data.fullPath += '&urlSource=smarttalk&t' + Date.now()
|
||||
}else {
|
||||
data.fullPath += '?urlSource=smarttalk&t' + Date.now()
|
||||
}
|
||||
linkWin[data.key].loadURL(data.fullPath)
|
||||
|
||||
linkWin[data.key].once('ready-to-show', () => {
|
||||
linkWin[data.key].show()
|
||||
linkWin[data.key].maximize()
|
||||
})
|
||||
linkWin[data.key].on('closed', () => {
|
||||
linkWin[data.key] = null
|
||||
delete linkWin[data.key]
|
||||
})
|
||||
}
|
||||
|
||||
// 初始化完成
|
||||
app.on('ready', () => {
|
||||
appWatchError() // 监听app错误
|
||||
process.env.LANG = 'en_US.UTF-8'
|
||||
// 设置应用程序用户模型标识符
|
||||
electronApp.setAppUserModelId('com.electron')
|
||||
|
||||
// Default open or close DevTools by F12 in development
|
||||
// and ignore CommandOrControl + R in production.
|
||||
// see https://github.com/alex8088/electron-toolkit/tree/master/packages/utils
|
||||
//一个新的browserWindow 被创建时触发
|
||||
app.on('browser-window-created', (_, window) => {
|
||||
optimizer.watchWindowShortcuts(window)
|
||||
})
|
||||
|
||||
//窗口 最大、最小、关闭
|
||||
ipcMain.on('minimize-window', () => {
|
||||
if (loginWindow) {
|
||||
loginWindow.minimize()
|
||||
}
|
||||
if (mainWindow) {
|
||||
mainWindow.minimize()
|
||||
}
|
||||
})
|
||||
|
||||
ipcMain.on('maximize-window', () => {
|
||||
mainWindow.isMaximized() ? mainWindow.unmaximize() : mainWindow.maximize()
|
||||
})
|
||||
|
||||
createWindow()
|
||||
ipcMain.on('close-window', () => {
|
||||
if (loginWindow) {
|
||||
loginWindow.destroy()
|
||||
}
|
||||
if (mainWindow) {
|
||||
mainWindow.close() // 先发出这个关闭指令
|
||||
setTimeout(() => {
|
||||
//
|
||||
mainWindow.destroy()
|
||||
}, 200)
|
||||
}
|
||||
})
|
||||
|
||||
// 打开主窗口
|
||||
ipcMain.on('openMainWindow', () => {
|
||||
if (!mainWindow) {
|
||||
createMainWindow()
|
||||
}
|
||||
loginWindow.destroy()
|
||||
loginWindow = null
|
||||
})
|
||||
// 打开登录窗口
|
||||
ipcMain.on('openLoginWindow', () => {
|
||||
if (!loginWindow) {
|
||||
createLoginWindow()
|
||||
}
|
||||
mainWindow.destroy()
|
||||
mainWindow = null
|
||||
loginWindow.show()
|
||||
loginWindow.focus()
|
||||
})
|
||||
|
||||
//打开作业窗口
|
||||
ipcMain.on('openWindow', (e, data) => {
|
||||
createLinkWin(data)
|
||||
})
|
||||
// zdg: 消息监听
|
||||
handleAll()
|
||||
// 打开-登录窗口
|
||||
createLoginWindow()
|
||||
|
||||
app.on('activate', function () {
|
||||
// On macOS it's common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (BrowserWindow.getAllWindows().length === 0) createWindow()
|
||||
if (BrowserWindow.getAllWindows().length === 0) createLoginWindow()
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -79,34 +260,62 @@ app.on('window-all-closed', () => {
|
|||
}
|
||||
})
|
||||
|
||||
ipcMain.on('toggle-top', (event) => {
|
||||
const win = BrowserWindow.getFocusedWindow();
|
||||
const isAlwaysOnTop = win.isAlwaysOnTop();
|
||||
win.setAlwaysOnTop(!isAlwaysOnTop);
|
||||
event.sender.send('top-status-changed', !isAlwaysOnTop);
|
||||
})
|
||||
// 监听全局事件
|
||||
function handleAll() {
|
||||
const chatInstance = chat.initialize() // im-chat 实例
|
||||
// 新窗口创建-监听
|
||||
ipcMain.on('new-window', (e, data) => {
|
||||
const { id, type } = data
|
||||
const win = BrowserWindow.fromId(id)
|
||||
win.type = type // 绑定独立标识
|
||||
remote.enable(win.webContents) // 开启远程服务
|
||||
chatInstance.enable(win.webContents) // 开启im-chat
|
||||
})
|
||||
// 用于监听-状态管理变化-同步所有窗口
|
||||
ipcMain.handle('pinia-state-change', (e, storeName, jsonStr) => {
|
||||
for(const curWin of BrowserWindow.getAllWindows()){
|
||||
const id = curWin.webContents.id
|
||||
const bool = id !== e.sender.id && !curWin.isDestroyed()
|
||||
if (bool) { // 除了消息发送窗口和销毁的窗口 其他都发送
|
||||
curWin.webContents.send('pinia-state-set', storeName, jsonStr)
|
||||
}
|
||||
}
|
||||
})
|
||||
// 用于监听-状态管理变化-初始同步
|
||||
ipcMain.handle('pinia-state-init', (e, wid, storeName, jsonStr) => {
|
||||
// console.log('pinia-state-init', jsonStr)
|
||||
const win = BrowserWindow.fromId(wid)
|
||||
win.webContents.send('pinia-state-set', storeName, jsonStr)
|
||||
})
|
||||
}
|
||||
|
||||
// app 崩溃监听器
|
||||
function appWatchError() {
|
||||
// 渲染进程崩溃
|
||||
app.on('renderer-process-crashed', (event, webContents, killed) => {
|
||||
console.error(
|
||||
`APP-ERROR:renderer-process-crashed; event: ${JSON.stringify(event)}; webContents:${JSON.stringify(
|
||||
webContents
|
||||
)}; killed:${JSON.stringify(killed)}`
|
||||
)
|
||||
})
|
||||
|
||||
ipcMain.on('minimize-window', () => {
|
||||
const win = BrowserWindow.getFocusedWindow();
|
||||
win.minimize();
|
||||
});
|
||||
// GPU进程崩溃
|
||||
app.on('gpu-process-crashed', (event, killed) => {
|
||||
console.error(`APP-ERROR:gpu-process-crashed; event: ${JSON.stringify(event)}; killed: ${JSON.stringify(killed)}`)
|
||||
})
|
||||
|
||||
ipcMain.on('maximize-window', () => {
|
||||
const win = BrowserWindow.getFocusedWindow();
|
||||
if (win.isMaximized()) {
|
||||
win.unmaximize();
|
||||
} else {
|
||||
win.maximize();
|
||||
}
|
||||
});
|
||||
// 渲染进程结束
|
||||
app.on('render-process-gone', async (event, webContents, details) => {
|
||||
console.error(
|
||||
`APP-ERROR:render-process-gone; event: ${JSON.stringify(event)}; webContents:${JSON.stringify(
|
||||
webContents
|
||||
)}; details:${JSON.stringify(details)}`
|
||||
)
|
||||
})
|
||||
|
||||
ipcMain.on('close-window', () => {
|
||||
const win = BrowserWindow.getFocusedWindow();
|
||||
win.close();
|
||||
});
|
||||
ipcMain.on('set-winsize', (e, {x, y})=>{
|
||||
const win = BrowserWindow.getFocusedWindow();
|
||||
win.setSize(x,y);
|
||||
win.center()
|
||||
})
|
||||
// 子进程结束
|
||||
app.on('child-process-gone', async (event, details) => {
|
||||
console.error(`APP-ERROR:child-process-gone; event: ${JSON.stringify(event)}; details:${JSON.stringify(details)}`)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
/**
|
||||
* @description 日志配置
|
||||
* @author zdg
|
||||
* @date 2021-07-05 14:07:01
|
||||
*/
|
||||
// import log from 'electron-log'
|
||||
import log from 'electron-log/main'
|
||||
import { app } from 'electron'
|
||||
import path from 'path'
|
||||
|
||||
// 关闭控制台打印
|
||||
// 日志控制台等级,默认值:false
|
||||
log.transports.console.level = false
|
||||
// log.transports.console.level = 'info'
|
||||
// 日志文件等级,默认值:false
|
||||
log.transports.file.level = 'info'
|
||||
// 日志文件名,默认:main.log
|
||||
// log.transports.file.fileName = 'main.log';
|
||||
// 日志大小,默认:1048576(1M),达到最大上限后,备份文件并重命名为:main.old.log,有且仅有一个备份文件
|
||||
log.transports.file.maxSize = 10 * 1024 * 1024; // 文件最大不超过 10M
|
||||
// 自定义日志文件滚动策略
|
||||
log.transports.file.rollSize = 10 * 1024 * 1024; // 10MB
|
||||
// 日志格式,默认:[{y}-{m}-{d} {h}:{i}:{s}.{ms}] [{level}]{scope} {text}
|
||||
log.transports.file.format = '[{y}-{m}-{d} {h}:{i}:{s}.{ms}] [{level}]{scope} {text}'
|
||||
let date = new Date()
|
||||
let dateStr = date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate()
|
||||
// 文件位置及命名方式
|
||||
// 默认位置为:C:\Users\[user]\AppData\Roaming\[appname]\electron_log\
|
||||
// 文件名为:年-月-日.log
|
||||
// 自定义文件保存位置为安装目录下 \log\年-月-日.log
|
||||
// log.transports.file.resolvePathFn = () => 'logs\\' + dateStr+ '.log';
|
||||
log.transports.file.resolvePathFn = () => path.join(app.getPath('userData'), `logs/${dateStr}.log`)
|
||||
|
||||
// 有六个日志级别error, warn, info, verbose, debug, silly。默认是silly
|
||||
export const logger = {
|
||||
error: (...args) => log.error(...args),
|
||||
warn: (...args) => log.warn(...args),
|
||||
info: (...args) => log.info(...args),
|
||||
verbose: (...args) => log.verbose(...args),
|
||||
debug: (...args) => log.debug(...args),
|
||||
silly: (...args) => log.silly(...args)
|
||||
}
|
||||
export function initialize(bool = true, type = 'all') {
|
||||
log.initialize() // 为渲染器进行初始化
|
||||
if (bool) { // 是否替换默认的console
|
||||
if (type == 'all') Object.assign(console, log.functions)
|
||||
else { // 替换指定类型
|
||||
console[type] = log[type]
|
||||
}
|
||||
}
|
||||
}
|
||||
export default { initialize }
|
|
@ -0,0 +1,61 @@
|
|||
/**
|
||||
* @description 解决 主进程|渲染进程 数据共享
|
||||
*/
|
||||
import Store from 'electron-store' // 持久化存储
|
||||
|
||||
// 设置ipc与渲染器通信
|
||||
Store.initRenderer()
|
||||
|
||||
// 默认共享数据
|
||||
const defaultData = {
|
||||
session: { // 缓存(临时sessionStorage)
|
||||
model: 'select', // 悬浮球-当前模式
|
||||
showBoardAll: false, // 全屏画板-是否显示
|
||||
isPdfWin: false, // pdf窗口是否打开
|
||||
isToolWin: false, // 工具窗口是否打开
|
||||
curSubjectNode: {
|
||||
data: {}, // 当前教材节点 (包含当前教材 单元)
|
||||
querySearch: {} // 查询资源所需参数
|
||||
}
|
||||
},
|
||||
local: { // 本地(永久localStorage)
|
||||
},
|
||||
}
|
||||
|
||||
// 初始化
|
||||
export function initialize(){
|
||||
// 缓存数据-sessionStore
|
||||
const sessionStore = new Store({
|
||||
name: 'session-store', // 存储文件名
|
||||
fileExtension: 'ini', // 文件后缀名
|
||||
encryptionKey: 'BvPLmgCC4DSIG0KkTec5', // 数据加密-防止用户直接改配置
|
||||
beforeEachMigration: (store, context) => { // 版本迁移回调
|
||||
console.log(`[session-store] 迁移从 ${context.fromVersion} → ${context.toVersion}`);
|
||||
},
|
||||
migrations: { // 版本变化
|
||||
'0.0.0': store => {
|
||||
// store.set('debugPhase', true);
|
||||
}
|
||||
}
|
||||
})
|
||||
sessionStore.clear() // 先清除-所有缓存数据
|
||||
sessionStore.set(defaultData.session) // 初始化-默认数据
|
||||
|
||||
// 缓存数据-localStore
|
||||
const localStore = new Store({
|
||||
name: 'local-store', // 存储文件名
|
||||
fileExtension: 'ini', // 文件后缀名
|
||||
encryptionKey: '6CyoHQmUaPmLzvVsh', // 数据加密-防止用户直接改配置
|
||||
beforeEachMigration: (store, context) => { // 版本迁移回调
|
||||
console.log(`[local-store] 迁移从 ${context.fromVersion} → ${context.toVersion}`);
|
||||
},
|
||||
migrations: { // 版本变化
|
||||
'0.0.0': store => {
|
||||
// store.set('debugPhase', true);
|
||||
}
|
||||
}
|
||||
})
|
||||
localStore.set(defaultData.local) // 初始化-默认数据
|
||||
return {sessionStore, localStore}
|
||||
}
|
||||
export default { initialize }
|
|
@ -0,0 +1,66 @@
|
|||
import { dialog } from 'electron'
|
||||
import logger from 'electron-log'
|
||||
const updateURL = 'http://27.128.240.72:3000/zhuhao/AIx_Smarttalk/releases/tag/V1.0.0%28%E6%B5%8B%E8%AF%95%E7%89%88%29/'
|
||||
|
||||
// 主进程中的更新检查
|
||||
const { autoUpdater } = require('electron-updater')
|
||||
|
||||
const updateInit = (win) => {
|
||||
logger.info('进来了')
|
||||
// 检查更新
|
||||
autoUpdater.checkForUpdates()
|
||||
// 自动下载
|
||||
autoUpdater.autoDownload = false
|
||||
// 设置版本更新服务器地址
|
||||
// autoUpdater.setFeedURL(updateURL)
|
||||
|
||||
//监听更新事件
|
||||
autoUpdater.on('update-available', (info) => {
|
||||
logger.info('发现新版本')
|
||||
dialog
|
||||
.showMessageBox(win,{
|
||||
type: 'info',
|
||||
title: '新版本可用',
|
||||
message: '有一个可用的新版本,要更新吗',
|
||||
buttons: ['是', '否']
|
||||
})
|
||||
.then((result) => {
|
||||
if (result.response === 0) {
|
||||
// 用户选择更新,触发下载和安装
|
||||
autoUpdater.downloadUpdate()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
// 没有新版本
|
||||
autoUpdater.on('update-not-available', () => {
|
||||
logger.info('没有新版本')
|
||||
})
|
||||
|
||||
// 更新发生错误
|
||||
autoUpdater.on('error', () => {
|
||||
logger.error('检查更新失败')
|
||||
})
|
||||
|
||||
// 监听下载进度
|
||||
autoUpdater.on('download-progress', (progressObj) => {
|
||||
win.webContents.send('update-app-progress', progressObj.percent);
|
||||
});
|
||||
|
||||
// 跟新下载完毕
|
||||
autoUpdater.on('update-downloaded', () => {
|
||||
dialog
|
||||
.showMessageBox({
|
||||
type: 'info',
|
||||
title: '更新下载完成',
|
||||
message: '点击确定重启获取最新内容',
|
||||
buttons: ['确定']
|
||||
})
|
||||
.then(() => {
|
||||
// 调用 quitAndInstall 来安装更新
|
||||
autoUpdater.quitAndInstall()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export default updateInit
|
|
@ -1,9 +1,11 @@
|
|||
import { contextBridge } from 'electron'
|
||||
import { electronAPI } from '@electron-toolkit/preload'
|
||||
|
||||
import TimRender from 'im_electron_sdk/dist/renderer' // im渲染部分实例
|
||||
// Custom APIs for renderer
|
||||
const api = {}
|
||||
|
||||
const api = {
|
||||
preloadPath: __dirname, // 当前preload地址
|
||||
getTimRender: () => new TimRender(), // im渲染部分实例
|
||||
}
|
||||
// Use `contextBridge` APIs to expose Electron APIs to
|
||||
// renderer only if context isolation is enabled, otherwise
|
||||
// just add to the DOM global.
|
||||
|
|
|
@ -2,13 +2,13 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Electron</title>
|
||||
<title>%VITE_APP_TITLE%</title>
|
||||
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
|
||||
<!-- <meta
|
||||
http-equiv="Content-Security-Policy"
|
||||
content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:"
|
||||
/> -->
|
||||
<meta http-equiv="Content-Security-Policy" content="connect-src *; default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src * 'self' data: blob:" />
|
||||
<meta http-equiv="Content-Security-Policy" content="connect-src *; default-src 'self'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *;img-src * 'self' data: blob:" />
|
||||
|
||||
</head>
|
||||
|
||||
|
|
After Width: | Height: | Size: 48 KiB |
|
@ -0,0 +1,20 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 创建对话
|
||||
export const createChart = ({ headers, data }) => {
|
||||
return request({
|
||||
url: '/qf/createChart',
|
||||
method: 'post',
|
||||
headers,
|
||||
data,
|
||||
})
|
||||
}
|
||||
// 大模型对话
|
||||
export const sendChart = ({ headers, data }) => {
|
||||
return request({
|
||||
url: '/qf/sendTalk',
|
||||
method: 'post',
|
||||
headers,
|
||||
data,
|
||||
})
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/**
|
||||
* @description: 后端接口api
|
||||
* @author zdg
|
||||
* @date 2023-07-03
|
||||
*/
|
||||
import request from '@/utils/request'
|
||||
// /system/user/txCloudSign
|
||||
export class ApiService {
|
||||
// zdg: 公共请求-处理(可进行特殊处理)
|
||||
static publicHttp(url, data, method, option = {}, type) {
|
||||
method = method || 'get' // 默认GET
|
||||
const config = { url, method }
|
||||
if (!!data) config[method=='get'?'params':'data'] = data
|
||||
if (!!option) Object.assign(config, option)
|
||||
// 特殊格式处理
|
||||
let headers
|
||||
if (type == 'file') headers = { 'Content-Type': 'multipart/form-data' }
|
||||
else if (type == 'json') headers = { 'Content-Type': 'application/json' }
|
||||
else if (type == 'form') headers = { 'Content-Type': 'application/x-www-form-urlencoded' }
|
||||
headers && (config.headers = { ...config.headers, ...headers })
|
||||
return request(config)
|
||||
}
|
||||
}
|
||||
// zdg: 腾讯云-即时通讯
|
||||
export class imChat {
|
||||
// 获取腾讯im-chat appid 签名
|
||||
static getTxCloudSign = data => ApiService.publicHttp('/system/user/txCloudSign', data)
|
||||
}
|
|
@ -0,0 +1,200 @@
|
|||
// 查询evaluation列表
|
||||
import request from '@/utils/request'
|
||||
// 查询班级列表
|
||||
export function listClassmain(query) {
|
||||
return request({
|
||||
url: '/education/classmain/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
// 查询学生列表
|
||||
export function listClassuser(query) {
|
||||
return request({
|
||||
url: '/education/classuser/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
// 新增班级
|
||||
export function addClassmain(data) {
|
||||
return request({
|
||||
url: '/education/classmain',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
// 查询所有学科的列表
|
||||
export function listEvaluation(query) {
|
||||
return request({
|
||||
url: '/education/evaluation/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
// 新增小组
|
||||
export function addClassgroup(data) {
|
||||
return request({
|
||||
url: '/education/classgroup',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
//班级详情
|
||||
export function getClassmain(id) {
|
||||
return request({
|
||||
url: '/education/classmain/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
// 获取小组列表
|
||||
export function listClassgroup(query) {
|
||||
return request({
|
||||
url: '/education/classgroup/new/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
//删除小组
|
||||
export function delClassgroup(id) {
|
||||
return request({
|
||||
url: '/education/classgroup/' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
//查询小组信息
|
||||
export function getClassgroup(id) {
|
||||
return request({
|
||||
url: '/education/classgroup/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
//修改小组信息
|
||||
export function updateClassgroup(data) {
|
||||
return request({
|
||||
url: '/education/classgroup',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
//新增学生
|
||||
export function addStudentmain(data) {
|
||||
return request({
|
||||
url: '/education/studentmain',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
//修改学生信息
|
||||
export function updateStudentmain(data) {
|
||||
return request({
|
||||
url: '/education/studentmain',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
//获取学生信息
|
||||
export function getStudentmain(id) {
|
||||
return request({
|
||||
url: '/education/studentmain/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
//删除学生
|
||||
export function leaveClass(data) {
|
||||
return request({
|
||||
url: '/education/classuser/leaveClass',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
//删除学生所有数据
|
||||
export function removeStudentDataAll(id) {
|
||||
return request({
|
||||
url: '/education/studentmain/removeStudent/' + id,
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
//删除教室
|
||||
export function delClassroom(id) {
|
||||
return request({
|
||||
url: '/education/classroom/' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
//导入学生
|
||||
export function addStudentmainByNameArray(data) {
|
||||
return request({
|
||||
url: '/education/studentmain/addByNameArray',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
//新增课程预约
|
||||
export function addSmartClassReserv(data) {
|
||||
return request({
|
||||
url: '/smarttalk/classReserv/addSmartClassReserv',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
//修改课程预约
|
||||
export function updateSmartClassReserv(data) {
|
||||
return request({
|
||||
url: '/smarttalk/classReserv/updateSmartClassReserv',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
//查询课程预约
|
||||
export function getSelfReserv() {
|
||||
return request({
|
||||
url: '/smarttalk/classReserv/getSelfReserv',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
export function deleteSmartReserv(id) {
|
||||
return request({
|
||||
url: '/smarttalk/classReserv/' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
export function startClass(id, ex3) {
|
||||
const params = {id}
|
||||
!!ex3 && (params.ex3 = ex3)
|
||||
return request({
|
||||
url: '/smarttalk/classReserv/startClass',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
export function endClass(id) {
|
||||
return request({
|
||||
url: '/smarttalk/classReserv/endClass',
|
||||
method: 'get',
|
||||
params: {id}
|
||||
})
|
||||
}
|
||||
/**
|
||||
* @description 获取课堂信息
|
||||
* @param {*} id
|
||||
* @returns
|
||||
*/
|
||||
export function getClassInfo(id) {
|
||||
return request({
|
||||
url: '/smarttalk/classReserv/selectById',
|
||||
method: 'get',
|
||||
params: {id}
|
||||
})
|
||||
}
|
||||
//加入班级
|
||||
export function addClasses(data) {
|
||||
return request({
|
||||
url: '/smarttalk/audit/applyAddClass',
|
||||
method: 'post',
|
||||
data: data,
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
}
|
||||
})
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
// 查询evaluation列表
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询作业列表
|
||||
export function listByDeadDate(query) {
|
||||
return request({
|
||||
url: '/education/classwork/listByDeadDate',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
//多个班级学生作业数据
|
||||
export function listClassworkdataByDeadDate(query) {
|
||||
return request({
|
||||
url: '/education/classworkdata/listByDeadDate',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询classworkdata列表 班级作业列表
|
||||
export function listClassworkdata(query) {
|
||||
return request({
|
||||
url: '/education/classworkdata/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询entpcoursework列表 课程作业列表
|
||||
export function listEntpcoursework(query) {
|
||||
return request({
|
||||
url: '/education/entpcoursework/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询classworkeval列表 课堂作业列表
|
||||
export function listClassworkeval(query) {
|
||||
return request({
|
||||
url: '/education/classworkeval/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 修改classworkeval
|
||||
export function updateClassworkeval(data) {
|
||||
return request({
|
||||
url: '/education/classworkeval',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改classworkdata
|
||||
export function updateClassworkdata(data) {
|
||||
return request({
|
||||
url: '/education/classworkdata',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 新增pdf圈点勾画
|
||||
export const addsmartBookMark = (params) => {
|
||||
return request({
|
||||
url: '/smarttalk/bookMark/addSmartBookMark',
|
||||
method: 'post',
|
||||
data:params
|
||||
})
|
||||
}
|
||||
|
||||
// 修改pdf圈点勾画
|
||||
export const updateSmartBookMarkContent = (params) => {
|
||||
return request({
|
||||
url: '/smarttalk/bookMark/updateSmartBookMarkContent',
|
||||
method: 'post',
|
||||
data:params
|
||||
})
|
||||
}
|
||||
|
||||
// 根据书id获取pdf圈点勾画
|
||||
export const getBookMarkById = (bookId) => {
|
||||
return request({
|
||||
url: '/smarttalk/bookMark/' + bookId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
//根据id删除对应页数
|
||||
export function deleteBookMark(ids) {
|
||||
return request({
|
||||
url: '/smarttalk/bookMark/' + ids,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 查询entpcoursework列表
|
||||
export function listEntpcoursework(query) {
|
||||
return request({
|
||||
url: '/education/entpcoursework/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询entpcoursework详细
|
||||
export function getEntpcoursework(id) {
|
||||
return request({
|
||||
url: '/education/entpcoursework/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增entpcoursework
|
||||
export function addEntpcoursework(data) {
|
||||
return request({
|
||||
url: '/education/entpcoursework',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改entpcoursework
|
||||
export function updateEntpcoursework(data) {
|
||||
return request({
|
||||
url: '/education/entpcoursework',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除entpcoursework
|
||||
export function delEntpcoursework(id) {
|
||||
return request({
|
||||
url: '/education/entpcoursework/' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// xuekubaoapi
|
||||
export function xuekubaoAPI(data) {
|
||||
return request({
|
||||
url: '/education/entpcoursework/xuekubaoapi',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// PPT文件上传
|
||||
export function uploadEntpcourseworkFile(data) {
|
||||
return request({
|
||||
url: '/education/entpcoursework/uploadWord',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 查询entpcoursework列表
|
||||
export function listEntpcourseworkNew(query) {
|
||||
return request({
|
||||
url: '/education/entpcoursework/new/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @desc: 学科网接口api
|
||||
* @return: {*}
|
||||
* @param {*} path 请求路径 /xopqbm/questions(无需全拼, 后端学科网sdk自动处理)
|
||||
* @param {*} method 请求方式 post/get
|
||||
* @param {*} params 请求参数 {key: value,}
|
||||
*/
|
||||
export function xkwAPI(path, method, isPostBody, params) {
|
||||
return request({
|
||||
url: '/xkw/post',
|
||||
method: 'post',
|
||||
data: {
|
||||
path: path,
|
||||
method: method,
|
||||
isPostBody: isPostBody,
|
||||
params: params,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc: 图文识别接口 python_OCR_api
|
||||
* @return: {*}
|
||||
* @param {*} path 请求路径 /ocrApi/data
|
||||
* @param {*} method 请求方式 post
|
||||
* @param {*} params 请求参数 {key: value,}
|
||||
*/
|
||||
export function pyOCRAPI(path) {
|
||||
return request({
|
||||
url: '/ocrApi/data',
|
||||
method: 'post',
|
||||
data: {
|
||||
imageBas64: path,
|
||||
}
|
||||
})
|
||||
}
|
|
@ -0,0 +1,162 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 查询entpcoursefile列表
|
||||
export function listEntpcoursefile(query) {
|
||||
return request({
|
||||
url: '/education/entpcoursefile/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
// zdg:查询entpcoursefile列表-新
|
||||
export function listEntpcoursefileNew(query) {
|
||||
return request({
|
||||
url: '/education/entpcoursefile/new/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
// 查询entpcoursefile详细
|
||||
export function getEntpcoursefile(id) {
|
||||
return request({
|
||||
url: '/education/entpcoursefile/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增entpcoursefile
|
||||
export function addEntpcoursefile(data) {
|
||||
return request({
|
||||
url: '/education/entpcoursefile',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 新增entpcoursefile
|
||||
export function addEntpcoursefileReturnId(data) {
|
||||
return request({
|
||||
url: '/education/entpcoursefile/addReturnId',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// addFromId
|
||||
export function addFromId(fromid, toid, entpid, entpcourseid, edituserid) {
|
||||
return request({
|
||||
url: '/education/entpcoursefile/addFromId/'+fromid+'/'+toid+'/'+entpid+'/'+entpcourseid+'/'+edituserid,
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
||||
// 修改entpcoursefile
|
||||
export function updateEntpcoursefile(data) {
|
||||
return request({
|
||||
url: '/education/entpcoursefile',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
// 新增 修改接口
|
||||
export function updateEntpcoursefileNew(data) {
|
||||
return request({
|
||||
url: '/education/entpcoursefile/newUpdateFile',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// updateFileByIds
|
||||
export function updateFileByIds(data) {
|
||||
return request({
|
||||
url: '/education/entpcoursefile/updateFileByIds',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// updateFileByArray
|
||||
export function updateFileByArray(data) {
|
||||
return request({
|
||||
url: '/education/entpcoursefile/updateFileByArray',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改entpcoursefile
|
||||
export function updateFile2Redis(data) {
|
||||
return request({
|
||||
url: '/education/entpcoursefile/updateFile2Redis',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除entpcoursefile
|
||||
export function delEntpcoursefile(id) {
|
||||
return request({
|
||||
url: '/education/entpcoursefile/' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 保存base64图片,返回url
|
||||
export function saveEntpCourseBase64File(data) {
|
||||
return request({
|
||||
url: '/education/entpcoursefile/saveBase64File',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 文件上传
|
||||
export function saveEntpCourseBase64File2(data) {
|
||||
return request({
|
||||
url: '/education/entpcoursefile/saveBase64File2',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 保存PPT页面预览base64图片,返回url
|
||||
export function savePPTPreviewBase64File(data) {
|
||||
return request({
|
||||
url: '/education/entpcoursefile/savePreviewBase64',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// PPT文件上传
|
||||
export function saveEntpCoursePPT(data) {
|
||||
return request({
|
||||
url: '/education/entpcoursefile/importPPT',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// PPT文件解析
|
||||
export function parsePPT(data) {
|
||||
return request({
|
||||
url: '/education/entpcoursefile/parsePPT',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 修改ppt.slide.index
|
||||
export function updateSlideIndex(data) {
|
||||
return request({
|
||||
url: '/education/entpcoursefile/saveSlideOrder',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
|
@ -9,6 +9,21 @@ export const getSmarttalkPage = (params) => {
|
|||
})
|
||||
}
|
||||
|
||||
export const creatAPT = (params) => {
|
||||
return request({
|
||||
url: '/smarttalk/file/createApt',
|
||||
method: 'post',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
export const getPrepareById = (id) => {
|
||||
return request({
|
||||
url: '/smarttalk/file/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function deleteSmarttalk(id) {
|
||||
return request({
|
||||
url: '/smarttalk/file/' + id,
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
//查询第三方课件的接口
|
||||
import request from '@/utils/request'
|
||||
//获取学科
|
||||
export const getSubjects = (params) => {
|
||||
return request({
|
||||
url: '/smarttalk/cnjy/getSubjects',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
//获取教材版本
|
||||
export const getTextbookVersion = (params) => {
|
||||
return request({
|
||||
url: '/smarttalk/cnjy/getVersions',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
//获得书籍
|
||||
export const getTextbook = (params) => {
|
||||
return request({
|
||||
url: '/smarttalk/cnjy/getBooks',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
//获取书籍章节
|
||||
export const getBook = (params) => {
|
||||
return request({
|
||||
url: '/smarttalk/cnjy/getChapters',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
//获取知识点信息
|
||||
export const getKnowledge = (params) => {
|
||||
return request({
|
||||
url: '/smarttalk/cnjy/getKnowledgePoints',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
//查询列表资源
|
||||
export const getBookList = (params) => {
|
||||
return request({
|
||||
url: '/smarttalk/cnjy/getDocuments',
|
||||
method: 'post',
|
||||
params
|
||||
})
|
||||
}
|
||||
//获取图片路径
|
||||
export const getImgPath = (params) => {
|
||||
return request({
|
||||
url: '/smarttalk/cnjy/getPreview',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -56,4 +56,77 @@ export function getCodeImg() {
|
|||
method: 'get',
|
||||
timeout: 20000
|
||||
})
|
||||
}
|
||||
|
||||
// 注册模块-生成人机验证
|
||||
export function captchaImg(data) {
|
||||
return request({
|
||||
url: '/captchaImg',
|
||||
headers: {
|
||||
isToken: false
|
||||
},
|
||||
method: 'get',
|
||||
params: data
|
||||
})
|
||||
}
|
||||
|
||||
//注册模块-发送验证码
|
||||
export function sendCode(data) {
|
||||
return request({
|
||||
url: '/smarttalk/register/authSendCode',
|
||||
method: 'post',
|
||||
data:data
|
||||
})
|
||||
}
|
||||
|
||||
//注册模块-申请注册
|
||||
export function signIn(data) {
|
||||
return request({
|
||||
url: '/smarttalk/register/authSignIn',
|
||||
method: 'post',
|
||||
data:data
|
||||
})
|
||||
}
|
||||
|
||||
//登录模块-找回密码
|
||||
export function retrievePwd(data) {
|
||||
return request({
|
||||
url: '/smarttalk/register/authRetrievePwd',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
//注册模块-获取学校
|
||||
export function deptTree(data) {
|
||||
return request({
|
||||
url: '/smarttalk/register/authDeptTree',
|
||||
method: 'get',
|
||||
params:data
|
||||
})
|
||||
}
|
||||
// 查询部门详细
|
||||
export function getDept(query) {
|
||||
return request({
|
||||
url: '/system/dept/detail',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询classmain列表
|
||||
export function listClassmain(query) {
|
||||
return request({
|
||||
url: '/education/classmain/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
// 查询evaluation列表
|
||||
export function listEvaluation(query) {
|
||||
return request({
|
||||
url: '/smarttalk/register/authEvaluationList',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
|
@ -9,7 +9,6 @@ export const listEvaluation = (params)=> {
|
|||
})
|
||||
}
|
||||
|
||||
|
||||
export const addFileToPrepare = (params) => {
|
||||
return request({
|
||||
url: '/smarttalk/file/addFileToPrepare',
|
||||
|
@ -17,3 +16,4 @@ export const addFileToPrepare = (params) => {
|
|||
params
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -50,3 +50,9 @@ export function updateUserInfo(data) {
|
|||
data: data
|
||||
})
|
||||
}
|
||||
export function getUserInfo(userId) {
|
||||
return request({
|
||||
url: '/system/user/' + userId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 查询classcourse列表
|
||||
export function listClasscourse(query) {
|
||||
return request({
|
||||
url: '/education/classcourse/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询classcourse详细
|
||||
export function getClasscourse(id) {
|
||||
return request({
|
||||
url: '/education/classcourse/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增classcourse
|
||||
export function addClasscourse(data) {
|
||||
return request({
|
||||
url: '/education/classcourse',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 新增classcourse
|
||||
export function addClasscourseReturnId(data) {
|
||||
return request({
|
||||
url: '/education/classcourse/saveReturnId',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改classcourse
|
||||
export function updateClasscourse(data) {
|
||||
return request({
|
||||
url: '/education/classcourse',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除classcourse
|
||||
export function delClasscourse(id) {
|
||||
return request({
|
||||
url: '/education/classcourse/' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 删除classcourse
|
||||
export function delClasscourseWithData(id) {
|
||||
return request({
|
||||
url: '/education/classcourse/removeData/' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// classcourse开始上课
|
||||
export function startCourseTeaching(id) {
|
||||
return request({
|
||||
url: '/education/classcourse/startCourseTeaching/'+id,
|
||||
method: 'post',
|
||||
})
|
||||
}
|
||||
|
||||
// 老师学生发送新的消息
|
||||
export function sendCourseTeachingMsg(data) {
|
||||
return request({
|
||||
url: '/education/classcourse/sendCourseTeachingMsg',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 老师学生获取新的交互消息
|
||||
export function getCourseTeachingMsg(id) {
|
||||
return request({
|
||||
url: '/education/classcourse/getCourseTeachingMsg/'+id,
|
||||
method: 'post',
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 查询classwork列表
|
||||
export function homeworklist(params) {
|
||||
return request({
|
||||
url: '/education/classwork/list',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// 查询entpcourse列表
|
||||
export function listEntpcourse(query) {
|
||||
return request({
|
||||
url: '/education/entpcourse/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 新增entpcourse
|
||||
export function addEntpcourse(data) {
|
||||
return request({
|
||||
url: '/education/entpcourse',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 布置作业
|
||||
export function saveByClassWorkArray(data) {
|
||||
return request({
|
||||
url: '/education/classwork/saveByClassWorkArray',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除classwork 作业
|
||||
export function delClasswork(id) {
|
||||
return request({
|
||||
url: '/education/classwork/' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增classwork
|
||||
export function addClassworkReturnId(data) {
|
||||
return request({
|
||||
url: '/education/classwork/saveAndReturnId',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 2794390 */
|
||||
src: url('iconfont.woff2?t=1721179711733') format('woff2'),
|
||||
url('iconfont.woff?t=1721179711733') format('woff'),
|
||||
url('iconfont.ttf?t=1721179711733') format('truetype'),
|
||||
url('iconfont.svg?t=1721179711733#iconfont') format('svg');
|
||||
src: url('iconfont.woff2?t=1725847033097') format('woff2'),
|
||||
url('iconfont.woff?t=1725847033097') format('woff'),
|
||||
url('iconfont.ttf?t=1725847033097') format('truetype'),
|
||||
url('iconfont.svg?t=1725847033097#iconfont') format('svg');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
|
@ -14,6 +14,662 @@
|
|||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-aijiqiren:before {
|
||||
content: "\e73c";
|
||||
}
|
||||
|
||||
.icon-saoyisao:before {
|
||||
content: "\e691";
|
||||
}
|
||||
|
||||
.icon-jiaoxuezhiliangfenxi:before {
|
||||
content: "\e690";
|
||||
}
|
||||
|
||||
.icon-jiaoxuejihua:before {
|
||||
content: "\e7e9";
|
||||
}
|
||||
|
||||
.icon-tongji:before {
|
||||
content: "\e68f";
|
||||
}
|
||||
|
||||
.icon-pigai:before {
|
||||
content: "\e68d";
|
||||
}
|
||||
|
||||
.icon-jiaoxuefansi:before {
|
||||
content: "\e6b2";
|
||||
}
|
||||
|
||||
.icon-kaoshi:before {
|
||||
content: "\e68a";
|
||||
}
|
||||
|
||||
.icon-yiwen:before {
|
||||
content: "\e687";
|
||||
}
|
||||
|
||||
.icon-yiwen-01:before {
|
||||
content: "\e688";
|
||||
}
|
||||
|
||||
.icon-yihuo:before {
|
||||
content: "\e689";
|
||||
}
|
||||
|
||||
.icon-a-yiwen:before {
|
||||
content: "\e6b1";
|
||||
}
|
||||
|
||||
.icon-zan:before {
|
||||
content: "\e658";
|
||||
}
|
||||
|
||||
.icon-zan1:before {
|
||||
content: "\e659";
|
||||
}
|
||||
|
||||
.icon-zan2:before {
|
||||
content: "\e65a";
|
||||
}
|
||||
|
||||
.icon-zan3:before {
|
||||
content: "\e65c";
|
||||
}
|
||||
|
||||
.icon-zan4:before {
|
||||
content: "\e67c";
|
||||
}
|
||||
|
||||
.icon-yizan:before {
|
||||
content: "\e67e";
|
||||
}
|
||||
|
||||
.icon-zan5:before {
|
||||
content: "\e67f";
|
||||
}
|
||||
|
||||
.icon-zan-yizan:before {
|
||||
content: "\e680";
|
||||
}
|
||||
|
||||
.icon-zan6:before {
|
||||
content: "\e681";
|
||||
}
|
||||
|
||||
.icon-MBEfenggeduosetubiao-xihuan:before {
|
||||
content: "\e682";
|
||||
}
|
||||
|
||||
.icon-zan7:before {
|
||||
content: "\e683";
|
||||
}
|
||||
|
||||
.icon-zan11:before {
|
||||
content: "\e6ff";
|
||||
}
|
||||
|
||||
.icon-zan8:before {
|
||||
content: "\e684";
|
||||
}
|
||||
|
||||
.icon-dianzan-red:before {
|
||||
content: "\e685";
|
||||
}
|
||||
|
||||
.icon-zan9:before {
|
||||
content: "\e69e";
|
||||
}
|
||||
|
||||
.icon-zanping:before {
|
||||
content: "\100ae";
|
||||
}
|
||||
|
||||
.icon-zan10:before {
|
||||
content: "\e686";
|
||||
}
|
||||
|
||||
.icon-arrangement:before {
|
||||
content: "\e656";
|
||||
}
|
||||
|
||||
.icon-zanwushuju:before {
|
||||
content: "\e655";
|
||||
}
|
||||
|
||||
.icon-xiangzuo:before {
|
||||
content: "\e64d";
|
||||
}
|
||||
|
||||
.icon-kechengziyuan1:before {
|
||||
content: "\e647";
|
||||
}
|
||||
|
||||
.icon-tubiaozhizuomobanyihuifu-:before {
|
||||
content: "\e69d";
|
||||
}
|
||||
|
||||
.icon-window-01:before {
|
||||
content: "\e70b";
|
||||
}
|
||||
|
||||
.icon-chuangkou-chuangkouhua:before {
|
||||
content: "\e64b";
|
||||
}
|
||||
|
||||
.icon-a-lujing13357:before {
|
||||
content: "\e64c";
|
||||
}
|
||||
|
||||
.icon-icon:before {
|
||||
content: "\e640";
|
||||
}
|
||||
|
||||
.icon-ke:before {
|
||||
content: "\e641";
|
||||
}
|
||||
|
||||
.icon-jiaocaixuanze:before {
|
||||
content: "\e642";
|
||||
}
|
||||
|
||||
.icon-organization-framework-line:before {
|
||||
content: "\e9fe";
|
||||
}
|
||||
|
||||
.icon-jiaocai:before {
|
||||
content: "\e67b";
|
||||
}
|
||||
|
||||
.icon-zaixiankaoshi:before {
|
||||
content: "\e643";
|
||||
}
|
||||
|
||||
.icon-mubiaohuizhi:before {
|
||||
content: "\e652";
|
||||
}
|
||||
|
||||
.icon-tupushujuyuan:before {
|
||||
content: "\e653";
|
||||
}
|
||||
|
||||
.icon-mubiao:before {
|
||||
content: "\e723";
|
||||
}
|
||||
|
||||
.icon-zhishitupu:before {
|
||||
content: "\e644";
|
||||
}
|
||||
|
||||
.icon-tupu:before {
|
||||
content: "\f48c";
|
||||
}
|
||||
|
||||
.icon-zhongwenwenxian:before {
|
||||
content: "\e645";
|
||||
}
|
||||
|
||||
.icon-tupu1:before {
|
||||
content: "\e952";
|
||||
}
|
||||
|
||||
.icon-kuangjia:before {
|
||||
content: "\e6ea";
|
||||
}
|
||||
|
||||
.icon-wenxian:before {
|
||||
content: "\e7b6";
|
||||
}
|
||||
|
||||
.icon-tupu-01:before {
|
||||
content: "\e679";
|
||||
}
|
||||
|
||||
.icon-tupu2:before {
|
||||
content: "\e69c";
|
||||
}
|
||||
|
||||
.icon-tupu3:before {
|
||||
content: "\e6a7";
|
||||
}
|
||||
|
||||
.icon-zuzhikuangjia:before {
|
||||
content: "\e646";
|
||||
}
|
||||
|
||||
.icon-tupu4:before {
|
||||
content: "\e6d5";
|
||||
}
|
||||
|
||||
.icon-a-kaoshi1:before {
|
||||
content: "\eb13";
|
||||
}
|
||||
|
||||
.icon-fankui:before {
|
||||
content: "\e738";
|
||||
}
|
||||
|
||||
.icon-tiku:before {
|
||||
content: "\e621";
|
||||
}
|
||||
|
||||
.icon-ldc-position:before {
|
||||
content: "\e63a";
|
||||
}
|
||||
|
||||
.icon-sucai:before {
|
||||
content: "\e620";
|
||||
}
|
||||
|
||||
.icon-pengyou:before {
|
||||
content: "\e61a";
|
||||
}
|
||||
|
||||
.icon-zuoye:before {
|
||||
content: "\e61c";
|
||||
}
|
||||
|
||||
.icon-jiaoxuefenxi:before {
|
||||
content: "\e605";
|
||||
}
|
||||
|
||||
.icon-wenjianjia:before {
|
||||
content: "\ec17";
|
||||
}
|
||||
|
||||
.icon-jiaoxueyanxiu:before {
|
||||
content: "\e60d";
|
||||
}
|
||||
|
||||
.icon-jiaoxuesheji:before {
|
||||
content: "\e606";
|
||||
}
|
||||
|
||||
.icon-zhuanyeziyuanku:before {
|
||||
content: "\e651";
|
||||
}
|
||||
|
||||
.icon-pengyouquan:before {
|
||||
content: "\e616";
|
||||
}
|
||||
|
||||
.icon-dangqianhuihua:before {
|
||||
content: "\e675";
|
||||
}
|
||||
|
||||
.icon-yanjiushi:before {
|
||||
content: "\e607";
|
||||
}
|
||||
|
||||
.icon-gongzuotai:before {
|
||||
content: "\e676";
|
||||
}
|
||||
|
||||
.icon-lunwen:before {
|
||||
content: "\e60e";
|
||||
}
|
||||
|
||||
.icon-decheng_xianshangxuexi:before {
|
||||
content: "\e624";
|
||||
}
|
||||
|
||||
.icon-jitibeike-:before {
|
||||
content: "\e65b";
|
||||
}
|
||||
|
||||
.icon-keti:before {
|
||||
content: "\e6fe";
|
||||
}
|
||||
|
||||
.icon-pengyouquan1:before {
|
||||
content: "\e635";
|
||||
}
|
||||
|
||||
.icon-beike1:before {
|
||||
content: "\e61b";
|
||||
}
|
||||
|
||||
.icon-fenxiang:before {
|
||||
content: "\e611";
|
||||
}
|
||||
|
||||
.icon-zhucetianjiahaoyou:before {
|
||||
content: "\e8ca";
|
||||
}
|
||||
|
||||
.icon-duoqudaojicheng:before {
|
||||
content: "\e696";
|
||||
}
|
||||
|
||||
.icon-yewukaizhan:before {
|
||||
content: "\e612";
|
||||
}
|
||||
|
||||
.icon-fankui1:before {
|
||||
content: "\e6fa";
|
||||
}
|
||||
|
||||
.icon-shezhi:before {
|
||||
content: "\e614";
|
||||
}
|
||||
|
||||
.icon-chayue:before {
|
||||
content: "\e617";
|
||||
}
|
||||
|
||||
.icon-baogao:before {
|
||||
content: "\e630";
|
||||
}
|
||||
|
||||
.icon-xuekezuhe:before {
|
||||
content: "\e625";
|
||||
}
|
||||
|
||||
.icon-fenxiang1:before {
|
||||
content: "\eb24";
|
||||
}
|
||||
|
||||
.icon-tongzhizhongxin:before {
|
||||
content: "\eb43";
|
||||
}
|
||||
|
||||
.icon-xiajia:before {
|
||||
content: "\e618";
|
||||
}
|
||||
|
||||
.icon-shengchanguochengguanli:before {
|
||||
content: "\e62a";
|
||||
}
|
||||
|
||||
.icon-kejian:before {
|
||||
content: "\e64a";
|
||||
}
|
||||
|
||||
.icon-liulan:before {
|
||||
content: "\e648";
|
||||
}
|
||||
|
||||
.icon-fabiao:before {
|
||||
content: "\e654";
|
||||
}
|
||||
|
||||
.icon-kecheng:before {
|
||||
content: "\e619";
|
||||
}
|
||||
|
||||
.icon-bianji1:before {
|
||||
content: "\e61d";
|
||||
}
|
||||
|
||||
.icon-pingjia:before {
|
||||
content: "\e628";
|
||||
}
|
||||
|
||||
.icon-zonghezhenduan:before {
|
||||
content: "\e6a0";
|
||||
}
|
||||
|
||||
.icon-banji:before {
|
||||
content: "\e71e";
|
||||
}
|
||||
|
||||
.icon-tousuyujianyi:before {
|
||||
content: "\e729";
|
||||
}
|
||||
|
||||
.icon-jiaoliu:before {
|
||||
content: "\e6b8";
|
||||
}
|
||||
|
||||
.icon-pingyi:before {
|
||||
content: "\e79a";
|
||||
}
|
||||
|
||||
.icon-xueqingfenxi:before {
|
||||
content: "\e67a";
|
||||
}
|
||||
|
||||
.icon-check:before {
|
||||
content: "\e622";
|
||||
}
|
||||
|
||||
.icon-upload:before {
|
||||
content: "\e634";
|
||||
}
|
||||
|
||||
.icon-taolun:before {
|
||||
content: "\e61e";
|
||||
}
|
||||
|
||||
.icon-tujing:before {
|
||||
content: "\e947";
|
||||
}
|
||||
|
||||
.icon-zixun:before {
|
||||
content: "\e6b3";
|
||||
}
|
||||
|
||||
.icon-liulan1:before {
|
||||
content: "\e6b4";
|
||||
}
|
||||
|
||||
.icon-yaosu:before {
|
||||
content: "\e68c";
|
||||
}
|
||||
|
||||
.icon-baogao1:before {
|
||||
content: "\e62e";
|
||||
}
|
||||
|
||||
.icon-shoucang:before {
|
||||
content: "\e61f";
|
||||
}
|
||||
|
||||
.icon-shenhe:before {
|
||||
content: "\e623";
|
||||
}
|
||||
|
||||
.icon-w_duoxuanti:before {
|
||||
content: "\e677";
|
||||
}
|
||||
|
||||
.icon-fenxi:before {
|
||||
content: "\e76d";
|
||||
}
|
||||
|
||||
.icon-kanshu:before {
|
||||
content: "\e626";
|
||||
}
|
||||
|
||||
.icon-qwe:before {
|
||||
content: "\e627";
|
||||
}
|
||||
|
||||
.icon-jiancha:before {
|
||||
content: "\e6c1";
|
||||
}
|
||||
|
||||
.icon-qunzu:before {
|
||||
content: "\e62b";
|
||||
}
|
||||
|
||||
.icon-zuopin:before {
|
||||
content: "\e6a9";
|
||||
}
|
||||
|
||||
.icon-shuyi_jiaoxueguanli:before {
|
||||
content: "\e678";
|
||||
}
|
||||
|
||||
.icon-liangsuan:before {
|
||||
content: "\e657";
|
||||
}
|
||||
|
||||
.icon-business-report:before {
|
||||
content: "\e880";
|
||||
}
|
||||
|
||||
.icon-xiangmupingshen:before {
|
||||
content: "\e742";
|
||||
}
|
||||
|
||||
.icon-xiangmushenbao:before {
|
||||
content: "\e743";
|
||||
}
|
||||
|
||||
.icon-xiajia1:before {
|
||||
content: "\e62c";
|
||||
}
|
||||
|
||||
.icon-a-fenxiang2:before {
|
||||
content: "\e62f";
|
||||
}
|
||||
|
||||
.icon-icon_kaoshifenxi:before {
|
||||
content: "\e6d3";
|
||||
}
|
||||
|
||||
.icon-a-ketangshilu1:before {
|
||||
content: "\e631";
|
||||
}
|
||||
|
||||
.icon-tubiao_moshileixingpeizhi:before {
|
||||
content: "\e632";
|
||||
}
|
||||
|
||||
.icon-xiezuo:before {
|
||||
content: "\e633";
|
||||
}
|
||||
|
||||
.icon-buzhi:before {
|
||||
content: "\e636";
|
||||
}
|
||||
|
||||
.icon-ziyuanfenxi:before {
|
||||
content: "\e637";
|
||||
}
|
||||
|
||||
.icon-shoucang1:before {
|
||||
content: "\e638";
|
||||
}
|
||||
|
||||
.icon-iconku-zhuanqu-:before {
|
||||
content: "\e649";
|
||||
}
|
||||
|
||||
.icon-PPT:before {
|
||||
content: "\e639";
|
||||
}
|
||||
|
||||
.icon-fabiaolunwen:before {
|
||||
content: "\e772";
|
||||
}
|
||||
|
||||
.icon-xiezuo1:before {
|
||||
content: "\e63b";
|
||||
}
|
||||
|
||||
.icon-fenxi1:before {
|
||||
content: "\e63c";
|
||||
}
|
||||
|
||||
.icon-kechengziyuan:before {
|
||||
content: "\e6e9";
|
||||
}
|
||||
|
||||
.icon-36zuoyepingtai:before {
|
||||
content: "\e699";
|
||||
}
|
||||
|
||||
.icon-jiekebiaozhunbijishu:before {
|
||||
content: "\e63d";
|
||||
}
|
||||
|
||||
.icon-xunzhang:before {
|
||||
content: "\e63e";
|
||||
}
|
||||
|
||||
.icon-jiaocaizhengding:before {
|
||||
content: "\e6a4";
|
||||
}
|
||||
|
||||
.icon-xinzengmoxing:before {
|
||||
content: "\e7b8";
|
||||
}
|
||||
|
||||
.icon-a-biaozhangxunzhangyingxiong:before {
|
||||
content: "\e79d";
|
||||
}
|
||||
|
||||
.icon-xunzhang1:before {
|
||||
content: "\e63f";
|
||||
}
|
||||
|
||||
.icon-paizhao-xianxing:before {
|
||||
content: "\e8d1";
|
||||
}
|
||||
|
||||
.icon-zhuye2:before {
|
||||
content: "\e604";
|
||||
}
|
||||
|
||||
.icon-zuoye2:before {
|
||||
content: "\f48d";
|
||||
}
|
||||
|
||||
.icon-zuoye1:before {
|
||||
content: "\e610";
|
||||
}
|
||||
|
||||
.icon-xiazai9:before {
|
||||
content: "\e60b";
|
||||
}
|
||||
|
||||
.icon-hudong:before {
|
||||
content: "\e60c";
|
||||
}
|
||||
|
||||
.icon-xiangpica:before {
|
||||
content: "\e6be";
|
||||
}
|
||||
|
||||
.icon-gengduo:before {
|
||||
content: "\e62d";
|
||||
}
|
||||
|
||||
.icon-jujiao:before {
|
||||
content: "\e615";
|
||||
}
|
||||
|
||||
.icon-huabi:before {
|
||||
content: "\e795";
|
||||
}
|
||||
|
||||
.icon-mouse:before {
|
||||
content: "\e603";
|
||||
}
|
||||
|
||||
.icon-xiayiye:before {
|
||||
content: "\e68b";
|
||||
}
|
||||
|
||||
.icon-shangyiye:before {
|
||||
content: "\e68e";
|
||||
}
|
||||
|
||||
.icon-shuangye:before {
|
||||
content: "\e64e";
|
||||
}
|
||||
|
||||
.icon-danyemoban:before {
|
||||
content: "\e859";
|
||||
}
|
||||
|
||||
.icon-lingdang:before {
|
||||
content: "\e613";
|
||||
}
|
||||
|
||||
.icon-yidongdaozu:before {
|
||||
content: "\e67d";
|
||||
}
|
||||
|
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 354 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 48 KiB |
|
@ -0,0 +1,177 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|