mirror of https://gitee.com/karson/fastadmin.git
Compare commits
804 Commits
v1.0.0.201
...
master
| Author | SHA1 | Date |
|---|---|---|
|
|
c74b9dc24a | |
|
|
5188621e9c | |
|
|
7238632f14 | |
|
|
4329b47c56 | |
|
|
418d93f448 | |
|
|
8e88e1c9dc | |
|
|
592a42fcc5 | |
|
|
a532001e7b | |
|
|
9876dc22db | |
|
|
37c18d4e92 | |
|
|
5c9c6ef89c | |
|
|
03ccce86f0 | |
|
|
18a661fb22 | |
|
|
c01628a914 | |
|
|
996fa27d62 | |
|
|
b13a1ca7b5 | |
|
|
c78b3aecc5 | |
|
|
54d6e0904b | |
|
|
6d4aaf5ea8 | |
|
|
4a97bdaf19 | |
|
|
028a0b5f22 | |
|
|
7f54960449 | |
|
|
e7c1922cf3 | |
|
|
c5285b8fdd | |
|
|
5400c6ff2a | |
|
|
090381a1a2 | |
|
|
8f7a55928c | |
|
|
e8a804afad | |
|
|
26a5ca4a2c | |
|
|
f932156c8e | |
|
|
77c386ed47 | |
|
|
57da65acd0 | |
|
|
6dd941e168 | |
|
|
b7eef593a3 | |
|
|
2b14bc4e2b | |
|
|
5e7d398b49 | |
|
|
58035763ea | |
|
|
7c9841cee9 | |
|
|
a5e1fe9cb6 | |
|
|
1a31ac2dc9 | |
|
|
56b33f1514 | |
|
|
c5d26b7f3a | |
|
|
de002debd7 | |
|
|
d1c240bd91 | |
|
|
e45b435b48 | |
|
|
aec4efe9e0 | |
|
|
0a5484b738 | |
|
|
9f2c08414a | |
|
|
448eaad5f5 | |
|
|
578044505a | |
|
|
36bf77df6c | |
|
|
bac6606786 | |
|
|
131ef803d1 | |
|
|
17eb182063 | |
|
|
f7e47d90f1 | |
|
|
a9a6065fde | |
|
|
6a94a07903 | |
|
|
5bf63c557b | |
|
|
5d3d667143 | |
|
|
8a0e8b1d3b | |
|
|
ee0be09841 | |
|
|
c8c1573c27 | |
|
|
76abb2dcd7 | |
|
|
787334972e | |
|
|
1c7d0b710e | |
|
|
b0a3851d93 | |
|
|
2e4fe16f44 | |
|
|
e3779a1f05 | |
|
|
d8acbf8abe | |
|
|
e76eba0c21 | |
|
|
7b66d0bf58 | |
|
|
bb68eb4254 | |
|
|
879554d5a8 | |
|
|
403c6a2a7d | |
|
|
42e91e10e6 | |
|
|
22628fca0e | |
|
|
709424da7f | |
|
|
ae57feebb6 | |
|
|
cdb41c5334 | |
|
|
2fe68b4c27 | |
|
|
31b307a4a1 | |
|
|
7fffba8963 | |
|
|
4aa2666c98 | |
|
|
940e9a0814 | |
|
|
901bea7d59 | |
|
|
faff9fc96f | |
|
|
cc9802877a | |
|
|
681558500c | |
|
|
033af96e1a | |
|
|
ad166f07eb | |
|
|
b76b99f3a0 | |
|
|
b4dc742fed | |
|
|
37e844181e | |
|
|
1a660364af | |
|
|
65068c9a29 | |
|
|
4845b08077 | |
|
|
b0387e668b | |
|
|
aca4e9221c | |
|
|
7a4d05bbd9 | |
|
|
a9003ecce4 | |
|
|
7f28eaa570 | |
|
|
31528c8951 | |
|
|
e4094e24e2 | |
|
|
80ad9e307a | |
|
|
e6f2894af7 | |
|
|
c170985264 | |
|
|
9d9c8dcf52 | |
|
|
4eaae6ac4e | |
|
|
7e6314a701 | |
|
|
a40420b8cd | |
|
|
31a6a47dc3 | |
|
|
2c66c67d71 | |
|
|
42fdea065a | |
|
|
0fb7924420 | |
|
|
7cd9281c74 | |
|
|
dc466cb1c9 | |
|
|
d2c275e20a | |
|
|
3549e95ea1 | |
|
|
a34c5fbdb8 | |
|
|
9fe7a6f9a0 | |
|
|
94b61ab7dc | |
|
|
6ebde793bd | |
|
|
faca2e0be0 | |
|
|
7c8d1a6683 | |
|
|
76c48c00fd | |
|
|
bc6bcb84f9 | |
|
|
5f35be92b5 | |
|
|
9cadda6c3f | |
|
|
152ac2cdcb | |
|
|
cd5fafde38 | |
|
|
3d4a02160c | |
|
|
1004bdedad | |
|
|
8ce9f1f884 | |
|
|
bfd3737b28 | |
|
|
4b4d4493aa | |
|
|
164a4f6664 | |
|
|
e59668c0f2 | |
|
|
afe0fdce73 | |
|
|
03f46a637d | |
|
|
0a062a8d63 | |
|
|
db5574582e | |
|
|
e4ef9f1db0 | |
|
|
2c02ed019b | |
|
|
eee98aad11 | |
|
|
6d8f98a554 | |
|
|
9e9d729c62 | |
|
|
91549dbfea | |
|
|
85f0e4f041 | |
|
|
17256db17a | |
|
|
2b81652072 | |
|
|
e846244791 | |
|
|
f8292a8813 | |
|
|
89ed50d790 | |
|
|
776a4fedb5 | |
|
|
6b190fe111 | |
|
|
d562f3d17c | |
|
|
445f0c94d8 | |
|
|
6e4321d5cf | |
|
|
6d4d564ae8 | |
|
|
b1af836710 | |
|
|
7f0e4eb25c | |
|
|
eaa1832852 | |
|
|
aa9fa16451 | |
|
|
f02121cfcc | |
|
|
4fb1379afa | |
|
|
ae935d260c | |
|
|
44887b8aec | |
|
|
1dbafec12f | |
|
|
9a90cbe329 | |
|
|
ae11381309 | |
|
|
c3bdbbf779 | |
|
|
3ba1192555 | |
|
|
80d928d872 | |
|
|
b9877c10ff | |
|
|
a7983055fc | |
|
|
3fd25c3de0 | |
|
|
85e0f4bacc | |
|
|
b3c4692164 | |
|
|
dfeff713bd | |
|
|
f639cecf73 | |
|
|
466aa4233f | |
|
|
378aad4409 | |
|
|
1a07280f79 | |
|
|
b3e172ddce | |
|
|
079f6df9dd | |
|
|
9400aa6e4e | |
|
|
0b4eceea54 | |
|
|
ce811fa904 | |
|
|
06ccca81c9 | |
|
|
be2f342044 | |
|
|
1898e481e0 | |
|
|
e59d2df641 | |
|
|
f4795e90da | |
|
|
9eeb35a79b | |
|
|
12e7bbf5f2 | |
|
|
940d4f0410 | |
|
|
5022da9cea | |
|
|
8e48aa7edd | |
|
|
036c2dcc25 | |
|
|
9116b86a36 | |
|
|
a4617c7f28 | |
|
|
a9a5696f58 | |
|
|
e67f9a20c5 | |
|
|
ff51380686 | |
|
|
2a97c21c0c | |
|
|
6470a8ed74 | |
|
|
d7ffc690c2 | |
|
|
41682bd850 | |
|
|
2401cd3ba1 | |
|
|
8b55020b3a | |
|
|
3dd4276ca1 | |
|
|
02cc257faf | |
|
|
cd60f5f381 | |
|
|
d4531c7df0 | |
|
|
d2d6648d9c | |
|
|
f700dbcdc7 | |
|
|
9ed5fbd2e3 | |
|
|
6569dfbb3c | |
|
|
c87a7f9f3c | |
|
|
077bba602d | |
|
|
edec9f7fe1 | |
|
|
0c950a93cf | |
|
|
96cb06f825 | |
|
|
65073c30b9 | |
|
|
d785d321f7 | |
|
|
ff85bb3b21 | |
|
|
c65e3b23e2 | |
|
|
c00584a5b5 | |
|
|
017970a2e3 | |
|
|
5673ce72fd | |
|
|
4fa13dca39 | |
|
|
8366745875 | |
|
|
a176508bb9 | |
|
|
5ea57836c8 | |
|
|
82ea7fcd15 | |
|
|
03bfe24893 | |
|
|
acca6a0584 | |
|
|
12ea49d937 | |
|
|
41fc1d1b3a | |
|
|
b52df110ee | |
|
|
e3169bcaf4 | |
|
|
d1cdc51798 | |
|
|
cd9d2e6516 | |
|
|
bc99cfddd8 | |
|
|
a7317ec08c | |
|
|
824f337481 | |
|
|
fce5b8e374 | |
|
|
093d60b719 | |
|
|
a7b7b772fd | |
|
|
48066342da | |
|
|
ecdaa81a8d | |
|
|
a87cfefd50 | |
|
|
e7f8b75ecf | |
|
|
9a239de4b1 | |
|
|
db69a36d28 | |
|
|
70b9c8affe | |
|
|
9d1d1248e9 | |
|
|
84eef812f3 | |
|
|
0266534d95 | |
|
|
e7ae8fb4d1 | |
|
|
c12f9bca84 | |
|
|
69ad41a3e9 | |
|
|
3a0352e183 | |
|
|
ab53e00a75 | |
|
|
ac2b3ffbff | |
|
|
9cf930a932 | |
|
|
343ad6055d | |
|
|
2ab8d7fa81 | |
|
|
f3b841c456 | |
|
|
683d837d20 | |
|
|
3f1cac43e4 | |
|
|
75141e192d | |
|
|
1d7c7d7ce6 | |
|
|
6178a5c231 | |
|
|
0c7a4850a2 | |
|
|
a502a98df0 | |
|
|
3d9805eea7 | |
|
|
8925cbc9f7 | |
|
|
80a25c9749 | |
|
|
70e215cdde | |
|
|
f501638884 | |
|
|
d1d3ea1dea | |
|
|
b3b9a61723 | |
|
|
60902457bb | |
|
|
8b11a77294 | |
|
|
dfd0ba0524 | |
|
|
5599170ce4 | |
|
|
ca8238df06 | |
|
|
2c4efe19f2 | |
|
|
b3d32e2bf3 | |
|
|
4275d769ea | |
|
|
9b4d4c78dd | |
|
|
88df7bd386 | |
|
|
503c67f9d8 | |
|
|
e05a8584e2 | |
|
|
82748502ea | |
|
|
33788fc93e | |
|
|
49ed6cb808 | |
|
|
4b1c3a3b4b | |
|
|
a5163732af | |
|
|
7adc36ae4f | |
|
|
9a7e29a080 | |
|
|
3dfa4f7065 | |
|
|
bbf728b5e6 | |
|
|
99c3fac317 | |
|
|
614384a2bb | |
|
|
44fd7d14ec | |
|
|
c615eda2dc | |
|
|
e5235a4991 | |
|
|
f05e5ae722 | |
|
|
6edcaffa75 | |
|
|
de1c8194f1 | |
|
|
364d7be7ba | |
|
|
e0b008097a | |
|
|
4f28da05fe | |
|
|
a5eb7ef3b7 | |
|
|
119b0273d4 | |
|
|
bba702bd18 | |
|
|
8130a49fab | |
|
|
4e657d1f25 | |
|
|
ed0da37370 | |
|
|
bf720c176e | |
|
|
7045f0d02b | |
|
|
cdebb284c3 | |
|
|
9f725a062a | |
|
|
d59ff78fd8 | |
|
|
289e9306bd | |
|
|
dba3ca50fc | |
|
|
6b9e5ba379 | |
|
|
1c62049989 | |
|
|
ab083686a8 | |
|
|
0236b39df0 | |
|
|
61cf9c2896 | |
|
|
04e1f7f0ae | |
|
|
43d8570337 | |
|
|
f1fb9cbb3b | |
|
|
e1fe326597 | |
|
|
454fdcded9 | |
|
|
a58a147143 | |
|
|
4db3a64b2c | |
|
|
0c494ee2b3 | |
|
|
132dc960b2 | |
|
|
5ad3d5125a | |
|
|
dc691dbe84 | |
|
|
120aa6b200 | |
|
|
cd37a9e7e4 | |
|
|
e2772b164b | |
|
|
ab89d2d506 | |
|
|
916722b139 | |
|
|
65daf79d0a | |
|
|
e4b2066e0f | |
|
|
d610fe6141 | |
|
|
97a6b53cec | |
|
|
63d74029f0 | |
|
|
fb2b5aed30 | |
|
|
c7126fe7bb | |
|
|
2e74e2c119 | |
|
|
2b5cab420a | |
|
|
f815edab04 | |
|
|
0b752a3dfa | |
|
|
6bac3fca8a | |
|
|
025f37f1f1 | |
|
|
89e14e8f8b | |
|
|
74a4aacb66 | |
|
|
6c0ea3a420 | |
|
|
b909c0b27a | |
|
|
8127f56953 | |
|
|
351475ca06 | |
|
|
5d7181fe1d | |
|
|
5ab531e0ec | |
|
|
dc5a2e01dd | |
|
|
5a9dbf0abf | |
|
|
af241c7c21 | |
|
|
9174b6c306 | |
|
|
1fc50ed06d | |
|
|
504e50e65c | |
|
|
76b31ced93 | |
|
|
700184c8eb | |
|
|
35220f545c | |
|
|
b82dbd7eee | |
|
|
6f17a39d90 | |
|
|
ce8c3a94d9 | |
|
|
e097ae2429 | |
|
|
c2460a3241 | |
|
|
c585fa1228 | |
|
|
00bca5e0c8 | |
|
|
4a9ebb9c7d | |
|
|
7daf3601ed | |
|
|
6609ac1470 | |
|
|
794f02c502 | |
|
|
39c6720cfc | |
|
|
dd3d6f3172 | |
|
|
12a62eaa05 | |
|
|
662d211946 | |
|
|
2a131ae573 | |
|
|
c4d676aa8c | |
|
|
9c13b07f73 | |
|
|
8af7f5653a | |
|
|
8d0384ee49 | |
|
|
fadcb5432a | |
|
|
eca3ae7086 | |
|
|
346f6eab1a | |
|
|
08ee8d3362 | |
|
|
2a811716b9 | |
|
|
0f3ee250ad | |
|
|
06057850c1 | |
|
|
d1bdd4982c | |
|
|
3e48396821 | |
|
|
bb97452fe1 | |
|
|
e8fa069fe9 | |
|
|
bcfbe92d51 | |
|
|
908039c13d | |
|
|
32f256f3fa | |
|
|
750f5d7887 | |
|
|
7b0ce82bbb | |
|
|
bcdbd82c5c | |
|
|
fffad26373 | |
|
|
ad69fbab5c | |
|
|
acb42e8eb8 | |
|
|
9d5ccb91b4 | |
|
|
1473fd93cf | |
|
|
aa5d413cc0 | |
|
|
e550b327dd | |
|
|
82fc4f971c | |
|
|
c8085a406e | |
|
|
b4185e2da8 | |
|
|
dfd326a6e1 | |
|
|
ebb5d34414 | |
|
|
b277d31c60 | |
|
|
d0f71f4f1d | |
|
|
98b813aff1 | |
|
|
15f6fb7553 | |
|
|
f70e1f3349 | |
|
|
045b756272 | |
|
|
788b1d57f6 | |
|
|
077eebec86 | |
|
|
36d762fc81 | |
|
|
4f7b083e8d | |
|
|
7150bea947 | |
|
|
a2d99f4bdb | |
|
|
8b772d30cd | |
|
|
5ea682edf4 | |
|
|
1cc0cadbdd | |
|
|
29976027fc | |
|
|
e37ca7506a | |
|
|
b7964f7aa9 | |
|
|
c3eae7b1aa | |
|
|
b194c91398 | |
|
|
30f1702b4c | |
|
|
e9755a31d7 | |
|
|
df72ef06fd | |
|
|
a685e48ada | |
|
|
a1a0d0f70c | |
|
|
07679a3fe3 | |
|
|
adb3cc080a | |
|
|
cdd53ac377 | |
|
|
bdb9b61f24 | |
|
|
4a675d5689 | |
|
|
6f56a83422 | |
|
|
9d2e7f1c95 | |
|
|
a3a5707cdd | |
|
|
b9d55fca25 | |
|
|
2fecaeae0b | |
|
|
b44add7ad8 | |
|
|
8ddbd81d6d | |
|
|
46bd263186 | |
|
|
4493a69b80 | |
|
|
8058ba312b | |
|
|
cd99b2d1f0 | |
|
|
2968a38abb | |
|
|
e31a546b48 | |
|
|
481256dff3 | |
|
|
0a164777fe | |
|
|
dd83a6255e | |
|
|
260198e1cb | |
|
|
3d9cde96a1 | |
|
|
f36a3415d7 | |
|
|
9ddcb1953f | |
|
|
da4402b44e | |
|
|
cb4c41e8bf | |
|
|
5ee9219627 | |
|
|
cdbcca0b0e | |
|
|
28a1321b4d | |
|
|
66e69dfd26 | |
|
|
bae3079574 | |
|
|
1c1f457e1d | |
|
|
2012f7f9f2 | |
|
|
9f2aa5cd3a | |
|
|
1a673fc758 | |
|
|
69d155b1d0 | |
|
|
7f2ca19ef8 | |
|
|
13da01a48c | |
|
|
84a181be73 | |
|
|
3abfacb86e | |
|
|
3f4e54d0dd | |
|
|
ac97988661 | |
|
|
926e16bde6 | |
|
|
1d37f23a5e | |
|
|
285095f80f | |
|
|
82966e07c3 | |
|
|
9f04fcdb66 | |
|
|
beccee0811 | |
|
|
614d88eb81 | |
|
|
e0231e4051 | |
|
|
07234a16c8 | |
|
|
ed20e5ac6f | |
|
|
e29a9e41fc | |
|
|
049e719d89 | |
|
|
d101bcd3e6 | |
|
|
af3aa231f8 | |
|
|
541a182a7e | |
|
|
c5da47b16b | |
|
|
6d34058826 | |
|
|
dbf47c182a | |
|
|
1dfbc62783 | |
|
|
0d800cbbb0 | |
|
|
df183a86e4 | |
|
|
ac7f3f2690 | |
|
|
2786259135 | |
|
|
b6aaaeaebe | |
|
|
5e908498bd | |
|
|
fc701cb901 | |
|
|
83ae127480 | |
|
|
a6b4a1d355 | |
|
|
bcd1b7fb9c | |
|
|
6657f92fe6 | |
|
|
d901af60e8 | |
|
|
3cae744a00 | |
|
|
431ac47172 | |
|
|
1a5661f994 | |
|
|
27d20e2fca | |
|
|
3c17401985 | |
|
|
8fb48352ed | |
|
|
d3a1c3978e | |
|
|
ce706fde18 | |
|
|
4d1b5db9f2 | |
|
|
cf4949db77 | |
|
|
36d062d612 | |
|
|
8c99271e66 | |
|
|
6c7b53a9d7 | |
|
|
7065215109 | |
|
|
489a29f15d | |
|
|
568fd153ad | |
|
|
caf60d8c2b | |
|
|
3793266280 | |
|
|
98c37f5e2b | |
|
|
7e3205fd38 | |
|
|
87aa1dcafe | |
|
|
b06d963a4a | |
|
|
40eb4ed86c | |
|
|
1a81c45317 | |
|
|
4346b37ab8 | |
|
|
a588fa629a | |
|
|
e9af5be8d6 | |
|
|
d0e42a27b7 | |
|
|
b849191a1d | |
|
|
713f882552 | |
|
|
f8a1c3975f | |
|
|
a97d0c9a68 | |
|
|
1dc1f7388c | |
|
|
3aacc8421f | |
|
|
bfaddd1832 | |
|
|
327f2a2707 | |
|
|
37d77a6e37 | |
|
|
8443d2e7c5 | |
|
|
7e73e0b562 | |
|
|
290bfc4f75 | |
|
|
30c695ff61 | |
|
|
b3d8877ead | |
|
|
1b3c22ead2 | |
|
|
c6f44aa060 | |
|
|
802346dd1f | |
|
|
597e50e722 | |
|
|
3ea0b57b97 | |
|
|
a4873a3a9a | |
|
|
fa088b1897 | |
|
|
b552ccd403 | |
|
|
e14008ca02 | |
|
|
edb6a12c3b | |
|
|
efc92f71a9 | |
|
|
63e0fb3fd5 | |
|
|
4bb4425d45 | |
|
|
ffd0060fd0 | |
|
|
088d272257 | |
|
|
a1deccd17a | |
|
|
d868c0fed3 | |
|
|
d3d9a5a751 | |
|
|
887a381ff3 | |
|
|
c14adbbdfd | |
|
|
054e75a96e | |
|
|
0d20ce6fa9 | |
|
|
e216bd7751 | |
|
|
2b60921cf3 | |
|
|
938671cf2b | |
|
|
014c29fcd2 | |
|
|
a3fc3f85be | |
|
|
a4f6a29c09 | |
|
|
f8714972fc | |
|
|
565bca602b | |
|
|
49facb7b7c | |
|
|
b6f2307737 | |
|
|
9b2ec96a03 | |
|
|
b6d51ee5b6 | |
|
|
515f4f78b1 | |
|
|
3157f3a574 | |
|
|
5cb74b5e36 | |
|
|
193f33f11a | |
|
|
8066902212 | |
|
|
9066b3964c | |
|
|
2f9732e905 | |
|
|
b388289dba | |
|
|
f5b9e28ffb | |
|
|
7267c2d531 | |
|
|
01521805cd | |
|
|
d4900be78f | |
|
|
3ba70093c5 | |
|
|
678be2f3a9 | |
|
|
2a19697858 | |
|
|
ebf38b470c | |
|
|
b0cfaed544 | |
|
|
e5bc5718c8 | |
|
|
42057091e7 | |
|
|
1390a5f1a7 | |
|
|
56d1493ba7 | |
|
|
f03430ccb7 | |
|
|
4cff10ca7e | |
|
|
df68b9d0c0 | |
|
|
92a9545564 | |
|
|
a85db2323a | |
|
|
b927b5443f | |
|
|
fbb1370005 | |
|
|
cb4a986184 | |
|
|
8c76ac77a4 | |
|
|
f42ea981ae | |
|
|
7dd47e858c | |
|
|
a3bdbdd522 | |
|
|
6e94113ebd | |
|
|
a7a6a68e8f | |
|
|
535d821ca7 | |
|
|
71195b4185 | |
|
|
e3f7268a8b | |
|
|
07e5608447 | |
|
|
f9d14aa693 | |
|
|
e45784dec6 | |
|
|
e5e3897374 | |
|
|
843a10fadd | |
|
|
cfba7e04c1 | |
|
|
830dd7a20d | |
|
|
842cfbedeb | |
|
|
16e02f643f | |
|
|
c550465f37 | |
|
|
ba215a4593 | |
|
|
b6777b60c3 | |
|
|
407a8eeaa5 | |
|
|
9db281a4c6 | |
|
|
9e8fc90f87 | |
|
|
7f2ea95489 | |
|
|
9d42f92c95 | |
|
|
5298c52e47 | |
|
|
4992c59620 | |
|
|
3b671000ad | |
|
|
74f0ea14ad | |
|
|
d9bf3b3715 | |
|
|
2c7546e43f | |
|
|
840abb714d | |
|
|
a3a742cebe | |
|
|
d775f062b5 | |
|
|
7618ad7dd8 | |
|
|
5ec2a9893a | |
|
|
d1b386dd08 | |
|
|
6facfcf894 | |
|
|
b23d7f9b72 | |
|
|
c0128a2e6c | |
|
|
41ae511dc3 | |
|
|
5153cfe3c4 | |
|
|
4a12b47021 | |
|
|
499e43c6d5 | |
|
|
f914920078 | |
|
|
251774d0bd | |
|
|
349c110717 | |
|
|
eccf03e43f | |
|
|
f5c72393d2 | |
|
|
a22315c18f | |
|
|
524c6c63e1 | |
|
|
7d1119386e | |
|
|
a8291db80d | |
|
|
d154e79e2c | |
|
|
d0c100f85e | |
|
|
065d05d0b4 | |
|
|
041ed69798 | |
|
|
891b175d22 | |
|
|
4bd4d15788 | |
|
|
216b8a1c9c | |
|
|
9d7970f58b | |
|
|
af21c68626 | |
|
|
2c9865e1c9 | |
|
|
fd2b888da7 | |
|
|
62283eb2e9 | |
|
|
95c6834d15 | |
|
|
b75fa0661f | |
|
|
cb754d169a | |
|
|
7a3fa9d6c1 | |
|
|
539cf051fc | |
|
|
d5bdcd1cd6 | |
|
|
a7627c347f | |
|
|
88226015a8 | |
|
|
a329e5fbb2 | |
|
|
a8140635c2 | |
|
|
2911a30374 | |
|
|
43d9883e7d | |
|
|
0f1ce99a25 | |
|
|
93f8f46eab | |
|
|
2bfd19267a | |
|
|
f9b43bdbe4 | |
|
|
f011bf6da2 | |
|
|
366bc7864c | |
|
|
49464f6135 | |
|
|
84ecf5a013 | |
|
|
02029bf972 | |
|
|
ac312ef41e | |
|
|
3763b0d69e | |
|
|
70f9bf0197 | |
|
|
a0e8f19056 | |
|
|
ed0b61ebbf | |
|
|
c9a8b364f5 | |
|
|
8d05d78fa0 | |
|
|
c0d709d3b2 | |
|
|
1c37e2af07 | |
|
|
b46b338dcf | |
|
|
dd1a66fcc8 | |
|
|
de11e26aa3 | |
|
|
fdd68b5b7a | |
|
|
0ac3eea2e6 | |
|
|
60b58cc397 | |
|
|
91919dbf0b | |
|
|
04edfbf5d2 | |
|
|
948b9e7ab8 | |
|
|
6863ff05b4 | |
|
|
83330796a3 | |
|
|
5c9818791b | |
|
|
7e831339c8 | |
|
|
453bb1ddeb | |
|
|
c6ef72f5fa | |
|
|
aa272a54fd | |
|
|
f6ccbb70dd | |
|
|
2000a876dd | |
|
|
2d4a8a3ec8 | |
|
|
307ed3d789 | |
|
|
d2c5dfbf0f | |
|
|
a7407ce069 | |
|
|
f71815a1fd | |
|
|
7dc185fb5f | |
|
|
3134cb7869 | |
|
|
0a4ed2791f | |
|
|
dca32b0a13 | |
|
|
86ba65d907 | |
|
|
336597859a | |
|
|
d60dcca9cb | |
|
|
571ef508ca | |
|
|
69a9de0a4d | |
|
|
c86f89b5d7 | |
|
|
c8e4c56e80 | |
|
|
7a4fdb61c9 | |
|
|
3250a5f965 | |
|
|
2c366f06b3 | |
|
|
544222fabb | |
|
|
6bc96814b9 | |
|
|
c462d4783c | |
|
|
25ecebc54a | |
|
|
c15be9773e | |
|
|
4c369498ce | |
|
|
9e3f1ccf42 | |
|
|
ace56cf050 | |
|
|
7413cb3a6a | |
|
|
95c08fb8bd | |
|
|
7fcae26d37 | |
|
|
c5d7fef22e | |
|
|
9753d94bc0 | |
|
|
3683728023 | |
|
|
3eb938e722 | |
|
|
fc2f8774e7 | |
|
|
66edd96c02 | |
|
|
e9d26ea603 | |
|
|
b65452c7c3 | |
|
|
4198f126a9 | |
|
|
1b08595857 | |
|
|
52712b644e | |
|
|
98e5f32429 | |
|
|
d54583e946 | |
|
|
03f6ba62d6 | |
|
|
f4604e1265 | |
|
|
3920be0f2b | |
|
|
36271ab07b | |
|
|
4bb1cbd2dd | |
|
|
045647c407 | |
|
|
de8ea27542 | |
|
|
ddd75e44c0 | |
|
|
2ad4650730 | |
|
|
ac6aa072a2 | |
|
|
47d2a430f3 | |
|
|
37fce92178 | |
|
|
afbe9d2770 | |
|
|
0d78f12ac0 | |
|
|
c62c0dfdc2 |
8
.bowerrc
8
.bowerrc
|
|
@ -1,9 +1,11 @@
|
||||||
{
|
{
|
||||||
"directory" : "public/assets/libs",
|
"directory": "public/assets/libs",
|
||||||
"ignoredDependencies": [
|
"ignoredDependencies": [
|
||||||
|
"es6-promise",
|
||||||
"file-saver",
|
"file-saver",
|
||||||
"html2canvas",
|
"html2canvas",
|
||||||
"jspdf",
|
"jspdf",
|
||||||
"jspdf-autotable"
|
"jspdf-autotable",
|
||||||
|
"pdfmake"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
[app]
|
||||||
|
debug = false
|
||||||
|
trace = false
|
||||||
|
|
||||||
|
[database]
|
||||||
|
hostname = 127.0.0.1
|
||||||
|
database = fastadmin
|
||||||
|
username = root
|
||||||
|
password = root
|
||||||
|
hostport = 3306
|
||||||
|
prefix = fa_
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
### 类型
|
||||||
|
类型(问题/建议/其他):?
|
||||||
|
|
||||||
|
|
||||||
|
### 现象
|
||||||
|
现象(请详细描述一下复现过程):?
|
||||||
|
|
||||||
|
|
||||||
|
### 期望结果
|
||||||
|
期望结果(请详细描述一下你说期望的结果):?
|
||||||
|
|
||||||
|
|
||||||
|
### 环境
|
||||||
|
(请详细说明一下你的运行环境)
|
||||||
|
- 操作系统(Linux/Windows/Other):?
|
||||||
|
- Web Server(NGINX/Apache/Other):?
|
||||||
|
- PHP 版本(7.2/7.3/7.4/8.0/8.1/8.2/Other):?
|
||||||
|
- MySQL 版本(5.6/5.7/8.0/Other):?
|
||||||
|
- 服务器面板(BT/phpStudy/XAMPP/其他/无):?
|
||||||
|
- FastAdmin 版本:?
|
||||||
|
- 浏览器(Chrome/IE/Edge/其他):?
|
||||||
|
- 报错信息:?
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
/vendor/
|
/vendor/
|
||||||
/runtime/*
|
/runtime/*
|
||||||
/addons/*
|
/addons/*
|
||||||
/application/admin/command/Install/*.lock
|
|
||||||
/public/assets/libs/
|
/public/assets/libs/
|
||||||
/public/assets/addons/*
|
/public/assets/addons/*
|
||||||
/public/uploads/*
|
/public/uploads/*
|
||||||
|
|
@ -13,3 +12,7 @@ composer.lock
|
||||||
*.css.map
|
*.css.map
|
||||||
!.gitkeep
|
!.gitkeep
|
||||||
.env
|
.env
|
||||||
|
.svn
|
||||||
|
.vscode
|
||||||
|
node_modules
|
||||||
|
.user.ini
|
||||||
|
|
|
||||||
60
README.md
60
README.md
|
|
@ -1,40 +1,42 @@
|
||||||
FastAdmin是一款基于ThinkPHP5+Bootstrap的极速后台开发框架。
|
FastAdmin是一款基于ThinkPHP+Bootstrap的极速后台开发框架。
|
||||||
===============
|
|
||||||
|
|
||||||
|
|
||||||
## **主要特性**
|
## 主要特性
|
||||||
|
|
||||||
* 基于Auth的权限管理系统
|
* 基于`Auth`验证的权限管理系统
|
||||||
* 支持无限级父子级权限继承,父级的管理员可任意增删改子级管理员及权限设置
|
* 支持无限级父子级权限继承,父级的管理员可任意增删改子级管理员及权限设置
|
||||||
* 支持单管理员多角色
|
* 支持单管理员多角色
|
||||||
* 支持管理子级数据或个人数据
|
* 支持管理子级数据或个人数据
|
||||||
* 强大的一键生成功能
|
* 强大的一键生成功能
|
||||||
* 一键生成CRUD,包括控制器、模型、视图、JS、语言包、菜单等
|
* 一键生成CRUD,包括控制器、模型、视图、JS、语言包、菜单、回收站等
|
||||||
* 一键压缩打包JS和CSS文件,一键CDN静态资源部署
|
* 一键压缩打包JS和CSS文件,一键CDN静态资源部署
|
||||||
* 一键生成控制器菜单和规则
|
* 一键生成控制器菜单和规则
|
||||||
* 一键生成API接口文档
|
* 一键生成API接口文档
|
||||||
* 完善的前端功能组件
|
* 完善的前端功能组件开发
|
||||||
* 基于AdminLTE二次开发
|
* 基于`AdminLTE`二次开发
|
||||||
* 基于Bootstrap开发,自适应手机、平板、PC
|
* 基于`Bootstrap`开发,自适应手机、平板、PC
|
||||||
* 基于RequireJS进行JS模块管理,按需加载
|
* 基于`RequireJS`进行JS模块管理,按需加载
|
||||||
* 基于Bower进行前端组件包管理
|
* 基于`Less`进行样式开发
|
||||||
* 强大的插件扩展功能,在线安装卸载升级插件
|
* 强大的插件扩展功能,在线安装卸载升级插件
|
||||||
* 通用的会员模块和API模块
|
* 通用的会员模块和API模块
|
||||||
* 共用同一账号体系的Web端会员中心权限验证和API接口会员权限验证
|
* 共用同一账号体系的Web端会员中心权限验证和API接口会员权限验证
|
||||||
* 二级域名部署支持,同时域名支持绑定到插件
|
* 二级域名部署支持,同时域名支持绑定到应用插件
|
||||||
* 多语言支持,服务端及客户端支持
|
* 多语言支持,服务端及客户端支持
|
||||||
* 强大的第三方模块支持(CMS、博客、文档生成)
|
* 支持大文件分片上传、剪切板粘贴上传、拖拽上传,进度条显示,图片上传前压缩
|
||||||
* 整合第三方短信接口(阿里云、创蓝短信)
|
* 支持表格固定列、固定表头、跨页选择、Excel导出、模板渲染等功能
|
||||||
* 无缝整合第三方云存储(七牛、阿里云OSS、又拍云)功能
|
* 强大的第三方应用模块支持([CMS](https://www.fastadmin.net/store/cms.html)、[CRM](https://www.fastadmin.net/store/facrm.html)、[企业网站管理系统](https://www.fastadmin.net/store/ldcms.html)、[知识库文档系统](https://www.fastadmin.net/store/knowbase.html)、[在线投票系统](https://www.fastadmin.net/store/vote.html)、[B2C商城](https://www.fastadmin.net/store/shopro.html)、[B2B2C商城](https://www.fastadmin.net/store/wanlshop.html))
|
||||||
* 第三方富文本编辑器支持(Summernote、Tinymce、百度编辑器)
|
* 整合第三方短信接口(阿里云、腾讯云短信)
|
||||||
|
* 无缝整合第三方云存储(七牛云、阿里云OSS、腾讯云存储、又拍云)功能,支持云储存分片上传
|
||||||
|
* 第三方富文本编辑器支持(Summernote、百度编辑器)
|
||||||
* 第三方登录(QQ、微信、微博)整合
|
* 第三方登录(QQ、微信、微博)整合
|
||||||
* Ucenter整合第三方应用
|
* 第三方支付(微信、支付宝)无缝整合,微信支持PC端扫码支付
|
||||||
|
* 丰富的插件应用市场
|
||||||
|
|
||||||
## **安装使用**
|
## 安装使用
|
||||||
|
|
||||||
https://doc.fastadmin.net
|
https://doc.fastadmin.net
|
||||||
|
|
||||||
## **在线演示**
|
## 在线演示
|
||||||
|
|
||||||
https://demo.fastadmin.net
|
https://demo.fastadmin.net
|
||||||
|
|
||||||
|
|
@ -44,24 +46,20 @@ https://demo.fastadmin.net
|
||||||
|
|
||||||
提 示:演示站数据无法进行修改,请下载源码安装体验全部功能
|
提 示:演示站数据无法进行修改,请下载源码安装体验全部功能
|
||||||
|
|
||||||
## **界面截图**
|
## 界面截图
|
||||||

|

|
||||||
|
|
||||||
## **问题反馈**
|
## 问题反馈
|
||||||
|
|
||||||
在使用中有任何问题,请使用以下联系方式联系我们
|
在使用中有任何问题,请使用以下联系方式联系我们
|
||||||
|
|
||||||
交流社区: https://forum.fastadmin.net
|
问答社区: https://ask.fastadmin.net
|
||||||
|
|
||||||
QQ群: [636393962](https://jq.qq.com/?_wv=1027&k=487PNBb)(交流群①) [708784003](https://jq.qq.com/?_wv=1027&k=5ObjtwM)(交流群②) [696992864](https://jq.qq.com/?_wv=1027&k=5R2AB00)(高级群,付费加入)
|
|
||||||
|
|
||||||
Email: (karsonzhang#163.com, 把#换成@)
|
|
||||||
|
|
||||||
Github: https://github.com/karsonzhang/fastadmin
|
Github: https://github.com/karsonzhang/fastadmin
|
||||||
|
|
||||||
Gitee: https://gitee.com/karson/fastadmin
|
Gitee: https://gitee.com/karson/fastadmin
|
||||||
|
|
||||||
## **特别鸣谢**
|
## 特别鸣谢
|
||||||
|
|
||||||
感谢以下的项目,排名不分先后
|
感谢以下的项目,排名不分先后
|
||||||
|
|
||||||
|
|
@ -79,6 +77,10 @@ Nice-validator: https://validator.niceue.com
|
||||||
|
|
||||||
SelectPage: https://github.com/TerryZ/SelectPage
|
SelectPage: https://github.com/TerryZ/SelectPage
|
||||||
|
|
||||||
|
Layer: https://layuion.com/layer/
|
||||||
|
|
||||||
|
DropzoneJS: https://www.dropzonejs.com
|
||||||
|
|
||||||
|
|
||||||
## 版权信息
|
## 版权信息
|
||||||
|
|
||||||
|
|
@ -86,6 +88,6 @@ FastAdmin遵循Apache2开源协议发布,并提供免费使用。
|
||||||
|
|
||||||
本项目包含的第三方源码和二进制文件之版权信息另行标注。
|
本项目包含的第三方源码和二进制文件之版权信息另行标注。
|
||||||
|
|
||||||
版权所有Copyright © 2017-2018 by FastAdmin (https://www.fastadmin.net)
|
版权所有Copyright © 2017-2024 by FastAdmin (https://www.fastadmin.net)
|
||||||
|
|
||||||
All rights reserved。
|
All rights reserved。
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
deny from all
|
||||||
|
|
@ -4,13 +4,11 @@ namespace app\admin\behavior;
|
||||||
|
|
||||||
class AdminLog
|
class AdminLog
|
||||||
{
|
{
|
||||||
|
public function run(&$response)
|
||||||
public function run(&$params)
|
|
||||||
{
|
{
|
||||||
if (request()->isPost())
|
//只记录POST请求的日志
|
||||||
{
|
if (request()->isPost() && config('fastadmin.auto_record_log')) {
|
||||||
\app\admin\model\AdminLog::record();
|
\app\admin\model\AdminLog::record();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,26 +15,28 @@ use think\exception\PDOException;
|
||||||
|
|
||||||
class Addon extends Command
|
class Addon extends Command
|
||||||
{
|
{
|
||||||
|
|
||||||
protected function configure()
|
protected function configure()
|
||||||
{
|
{
|
||||||
$this
|
$this
|
||||||
->setName('addon')
|
->setName('addon')
|
||||||
->addOption('name', 'a', Option::VALUE_REQUIRED, 'addon name', null)
|
->addOption('name', 'a', Option::VALUE_REQUIRED, 'addon name', null)
|
||||||
->addOption('action', 'c', Option::VALUE_REQUIRED, 'action(create/enable/disable/install/uninstall/refresh/upgrade/package)', 'create')
|
->addOption('action', 'c', Option::VALUE_REQUIRED, 'action(create/enable/disable/uninstall/refresh/package/move)', 'create')
|
||||||
->addOption('force', 'f', Option::VALUE_OPTIONAL, 'force override', null)
|
->addOption('force', 'f', Option::VALUE_OPTIONAL, 'force override', null)
|
||||||
->addOption('release', 'r', Option::VALUE_OPTIONAL, 'addon release version', null)
|
->addOption('release', 'r', Option::VALUE_OPTIONAL, 'addon release version', null)
|
||||||
->addOption('uid', 'u', Option::VALUE_OPTIONAL, 'fastadmin uid', null)
|
->addOption('uid', 'u', Option::VALUE_OPTIONAL, 'fastadmin uid', null)
|
||||||
->addOption('token', 't', Option::VALUE_OPTIONAL, 'fastadmin token', null)
|
->addOption('token', 't', Option::VALUE_OPTIONAL, 'fastadmin token', null)
|
||||||
|
->addOption('domain', 'd', Option::VALUE_OPTIONAL, 'domain', null)
|
||||||
|
->addOption('local', 'l', Option::VALUE_OPTIONAL, 'local package', null)
|
||||||
->setDescription('Addon manager');
|
->setDescription('Addon manager');
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function execute(Input $input, Output $output)
|
protected function execute(Input $input, Output $output)
|
||||||
{
|
{
|
||||||
|
\think\Config::load(dirname(dirname(__FILE__)) . DS . 'config.php');
|
||||||
$name = $input->getOption('name') ?: '';
|
$name = $input->getOption('name') ?: '';
|
||||||
$action = $input->getOption('action') ?: '';
|
$action = $input->getOption('action') ?: '';
|
||||||
if(stripos($name, 'addons/')!==false){
|
if (stripos($name, 'addons' . DS) !== false) {
|
||||||
$name = explode('/', $name)[1];
|
$name = explode(DS, $name)[1];
|
||||||
}
|
}
|
||||||
//强制覆盖
|
//强制覆盖
|
||||||
$force = $input->getOption('force');
|
$force = $input->getOption('force');
|
||||||
|
|
@ -47,10 +49,10 @@ class Addon extends Command
|
||||||
|
|
||||||
include dirname(__DIR__) . DS . 'common.php';
|
include dirname(__DIR__) . DS . 'common.php';
|
||||||
|
|
||||||
if (!$name) {
|
if (!$name && !in_array($action, ['refresh'])) {
|
||||||
throw new Exception('Addon name could not be empty');
|
throw new Exception('Addon name could not be empty');
|
||||||
}
|
}
|
||||||
if (!$action || !in_array($action, ['create', 'disable', 'enable', 'install', 'uninstall', 'refresh', 'upgrade', 'package'])) {
|
if (!$action || !in_array($action, ['create', 'disable', 'enable', 'install', 'uninstall', 'refresh', 'upgrade', 'package', 'move'])) {
|
||||||
throw new Exception('Please input correct action name');
|
throw new Exception('Please input correct action name');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -80,14 +82,13 @@ class Addon extends Command
|
||||||
$createTableSql = $result[0]['Create Table'];
|
$createTableSql = $result[0]['Create Table'];
|
||||||
}
|
}
|
||||||
} catch (PDOException $e) {
|
} catch (PDOException $e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
'name' => $name,
|
'name' => $name,
|
||||||
'addon' => $name,
|
'addon' => $name,
|
||||||
'addonClassName' => ucfirst($name),
|
'addonClassName' => ucfirst($name),
|
||||||
'addonInstallMenu' => $createMenu ? "\$menu = " . var_export_short($createMenu, "\t") . ";\n\tMenu::create(\$menu);" : '',
|
'addonInstallMenu' => $createMenu ? "\$menu = " . var_export_short($createMenu) . ";\n\tMenu::create(\$menu);" : '',
|
||||||
'addonUninstallMenu' => $menuList ? 'Menu::delete("' . $name . '");' : '',
|
'addonUninstallMenu' => $menuList ? 'Menu::delete("' . $name . '");' : '',
|
||||||
'addonEnableMenu' => $menuList ? 'Menu::enable("' . $name . '");' : '',
|
'addonEnableMenu' => $menuList ? 'Menu::enable("' . $name . '");' : '',
|
||||||
'addonDisableMenu' => $menuList ? 'Menu::disable("' . $name . '");' : '',
|
'addonDisableMenu' => $menuList ? 'Menu::disable("' . $name . '");' : '',
|
||||||
|
|
@ -119,7 +120,7 @@ class Addon extends Command
|
||||||
$output->warning($v);
|
$output->warning($v);
|
||||||
}
|
}
|
||||||
$output->info("Are you sure you want to " . ($action == 'enable' ? 'override' : 'delete') . " all those files? Type 'yes' to continue: ");
|
$output->info("Are you sure you want to " . ($action == 'enable' ? 'override' : 'delete') . " all those files? Type 'yes' to continue: ");
|
||||||
$line = fgets(STDIN);
|
$line = fgets(defined('STDIN') ? STDIN : fopen('php://stdin', 'r'));
|
||||||
if (trim($line) != 'yes') {
|
if (trim($line) != 'yes') {
|
||||||
throw new Exception("Operation is aborted!");
|
throw new Exception("Operation is aborted!");
|
||||||
}
|
}
|
||||||
|
|
@ -131,40 +132,6 @@ class Addon extends Command
|
||||||
}
|
}
|
||||||
$output->info(ucfirst($action) . " Successed!");
|
$output->info(ucfirst($action) . " Successed!");
|
||||||
break;
|
break;
|
||||||
case 'install':
|
|
||||||
//非覆盖模式时如果存在则报错
|
|
||||||
if (is_dir($addonDir) && !$force) {
|
|
||||||
throw new Exception("addon already exists!\nIf you need to install again, use the parameter --force=true ");
|
|
||||||
}
|
|
||||||
//如果存在先移除
|
|
||||||
if (is_dir($addonDir)) {
|
|
||||||
rmdirs($addonDir);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
Service::install($name, 0, ['version' => $release]);
|
|
||||||
} catch (AddonException $e) {
|
|
||||||
if ($e->getCode() != -3) {
|
|
||||||
throw new Exception($e->getMessage());
|
|
||||||
}
|
|
||||||
if (!$force) {
|
|
||||||
//如果有冲突文件则提醒
|
|
||||||
$data = $e->getData();
|
|
||||||
foreach ($data['conflictlist'] as $k => $v) {
|
|
||||||
$output->warning($v);
|
|
||||||
}
|
|
||||||
$output->info("Are you sure you want to override all those files? Type 'yes' to continue: ");
|
|
||||||
$line = fgets(STDIN);
|
|
||||||
if (trim($line) != 'yes') {
|
|
||||||
throw new Exception("Operation is aborted!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Service::install($name, 1, ['version' => $release, 'uid' => $uid, 'token' => $token]);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
throw new Exception($e->getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
$output->info("Install Successed!");
|
|
||||||
break;
|
|
||||||
case 'uninstall':
|
case 'uninstall':
|
||||||
//非覆盖模式时如果存在则报错
|
//非覆盖模式时如果存在则报错
|
||||||
if (!$force) {
|
if (!$force) {
|
||||||
|
|
@ -183,7 +150,7 @@ class Addon extends Command
|
||||||
$output->warning($v);
|
$output->warning($v);
|
||||||
}
|
}
|
||||||
$output->info("Are you sure you want to delete all those files? Type 'yes' to continue: ");
|
$output->info("Are you sure you want to delete all those files? Type 'yes' to continue: ");
|
||||||
$line = fgets(STDIN);
|
$line = fgets(defined('STDIN') ? STDIN : fopen('php://stdin', 'r'));
|
||||||
if (trim($line) != 'yes') {
|
if (trim($line) != 'yes') {
|
||||||
throw new Exception("Operation is aborted!");
|
throw new Exception("Operation is aborted!");
|
||||||
}
|
}
|
||||||
|
|
@ -199,10 +166,6 @@ class Addon extends Command
|
||||||
Service::refresh();
|
Service::refresh();
|
||||||
$output->info("Refresh Successed!");
|
$output->info("Refresh Successed!");
|
||||||
break;
|
break;
|
||||||
case 'upgrade':
|
|
||||||
Service::upgrade($name, ['version' => $release, 'uid' => $uid, 'token' => $token]);
|
|
||||||
$output->info("Upgrade Successed!");
|
|
||||||
break;
|
|
||||||
case 'package':
|
case 'package':
|
||||||
$infoFile = $addonDir . 'info.ini';
|
$infoFile = $addonDir . 'info.ini';
|
||||||
if (!is_file($infoFile)) {
|
if (!is_file($infoFile)) {
|
||||||
|
|
@ -213,12 +176,12 @@ class Addon extends Command
|
||||||
if (!$info) {
|
if (!$info) {
|
||||||
throw new Exception(__('Addon info file data incorrect'));
|
throw new Exception(__('Addon info file data incorrect'));
|
||||||
}
|
}
|
||||||
$infoname = isset($info['name']) ? $info['name'] : '';
|
$infoname = $info['name'] ?? '';
|
||||||
if (!$infoname || !preg_match("/^[a-z]+$/i", $infoname) || $infoname != $name) {
|
if (!$infoname || !preg_match("/^[a-z]+$/i", $infoname) || $infoname != $name) {
|
||||||
throw new Exception(__('Addon info name incorrect'));
|
throw new Exception(__('Addon info name incorrect'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$infoversion = isset($info['version']) ? $info['version'] : '';
|
$infoversion = $info['version'] ?? '';
|
||||||
if (!$infoversion || !preg_match("/^\d+\.\d+\.\d+$/i", $infoversion)) {
|
if (!$infoversion || !preg_match("/^\d+\.\d+\.\d+$/i", $infoversion)) {
|
||||||
throw new Exception(__('Addon info version incorrect'));
|
throw new Exception(__('Addon info version incorrect'));
|
||||||
}
|
}
|
||||||
|
|
@ -241,7 +204,7 @@ class Addon extends Command
|
||||||
foreach ($files as $name => $file) {
|
foreach ($files as $name => $file) {
|
||||||
if (!$file->isDir()) {
|
if (!$file->isDir()) {
|
||||||
$filePath = $file->getRealPath();
|
$filePath = $file->getRealPath();
|
||||||
$relativePath = substr($filePath, strlen($addonDir));
|
$relativePath = str_replace(DS, '/', substr($filePath, strlen($addonDir)));
|
||||||
if (!in_array($file->getFilename(), ['.git', '.DS_Store', 'Thumbs.db'])) {
|
if (!in_array($file->getFilename(), ['.git', '.DS_Store', 'Thumbs.db'])) {
|
||||||
$zip->addFile($filePath, $relativePath);
|
$zip->addFile($filePath, $relativePath);
|
||||||
}
|
}
|
||||||
|
|
@ -250,8 +213,69 @@ class Addon extends Command
|
||||||
$zip->close();
|
$zip->close();
|
||||||
$output->info("Package Successed!");
|
$output->info("Package Successed!");
|
||||||
break;
|
break;
|
||||||
|
case 'move':
|
||||||
default :
|
$movePath = [
|
||||||
|
'adminOnlySelfDir' => ['admin/behavior', 'admin/controller', 'admin/library', 'admin/model', 'admin/validate', 'admin/view'],
|
||||||
|
'adminAllSubDir' => ['admin/lang'],
|
||||||
|
'publicDir' => ['public/assets/addons', 'public/assets/js/backend']
|
||||||
|
];
|
||||||
|
$paths = [];
|
||||||
|
$appPath = str_replace('/', DS, APP_PATH);
|
||||||
|
$rootPath = str_replace('/', DS, ROOT_PATH);
|
||||||
|
foreach ($movePath as $k => $items) {
|
||||||
|
switch ($k) {
|
||||||
|
case 'adminOnlySelfDir':
|
||||||
|
foreach ($items as $v) {
|
||||||
|
$v = str_replace('/', DS, $v);
|
||||||
|
$oldPath = $appPath . $v . DS . $name;
|
||||||
|
$newPath = $rootPath . "addons" . DS . $name . DS . "application" . DS . $v . DS . $name;
|
||||||
|
$paths[$oldPath] = $newPath;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'adminAllSubDir':
|
||||||
|
foreach ($items as $v) {
|
||||||
|
$v = str_replace('/', DS, $v);
|
||||||
|
$vPath = $appPath . $v;
|
||||||
|
$list = scandir($vPath);
|
||||||
|
foreach ($list as $_v) {
|
||||||
|
if (!in_array($_v, ['.', '..']) && is_dir($vPath . DS . $_v)) {
|
||||||
|
$oldPath = $appPath . $v . DS . $_v . DS . $name;
|
||||||
|
$newPath = $rootPath . "addons" . DS . $name . DS . "application" . DS . $v . DS . $_v . DS . $name;
|
||||||
|
$paths[$oldPath] = $newPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'publicDir':
|
||||||
|
foreach ($items as $v) {
|
||||||
|
$v = str_replace('/', DS, $v);
|
||||||
|
$oldPath = $rootPath . $v . DS . $name;
|
||||||
|
$newPath = $rootPath . 'addons' . DS . $name . DS . $v . DS . $name;
|
||||||
|
$paths[$oldPath] = $newPath;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach ($paths as $oldPath => $newPath) {
|
||||||
|
if (is_dir($oldPath)) {
|
||||||
|
if ($force) {
|
||||||
|
if (is_dir($newPath)) {
|
||||||
|
$list = scandir($newPath);
|
||||||
|
foreach ($list as $_v) {
|
||||||
|
if (!in_array($_v, ['.', '..'])) {
|
||||||
|
$file = $newPath . DS . $_v;
|
||||||
|
@chmod($file, 0777);
|
||||||
|
@unlink($file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@rmdir($newPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
copydirs($oldPath, $newPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -286,7 +310,7 @@ class Addon extends Command
|
||||||
/**
|
/**
|
||||||
* 写入到文件
|
* 写入到文件
|
||||||
* @param string $name
|
* @param string $name
|
||||||
* @param array $data
|
* @param array $data
|
||||||
* @param string $pathname
|
* @param string $pathname
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
|
|
@ -315,5 +339,4 @@ class Addon extends Command
|
||||||
{
|
{
|
||||||
return __DIR__ . '/Addon/stubs/' . $name . '.stub';
|
return __DIR__ . '/Addon/stubs/' . $name . '.stub';
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -51,18 +51,4 @@ class {%addonClassName%} extends Addons
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 实现钩子方法
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
public function testhook($param)
|
|
||||||
{
|
|
||||||
// 调用钩子时候的参数信息
|
|
||||||
print_r($param);
|
|
||||||
// 当前插件的配置信息,配置信息存在当前目录的config.php文件中,见下方
|
|
||||||
print_r($this->getConfig());
|
|
||||||
// 可以返回模板,模板文件默认读取的为插件目录中的文件。模板名不能为空!
|
|
||||||
//return $this->fetch('view/info');
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,17 +3,21 @@
|
||||||
return [
|
return [
|
||||||
[
|
[
|
||||||
//配置唯一标识
|
//配置唯一标识
|
||||||
'name' => 'usernmae',
|
'name' => 'username',
|
||||||
//显示的标题
|
//显示的标题
|
||||||
'title' => '用户名',
|
'title' => '用户名',
|
||||||
//类型
|
//类型
|
||||||
'type' => 'string',
|
'type' => 'string',
|
||||||
|
//分组
|
||||||
|
'group' => '',
|
||||||
|
//动态显示
|
||||||
|
'visible' => '',
|
||||||
//数据字典
|
//数据字典
|
||||||
'content' => [
|
'content' => [
|
||||||
],
|
],
|
||||||
//值
|
//值
|
||||||
'value' => '',
|
'value' => '',
|
||||||
//验证规则
|
//验证规则
|
||||||
'rule' => 'required',
|
'rule' => 'required',
|
||||||
//错误消息
|
//错误消息
|
||||||
'msg' => '',
|
'msg' => '',
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
name = {%name%}
|
name = {%name%}
|
||||||
title = 插件名称{%name%}
|
title = 插件名称{%name%}
|
||||||
intro = FastAdmin插件
|
intro = 插件介绍
|
||||||
author = yourname
|
author = yourname
|
||||||
website = https://www.fastadmin.net
|
website = https://www.fastadmin.net
|
||||||
version = 1.0.0
|
version = 1.0.0
|
||||||
state = 1
|
state = 1
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ use think\Exception;
|
||||||
|
|
||||||
class Api extends Command
|
class Api extends Command
|
||||||
{
|
{
|
||||||
|
|
||||||
protected function configure()
|
protected function configure()
|
||||||
{
|
{
|
||||||
$site = Config::get('site');
|
$site = Config::get('site');
|
||||||
|
|
@ -23,11 +22,12 @@ class Api extends Command
|
||||||
->addOption('output', 'o', Option::VALUE_OPTIONAL, 'output index file name', 'api.html')
|
->addOption('output', 'o', Option::VALUE_OPTIONAL, 'output index file name', 'api.html')
|
||||||
->addOption('template', 'e', Option::VALUE_OPTIONAL, '', 'index.html')
|
->addOption('template', 'e', Option::VALUE_OPTIONAL, '', 'index.html')
|
||||||
->addOption('force', 'f', Option::VALUE_OPTIONAL, 'force override general file', false)
|
->addOption('force', 'f', Option::VALUE_OPTIONAL, 'force override general file', false)
|
||||||
->addOption('title', 't', Option::VALUE_OPTIONAL, 'document title', $site['name'])
|
->addOption('title', 't', Option::VALUE_OPTIONAL, 'document title', $site['name'] ?? '')
|
||||||
->addOption('author', 'a', Option::VALUE_OPTIONAL, 'document author', $site['name'])
|
|
||||||
->addOption('class', 'c', Option::VALUE_OPTIONAL | Option::VALUE_IS_ARRAY, 'extend class', null)
|
->addOption('class', 'c', Option::VALUE_OPTIONAL | Option::VALUE_IS_ARRAY, 'extend class', null)
|
||||||
->addOption('language', 'l', Option::VALUE_OPTIONAL, 'language', 'zh-cn')
|
->addOption('language', 'l', Option::VALUE_OPTIONAL, 'language', 'zh-cn')
|
||||||
->setDescription('Compress js and css file');
|
->addOption('addon', 'a', Option::VALUE_OPTIONAL, 'addon name', null)
|
||||||
|
->addOption('controller', 'r', Option::VALUE_REQUIRED | Option::VALUE_IS_ARRAY, 'controller name', null)
|
||||||
|
->setDescription('Build Api document from controller');
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function execute(Input $input, Output $output)
|
protected function execute(Input $input, Output $output)
|
||||||
|
|
@ -37,6 +37,10 @@ class Api extends Command
|
||||||
$force = $input->getOption('force');
|
$force = $input->getOption('force');
|
||||||
$url = $input->getOption('url');
|
$url = $input->getOption('url');
|
||||||
$language = $input->getOption('language');
|
$language = $input->getOption('language');
|
||||||
|
$template = $input->getOption('template');
|
||||||
|
if (!preg_match("/^([a-z0-9]+)\.html\$/i", $template)) {
|
||||||
|
throw new Exception('template file not correct');
|
||||||
|
}
|
||||||
$language = $language ? $language : 'zh-cn';
|
$language = $language ? $language : 'zh-cn';
|
||||||
$langFile = $apiDir . 'lang' . DS . $language . '.php';
|
$langFile = $apiDir . 'lang' . DS . $language . '.php';
|
||||||
if (!is_file($langFile)) {
|
if (!is_file($langFile)) {
|
||||||
|
|
@ -51,7 +55,7 @@ class Api extends Command
|
||||||
}
|
}
|
||||||
// 模板文件
|
// 模板文件
|
||||||
$template_dir = $apiDir . 'template' . DS;
|
$template_dir = $apiDir . 'template' . DS;
|
||||||
$template_file = $template_dir . $input->getOption('template');
|
$template_file = $template_dir . $template;
|
||||||
if (!is_file($template_file)) {
|
if (!is_file($template_file)) {
|
||||||
throw new Exception('template file not found');
|
throw new Exception('template file not found');
|
||||||
}
|
}
|
||||||
|
|
@ -59,48 +63,62 @@ class Api extends Command
|
||||||
$classes = $input->getOption('class');
|
$classes = $input->getOption('class');
|
||||||
// 标题
|
// 标题
|
||||||
$title = $input->getOption('title');
|
$title = $input->getOption('title');
|
||||||
// 作者
|
|
||||||
$author = $input->getOption('author');
|
|
||||||
// 模块
|
// 模块
|
||||||
$module = $input->getOption('module');
|
$module = $input->getOption('module');
|
||||||
|
// 插件
|
||||||
|
$addon = $input->getOption('addon');
|
||||||
|
|
||||||
$moduleDir = APP_PATH . $module . DS;
|
$moduleDir = $addonDir = '';
|
||||||
|
if ($addon) {
|
||||||
|
$addonInfo = get_addon_info($addon);
|
||||||
|
if (!$addonInfo) {
|
||||||
|
throw new Exception('addon not found');
|
||||||
|
}
|
||||||
|
$moduleDir = ADDON_PATH . $addon . DS;
|
||||||
|
} else {
|
||||||
|
$moduleDir = APP_PATH . $module . DS;
|
||||||
|
}
|
||||||
if (!is_dir($moduleDir)) {
|
if (!is_dir($moduleDir)) {
|
||||||
throw new Exception('module not found');
|
throw new Exception('module not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version_compare(PHP_VERSION, '7.0.0', '<')) {
|
if (version_compare(PHP_VERSION, '7.0.0', '<')) {
|
||||||
if (extension_loaded('opcache')) {
|
throw new Exception("Requires PHP version 7.0 or newer");
|
||||||
$configuration = opcache_get_configuration();
|
}
|
||||||
$directives = $configuration['directives'];
|
|
||||||
$configName = request()->isCli() ? 'opcache.enable_cli' : 'opcache.enable';
|
//控制器名
|
||||||
if (!$directives[$configName]) {
|
$controller = $input->getOption('controller') ?: [];
|
||||||
throw new Exception("Please make sure {$configName} is turned on, Get help:https://forum.fastadmin.net/d/1321");
|
if (!$controller) {
|
||||||
|
$controllerDir = $moduleDir . Config::get('url_controller_layer') . DS;
|
||||||
|
$files = new \RecursiveIteratorIterator(
|
||||||
|
new \RecursiveDirectoryIterator($controllerDir),
|
||||||
|
\RecursiveIteratorIterator::LEAVES_ONLY
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($files as $name => $file) {
|
||||||
|
if (!$file->isDir() && $file->getExtension() == 'php') {
|
||||||
|
$filePath = $file->getRealPath();
|
||||||
|
$classes[] = $this->getClassFromFile($filePath);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
throw new Exception("Please make sure opcache already enabled, Get help:https://forum.fastadmin.net/d/1321");
|
} else {
|
||||||
|
foreach ($controller as $index => $item) {
|
||||||
|
$filePath = $moduleDir . Config::get('url_controller_layer') . DS . $item . '.php';
|
||||||
|
$classes[] = $this->getClassFromFile($filePath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$controllerDir = $moduleDir . Config::get('url_controller_layer') . DS;
|
$classes = array_unique(array_filter($classes));
|
||||||
$files = new \RecursiveIteratorIterator(
|
|
||||||
new \RecursiveDirectoryIterator($controllerDir), \RecursiveIteratorIterator::LEAVES_ONLY
|
|
||||||
);
|
|
||||||
|
|
||||||
foreach ($files as $name => $file) {
|
|
||||||
if (!$file->isDir()) {
|
|
||||||
$filePath = $file->getRealPath();
|
|
||||||
$classes[] = $this->get_class_from_file($filePath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$config = [
|
$config = [
|
||||||
|
'sitename' => config('site.name'),
|
||||||
'title' => $title,
|
'title' => $title,
|
||||||
'author' => $author,
|
'author' => config('site.name'),
|
||||||
'description' => '',
|
'description' => '',
|
||||||
'apiurl' => $url,
|
'apiurl' => $url,
|
||||||
'language' => $language,
|
'language' => $language,
|
||||||
];
|
];
|
||||||
|
|
||||||
$builder = new Builder($classes);
|
$builder = new Builder($classes);
|
||||||
$content = $builder->render($template_file, ['config' => $config, 'lang' => $lang]);
|
$content = $builder->render($template_file, ['config' => $config, 'lang' => $lang]);
|
||||||
|
|
||||||
|
|
@ -111,68 +129,61 @@ class Api extends Command
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get full qualified class name
|
* 从文件获取命名空间和类名
|
||||||
*
|
*
|
||||||
* @param string $path_to_file
|
* @param string $filename
|
||||||
* @author JBYRNE http://jarretbyrne.com/2015/06/197/
|
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected function get_class_from_file($path_to_file)
|
protected function getClassFromFile($filename)
|
||||||
{
|
{
|
||||||
//Grab the contents of the file
|
$getNext = null;
|
||||||
$contents = file_get_contents($path_to_file);
|
$isNamespace = false;
|
||||||
|
$skipNext = false;
|
||||||
//Start with a blank namespace and class
|
$namespace = '';
|
||||||
$namespace = $class = "";
|
$class = '';
|
||||||
|
foreach (\PhpToken::tokenize(file_get_contents($filename)) as $token) {
|
||||||
//Set helper values to know that we have found the namespace/class token and need to collect the string values after them
|
if (!$token->isIgnorable()) {
|
||||||
$getting_namespace = $getting_class = false;
|
$name = $token->getTokenName();
|
||||||
|
switch ($name) {
|
||||||
//Go through each token and evaluate it as necessary
|
case 'T_NAMESPACE':
|
||||||
foreach (token_get_all($contents) as $token) {
|
$isNamespace = true;
|
||||||
|
break;
|
||||||
//If this token is the namespace declaring, then flag that the next tokens will be the namespace name
|
case 'T_EXTENDS':
|
||||||
if (is_array($token) && $token[0] == T_NAMESPACE) {
|
case 'T_USE':
|
||||||
$getting_namespace = true;
|
case 'T_IMPLEMENTS':
|
||||||
}
|
$skipNext = true;
|
||||||
|
break;
|
||||||
//If this token is the class declaring, then flag that the next tokens will be the class name
|
case 'T_CLASS':
|
||||||
if (is_array($token) && $token[0] == T_CLASS) {
|
if ($skipNext) {
|
||||||
$getting_class = true;
|
$skipNext = false;
|
||||||
}
|
} else {
|
||||||
|
$getNext = strtolower(substr($name, 2));
|
||||||
//While we're grabbing the namespace name...
|
}
|
||||||
if ($getting_namespace === true) {
|
break;
|
||||||
|
case 'T_NAME_QUALIFIED':
|
||||||
//If the token is a string or the namespace separator...
|
case 'T_NS_SEPARATOR':
|
||||||
if (is_array($token) && in_array($token[0], [T_STRING, T_NS_SEPARATOR])) {
|
case 'T_STRING':
|
||||||
|
case ';':
|
||||||
//Append the token's value to the name of the namespace
|
if ($isNamespace) {
|
||||||
$namespace .= $token[1];
|
if ($name == ';') {
|
||||||
} else if ($token === ';') {
|
$isNamespace = false;
|
||||||
|
} else {
|
||||||
//If the token is the semicolon, then we're done with the namespace declaration
|
$namespace .= $token->text;
|
||||||
$getting_namespace = false;
|
}
|
||||||
}
|
} elseif ($skipNext) {
|
||||||
}
|
$skipNext = false;
|
||||||
|
} elseif ($getNext == 'class') {
|
||||||
//While we're grabbing the class name...
|
$class = $token->text;
|
||||||
if ($getting_class === true) {
|
$getNext = null;
|
||||||
|
break 2;
|
||||||
//If the token is a string, it's the name of the class
|
}
|
||||||
if (is_array($token) && $token[0] == T_STRING) {
|
break;
|
||||||
|
default:
|
||||||
//Store the token's value as the class name
|
$getNext = null;
|
||||||
$class = $token[1];
|
|
||||||
|
|
||||||
//Got what we need, stope here
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Build the fully-qualified class name and return it
|
return $namespace . '\\' . $class;
|
||||||
return $namespace ? $namespace . '\\' . $class : $class;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,13 @@ return [
|
||||||
'Required' => '必选',
|
'Required' => '必选',
|
||||||
'Description' => '描述',
|
'Description' => '描述',
|
||||||
'Send' => '提交',
|
'Send' => '提交',
|
||||||
|
'Reset' => '重置',
|
||||||
'Tokentips' => 'Token在会员注册或登录后都会返回,WEB端同时存在于Cookie中',
|
'Tokentips' => 'Token在会员注册或登录后都会返回,WEB端同时存在于Cookie中',
|
||||||
'Apiurltips' => 'API接口URL',
|
'Apiurltips' => 'API接口URL',
|
||||||
'Savetips' => '点击保存后Token和Api url都将保存在本地Localstorage中',
|
'Savetips' => '点击保存后Token和Api url都将保存在本地Localstorage中',
|
||||||
|
'Authorization' => '权限',
|
||||||
|
'NeedLogin' => '登录',
|
||||||
|
'NeedRight' => '鉴权',
|
||||||
'ReturnHeaders' => '响应头',
|
'ReturnHeaders' => '响应头',
|
||||||
'ReturnParameters' => '返回参数',
|
'ReturnParameters' => '返回参数',
|
||||||
'Response' => '响应输出',
|
'Response' => '响应输出',
|
||||||
|
|
|
||||||
|
|
@ -7,25 +7,25 @@ use think\Config;
|
||||||
/**
|
/**
|
||||||
* @website https://github.com/calinrada/php-apidoc
|
* @website https://github.com/calinrada/php-apidoc
|
||||||
* @author Calin Rada <rada.calin@gmail.com>
|
* @author Calin Rada <rada.calin@gmail.com>
|
||||||
* @author Karson <karsonzhang@163.com>
|
* @author Karson <karson@fastadmin.net>
|
||||||
*/
|
*/
|
||||||
class Builder
|
class Builder
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @var \think\View
|
* @var \think\View
|
||||||
*/
|
*/
|
||||||
public $view = null;
|
public $view = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* parse classes
|
* parse classes
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $classes = [];
|
protected $classes = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param array $classes
|
* @param array $classes
|
||||||
*/
|
*/
|
||||||
public function __construct($classes = [])
|
public function __construct($classes = [])
|
||||||
|
|
@ -36,30 +36,45 @@ class Builder
|
||||||
|
|
||||||
protected function extractAnnotations()
|
protected function extractAnnotations()
|
||||||
{
|
{
|
||||||
$st_output = [];
|
foreach ($this->classes as $class) {
|
||||||
foreach ($this->classes as $class)
|
$classAnnotation = Extractor::getClassAnnotations($class);
|
||||||
{
|
// 如果忽略
|
||||||
$st_output[] = Extractor::getAllClassAnnotations($class);
|
if (isset($classAnnotation['ApiInternal'])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Extractor::getClassMethodAnnotations($class);
|
||||||
|
//Extractor::getClassPropertyValues($class);
|
||||||
}
|
}
|
||||||
return end($st_output);
|
$allClassAnnotation = Extractor::getAllClassAnnotations();
|
||||||
|
$allClassMethodAnnotation = Extractor::getAllClassMethodAnnotations();
|
||||||
|
//$allClassPropertyValue = Extractor::getAllClassPropertyValues();
|
||||||
|
|
||||||
|
// foreach ($allClassMethodAnnotation as $className => &$methods) {
|
||||||
|
// foreach ($methods as &$method) {
|
||||||
|
// //权重判断
|
||||||
|
// if ($method && !isset($method['ApiWeigh']) && isset($allClassAnnotation[$className]['ApiWeigh'])) {
|
||||||
|
// $method['ApiWeigh'] = $allClassAnnotation[$className]['ApiWeigh'];
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// unset($methods);
|
||||||
|
return [$allClassAnnotation, $allClassMethodAnnotation];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function generateHeadersTemplate($docs)
|
protected function generateHeadersTemplate($docs)
|
||||||
{
|
{
|
||||||
if (!isset($docs['ApiHeaders']))
|
if (!isset($docs['ApiHeaders'])) {
|
||||||
{
|
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
$headerslist = array();
|
$headerslist = array();
|
||||||
foreach ($docs['ApiHeaders'] as $params)
|
foreach ($docs['ApiHeaders'] as $params) {
|
||||||
{
|
|
||||||
$tr = array(
|
$tr = array(
|
||||||
'name' => $params['name'],
|
'name' => $params['name'] ?? '',
|
||||||
'type' => $params['type'],
|
'type' => $params['type'] ?? 'string',
|
||||||
'sample' => isset($params['sample']) ? $params['sample'] : '',
|
'sample' => $params['sample'] ?? '',
|
||||||
'required' => isset($params['required']) ? $params['required'] : false,
|
'required' => $params['required'] ?? false,
|
||||||
'description' => isset($params['description']) ? $params['description'] : '',
|
'description' => $params['description'] ?? '',
|
||||||
);
|
);
|
||||||
$headerslist[] = $tr;
|
$headerslist[] = $tr;
|
||||||
}
|
}
|
||||||
|
|
@ -69,20 +84,24 @@ class Builder
|
||||||
|
|
||||||
protected function generateParamsTemplate($docs)
|
protected function generateParamsTemplate($docs)
|
||||||
{
|
{
|
||||||
if (!isset($docs['ApiParams']))
|
if (!isset($docs['ApiParams'])) {
|
||||||
{
|
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$typeArr = [
|
||||||
|
'integer' => 'number',
|
||||||
|
'file' => 'file',
|
||||||
|
];
|
||||||
$paramslist = array();
|
$paramslist = array();
|
||||||
foreach ($docs['ApiParams'] as $params)
|
foreach ($docs['ApiParams'] as $params) {
|
||||||
{
|
$inputtype = $params['type'] && isset($typeArr[$params['type']]) ? $typeArr[$params['type']] : ($params['name'] == 'password' ? 'password' : 'text');
|
||||||
$tr = array(
|
$tr = array(
|
||||||
'name' => $params['name'],
|
'name' => $params['name'],
|
||||||
'type' => isset($params['type']) ? $params['type'] : 'string',
|
'type' => $params['type'] ?? 'string',
|
||||||
'sample' => isset($params['sample']) ? $params['sample'] : '',
|
'inputtype' => $inputtype,
|
||||||
'required' => isset($params['required']) ? $params['required'] : true,
|
'sample' => $params['sample'] ?? '',
|
||||||
'description' => isset($params['description']) ? $params['description'] : '',
|
'required' => $params['required'] ?? true,
|
||||||
|
'description' => $params['description'] ?? '',
|
||||||
);
|
);
|
||||||
$paramslist[] = $tr;
|
$paramslist[] = $tr;
|
||||||
}
|
}
|
||||||
|
|
@ -92,20 +111,18 @@ class Builder
|
||||||
|
|
||||||
protected function generateReturnHeadersTemplate($docs)
|
protected function generateReturnHeadersTemplate($docs)
|
||||||
{
|
{
|
||||||
if (!isset($docs['ApiReturnHeaders']))
|
if (!isset($docs['ApiReturnHeaders'])) {
|
||||||
{
|
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
$headerslist = array();
|
$headerslist = array();
|
||||||
foreach ($docs['ApiReturnHeaders'] as $params)
|
foreach ($docs['ApiReturnHeaders'] as $params) {
|
||||||
{
|
|
||||||
$tr = array(
|
$tr = array(
|
||||||
'name' => $params['name'],
|
'name' => $params['name'] ?? '',
|
||||||
'type' => 'string',
|
'type' => 'string',
|
||||||
'sample' => isset($params['sample']) ? $params['sample'] : '',
|
'sample' => $params['sample'] ?? '',
|
||||||
'required' => isset($params['required']) && $params['required'] ? 'Yes' : 'No',
|
'required' => isset($params['required']) && $params['required'] ? 'Yes' : 'No',
|
||||||
'description' => isset($params['description']) ? $params['description'] : '',
|
'description' => $params['description'] ?? '',
|
||||||
);
|
);
|
||||||
$headerslist[] = $tr;
|
$headerslist[] = $tr;
|
||||||
}
|
}
|
||||||
|
|
@ -115,19 +132,17 @@ class Builder
|
||||||
|
|
||||||
protected function generateReturnParamsTemplate($st_params)
|
protected function generateReturnParamsTemplate($st_params)
|
||||||
{
|
{
|
||||||
if (!isset($st_params['ApiReturnParams']))
|
if (!isset($st_params['ApiReturnParams'])) {
|
||||||
{
|
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
$paramslist = array();
|
$paramslist = array();
|
||||||
foreach ($st_params['ApiReturnParams'] as $params)
|
foreach ($st_params['ApiReturnParams'] as $params) {
|
||||||
{
|
|
||||||
$tr = array(
|
$tr = array(
|
||||||
'name' => $params['name'],
|
'name' => $params['name'] ?? '',
|
||||||
'type' => isset($params['type']) ? $params['type'] : 'string',
|
'type' => $params['type'] ?? 'string',
|
||||||
'sample' => isset($params['sample']) ? $params['sample'] : '',
|
'sample' => $params['sample'] ?? '',
|
||||||
'description' => isset($params['description']) ? $params['description'] : '',
|
'description' => $params['description'] ?? '',
|
||||||
);
|
);
|
||||||
$paramslist[] = $tr;
|
$paramslist[] = $tr;
|
||||||
}
|
}
|
||||||
|
|
@ -152,47 +167,76 @@ class Builder
|
||||||
|
|
||||||
public function parse()
|
public function parse()
|
||||||
{
|
{
|
||||||
$annotations = $this->extractAnnotations();
|
list($allClassAnnotations, $allClassMethodAnnotations) = $this->extractAnnotations();
|
||||||
|
|
||||||
|
$sectorArr = [];
|
||||||
|
foreach ($allClassAnnotations as $index => &$allClassAnnotation) {
|
||||||
|
// 如果设置隐藏,则不显示在文档
|
||||||
|
if (isset($allClassAnnotation['ApiInternal'])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$sector = isset($allClassAnnotation['ApiSector']) ? $allClassAnnotation['ApiSector'][0] : $allClassAnnotation['ApiTitle'][0];
|
||||||
|
$sectorArr[$sector] = isset($allClassAnnotation['ApiWeigh']) ? $allClassAnnotation['ApiWeigh'][0] : 0;
|
||||||
|
}
|
||||||
|
unset($allClassAnnotation);
|
||||||
|
|
||||||
|
arsort($sectorArr);
|
||||||
|
$routes = include_once CONF_PATH . 'route.php';
|
||||||
|
$subdomain = false;
|
||||||
|
if (config('url_domain_deploy') && isset($routes['__domain__']) && isset($routes['__domain__']['api']) && $routes['__domain__']['api']) {
|
||||||
|
$subdomain = true;
|
||||||
|
}
|
||||||
$counter = 0;
|
$counter = 0;
|
||||||
$section = null;
|
$section = null;
|
||||||
$docslist = [];
|
$weigh = 0;
|
||||||
foreach ($annotations as $class => $methods)
|
$docsList = [];
|
||||||
{
|
foreach ($allClassMethodAnnotations as $class => $methods) {
|
||||||
foreach ($methods as $name => $docs)
|
foreach ($methods as $name => $docs) {
|
||||||
{
|
if (isset($docs['ApiSector'][0])) {
|
||||||
if (isset($docs['ApiSector'][0]))
|
|
||||||
{
|
|
||||||
$section = is_array($docs['ApiSector'][0]) ? $docs['ApiSector'][0]['data'] : $docs['ApiSector'][0];
|
$section = is_array($docs['ApiSector'][0]) ? $docs['ApiSector'][0]['data'] : $docs['ApiSector'][0];
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$section = $class;
|
$section = $class;
|
||||||
}
|
}
|
||||||
if (0 === count($docs))
|
if (0 === count($docs)) {
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
$route = is_array($docs['ApiRoute'][0]) ? $docs['ApiRoute'][0]['data'] : $docs['ApiRoute'][0];
|
||||||
$docslist[$section][] = [
|
if ($subdomain) {
|
||||||
|
$route = substr($route, 4);
|
||||||
|
}
|
||||||
|
$docsList[$section][$name] = [
|
||||||
'id' => $counter,
|
'id' => $counter,
|
||||||
'method' => is_array($docs['ApiMethod'][0]) ? $docs['ApiMethod'][0]['data'] : $docs['ApiMethod'][0],
|
'method' => is_array($docs['ApiMethod'][0]) ? $docs['ApiMethod'][0]['data'] : $docs['ApiMethod'][0],
|
||||||
'method_label' => $this->generateBadgeForMethod($docs),
|
'methodLabel' => $this->generateBadgeForMethod($docs),
|
||||||
'section' => $section,
|
'section' => $section,
|
||||||
'route' => is_array($docs['ApiRoute'][0]) ? $docs['ApiRoute'][0]['data'] : $docs['ApiRoute'][0],
|
'route' => $route,
|
||||||
|
'title' => is_array($docs['ApiTitle'][0]) ? $docs['ApiTitle'][0]['data'] : $docs['ApiTitle'][0],
|
||||||
'summary' => is_array($docs['ApiSummary'][0]) ? $docs['ApiSummary'][0]['data'] : $docs['ApiSummary'][0],
|
'summary' => is_array($docs['ApiSummary'][0]) ? $docs['ApiSummary'][0]['data'] : $docs['ApiSummary'][0],
|
||||||
'body' => isset($docs['ApiBody'][0]) ? is_array($docs['ApiBody'][0]) ? $docs['ApiBody'][0]['data'] : $docs['ApiBody'][0] : '',
|
'body' => isset($docs['ApiBody'][0]) ? (is_array($docs['ApiBody'][0]) ? $docs['ApiBody'][0]['data'] : $docs['ApiBody'][0]) : '',
|
||||||
'headerslist' => $this->generateHeadersTemplate($docs),
|
'headersList' => $this->generateHeadersTemplate($docs),
|
||||||
'paramslist' => $this->generateParamsTemplate($docs),
|
'paramsList' => $this->generateParamsTemplate($docs),
|
||||||
'returnheaderslist' => $this->generateReturnHeadersTemplate($docs),
|
'returnHeadersList' => $this->generateReturnHeadersTemplate($docs),
|
||||||
'returnparamslist' => $this->generateReturnParamsTemplate($docs),
|
'returnParamsList' => $this->generateReturnParamsTemplate($docs),
|
||||||
'return' => isset($docs['ApiReturn']) ? is_array($docs['ApiReturn'][0]) ? $docs['ApiReturn'][0]['data'] : $docs['ApiReturn'][0] : '',
|
'weigh' => is_array($docs['ApiWeigh'][0]) ? $docs['ApiWeigh'][0]['data'] : $docs['ApiWeigh'][0],
|
||||||
|
'return' => isset($docs['ApiReturn']) ? (is_array($docs['ApiReturn'][0]) ? $docs['ApiReturn'][0]['data'] : $docs['ApiReturn'][0]) : '',
|
||||||
|
'needLogin' => $docs['ApiPermissionLogin'][0],
|
||||||
|
'needRight' => $docs['ApiPermissionRight'][0],
|
||||||
];
|
];
|
||||||
$counter++;
|
$counter++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $docslist;
|
//重建排序
|
||||||
|
foreach ($docsList as $index => &$methods) {
|
||||||
|
$methodSectorArr = [];
|
||||||
|
foreach ($methods as $name => $method) {
|
||||||
|
$methodSectorArr[$name] = isset($method['weigh']) ? $method['weigh'] : 0;
|
||||||
|
}
|
||||||
|
arsort($methodSectorArr);
|
||||||
|
$methods = array_merge(array_flip(array_keys($methodSectorArr)), $methods);
|
||||||
|
}
|
||||||
|
$docsList = array_merge(array_flip(array_keys($sectorArr)), $docsList);
|
||||||
|
return $docsList;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getView()
|
public function getView()
|
||||||
|
|
@ -203,14 +247,13 @@ class Builder
|
||||||
/**
|
/**
|
||||||
* 渲染
|
* 渲染
|
||||||
* @param string $template
|
* @param string $template
|
||||||
* @param array $vars
|
* @param array $vars
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function render($template, $vars = [])
|
public function render($template, $vars = [])
|
||||||
{
|
{
|
||||||
$docslist = $this->parse();
|
$docsList = $this->parse();
|
||||||
|
|
||||||
return $this->view->display(file_get_contents($template), array_merge($vars, ['docslist' => $docslist]));
|
return $this->view->display(file_get_contents($template), array_merge($vars, ['docsList' => $docsList]));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,12 @@ class Extractor
|
||||||
*/
|
*/
|
||||||
private static $annotationCache;
|
private static $annotationCache;
|
||||||
|
|
||||||
|
private static $classAnnotationCache;
|
||||||
|
|
||||||
|
private static $classMethodAnnotationCache;
|
||||||
|
|
||||||
|
private static $classPropertyValueCache;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates that annotations should has strict behavior, 'false' by default
|
* Indicates that annotations should has strict behavior, 'false' by default
|
||||||
* @var boolean
|
* @var boolean
|
||||||
|
|
@ -38,7 +44,7 @@ class Extractor
|
||||||
*/
|
*/
|
||||||
public function setStrict($value)
|
public function setStrict($value)
|
||||||
{
|
{
|
||||||
$this->strict = (bool) $value;
|
$this->strict = (bool)$value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -62,58 +68,92 @@ class Extractor
|
||||||
/**
|
/**
|
||||||
* Gets all anotations with pattern @SomeAnnotation() from a given class
|
* Gets all anotations with pattern @SomeAnnotation() from a given class
|
||||||
*
|
*
|
||||||
* @param string $className class name to get annotations
|
* @param string $className class name to get annotations
|
||||||
* @return array self::$annotationCache all annotated elements
|
* @return array self::$classAnnotationCache all annotated elements
|
||||||
*/
|
*/
|
||||||
public static function getClassAnnotations($className)
|
public static function getClassAnnotations($className)
|
||||||
{
|
{
|
||||||
if (!isset(self::$annotationCache[$className]))
|
if (!isset(self::$classAnnotationCache[$className])) {
|
||||||
{
|
|
||||||
$class = new \ReflectionClass($className);
|
$class = new \ReflectionClass($className);
|
||||||
self::$annotationCache[$className] = self::parseAnnotations($class->getDocComment());
|
$annotationArr = self::parseAnnotations($class->getDocComment());
|
||||||
|
$annotationArr['ApiTitle'] = !isset($annotationArr['ApiTitle'][0]) || !trim($annotationArr['ApiTitle'][0]) ? [$class->getShortName()] : $annotationArr['ApiTitle'];
|
||||||
|
self::$classAnnotationCache[$className] = $annotationArr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return self::$annotationCache[$className];
|
return self::$classAnnotationCache[$className];
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getAllClassAnnotations($className)
|
/**
|
||||||
|
* 获取类所有方法的属性配置
|
||||||
|
* @param $className
|
||||||
|
* @return mixed
|
||||||
|
* @throws \ReflectionException
|
||||||
|
*/
|
||||||
|
public static function getClassMethodAnnotations($className)
|
||||||
{
|
{
|
||||||
$class = new \ReflectionClass($className);
|
$class = new \ReflectionClass($className);
|
||||||
|
|
||||||
foreach ($class->getMethods() as $object)
|
foreach ($class->getMethods() as $object) {
|
||||||
{
|
self::$classMethodAnnotationCache[$className][$object->name] = self::getMethodAnnotations($className, $object->name);
|
||||||
self::$annotationCache['annotations'][$className][$object->name] = self::getMethodAnnotations($className, $object->name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return self::$annotationCache['annotations'];
|
return self::$classMethodAnnotationCache[$className];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getClassPropertyValues($className)
|
||||||
|
{
|
||||||
|
$class = new \ReflectionClass($className);
|
||||||
|
|
||||||
|
foreach ($class->getProperties() as $object) {
|
||||||
|
self::$classPropertyValueCache[$className][$object->name] = self::getClassPropertyValue($className, $object->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$classMethodAnnotationCache[$className];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getAllClassAnnotations()
|
||||||
|
{
|
||||||
|
return self::$classAnnotationCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getAllClassMethodAnnotations()
|
||||||
|
{
|
||||||
|
return self::$classMethodAnnotationCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getAllClassPropertyValues()
|
||||||
|
{
|
||||||
|
return self::$classPropertyValueCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getClassPropertyValue($className, $property)
|
||||||
|
{
|
||||||
|
$_SERVER['REQUEST_METHOD'] = 'GET';
|
||||||
|
$reflectionClass = new \ReflectionClass($className);
|
||||||
|
$reflectionProperty = $reflectionClass->getProperty($property);
|
||||||
|
$reflectionProperty->setAccessible(true);
|
||||||
|
return $reflectionProperty->getValue($reflectionClass->newInstanceWithoutConstructor());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets all anotations with pattern @SomeAnnotation() from a determinated method of a given class
|
* Gets all anotations with pattern @SomeAnnotation() from a determinated method of a given class
|
||||||
*
|
*
|
||||||
* @param string $className class name
|
* @param string $className class name
|
||||||
* @param string $methodName method name to get annotations
|
* @param string $methodName method name to get annotations
|
||||||
* @return array self::$annotationCache all annotated elements of a method given
|
* @return array self::$annotationCache all annotated elements of a method given
|
||||||
*/
|
*/
|
||||||
public static function getMethodAnnotations($className, $methodName)
|
public static function getMethodAnnotations($className, $methodName)
|
||||||
{
|
{
|
||||||
if (!isset(self::$annotationCache[$className . '::' . $methodName]))
|
if (!isset(self::$annotationCache[$className . '::' . $methodName])) {
|
||||||
{
|
try {
|
||||||
try
|
|
||||||
{
|
|
||||||
$method = new \ReflectionMethod($className, $methodName);
|
$method = new \ReflectionMethod($className, $methodName);
|
||||||
$class = new \ReflectionClass($className);
|
$class = new \ReflectionClass($className);
|
||||||
if (!$method->isPublic() || $method->isConstructor())
|
if (!$method->isPublic() || $method->isConstructor()) {
|
||||||
{
|
|
||||||
$annotations = array();
|
$annotations = array();
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$annotations = self::consolidateAnnotations($method, $class);
|
$annotations = self::consolidateAnnotations($method, $class);
|
||||||
}
|
}
|
||||||
}
|
} catch (\ReflectionException $e) {
|
||||||
catch (\ReflectionException $e)
|
|
||||||
{
|
|
||||||
$annotations = array();
|
$annotations = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -127,8 +167,8 @@ class Extractor
|
||||||
* Gets all anotations with pattern @SomeAnnotation() from a determinated method of a given class
|
* Gets all anotations with pattern @SomeAnnotation() from a determinated method of a given class
|
||||||
* and instance its abcAnnotation class
|
* and instance its abcAnnotation class
|
||||||
*
|
*
|
||||||
* @param string $className class name
|
* @param string $className class name
|
||||||
* @param string $methodName method name to get annotations
|
* @param string $methodName method name to get annotations
|
||||||
* @return array self::$annotationCache all annotated objects of a method given
|
* @return array self::$annotationCache all annotated objects of a method given
|
||||||
*/
|
*/
|
||||||
public function getMethodAnnotationsObjects($className, $methodName)
|
public function getMethodAnnotationsObjects($className, $methodName)
|
||||||
|
|
@ -138,42 +178,31 @@ class Extractor
|
||||||
|
|
||||||
$i = 0;
|
$i = 0;
|
||||||
|
|
||||||
foreach ($annotations as $annotationClass => $listParams)
|
foreach ($annotations as $annotationClass => $listParams) {
|
||||||
{
|
|
||||||
$annotationClass = ucfirst($annotationClass);
|
$annotationClass = ucfirst($annotationClass);
|
||||||
$class = $this->defaultNamespace . $annotationClass . 'Annotation';
|
$class = $this->defaultNamespace . $annotationClass . 'Annotation';
|
||||||
|
|
||||||
// verify is the annotation class exists, depending if Annotations::strict is true
|
// verify is the annotation class exists, depending if Annotations::strict is true
|
||||||
// if not, just skip the annotation instance creation.
|
// if not, just skip the annotation instance creation.
|
||||||
if (!class_exists($class))
|
if (!class_exists($class)) {
|
||||||
{
|
if ($this->strict) {
|
||||||
if ($this->strict)
|
|
||||||
{
|
|
||||||
throw new Exception(sprintf('Runtime Error: Annotation Class Not Found: %s', $class));
|
throw new Exception(sprintf('Runtime Error: Annotation Class Not Found: %s', $class));
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// silent skip & continue
|
// silent skip & continue
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($objects[$annotationClass]))
|
if (empty($objects[$annotationClass])) {
|
||||||
{
|
|
||||||
$objects[$annotationClass] = new $class();
|
$objects[$annotationClass] = new $class();
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($listParams as $params)
|
foreach ($listParams as $params) {
|
||||||
{
|
if (is_array($params)) {
|
||||||
if (is_array($params))
|
foreach ($params as $key => $value) {
|
||||||
{
|
|
||||||
foreach ($params as $key => $value)
|
|
||||||
{
|
|
||||||
$objects[$annotationClass]->set($key, $value);
|
$objects[$annotationClass]->set($key, $value);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$objects[$annotationClass]->set($i++, $params);
|
$objects[$annotationClass]->set($i++, $params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -189,90 +218,75 @@ class Extractor
|
||||||
$methodName = $method->getName();
|
$methodName = $method->getName();
|
||||||
|
|
||||||
$methodAnnotations = self::parseAnnotations($docblockMethod);
|
$methodAnnotations = self::parseAnnotations($docblockMethod);
|
||||||
|
$methodAnnotations['ApiTitle'] = !isset($methodAnnotations['ApiTitle'][0]) || !trim($methodAnnotations['ApiTitle'][0]) ? [$method->getName()] : $methodAnnotations['ApiTitle'];
|
||||||
|
|
||||||
$classAnnotations = self::parseAnnotations($dockblockClass);
|
$classAnnotations = self::parseAnnotations($dockblockClass);
|
||||||
if (isset($methodAnnotations['ApiInternal']) || $methodName == '_initialize' || $methodName == '_empty')
|
$classAnnotations['ApiTitle'] = !isset($classAnnotations['ApiTitle'][0]) || !trim($classAnnotations['ApiTitle'][0]) ? [$class->getShortName()] : $classAnnotations['ApiTitle'];
|
||||||
{
|
|
||||||
|
if (isset($methodAnnotations['ApiInternal']) || $methodName == '_initialize' || $methodName == '_empty') {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
$properties = $class->getDefaultProperties();
|
$properties = $class->getDefaultProperties();
|
||||||
$noNeedLogin = isset($properties['noNeedLogin']) ? is_array($properties['noNeedLogin']) ? $properties['noNeedLogin'] : [$properties['noNeedLogin']] : [];
|
$noNeedLogin = isset($properties['noNeedLogin']) ? (is_array($properties['noNeedLogin']) ? $properties['noNeedLogin'] : [$properties['noNeedLogin']]) : [];
|
||||||
$noNeedRight = isset($properties['noNeedRight']) ? is_array($properties['noNeedRight']) ? $properties['noNeedRight'] : [$properties['noNeedRight']] : [];
|
$noNeedRight = isset($properties['noNeedRight']) ? (is_array($properties['noNeedRight']) ? $properties['noNeedRight'] : [$properties['noNeedRight']]) : [];
|
||||||
|
|
||||||
preg_match_all("/\*[\s]+(.*)(\\r\\n|\\r|\\n)/U", str_replace('/**', '', $docblockMethod), $methodArr);
|
preg_match_all("/\*[\s]+(.*)(\\r\\n|\\r|\\n)/U", str_replace('/**', '', $docblockMethod), $methodArr);
|
||||||
preg_match_all("/\*[\s]+(.*)(\\r\\n|\\r|\\n)/U", str_replace('/**', '', $dockblockClass), $classArr);
|
preg_match_all("/\*[\s]+(.*)(\\r\\n|\\r|\\n)/U", str_replace('/**', '', $dockblockClass), $classArr);
|
||||||
|
|
||||||
$methodTitle = isset($methodArr[1]) && isset($methodArr[1][0]) ? $methodArr[1][0] : '';
|
if (!isset($methodAnnotations['ApiMethod'])) {
|
||||||
$classTitle = isset($classArr[1]) && isset($classArr[1][0]) ? $classArr[1][0] : '';
|
|
||||||
|
|
||||||
if (!isset($methodAnnotations['ApiMethod']))
|
|
||||||
{
|
|
||||||
$methodAnnotations['ApiMethod'] = ['get'];
|
$methodAnnotations['ApiMethod'] = ['get'];
|
||||||
}
|
}
|
||||||
if (!isset($methodAnnotations['ApiSummary']))
|
if (!isset($methodAnnotations['ApiWeigh'])) {
|
||||||
{
|
$methodAnnotations['ApiWeigh'] = [0];
|
||||||
$methodAnnotations['ApiSummary'] = [$methodTitle];
|
}
|
||||||
|
if (!isset($methodAnnotations['ApiSummary'])) {
|
||||||
|
$methodAnnotations['ApiSummary'] = $methodAnnotations['ApiTitle'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($methodAnnotations)
|
if ($methodAnnotations) {
|
||||||
{
|
foreach ($classAnnotations as $name => $valueClass) {
|
||||||
foreach ($classAnnotations as $name => $valueClass)
|
if (count($valueClass) !== 1) {
|
||||||
{
|
|
||||||
if (count($valueClass) !== 1)
|
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($name === 'ApiRoute')
|
if ($name === 'ApiRoute') {
|
||||||
{
|
if (isset($methodAnnotations[$name])) {
|
||||||
if (isset($methodAnnotations[$name]))
|
|
||||||
{
|
|
||||||
$methodAnnotations[$name] = [rtrim($valueClass[0], '/') . $methodAnnotations[$name][0]];
|
$methodAnnotations[$name] = [rtrim($valueClass[0], '/') . $methodAnnotations[$name][0]];
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$methodAnnotations[$name] = [rtrim($valueClass[0], '/') . '/' . $method->getName()];
|
$methodAnnotations[$name] = [rtrim($valueClass[0], '/') . '/' . $method->getName()];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($name === 'ApiSector')
|
if ($name === 'ApiSector') {
|
||||||
{
|
|
||||||
$methodAnnotations[$name] = $valueClass;
|
$methodAnnotations[$name] = $valueClass;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!isset($methodAnnotations['ApiTitle']))
|
if (!isset($methodAnnotations['ApiRoute'])) {
|
||||||
{
|
|
||||||
$methodAnnotations['ApiTitle'] = [$methodTitle];
|
|
||||||
}
|
|
||||||
if (!isset($methodAnnotations['ApiRoute']))
|
|
||||||
{
|
|
||||||
$urlArr = [];
|
$urlArr = [];
|
||||||
$className = $class->getName();
|
$className = $class->getName();
|
||||||
|
|
||||||
list($prefix, $suffix) = explode('\\' . \think\Config::get('url_controller_layer') . '\\', $className);
|
list($prefix, $suffix) = explode('\\' . \think\Config::get('url_controller_layer') . '\\', $className);
|
||||||
$prefixArr = explode('\\', $prefix);
|
$prefixArr = explode('\\', $prefix);
|
||||||
$suffixArr = explode('\\', $suffix);
|
$suffixArr = explode('\\', $suffix);
|
||||||
if ($prefixArr[0] == \think\Config::get('app_namespace'))
|
if ($prefixArr[0] == \think\Config::get('app_namespace')) {
|
||||||
{
|
|
||||||
$prefixArr[0] = '';
|
$prefixArr[0] = '';
|
||||||
}
|
}
|
||||||
$urlArr = array_merge($urlArr, $prefixArr);
|
$urlArr = array_merge($urlArr, $prefixArr);
|
||||||
$urlArr[] = implode('.', array_map(function($item) {
|
$urlArr[] = implode('.', array_map(function ($item) {
|
||||||
return \think\Loader::parseName($item);
|
return \think\Loader::parseName($item);
|
||||||
}, $suffixArr));
|
}, $suffixArr));
|
||||||
$urlArr[] = $method->getName();
|
$urlArr[] = $method->getName();
|
||||||
|
|
||||||
$methodAnnotations['ApiRoute'] = [implode('/', $urlArr)];
|
$methodAnnotations['ApiRoute'] = [implode('/', $urlArr)];
|
||||||
}
|
}
|
||||||
if (!isset($methodAnnotations['ApiSector']))
|
if (!isset($methodAnnotations['ApiSector'])) {
|
||||||
{
|
$methodAnnotations['ApiSector'] = isset($classAnnotations['ApiSector']) ? $classAnnotations['ApiSector'] : $classAnnotations['ApiTitle'];
|
||||||
$methodAnnotations['ApiSector'] = isset($classAnnotations['ApiSector']) ? $classAnnotations['ApiSector'] : [$classTitle];
|
|
||||||
}
|
}
|
||||||
if (!isset($methodAnnotations['ApiParams']))
|
if (!isset($methodAnnotations['ApiParams'])) {
|
||||||
{
|
|
||||||
$params = self::parseCustomAnnotations($docblockMethod, 'param');
|
$params = self::parseCustomAnnotations($docblockMethod, 'param');
|
||||||
foreach ($params as $k => $v)
|
foreach ($params as $k => $v) {
|
||||||
{
|
|
||||||
$arr = explode(' ', preg_replace("/[\s]+/", " ", $v));
|
$arr = explode(' ', preg_replace("/[\s]+/", " ", $v));
|
||||||
$methodAnnotations['ApiParams'][] = [
|
$methodAnnotations['ApiParams'][] = [
|
||||||
'name' => isset($arr[1]) ? str_replace('$', '', $arr[1]) : '',
|
'name' => isset($arr[1]) ? str_replace('$', '', $arr[1]) : '',
|
||||||
|
|
@ -283,15 +297,15 @@ class Extractor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$methodAnnotations['ApiPermissionLogin'] = [!in_array('*', $noNeedLogin) && !in_array($methodName, $noNeedLogin)];
|
$methodAnnotations['ApiPermissionLogin'] = [!in_array('*', $noNeedLogin) && !in_array($methodName, $noNeedLogin)];
|
||||||
$methodAnnotations['ApiPermissionRight'] = [!in_array('*', $noNeedRight) && !in_array($methodName, $noNeedRight)];
|
$methodAnnotations['ApiPermissionRight'] = !$methodAnnotations['ApiPermissionLogin'][0] ? [false] : [!in_array('*', $noNeedRight) && !in_array($methodName, $noNeedRight)];
|
||||||
return $methodAnnotations;
|
return $methodAnnotations;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse annotations
|
* Parse annotations
|
||||||
*
|
*
|
||||||
* @param string $docblock
|
* @param string $docblock
|
||||||
* @param string $name
|
* @param string $name
|
||||||
* @return array parsed annotations params
|
* @return array parsed annotations params
|
||||||
*/
|
*/
|
||||||
private static function parseCustomAnnotations($docblock, $name = 'param')
|
private static function parseCustomAnnotations($docblock, $name = 'param')
|
||||||
|
|
@ -299,10 +313,8 @@ class Extractor
|
||||||
$annotations = array();
|
$annotations = array();
|
||||||
|
|
||||||
$docblock = substr($docblock, 3, -2);
|
$docblock = substr($docblock, 3, -2);
|
||||||
if (preg_match_all('/@' . $name . '(?:\s*(?:\(\s*)?(.*?)(?:\s*\))?)??\s*(?:\n|\*\/)/', $docblock, $matches))
|
if (preg_match_all('/@' . $name . '(?:\s*(?:\(\s*)?(.*?)(?:\s*\))?)??\s*(?:\n|\*\/)/', $docblock, $matches)) {
|
||||||
{
|
foreach ($matches[1] as $k => $v) {
|
||||||
foreach ($matches[1] as $k => $v)
|
|
||||||
{
|
|
||||||
$annotations[] = $v;
|
$annotations[] = $v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -312,7 +324,7 @@ class Extractor
|
||||||
/**
|
/**
|
||||||
* Parse annotations
|
* Parse annotations
|
||||||
*
|
*
|
||||||
* @param string $docblock
|
* @param string $docblock
|
||||||
* @return array parsed annotations params
|
* @return array parsed annotations params
|
||||||
*/
|
*/
|
||||||
private static function parseAnnotations($docblock)
|
private static function parseAnnotations($docblock)
|
||||||
|
|
@ -321,36 +333,36 @@ class Extractor
|
||||||
|
|
||||||
// Strip away the docblock header and footer to ease parsing of one line annotations
|
// Strip away the docblock header and footer to ease parsing of one line annotations
|
||||||
$docblock = substr($docblock, 3, -2);
|
$docblock = substr($docblock, 3, -2);
|
||||||
if (preg_match_all('/@(?<name>[A-Za-z_-]+)[\s\t]*\((?<args>(?:(?!\)).)*)\)\r?/s', $docblock, $matches))
|
if (preg_match_all('/@(?<name>[A-Za-z_-]+)[\s\t]*\((?<args>(?:(?!\)).)*)\)\r?/s', $docblock, $matches)) {
|
||||||
{
|
|
||||||
$numMatches = count($matches[0]);
|
$numMatches = count($matches[0]);
|
||||||
for ($i = 0; $i < $numMatches; ++$i)
|
for ($i = 0; $i < $numMatches; ++$i) {
|
||||||
{
|
$name = $matches['name'][$i];
|
||||||
|
$value = '';
|
||||||
// annotations has arguments
|
// annotations has arguments
|
||||||
if (isset($matches['args'][$i]))
|
if (isset($matches['args'][$i])) {
|
||||||
{
|
|
||||||
$argsParts = trim($matches['args'][$i]);
|
$argsParts = trim($matches['args'][$i]);
|
||||||
$name = $matches['name'][$i];
|
if ($name == 'ApiReturn') {
|
||||||
if($name == 'ApiReturn')
|
|
||||||
{
|
|
||||||
$value = $argsParts;
|
$value = $argsParts;
|
||||||
} else {
|
} elseif ($matches['args'][$i] != '') {
|
||||||
$argsParts = preg_replace("/\{(\w+)\}/", '#$1#', $argsParts);
|
$argsParts = preg_replace("/\{(\w+)\}/", '#$1#', $argsParts);
|
||||||
$value = self::parseArgs($argsParts);
|
$value = self::parseArgs($argsParts);
|
||||||
if(is_string($value))
|
if (is_string($value)) {
|
||||||
{
|
|
||||||
$value = preg_replace("/\#(\w+)\#/", '{$1}', $argsParts);
|
$value = preg_replace("/\#(\w+)\#/", '{$1}', $argsParts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
$value = array();
|
|
||||||
}
|
|
||||||
|
|
||||||
$annotations[$name][] = $value;
|
$annotations[$name][] = $value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (stripos($docblock, '@ApiInternal') !== false) {
|
||||||
|
$annotations['ApiInternal'] = [true];
|
||||||
|
}
|
||||||
|
if (!isset($annotations['ApiTitle'])) {
|
||||||
|
preg_match_all("/\*[\s]+(.*)(\\r\\n|\\r|\\n)/U", str_replace('/**', '', $docblock), $matchArr);
|
||||||
|
$title = isset($matchArr[1]) && isset($matchArr[1][0]) ? $matchArr[1][0] : '';
|
||||||
|
$annotations['ApiTitle'] = [$title];
|
||||||
|
}
|
||||||
|
|
||||||
return $annotations;
|
return $annotations;
|
||||||
}
|
}
|
||||||
|
|
@ -358,7 +370,7 @@ class Extractor
|
||||||
/**
|
/**
|
||||||
* Parse individual annotation arguments
|
* Parse individual annotation arguments
|
||||||
*
|
*
|
||||||
* @param string $content arguments string
|
* @param string $content arguments string
|
||||||
* @return array annotated arguments
|
* @return array annotated arguments
|
||||||
*/
|
*/
|
||||||
private static function parseArgs($content)
|
private static function parseArgs($content)
|
||||||
|
|
@ -382,39 +394,34 @@ class Extractor
|
||||||
$quoted = false;
|
$quoted = false;
|
||||||
$tokens = array('"', '"', '{', '}', ',', '=');
|
$tokens = array('"', '"', '{', '}', ',', '=');
|
||||||
|
|
||||||
while ($i <= $len)
|
while ($i <= $len) {
|
||||||
{
|
|
||||||
$prev_c = substr($content, $i - 1, 1);
|
$prev_c = substr($content, $i - 1, 1);
|
||||||
$c = substr($content, $i++, 1);
|
$c = substr($content, $i++, 1);
|
||||||
|
|
||||||
if ($c === '"' && $prev_c !== "\\")
|
if ($c === '"' && $prev_c !== "\\") {
|
||||||
{
|
|
||||||
$delimiter = $c;
|
$delimiter = $c;
|
||||||
//open delimiter
|
//open delimiter
|
||||||
if (!$composing && empty($prevDelimiter) && empty($nextDelimiter))
|
if (!$composing && empty($prevDelimiter) && empty($nextDelimiter)) {
|
||||||
{
|
|
||||||
$prevDelimiter = $nextDelimiter = $delimiter;
|
$prevDelimiter = $nextDelimiter = $delimiter;
|
||||||
$val = '';
|
$val = '';
|
||||||
$composing = true;
|
$composing = true;
|
||||||
$quoted = true;
|
$quoted = true;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// close delimiter
|
// close delimiter
|
||||||
if ($c !== $nextDelimiter)
|
if ($c !== $nextDelimiter) {
|
||||||
{
|
|
||||||
throw new Exception(sprintf(
|
throw new Exception(sprintf(
|
||||||
"Parse Error: enclosing error -> expected: [%s], given: [%s]", $nextDelimiter, $c
|
"Parse Error: enclosing error -> expected: [%s], given: [%s]",
|
||||||
|
$nextDelimiter,
|
||||||
|
$c
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// validating syntax
|
// validating syntax
|
||||||
if ($i < $len)
|
if ($i < $len) {
|
||||||
{
|
if (',' !== substr($content, $i, 1) && '\\' !== $prev_c) {
|
||||||
if (',' !== substr($content, $i, 1) && '\\' !== $prev_c)
|
|
||||||
{
|
|
||||||
throw new Exception(sprintf(
|
throw new Exception(sprintf(
|
||||||
"Parse Error: missing comma separator near: ...%s<--", substr($content, ($i - 10), $i)
|
"Parse Error: missing comma separator near: ...%s<--",
|
||||||
|
substr($content, ($i - 10), $i)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -423,11 +430,8 @@ class Extractor
|
||||||
$composing = false;
|
$composing = false;
|
||||||
$delimiter = null;
|
$delimiter = null;
|
||||||
}
|
}
|
||||||
}
|
} elseif (!$composing && in_array($c, $tokens)) {
|
||||||
elseif (!$composing && in_array($c, $tokens))
|
switch ($c) {
|
||||||
{
|
|
||||||
switch ($c)
|
|
||||||
{
|
|
||||||
case '=':
|
case '=':
|
||||||
$prevDelimiter = $nextDelimiter = '';
|
$prevDelimiter = $nextDelimiter = '';
|
||||||
$level = 2;
|
$level = 2;
|
||||||
|
|
@ -440,10 +444,11 @@ class Extractor
|
||||||
|
|
||||||
// If composing flag is true yet,
|
// If composing flag is true yet,
|
||||||
// it means that the string was not enclosed, so it is parsing error.
|
// it means that the string was not enclosed, so it is parsing error.
|
||||||
if ($composing === true && !empty($prevDelimiter) && !empty($nextDelimiter))
|
if ($composing === true && !empty($prevDelimiter) && !empty($nextDelimiter)) {
|
||||||
{
|
|
||||||
throw new Exception(sprintf(
|
throw new Exception(sprintf(
|
||||||
"Parse Error: enclosing error -> expected: [%s], given: [%s]", $nextDelimiter, $c
|
"Parse Error: enclosing error -> expected: [%s], given: [%s]",
|
||||||
|
$nextDelimiter,
|
||||||
|
$c
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -453,19 +458,16 @@ class Extractor
|
||||||
$subc = '';
|
$subc = '';
|
||||||
$subComposing = true;
|
$subComposing = true;
|
||||||
|
|
||||||
while ($i <= $len)
|
while ($i <= $len) {
|
||||||
{
|
|
||||||
$c = substr($content, $i++, 1);
|
$c = substr($content, $i++, 1);
|
||||||
|
|
||||||
if (isset($delimiter) && $c === $delimiter)
|
if (isset($delimiter) && $c === $delimiter) {
|
||||||
{
|
|
||||||
throw new Exception(sprintf(
|
throw new Exception(sprintf(
|
||||||
"Parse Error: Composite variable is not enclosed correctly."
|
"Parse Error: Composite variable is not enclosed correctly."
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($c === '}')
|
if ($c === '}') {
|
||||||
{
|
|
||||||
$subComposing = false;
|
$subComposing = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -473,37 +475,28 @@ class Extractor
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the string is composing yet means that the structure of var. never was enclosed with '}'
|
// if the string is composing yet means that the structure of var. never was enclosed with '}'
|
||||||
if ($subComposing)
|
if ($subComposing) {
|
||||||
{
|
|
||||||
throw new Exception(sprintf(
|
throw new Exception(sprintf(
|
||||||
"Parse Error: Composite variable is not enclosed correctly. near: ...%s'", $subc
|
"Parse Error: Composite variable is not enclosed correctly. near: ...%s'",
|
||||||
|
$subc
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
$val = self::parseArgs($subc);
|
$val = self::parseArgs($subc);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
if ($level == 1) {
|
||||||
{
|
|
||||||
if ($level == 1)
|
|
||||||
{
|
|
||||||
$var .= $c;
|
$var .= $c;
|
||||||
}
|
} elseif ($level == 2) {
|
||||||
elseif ($level == 2)
|
|
||||||
{
|
|
||||||
$val .= $c;
|
$val .= $c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($level === 3 || $i === $len)
|
if ($level === 3 || $i === $len) {
|
||||||
{
|
if ($type == 'plain' && $i === $len) {
|
||||||
if ($type == 'plain' && $i === $len)
|
|
||||||
{
|
|
||||||
$data = self::castValue($var);
|
$data = self::castValue($var);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$data[trim($var)] = self::castValue($val, !$quoted);
|
$data[trim($var)] = self::castValue($val, !$quoted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -520,34 +513,26 @@ class Extractor
|
||||||
/**
|
/**
|
||||||
* Try determinate the original type variable of a string
|
* Try determinate the original type variable of a string
|
||||||
*
|
*
|
||||||
* @param string $val string containing possibles variables that can be cast to bool or int
|
* @param string $val string containing possibles variables that can be cast to bool or int
|
||||||
* @param boolean $trim indicate if the value passed should be trimmed after to try cast
|
* @param boolean $trim indicate if the value passed should be trimmed after to try cast
|
||||||
* @return mixed returns the value converted to original type if was possible
|
* @return mixed returns the value converted to original type if was possible
|
||||||
*/
|
*/
|
||||||
private static function castValue($val, $trim = false)
|
private static function castValue($val, $trim = false)
|
||||||
{
|
{
|
||||||
if (is_array($val))
|
if (is_array($val)) {
|
||||||
{
|
foreach ($val as $key => $value) {
|
||||||
foreach ($val as $key => $value)
|
|
||||||
{
|
|
||||||
$val[$key] = self::castValue($value);
|
$val[$key] = self::castValue($value);
|
||||||
}
|
}
|
||||||
}
|
} elseif (is_string($val)) {
|
||||||
elseif (is_string($val))
|
if ($trim) {
|
||||||
{
|
|
||||||
if ($trim)
|
|
||||||
{
|
|
||||||
$val = trim($val);
|
$val = trim($val);
|
||||||
}
|
}
|
||||||
$val = stripslashes($val);
|
$val = stripslashes($val);
|
||||||
$tmp = strtolower($val);
|
$tmp = strtolower($val);
|
||||||
|
|
||||||
if ($tmp === 'false' || $tmp === 'true')
|
if ($tmp === 'false' || $tmp === 'true') {
|
||||||
{
|
|
||||||
$val = $tmp === 'true';
|
$val = $tmp === 'true';
|
||||||
}
|
} elseif (is_numeric($val)) {
|
||||||
elseif (is_numeric($val))
|
|
||||||
{
|
|
||||||
return $val + 0;
|
return $val + 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -556,5 +541,4 @@ class Extractor
|
||||||
|
|
||||||
return $val;
|
return $val;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,24 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="{$config.language}">
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<meta name="description" content="">
|
<meta name="description" content="">
|
||||||
<meta name="author" content="{$config.author}">
|
|
||||||
<title>{$config.title}</title>
|
<title>{$config.title}</title>
|
||||||
<link href="https://cdn.bootcss.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
|
|
||||||
|
<!-- Bootstrap Core CSS -->
|
||||||
|
<link href="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<!-- Plugin CSS -->
|
||||||
|
<link href="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
|
||||||
|
<!--[if lt IE 9]>
|
||||||
|
<script src="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/html5shiv/3.7.3/html5shiv.min.js"></script>
|
||||||
|
<script src="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/respond.js/1.4.2/respond.min.js"></script>
|
||||||
|
<![endif]-->
|
||||||
|
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
body {
|
body {
|
||||||
padding-top: 70px; margin-bottom: 15px;
|
padding-top: 70px; margin-bottom: 15px;
|
||||||
|
|
@ -16,18 +27,89 @@
|
||||||
font-family: "Roboto", "SF Pro SC", "SF Pro Display", "SF Pro Icons", "PingFang SC", BlinkMacSystemFont, -apple-system, "Segoe UI", "Microsoft Yahei", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", "Helvetica", "Arial", sans-serif;
|
font-family: "Roboto", "SF Pro SC", "SF Pro Display", "SF Pro Icons", "PingFang SC", BlinkMacSystemFont, -apple-system, "Segoe UI", "Microsoft Yahei", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", "Helvetica", "Arial", sans-serif;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
}
|
}
|
||||||
h2 { font-size: 1.6em; }
|
h2 { font-size: 1.2em; }
|
||||||
hr { margin-top: 10px; }
|
hr { margin-top: 10px; }
|
||||||
.tab-pane { padding-top: 10px; }
|
.tab-pane { padding-top: 10px; }
|
||||||
.mt0 { margin-top: 0px; }
|
.mt0 { margin-top: 0px; }
|
||||||
.footer { font-size: 12px; color: #666; }
|
.footer { font-size: 12px; color: #666; }
|
||||||
.label { display: inline-block; min-width: 65px; padding: 0.3em 0.6em 0.3em; }
|
.docs-list .label { display: inline-block; min-width: 65px; padding: 0.3em 0.6em 0.3em; }
|
||||||
.string { color: green; }
|
.string { color: green; }
|
||||||
.number { color: darkorange; }
|
.number { color: darkorange; }
|
||||||
.boolean { color: blue; }
|
.boolean { color: blue; }
|
||||||
.null { color: magenta; }
|
.null { color: magenta; }
|
||||||
.key { color: red; }
|
.key { color: red; }
|
||||||
.popover { max-width: 400px; max-height: 400px; overflow-y: auto;}
|
.popover { max-width: 400px; max-height: 400px; overflow-y: auto;}
|
||||||
|
.list-group.panel > .list-group-item {
|
||||||
|
}
|
||||||
|
.list-group-item:last-child {
|
||||||
|
border-radius:0;
|
||||||
|
}
|
||||||
|
h4.panel-title a {
|
||||||
|
font-weight:normal;
|
||||||
|
font-size:14px;
|
||||||
|
}
|
||||||
|
h4.panel-title a .text-muted {
|
||||||
|
font-size:12px;
|
||||||
|
font-weight:normal;
|
||||||
|
font-family: 'Verdana';
|
||||||
|
}
|
||||||
|
#sidebar {
|
||||||
|
width: 220px;
|
||||||
|
position: fixed;
|
||||||
|
margin-left: -240px;
|
||||||
|
overflow-y:auto;
|
||||||
|
}
|
||||||
|
#sidebar > .list-group {
|
||||||
|
margin-bottom:0;
|
||||||
|
}
|
||||||
|
#sidebar > .list-group > a{
|
||||||
|
text-indent:0;
|
||||||
|
}
|
||||||
|
#sidebar .child > a .tag{
|
||||||
|
position: absolute;
|
||||||
|
right: 10px;
|
||||||
|
top: 11px;
|
||||||
|
}
|
||||||
|
#sidebar .child > a .pull-right{
|
||||||
|
margin-left:3px;
|
||||||
|
}
|
||||||
|
#sidebar .child {
|
||||||
|
border:1px solid #ddd;
|
||||||
|
border-bottom:none;
|
||||||
|
}
|
||||||
|
#sidebar .child:last-child {
|
||||||
|
border-bottom:1px solid #ddd;
|
||||||
|
}
|
||||||
|
#sidebar .child > a {
|
||||||
|
border:0;
|
||||||
|
min-height: 40px;
|
||||||
|
}
|
||||||
|
#sidebar .list-group a.current {
|
||||||
|
background:#f5f5f5;
|
||||||
|
}
|
||||||
|
@media (max-width: 1620px){
|
||||||
|
#sidebar {
|
||||||
|
margin:0;
|
||||||
|
}
|
||||||
|
#accordion {
|
||||||
|
padding-left:235px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (max-width: 768px){
|
||||||
|
#sidebar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
#accordion {
|
||||||
|
padding-left:0px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.label-primary {
|
||||||
|
background-color: #248aff;
|
||||||
|
}
|
||||||
|
.docs-list .panel .panel-body .table {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
@ -41,7 +123,7 @@
|
||||||
<span class="icon-bar"></span>
|
<span class="icon-bar"></span>
|
||||||
<span class="icon-bar"></span>
|
<span class="icon-bar"></span>
|
||||||
</button>
|
</button>
|
||||||
<a class="navbar-brand" href="https://www.fastadmin.net" target="_blank">{$config.title}</a>
|
<a class="navbar-brand" href="./" target="_blank">{$config.title}</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="navbar-collapse collapse">
|
<div class="navbar-collapse collapse">
|
||||||
<form class="navbar-form navbar-right">
|
<form class="navbar-form navbar-right">
|
||||||
|
|
@ -55,7 +137,7 @@
|
||||||
Apiurl:
|
Apiurl:
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<input id="apiUrl" type="text" class="form-control input-sm" data-toggle="tooltip" title="{$lang.Apiurltips}" placeholder="https://api.mydomain.com" value="{$config.apiurl}" />
|
<input id="apiUrl" type="text" class="form-control input-sm" data-toggle="tooltip" title="{$lang.Apiurltips}" placeholder="https://api.example.com" value="{$config.apiurl}" />
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<button type="button" class="btn btn-success btn-sm" data-toggle="tooltip" title="{$lang.Savetips}" id="save_data">
|
<button type="button" class="btn btn-success btn-sm" data-toggle="tooltip" title="{$lang.Savetips}" id="save_data">
|
||||||
|
|
@ -68,15 +150,38 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="panel-group" id="accordion">
|
<!-- menu -->
|
||||||
{foreach name="docslist" id="docs"}
|
<div id="sidebar">
|
||||||
|
<div class="list-group panel">
|
||||||
|
{foreach name="docsList" id="docs"}
|
||||||
|
<a href="#{$key}" class="list-group-item" data-toggle="collapse" data-parent="#sidebar">{$key} <i class="fa fa-caret-down"></i></a>
|
||||||
|
<div class="child collapse" id="{$key}">
|
||||||
|
{foreach name="docs" id="api" }
|
||||||
|
<a href="javascript:;" data-id="{$api.id}" class="list-group-item">{$api.title}
|
||||||
|
<span class="tag">
|
||||||
|
{if $api.needRight}
|
||||||
|
<span class="label label-danger pull-right">鉴</span>
|
||||||
|
{/if}
|
||||||
|
{if $api.needLogin}
|
||||||
|
<span class="label label-success pull-right noneedlogin">登</span>
|
||||||
|
{/if}
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
{/foreach}
|
||||||
|
</div>
|
||||||
|
{/foreach}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="panel-group docs-list" id="accordion">
|
||||||
|
{foreach name="docsList" id="docs"}
|
||||||
<h2>{$key}</h2>
|
<h2>{$key}</h2>
|
||||||
<hr>
|
<hr>
|
||||||
{foreach name="docs" id="api" }
|
{foreach name="docs" id="api" }
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading" id="heading-{$api.id}">
|
||||||
<h4 class="panel-title">
|
<h4 class="panel-title">
|
||||||
<span class="label {$api.method_label}">{$api.method|strtoupper}</span> <a data-toggle="collapse" data-parent="#accordion{$api.id}" href="#collapseOne{$api.id}"> {$api.route}</a>
|
<span class="label {$api.methodLabel}">{$api.method|strtoupper}</span>
|
||||||
|
<a data-toggle="collapse" data-parent="#accordion{$api.id}" href="#collapseOne{$api.id}"> {$api.title} <span class="text-muted">{$api.route}</span></a>
|
||||||
</h4>
|
</h4>
|
||||||
</div>
|
</div>
|
||||||
<div id="collapseOne{$api.id}" class="panel-collapse collapse">
|
<div id="collapseOne{$api.id}" class="panel-collapse collapse">
|
||||||
|
|
@ -96,10 +201,27 @@
|
||||||
<div class="well">
|
<div class="well">
|
||||||
{$api.summary}
|
{$api.summary}
|
||||||
</div>
|
</div>
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading"><strong>{$lang.Authorization}</strong></div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<table class="table table-hover">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>{$lang.NeedLogin}</td>
|
||||||
|
<td>{$api.needLogin?'是':'否'}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{$lang.NeedRight}</td>
|
||||||
|
<td>{$api.needRight?'是':'否'}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading"><strong>{$lang.Headers}</strong></div>
|
<div class="panel-heading"><strong>{$lang.Headers}</strong></div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
{if $api.headerslist}
|
{if $api.headersList}
|
||||||
<table class="table table-hover">
|
<table class="table table-hover">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
|
@ -110,7 +232,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{foreach name="api['headerslist']" id="header"}
|
{foreach name="api['headersList']" id="header"}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{$header.name}</td>
|
<td>{$header.name}</td>
|
||||||
<td>{$header.type}</td>
|
<td>{$header.type}</td>
|
||||||
|
|
@ -128,7 +250,7 @@
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading"><strong>{$lang.Parameters}</strong></div>
|
<div class="panel-heading"><strong>{$lang.Parameters}</strong></div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
{if $api.paramslist}
|
{if $api.paramsList}
|
||||||
<table class="table table-hover">
|
<table class="table table-hover">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
|
@ -139,7 +261,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{foreach name="api['paramslist']" id="param"}
|
{foreach name="api['paramsList']" id="param"}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{$param.name}</td>
|
<td>{$param.name}</td>
|
||||||
<td>{$param.type}</td>
|
<td>{$param.type}</td>
|
||||||
|
|
@ -165,15 +287,15 @@
|
||||||
<div class="tab-pane" id="sandbox{$api.id}">
|
<div class="tab-pane" id="sandbox{$api.id}">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
{if $api.headerslist}
|
{if $api.headersList}
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading"><strong>{$lang.Headers}</strong></div>
|
<div class="panel-heading"><strong>{$lang.Headers}</strong></div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<div class="headers">
|
<div class="headers">
|
||||||
{foreach name="api['headerslist']" id="param"}
|
{foreach name="api['headersList']" id="param"}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="control-label" for="{$param.name}">{$param.name}</label>
|
<label class="control-label" for="{$param.name}">{$param.name}</label>
|
||||||
<input type="{$param.type}" class="form-control input-sm" id="{$param.name}" {if $param.required}required{/if} placeholder="{$param.description} - Ex: {$param.sample}" name="{$param.name}">
|
<input type="{$param.inputtype|default='text'}" class="form-control input-sm" id="{$param.name}" {if $param.required}required{/if} placeholder="{$param.description} - Ex: {$param.sample}" name="{$param.name}">
|
||||||
</div>
|
</div>
|
||||||
{/foreach}
|
{/foreach}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -181,14 +303,18 @@
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading"><strong>{$lang.Parameters}</strong></div>
|
<div class="panel-heading"><strong>{$lang.Parameters}</strong>
|
||||||
|
<div class="pull-right">
|
||||||
|
<a href="javascript:" class="btn btn-xs btn-info btn-append">追加</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<form enctype="application/x-www-form-urlencoded" role="form" action="{$api.route}" method="{$api.method}" name="form{$api.id}" id="form{$api.id}">
|
<form enctype="application/x-www-form-urlencoded" role="form" action="{$api.route}" method="{$api.method}" name="form{$api.id}" id="form{$api.id}">
|
||||||
{if $api.paramslist}
|
{if $api.paramsList}
|
||||||
{foreach name="api['paramslist']" id="param"}
|
{foreach name="api['paramsList']" id="param"}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="control-label" for="{$param.name}">{$param.name}</label>
|
<label class="control-label" for="{$param.name}">{$param.name}</label>
|
||||||
<input type="{$param.type}" class="form-control input-sm" id="{$param.name}" {if $param.required}required{/if} placeholder="{$param.description}{if $param.sample} - 例: {$param.sample}{/if}" name="{$param.name}">
|
<input type="{$param.inputtype|default='text'}" class="form-control input-sm" id="{$param.name}" {if $param.required}required{/if} placeholder="{$param.description}{if $param.sample} - 例: {$param.sample}{/if}" name="{$param.name}">
|
||||||
</div>
|
</div>
|
||||||
{/foreach}
|
{/foreach}
|
||||||
{else /}
|
{else /}
|
||||||
|
|
@ -196,8 +322,9 @@
|
||||||
无
|
无
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
<div class="form-group">
|
<div class="form-group form-group-submit">
|
||||||
<button type="submit" class="btn btn-success send" rel="{$api.id}">{$lang.Send}</button>
|
<button type="submit" class="btn btn-success send" rel="{$api.id}">{$lang.Send}</button>
|
||||||
|
<button type="reset" class="btn btn-info" rel="{$api.id}">{$lang.Reset}</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -216,7 +343,7 @@
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading"><strong>{$lang.ReturnParameters}</strong></div>
|
<div class="panel-heading"><strong>{$lang.ReturnParameters}</strong></div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
{if $api.returnparamslist}
|
{if $api.returnParamsList}
|
||||||
<table class="table table-hover">
|
<table class="table table-hover">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
|
@ -226,7 +353,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{foreach name="api['returnparamslist']" id="param"}
|
{foreach name="api['returnParamsList']" id="param"}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{$param.name}</td>
|
<td>{$param.name}</td>
|
||||||
<td>{$param.type}</td>
|
<td>{$param.type}</td>
|
||||||
|
|
@ -264,17 +391,21 @@
|
||||||
|
|
||||||
<div class="row mt0 footer">
|
<div class="row mt0 footer">
|
||||||
<div class="col-md-6" align="left">
|
<div class="col-md-6" align="left">
|
||||||
Generated on {:date('Y-m-d H:i:s')}
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6" align="right">
|
<div class="col-md-6" align="right">
|
||||||
<a href="https://www.fastadmin.net" target="_blank">FastAdmin</a>
|
Generated on {:date('Y-m-d H:i:s')} <a href="./" target="_blank">{$config.sitename}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div> <!-- /container -->
|
</div> <!-- /container -->
|
||||||
|
|
||||||
<script src="https://cdn.bootcss.com/jquery/1.10.2/jquery.min.js"></script>
|
<!-- jQuery -->
|
||||||
<script src="https://cdn.bootcss.com/bootstrap/3.0.3/js/bootstrap.min.js"></script>
|
<script src="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/jquery/3.6.0/jquery.min.js"></script>
|
||||||
|
|
||||||
|
<!-- Bootstrap Core JavaScript -->
|
||||||
|
<script src="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
function syntaxHighlight(json) {
|
function syntaxHighlight(json) {
|
||||||
if (typeof json != 'string') {
|
if (typeof json != 'string') {
|
||||||
|
|
@ -341,14 +472,32 @@
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
|
|
||||||
if (storage) {
|
if (storage) {
|
||||||
$('#token').val(storage.getItem('token'));
|
storage.getItem('token') && $('#token').val(storage.getItem('token'));
|
||||||
$('#apiUrl').val(storage.getItem('apiUrl'));
|
storage.getItem('apiUrl') && $('#apiUrl').val(storage.getItem('apiUrl'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$('[data-toggle="tooltip"]').tooltip({
|
$('[data-toggle="tooltip"]').tooltip({
|
||||||
placement: 'bottom'
|
placement: 'bottom'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$(window).on("resize", function(){
|
||||||
|
$("#sidebar").css("max-height", $(window).height()-80);
|
||||||
|
});
|
||||||
|
|
||||||
|
$(window).trigger("resize");
|
||||||
|
|
||||||
|
$(document).on("click", "#sidebar .list-group > .list-group-item", function(){
|
||||||
|
$("#sidebar .list-group > .list-group-item").removeClass("current");
|
||||||
|
$(this).addClass("current");
|
||||||
|
});
|
||||||
|
$(document).on("click", "#sidebar .child a", function(){
|
||||||
|
var heading = $("#heading-"+$(this).data("id"));
|
||||||
|
if(!heading.next().hasClass("in")){
|
||||||
|
$("a", heading).trigger("click");
|
||||||
|
}
|
||||||
|
$("html,body").animate({scrollTop:heading.offset().top-70});
|
||||||
|
});
|
||||||
|
|
||||||
$('code[id^=response]').hide();
|
$('code[id^=response]').hide();
|
||||||
|
|
||||||
$.each($('pre[id^=sample_response],pre[id^=sample_post_body]'), function () {
|
$.each($('pre[id^=sample_response],pre[id^=sample_post_body]'), function () {
|
||||||
|
|
@ -371,7 +520,7 @@
|
||||||
$sample.html('<pre>' + str + '</pre>');
|
$sample.html('<pre>' + str + '</pre>');
|
||||||
});
|
});
|
||||||
|
|
||||||
$('body').on('click', '#save_data', function (e) {
|
$(document).on('click', '#save_data', function (e) {
|
||||||
if (storage) {
|
if (storage) {
|
||||||
storage.setItem('token', $('#token').val());
|
storage.setItem('token', $('#token').val());
|
||||||
storage.setItem('apiUrl', $('#apiUrl').val());
|
storage.setItem('apiUrl', $('#apiUrl').val());
|
||||||
|
|
@ -379,8 +528,20 @@
|
||||||
alert('Your browser does not support local storage');
|
alert('Your browser does not support local storage');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
$(document).on('click', '.btn-append', function (e) {
|
||||||
|
$($("#appendtpl").html()).insertBefore($(this).closest(".panel").find(".form-group-submit"));
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
$(document).on('click', '.btn-remove', function (e) {
|
||||||
|
$(this).closest(".form-group").remove();
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
$(document).on('keyup', '.input-custom-name', function (e) {
|
||||||
|
$(this).closest(".row").find(".input-custom-value").attr("name", $(this).val());
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
$('body').on('click', '.send', function (e) {
|
$(document).on('click', '.send', function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
var form = $(this).closest('form');
|
var form = $(this).closest('form');
|
||||||
//added /g to get all the matched params instead of only first
|
//added /g to get all the matched params instead of only first
|
||||||
|
|
@ -389,12 +550,14 @@
|
||||||
//keep a copy of action attribute in order to modify the copy
|
//keep a copy of action attribute in order to modify the copy
|
||||||
//instead of the initial attribute
|
//instead of the initial attribute
|
||||||
var url = $(form).attr('action');
|
var url = $(form).attr('action');
|
||||||
|
var method = $(form).prop('method').toLowerCase() || 'get';
|
||||||
|
|
||||||
var formData = new FormData();
|
var formData = new FormData();
|
||||||
|
|
||||||
$(form).find('input').each(function (i, input) {
|
$(form).find('input').each(function (i, input) {
|
||||||
if ($(input).attr('type') == 'file') {
|
if ($(input).attr('type').toLowerCase() == 'file') {
|
||||||
formData.append($(input).attr('name'), $(input)[0].files[0]);
|
formData.append($(input).attr('name'), $(input)[0].files[0]);
|
||||||
|
method = 'post';
|
||||||
} else {
|
} else {
|
||||||
formData.append($(input).attr('name'), $(input).val())
|
formData.append($(input).attr('name'), $(input).val())
|
||||||
}
|
}
|
||||||
|
|
@ -437,12 +600,15 @@
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: $('#apiUrl').val() + url,
|
url: $('#apiUrl').val() + url,
|
||||||
data: $(form).prop('method').toLowerCase() == 'get' ? $(form).serialize() : formData,
|
data: method == 'get' ? $(form).serialize() : formData,
|
||||||
type: $(form).prop('method') + '',
|
type: method,
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
contentType: false,
|
contentType: false,
|
||||||
processData: false,
|
processData: false,
|
||||||
headers: headers,
|
headers: headers,
|
||||||
|
xhrFields: {
|
||||||
|
withCredentials: true
|
||||||
|
},
|
||||||
success: function (data, textStatus, xhr) {
|
success: function (data, textStatus, xhr) {
|
||||||
if (typeof data === 'object') {
|
if (typeof data === 'object') {
|
||||||
var str = JSON.stringify(data, null, 2);
|
var str = JSON.stringify(data, null, 2);
|
||||||
|
|
@ -468,5 +634,21 @@
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
<script type="text/html" id="appendtpl">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="control-label">自定义</label>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-4">
|
||||||
|
<input type="text" class="form-control input-sm input-custom-name" placeholder="名称">
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-6">
|
||||||
|
<input type="text" class="form-control input-sm input-custom-value" placeholder="值">
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-2 text-center">
|
||||||
|
<a href="javascript:" class="btn btn-sm btn-danger btn-remove">删除</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -4,8 +4,7 @@
|
||||||
<div class="form-group layer-footer">
|
<div class="form-group layer-footer">
|
||||||
<label class="control-label col-xs-12 col-sm-2"></label>
|
<label class="control-label col-xs-12 col-sm-2"></label>
|
||||||
<div class="col-xs-12 col-sm-8">
|
<div class="col-xs-12 col-sm-8">
|
||||||
<button type="submit" class="btn btn-success btn-embossed disabled">{:__('OK')}</button>
|
<button type="submit" class="btn btn-primary btn-embossed disabled">{:__('OK')}</button>
|
||||||
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ use app\common\controller\Backend;
|
||||||
*/
|
*/
|
||||||
class {%controllerName%} extends Backend
|
class {%controllerName%} extends Backend
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {%modelName%}模型对象
|
* {%modelName%}模型对象
|
||||||
* @var \{%modelNamespace%}\{%modelName%}
|
* @var \{%modelNamespace%}\{%modelName%}
|
||||||
|
|
@ -21,15 +21,17 @@ class {%controllerName%} extends Backend
|
||||||
public function _initialize()
|
public function _initialize()
|
||||||
{
|
{
|
||||||
parent::_initialize();
|
parent::_initialize();
|
||||||
$this->model = model('{%modelName%}');
|
$this->model = new \{%modelNamespace%}\{%modelName%};
|
||||||
{%controllerAssignList%}
|
{%controllerAssignList%}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{%controllerImport%}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
|
* 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
|
||||||
* 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
|
* 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
|
||||||
* 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
|
* 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
|
||||||
*/
|
*/
|
||||||
|
|
||||||
{%controllerIndex%}
|
{%controllerIndex%}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,36 +7,28 @@
|
||||||
//当前是否为关联查询
|
//当前是否为关联查询
|
||||||
$this->relationSearch = {%relationSearch%};
|
$this->relationSearch = {%relationSearch%};
|
||||||
//设置过滤方法
|
//设置过滤方法
|
||||||
$this->request->filter(['strip_tags']);
|
$this->request->filter(['strip_tags', 'trim']);
|
||||||
if ($this->request->isAjax())
|
if ($this->request->isAjax()) {
|
||||||
{
|
|
||||||
//如果发送的来源是Selectpage,则转发到Selectpage
|
//如果发送的来源是Selectpage,则转发到Selectpage
|
||||||
if ($this->request->request('keyField'))
|
if ($this->request->request('keyField')) {
|
||||||
{
|
|
||||||
return $this->selectpage();
|
return $this->selectpage();
|
||||||
}
|
}
|
||||||
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
|
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
|
||||||
$total = $this->model
|
|
||||||
{%relationWithList%}
|
|
||||||
->where($where)
|
|
||||||
->order($sort, $order)
|
|
||||||
->count();
|
|
||||||
|
|
||||||
$list = $this->model
|
$list = $this->model
|
||||||
{%relationWithList%}
|
{%relationWithList%}
|
||||||
->where($where)
|
->where($where)
|
||||||
->order($sort, $order)
|
->order($sort, $order)
|
||||||
->limit($offset, $limit)
|
->paginate($limit);
|
||||||
->select();
|
|
||||||
|
|
||||||
foreach ($list as $row) {
|
foreach ($list as $row) {
|
||||||
{%visibleFieldList%}
|
{%visibleFieldList%}
|
||||||
{%relationVisibleFieldList%}
|
{%relationVisibleFieldList%}
|
||||||
}
|
}
|
||||||
$list = collection($list)->toArray();
|
|
||||||
$result = array("total" => $total, "rows" => $list);
|
$result = array("total" => $list->total(), "rows" => $list->items());
|
||||||
|
|
||||||
return json($result);
|
return json($result);
|
||||||
}
|
}
|
||||||
return $this->view->fetch();
|
return $this->view->fetch();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,7 @@
|
||||||
<div class="form-group layer-footer">
|
<div class="form-group layer-footer">
|
||||||
<label class="control-label col-xs-12 col-sm-2"></label>
|
<label class="control-label col-xs-12 col-sm-2"></label>
|
||||||
<div class="col-xs-12 col-sm-8">
|
<div class="col-xs-12 col-sm-8">
|
||||||
<button type="submit" class="btn btn-success btn-embossed disabled">{:__('OK')}</button>
|
<button type="submit" class="btn btn-primary btn-embossed disabled">{:__('OK')}</button>
|
||||||
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
|
||||||
|
<dl class="list-unstyled fieldlist" data-name="{%fieldName%}" data-template="{%fieldName%}tpl">
|
||||||
|
<dd>
|
||||||
|
<ins>{:__('{%itemValue%}')}</ins>
|
||||||
|
</dd>
|
||||||
|
<dd>
|
||||||
|
<ins><a href="javascript:;" class="btn btn-sm btn-success btn-append"><i class="fa fa-plus"></i> {:__('Append')}</a></ins>
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
|
||||||
|
<textarea name="{%fieldName%}" class="form-control hide" cols="30" rows="5">{%fieldValue%}</textarea>
|
||||||
|
<script id="{%fieldName%}tpl" type="text/html">
|
||||||
|
<dd class="form-inline">
|
||||||
|
<ins><input type="text" name="<%=name%>[<%=index%>][value]" class="form-control" size="15" value="<%=row%>"/></ins>
|
||||||
|
<ins>
|
||||||
|
<span class="btn btn-sm btn-danger btn-remove"><i class="fa fa-times"></i></span>
|
||||||
|
<span class="btn btn-sm btn-primary btn-dragsort"><i class="fa fa-arrows"></i></span>
|
||||||
|
</ins>
|
||||||
|
</dd>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
|
||||||
|
<table class="table fieldlist" data-name="{%fieldName%}" data-template="{%fieldName%}tpl">
|
||||||
|
<tr>
|
||||||
|
{%theadList%}
|
||||||
|
<td width="90">{:__('Operate')}</td>
|
||||||
|
</tr>
|
||||||
|
<tr><td colspan="{%colspan%}">
|
||||||
|
<a href="javascript:;" class="btn btn-sm btn-success btn-append"><i class="fa fa-plus"></i> {:__('Append')}</a>
|
||||||
|
<textarea name="{%fieldName%}" class="form-control hide" cols="30" rows="5">{%fieldValue%}</textarea>
|
||||||
|
</td></tr>
|
||||||
|
</table>
|
||||||
|
<script type="text/html" id="{%fieldName%}tpl">
|
||||||
|
<tr>
|
||||||
|
{%tbodyList%}
|
||||||
|
<td width="90">
|
||||||
|
<span class="btn btn-sm btn-danger btn-remove"><i class="fa fa-times"></i></span>
|
||||||
|
<span class="btn btn-sm btn-primary btn-dragsort"><i class="fa fa-arrows"></i></span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
|
||||||
|
<dl class="fieldlist" data-name="{%fieldName%}">
|
||||||
|
<dd>
|
||||||
|
<ins>{:__('{%itemKey%}')}</ins>
|
||||||
|
<ins>{:__('{%itemValue%}')}</ins>
|
||||||
|
</dd>
|
||||||
|
<dd><a href="javascript:;" class="btn btn-sm btn-success btn-append"><i class="fa fa-plus"></i> {:__('Append')}</a></dd>
|
||||||
|
<textarea name="{%fieldName%}" class="form-control hide" cols="30" rows="5">{%fieldValue%}</textarea>
|
||||||
|
</dl>
|
||||||
|
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
|
||||||
|
<div class="panel-heading">
|
||||||
|
{:build_heading(null,FALSE)}
|
||||||
|
<ul class="nav nav-tabs" data-field="{%field%}">
|
||||||
|
<li class="{:$Think.get.{%field%} === null ? 'active' : ''}"><a href="#t-all" data-value="" data-toggle="tab">{:__('All')}</a></li>
|
||||||
|
{foreach name="{%fieldName%}List" item="vo"}
|
||||||
|
<li class="{:$Think.get.{%field%} === (string)$key ? 'active' : ''}"><a href="#t-{$key}" data-value="{$key}" data-toggle="tab">{$vo}</a></li>
|
||||||
|
{/foreach}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
<div class="dropdown btn-group {:$auth->check('{%controllerUrl%}/multi')?'':'hide'}">
|
||||||
|
<a class="btn btn-primary btn-more dropdown-toggle btn-disabled disabled" data-toggle="dropdown"><i class="fa fa-cog"></i> {:__('More')}</a>
|
||||||
|
<ul class="dropdown-menu text-left" role="menu">
|
||||||
|
{foreach name="{%fieldName%}List" item="vo"}
|
||||||
|
<li><a class="btn btn-link btn-multi btn-disabled disabled" href="javascript:" data-params="{%field%}={$key}">{:__('Set {%field%} to ' . $key)}</a></li>
|
||||||
|
{/foreach}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
<a class="btn btn-success btn-recyclebin btn-dialog {:$auth->check('{%controllerUrl%}/recyclebin')?'':'hide'}" href="{%controllerUrl%}/recyclebin" title="{:__('Recycle bin')}"><i class="fa fa-recycle"></i> {:__('Recycle bin')}</a>
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
|
||||||
|
<input {%attrStr%} name="{%fieldName%}" type="hidden" value="{%fieldValue%}">
|
||||||
|
<a href="javascript:;" data-toggle="switcher" class="btn-switcher" data-input-id="c-{%field%}" data-yes="{%fieldYes%}" data-no="{%fieldNo%}" >
|
||||||
|
<i class="fa fa-toggle-on text-success {%fieldSwitchClass%} fa-2x"></i>
|
||||||
|
</a>
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<div class="panel panel-default panel-intro">
|
<div class="panel panel-default panel-intro">
|
||||||
{:build_heading()}
|
{%headingHtml%}
|
||||||
|
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<div id="myTabContent" class="tab-content">
|
<div id="myTabContent" class="tab-content">
|
||||||
|
|
@ -10,19 +10,15 @@
|
||||||
<a href="javascript:;" class="btn btn-success btn-add {:$auth->check('{%controllerUrl%}/add')?'':'hide'}" title="{:__('Add')}" ><i class="fa fa-plus"></i> {:__('Add')}</a>
|
<a href="javascript:;" class="btn btn-success btn-add {:$auth->check('{%controllerUrl%}/add')?'':'hide'}" title="{:__('Add')}" ><i class="fa fa-plus"></i> {:__('Add')}</a>
|
||||||
<a href="javascript:;" class="btn btn-success btn-edit btn-disabled disabled {:$auth->check('{%controllerUrl%}/edit')?'':'hide'}" title="{:__('Edit')}" ><i class="fa fa-pencil"></i> {:__('Edit')}</a>
|
<a href="javascript:;" class="btn btn-success btn-edit btn-disabled disabled {:$auth->check('{%controllerUrl%}/edit')?'':'hide'}" title="{:__('Edit')}" ><i class="fa fa-pencil"></i> {:__('Edit')}</a>
|
||||||
<a href="javascript:;" class="btn btn-danger btn-del btn-disabled disabled {:$auth->check('{%controllerUrl%}/del')?'':'hide'}" title="{:__('Delete')}" ><i class="fa fa-trash"></i> {:__('Delete')}</a>
|
<a href="javascript:;" class="btn btn-danger btn-del btn-disabled disabled {:$auth->check('{%controllerUrl%}/del')?'':'hide'}" title="{:__('Delete')}" ><i class="fa fa-trash"></i> {:__('Delete')}</a>
|
||||||
<a href="javascript:;" class="btn btn-danger btn-import {:$auth->check('{%controllerUrl%}/import')?'':'hide'}" title="{:__('Import')}" id="btn-import-file" data-url="ajax/upload" data-mimetype="csv,xls,xlsx" data-multiple="false"><i class="fa fa-upload"></i> {:__('Import')}</a>
|
{%importHtml%}
|
||||||
|
|
||||||
<div class="dropdown btn-group {:$auth->check('{%controllerUrl%}/multi')?'':'hide'}">
|
{%multipleHtml%}
|
||||||
<a class="btn btn-primary btn-more dropdown-toggle btn-disabled disabled" data-toggle="dropdown"><i class="fa fa-cog"></i> {:__('More')}</a>
|
|
||||||
<ul class="dropdown-menu text-left" role="menu">
|
{%recyclebinHtml%}
|
||||||
<li><a class="btn btn-link btn-multi btn-disabled disabled" href="javascript:;" data-params="status=normal"><i class="fa fa-eye"></i> {:__('Set to normal')}</a></li>
|
|
||||||
<li><a class="btn btn-link btn-multi btn-disabled disabled" href="javascript:;" data-params="status=hidden"><i class="fa fa-eye-slash"></i> {:__('Set to hidden')}</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<table id="table" class="table table-striped table-bordered table-hover"
|
<table id="table" class="table table-striped table-bordered table-hover table-nowrap"
|
||||||
data-operate-edit="{:$auth->check('{%controllerUrl%}/edit')}"
|
data-operate-edit="{:$auth->check('{%controllerUrl%}/edit')}"
|
||||||
data-operate-del="{:$auth->check('{%controllerUrl%}/del')}"
|
data-operate-del="{:$auth->check('{%controllerUrl%}/del')}"
|
||||||
width="100%">
|
width="100%">
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,12 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
||||||
// 初始化表格参数配置
|
// 初始化表格参数配置
|
||||||
Table.api.init({
|
Table.api.init({
|
||||||
extend: {
|
extend: {
|
||||||
index_url: '{%controllerUrl%}/index',
|
index_url: '{%controllerUrl%}/index' + location.search,
|
||||||
add_url: '{%controllerUrl%}/add',
|
add_url: '{%controllerUrl%}/add',
|
||||||
edit_url: '{%controllerUrl%}/edit',
|
edit_url: '{%controllerUrl%}/edit',
|
||||||
del_url: '{%controllerUrl%}/del',
|
del_url: '{%controllerUrl%}/del',
|
||||||
multi_url: '{%controllerUrl%}/multi',
|
multi_url: '{%controllerUrl%}/multi',
|
||||||
|
import_url: '{%controllerUrl%}/import',
|
||||||
table: '{%table%}',
|
table: '{%table%}',
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -20,7 +21,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
||||||
table.bootstrapTable({
|
table.bootstrapTable({
|
||||||
url: $.fn.bootstrapTable.defaults.extend.index_url,
|
url: $.fn.bootstrapTable.defaults.extend.index_url,
|
||||||
pk: '{%pk%}',
|
pk: '{%pk%}',
|
||||||
sortName: '{%order%}',
|
sortName: '{%order%}',{%fixedColumnsJs%}
|
||||||
columns: [
|
columns: [
|
||||||
[
|
[
|
||||||
{%javascriptList%}
|
{%javascriptList%}
|
||||||
|
|
@ -30,7 +31,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
||||||
|
|
||||||
// 为表格绑定事件
|
// 为表格绑定事件
|
||||||
Table.api.bindevent(table);
|
Table.api.bindevent(table);
|
||||||
},
|
},{%recyclebinJs%}
|
||||||
add: function () {
|
add: function () {
|
||||||
Controller.api.bindevent();
|
Controller.api.bindevent();
|
||||||
},
|
},
|
||||||
|
|
@ -44,4 +45,4 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return Controller;
|
return Controller;
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
public function {%methodName%}($value, $data)
|
public function {%methodName%}($value, $data)
|
||||||
{
|
{
|
||||||
$value = $value ? $value : $data['{%field%}'];
|
$value = $value ? $value : (isset($data['{%field%}']) ? $data['{%field%}'] : '');
|
||||||
$valueArr = explode(',', $value);
|
$valueArr = explode(',', $value);
|
||||||
$list = $this->{%listMethodName%}();
|
$list = $this->{%listMethodName%}();
|
||||||
return implode(',', array_intersect_key($list, array_flip($valueArr)));
|
return implode(',', array_intersect_key($list, array_flip($valueArr)));
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
public function {%methodName%}($value, $data)
|
public function {%methodName%}($value, $data)
|
||||||
{
|
{
|
||||||
$value = $value ? $value : $data['{%field%}'];
|
$value = $value ? $value : (isset($data['{%field%}']) ? $data['{%field%}'] : '');
|
||||||
return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
|
return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
public function import()
|
||||||
|
{
|
||||||
|
parent::import();
|
||||||
|
}
|
||||||
|
|
@ -2,7 +2,9 @@
|
||||||
protected static function init()
|
protected static function init()
|
||||||
{
|
{
|
||||||
self::afterInsert(function ($row) {
|
self::afterInsert(function ($row) {
|
||||||
$pk = $row->getPk();
|
if (!$row['{%order%}']) {
|
||||||
$row->getQuery()->where($pk, $row[$pk])->update(['{%order%}' => $row[$pk]]);
|
$pk = $row->getPk();
|
||||||
|
$row->getQuery()->where($pk, $row[$pk])->update(['{%order%}' => $row[$pk]]);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
|
||||||
|
public function {%relationMethod%}s()
|
||||||
|
{
|
||||||
|
return $this->{%relationMode%}('{%relationClassName%}', '{%relationForeignKey%}', '{%relationPrimaryKey%}');
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
public function {%relationMethod%}()
|
public function {%relationMethod%}()
|
||||||
{
|
{
|
||||||
return $this->{%relationMode%}('{%relationName%}', '{%relationForeignKey%}', '{%relationPrimaryKey%}', [], 'LEFT')->setEagerlyType(0);
|
return $this->{%relationMode%}('{%relationClassName%}', '{%relationForeignKey%}', '{%relationPrimaryKey%}', [], 'LEFT')->setEagerlyType(0);
|
||||||
}
|
}
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
public function {%methodName%}($value, $data)
|
public function {%methodName%}($value, $data)
|
||||||
{
|
{
|
||||||
$value = $value ? $value : $data['{%field%}'];
|
$value = $value ?: ($data['{%field%}'] ?? '');
|
||||||
$valueArr = explode(',', $value);
|
$valueArr = explode(',', $value);
|
||||||
$list = $this->{%listMethodName%}();
|
$list = $this->{%listMethodName%}();
|
||||||
return implode(',', array_intersect_key($list, array_flip($valueArr)));
|
return implode(',', array_intersect_key($list, array_flip($valueArr)));
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
public function {%methodName%}($value, $data)
|
public function {%methodName%}($value, $data)
|
||||||
{
|
{
|
||||||
$value = $value ? $value : $data['{%field%}'];
|
$value = $value ? $value : (isset($data['{%field%}']) ? $data['{%field%}'] : '');
|
||||||
$list = $this->{%listMethodName%}();
|
$list = $this->{%listMethodName%}();
|
||||||
return isset($list[$value]) ? $list[$value] : '';
|
return isset($list[$value]) ? $list[$value] : '';
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
|
||||||
|
recyclebin: function () {
|
||||||
|
// 初始化表格参数配置
|
||||||
|
Table.api.init({
|
||||||
|
extend: {
|
||||||
|
'dragsort_url': ''
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var table = $("#table");
|
||||||
|
|
||||||
|
// 初始化表格
|
||||||
|
table.bootstrapTable({
|
||||||
|
url: '{%controllerUrl%}/recyclebin' + location.search,
|
||||||
|
pk: 'id',
|
||||||
|
sortName: 'id',
|
||||||
|
columns: [
|
||||||
|
[
|
||||||
|
{checkbox: true},
|
||||||
|
{field: 'id', title: __('Id')},{%recyclebinTitleJs%}
|
||||||
|
{
|
||||||
|
field: '{%deleteTimeField%}',
|
||||||
|
title: __('Deletetime'),
|
||||||
|
operate: 'RANGE',
|
||||||
|
addclass: 'datetimerange',
|
||||||
|
formatter: Table.api.formatter.datetime
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'operate',
|
||||||
|
width: '140px',
|
||||||
|
title: __('Operate'),
|
||||||
|
table: table,
|
||||||
|
events: Table.api.events.operate,
|
||||||
|
buttons: [
|
||||||
|
{
|
||||||
|
name: 'Restore',
|
||||||
|
text: __('Restore'),
|
||||||
|
classname: 'btn btn-xs btn-info btn-ajax btn-restoreit',
|
||||||
|
icon: 'fa fa-rotate-left',
|
||||||
|
url: '{%controllerUrl%}/restore',
|
||||||
|
refresh: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Destroy',
|
||||||
|
text: __('Destroy'),
|
||||||
|
classname: 'btn btn-xs btn-danger btn-ajax btn-destroyit',
|
||||||
|
icon: 'fa fa-times',
|
||||||
|
url: '{%controllerUrl%}/destroy',
|
||||||
|
refresh: true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
formatter: Table.api.formatter.operate
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
// 为表格绑定事件
|
||||||
|
Table.api.bindevent(table);
|
||||||
|
},
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
public function {%methodName%}($value, $data)
|
public function {%methodName%}($value, $data)
|
||||||
{
|
{
|
||||||
$value = $value ? $value : $data['{%field%}'];
|
$value = $value ? $value : (isset($data['{%field%}']) ? $data['{%field%}'] : '');
|
||||||
$list = $this->{%listMethodName%}();
|
$list = $this->{%listMethodName%}();
|
||||||
return isset($list[$value]) ? $list[$value] : '';
|
return isset($list[$value]) ? $list[$value] : '';
|
||||||
}
|
}
|
||||||
|
|
@ -3,9 +3,15 @@
|
||||||
namespace {%modelNamespace%};
|
namespace {%modelNamespace%};
|
||||||
|
|
||||||
use think\Model;
|
use think\Model;
|
||||||
|
{%softDeleteClassPath%}
|
||||||
|
|
||||||
class {%modelName%} extends Model
|
class {%modelName%} extends Model
|
||||||
{
|
{
|
||||||
|
|
||||||
|
{%softDelete%}
|
||||||
|
|
||||||
|
{%modelConnection%}
|
||||||
|
|
||||||
// 表名
|
// 表名
|
||||||
protected ${%modelTableType%} = '{%modelTableTypeName%}';
|
protected ${%modelTableType%} = '{%modelTableTypeName%}';
|
||||||
|
|
||||||
|
|
@ -15,7 +21,8 @@ class {%modelName%} extends Model
|
||||||
// 定义时间戳字段名
|
// 定义时间戳字段名
|
||||||
protected $createTime = {%createTime%};
|
protected $createTime = {%createTime%};
|
||||||
protected $updateTime = {%updateTime%};
|
protected $updateTime = {%updateTime%};
|
||||||
|
protected $deleteTime = {%deleteTime%};
|
||||||
|
|
||||||
// 追加属性
|
// 追加属性
|
||||||
protected $append = [
|
protected $append = [
|
||||||
{%appendAttrList%}
|
{%appendAttrList%}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
<div class="panel panel-default panel-intro">
|
||||||
|
{:build_heading()}
|
||||||
|
|
||||||
|
<div class="panel-body">
|
||||||
|
<div id="myTabContent" class="tab-content">
|
||||||
|
<div class="tab-pane fade active in" id="one">
|
||||||
|
<div class="widget-body no-padding">
|
||||||
|
<div id="toolbar" class="toolbar">
|
||||||
|
{:build_toolbar('refresh')}
|
||||||
|
<a class="btn btn-info btn-multi btn-disabled disabled {:$auth->check('{%controllerUrl%}/restore')?'':'hide'}" href="javascript:;" data-url="{%controllerUrl%}/restore" data-action="restore"><i class="fa fa-rotate-left"></i> {:__('Restore')}</a>
|
||||||
|
<a class="btn btn-danger btn-multi btn-disabled disabled {:$auth->check('{%controllerUrl%}/destroy')?'':'hide'}" href="javascript:;" data-url="{%controllerUrl%}/destroy" data-action="destroy"><i class="fa fa-times"></i> {:__('Destroy')}</a>
|
||||||
|
<a class="btn btn-success btn-restoreall {:$auth->check('{%controllerUrl%}/restore')?'':'hide'}" href="javascript:;" data-url="{%controllerUrl%}/restore" title="{:__('Restore all')}"><i class="fa fa-rotate-left"></i> {:__('Restore all')}</a>
|
||||||
|
<a class="btn btn-danger btn-destroyall {:$auth->check('{%controllerUrl%}/destroy')?'':'hide'}" href="javascript:;" data-url="{%controllerUrl%}/destroy" title="{:__('Destroy all')}"><i class="fa fa-times"></i> {:__('Destroy all')}</a>
|
||||||
|
</div>
|
||||||
|
<table id="table" class="table table-striped table-bordered table-hover"
|
||||||
|
data-operate-restore="{:$auth->check('{%controllerUrl%}/restore')}"
|
||||||
|
data-operate-destroy="{:$auth->check('{%controllerUrl%}/destroy')}"
|
||||||
|
width="100%">
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
namespace app\admin\command;
|
namespace app\admin\command;
|
||||||
|
|
||||||
|
use fast\Random;
|
||||||
use PDO;
|
use PDO;
|
||||||
use think\Config;
|
use think\Config;
|
||||||
use think\console\Command;
|
use think\console\Command;
|
||||||
|
|
@ -10,29 +11,44 @@ use think\console\input\Option;
|
||||||
use think\console\Output;
|
use think\console\Output;
|
||||||
use think\Db;
|
use think\Db;
|
||||||
use think\Exception;
|
use think\Exception;
|
||||||
|
use think\Lang;
|
||||||
|
use think\Request;
|
||||||
|
use think\View;
|
||||||
|
|
||||||
class Install extends Command
|
class Install extends Command
|
||||||
{
|
{
|
||||||
|
|
||||||
protected $model = null;
|
protected $model = null;
|
||||||
|
/**
|
||||||
|
* @var \think\View 视图类实例
|
||||||
|
*/
|
||||||
|
protected $view;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \think\Request Request 实例
|
||||||
|
*/
|
||||||
|
protected $request;
|
||||||
|
|
||||||
protected function configure()
|
protected function configure()
|
||||||
{
|
{
|
||||||
$config = Config::get('database');
|
$config = Config::get('database');
|
||||||
$this
|
$this
|
||||||
->setName('install')
|
->setName('install')
|
||||||
->addOption('hostname', 'a', Option::VALUE_OPTIONAL, 'mysql hostname', $config['hostname'])
|
->addOption('hostname', 'a', Option::VALUE_OPTIONAL, 'mysql hostname', $config['hostname'])
|
||||||
->addOption('hostport', 'o', Option::VALUE_OPTIONAL, 'mysql hostport', $config['hostport'])
|
->addOption('hostport', 'o', Option::VALUE_OPTIONAL, 'mysql hostport', $config['hostport'])
|
||||||
->addOption('database', 'd', Option::VALUE_OPTIONAL, 'mysql database', $config['database'])
|
->addOption('database', 'd', Option::VALUE_OPTIONAL, 'mysql database', $config['database'])
|
||||||
->addOption('prefix', 'r', Option::VALUE_OPTIONAL, 'table prefix', $config['prefix'])
|
->addOption('prefix', 'r', Option::VALUE_OPTIONAL, 'table prefix', $config['prefix'])
|
||||||
->addOption('username', 'u', Option::VALUE_OPTIONAL, 'mysql username', $config['username'])
|
->addOption('username', 'u', Option::VALUE_OPTIONAL, 'mysql username', $config['username'])
|
||||||
->addOption('password', 'p', Option::VALUE_OPTIONAL, 'mysql password', $config['password'])
|
->addOption('password', 'p', Option::VALUE_OPTIONAL, 'mysql password', $config['password'])
|
||||||
->addOption('force', 'f', Option::VALUE_OPTIONAL, 'force override', FALSE)
|
->addOption('force', 'f', Option::VALUE_OPTIONAL, 'force override', false)
|
||||||
->setDescription('New installation of FastAdmin');
|
->setDescription('New installation of FastAdmin');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 命令行安装
|
||||||
|
*/
|
||||||
protected function execute(Input $input, Output $output)
|
protected function execute(Input $input, Output $output)
|
||||||
{
|
{
|
||||||
|
define('INSTALL_PATH', APP_PATH . 'admin' . DS . 'command' . DS . 'Install' . DS);
|
||||||
// 覆盖安装
|
// 覆盖安装
|
||||||
$force = $input->getOption('force');
|
$force = $input->getOption('force');
|
||||||
$hostname = $input->getOption('hostname');
|
$hostname = $input->getOption('hostname');
|
||||||
|
|
@ -42,48 +58,272 @@ class Install extends Command
|
||||||
$username = $input->getOption('username');
|
$username = $input->getOption('username');
|
||||||
$password = $input->getOption('password');
|
$password = $input->getOption('password');
|
||||||
|
|
||||||
$installLockFile = __DIR__ . "/Install/install.lock";
|
$installLockFile = INSTALL_PATH . "install.lock";
|
||||||
if (is_file($installLockFile) && !$force)
|
if (is_file($installLockFile) && !$force) {
|
||||||
{
|
|
||||||
throw new Exception("\nFastAdmin already installed!\nIf you need to reinstall again, use the parameter --force=true ");
|
throw new Exception("\nFastAdmin already installed!\nIf you need to reinstall again, use the parameter --force=true ");
|
||||||
}
|
}
|
||||||
|
|
||||||
$sql = file_get_contents(__DIR__ . '/Install/fastadmin.sql');
|
$adminUsername = 'admin';
|
||||||
|
$adminPassword = Random::alnum(10);
|
||||||
|
$adminEmail = 'admin@admin.com';
|
||||||
|
$siteName = __('My Website');
|
||||||
|
|
||||||
$sql = str_replace("`fa_", "`{$prefix}", $sql);
|
$adminName = $this->installation($hostname, $hostport, $database, $username, $password, $prefix, $adminUsername, $adminPassword, $adminEmail, $siteName);
|
||||||
|
if ($adminName) {
|
||||||
|
$output->highlight("Admin url:http://www.example.com/{$adminName}");
|
||||||
|
}
|
||||||
|
|
||||||
// 先尝试能否自动创建数据库
|
$output->highlight("Admin username:{$adminUsername}");
|
||||||
$config = Config::get('database');
|
$output->highlight("Admin password:{$adminPassword}");
|
||||||
$pdo = new PDO("{$config['type']}:host={$hostname}" . ($hostport ? ";port={$hostport}" : ''), $username, $password);
|
|
||||||
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
|
||||||
$pdo->query("CREATE DATABASE IF NOT EXISTS `{$database}` CHARACTER SET utf8 COLLATE utf8_general_ci;");
|
|
||||||
|
|
||||||
// 查询一次SQL,判断连接是否正常
|
|
||||||
Db::execute("SELECT 1");
|
|
||||||
|
|
||||||
// 调用原生PDO对象进行批量查询
|
|
||||||
Db::getPdo()->exec($sql);
|
|
||||||
|
|
||||||
file_put_contents($installLockFile, 1);
|
|
||||||
|
|
||||||
$dbConfigFile = APP_PATH . 'database.php';
|
|
||||||
$config = @file_get_contents($dbConfigFile);
|
|
||||||
$callback = function($matches) use($hostname, $hostport, $username, $password, $database, $prefix) {
|
|
||||||
$field = $matches[1];
|
|
||||||
$replace = $$field;
|
|
||||||
if ($matches[1] == 'hostport' && $hostport == 3306)
|
|
||||||
{
|
|
||||||
$replace = '';
|
|
||||||
}
|
|
||||||
return "'{$matches[1]}'{$matches[2]}=>{$matches[3]}Env::get('database.{$matches[1]}', '{$replace}'),";
|
|
||||||
};
|
|
||||||
$config = preg_replace_callback("/'(hostname|database|username|password|hostport|prefix)'(\s+)=>(\s+)Env::get\((.*)\)\,/", $callback, $config);
|
|
||||||
// 写入数据库配置
|
|
||||||
file_put_contents($dbConfigFile, $config);
|
|
||||||
|
|
||||||
\think\Cache::rm('__menu__');
|
\think\Cache::rm('__menu__');
|
||||||
|
|
||||||
$output->info("Install Successed!");
|
$output->info("Install Successed!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PC端安装
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$this->view = View::instance(array_merge(Config::get('template'), ['tpl_cache' => false]));
|
||||||
|
$this->request = Request::instance();
|
||||||
|
|
||||||
|
define('INSTALL_PATH', APP_PATH . 'admin' . DS . 'command' . DS . 'Install' . DS);
|
||||||
|
|
||||||
|
$lang = $this->request->langset();
|
||||||
|
$lang = preg_match("/^([a-zA-Z\-_]{2,10})\$/i", $lang) ? $lang : 'zh-cn';
|
||||||
|
|
||||||
|
if (!$lang || in_array($lang, ['zh-cn', 'zh-hans-cn'])) {
|
||||||
|
Lang::load(INSTALL_PATH . 'zh-cn.php');
|
||||||
|
}
|
||||||
|
|
||||||
|
$installLockFile = INSTALL_PATH . "install.lock";
|
||||||
|
|
||||||
|
if (is_file($installLockFile)) {
|
||||||
|
echo __('The system has been installed. If you need to reinstall, please remove %s first', 'install.lock');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
$output = function ($code, $msg, $url = null, $data = null) {
|
||||||
|
return json(['code' => $code, 'msg' => $msg, 'url' => $url, 'data' => $data]);
|
||||||
|
};
|
||||||
|
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$mysqlHostname = $this->request->post('mysqlHostname', '127.0.0.1');
|
||||||
|
$mysqlHostport = $this->request->post('mysqlHostport', '3306');
|
||||||
|
$hostArr = explode(':', $mysqlHostname);
|
||||||
|
if (count($hostArr) > 1) {
|
||||||
|
$mysqlHostname = $hostArr[0];
|
||||||
|
$mysqlHostport = $hostArr[1];
|
||||||
|
}
|
||||||
|
$mysqlUsername = $this->request->post('mysqlUsername', 'root');
|
||||||
|
$mysqlPassword = $this->request->post('mysqlPassword', '');
|
||||||
|
$mysqlDatabase = $this->request->post('mysqlDatabase', '');
|
||||||
|
$mysqlPrefix = $this->request->post('mysqlPrefix', 'fa_');
|
||||||
|
$adminUsername = $this->request->post('adminUsername', 'admin');
|
||||||
|
$adminPassword = $this->request->post('adminPassword', '');
|
||||||
|
$adminPasswordConfirmation = $this->request->post('adminPasswordConfirmation', '');
|
||||||
|
$adminEmail = $this->request->post('adminEmail', 'admin@admin.com');
|
||||||
|
$siteName = $this->request->post('siteName', __('My Website'));
|
||||||
|
|
||||||
|
if ($adminPassword !== $adminPasswordConfirmation) {
|
||||||
|
return $output(0, __('The two passwords you entered did not match'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$adminName = '';
|
||||||
|
try {
|
||||||
|
$adminName = $this->installation($mysqlHostname, $mysqlHostport, $mysqlDatabase, $mysqlUsername, $mysqlPassword, $mysqlPrefix, $adminUsername, $adminPassword, $adminEmail, $siteName);
|
||||||
|
} catch (\PDOException $e) {
|
||||||
|
throw new Exception($e->getMessage());
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return $output(0, $e->getMessage());
|
||||||
|
}
|
||||||
|
return $output(1, __('Install Successed'), null, ['adminName' => $adminName]);
|
||||||
|
}
|
||||||
|
$errInfo = '';
|
||||||
|
try {
|
||||||
|
$this->checkenv();
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$errInfo = $e->getMessage();
|
||||||
|
}
|
||||||
|
return $this->view->fetch(INSTALL_PATH . "install.html", ['errInfo' => $errInfo]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行安装
|
||||||
|
*/
|
||||||
|
protected function installation($mysqlHostname, $mysqlHostport, $mysqlDatabase, $mysqlUsername, $mysqlPassword, $mysqlPrefix, $adminUsername, $adminPassword, $adminEmail = null, $siteName = null)
|
||||||
|
{
|
||||||
|
$this->checkenv();
|
||||||
|
|
||||||
|
if ($mysqlDatabase == '') {
|
||||||
|
throw new Exception(__('Please input correct database'));
|
||||||
|
}
|
||||||
|
if (!preg_match("/^\w{3,12}$/", $adminUsername)) {
|
||||||
|
throw new Exception(__('Please input correct username'));
|
||||||
|
}
|
||||||
|
if (!preg_match("/^[\S]{6,16}$/", $adminPassword)) {
|
||||||
|
throw new Exception(__('Please input correct password'));
|
||||||
|
}
|
||||||
|
$weakPasswordArr = ['123456', '12345678', '123456789', '654321', '111111', '000000', 'password', 'qwerty', 'abc123', '1qaz2wsx'];
|
||||||
|
if (in_array($adminPassword, $weakPasswordArr)) {
|
||||||
|
throw new Exception(__('Password is too weak'));
|
||||||
|
}
|
||||||
|
if ($siteName == '' || preg_match("/fast" . "admin/i", $siteName)) {
|
||||||
|
throw new Exception(__('Please input correct website'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql = file_get_contents(INSTALL_PATH . 'fastadmin.sql');
|
||||||
|
|
||||||
|
$sql = str_replace("`fa_", "`{$mysqlPrefix}", $sql);
|
||||||
|
|
||||||
|
// 先尝试能否自动创建数据库
|
||||||
|
$config = Config::get('database');
|
||||||
|
try {
|
||||||
|
$pdo = new PDO("{$config['type']}:host={$mysqlHostname}" . ($mysqlHostport ? ";port={$mysqlHostport}" : ''), $mysqlUsername, $mysqlPassword);
|
||||||
|
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||||
|
$pdo->query("CREATE DATABASE IF NOT EXISTS `{$mysqlDatabase}` CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;");
|
||||||
|
|
||||||
|
// 连接install命令中指定的数据库
|
||||||
|
$instance = Db::connect([
|
||||||
|
'type' => "{$config['type']}",
|
||||||
|
'hostname' => "{$mysqlHostname}",
|
||||||
|
'hostport' => "{$mysqlHostport}",
|
||||||
|
'database' => "{$mysqlDatabase}",
|
||||||
|
'username' => "{$mysqlUsername}",
|
||||||
|
'password' => "{$mysqlPassword}",
|
||||||
|
'prefix' => "{$mysqlPrefix}",
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 查询一次SQL,判断连接是否正常
|
||||||
|
$instance->execute("SELECT 1");
|
||||||
|
|
||||||
|
// 调用原生PDO对象进行批量查询
|
||||||
|
$instance->getPdo()->exec($sql);
|
||||||
|
} catch (\PDOException $e) {
|
||||||
|
throw new Exception($e->getMessage());
|
||||||
|
}
|
||||||
|
// 后台入口文件
|
||||||
|
$adminFile = ROOT_PATH . 'public' . DS . 'admin.php';
|
||||||
|
|
||||||
|
// 数据库配置文件
|
||||||
|
$dbConfigFile = APP_PATH . 'database.php';
|
||||||
|
$dbConfigText = @file_get_contents($dbConfigFile);
|
||||||
|
$callback = function ($matches) use ($mysqlHostname, $mysqlHostport, $mysqlUsername, $mysqlPassword, $mysqlDatabase, $mysqlPrefix) {
|
||||||
|
$field = "mysql" . ucfirst($matches[1]);
|
||||||
|
$replace = $$field;
|
||||||
|
if ($matches[1] == 'hostport' && $mysqlHostport == 3306) {
|
||||||
|
$replace = '';
|
||||||
|
}
|
||||||
|
return "'{$matches[1]}'{$matches[2]}=>{$matches[3]}Env::get('database.{$matches[1]}', '{$replace}'),";
|
||||||
|
};
|
||||||
|
$dbConfigText = preg_replace_callback("/'(hostname|database|username|password|hostport|prefix)'(\s+)=>(\s+)Env::get\((.*)\)\,/", $callback, $dbConfigText);
|
||||||
|
|
||||||
|
// 检测能否成功写入数据库配置
|
||||||
|
$result = @file_put_contents($dbConfigFile, $dbConfigText);
|
||||||
|
if (!$result) {
|
||||||
|
throw new Exception(__('The current permissions are insufficient to write the file %s', 'application/database.php'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置新的Token随机密钥key
|
||||||
|
$oldTokenKey = config('token.key');
|
||||||
|
$newTokenKey = \fast\Random::alnum(32);
|
||||||
|
$coreConfigFile = CONF_PATH . 'config.php';
|
||||||
|
$coreConfigText = @file_get_contents($coreConfigFile);
|
||||||
|
$coreConfigText = preg_replace("/'key'(\s+)=>(\s+)'{$oldTokenKey}'/", "'key'\$1=>\$2'{$newTokenKey}'", $coreConfigText);
|
||||||
|
|
||||||
|
$result = @file_put_contents($coreConfigFile, $coreConfigText);
|
||||||
|
if (!$result) {
|
||||||
|
throw new Exception(__('The current permissions are insufficient to write the file %s', 'application/config.php'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$avatar = request()->domain() . '/assets/img/avatar.png';
|
||||||
|
// 变更默认管理员密码
|
||||||
|
$adminPassword = $adminPassword ? $adminPassword : Random::alnum(8);
|
||||||
|
$adminEmail = $adminEmail ? $adminEmail : "admin@admin.com";
|
||||||
|
$newSalt = substr(md5(uniqid(true)), 0, 6);
|
||||||
|
$newPassword = md5(md5($adminPassword) . $newSalt);
|
||||||
|
$data = ['username' => $adminUsername, 'email' => $adminEmail, 'avatar' => $avatar, 'password' => $newPassword, 'salt' => $newSalt];
|
||||||
|
$instance->name('admin')->where('username', 'admin')->update($data);
|
||||||
|
|
||||||
|
// 变更前台默认用户的密码,随机生成
|
||||||
|
$newSalt = substr(md5(uniqid(true)), 0, 6);
|
||||||
|
$newPassword = md5(md5(Random::alnum(8)) . $newSalt);
|
||||||
|
$instance->name('user')->where('username', 'admin')->update(['avatar' => $avatar, 'password' => $newPassword, 'salt' => $newSalt]);
|
||||||
|
|
||||||
|
// 修改后台入口
|
||||||
|
$adminName = '';
|
||||||
|
if (is_file($adminFile)) {
|
||||||
|
$adminName = Random::alpha(10) . '.php';
|
||||||
|
rename($adminFile, ROOT_PATH . 'public' . DS . $adminName);
|
||||||
|
}
|
||||||
|
|
||||||
|
//修改站点名称
|
||||||
|
if ($siteName != config('site.name')) {
|
||||||
|
$instance->name('config')->where('name', 'name')->update(['value' => $siteName]);
|
||||||
|
$siteConfigFile = CONF_PATH . 'extra' . DS . 'site.php';
|
||||||
|
$siteConfig = include $siteConfigFile;
|
||||||
|
$configList = $instance->name("config")->select();
|
||||||
|
foreach ($configList as $k => $value) {
|
||||||
|
if (in_array($value['type'], ['selects', 'checkbox', 'images', 'files'])) {
|
||||||
|
$value['value'] = is_array($value['value']) ? $value['value'] : explode(',', $value['value']);
|
||||||
|
}
|
||||||
|
if ($value['type'] == 'array') {
|
||||||
|
$value['value'] = (array)json_decode($value['value'], true);
|
||||||
|
}
|
||||||
|
$siteConfig[$value['name']] = $value['value'];
|
||||||
|
}
|
||||||
|
$siteConfig['name'] = $siteName;
|
||||||
|
file_put_contents($siteConfigFile, '<?php' . "\n\nreturn " . var_export_short($siteConfig) . ";\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
$installLockFile = INSTALL_PATH . "install.lock";
|
||||||
|
//检测能否成功写入lock文件
|
||||||
|
$result = @file_put_contents($installLockFile, 1);
|
||||||
|
if (!$result) {
|
||||||
|
throw new Exception(__('The current permissions are insufficient to write the file %s', 'application/admin/command/Install/install.lock'));
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
//删除安装脚本
|
||||||
|
@unlink(ROOT_PATH . 'public' . DS . 'install.php');
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return $adminName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检测环境
|
||||||
|
*/
|
||||||
|
protected function checkenv()
|
||||||
|
{
|
||||||
|
// 检测目录是否存在
|
||||||
|
$checkDirs = [
|
||||||
|
'thinkphp',
|
||||||
|
'vendor',
|
||||||
|
'public' . DS . 'assets' . DS . 'libs'
|
||||||
|
];
|
||||||
|
|
||||||
|
//数据库配置文件
|
||||||
|
$dbConfigFile = APP_PATH . 'database.php';
|
||||||
|
|
||||||
|
if (version_compare(PHP_VERSION, '7.4.0', '<')) {
|
||||||
|
throw new Exception(__("The current version %s is too low, please use PHP 7.4 or higher", PHP_VERSION));
|
||||||
|
}
|
||||||
|
if (!extension_loaded("PDO")) {
|
||||||
|
throw new Exception(__("PDO is not currently installed and cannot be installed"));
|
||||||
|
}
|
||||||
|
if (!is_really_writable($dbConfigFile)) {
|
||||||
|
throw new Exception(__('The current permissions are insufficient to write the configuration file application/database.php'));
|
||||||
|
}
|
||||||
|
foreach ($checkDirs as $k => $v) {
|
||||||
|
if (!is_dir(ROOT_PATH . $v)) {
|
||||||
|
throw new Exception(__('Please go to the official website to download the full package or resource package and try to install'));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,6 @@
|
||||||
/*
|
/*
|
||||||
FastAdmin Install SQL
|
FastAdmin Install SQL
|
||||||
|
Date: 2024-09-03 15:05:25
|
||||||
官网: https://www.fastadmin.net
|
|
||||||
演示: https://demo.fastadmin.net
|
|
||||||
|
|
||||||
Date: 2018年03月07日
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SET FOREIGN_KEY_CHECKS = 0;
|
SET FOREIGN_KEY_CHECKS = 0;
|
||||||
|
|
@ -12,477 +8,508 @@ SET FOREIGN_KEY_CHECKS = 0;
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Table structure for fa_admin
|
-- Table structure for fa_admin
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
DROP TABLE IF EXISTS `fa_admin`;
|
|
||||||
CREATE TABLE `fa_admin` (
|
CREATE TABLE `fa_admin` (
|
||||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
|
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
|
||||||
`username` varchar(20) NOT NULL DEFAULT '' COMMENT '用户名',
|
`username` varchar(20) DEFAULT '' COMMENT '用户名',
|
||||||
`nickname` varchar(50) NOT NULL DEFAULT '' COMMENT '昵称',
|
`nickname` varchar(50) DEFAULT '' COMMENT '昵称',
|
||||||
`password` varchar(32) NOT NULL DEFAULT '' COMMENT '密码',
|
`password` varchar(32) DEFAULT '' COMMENT '密码',
|
||||||
`salt` varchar(30) NOT NULL DEFAULT '' COMMENT '密码盐',
|
`salt` varchar(30) DEFAULT '' COMMENT '密码盐',
|
||||||
`avatar` varchar(100) NOT NULL DEFAULT '' COMMENT '头像',
|
`avatar` varchar(255) DEFAULT '' COMMENT '头像',
|
||||||
`email` varchar(100) NOT NULL DEFAULT '' COMMENT '电子邮箱',
|
`email` varchar(100) DEFAULT '' COMMENT '电子邮箱',
|
||||||
|
`mobile` varchar(11) DEFAULT '' COMMENT '手机号码',
|
||||||
`loginfailure` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '失败次数',
|
`loginfailure` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '失败次数',
|
||||||
`logintime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '登录时间',
|
`logintime` bigint(16) DEFAULT NULL COMMENT '登录时间',
|
||||||
`createtime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间',
|
`loginip` varchar(50) DEFAULT NULL COMMENT '登录IP',
|
||||||
`updatetime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '更新时间',
|
`createtime` bigint(16) DEFAULT NULL COMMENT '创建时间',
|
||||||
`token` varchar(59) NOT NULL DEFAULT '' COMMENT 'Session标识',
|
`updatetime` bigint(16) DEFAULT NULL COMMENT '更新时间',
|
||||||
|
`token` varchar(59) DEFAULT '' COMMENT 'Session标识',
|
||||||
`status` varchar(30) NOT NULL DEFAULT 'normal' COMMENT '状态',
|
`status` varchar(30) NOT NULL DEFAULT 'normal' COMMENT '状态',
|
||||||
PRIMARY KEY (`id`),
|
PRIMARY KEY (`id`),
|
||||||
UNIQUE KEY `username` (`username`) USING BTREE
|
UNIQUE KEY `username` (`username`) USING BTREE
|
||||||
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='管理员表';
|
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci COMMENT='管理员表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of fa_admin
|
-- Records of fa_admin
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
BEGIN;
|
BEGIN;
|
||||||
INSERT INTO `fa_admin` VALUES (1, 'admin', 'Admin', '075eaec83636846f51c152f29b98a2fd', 's4f3', '/assets/img/avatar.png', 'admin@fastadmin.net', 0, 1502029281, 1492186163, 1502029281, 'd3992c3b-5ecc-4ecb-9dc2-8997780fcadc', 'normal');
|
INSERT INTO `fa_admin` VALUES (1, 'admin', 'Admin', '', '', '/assets/img/avatar.png', 'admin@example.com', '', 0, 1491635035, '127.0.0.1',1491635035, 1491635035, '', 'normal');
|
||||||
INSERT INTO `fa_admin` VALUES (2, 'admin2', 'admin2', '9a28ce07ce875fbd14172a9ca5357d3c', '2dHDmj', '/assets/img/avatar.png', 'admin2@fastadmin.net', 0, 1505450906, 1492186163, 1505450906, 'df45fdd5-26f4-45ca-83b3-47e4491a315a', 'normal');
|
|
||||||
INSERT INTO `fa_admin` VALUES (3, 'admin3', 'admin3', '1c11f945dfcd808a130a8c2a8753fe62', 'WOKJEn', '/assets/img/avatar.png', 'admin3@fastadmin.net', 0, 1501980868, 1492186201, 1501982377, '', 'normal');
|
|
||||||
INSERT INTO `fa_admin` VALUES (4, 'admin22', 'admin22', '1c1a0aa0c3c56a8c1a908aab94519648', 'Aybcn5', '/assets/img/avatar.png', 'admin22@fastadmin.net', 0, 0, 1492186240, 1492186240, '', 'normal');
|
|
||||||
INSERT INTO `fa_admin` VALUES (5, 'admin32', 'admin32', 'ade94d5d7a7033afa7d84ac3066d0a02', 'FvYK0u', '/assets/img/avatar.png', 'admin32@fastadmin.net', 0, 0, 1492186263, 1492186263, '', 'normal');
|
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Table structure for fa_admin_log
|
-- Table structure for fa_admin_log
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
DROP TABLE IF EXISTS `fa_admin_log`;
|
|
||||||
CREATE TABLE `fa_admin_log` (
|
CREATE TABLE `fa_admin_log` (
|
||||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
|
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
|
||||||
`admin_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '管理员ID',
|
`admin_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '管理员ID',
|
||||||
`username` varchar(30) NOT NULL DEFAULT '' COMMENT '管理员名字',
|
`username` varchar(30) DEFAULT '' COMMENT '管理员名字',
|
||||||
`url` varchar(1500) NOT NULL DEFAULT '' COMMENT '操作页面',
|
`url` varchar(1500) DEFAULT '' COMMENT '操作页面',
|
||||||
`title` varchar(100) NOT NULL DEFAULT '' COMMENT '日志标题',
|
`title` varchar(100) DEFAULT '' COMMENT '日志标题',
|
||||||
`content` text NOT NULL COMMENT '内容',
|
`content` longtext NOT NULL COMMENT '内容',
|
||||||
`ip` varchar(50) NOT NULL DEFAULT '' COMMENT 'IP',
|
`ip` varchar(50) DEFAULT '' COMMENT 'IP',
|
||||||
`useragent` varchar(255) NOT NULL DEFAULT '' COMMENT 'User-Agent',
|
`useragent` varchar(255) DEFAULT '' COMMENT 'User-Agent',
|
||||||
`createtime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '操作时间',
|
`createtime` bigint(16) DEFAULT NULL COMMENT '操作时间',
|
||||||
PRIMARY KEY (`id`),
|
PRIMARY KEY (`id`),
|
||||||
KEY `name` (`username`)
|
KEY `name` (`username`)
|
||||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='管理员日志表';
|
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci COMMENT='管理员日志表';
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for fa_area
|
||||||
|
-- ----------------------------
|
||||||
|
CREATE TABLE `fa_area` (
|
||||||
|
`id` int(10) NOT NULL AUTO_INCREMENT COMMENT 'ID',
|
||||||
|
`pid` int(10) DEFAULT NULL COMMENT '父id',
|
||||||
|
`shortname` varchar(100) DEFAULT NULL COMMENT '简称',
|
||||||
|
`name` varchar(100) DEFAULT NULL COMMENT '名称',
|
||||||
|
`mergename` varchar(255) DEFAULT NULL COMMENT '全称',
|
||||||
|
`level` tinyint(4) DEFAULT NULL COMMENT '层级:1=省,2=市,3=区/县',
|
||||||
|
`pinyin` varchar(100) DEFAULT NULL COMMENT '拼音',
|
||||||
|
`code` varchar(100) DEFAULT NULL COMMENT '长途区号',
|
||||||
|
`zip` varchar(100) DEFAULT NULL COMMENT '邮编',
|
||||||
|
`first` varchar(50) DEFAULT NULL COMMENT '首字母',
|
||||||
|
`lng` varchar(100) DEFAULT NULL COMMENT '经度',
|
||||||
|
`lat` varchar(100) DEFAULT NULL COMMENT '纬度',
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
KEY `pid` (`pid`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci COMMENT='地区表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Table structure for fa_attachment
|
-- Table structure for fa_attachment
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
DROP TABLE IF EXISTS `fa_attachment`;
|
|
||||||
CREATE TABLE `fa_attachment` (
|
CREATE TABLE `fa_attachment` (
|
||||||
`id` int(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
|
`id` int(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
|
||||||
|
`category` varchar(50) DEFAULT '' COMMENT '类别',
|
||||||
`admin_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '管理员ID',
|
`admin_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '管理员ID',
|
||||||
`user_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '会员ID',
|
`user_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '会员ID',
|
||||||
`url` varchar(255) NOT NULL DEFAULT '' COMMENT '物理路径',
|
`url` varchar(255) DEFAULT '' COMMENT '物理路径',
|
||||||
`imagewidth` varchar(30) NOT NULL DEFAULT '' COMMENT '宽度',
|
`imagewidth` int(10) unsigned DEFAULT 0 COMMENT '宽度',
|
||||||
`imageheight` varchar(30) NOT NULL DEFAULT '' COMMENT '高度',
|
`imageheight` int(10) unsigned DEFAULT 0 COMMENT '高度',
|
||||||
`imagetype` varchar(30) NOT NULL DEFAULT '' COMMENT '图片类型',
|
`imagetype` varchar(30) DEFAULT '' COMMENT '图片类型',
|
||||||
`imageframes` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '图片帧数',
|
`imageframes` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '图片帧数',
|
||||||
|
`filename` varchar(100) DEFAULT '' COMMENT '文件名称',
|
||||||
`filesize` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '文件大小',
|
`filesize` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '文件大小',
|
||||||
`mimetype` varchar(100) NOT NULL DEFAULT '' COMMENT 'mime类型',
|
`mimetype` varchar(100) DEFAULT '' COMMENT 'mime类型',
|
||||||
`extparam` varchar(255) NOT NULL DEFAULT '' COMMENT '透传数据',
|
`extparam` varchar(255) DEFAULT '' COMMENT '透传数据',
|
||||||
`createtime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '创建日期',
|
`createtime` bigint(16) DEFAULT NULL COMMENT '创建日期',
|
||||||
`updatetime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '更新时间',
|
`updatetime` bigint(16) DEFAULT NULL COMMENT '更新时间',
|
||||||
`uploadtime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '上传时间',
|
`uploadtime` bigint(16) DEFAULT NULL COMMENT '上传时间',
|
||||||
`storage` varchar(100) NOT NULL DEFAULT 'local' COMMENT '存储位置',
|
`storage` varchar(100) NOT NULL DEFAULT 'local' COMMENT '存储位置',
|
||||||
`sha1` varchar(40) NOT NULL DEFAULT '' COMMENT '文件 sha1编码',
|
`sha1` varchar(40) DEFAULT '' COMMENT '文件 sha1编码',
|
||||||
PRIMARY KEY (`id`)
|
PRIMARY KEY (`id`)
|
||||||
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='附件表';
|
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci COMMENT='附件表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of fa_attachment
|
-- Records of fa_attachment
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
BEGIN;
|
BEGIN;
|
||||||
INSERT INTO `fa_attachment` VALUES (1, 1, 0, '/assets/img/qrcode.png', '150', '150', 'png', 0, 21859, 'image/png', '', 1499681848, 1499681848, 1499681848, 'local', '17163603d0263e4838b9387ff2cd4877e8b018f6');
|
INSERT INTO `fa_attachment` VALUES (1, '', 1, 0, '/assets/img/qrcode.png', '150', '150', 'png', 0, 'qrcode.png', 21859, 'image/png', '', 1491635035, 1491635035, 1491635035, 'local', '17163603d0263e4838b9387ff2cd4877e8b018f6');
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Table structure for fa_auth_group
|
-- Table structure for fa_auth_group
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
DROP TABLE IF EXISTS `fa_auth_group`;
|
|
||||||
CREATE TABLE `fa_auth_group` (
|
CREATE TABLE `fa_auth_group` (
|
||||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||||
`pid` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '父组别',
|
`pid` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '父组别',
|
||||||
`name` varchar(100) NOT NULL DEFAULT '' COMMENT '组名',
|
`name` varchar(100) DEFAULT '' COMMENT '组名',
|
||||||
`rules` text NOT NULL COMMENT '规则ID',
|
`rules` text NOT NULL COMMENT '规则ID',
|
||||||
`createtime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间',
|
`createtime` bigint(16) DEFAULT NULL COMMENT '创建时间',
|
||||||
`updatetime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '更新时间',
|
`updatetime` bigint(16) DEFAULT NULL COMMENT '更新时间',
|
||||||
`status` varchar(30) NOT NULL DEFAULT '' COMMENT '状态',
|
`status` varchar(30) DEFAULT '' COMMENT '状态',
|
||||||
PRIMARY KEY (`id`)
|
PRIMARY KEY (`id`)
|
||||||
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COMMENT='分组表';
|
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci COMMENT='分组表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of fa_auth_group
|
-- Records of fa_auth_group
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
BEGIN;
|
BEGIN;
|
||||||
INSERT INTO `fa_auth_group` VALUES (1, 0, 'Admin group', '*', 1490883540, 149088354, 'normal');
|
INSERT INTO `fa_auth_group` VALUES (1, 0, 'Admin group', '*', 1491635035, 1491635035, 'normal');
|
||||||
INSERT INTO `fa_auth_group` VALUES (2, 1, 'Second group', '13,14,16,15,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,40,41,42,43,44,45,46,47,48,49,50,55,56,57,58,59,60,61,62,63,64,65,1,9,10,11,7,6,8,2,4,5', 1490883540, 1505465692, 'normal');
|
INSERT INTO `fa_auth_group` VALUES (2, 1, 'Second group', '13,14,16,15,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,40,41,42,43,44,45,46,47,48,49,50,55,56,57,58,59,60,61,62,63,64,65,1,9,10,11,7,6,8,2,4,5', 1491635035, 1491635035, 'normal');
|
||||||
INSERT INTO `fa_auth_group` VALUES (3, 2, 'Third group', '1,4,9,10,11,13,14,15,16,17,40,41,42,43,44,45,46,47,48,49,50,55,56,57,58,59,60,61,62,63,64,65,5', 1490883540, 1502205322, 'normal');
|
INSERT INTO `fa_auth_group` VALUES (3, 2, 'Third group', '1,4,9,10,11,13,14,15,16,17,40,41,42,43,44,45,46,47,48,49,50,55,56,57,58,59,60,61,62,63,64,65,5', 1491635035, 1491635035, 'normal');
|
||||||
INSERT INTO `fa_auth_group` VALUES (4, 1, 'Second group 2', '1,4,13,14,15,16,17,55,56,57,58,59,60,61,62,63,64,65', 1490883540, 1502205350, 'normal');
|
INSERT INTO `fa_auth_group` VALUES (4, 1, 'Second group 2', '1,4,13,14,15,16,17,55,56,57,58,59,60,61,62,63,64,65', 1491635035, 1491635035, 'normal');
|
||||||
INSERT INTO `fa_auth_group` VALUES (5, 2, 'Third group 2', '1,2,6,7,8,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34', 1490883540, 1502205344, 'normal');
|
INSERT INTO `fa_auth_group` VALUES (5, 2, 'Third group 2', '1,2,6,7,8,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34', 1491635035, 1491635035, 'normal');
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Table structure for fa_auth_group_access
|
-- Table structure for fa_auth_group_access
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
DROP TABLE IF EXISTS `fa_auth_group_access`;
|
|
||||||
CREATE TABLE `fa_auth_group_access` (
|
CREATE TABLE `fa_auth_group_access` (
|
||||||
`uid` int(10) unsigned NOT NULL COMMENT '会员ID',
|
`uid` int(10) unsigned NOT NULL COMMENT '会员ID',
|
||||||
`group_id` int(10) unsigned NOT NULL COMMENT '级别ID',
|
`group_id` int(10) unsigned NOT NULL COMMENT '级别ID',
|
||||||
UNIQUE KEY `uid_group_id` (`uid`,`group_id`),
|
UNIQUE KEY `uid_group_id` (`uid`,`group_id`),
|
||||||
KEY `uid` (`uid`),
|
KEY `uid` (`uid`),
|
||||||
KEY `group_id` (`group_id`)
|
KEY `group_id` (`group_id`)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='权限分组表';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci COMMENT='权限分组表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of fa_auth_group_access
|
-- Records of fa_auth_group_access
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
BEGIN;
|
BEGIN;
|
||||||
INSERT INTO `fa_auth_group_access` VALUES (1, 1);
|
INSERT INTO `fa_auth_group_access` VALUES (1, 1);
|
||||||
INSERT INTO `fa_auth_group_access` VALUES (2, 2);
|
|
||||||
INSERT INTO `fa_auth_group_access` VALUES (3, 3);
|
|
||||||
INSERT INTO `fa_auth_group_access` VALUES (4, 5);
|
|
||||||
INSERT INTO `fa_auth_group_access` VALUES (5, 5);
|
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Table structure for fa_auth_rule
|
-- Table structure for fa_auth_rule
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
DROP TABLE IF EXISTS `fa_auth_rule`;
|
|
||||||
CREATE TABLE `fa_auth_rule` (
|
CREATE TABLE `fa_auth_rule` (
|
||||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||||
`type` enum('menu','file') NOT NULL DEFAULT 'file' COMMENT 'menu为菜单,file为权限节点',
|
`type` enum('menu','file') NOT NULL DEFAULT 'file' COMMENT 'menu为菜单,file为权限节点',
|
||||||
`pid` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '父ID',
|
`pid` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '父ID',
|
||||||
`name` varchar(100) NOT NULL DEFAULT '' COMMENT '规则名称',
|
`name` varchar(100) DEFAULT '' COMMENT '规则名称',
|
||||||
`title` varchar(50) NOT NULL DEFAULT '' COMMENT '规则名称',
|
`title` varchar(50) DEFAULT '' COMMENT '规则名称',
|
||||||
`icon` varchar(50) NOT NULL DEFAULT '' COMMENT '图标',
|
`icon` varchar(50) DEFAULT '' COMMENT '图标',
|
||||||
`condition` varchar(255) NOT NULL DEFAULT '' COMMENT '条件',
|
`url` varchar(255) DEFAULT '' COMMENT '规则URL',
|
||||||
`remark` varchar(255) NOT NULL DEFAULT '' COMMENT '备注',
|
`condition` varchar(255) DEFAULT '' COMMENT '条件',
|
||||||
|
`remark` varchar(255) DEFAULT '' COMMENT '备注',
|
||||||
`ismenu` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '是否为菜单',
|
`ismenu` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '是否为菜单',
|
||||||
`createtime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间',
|
`menutype` enum('addtabs','blank','dialog','ajax') DEFAULT NULL COMMENT '菜单类型',
|
||||||
`updatetime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '更新时间',
|
`extend` varchar(255) DEFAULT '' COMMENT '扩展属性',
|
||||||
|
`py` varchar(30) DEFAULT '' COMMENT '拼音首字母',
|
||||||
|
`pinyin` varchar(100) DEFAULT '' COMMENT '拼音',
|
||||||
|
`createtime` bigint(16) DEFAULT NULL COMMENT '创建时间',
|
||||||
|
`updatetime` bigint(16) DEFAULT NULL COMMENT '更新时间',
|
||||||
`weigh` int(10) NOT NULL DEFAULT '0' COMMENT '权重',
|
`weigh` int(10) NOT NULL DEFAULT '0' COMMENT '权重',
|
||||||
`status` varchar(30) NOT NULL DEFAULT '' COMMENT '状态',
|
`status` varchar(30) DEFAULT '' COMMENT '状态',
|
||||||
PRIMARY KEY (`id`),
|
PRIMARY KEY (`id`),
|
||||||
UNIQUE KEY `name` (`name`) USING BTREE,
|
UNIQUE KEY `name` (`name`) USING BTREE,
|
||||||
KEY `pid` (`pid`),
|
KEY `pid` (`pid`),
|
||||||
KEY `weigh` (`weigh`)
|
KEY `weigh` (`weigh`)
|
||||||
) ENGINE=InnoDB AUTO_INCREMENT=66 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='节点表';
|
) ENGINE=InnoDB AUTO_INCREMENT=66 DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci COMMENT='节点表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of fa_auth_rule
|
-- Records of fa_auth_rule
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
BEGIN;
|
BEGIN;
|
||||||
INSERT INTO `fa_auth_rule` VALUES (1, 'file', 0, 'dashboard', 'Dashboard', 'fa fa-dashboard', '', 'Dashboard tips', 1, 1497429920, 1497429920, 143, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (1, 'file', 0, 'dashboard', 'Dashboard', 'fa fa-dashboard', '', '', 'Dashboard tips', 1, NULL, '', 'kzt', 'kongzhitai', 1491635035, 1491635035, 143, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (2, 'file', 0, 'general', 'General', 'fa fa-cogs', '', '', 1, 1497429920, 1497430169, 137, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (2, 'file', 0, 'general', 'General', 'fa fa-cogs', '', '', '', 1, NULL, '', 'cggl', 'changguiguanli', 1491635035, 1491635035, 137, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (3, 'file', 0, 'category', 'Category', 'fa fa-list', '', 'Category tips', 1, 1497429920, 1497429920, 119, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (3, 'file', 0, 'category', 'Category', 'fa fa-leaf', '', '', 'Category tips', 0, NULL, '', 'flgl', 'fenleiguanli', 1491635035, 1491635035, 119, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (4, 'file', 0, 'addon', 'Addon', 'fa fa-rocket', '', 'Addon tips', 1, 1502035509, 1502035509, 0, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (4, 'file', 0, 'addon', 'Addon', 'fa fa-rocket', '', '', 'Addon tips', 1, NULL, '', 'cjgl', 'chajianguanli', 1491635035, 1491635035, 0, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (5, 'file', 0, 'auth', 'Auth', 'fa fa-group', '', '', 1, 1497429920, 1497430092, 99, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (5, 'file', 0, 'auth', 'Auth', 'fa fa-group', '', '', '', 1, NULL, '', 'qxgl', 'quanxianguanli', 1491635035, 1491635035, 99, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (6, 'file', 2, 'general/config', 'Config', 'fa fa-cog', '', 'Config tips', 1, 1497429920, 1497430683, 60, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (6, 'file', 2, 'general/config', 'Config', 'fa fa-cog', '', '', 'Config tips', 1, NULL, '', 'xtpz', 'xitongpeizhi', 1491635035, 1491635035, 60, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (7, 'file', 2, 'general/attachment', 'Attachment', 'fa fa-file-image-o', '', 'Attachment tips', 1, 1497429920, 1497430699, 53, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (7, 'file', 2, 'general/attachment', 'Attachment', 'fa fa-file-image-o', '', '', 'Attachment tips', 1, NULL, '', 'fjgl', 'fujianguanli', 1491635035, 1491635035, 53, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (8, 'file', 2, 'general/profile', 'Profile', 'fa fa-user', '', '', 1, 1497429920, 1497429920, 34, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (8, 'file', 2, 'general/profile', 'Profile', 'fa fa-user', '', '', '', 1, NULL, '', 'grzl', 'gerenziliao', 1491635035, 1491635035, 34, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (9, 'file', 5, 'auth/admin', 'Admin', 'fa fa-user', '', 'Admin tips', 1, 1497429920, 1497430320, 118, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (9, 'file', 5, 'auth/admin', 'Admin', 'fa fa-user', '', '', 'Admin tips', 1, NULL, '', 'glygl', 'guanliyuanguanli', 1491635035, 1491635035, 118, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (10, 'file', 5, 'auth/adminlog', 'Admin log', 'fa fa-list-alt', '', 'Admin log tips', 1, 1497429920, 1497430307, 113, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (10, 'file', 5, 'auth/adminlog', 'Admin log', 'fa fa-list-alt', '', '', 'Admin log tips', 1, NULL, '', 'glyrz', 'guanliyuanrizhi', 1491635035, 1491635035, 113, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (11, 'file', 5, 'auth/group', 'Group', 'fa fa-group', '', 'Group tips', 1, 1497429920, 1497429920, 109, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (11, 'file', 5, 'auth/group', 'Group', 'fa fa-group', '', '', 'Group tips', 1, NULL, '', 'jsz', 'juesezu', 1491635035, 1491635035, 109, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (12, 'file', 5, 'auth/rule', 'Rule', 'fa fa-bars', '', 'Rule tips', 1, 1497429920, 1497430581, 104, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (12, 'file', 5, 'auth/rule', 'Rule', 'fa fa-bars', '', '', 'Rule tips', 1, NULL, '', 'cdgz', 'caidanguize', 1491635035, 1491635035, 104, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (13, 'file', 1, 'dashboard/index', 'View', 'fa fa-circle-o', '', '', 0, 1497429920, 1497429920, 136, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (13, 'file', 1, 'dashboard/index', 'View', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 136, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (14, 'file', 1, 'dashboard/add', 'Add', 'fa fa-circle-o', '', '', 0, 1497429920, 1497429920, 135, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (14, 'file', 1, 'dashboard/add', 'Add', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 135, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (15, 'file', 1, 'dashboard/del', 'Delete', 'fa fa-circle-o', '', '', 0, 1497429920, 1497429920, 133, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (15, 'file', 1, 'dashboard/del', 'Delete', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 133, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (16, 'file', 1, 'dashboard/edit', 'Edit', 'fa fa-circle-o', '', '', 0, 1497429920, 1497429920, 134, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (16, 'file', 1, 'dashboard/edit', 'Edit', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 134, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (17, 'file', 1, 'dashboard/multi', 'Multi', 'fa fa-circle-o', '', '', 0, 1497429920, 1497429920, 132, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (17, 'file', 1, 'dashboard/multi', 'Multi', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 132, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (18, 'file', 6, 'general/config/index', 'View', 'fa fa-circle-o', '', '', 0, 1497429920, 1497429920, 52, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (18, 'file', 6, 'general/config/index', 'View', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 52, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (19, 'file', 6, 'general/config/add', 'Add', 'fa fa-circle-o', '', '', 0, 1497429920, 1497429920, 51, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (19, 'file', 6, 'general/config/add', 'Add', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 51, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (20, 'file', 6, 'general/config/edit', 'Edit', 'fa fa-circle-o', '', '', 0, 1497429920, 1497429920, 50, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (20, 'file', 6, 'general/config/edit', 'Edit', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 50, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (21, 'file', 6, 'general/config/del', 'Delete', 'fa fa-circle-o', '', '', 0, 1497429920, 1497429920, 49, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (21, 'file', 6, 'general/config/del', 'Delete', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 49, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (22, 'file', 6, 'general/config/multi', 'Multi', 'fa fa-circle-o', '', '', 0, 1497429920, 1497429920, 48, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (22, 'file', 6, 'general/config/multi', 'Multi', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 48, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (23, 'file', 7, 'general/attachment/index', 'View', 'fa fa-circle-o', '', 'Attachment tips', 0, 1497429920, 1497429920, 59, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (23, 'file', 7, 'general/attachment/index', 'View', 'fa fa-circle-o', '', '', 'Attachment tips', 0, NULL, '', '', '', 1491635035, 1491635035, 59, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (24, 'file', 7, 'general/attachment/select', 'Select attachment', 'fa fa-circle-o', '', '', 0, 1497429920, 1497429920, 58, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (24, 'file', 7, 'general/attachment/select', 'Select attachment', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 58, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (25, 'file', 7, 'general/attachment/add', 'Add', 'fa fa-circle-o', '', '', 0, 1497429920, 1497429920, 57, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (25, 'file', 7, 'general/attachment/add', 'Add', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 57, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (26, 'file', 7, 'general/attachment/edit', 'Edit', 'fa fa-circle-o', '', '', 0, 1497429920, 1497429920, 56, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (26, 'file', 7, 'general/attachment/edit', 'Edit', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 56, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (27, 'file', 7, 'general/attachment/del', 'Delete', 'fa fa-circle-o', '', '', 0, 1497429920, 1497429920, 55, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (27, 'file', 7, 'general/attachment/del', 'Delete', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 55, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (28, 'file', 7, 'general/attachment/multi', 'Multi', 'fa fa-circle-o', '', '', 0, 1497429920, 1497429920, 54, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (28, 'file', 7, 'general/attachment/multi', 'Multi', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 54, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (29, 'file', 8, 'general/profile/index', 'View', 'fa fa-circle-o', '', '', 0, 1497429920, 1497429920, 33, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (29, 'file', 8, 'general/profile/index', 'View', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 33, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (30, 'file', 8, 'general/profile/update', 'Update profile', 'fa fa-circle-o', '', '', 0, 1497429920, 1497429920, 32, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (30, 'file', 8, 'general/profile/update', 'Update profile', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 32, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (31, 'file', 8, 'general/profile/add', 'Add', 'fa fa-circle-o', '', '', 0, 1497429920, 1497429920, 31, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (31, 'file', 8, 'general/profile/add', 'Add', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 31, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (32, 'file', 8, 'general/profile/edit', 'Edit', 'fa fa-circle-o', '', '', 0, 1497429920, 1497429920, 30, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (32, 'file', 8, 'general/profile/edit', 'Edit', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 30, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (33, 'file', 8, 'general/profile/del', 'Delete', 'fa fa-circle-o', '', '', 0, 1497429920, 1497429920, 29, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (33, 'file', 8, 'general/profile/del', 'Delete', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 29, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (34, 'file', 8, 'general/profile/multi', 'Multi', 'fa fa-circle-o', '', '', 0, 1497429920, 1497429920, 28, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (34, 'file', 8, 'general/profile/multi', 'Multi', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 28, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (35, 'file', 3, 'category/index', 'View', 'fa fa-circle-o', '', 'Category tips', 0, 1497429920, 1497429920, 142, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (35, 'file', 3, 'category/index', 'View', 'fa fa-circle-o', '', '', 'Category tips', 0, NULL, '', '', '', 1491635035, 1491635035, 142, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (36, 'file', 3, 'category/add', 'Add', 'fa fa-circle-o', '', '', 0, 1497429920, 1497429920, 141, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (36, 'file', 3, 'category/add', 'Add', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 141, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (37, 'file', 3, 'category/edit', 'Edit', 'fa fa-circle-o', '', '', 0, 1497429920, 1497429920, 140, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (37, 'file', 3, 'category/edit', 'Edit', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 140, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (38, 'file', 3, 'category/del', 'Delete', 'fa fa-circle-o', '', '', 0, 1497429920, 1497429920, 139, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (38, 'file', 3, 'category/del', 'Delete', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 139, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (39, 'file', 3, 'category/multi', 'Multi', 'fa fa-circle-o', '', '', 0, 1497429920, 1497429920, 138, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (39, 'file', 3, 'category/multi', 'Multi', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 138, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (40, 'file', 9, 'auth/admin/index', 'View', 'fa fa-circle-o', '', 'Admin tips', 0, 1497429920, 1497429920, 117, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (40, 'file', 9, 'auth/admin/index', 'View', 'fa fa-circle-o', '', '', 'Admin tips', 0, NULL, '', '', '', 1491635035, 1491635035, 117, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (41, 'file', 9, 'auth/admin/add', 'Add', 'fa fa-circle-o', '', '', 0, 1497429920, 1497429920, 116, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (41, 'file', 9, 'auth/admin/add', 'Add', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 116, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (42, 'file', 9, 'auth/admin/edit', 'Edit', 'fa fa-circle-o', '', '', 0, 1497429920, 1497429920, 115, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (42, 'file', 9, 'auth/admin/edit', 'Edit', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 115, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (43, 'file', 9, 'auth/admin/del', 'Delete', 'fa fa-circle-o', '', '', 0, 1497429920, 1497429920, 114, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (43, 'file', 9, 'auth/admin/del', 'Delete', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 114, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (44, 'file', 10, 'auth/adminlog/index', 'View', 'fa fa-circle-o', '', 'Admin log tips', 0, 1497429920, 1497429920, 112, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (44, 'file', 10, 'auth/adminlog/index', 'View', 'fa fa-circle-o', '', '', 'Admin log tips', 0, NULL, '', '', '', 1491635035, 1491635035, 112, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (45, 'file', 10, 'auth/adminlog/detail', 'Detail', 'fa fa-circle-o', '', '', 0, 1497429920, 1497429920, 111, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (45, 'file', 10, 'auth/adminlog/detail', 'Detail', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 111, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (46, 'file', 10, 'auth/adminlog/del', 'Delete', 'fa fa-circle-o', '', '', 0, 1497429920, 1497429920, 110, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (46, 'file', 10, 'auth/adminlog/del', 'Delete', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 110, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (47, 'file', 11, 'auth/group/index', 'View', 'fa fa-circle-o', '', 'Group tips', 0, 1497429920, 1497429920, 108, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (47, 'file', 11, 'auth/group/index', 'View', 'fa fa-circle-o', '', '', 'Group tips', 0, NULL, '', '', '', 1491635035, 1491635035, 108, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (48, 'file', 11, 'auth/group/add', 'Add', 'fa fa-circle-o', '', '', 0, 1497429920, 1497429920, 107, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (48, 'file', 11, 'auth/group/add', 'Add', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 107, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (49, 'file', 11, 'auth/group/edit', 'Edit', 'fa fa-circle-o', '', '', 0, 1497429920, 1497429920, 106, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (49, 'file', 11, 'auth/group/edit', 'Edit', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 106, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (50, 'file', 11, 'auth/group/del', 'Delete', 'fa fa-circle-o', '', '', 0, 1497429920, 1497429920, 105, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (50, 'file', 11, 'auth/group/del', 'Delete', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 105, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (51, 'file', 12, 'auth/rule/index', 'View', 'fa fa-circle-o', '', 'Rule tips', 0, 1497429920, 1497429920, 103, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (51, 'file', 12, 'auth/rule/index', 'View', 'fa fa-circle-o', '', '', 'Rule tips', 0, NULL, '', '', '', 1491635035, 1491635035, 103, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (52, 'file', 12, 'auth/rule/add', 'Add', 'fa fa-circle-o', '', '', 0, 1497429920, 1497429920, 102, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (52, 'file', 12, 'auth/rule/add', 'Add', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 102, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (53, 'file', 12, 'auth/rule/edit', 'Edit', 'fa fa-circle-o', '', '', 0, 1497429920, 1497429920, 101, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (53, 'file', 12, 'auth/rule/edit', 'Edit', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 101, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (54, 'file', 12, 'auth/rule/del', 'Delete', 'fa fa-circle-o', '', '', 0, 1497429920, 1497429920, 100, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (54, 'file', 12, 'auth/rule/del', 'Delete', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 100, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (55, 'file', 4, 'addon/index', 'View', 'fa fa-circle-o', '', 'Addon tips', 0, 1502035509, 1502035509, 0, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (55, 'file', 4, 'addon/index', 'View', 'fa fa-circle-o', '', '', 'Addon tips', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (56, 'file', 4, 'addon/add', 'Add', 'fa fa-circle-o', '', '', 0, 1502035509, 1502035509, 0, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (56, 'file', 4, 'addon/add', 'Add', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (57, 'file', 4, 'addon/edit', 'Edit', 'fa fa-circle-o', '', '', 0, 1502035509, 1502035509, 0, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (57, 'file', 4, 'addon/edit', 'Edit', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (58, 'file', 4, 'addon/del', 'Delete', 'fa fa-circle-o', '', '', 0, 1502035509, 1502035509, 0, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (58, 'file', 4, 'addon/del', 'Delete', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (59, 'file', 4, 'addon/local', 'Local install', 'fa fa-circle-o', '', '', 0, 1502035509, 1502035509, 0, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (59, 'file', 4, 'addon/downloaded', 'Local addon', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (60, 'file', 4, 'addon/state', 'Update state', 'fa fa-circle-o', '', '', 0, 1502035509, 1502035509, 0, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (60, 'file', 4, 'addon/state', 'Update state', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (61, 'file', 4, 'addon/install', 'Install', 'fa fa-circle-o', '', '', 0, 1502035509, 1502035509, 0, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (63, 'file', 4, 'addon/config', 'Setting', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (62, 'file', 4, 'addon/uninstall', 'Uninstall', 'fa fa-circle-o', '', '', 0, 1502035509, 1502035509, 0, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (64, 'file', 4, 'addon/refresh', 'Refresh', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (63, 'file', 4, 'addon/config', 'Setting', 'fa fa-circle-o', '', '', 0, 1502035509, 1502035509, 0, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (65, 'file', 4, 'addon/multi', 'Multi', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (64, 'file', 4, 'addon/refresh', 'Refresh', 'fa fa-circle-o', '', '', 0, 1502035509, 1502035509, 0, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (66, 'file', 0, 'user', 'User', 'fa fa-user-circle', '', '', '', 1, NULL, '', 'hygl', 'huiyuanguanli', 1491635035, 1491635035, 0, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (65, 'file', 4, 'addon/multi', 'Multi', 'fa fa-circle-o', '', '', 0, 1502035509, 1502035509, 0, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (67, 'file', 66, 'user/user', 'User', 'fa fa-user', '', '', '', 1, NULL, '', 'hygl', 'huiyuanguanli', 1491635035, 1491635035, 0, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (66, 'file', 0, 'user', 'User', 'fa fa-list', '', '', 1, 1516374729, 1516374729, 0, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (68, 'file', 67, 'user/user/index', 'View', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (67, 'file', 66, 'user/user', 'User', 'fa fa-user', '', '', 1, 1516374729, 1516374729, 0, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (69, 'file', 67, 'user/user/edit', 'Edit', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (68, 'file', 67, 'user/user/index', 'View', 'fa fa-circle-o', '', '', 0, 1516374729, 1516374729, 0, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (70, 'file', 67, 'user/user/add', 'Add', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (69, 'file', 67, 'user/user/edit', 'Edit', 'fa fa-circle-o', '', '', 0, 1516374729, 1516374729, 0, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (71, 'file', 67, 'user/user/del', 'Del', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (70, 'file', 67, 'user/user/add', 'Add', 'fa fa-circle-o', '', '', 0, 1516374729, 1516374729, 0, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (72, 'file', 67, 'user/user/multi', 'Multi', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (71, 'file', 67, 'user/user/del', 'Del', 'fa fa-circle-o', '', '', 0, 1516374729, 1516374729, 0, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (73, 'file', 66, 'user/group', 'User group', 'fa fa-users', '', '', '', 1, NULL, '', 'hyfz', 'huiyuanfenzu', 1491635035, 1491635035, 0, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (72, 'file', 67, 'user/user/multi', 'Multi', 'fa fa-circle-o', '', '', 0, 1516374729, 1516374729, 0, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (74, 'file', 73, 'user/group/add', 'Add', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (73, 'file', 66, 'user/group', 'User group', 'fa fa-users', '', '', 1, 1516374729, 1516374729, 0, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (75, 'file', 73, 'user/group/edit', 'Edit', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (74, 'file', 73, 'user/group/add', 'Add', 'fa fa-circle-o', '', '', 0, 1516374729, 1516374729, 0, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (76, 'file', 73, 'user/group/index', 'View', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (75, 'file', 73, 'user/group/edit', 'Edit', 'fa fa-circle-o', '', '', 0, 1516374729, 1516374729, 0, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (77, 'file', 73, 'user/group/del', 'Del', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (76, 'file', 73, 'user/group/index', 'View', 'fa fa-circle-o', '', '', 0, 1516374729, 1516374729, 0, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (78, 'file', 73, 'user/group/multi', 'Multi', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (77, 'file', 73, 'user/group/del', 'Del', 'fa fa-circle-o', '', '', 0, 1516374729, 1516374729, 0, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (79, 'file', 66, 'user/rule', 'User rule', 'fa fa-circle-o', '', '', '', 1, NULL, '', 'hygz', 'huiyuanguize', 1491635035, 1491635035, 0, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (78, 'file', 73, 'user/group/multi', 'Multi', 'fa fa-circle-o', '', '', 0, 1516374729, 1516374729, 0, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (80, 'file', 79, 'user/rule/index', 'View', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (79, 'file', 66, 'user/rule', 'User rule', 'fa fa-circle-o', '', '', 1, 1516374729, 1516374729, 0, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (81, 'file', 79, 'user/rule/del', 'Del', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (80, 'file', 79, 'user/rule/index', 'View', 'fa fa-circle-o', '', '', 0, 1516374729, 1516374729, 0, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (82, 'file', 79, 'user/rule/add', 'Add', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (81, 'file', 79, 'user/rule/del', 'Del', 'fa fa-circle-o', '', '', 0, 1516374729, 1516374729, 0, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (83, 'file', 79, 'user/rule/edit', 'Edit', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (82, 'file', 79, 'user/rule/add', 'Add', 'fa fa-circle-o', '', '', 0, 1516374729, 1516374729, 0, 'normal');
|
INSERT INTO `fa_auth_rule` VALUES (84, 'file', 79, 'user/rule/multi', 'Multi', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
|
||||||
INSERT INTO `fa_auth_rule` VALUES (83, 'file', 79, 'user/rule/edit', 'Edit', 'fa fa-circle-o', '', '', 0, 1516374729, 1516374729, 0, 'normal');
|
|
||||||
INSERT INTO `fa_auth_rule` VALUES (84, 'file', 79, 'user/rule/multi', 'Multi', 'fa fa-circle-o', '', '', 0, 1516374729, 1516374729, 0, 'normal');
|
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Table structure for fa_category
|
-- Table structure for fa_category
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
DROP TABLE IF EXISTS `fa_category`;
|
|
||||||
CREATE TABLE `fa_category` (
|
CREATE TABLE `fa_category` (
|
||||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||||
`pid` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '父ID',
|
`pid` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '父ID',
|
||||||
`type` varchar(30) NOT NULL DEFAULT '' COMMENT '栏目类型',
|
`type` varchar(30) DEFAULT '' COMMENT '栏目类型',
|
||||||
`name` varchar(30) NOT NULL DEFAULT '',
|
`name` varchar(30) DEFAULT '',
|
||||||
`nickname` varchar(50) NOT NULL DEFAULT '',
|
`nickname` varchar(50) DEFAULT '',
|
||||||
`flag` set('hot','index','recommend') NOT NULL DEFAULT '',
|
`flag` set('hot','index','recommend') DEFAULT '',
|
||||||
`image` varchar(100) NOT NULL DEFAULT '' COMMENT '图片',
|
`image` varchar(100) DEFAULT '' COMMENT '图片',
|
||||||
`keywords` varchar(255) NOT NULL DEFAULT '' COMMENT '关键字',
|
`keywords` varchar(255) DEFAULT '' COMMENT '关键字',
|
||||||
`description` varchar(255) NOT NULL DEFAULT '' COMMENT '描述',
|
`description` varchar(255) DEFAULT '' COMMENT '描述',
|
||||||
`diyname` varchar(30) NOT NULL DEFAULT '' COMMENT '自定义名称',
|
`diyname` varchar(30) DEFAULT '' COMMENT '自定义名称',
|
||||||
`createtime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间',
|
`createtime` bigint(16) DEFAULT NULL COMMENT '创建时间',
|
||||||
`updatetime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '更新时间',
|
`updatetime` bigint(16) DEFAULT NULL COMMENT '更新时间',
|
||||||
`weigh` int(10) NOT NULL DEFAULT '0' COMMENT '权重',
|
`weigh` int(10) NOT NULL DEFAULT '0' COMMENT '权重',
|
||||||
`status` varchar(30) NOT NULL DEFAULT '' COMMENT '状态',
|
`status` varchar(30) DEFAULT '' COMMENT '状态',
|
||||||
PRIMARY KEY (`id`),
|
PRIMARY KEY (`id`),
|
||||||
KEY `weigh` (`weigh`,`id`),
|
KEY `weigh` (`weigh`,`id`),
|
||||||
KEY `pid` (`pid`)
|
KEY `pid` (`pid`)
|
||||||
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='分类表';
|
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci COMMENT='分类表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of fa_category
|
-- Records of fa_category
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
BEGIN;
|
BEGIN;
|
||||||
INSERT INTO `fa_category` VALUES (1, 0, 'page', '官方新闻', 'news', 'recommend', '/assets/img/qrcode.png', '', '', 'news', 1495262190, 1495262190, 1, 'normal');
|
INSERT INTO `fa_category` VALUES (1, 0, 'page', '官方新闻', 'news', 'recommend', '/assets/img/qrcode.png', '', '', 'news', 1491635035, 1491635035, 1, 'normal');
|
||||||
INSERT INTO `fa_category` VALUES (2, 0, 'page', '移动应用', 'mobileapp', 'hot', '/assets/img/qrcode.png', '', '', 'mobileapp', 1495262244, 1495262244, 2, 'normal');
|
INSERT INTO `fa_category` VALUES (2, 0, 'page', '移动应用', 'mobileapp', 'hot', '/assets/img/qrcode.png', '', '', 'mobileapp', 1491635035, 1491635035, 2, 'normal');
|
||||||
INSERT INTO `fa_category` VALUES (3, 2, 'page', '微信公众号', 'wechatpublic', 'index', '/assets/img/qrcode.png', '', '', 'wechatpublic', 1495262288, 1495262288, 3, 'normal');
|
INSERT INTO `fa_category` VALUES (3, 2, 'page', '微信公众号', 'wechatpublic', 'index', '/assets/img/qrcode.png', '', '', 'wechatpublic', 1491635035, 1491635035, 3, 'normal');
|
||||||
INSERT INTO `fa_category` VALUES (4, 2, 'page', 'Android开发', 'android', 'recommend', '/assets/img/qrcode.png', '', '', 'android', 1495262317, 1495262317, 4, 'normal');
|
INSERT INTO `fa_category` VALUES (4, 2, 'page', 'Android开发', 'android', 'recommend', '/assets/img/qrcode.png', '', '', 'android', 1491635035, 1491635035, 4, 'normal');
|
||||||
INSERT INTO `fa_category` VALUES (5, 0, 'page', '软件产品', 'software', 'recommend', '/assets/img/qrcode.png', '', '', 'software', 1495262336, 1499681850, 5, 'normal');
|
INSERT INTO `fa_category` VALUES (5, 0, 'page', '软件产品', 'software', 'recommend', '/assets/img/qrcode.png', '', '', 'software', 1491635035, 1491635035, 5, 'normal');
|
||||||
INSERT INTO `fa_category` VALUES (6, 5, 'page', '网站建站', 'website', 'recommend', '/assets/img/qrcode.png', '', '', 'website', 1495262357, 1495262357, 6, 'normal');
|
INSERT INTO `fa_category` VALUES (6, 5, 'page', '网站建站', 'website', 'recommend', '/assets/img/qrcode.png', '', '', 'website', 1491635035, 1491635035, 6, 'normal');
|
||||||
INSERT INTO `fa_category` VALUES (7, 5, 'page', '企业管理软件', 'company', 'index', '/assets/img/qrcode.png', '', '', 'company', 1495262391, 1495262391, 7, 'normal');
|
INSERT INTO `fa_category` VALUES (7, 5, 'page', '企业管理软件', 'company', 'index', '/assets/img/qrcode.png', '', '', 'company', 1491635035, 1491635035, 7, 'normal');
|
||||||
INSERT INTO `fa_category` VALUES (8, 6, 'page', 'PC端', 'website-pc', 'recommend', '/assets/img/qrcode.png', '', '', 'website-pc', 1495262424, 1495262424, 8, 'normal');
|
INSERT INTO `fa_category` VALUES (8, 6, 'page', 'PC端', 'website-pc', 'recommend', '/assets/img/qrcode.png', '', '', 'website-pc', 1491635035, 1491635035, 8, 'normal');
|
||||||
INSERT INTO `fa_category` VALUES (9, 6, 'page', '移动端', 'website-mobile', 'recommend', '/assets/img/qrcode.png', '', '', 'website-mobile', 1495262456, 1495262456, 9, 'normal');
|
INSERT INTO `fa_category` VALUES (9, 6, 'page', '移动端', 'website-mobile', 'recommend', '/assets/img/qrcode.png', '', '', 'website-mobile', 1491635035, 1491635035, 9, 'normal');
|
||||||
INSERT INTO `fa_category` VALUES (10, 7, 'page', 'CRM系统 ', 'company-crm', 'recommend', '/assets/img/qrcode.png', '', '', 'company-crm', 1495262487, 1495262487, 10, 'normal');
|
INSERT INTO `fa_category` VALUES (10, 7, 'page', 'CRM系统 ', 'company-crm', 'recommend', '/assets/img/qrcode.png', '', '', 'company-crm', 1491635035, 1491635035, 10, 'normal');
|
||||||
INSERT INTO `fa_category` VALUES (11, 7, 'page', 'SASS平台软件', 'company-sass', 'recommend', '/assets/img/qrcode.png', '', '', 'company-sass', 1495262515, 1495262515, 11, 'normal');
|
INSERT INTO `fa_category` VALUES (11, 7, 'page', 'SASS平台软件', 'company-sass', 'recommend', '/assets/img/qrcode.png', '', '', 'company-sass', 1491635035, 1491635035, 11, 'normal');
|
||||||
INSERT INTO `fa_category` VALUES (12, 0, 'test', '测试1', 'test1', 'recommend', '/assets/img/qrcode.png', '', '', 'test1', 1497015727, 1497015727, 12, 'normal');
|
INSERT INTO `fa_category` VALUES (12, 0, 'test', '测试1', 'test1', 'recommend', '/assets/img/qrcode.png', '', '', 'test1', 1491635035, 1491635035, 12, 'normal');
|
||||||
INSERT INTO `fa_category` VALUES (13, 0, 'test', '测试2', 'test2', 'recommend', '/assets/img/qrcode.png', '', '', 'test2', 1497015738, 1497015738, 13, 'normal');
|
INSERT INTO `fa_category` VALUES (13, 0, 'test', '测试2', 'test2', 'recommend', '/assets/img/qrcode.png', '', '', 'test2', 1491635035, 1491635035, 13, 'normal');
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Table structure for fa_config
|
-- Table structure for fa_config
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
DROP TABLE IF EXISTS `fa_config`;
|
|
||||||
CREATE TABLE `fa_config` (
|
CREATE TABLE `fa_config` (
|
||||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||||
`name` varchar(30) NOT NULL DEFAULT '' COMMENT '变量名',
|
`name` varchar(30) DEFAULT '' COMMENT '变量名',
|
||||||
`group` varchar(30) NOT NULL DEFAULT '' COMMENT '分组',
|
`group` varchar(30) DEFAULT '' COMMENT '分组',
|
||||||
`title` varchar(100) NOT NULL DEFAULT '' COMMENT '变量标题',
|
`title` varchar(100) DEFAULT '' COMMENT '变量标题',
|
||||||
`tip` varchar(100) NOT NULL DEFAULT '' COMMENT '变量描述',
|
`tip` varchar(100) DEFAULT '' COMMENT '变量描述',
|
||||||
`type` varchar(30) NOT NULL DEFAULT '' COMMENT '类型:string,text,int,bool,array,datetime,date,file',
|
`type` varchar(30) DEFAULT '' COMMENT '类型:string,text,int,bool,array,datetime,date,file',
|
||||||
`value` text NOT NULL COMMENT '变量值',
|
`visible` varchar(255) DEFAULT '' COMMENT '可见条件',
|
||||||
`content` text NOT NULL COMMENT '变量字典数据',
|
`value` text COMMENT '变量值',
|
||||||
`rule` varchar(100) NOT NULL DEFAULT '' COMMENT '验证规则',
|
`content` text COMMENT '变量字典数据',
|
||||||
`extend` varchar(255) NOT NULL DEFAULT '' COMMENT '扩展属性',
|
`rule` varchar(100) DEFAULT '' COMMENT '验证规则',
|
||||||
|
`extend` varchar(255) DEFAULT '' COMMENT '扩展属性',
|
||||||
|
`setting` varchar(255) DEFAULT '' COMMENT '配置',
|
||||||
PRIMARY KEY (`id`),
|
PRIMARY KEY (`id`),
|
||||||
UNIQUE KEY `name` (`name`)
|
UNIQUE KEY `name` (`name`)
|
||||||
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8 COMMENT='系统配置';
|
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci COMMENT='系统配置';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of fa_config
|
-- Records of fa_config
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
BEGIN;
|
BEGIN;
|
||||||
INSERT INTO `fa_config` VALUES (1, 'name', 'basic', 'Site name', '请填写站点名称', 'string', 'FastAdmin', '', 'required', '');
|
INSERT INTO `fa_config` VALUES (1, 'name', 'basic', 'Site name', '请填写站点名称', 'string', '', '我的网站', '', 'required', '', '');
|
||||||
INSERT INTO `fa_config` VALUES (2, 'beian', 'basic', 'Beian', '粤ICP备15054802号-4', 'string', '', '', '', '');
|
INSERT INTO `fa_config` VALUES (2, 'beian', 'basic', 'Beian', '粤ICP备15000000号-1', 'string', '', '', '', '', '', '');
|
||||||
INSERT INTO `fa_config` VALUES (3, 'cdnurl', 'basic', 'Cdn url', '如果静态资源使用第三方云储存请配置该值', 'string', '', '', '', '');
|
INSERT INTO `fa_config` VALUES (3, 'cdnurl', 'basic', 'Cdn url', '如果全站静态资源使用第三方云储存请配置该值', 'string', '', '', '', '', '', '');
|
||||||
INSERT INTO `fa_config` VALUES (4, 'version', 'basic', 'Version', '如果静态资源有变动请重新配置该值', 'string', '1.0.1', '', 'required', '');
|
INSERT INTO `fa_config` VALUES (4, 'version', 'basic', 'Version', '如果静态资源有变动请重新配置该值', 'string', '', '1.0.1', '', 'required', '', '');
|
||||||
INSERT INTO `fa_config` VALUES (5, 'timezone', 'basic', 'Timezone', '', 'string', 'Asia/Shanghai', '', 'required', '');
|
INSERT INTO `fa_config` VALUES (5, 'timezone', 'basic', 'Timezone', '', 'string', '', 'Asia/Shanghai', '', 'required', '', '');
|
||||||
INSERT INTO `fa_config` VALUES (6, 'forbiddenip', 'basic', 'Forbidden ip', '一行一条记录', 'text', '', '', '', '');
|
INSERT INTO `fa_config` VALUES (6, 'forbiddenip', 'basic', 'Forbidden ip', '一行一条记录', 'text', '', '', '', '', '', '');
|
||||||
INSERT INTO `fa_config` VALUES (7, 'languages', 'basic', 'Languages', '', 'array', '{\"backend\":\"zh-cn\",\"frontend\":\"zh-cn\"}', '', 'required', '');
|
INSERT INTO `fa_config` VALUES (7, 'languages', 'basic', 'Languages', '', 'array', '', '{\"backend\":\"zh-cn\",\"frontend\":\"zh-cn\"}', '', 'required', '', '');
|
||||||
INSERT INTO `fa_config` VALUES (8, 'fixedpage', 'basic', 'Fixed page', '请尽量输入左侧菜单栏存在的链接', 'string', 'dashboard', '', 'required', '');
|
INSERT INTO `fa_config` VALUES (8, 'fixedpage', 'basic', 'Fixed page', '请输入左侧菜单栏存在的链接', 'string', '', 'dashboard', '', 'required', '', '');
|
||||||
INSERT INTO `fa_config` VALUES (9, 'categorytype', 'dictionary', 'Category type', '', 'array', '{\"default\":\"Default\",\"page\":\"Page\",\"article\":\"Article\",\"test\":\"Test\"}', '', '', '');
|
INSERT INTO `fa_config` VALUES (9, 'categorytype', 'dictionary', 'Category type', '', 'array', '', '{\"default\":\"Default\",\"page\":\"Page\",\"article\":\"Article\",\"test\":\"Test\"}', '', '', '', '');
|
||||||
INSERT INTO `fa_config` VALUES (10, 'configgroup', 'dictionary', 'Config group', '', 'array', '{\"basic\":\"Basic\",\"email\":\"Email\",\"dictionary\":\"Dictionary\",\"user\":\"User\",\"example\":\"Example\"}', '', '', '');
|
INSERT INTO `fa_config` VALUES (10, 'configgroup', 'dictionary', 'Config group', '', 'array', '', '{\"basic\":\"Basic\",\"email\":\"Email\",\"dictionary\":\"Dictionary\",\"user\":\"User\",\"example\":\"Example\"}', '', '', '', '');
|
||||||
INSERT INTO `fa_config` VALUES (11, 'mail_type', 'email', 'Mail type', '选择邮件发送方式', 'select', '1', '[\"Please select\",\"SMTP\",\"Mail\"]', '', '');
|
INSERT INTO `fa_config` VALUES (11, 'mail_type', 'email', 'Mail type', '选择邮件发送方式', 'select', '', '1', '[\"请选择\",\"SMTP\"]', '', '', '');
|
||||||
INSERT INTO `fa_config` VALUES (12, 'mail_smtp_host', 'email', 'Mail smtp host', '错误的配置发送邮件会导致服务器超时', 'string', 'smtp.qq.com', '', '', '');
|
INSERT INTO `fa_config` VALUES (12, 'mail_smtp_host', 'email', 'Mail smtp host', '错误的配置发送邮件会导致服务器超时', 'string', '', 'smtp.qq.com', '', '', '', '');
|
||||||
INSERT INTO `fa_config` VALUES (13, 'mail_smtp_port', 'email', 'Mail smtp port', '(不加密默认25,SSL默认465,TLS默认587)', 'string', '465', '', '', '');
|
INSERT INTO `fa_config` VALUES (13, 'mail_smtp_port', 'email', 'Mail smtp port', '(不加密默认25,SSL默认465,TLS默认587)', 'string', '', '465', '', '', '', '');
|
||||||
INSERT INTO `fa_config` VALUES (14, 'mail_smtp_user', 'email', 'Mail smtp user', '(填写完整用户名)', 'string', '10000', '', '', '');
|
INSERT INTO `fa_config` VALUES (14, 'mail_smtp_user', 'email', 'Mail smtp user', '(填写完整用户名)', 'string', '', '', '', '', '', '');
|
||||||
INSERT INTO `fa_config` VALUES (15, 'mail_smtp_pass', 'email', 'Mail smtp password', '(填写您的密码)', 'string', 'password', '', '', '');
|
INSERT INTO `fa_config` VALUES (15, 'mail_smtp_pass', 'email', 'Mail smtp password', '(填写您的密码或授权码)', 'password', '', '', '', '', '', '');
|
||||||
INSERT INTO `fa_config` VALUES (16, 'mail_verify_type', 'email', 'Mail vertify type', '(SMTP验证方式[推荐SSL])', 'select', '2', '[\"None\",\"TLS\",\"SSL\"]', '', '');
|
INSERT INTO `fa_config` VALUES (16, 'mail_verify_type', 'email', 'Mail vertify type', '(SMTP验证方式[推荐SSL])', 'select', '', '2', '[\"无\",\"TLS\",\"SSL\"]', '', '', '');
|
||||||
INSERT INTO `fa_config` VALUES (17, 'mail_from', 'email', 'Mail from', '', 'string', '10000@qq.com', '', '', '');
|
INSERT INTO `fa_config` VALUES (17, 'mail_from', 'email', 'Mail from', '', 'string', '', '', '', '', '', '');
|
||||||
|
INSERT INTO `fa_config` VALUES (18, 'attachmentcategory', 'dictionary', 'Attachment category', '', 'array', '', '{\"category1\":\"Category1\",\"category2\":\"Category2\",\"custom\":\"Custom\"}', '', '', '', '');
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Table structure for fa_ems
|
-- Table structure for fa_ems
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
DROP TABLE IF EXISTS `fa_ems`;
|
|
||||||
CREATE TABLE `fa_ems` (
|
CREATE TABLE `fa_ems` (
|
||||||
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'ID',
|
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'ID',
|
||||||
`event` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '事件',
|
`event` varchar(30) DEFAULT '' COMMENT '事件',
|
||||||
`email` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '邮箱',
|
`email` varchar(100) DEFAULT '' COMMENT '邮箱',
|
||||||
`code` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '验证码',
|
`code` varchar(10) DEFAULT '' COMMENT '验证码',
|
||||||
`times` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '验证次数',
|
`times` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '验证次数',
|
||||||
`ip` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT 'IP',
|
`ip` varchar(30) DEFAULT '' COMMENT 'IP',
|
||||||
`createtime` int(10) UNSIGNED NULL DEFAULT 0 COMMENT '创建时间',
|
`createtime` bigint(16) DEFAULT NULL COMMENT '创建时间',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='邮箱验证码表';
|
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci COMMENT='邮箱验证码表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Table structure for fa_sms
|
-- Table structure for fa_sms
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
DROP TABLE IF EXISTS `fa_sms`;
|
|
||||||
CREATE TABLE `fa_sms` (
|
CREATE TABLE `fa_sms` (
|
||||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
|
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
|
||||||
`event` varchar(30) NOT NULL DEFAULT '' COMMENT '事件',
|
`event` varchar(30) DEFAULT '' COMMENT '事件',
|
||||||
`mobile` varchar(20) NOT NULL DEFAULT '' COMMENT '手机号',
|
`mobile` varchar(20) DEFAULT '' COMMENT '手机号',
|
||||||
`code` varchar(10) NOT NULL DEFAULT '' COMMENT '验证码',
|
`code` varchar(10) DEFAULT '' COMMENT '验证码',
|
||||||
`times` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '验证次数',
|
`times` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '验证次数',
|
||||||
`ip` varchar(30) NOT NULL DEFAULT '' COMMENT 'IP',
|
`ip` varchar(30) DEFAULT '' COMMENT 'IP',
|
||||||
`createtime` int(10) unsigned DEFAULT '0' COMMENT '创建时间',
|
`createtime` bigint(16) unsigned DEFAULT '0' COMMENT '创建时间',
|
||||||
PRIMARY KEY (`id`)
|
PRIMARY KEY (`id`)
|
||||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='短信验证码表';
|
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci COMMENT='短信验证码表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Table structure for fa_test
|
-- Table structure for fa_test
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
DROP TABLE IF EXISTS `fa_test`;
|
|
||||||
CREATE TABLE `fa_test` (
|
CREATE TABLE `fa_test` (
|
||||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
|
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
|
||||||
`admin_id` int(10) NOT NULL DEFAULT '0' COMMENT '管理员ID',
|
`user_id` int(10) DEFAULT '0' COMMENT '会员ID',
|
||||||
`category_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '分类ID(单选)',
|
`admin_id` int(10) DEFAULT '0' COMMENT '管理员ID',
|
||||||
`category_ids` varchar(100) NOT NULL COMMENT '分类ID(多选)',
|
`category_id` int(10) unsigned DEFAULT '0' COMMENT '分类ID(单选)',
|
||||||
`week` enum('monday','tuesday','wednesday') NOT NULL COMMENT '星期(单选):monday=星期一,tuesday=星期二,wednesday=星期三',
|
`category_ids` varchar(100) COMMENT '分类ID(多选)',
|
||||||
`flag` set('hot','index','recommend') NOT NULL DEFAULT '' COMMENT '标志(多选):hot=热门,index=首页,recommend=推荐',
|
`tags` varchar(255) DEFAULT '' COMMENT '标签',
|
||||||
`genderdata` enum('male','female') NOT NULL DEFAULT 'male' COMMENT '性别(单选):male=男,female=女',
|
`week` enum('monday','tuesday','wednesday') COMMENT '星期(单选):monday=星期一,tuesday=星期二,wednesday=星期三',
|
||||||
`hobbydata` set('music','reading','swimming') NOT NULL COMMENT '爱好(多选):music=音乐,reading=读书,swimming=游泳',
|
`flag` set('hot','index','recommend') DEFAULT '' COMMENT '标志(多选):hot=热门,index=首页,recommend=推荐',
|
||||||
`title` varchar(50) NOT NULL DEFAULT '' COMMENT '标题',
|
`genderdata` enum('male','female') DEFAULT 'male' COMMENT '性别(单选):male=男,female=女',
|
||||||
`content` text NOT NULL COMMENT '内容',
|
`hobbydata` set('music','reading','swimming') COMMENT '爱好(多选):music=音乐,reading=读书,swimming=游泳',
|
||||||
`image` varchar(100) NOT NULL DEFAULT '' COMMENT '图片',
|
`title` varchar(100) DEFAULT '' COMMENT '标题',
|
||||||
`images` varchar(1500) NOT NULL DEFAULT '' COMMENT '图片组',
|
`content` text COMMENT '内容',
|
||||||
`attachfile` varchar(100) NOT NULL DEFAULT '' COMMENT '附件',
|
`image` varchar(100) DEFAULT '' COMMENT '图片',
|
||||||
`keywords` varchar(100) NOT NULL DEFAULT '' COMMENT '关键字',
|
`images` varchar(1500) DEFAULT '' COMMENT '图片组',
|
||||||
`description` varchar(255) NOT NULL DEFAULT '' COMMENT '描述',
|
`attachfile` varchar(100) DEFAULT '' COMMENT '附件',
|
||||||
`city` varchar(100) NOT NULL DEFAULT '' COMMENT '省市',
|
`keywords` varchar(255) DEFAULT '' COMMENT '关键字',
|
||||||
`price` float(10,2) unsigned NOT NULL DEFAULT '0.00' COMMENT '价格',
|
`description` varchar(255) DEFAULT '' COMMENT '描述',
|
||||||
`views` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '点击',
|
`city` varchar(100) DEFAULT '' COMMENT '省市',
|
||||||
|
`array` varchar(255) DEFAULT '' COMMENT '数组:value=值',
|
||||||
|
`json` varchar(255) DEFAULT '' COMMENT '配置:key=名称,value=值',
|
||||||
|
`multiplejson` varchar(1500) DEFAULT '' COMMENT '二维数组:title=标题,intro=介绍,author=作者,age=年龄',
|
||||||
|
`price` decimal(10,2) unsigned DEFAULT '0.00' COMMENT '价格',
|
||||||
|
`views` int(10) unsigned DEFAULT '0' COMMENT '点击',
|
||||||
|
`workrange` varchar(100) DEFAULT '' COMMENT '时间区间',
|
||||||
`startdate` date DEFAULT NULL COMMENT '开始日期',
|
`startdate` date DEFAULT NULL COMMENT '开始日期',
|
||||||
`activitytime` datetime DEFAULT NULL COMMENT '活动时间(datetime)',
|
`activitytime` datetime DEFAULT NULL COMMENT '活动时间(datetime)',
|
||||||
`year` year(4) DEFAULT NULL COMMENT '年',
|
`year` year(4) DEFAULT NULL COMMENT '年',
|
||||||
`times` time DEFAULT NULL COMMENT '时间',
|
`times` time DEFAULT NULL COMMENT '时间',
|
||||||
`refreshtime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '刷新时间(int)',
|
`refreshtime` bigint(16) DEFAULT NULL COMMENT '刷新时间',
|
||||||
`createtime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间',
|
`createtime` bigint(16) DEFAULT NULL COMMENT '创建时间',
|
||||||
`updatetime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '更新时间',
|
`updatetime` bigint(16) DEFAULT NULL COMMENT '更新时间',
|
||||||
`weigh` int(10) NOT NULL DEFAULT '0' COMMENT '权重',
|
`deletetime` bigint(16) DEFAULT NULL COMMENT '删除时间',
|
||||||
`switch` tinyint(1) NOT NULL DEFAULT '0' COMMENT '开关',
|
`weigh` int(10) DEFAULT '0' COMMENT '权重',
|
||||||
`status` enum('normal','hidden') NOT NULL DEFAULT 'normal' COMMENT '状态',
|
`switch` tinyint(1) DEFAULT '0' COMMENT '开关',
|
||||||
`state` enum('0','1','2') NOT NULL DEFAULT '1' COMMENT '状态值:0=禁用,1=正常,2=推荐',
|
`status` enum('normal','hidden') DEFAULT 'normal' COMMENT '状态',
|
||||||
|
`state` enum('0','1','2') DEFAULT '1' COMMENT '状态值:0=禁用,1=正常,2=推荐',
|
||||||
PRIMARY KEY (`id`)
|
PRIMARY KEY (`id`)
|
||||||
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='测试表';
|
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci COMMENT='测试表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of fa_test
|
-- Records of fa_test
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
BEGIN;
|
BEGIN;
|
||||||
INSERT INTO `fa_test` VALUES (1, 0, 12, '12,13', 'monday', 'hot,index', 'male', 'music,reading', '我是一篇测试文章', '<p>我是测试内容</p>', '/assets/img/avatar.png', '/assets/img/avatar.png,/assets/img/qrcode.png', '/assets/img/avatar.png', '关键字', '描述', '广西壮族自治区/百色市/平果县', 0.00, 0, '2017-07-10', '2017-07-10 18:24:45', 2017, '18:24:45', 1499682285, 1499682526, 1499682526, 0, 1, 'normal', '1');
|
INSERT INTO `fa_test` VALUES (1, 1, 1, 12, '12,13', '互联网,计算机', 'monday', 'hot,index', 'male', 'music,reading', '我是一篇测试文章', '<p>我是测试内容</p>', '/assets/img/avatar.png', '/assets/img/avatar.png,/assets/img/qrcode.png', '/assets/img/avatar.png', '关键字', '我是一篇测试文章描述,内容过多时将自动隐藏', '广西壮族自治区/百色市/平果县', '[\"a\",\"b\"]', '{\"a\":\"1\",\"b\":\"2\"}', '[{\"title\":\"标题一\",\"intro\":\"介绍一\",\"author\":\"小明\",\"age\":\"21\"}]', 0.00, 0, '2020-10-01 00:00:00 - 2021-10-31 23:59:59', '2017-07-10', '2017-07-10 18:24:45', 2017, '18:24:45', 1491635035, 1491635035, 1491635035, NULL, 0, 1, 'normal', '1');
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Table structure for fa_user
|
-- Table structure for fa_user
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
DROP TABLE IF EXISTS `fa_user`;
|
|
||||||
CREATE TABLE `fa_user` (
|
CREATE TABLE `fa_user` (
|
||||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
|
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
|
||||||
`group_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '组别ID',
|
`group_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '组别ID',
|
||||||
`username` varchar(32) NOT NULL DEFAULT '' COMMENT '用户名',
|
`username` varchar(32) DEFAULT '' COMMENT '用户名',
|
||||||
`nickname` varchar(50) NOT NULL DEFAULT '' COMMENT '昵称',
|
`nickname` varchar(50) DEFAULT '' COMMENT '昵称',
|
||||||
`password` varchar(32) NOT NULL DEFAULT '' COMMENT '密码',
|
`password` varchar(32) DEFAULT '' COMMENT '密码',
|
||||||
`salt` varchar(30) NOT NULL DEFAULT '' COMMENT '密码盐',
|
`salt` varchar(30) DEFAULT '' COMMENT '密码盐',
|
||||||
`email` varchar(100) NOT NULL DEFAULT '' COMMENT '电子邮箱',
|
`email` varchar(100) DEFAULT '' COMMENT '电子邮箱',
|
||||||
`mobile` varchar(11) NOT NULL DEFAULT '' COMMENT '手机号',
|
`mobile` varchar(11) DEFAULT '' COMMENT '手机号',
|
||||||
`avatar` varchar(255) NOT NULL DEFAULT '' COMMENT '头像',
|
`avatar` varchar(255) DEFAULT '' COMMENT '头像',
|
||||||
`level` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '等级',
|
`level` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '等级',
|
||||||
`gender` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '性别',
|
`gender` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '性别',
|
||||||
`birthday` date COMMENT '生日',
|
`birthday` date DEFAULT NULL COMMENT '生日',
|
||||||
`bio` varchar(100) NOT NULL DEFAULT '' COMMENT '格言',
|
`bio` varchar(100) DEFAULT '' COMMENT '格言',
|
||||||
`score` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '积分',
|
`money` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '余额',
|
||||||
|
`score` int(10) NOT NULL DEFAULT '0' COMMENT '积分',
|
||||||
`successions` int(10) unsigned NOT NULL DEFAULT '1' COMMENT '连续登录天数',
|
`successions` int(10) unsigned NOT NULL DEFAULT '1' COMMENT '连续登录天数',
|
||||||
`maxsuccessions` int(10) unsigned NOT NULL DEFAULT '1' COMMENT '最大连续登录天数',
|
`maxsuccessions` int(10) unsigned NOT NULL DEFAULT '1' COMMENT '最大连续登录天数',
|
||||||
`prevtime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '上次登录时间',
|
`prevtime` bigint(16) DEFAULT NULL COMMENT '上次登录时间',
|
||||||
`logintime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '登录时间',
|
`logintime` bigint(16) DEFAULT NULL COMMENT '登录时间',
|
||||||
`loginip` varchar(50) NOT NULL DEFAULT '' COMMENT '登录IP',
|
`loginip` varchar(50) DEFAULT '' COMMENT '登录IP',
|
||||||
`loginfailure` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '失败次数',
|
`loginfailure` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '失败次数',
|
||||||
`joinip` varchar(50) NOT NULL DEFAULT '' COMMENT '加入IP',
|
`loginfailuretime` bigint(16) DEFAULT NULL COMMENT '最后登录失败时间',
|
||||||
`jointime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '加入时间',
|
`joinip` varchar(50) DEFAULT '' COMMENT '加入IP',
|
||||||
`createtime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间',
|
`jointime` bigint(16) DEFAULT NULL COMMENT '加入时间',
|
||||||
`updatetime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '更新时间',
|
`createtime` bigint(16) DEFAULT NULL COMMENT '创建时间',
|
||||||
`token` varchar(50) NOT NULL DEFAULT '' COMMENT 'Token',
|
`updatetime` bigint(16) DEFAULT NULL COMMENT '更新时间',
|
||||||
`status` varchar(30) NOT NULL DEFAULT '' COMMENT '状态',
|
`token` varchar(50) DEFAULT '' COMMENT 'Token',
|
||||||
`verification` varchar(255) NOT NULL DEFAULT '' COMMENT '验证',
|
`status` varchar(30) DEFAULT '' COMMENT '状态',
|
||||||
|
`verification` varchar(255) DEFAULT '' COMMENT '验证',
|
||||||
PRIMARY KEY (`id`),
|
PRIMARY KEY (`id`),
|
||||||
KEY `username` (`username`),
|
KEY `username` (`username`),
|
||||||
KEY `email` (`email`),
|
KEY `email` (`email`),
|
||||||
KEY `mobile` (`mobile`)
|
KEY `mobile` (`mobile`)
|
||||||
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='会员表';
|
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci COMMENT='会员表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of fa_user
|
-- Records of fa_user
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
BEGIN;
|
BEGIN;
|
||||||
INSERT INTO `fa_user` VALUES (1, 1, 'admin', 'admin', 'c13f62012fd6a8fdf06b3452a94430e5', 'rpR6Bv', 'admin@163.com', '13888888888', '/assets/img/avatar.png', 0, 0, '2017-04-15', '', 0, 1, 1, 1516170492, 1516171614, '127.0.0.1', 0, '127.0.0.1', 1491461418, 0, 1516171614, '', 'normal','');
|
INSERT INTO `fa_user` VALUES (1, 1, 'admin', 'admin', '', '', 'admin@163.com', '13000000000', '', 0, 0, '2017-04-08', '', 0, 0, 1, 1, 1491635035, 1491635035, '127.0.0.1', 0, 1491635035,'127.0.0.1', 1491635035, 0, 1491635035, '', 'normal','');
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Table structure for fa_user_group
|
-- Table structure for fa_user_group
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
DROP TABLE IF EXISTS `fa_user_group`;
|
|
||||||
CREATE TABLE `fa_user_group` (
|
CREATE TABLE `fa_user_group` (
|
||||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||||
`name` varchar(50) DEFAULT '' COMMENT '组名',
|
`name` varchar(50) DEFAULT '' COMMENT '组名',
|
||||||
`rules` text COMMENT '权限节点',
|
`rules` text COMMENT '权限节点',
|
||||||
`createtime` int(10) DEFAULT NULL COMMENT '添加时间',
|
`createtime` bigint(16) DEFAULT NULL COMMENT '添加时间',
|
||||||
`updatetime` int(10) DEFAULT NULL COMMENT '更新时间',
|
`updatetime` bigint(16) DEFAULT NULL COMMENT '更新时间',
|
||||||
`status` enum('normal','hidden') DEFAULT NULL COMMENT '状态',
|
`status` enum('normal','hidden') DEFAULT NULL COMMENT '状态',
|
||||||
PRIMARY KEY (`id`)
|
PRIMARY KEY (`id`)
|
||||||
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='会员组表';
|
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci COMMENT='会员组表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of fa_user_group
|
-- Records of fa_user_group
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
BEGIN;
|
BEGIN;
|
||||||
INSERT INTO `fa_user_group` VALUES (1, '默认组', '1,2,3,4,5,6,7,8,9,10,11,12', 1515386468, 1516168298, 'normal');
|
INSERT INTO `fa_user_group` VALUES (1, '默认组', '1,2,3,4,5,6,7,8,9,10,11,12', 1491635035, 1491635035, 'normal');
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for fa_user_money_log
|
||||||
|
-- ----------------------------
|
||||||
|
CREATE TABLE `fa_user_money_log` (
|
||||||
|
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||||
|
`user_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '会员ID',
|
||||||
|
`money` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '变更余额',
|
||||||
|
`before` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '变更前余额',
|
||||||
|
`after` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '变更后余额',
|
||||||
|
`memo` varchar(255) DEFAULT '' COMMENT '备注',
|
||||||
|
`createtime` bigint(16) DEFAULT NULL COMMENT '创建时间',
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci COMMENT='会员余额变动表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Table structure for fa_user_rule
|
-- Table structure for fa_user_rule
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
DROP TABLE IF EXISTS `fa_user_rule`;
|
|
||||||
CREATE TABLE `fa_user_rule` (
|
CREATE TABLE `fa_user_rule` (
|
||||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||||
`pid` int(10) DEFAULT NULL COMMENT '父ID',
|
`pid` int(10) DEFAULT NULL COMMENT '父ID',
|
||||||
|
|
@ -490,82 +517,72 @@ CREATE TABLE `fa_user_rule` (
|
||||||
`title` varchar(50) DEFAULT '' COMMENT '标题',
|
`title` varchar(50) DEFAULT '' COMMENT '标题',
|
||||||
`remark` varchar(100) DEFAULT NULL COMMENT '备注',
|
`remark` varchar(100) DEFAULT NULL COMMENT '备注',
|
||||||
`ismenu` tinyint(1) DEFAULT NULL COMMENT '是否菜单',
|
`ismenu` tinyint(1) DEFAULT NULL COMMENT '是否菜单',
|
||||||
`createtime` int(10) DEFAULT NULL COMMENT '创建时间',
|
`createtime` bigint(16) DEFAULT NULL COMMENT '创建时间',
|
||||||
`updatetime` int(10) DEFAULT NULL COMMENT '更新时间',
|
`updatetime` bigint(16) DEFAULT NULL COMMENT '更新时间',
|
||||||
`weigh` int(10) DEFAULT '0' COMMENT '权重',
|
`weigh` int(10) DEFAULT '0' COMMENT '权重',
|
||||||
`status` enum('normal','hidden') DEFAULT NULL COMMENT '状态',
|
`status` enum('normal','hidden') DEFAULT NULL COMMENT '状态',
|
||||||
PRIMARY KEY (`id`)
|
PRIMARY KEY (`id`)
|
||||||
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8 COMMENT='会员规则表';
|
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci COMMENT='会员规则表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of fa_user_rule
|
-- Records of fa_user_rule
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
BEGIN;
|
BEGIN;
|
||||||
INSERT INTO `fa_user_rule` VALUES (1, 0, 'index', '前台', '', 1, 1516168079, 1516168079, 1, 'normal');
|
INSERT INTO `fa_user_rule` VALUES (1, 0, 'index', 'Frontend', '', 1, 1491635035, 1491635035, 1, 'normal');
|
||||||
INSERT INTO `fa_user_rule` VALUES (2, 0, 'api', 'API接口', '', 1, 1516168062, 1516168062, 2, 'normal');
|
INSERT INTO `fa_user_rule` VALUES (2, 0, 'api', 'API Interface', '', 1, 1491635035, 1491635035, 2, 'normal');
|
||||||
INSERT INTO `fa_user_rule` VALUES (3, 1, 'user', '会员模块', '', 1, 1515386221, 1516168103, 12, 'normal');
|
INSERT INTO `fa_user_rule` VALUES (3, 1, 'user', 'User Module', '', 1, 1491635035, 1491635035, 12, 'normal');
|
||||||
INSERT INTO `fa_user_rule` VALUES (4, 2, 'user', '会员模块', '', 1, 1515386221, 1516168092, 11, 'normal');
|
INSERT INTO `fa_user_rule` VALUES (4, 2, 'user', 'User Module', '', 1, 1491635035, 1491635035, 11, 'normal');
|
||||||
INSERT INTO `fa_user_rule` VALUES (5, 3, 'index/user/login', '登录', '', 0, 1515386247, 1515386247, 5, 'normal');
|
INSERT INTO `fa_user_rule` VALUES (5, 3, 'index/user/login', 'Login', '', 0, 1491635035, 1491635035, 5, 'normal');
|
||||||
INSERT INTO `fa_user_rule` VALUES (6, 3, 'index/user/register', '注册', '', 0, 1515386262, 1516015236, 7, 'normal');
|
INSERT INTO `fa_user_rule` VALUES (6, 3, 'index/user/register', 'Register', '', 0, 1491635035, 1491635035, 7, 'normal');
|
||||||
INSERT INTO `fa_user_rule` VALUES (7, 3, 'index/user/index', '会员中心', '', 0, 1516015012, 1516015012, 9, 'normal');
|
INSERT INTO `fa_user_rule` VALUES (7, 3, 'index/user/index', 'User Center', '', 0, 1491635035, 1491635035, 9, 'normal');
|
||||||
INSERT INTO `fa_user_rule` VALUES (8, 3, 'index/user/profile', '个人资料', '', 0, 1516015012, 1516015012, 4, 'normal');
|
INSERT INTO `fa_user_rule` VALUES (8, 3, 'index/user/profile', 'Profile', '', 0, 1491635035, 1491635035, 4, 'normal');
|
||||||
INSERT INTO `fa_user_rule` VALUES (9, 4, 'api/user/login', '登录', '', 0, 1515386247, 1515386247, 6, 'normal');
|
INSERT INTO `fa_user_rule` VALUES (9, 4, 'api/user/login', 'Login', '', 0, 1491635035, 1491635035, 6, 'normal');
|
||||||
INSERT INTO `fa_user_rule` VALUES (10, 4, 'api/user/register', '注册', '', 0, 1515386262, 1516015236, 8, 'normal');
|
INSERT INTO `fa_user_rule` VALUES (10, 4, 'api/user/register', 'Register', '', 0, 1491635035, 1491635035, 8, 'normal');
|
||||||
INSERT INTO `fa_user_rule` VALUES (11, 4, 'api/user/index', '会员中心', '', 0, 1516015012, 1516015012, 10, 'normal');
|
INSERT INTO `fa_user_rule` VALUES (11, 4, 'api/user/index', 'User Center', '', 0, 1491635035, 1491635035, 10, 'normal');
|
||||||
INSERT INTO `fa_user_rule` VALUES (12, 4, 'api/user/profile', '个人资料', '', 0, 1516015012, 1516015012, 3, 'normal');
|
INSERT INTO `fa_user_rule` VALUES (12, 4, 'api/user/profile', 'Profile', '', 0, 1491635035, 1491635035, 3, 'normal');
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Table structure for fa_user_score_log
|
-- Table structure for fa_user_score_log
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
DROP TABLE IF EXISTS `fa_user_score_log`;
|
|
||||||
CREATE TABLE `fa_user_score_log` (
|
CREATE TABLE `fa_user_score_log` (
|
||||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||||
`user_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '会员ID',
|
`user_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '会员ID',
|
||||||
`score` int(10) NOT NULL DEFAULT '0' COMMENT '变更积分',
|
`score` int(10) NOT NULL DEFAULT '0' COMMENT '变更积分',
|
||||||
`before` int(10) NOT NULL DEFAULT '0' COMMENT '变更前积分',
|
`before` int(10) NOT NULL DEFAULT '0' COMMENT '变更前积分',
|
||||||
`after` int(10) NOT NULL DEFAULT '0' COMMENT '变更后积分',
|
`after` int(10) NOT NULL DEFAULT '0' COMMENT '变更后积分',
|
||||||
`memo` varchar(255) NOT NULL DEFAULT '' COMMENT '备注',
|
`memo` varchar(255) DEFAULT '' COMMENT '备注',
|
||||||
`createtime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间',
|
`createtime` bigint(16) DEFAULT NULL COMMENT '创建时间',
|
||||||
PRIMARY KEY (`id`)
|
PRIMARY KEY (`id`)
|
||||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='会员积分变动表';
|
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci COMMENT='会员积分变动表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Table structure for fa_user_token
|
-- Table structure for fa_user_token
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
DROP TABLE IF EXISTS `fa_user_token`;
|
|
||||||
CREATE TABLE `fa_user_token` (
|
CREATE TABLE `fa_user_token` (
|
||||||
`token` varchar(50) NOT NULL COMMENT 'Token',
|
`token` varchar(50) NOT NULL COMMENT 'Token',
|
||||||
`user_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '会员ID',
|
`user_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '会员ID',
|
||||||
`createtime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间',
|
`createtime` bigint(16) DEFAULT NULL COMMENT '创建时间',
|
||||||
`expiretime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '过期时间',
|
`expiretime` bigint(16) DEFAULT NULL COMMENT '过期时间',
|
||||||
PRIMARY KEY (`token`)
|
PRIMARY KEY (`token`)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='会员Token表';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci COMMENT='会员Token表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Table structure for fa_version
|
-- Table structure for fa_version
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
DROP TABLE IF EXISTS `fa_version`;
|
|
||||||
CREATE TABLE `fa_version` (
|
CREATE TABLE `fa_version` (
|
||||||
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
|
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
|
||||||
`oldversion` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '旧版本号',
|
`oldversion` varchar(30) DEFAULT '' COMMENT '旧版本号',
|
||||||
`newversion` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '新版本号',
|
`newversion` varchar(30) DEFAULT '' COMMENT '新版本号',
|
||||||
`packagesize` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '包大小',
|
`packagesize` varchar(30) DEFAULT '' COMMENT '包大小',
|
||||||
`content` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '升级内容',
|
`content` varchar(500) DEFAULT '' COMMENT '升级内容',
|
||||||
`downloadurl` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '下载地址',
|
`downloadurl` varchar(255) DEFAULT '' COMMENT '下载地址',
|
||||||
`enforce` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT '强制更新',
|
`enforce` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT '强制更新',
|
||||||
`createtime` int(10) NOT NULL DEFAULT 0 COMMENT '创建时间',
|
`createtime` bigint(16) DEFAULT NULL COMMENT '创建时间',
|
||||||
`updatetime` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '更新时间',
|
`updatetime` bigint(16) DEFAULT NULL COMMENT '更新时间',
|
||||||
`weigh` int(10) NOT NULL DEFAULT 0 COMMENT '权重',
|
`weigh` int(10) NOT NULL DEFAULT 0 COMMENT '权重',
|
||||||
`status` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '状态',
|
`status` varchar(30) DEFAULT '' COMMENT '状态',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '版本表' ROW_FORMAT = Compact;
|
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci COMMENT='版本表';
|
||||||
|
|
||||||
-- ----------------------------
|
|
||||||
-- Table structure for fa_version
|
|
||||||
-- ----------------------------
|
|
||||||
BEGIN;
|
|
||||||
INSERT INTO `fa_version` (`id`, `oldversion`, `newversion`, `packagesize`, `content`, `downloadurl`, `enforce`, `createtime`, `updatetime`, `weigh`, `status`) VALUES
|
|
||||||
(1, '1.1.1,2', '1.2.1', '20M', '更新内容', 'https://www.fastadmin.net/download.html', 1, 1520425318, 0, 0, 'normal');
|
|
||||||
COMMIT;
|
|
||||||
SET FOREIGN_KEY_CHECKS = 1;
|
SET FOREIGN_KEY_CHECKS = 1;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,316 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<title>{:__('Installing FastAdmin')}</title>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1">
|
||||||
|
<meta name="renderer" content="webkit">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background: #f1f6fd;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
line-height: 1.5;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
}
|
||||||
|
|
||||||
|
body, input, button {
|
||||||
|
font-family: 'Source Sans Pro', 'Helvetica Neue', Helvetica, 'Microsoft Yahei', Arial, sans-serif;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #7E96B3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 480px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 20px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #4e73df;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: normal;
|
||||||
|
color: #3C5675;
|
||||||
|
margin-bottom: 0;
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
form {
|
||||||
|
margin-top: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group .form-field:first-child input {
|
||||||
|
border-top-left-radius: 4px;
|
||||||
|
border-top-right-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group .form-field:last-child input {
|
||||||
|
border-bottom-left-radius: 4px;
|
||||||
|
border-bottom-right-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-field input {
|
||||||
|
background: #fff;
|
||||||
|
margin: 0 0 2px;
|
||||||
|
border: 2px solid transparent;
|
||||||
|
transition: background 0.2s, border-color 0.2s, color 0.2s;
|
||||||
|
width: 100%;
|
||||||
|
padding: 15px 15px 15px 180px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-field input:focus {
|
||||||
|
border-color: #4e73df;
|
||||||
|
background: #fff;
|
||||||
|
color: #444;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-field label {
|
||||||
|
float: left;
|
||||||
|
width: 160px;
|
||||||
|
text-align: right;
|
||||||
|
margin-right: -160px;
|
||||||
|
position: relative;
|
||||||
|
margin-top: 15px;
|
||||||
|
font-size: 14px;
|
||||||
|
pointer-events: none;
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
button, .btn {
|
||||||
|
background: #3C5675;
|
||||||
|
color: #fff;
|
||||||
|
border: 0;
|
||||||
|
font-weight: bold;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 15px 30px;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
button[disabled] {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-buttons {
|
||||||
|
height: 52px;
|
||||||
|
line-height: 52px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-buttons .btn {
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#error, .error, #success, .success, #warmtips, .warmtips {
|
||||||
|
background: #D83E3E;
|
||||||
|
color: #fff;
|
||||||
|
padding: 15px 20px;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#success {
|
||||||
|
background: #3C5675;
|
||||||
|
}
|
||||||
|
|
||||||
|
#error a, .error a {
|
||||||
|
color: white;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
#warmtips {
|
||||||
|
background: #ffcdcd;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #e74c3c;
|
||||||
|
}
|
||||||
|
|
||||||
|
#warmtips a {
|
||||||
|
background: #ffffff7a;
|
||||||
|
display: block;
|
||||||
|
height: 30px;
|
||||||
|
line-height: 30px;
|
||||||
|
margin-top: 10px;
|
||||||
|
color: #e21a1a;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h1>
|
||||||
|
<svg width="80px" height="96px" viewBox="0 0 768 830" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<g id="logo" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<path d="M64.433651,605.899968 C20.067302,536.265612 0,469.698785 0,389.731348 C0,174.488668 171.922656,0 384,0 C596.077344,0 768,174.488668 768,389.731348 C768,469.698785 747.932698,536.265612 703.566349,605.899968 C614.4,753.480595 441.6,870.4 384,870.4 C326.4,870.4 153.6,753.480595 64.433651,605.899968 L64.433651,605.899968 Z"
|
||||||
|
id="body" fill="#4e73df"></path>
|
||||||
|
<path d="M429.648991,190.816 L430.160991,190.816 L429.648991,190.816 L429.648991,190.816 Z M429.648991,156 L427.088991,156 C419.408991,157.024 411.728991,160.608 404.560991,168.8 L403.024991,170.848 L206.928991,429.92 C198.736991,441.184 197.712991,453.984 204.368991,466.784 C210.512991,478.048 222.288991,485.728 235.600991,485.728 L336.464991,486.24 L304.208991,673.632 C301.648991,689.504 310.352991,705.376 325.200991,712.032 C329.808991,714.08 334.416991,714.592 339.536991,714.592 C349.776991,714.592 358.992991,709.472 366.160991,700.256 L561.744991,419.168 C569.936991,407.904 570.960991,395.104 564.304991,382.304 C557.648991,369.504 547.408991,363.36 533.072991,363.36 L432.208991,363.36 L463.952991,199.008 C464.464991,196.448 464.976991,193.376 464.976991,190.816 C464.976991,171.872 449.104991,156 431.184991,156 L429.648991,156 L429.648991,156 Z"
|
||||||
|
id="flash" fill="#FFFFFF"></path>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
</h1>
|
||||||
|
<h2>{:__('Installing FastAdmin')}</h2>
|
||||||
|
<div>
|
||||||
|
|
||||||
|
<form method="post">
|
||||||
|
{if $errInfo}
|
||||||
|
<div class="error">
|
||||||
|
{$errInfo}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
<div id="error" style="display:none"></div>
|
||||||
|
<div id="success" style="display:none"></div>
|
||||||
|
<div id="warmtips" style="display:none"></div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="form-field">
|
||||||
|
<label>{:__('Mysql Hostname')}</label>
|
||||||
|
<input type="text" name="mysqlHostname" value="127.0.0.1" required="">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-field">
|
||||||
|
<label>{:__('Mysql Database')}</label>
|
||||||
|
<input type="text" name="mysqlDatabase" value="" required="">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-field">
|
||||||
|
<label>{:__('Mysql Username')}</label>
|
||||||
|
<input type="text" name="mysqlUsername" value="root" required="">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-field">
|
||||||
|
<label>{:__('Mysql Password')}</label>
|
||||||
|
<input type="password" name="mysqlPassword">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-field">
|
||||||
|
<label>{:__('Mysql Prefix')}</label>
|
||||||
|
<input type="text" name="mysqlPrefix" value="fa_">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-field">
|
||||||
|
<label>{:__('Mysql Hostport')}</label>
|
||||||
|
<input type="number" name="mysqlHostport" value="3306">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="form-field">
|
||||||
|
<label>{:__('Admin Username')}</label>
|
||||||
|
<input name="adminUsername" value="admin" required=""/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-field">
|
||||||
|
<label>{:__('Admin Email')}</label>
|
||||||
|
<input name="adminEmail" value="admin@admin.com" required="">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-field">
|
||||||
|
<label>{:__('Admin Password')}</label>
|
||||||
|
<input type="password" name="adminPassword" required="">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-field">
|
||||||
|
<label>{:__('Repeat Password')}</label>
|
||||||
|
<input type="password" name="adminPasswordConfirmation" required="">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="form-field">
|
||||||
|
<label>{:__('Website')}</label>
|
||||||
|
<input type="text" name="siteName" value="{:__('My Website')}" required=""/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-buttons">
|
||||||
|
<!--@formatter:off-->
|
||||||
|
<button type="submit" {:$errInfo?'disabled':''}>{:__('Install now')}</button>
|
||||||
|
<!--@formatter:on-->
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<!-- jQuery -->
|
||||||
|
<script src="__ROOT__/assets/libs/jquery/dist/jquery.min.js"></script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(function () {
|
||||||
|
$('form :input:first').select();
|
||||||
|
|
||||||
|
$('form').on('submit', function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
var form = this;
|
||||||
|
var $error = $("#error");
|
||||||
|
var $success = $("#success");
|
||||||
|
var $button = $(this).find('button')
|
||||||
|
.text("{:__('Installing')}")
|
||||||
|
.prop('disabled', true);
|
||||||
|
$.ajax({
|
||||||
|
url: "",
|
||||||
|
type: "POST",
|
||||||
|
dataType: "json",
|
||||||
|
data: $(this).serialize(),
|
||||||
|
success: function (ret) {
|
||||||
|
if (ret.code == 1) {
|
||||||
|
var data = ret.data;
|
||||||
|
$error.hide();
|
||||||
|
$(".form-group", form).remove();
|
||||||
|
$button.remove();
|
||||||
|
$("#success").text(ret.msg).show();
|
||||||
|
|
||||||
|
$buttons = $(".form-buttons", form);
|
||||||
|
$("<a class='btn' href='./'>{:__('Home')}</a>").appendTo($buttons);
|
||||||
|
|
||||||
|
if (typeof data.adminName !== 'undefined') {
|
||||||
|
var url = location.href.replace(/install\.php/, data.adminName);
|
||||||
|
$("#warmtips").html("{:__('Security tips')}" + '<a href="' + url + '">' + url + '</a>').show();
|
||||||
|
$('<a class="btn" href="' + url + '" id="btn-admin" style="background:#4e73df">' + "{:__('Dashboard')}" + '</a>').appendTo($buttons);
|
||||||
|
}
|
||||||
|
localStorage.setItem("fastep", "installed");
|
||||||
|
} else {
|
||||||
|
$error.show().text(ret.msg);
|
||||||
|
$button.prop('disabled', false).text("{:__('Install now')}");
|
||||||
|
$("html,body").animate({
|
||||||
|
scrollTop: 0
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function (xhr) {
|
||||||
|
$error.show().text(xhr.responseText);
|
||||||
|
$button.prop('disabled', false).text("{:__('Install now')}");
|
||||||
|
$("html,body").animate({
|
||||||
|
scrollTop: 0
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
<?php
|
||||||
|
return [
|
||||||
|
'Warning' => '温馨提示',
|
||||||
|
'Installing FastAdmin' => '安装FastAdmin',
|
||||||
|
'Mysql Hostname' => 'MySQL 数据库地址',
|
||||||
|
'Mysql Database' => 'MySQL 数据库名',
|
||||||
|
'Mysql Username' => 'MySQL 用户名',
|
||||||
|
'Mysql Password' => 'MySQL 密码',
|
||||||
|
'Mysql Prefix' => 'MySQL 数据表前缀',
|
||||||
|
'Mysql Hostport' => 'MySQL 端口号',
|
||||||
|
'Admin Username' => '管理员用户名',
|
||||||
|
'Admin Email' => '管理员Email',
|
||||||
|
'Admin Password' => '管理员密码',
|
||||||
|
'Repeat Password' => '重复管理员密码',
|
||||||
|
'Website' => '网站名称',
|
||||||
|
'My Website' => '我的网站',
|
||||||
|
'Install now' => '点击安装',
|
||||||
|
'Installing' => '安装中...',
|
||||||
|
'Home' => '访问首页',
|
||||||
|
'Dashboard' => '进入后台',
|
||||||
|
'Go back' => '返回上一页',
|
||||||
|
'Install Successed' => '安装成功!',
|
||||||
|
'Security tips' => '温馨提示:请将以下后台登录入口添加到你的收藏夹,为了你的站点安全,不要泄漏或发送给他人!如有泄漏请及时修改!',
|
||||||
|
'Please input correct database' => '请输入正确的数据库名',
|
||||||
|
'Please input correct username' => '用户名只能由3-30位数字、字母、下划线组合',
|
||||||
|
'Please input correct password' => '密码长度必须在6-30位之间,不能包含空格',
|
||||||
|
'Password is too weak' => '密码太简单,请重新输入',
|
||||||
|
'The two passwords you entered did not match' => '两次输入的密码不一致',
|
||||||
|
'Please input correct website' => '网站名称输入不正确',
|
||||||
|
'The current version %s is too low, please use PHP 7.4 or higher' => '当前版本%s过低,请使用PHP7.4及以上版本',
|
||||||
|
'PDO is not currently installed and cannot be installed' => '当前未开启PDO,无法进行安装',
|
||||||
|
'The current permissions are insufficient to write the file %s' => '当前权限不足,无法写入文件%s',
|
||||||
|
'Please go to the official website to download the full package or resource package and try to install' => '当前代码仅包含核心代码,请前往官网下载完整包或资源包覆盖后再尝试安装',
|
||||||
|
'The system has been installed. If you need to reinstall, please remove %s first' => '当前已经安装成功,如果需要重新安装,请手动移除%s文件',
|
||||||
|
];
|
||||||
|
|
@ -12,10 +12,10 @@ use think\console\Input;
|
||||||
use think\console\input\Option;
|
use think\console\input\Option;
|
||||||
use think\console\Output;
|
use think\console\Output;
|
||||||
use think\Exception;
|
use think\Exception;
|
||||||
|
use think\Loader;
|
||||||
|
|
||||||
class Menu extends Command
|
class Menu extends Command
|
||||||
{
|
{
|
||||||
|
|
||||||
protected $model = null;
|
protected $model = null;
|
||||||
|
|
||||||
protected function configure()
|
protected function configure()
|
||||||
|
|
@ -25,7 +25,9 @@ class Menu extends Command
|
||||||
->addOption('controller', 'c', Option::VALUE_REQUIRED | Option::VALUE_IS_ARRAY, 'controller name,use \'all-controller\' when build all menu', null)
|
->addOption('controller', 'c', Option::VALUE_REQUIRED | Option::VALUE_IS_ARRAY, 'controller name,use \'all-controller\' when build all menu', null)
|
||||||
->addOption('delete', 'd', Option::VALUE_OPTIONAL, 'delete the specified menu', '')
|
->addOption('delete', 'd', Option::VALUE_OPTIONAL, 'delete the specified menu', '')
|
||||||
->addOption('force', 'f', Option::VALUE_OPTIONAL, 'force delete menu,without tips', null)
|
->addOption('force', 'f', Option::VALUE_OPTIONAL, 'force delete menu,without tips', null)
|
||||||
|
->addOption('equal', 'e', Option::VALUE_OPTIONAL, 'the controller must be equal', null)
|
||||||
->setDescription('Build auth menu from controller');
|
->setDescription('Build auth menu from controller');
|
||||||
|
//要执行的controller必须一样,不适用模糊查询
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function execute(Input $input, Output $output)
|
protected function execute(Input $input, Output $output)
|
||||||
|
|
@ -40,14 +42,34 @@ class Menu extends Command
|
||||||
$force = $input->getOption('force');
|
$force = $input->getOption('force');
|
||||||
//是否为删除模式
|
//是否为删除模式
|
||||||
$delete = $input->getOption('delete');
|
$delete = $input->getOption('delete');
|
||||||
|
//是否控制器完全匹配
|
||||||
|
$equal = $input->getOption('equal');
|
||||||
|
|
||||||
|
|
||||||
if ($delete) {
|
if ($delete) {
|
||||||
if (in_array('all-controller', $controller)) {
|
if (in_array('all-controller', $controller)) {
|
||||||
throw new Exception("could not delete all menu");
|
throw new Exception("could not delete all menu");
|
||||||
}
|
}
|
||||||
$ids = [];
|
$ids = [];
|
||||||
$list = $this->model->where(function ($query) use ($controller) {
|
$list = $this->model->where(function ($query) use ($controller, $equal) {
|
||||||
foreach ($controller as $index => $item) {
|
foreach ($controller as $index => $item) {
|
||||||
$query->whereOr('name', 'like', strtolower($item) . "%");
|
if (stripos($item, '_') !== false) {
|
||||||
|
$item = Loader::parseName($item, 1);
|
||||||
|
}
|
||||||
|
if (stripos($item, '/') !== false) {
|
||||||
|
$controllerArr = explode('/', $item);
|
||||||
|
end($controllerArr);
|
||||||
|
$key = key($controllerArr);
|
||||||
|
$controllerArr[$key] = Loader::parseName($controllerArr[$key]);
|
||||||
|
} else {
|
||||||
|
$controllerArr = [Loader::parseName($item)];
|
||||||
|
}
|
||||||
|
$item = str_replace('_', '\_', implode('/', $controllerArr));
|
||||||
|
if ($equal) {
|
||||||
|
$query->whereOr('name', 'eq', $item);
|
||||||
|
} else {
|
||||||
|
$query->whereOr('name', 'like', strtolower($item) . "%");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})->select();
|
})->select();
|
||||||
foreach ($list as $k => $v) {
|
foreach ($list as $k => $v) {
|
||||||
|
|
@ -59,7 +81,7 @@ class Menu extends Command
|
||||||
}
|
}
|
||||||
if (!$force) {
|
if (!$force) {
|
||||||
$output->info("Are you sure you want to delete all those menu? Type 'yes' to continue: ");
|
$output->info("Are you sure you want to delete all those menu? Type 'yes' to continue: ");
|
||||||
$line = fgets(STDIN);
|
$line = fgets(defined('STDIN') ? STDIN : fopen('php://stdin', 'r'));
|
||||||
if (trim($line) != 'yes') {
|
if (trim($line) != 'yes') {
|
||||||
throw new Exception("Operation is aborted!");
|
throw new Exception("Operation is aborted!");
|
||||||
}
|
}
|
||||||
|
|
@ -73,10 +95,17 @@ class Menu extends Command
|
||||||
|
|
||||||
if (!in_array('all-controller', $controller)) {
|
if (!in_array('all-controller', $controller)) {
|
||||||
foreach ($controller as $index => $item) {
|
foreach ($controller as $index => $item) {
|
||||||
$controllerArr = explode('/', $item);
|
if (stripos($item, '_') !== false) {
|
||||||
end($controllerArr);
|
$item = Loader::parseName($item, 1);
|
||||||
$key = key($controllerArr);
|
}
|
||||||
$controllerArr[$key] = ucfirst($controllerArr[$key]);
|
if (stripos($item, '/') !== false) {
|
||||||
|
$controllerArr = explode('/', $item);
|
||||||
|
end($controllerArr);
|
||||||
|
$key = key($controllerArr);
|
||||||
|
$controllerArr[$key] = ucfirst($controllerArr[$key]);
|
||||||
|
} else {
|
||||||
|
$controllerArr = [ucfirst($item)];
|
||||||
|
}
|
||||||
$adminPath = dirname(__DIR__) . DS . 'controller' . DS . implode(DS, $controllerArr) . '.php';
|
$adminPath = dirname(__DIR__) . DS . 'controller' . DS . implode(DS, $controllerArr) . '.php';
|
||||||
if (!is_file($adminPath)) {
|
if (!is_file($adminPath)) {
|
||||||
$output->error("controller not found");
|
$output->error("controller not found");
|
||||||
|
|
@ -84,8 +113,11 @@ class Menu extends Command
|
||||||
}
|
}
|
||||||
$this->importRule($item);
|
$this->importRule($item);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
$authRuleList = AuthRule::select();
|
||||||
|
//生成权限规则备份文件
|
||||||
|
file_put_contents(RUNTIME_PATH . 'authrule.json', json_encode(collection($authRuleList)->toArray()));
|
||||||
|
|
||||||
$this->model->where('id', '>', 0)->delete();
|
$this->model->where('id', '>', 0)->delete();
|
||||||
$controllerDir = $adminPath . 'controller' . DS;
|
$controllerDir = $adminPath . 'controller' . DS;
|
||||||
// 扫描新的节点信息并导入
|
// 扫描新的节点信息并导入
|
||||||
|
|
@ -146,10 +178,16 @@ class Menu extends Command
|
||||||
|
|
||||||
protected function importRule($controller)
|
protected function importRule($controller)
|
||||||
{
|
{
|
||||||
$controllerArr = explode('/', $controller);
|
$controller = str_replace('\\', '/', $controller);
|
||||||
end($controllerArr);
|
if (stripos($controller, '/') !== false) {
|
||||||
$key = key($controllerArr);
|
$controllerArr = explode('/', $controller);
|
||||||
$controllerArr[$key] = ucfirst($controllerArr[$key]);
|
end($controllerArr);
|
||||||
|
$key = key($controllerArr);
|
||||||
|
$controllerArr[$key] = ucfirst($controllerArr[$key]);
|
||||||
|
} else {
|
||||||
|
$key = 0;
|
||||||
|
$controllerArr = [ucfirst($controller)];
|
||||||
|
}
|
||||||
$classSuffix = Config::get('controller_suffix') ? ucfirst(Config::get('url_controller_layer')) : '';
|
$classSuffix = Config::get('controller_suffix') ? ucfirst(Config::get('url_controller_layer')) : '';
|
||||||
$className = "\\app\\admin\\controller\\" . implode("\\", $controllerArr) . $classSuffix;
|
$className = "\\app\\admin\\controller\\" . implode("\\", $controllerArr) . $classSuffix;
|
||||||
|
|
||||||
|
|
@ -165,21 +203,27 @@ class Menu extends Command
|
||||||
$tempClassFile = __DIR__ . DS . $uniqueName . ".php";
|
$tempClassFile = __DIR__ . DS . $uniqueName . ".php";
|
||||||
file_put_contents($tempClassFile, $classContent);
|
file_put_contents($tempClassFile, $classContent);
|
||||||
$className = "\\app\\admin\\command\\" . $uniqueName;
|
$className = "\\app\\admin\\command\\" . $uniqueName;
|
||||||
|
|
||||||
|
//删除临时文件
|
||||||
|
register_shutdown_function(function () use ($tempClassFile) {
|
||||||
|
if ($tempClassFile) {
|
||||||
|
//删除临时文件
|
||||||
|
@unlink($tempClassFile);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
//反射机制调用类的注释和方法名
|
//反射机制调用类的注释和方法名
|
||||||
$reflector = new ReflectionClass($className);
|
$reflector = new ReflectionClass($className);
|
||||||
|
|
||||||
if (isset($tempClassFile)) {
|
|
||||||
//删除临时文件
|
|
||||||
@unlink($tempClassFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
//只匹配公共的方法
|
//只匹配公共的方法
|
||||||
$methods = $reflector->getMethods(ReflectionMethod::IS_PUBLIC);
|
$methods = $reflector->getMethods(ReflectionMethod::IS_PUBLIC);
|
||||||
$classComment = $reflector->getDocComment();
|
$classComment = $reflector->getDocComment();
|
||||||
//判断是否有启用软删除
|
//判断是否有启用软删除
|
||||||
$softDeleteMethods = ['destroy', 'restore', 'recyclebin'];
|
$softDeleteMethods = ['destroy', 'restore', 'recyclebin'];
|
||||||
$withSofeDelete = false;
|
$withSofeDelete = false;
|
||||||
preg_match_all("/\\\$this\->model\s*=\s*model\('(\w+)'\);/", $classContent, $matches);
|
$modelRegexArr = ["/\\\$this\->model\s*=\s*model\(['|\"](\w+)['|\"]\);/", "/\\\$this\->model\s*=\s*new\s+([a-zA-Z\\\]+);/"];
|
||||||
|
$modelRegex = preg_match($modelRegexArr[0], $classContent) ? $modelRegexArr[0] : $modelRegexArr[1];
|
||||||
|
preg_match_all($modelRegex, $classContent, $matches);
|
||||||
if (isset($matches[1]) && isset($matches[1][0]) && $matches[1][0]) {
|
if (isset($matches[1]) && isset($matches[1][0]) && $matches[1][0]) {
|
||||||
\think\Request::instance()->module('admin');
|
\think\Request::instance()->module('admin');
|
||||||
$model = model($matches[1][0]);
|
$model = model($matches[1][0]);
|
||||||
|
|
@ -188,7 +232,7 @@ class Menu extends Command
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//忽略的类
|
//忽略的类
|
||||||
if (stripos($classComment, "@internal") !== FALSE) {
|
if (stripos($classComment, "@internal") !== false) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
preg_match_all('#(@.*?)\n#s', $classComment, $annotations);
|
preg_match_all('#(@.*?)\n#s', $classComment, $annotations);
|
||||||
|
|
@ -197,10 +241,10 @@ class Menu extends Command
|
||||||
//判断注释中是否设置了icon值
|
//判断注释中是否设置了icon值
|
||||||
if (isset($annotations[1])) {
|
if (isset($annotations[1])) {
|
||||||
foreach ($annotations[1] as $tag) {
|
foreach ($annotations[1] as $tag) {
|
||||||
if (stripos($tag, '@icon') !== FALSE) {
|
if (stripos($tag, '@icon') !== false) {
|
||||||
$controllerIcon = substr($tag, stripos($tag, ' ') + 1);
|
$controllerIcon = substr($tag, stripos($tag, ' ') + 1);
|
||||||
}
|
}
|
||||||
if (stripos($tag, '@remark') !== FALSE) {
|
if (stripos($tag, '@remark') !== false) {
|
||||||
$controllerRemark = substr($tag, stripos($tag, ' ') + 1);
|
$controllerRemark = substr($tag, stripos($tag, ' ') + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -215,7 +259,13 @@ class Menu extends Command
|
||||||
$pid = 0;
|
$pid = 0;
|
||||||
foreach ($controllerArr as $k => $v) {
|
foreach ($controllerArr as $k => $v) {
|
||||||
$key = $k + 1;
|
$key = $k + 1;
|
||||||
$name = strtolower(implode('/', array_slice($controllerArr, 0, $key)));
|
//驼峰转下划线
|
||||||
|
$controllerNameArr = array_slice($controllerArr, 0, $key);
|
||||||
|
foreach ($controllerNameArr as &$val) {
|
||||||
|
$val = strtolower(trim(preg_replace("/[A-Z]/", "_\\0", $val), "_"));
|
||||||
|
}
|
||||||
|
unset($val);
|
||||||
|
$name = implode('/', $controllerNameArr);
|
||||||
$title = (!isset($controllerArr[$key]) ? $controllerTitle : '');
|
$title = (!isset($controllerArr[$key]) ? $controllerTitle : '');
|
||||||
$icon = (!isset($controllerArr[$key]) ? $controllerIcon : 'fa fa-list');
|
$icon = (!isset($controllerArr[$key]) ? $controllerIcon : 'fa fa-list');
|
||||||
$remark = (!isset($controllerArr[$key]) ? $controllerRemark : '');
|
$remark = (!isset($controllerArr[$key]) ? $controllerRemark : '');
|
||||||
|
|
@ -248,7 +298,7 @@ class Menu extends Command
|
||||||
}
|
}
|
||||||
$comment = $reflector->getMethod($n->name)->getDocComment();
|
$comment = $reflector->getMethod($n->name)->getDocComment();
|
||||||
//忽略的方法
|
//忽略的方法
|
||||||
if (stripos($comment, "@internal") !== FALSE) {
|
if (stripos($comment, "@internal") !== false) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
//过滤掉其它字符
|
//过滤掉其它字符
|
||||||
|
|
@ -274,5 +324,4 @@ class Menu extends Command
|
||||||
return $id ? $id : null;
|
return $id ? $id : null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,12 +37,10 @@ class Min extends Command
|
||||||
$resource = $input->getOption('resource') ?: '';
|
$resource = $input->getOption('resource') ?: '';
|
||||||
$optimize = $input->getOption('optimize') ?: 'none';
|
$optimize = $input->getOption('optimize') ?: 'none';
|
||||||
|
|
||||||
if (!$module || !in_array($module, ['frontend', 'backend', 'all']))
|
if (!$module || !in_array($module, ['frontend', 'backend', 'all'])) {
|
||||||
{
|
|
||||||
throw new Exception('Please input correct module name');
|
throw new Exception('Please input correct module name');
|
||||||
}
|
}
|
||||||
if (!$resource || !in_array($resource, ['js', 'css', 'all']))
|
if (!$resource || !in_array($resource, ['js', 'css', 'all'])) {
|
||||||
{
|
|
||||||
throw new Exception('Please input correct resource name');
|
throw new Exception('Please input correct resource name');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -55,34 +53,31 @@ class Min extends Command
|
||||||
|
|
||||||
$nodeExec = '';
|
$nodeExec = '';
|
||||||
|
|
||||||
if (!$nodeExec)
|
if (!$nodeExec) {
|
||||||
{
|
if (IS_WIN) {
|
||||||
if (IS_WIN)
|
|
||||||
{
|
|
||||||
// Winsows下请手动配置配置该值,一般将该值配置为 '"C:\Program Files\nodejs\node.exe"',除非你的Node安装路径有变更
|
// Winsows下请手动配置配置该值,一般将该值配置为 '"C:\Program Files\nodejs\node.exe"',除非你的Node安装路径有变更
|
||||||
$nodeExec = '"C:\Program Files\nodejs\node.exe"';
|
$nodeExec = 'C:\Program Files\nodejs\node.exe';
|
||||||
}
|
if (file_exists($nodeExec)) {
|
||||||
else
|
$nodeExec = '"' . $nodeExec . '"';
|
||||||
{
|
} else {
|
||||||
try
|
// 如果 '"C:\Program Files\nodejs\node.exe"' 不存在,可能是node安装路径有变更
|
||||||
{
|
// 但安装node会自动配置环境变量,直接执行 '"node.exe"' 提高第一次使用压缩打包的成功率
|
||||||
|
$nodeExec = '"node.exe"';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
$nodeExec = exec("which node");
|
$nodeExec = exec("which node");
|
||||||
if (!$nodeExec)
|
if (!$nodeExec) {
|
||||||
{
|
|
||||||
throw new Exception("node environment not found!please install node first!");
|
throw new Exception("node environment not found!please install node first!");
|
||||||
}
|
}
|
||||||
}
|
} catch (Exception $e) {
|
||||||
catch (Exception $e)
|
|
||||||
{
|
|
||||||
throw new Exception($e->getMessage());
|
throw new Exception($e->getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($moduleArr as $mod)
|
foreach ($moduleArr as $mod) {
|
||||||
{
|
foreach ($resourceArr as $res) {
|
||||||
foreach ($resourceArr as $res)
|
|
||||||
{
|
|
||||||
$data = [
|
$data = [
|
||||||
'publicPath' => $publicPath,
|
'publicPath' => $publicPath,
|
||||||
'jsBaseName' => str_replace('{module}', $mod, $this->options['jsBaseName']),
|
'jsBaseName' => str_replace('{module}', $mod, $this->options['jsBaseName']),
|
||||||
|
|
@ -97,21 +92,19 @@ class Min extends Command
|
||||||
|
|
||||||
//源文件
|
//源文件
|
||||||
$from = $data["{$res}BasePath"] . $data["{$res}BaseName"] . '.' . $res;
|
$from = $data["{$res}BasePath"] . $data["{$res}BaseName"] . '.' . $res;
|
||||||
if (!is_file($from))
|
if (!is_file($from)) {
|
||||||
{
|
|
||||||
$output->error("{$res} source file not found!file:{$from}");
|
$output->error("{$res} source file not found!file:{$from}");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ($res == "js")
|
if ($res == "js") {
|
||||||
{
|
|
||||||
$content = file_get_contents($from);
|
$content = file_get_contents($from);
|
||||||
preg_match("/require\.config\(\{[\r\n]?[\n]?+(.*?)[\r\n]?[\n]?}\);/is", $content, $matches);
|
preg_match("/require\.config\(\{[\r\n]?[\n]?+(.*?)[\r\n]?[\n]?}\);/is", $content, $matches);
|
||||||
if (!isset($matches[1]))
|
if (!isset($matches[1])) {
|
||||||
{
|
|
||||||
$output->error("js config not found!");
|
$output->error("js config not found!");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$config = preg_replace("/(urlArgs|baseUrl):(.*)\n/", '', $matches[1]);
|
$config = preg_replace("/(urlArgs|baseUrl):(.*)\n/", '', $matches[1]);
|
||||||
|
$config = preg_replace("/('tableexport'):(.*)\,\n/", "'tableexport': 'empty:',\n", $config);
|
||||||
$data['config'] = $config;
|
$data['config'] = $config;
|
||||||
}
|
}
|
||||||
// 生成压缩文件
|
// 生成压缩文件
|
||||||
|
|
@ -121,16 +114,14 @@ class Min extends Command
|
||||||
|
|
||||||
// 执行压缩
|
// 执行压缩
|
||||||
$command = "{$nodeExec} \"{$minPath}r.js\" -o \"{$tempFile}\" >> \"{$minPath}node.log\"";
|
$command = "{$nodeExec} \"{$minPath}r.js\" -o \"{$tempFile}\" >> \"{$minPath}node.log\"";
|
||||||
if ($output->isDebug())
|
if ($output->isDebug()) {
|
||||||
{
|
|
||||||
$output->warning($command);
|
$output->warning($command);
|
||||||
}
|
}
|
||||||
echo exec($command);
|
echo exec($command);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$output->isDebug())
|
if (!$output->isDebug()) {
|
||||||
{
|
|
||||||
@unlink($tempFile);
|
@unlink($tempFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -147,16 +138,14 @@ class Min extends Command
|
||||||
protected function writeToFile($name, $data, $pathname)
|
protected function writeToFile($name, $data, $pathname)
|
||||||
{
|
{
|
||||||
$search = $replace = [];
|
$search = $replace = [];
|
||||||
foreach ($data as $k => $v)
|
foreach ($data as $k => $v) {
|
||||||
{
|
|
||||||
$search[] = "{%{$k}%}";
|
$search[] = "{%{$k}%}";
|
||||||
$replace[] = $v;
|
$replace[] = $v;
|
||||||
}
|
}
|
||||||
$stub = file_get_contents($this->getStub($name));
|
$stub = file_get_contents($this->getStub($name));
|
||||||
$content = str_replace($search, $replace, $stub);
|
$content = str_replace($search, $replace, $stub);
|
||||||
|
|
||||||
if (!is_dir(dirname($pathname)))
|
if (!is_dir(dirname($pathname))) {
|
||||||
{
|
|
||||||
mkdir(strtolower(dirname($pathname)), 0755, true);
|
mkdir(strtolower(dirname($pathname)), 0755, true);
|
||||||
}
|
}
|
||||||
return file_put_contents($pathname, $content);
|
return file_put_contents($pathname, $content);
|
||||||
|
|
@ -171,5 +160,4 @@ class Min extends Command
|
||||||
{
|
{
|
||||||
return __DIR__ . DS . 'Min' . DS . 'stubs' . DS . $name . '.stub';
|
return __DIR__ . DS . 'Min' . DS . 'stubs' . DS . $name . '.stub';
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,21 +4,22 @@ use app\common\model\Category;
|
||||||
use fast\Form;
|
use fast\Form;
|
||||||
use fast\Tree;
|
use fast\Tree;
|
||||||
use think\Db;
|
use think\Db;
|
||||||
|
use think\Loader;
|
||||||
|
|
||||||
if (!function_exists('build_select')) {
|
if (!function_exists('build_select')) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成下拉列表
|
* 生成下拉列表
|
||||||
* @param string $name
|
* @param string $name
|
||||||
* @param mixed $options
|
* @param mixed $options
|
||||||
* @param mixed $selected
|
* @param mixed $selected
|
||||||
* @param mixed $attr
|
* @param mixed $attr
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
function build_select($name, $options, $selected = [], $attr = [])
|
function build_select($name, $options, $selected = [], $attr = [])
|
||||||
{
|
{
|
||||||
$options = is_array($options) ? $options : explode(',', $options);
|
$options = is_array($options) ? $options : explode(',', $options ?? '');
|
||||||
$selected = is_array($selected) ? $selected : explode(',', $selected);
|
$selected = is_array($selected) ? $selected : explode(',', $selected ?? '');
|
||||||
return Form::select($name, $options, $selected, $attr);
|
return Form::select($name, $options, $selected, $attr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -28,8 +29,8 @@ if (!function_exists('build_radios')) {
|
||||||
/**
|
/**
|
||||||
* 生成单选按钮组
|
* 生成单选按钮组
|
||||||
* @param string $name
|
* @param string $name
|
||||||
* @param array $list
|
* @param array $list
|
||||||
* @param mixed $selected
|
* @param mixed $selected
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
function build_radios($name, $list = [], $selected = null)
|
function build_radios($name, $list = [], $selected = null)
|
||||||
|
|
@ -38,7 +39,7 @@ if (!function_exists('build_radios')) {
|
||||||
$selected = is_null($selected) ? key($list) : $selected;
|
$selected = is_null($selected) ? key($list) : $selected;
|
||||||
$selected = is_array($selected) ? $selected : explode(',', $selected);
|
$selected = is_array($selected) ? $selected : explode(',', $selected);
|
||||||
foreach ($list as $k => $v) {
|
foreach ($list as $k => $v) {
|
||||||
$html[] = sprintf(Form::label("{$name}-{$k}", "%s {$v}"), Form::radio($name, $k, in_array($k, $selected), ['id' => "{$name}-{$k}"]));
|
$html[] = sprintf(Form::label("{$name}-{$k}", "%s " . str_replace('%', '%%', $v)), Form::radio($name, $k, in_array($k, $selected), ['id' => "{$name}-{$k}"]));
|
||||||
}
|
}
|
||||||
return '<div class="radio">' . implode(' ', $html) . '</div>';
|
return '<div class="radio">' . implode(' ', $html) . '</div>';
|
||||||
}
|
}
|
||||||
|
|
@ -49,8 +50,8 @@ if (!function_exists('build_checkboxs')) {
|
||||||
/**
|
/**
|
||||||
* 生成复选按钮组
|
* 生成复选按钮组
|
||||||
* @param string $name
|
* @param string $name
|
||||||
* @param array $list
|
* @param array $list
|
||||||
* @param mixed $selected
|
* @param mixed $selected
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
function build_checkboxs($name, $list = [], $selected = null)
|
function build_checkboxs($name, $list = [], $selected = null)
|
||||||
|
|
@ -59,7 +60,7 @@ if (!function_exists('build_checkboxs')) {
|
||||||
$selected = is_null($selected) ? [] : $selected;
|
$selected = is_null($selected) ? [] : $selected;
|
||||||
$selected = is_array($selected) ? $selected : explode(',', $selected);
|
$selected = is_array($selected) ? $selected : explode(',', $selected);
|
||||||
foreach ($list as $k => $v) {
|
foreach ($list as $k => $v) {
|
||||||
$html[] = sprintf(Form::label("{$name}-{$k}", "%s {$v}"), Form::checkbox($name, $k, in_array($k, $selected), ['id' => "{$name}-{$k}"]));
|
$html[] = sprintf(Form::label("{$name}-{$k}", "%s " . str_replace('%', '%%', $v)), Form::checkbox($name, $k, in_array($k, $selected), ['id' => "{$name}-{$k}"]));
|
||||||
}
|
}
|
||||||
return '<div class="checkbox">' . implode(' ', $html) . '</div>';
|
return '<div class="checkbox">' . implode(' ', $html) . '</div>';
|
||||||
}
|
}
|
||||||
|
|
@ -72,8 +73,9 @@ if (!function_exists('build_category_select')) {
|
||||||
* 生成分类下拉列表框
|
* 生成分类下拉列表框
|
||||||
* @param string $name
|
* @param string $name
|
||||||
* @param string $type
|
* @param string $type
|
||||||
* @param mixed $selected
|
* @param mixed $selected
|
||||||
* @param array $attr
|
* @param array $attr
|
||||||
|
* @param array $header
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
function build_category_select($name, $type, $selected = null, $attr = [], $header = [])
|
function build_category_select($name, $type, $selected = null, $attr = [], $header = [])
|
||||||
|
|
@ -98,14 +100,14 @@ if (!function_exists('build_toolbar')) {
|
||||||
* @param array $attr 按钮属性值
|
* @param array $attr 按钮属性值
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
function build_toolbar($btns = NULL, $attr = [])
|
function build_toolbar($btns = null, $attr = [])
|
||||||
{
|
{
|
||||||
$auth = \app\admin\library\Auth::instance();
|
$auth = \app\admin\library\Auth::instance();
|
||||||
$controller = str_replace('.', '/', strtolower(think\Request::instance()->controller()));
|
$controller = str_replace('.', '/', Loader::parseName(request()->controller()));
|
||||||
$btns = $btns ? $btns : ['refresh', 'add', 'edit', 'del', 'import'];
|
$btns = $btns ? $btns : ['refresh', 'add', 'edit', 'del', 'import'];
|
||||||
$btns = is_array($btns) ? $btns : explode(',', $btns);
|
$btns = is_array($btns) ? $btns : explode(',', $btns);
|
||||||
$index = array_search('delete', $btns);
|
$index = array_search('delete', $btns);
|
||||||
if ($index !== FALSE) {
|
if ($index !== false) {
|
||||||
$btns[$index] = 'del';
|
$btns[$index] = 'del';
|
||||||
}
|
}
|
||||||
$btnAttr = [
|
$btnAttr = [
|
||||||
|
|
@ -113,18 +115,49 @@ if (!function_exists('build_toolbar')) {
|
||||||
'add' => ['javascript:;', 'btn btn-success btn-add', 'fa fa-plus', __('Add'), __('Add')],
|
'add' => ['javascript:;', 'btn btn-success btn-add', 'fa fa-plus', __('Add'), __('Add')],
|
||||||
'edit' => ['javascript:;', 'btn btn-success btn-edit btn-disabled disabled', 'fa fa-pencil', __('Edit'), __('Edit')],
|
'edit' => ['javascript:;', 'btn btn-success btn-edit btn-disabled disabled', 'fa fa-pencil', __('Edit'), __('Edit')],
|
||||||
'del' => ['javascript:;', 'btn btn-danger btn-del btn-disabled disabled', 'fa fa-trash', __('Delete'), __('Delete')],
|
'del' => ['javascript:;', 'btn btn-danger btn-del btn-disabled disabled', 'fa fa-trash', __('Delete'), __('Delete')],
|
||||||
'import' => ['javascript:;', 'btn btn-danger btn-import', 'fa fa-upload', __('Import'), __('Import')],
|
'import' => ['javascript:;', 'btn btn-info btn-import', 'fa fa-upload', __('Import'), __('Import')],
|
||||||
];
|
];
|
||||||
$btnAttr = array_merge($btnAttr, $attr);
|
$btnAttr = array_merge($btnAttr, $attr);
|
||||||
$html = [];
|
$html = [];
|
||||||
foreach ($btns as $k => $v) {
|
foreach ($btns as $k => $v) {
|
||||||
//如果未定义或没有权限
|
//如果未定义或没有权限
|
||||||
if (!isset($btnAttr[$v]) || ($v !== 'refresh' && !$auth->check("{$controller}/{$v}"))) {
|
if (!isset($btnAttr[$v]) || ($v !== 'refresh' && !$auth->check("{$controller}/{$v}", $auth->id))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
list($href, $class, $icon, $text, $title) = $btnAttr[$v];
|
list($href, $class, $icon, $text, $title) = $btnAttr[$v];
|
||||||
$extend = $v == 'import' ? 'id="btn-import-file" data-url="ajax/upload" data-mimetype="csv,xls,xlsx" data-multiple="false"' : '';
|
//$extend = $v == 'import' ? 'id="btn-import-file" data-url="ajax/upload" data-mimetype="csv,xls,xlsx" data-multiple="false"' : '';
|
||||||
$html[] = '<a href="' . $href . '" class="' . $class . '" title="' . $title . '" ' . $extend . '><i class="' . $icon . '"></i> ' . $text . '</a>';
|
//$html[] = '<a href="' . $href . '" class="' . $class . '" title="' . $title . '" ' . $extend . '><i class="' . $icon . '"></i> ' . $text . '</a>';
|
||||||
|
if ($v == 'import') {
|
||||||
|
$template = str_replace('/', '_', $controller);
|
||||||
|
$download = '';
|
||||||
|
if (file_exists("./template/{$template}.xlsx")) {
|
||||||
|
$download .= "<li><a href=\"/template/{$template}.xlsx\" target=\"_blank\">XLSX模版</a></li>";
|
||||||
|
}
|
||||||
|
if (file_exists("./template/{$template}.xls")) {
|
||||||
|
$download .= "<li><a href=\"/template/{$template}.xls\" target=\"_blank\">XLS模版</a></li>";
|
||||||
|
}
|
||||||
|
if (file_exists("./template/{$template}.csv")) {
|
||||||
|
$download .= empty($download) ? '' : "<li class=\"divider\"></li>";
|
||||||
|
$download .= "<li><a href=\"/template/{$template}.csv\" target=\"_blank\">CSV模版</a></li>";
|
||||||
|
}
|
||||||
|
$download .= empty($download) ? '' : "\n ";
|
||||||
|
if (!empty($download)) {
|
||||||
|
$html[] = <<<EOT
|
||||||
|
<div class="btn-group">
|
||||||
|
<button type="button" href="{$href}" class="btn btn-info btn-import" title="{$title}" id="btn-import-file" data-url="ajax/upload" data-mimetype="csv,xls,xlsx" data-multiple="false"><i class="{$icon}"></i> {$text}</button>
|
||||||
|
<button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown" title="下载批量导入模版">
|
||||||
|
<span class="caret"></span>
|
||||||
|
<span class="sr-only">Toggle Dropdown</span>
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-menu" role="menu">{$download}</ul>
|
||||||
|
</div>
|
||||||
|
EOT;
|
||||||
|
} else {
|
||||||
|
$html[] = '<a href="' . $href . '" class="' . $class . '" title="' . $title . '" id="btn-import-file" data-url="ajax/upload" data-mimetype="csv,xls,xlsx" data-multiple="false"><i class="' . $icon . '"></i> ' . $text . '</a>';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$html[] = '<a href="' . $href . '" class="' . $class . '" title="' . $title . '"><i class="' . $icon . '"></i> ' . $text . '</a>';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return implode(' ', $html);
|
return implode(' ', $html);
|
||||||
}
|
}
|
||||||
|
|
@ -138,12 +171,12 @@ if (!function_exists('build_heading')) {
|
||||||
* @param string $path 指定的path
|
* @param string $path 指定的path
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
function build_heading($path = NULL, $container = TRUE)
|
function build_heading($path = null, $container = true)
|
||||||
{
|
{
|
||||||
$title = $content = '';
|
$title = $content = '';
|
||||||
if (is_null($path)) {
|
if (is_null($path)) {
|
||||||
$action = request()->action();
|
$action = request()->action();
|
||||||
$controller = str_replace('.', '/', request()->controller());
|
$controller = str_replace('.', '/', Loader::parseName(request()->controller()));
|
||||||
$path = strtolower($controller . ($action && $action != 'index' ? '/' . $action : ''));
|
$path = strtolower($controller . ($action && $action != 'index' ? '/' . $action : ''));
|
||||||
}
|
}
|
||||||
// 根据当前的URI自动匹配父节点的标题和备注
|
// 根据当前的URI自动匹配父节点的标题和备注
|
||||||
|
|
@ -152,8 +185,9 @@ if (!function_exists('build_heading')) {
|
||||||
$title = __($data['title']);
|
$title = __($data['title']);
|
||||||
$content = __($data['remark']);
|
$content = __($data['remark']);
|
||||||
}
|
}
|
||||||
if (!$content)
|
if (!$content) {
|
||||||
return '';
|
return '';
|
||||||
|
}
|
||||||
$result = '<div class="panel-lead"><em>' . $title . '</em>' . $content . '</div>';
|
$result = '<div class="panel-lead"><em>' . $title . '</em>' . $content . '</div>';
|
||||||
if ($container) {
|
if ($container) {
|
||||||
$result = '<div class="panel-heading">' . $result . '</div>';
|
$result = '<div class="panel-heading">' . $result . '</div>';
|
||||||
|
|
|
||||||
|
|
@ -8,26 +8,30 @@ use think\addons\AddonException;
|
||||||
use think\addons\Service;
|
use think\addons\Service;
|
||||||
use think\Cache;
|
use think\Cache;
|
||||||
use think\Config;
|
use think\Config;
|
||||||
|
use think\Db;
|
||||||
use think\Exception;
|
use think\Exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 插件管理
|
* 插件管理
|
||||||
*
|
*
|
||||||
* @icon fa fa-circle-o
|
* @icon fa fa-cube
|
||||||
* @remark 可在线安装、卸载、禁用、启用插件,同时支持添加本地插件。FastAdmin已上线插件商店 ,你可以发布你的免费或付费插件:<a href="https://www.fastadmin.net/store.html" target="_blank">https://www.fastadmin.net/store.html</a>
|
* @remark 可在线安装、卸载、禁用、启用、配置、升级插件,插件升级前请做好备份。
|
||||||
*/
|
*/
|
||||||
class Addon extends Backend
|
class Addon extends Backend
|
||||||
{
|
{
|
||||||
|
|
||||||
protected $model = null;
|
protected $model = null;
|
||||||
|
protected $noNeedRight = ['get_table_list'];
|
||||||
|
|
||||||
public function _initialize()
|
public function _initialize()
|
||||||
{
|
{
|
||||||
parent::_initialize();
|
parent::_initialize();
|
||||||
|
if (!$this->auth->isSuperAdmin() && in_array($this->request->action(), ['install', 'uninstall', 'local', 'upgrade', 'authorization', 'testdata'])) {
|
||||||
|
$this->error(__('Access is allowed only to the super management group'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查看
|
* 插件列表
|
||||||
*/
|
*/
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
|
|
@ -35,29 +39,31 @@ class Addon extends Backend
|
||||||
foreach ($addons as $k => &$v) {
|
foreach ($addons as $k => &$v) {
|
||||||
$config = get_addon_config($v['name']);
|
$config = get_addon_config($v['name']);
|
||||||
$v['config'] = $config ? 1 : 0;
|
$v['config'] = $config ? 1 : 0;
|
||||||
|
$v['url'] = str_replace($this->request->server('SCRIPT_NAME'), '', $v['url']);
|
||||||
}
|
}
|
||||||
$this->assignconfig(['addons' => $addons]);
|
$this->assignconfig(['addons' => $addons, 'api_url' => config('fastadmin.api_url'), 'faversion' => config('fastadmin.version'), 'domain' => request()->host(true)]);
|
||||||
return $this->view->fetch();
|
return $this->view->fetch();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 配置
|
* 配置
|
||||||
*/
|
*/
|
||||||
public function config($ids = NULL)
|
public function config($name = null)
|
||||||
{
|
{
|
||||||
$name = $this->request->get("name");
|
$name = $name ? $name : $this->request->get("name");
|
||||||
if (!$name) {
|
if (!$name) {
|
||||||
$this->error(__('Parameter %s can not be empty', $ids ? 'id' : 'name'));
|
$this->error(__('Parameter %s can not be empty', 'name'));
|
||||||
}
|
}
|
||||||
if (!is_dir(ADDON_PATH . $name)) {
|
if (!preg_match("/^[a-zA-Z0-9]+$/", $name)) {
|
||||||
$this->error(__('Directory not found'));
|
$this->error(__('Addon name incorrect'));
|
||||||
}
|
}
|
||||||
$info = get_addon_info($name);
|
$info = get_addon_info($name);
|
||||||
$config = get_addon_fullconfig($name);
|
$config = get_addon_fullconfig($name);
|
||||||
if (!$info)
|
if (!$info) {
|
||||||
$this->error(__('No Results were found'));
|
$this->error(__('Addon not exists'));
|
||||||
|
}
|
||||||
if ($this->request->isPost()) {
|
if ($this->request->isPost()) {
|
||||||
$params = $this->request->post("row/a");
|
$params = $this->request->post("row/a", [], 'trim');
|
||||||
if ($params) {
|
if ($params) {
|
||||||
foreach ($config as $k => &$v) {
|
foreach ($config as $k => &$v) {
|
||||||
if (isset($params[$v['name']])) {
|
if (isset($params[$v['name']])) {
|
||||||
|
|
@ -71,18 +77,47 @@ class Addon extends Backend
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
//更新配置文件
|
$addon = get_addon_instance($name);
|
||||||
set_addon_fullconfig($name, $config);
|
//插件自定义配置实现逻辑
|
||||||
Service::refresh();
|
if (method_exists($addon, 'config')) {
|
||||||
$this->success();
|
$addon->config($name, $config);
|
||||||
|
} else {
|
||||||
|
//更新配置文件
|
||||||
|
set_addon_fullconfig($name, $config);
|
||||||
|
Service::refresh();
|
||||||
|
}
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
$this->error(__($e->getMessage()));
|
$this->error(__($e->getMessage()));
|
||||||
}
|
}
|
||||||
|
$this->success();
|
||||||
}
|
}
|
||||||
$this->error(__('Parameter %s can not be empty', ''));
|
$this->error(__('Parameter %s can not be empty', ''));
|
||||||
}
|
}
|
||||||
$this->view->assign("addon", ['info' => $info, 'config' => $config]);
|
$tips = [];
|
||||||
return $this->view->fetch();
|
$groupList = [];
|
||||||
|
$ungroupList = [];
|
||||||
|
foreach ($config as $index => &$item) {
|
||||||
|
//如果有设置分组
|
||||||
|
if (isset($item['group']) && $item['group']) {
|
||||||
|
if (!in_array($item['group'], $groupList)) {
|
||||||
|
$groupList["custom" . (count($groupList) + 1)] = $item['group'];
|
||||||
|
}
|
||||||
|
} elseif ($item['name'] != '__tips__') {
|
||||||
|
$ungroupList[] = $item['name'];
|
||||||
|
}
|
||||||
|
if ($item['name'] == '__tips__') {
|
||||||
|
$tips = $item;
|
||||||
|
unset($config[$index]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($ungroupList) {
|
||||||
|
$groupList['other'] = '其它';
|
||||||
|
}
|
||||||
|
$this->view->assign("groupList", $groupList);
|
||||||
|
$this->view->assign("addon", ['info' => $info, 'config' => $config, 'tips' => $tips]);
|
||||||
|
$configFile = ADDON_PATH . $name . DS . 'config.html';
|
||||||
|
$viewFile = is_file($configFile) ? $configFile : '';
|
||||||
|
return $this->view->fetch($viewFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -95,6 +130,11 @@ class Addon extends Backend
|
||||||
if (!$name) {
|
if (!$name) {
|
||||||
$this->error(__('Parameter %s can not be empty', 'name'));
|
$this->error(__('Parameter %s can not be empty', 'name'));
|
||||||
}
|
}
|
||||||
|
if (!preg_match("/^[a-zA-Z0-9]+$/", $name)) {
|
||||||
|
$this->error(__('Addon name incorrect'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$info = [];
|
||||||
try {
|
try {
|
||||||
$uid = $this->request->post("uid");
|
$uid = $this->request->post("uid");
|
||||||
$token = $this->request->post("token");
|
$token = $this->request->post("token");
|
||||||
|
|
@ -106,16 +146,13 @@ class Addon extends Backend
|
||||||
'version' => $version,
|
'version' => $version,
|
||||||
'faversion' => $faversion
|
'faversion' => $faversion
|
||||||
];
|
];
|
||||||
Service::install($name, $force, $extend);
|
$info = Service::install($name, $force, $extend);
|
||||||
$info = get_addon_info($name);
|
|
||||||
$info['config'] = get_addon_config($name) ? 1 : 0;
|
|
||||||
$info['state'] = 1;
|
|
||||||
$this->success(__('Install successful'), null, ['addon' => $info]);
|
|
||||||
} catch (AddonException $e) {
|
} catch (AddonException $e) {
|
||||||
$this->result($e->getData(), $e->getCode(), __($e->getMessage()));
|
$this->result($e->getData(), $e->getCode(), __($e->getMessage()));
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
$this->error(__($e->getMessage()), $e->getCode());
|
$this->error(__($e->getMessage()), $e->getCode());
|
||||||
}
|
}
|
||||||
|
$this->success(__('Install successful'), '', ['addon' => $info]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -125,17 +162,37 @@ class Addon extends Backend
|
||||||
{
|
{
|
||||||
$name = $this->request->post("name");
|
$name = $this->request->post("name");
|
||||||
$force = (int)$this->request->post("force");
|
$force = (int)$this->request->post("force");
|
||||||
|
$droptables = (int)$this->request->post("droptables");
|
||||||
if (!$name) {
|
if (!$name) {
|
||||||
$this->error(__('Parameter %s can not be empty', 'name'));
|
$this->error(__('Parameter %s can not be empty', 'name'));
|
||||||
}
|
}
|
||||||
|
if (!preg_match("/^[a-zA-Z0-9]+$/", $name)) {
|
||||||
|
$this->error(__('Addon name incorrect'));
|
||||||
|
}
|
||||||
|
//只有开启调试且为超级管理员才允许删除相关数据库
|
||||||
|
$tables = [];
|
||||||
|
if ($droptables && Config::get("app_debug") && $this->auth->isSuperAdmin()) {
|
||||||
|
$tables = get_addon_tables($name);
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
Service::uninstall($name, $force);
|
Service::uninstall($name, $force);
|
||||||
$this->success(__('Uninstall successful'));
|
if ($tables) {
|
||||||
|
$prefix = Config::get('database.prefix');
|
||||||
|
//删除插件关联表
|
||||||
|
foreach ($tables as $index => $table) {
|
||||||
|
//忽略非插件标识的表名
|
||||||
|
if (!preg_match("/^{$prefix}{$name}/", $table)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Db::execute("DROP TABLE IF EXISTS `{$table}`");
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (AddonException $e) {
|
} catch (AddonException $e) {
|
||||||
$this->result($e->getData(), $e->getCode(), __($e->getMessage()));
|
$this->result($e->getData(), $e->getCode(), __($e->getMessage()));
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
$this->error(__($e->getMessage()));
|
$this->error(__($e->getMessage()));
|
||||||
}
|
}
|
||||||
|
$this->success(__('Uninstall successful'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -149,17 +206,20 @@ class Addon extends Backend
|
||||||
if (!$name) {
|
if (!$name) {
|
||||||
$this->error(__('Parameter %s can not be empty', 'name'));
|
$this->error(__('Parameter %s can not be empty', 'name'));
|
||||||
}
|
}
|
||||||
|
if (!preg_match("/^[a-zA-Z0-9]+$/", $name)) {
|
||||||
|
$this->error(__('Addon name incorrect'));
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
$action = $action == 'enable' ? $action : 'disable';
|
$action = $action == 'enable' ? $action : 'disable';
|
||||||
//调用启用、禁用的方法
|
//调用启用、禁用的方法
|
||||||
Service::$action($name, $force);
|
Service::$action($name, $force);
|
||||||
Cache::rm('__menu__');
|
Cache::rm('__menu__');
|
||||||
$this->success(__('Operate successful'));
|
|
||||||
} catch (AddonException $e) {
|
} catch (AddonException $e) {
|
||||||
$this->result($e->getData(), $e->getCode(), __($e->getMessage()));
|
$this->result($e->getData(), $e->getCode(), __($e->getMessage()));
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
$this->error(__($e->getMessage()));
|
$this->error(__($e->getMessage()));
|
||||||
}
|
}
|
||||||
|
$this->success(__('Operate successful'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -169,70 +229,28 @@ class Addon extends Backend
|
||||||
{
|
{
|
||||||
Config::set('default_return_type', 'json');
|
Config::set('default_return_type', 'json');
|
||||||
|
|
||||||
|
$info = [];
|
||||||
$file = $this->request->file('file');
|
$file = $this->request->file('file');
|
||||||
$addonTmpDir = RUNTIME_PATH . 'addons' . DS;
|
try {
|
||||||
if (!is_dir($addonTmpDir)) {
|
$uid = $this->request->post("uid");
|
||||||
@mkdir($addonTmpDir, 0755, true);
|
$token = $this->request->post("token");
|
||||||
}
|
$faversion = $this->request->post("faversion");
|
||||||
$info = $file->rule('uniqid')->validate(['size' => 10240000, 'ext' => 'zip'])->move($addonTmpDir);
|
$force = $this->request->post("force");
|
||||||
if ($info) {
|
if (!$uid || !$token) {
|
||||||
$tmpName = substr($info->getFilename(), 0, stripos($info->getFilename(), '.'));
|
throw new Exception(__('Please login and try to install'));
|
||||||
$tmpAddonDir = ADDON_PATH . $tmpName . DS;
|
|
||||||
$tmpFile = $addonTmpDir . $info->getSaveName();
|
|
||||||
try {
|
|
||||||
Service::unzip($tmpName);
|
|
||||||
@unlink($tmpFile);
|
|
||||||
$infoFile = $tmpAddonDir . 'info.ini';
|
|
||||||
if (!is_file($infoFile)) {
|
|
||||||
throw new Exception(__('Addon info file was not found'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$config = Config::parse($infoFile, '', $tmpName);
|
|
||||||
$name = isset($config['name']) ? $config['name'] : '';
|
|
||||||
if (!$name) {
|
|
||||||
throw new Exception(__('Addon info file data incorrect'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$newAddonDir = ADDON_PATH . $name . DS;
|
|
||||||
if (is_dir($newAddonDir)) {
|
|
||||||
throw new Exception(__('Addon already exists'));
|
|
||||||
}
|
|
||||||
|
|
||||||
//重命名插件文件夹
|
|
||||||
rename($tmpAddonDir, $newAddonDir);
|
|
||||||
try {
|
|
||||||
//默认禁用该插件
|
|
||||||
$info = get_addon_info($name);
|
|
||||||
if ($info['state']) {
|
|
||||||
$info['state'] = 0;
|
|
||||||
set_addon_info($name, $info);
|
|
||||||
}
|
|
||||||
|
|
||||||
//执行插件的安装方法
|
|
||||||
$class = get_addon_class($name);
|
|
||||||
if (class_exists($class)) {
|
|
||||||
$addon = new $class();
|
|
||||||
$addon->install();
|
|
||||||
}
|
|
||||||
|
|
||||||
//导入SQL
|
|
||||||
Service::importsql($name);
|
|
||||||
|
|
||||||
$info['config'] = get_addon_config($name) ? 1 : 0;
|
|
||||||
$this->success(__('Offline installed tips'), null, ['addon' => $info]);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
@rmdirs($newAddonDir);
|
|
||||||
throw new Exception(__($e->getMessage()));
|
|
||||||
}
|
|
||||||
} catch (Exception $e) {
|
|
||||||
@unlink($tmpFile);
|
|
||||||
@rmdirs($tmpAddonDir);
|
|
||||||
$this->error(__($e->getMessage()));
|
|
||||||
}
|
}
|
||||||
} else {
|
$extend = [
|
||||||
// 上传失败获取错误信息
|
'uid' => $uid,
|
||||||
$this->error(__($file->getError()));
|
'token' => $token,
|
||||||
|
'faversion' => $faversion
|
||||||
|
];
|
||||||
|
$info = Service::local($file, $extend, $force);
|
||||||
|
} catch (AddonException $e) {
|
||||||
|
$this->result($e->getData(), $e->getCode(), __($e->getMessage()));
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$this->error(__($e->getMessage()));
|
||||||
}
|
}
|
||||||
|
$this->success(__('Offline installed tips'), '', ['addon' => $info]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -241,29 +259,63 @@ class Addon extends Backend
|
||||||
public function upgrade()
|
public function upgrade()
|
||||||
{
|
{
|
||||||
$name = $this->request->post("name");
|
$name = $this->request->post("name");
|
||||||
|
$addonTmpDir = RUNTIME_PATH . 'addons' . DS;
|
||||||
if (!$name) {
|
if (!$name) {
|
||||||
$this->error(__('Parameter %s can not be empty', 'name'));
|
$this->error(__('Parameter %s can not be empty', 'name'));
|
||||||
}
|
}
|
||||||
|
if (!preg_match("/^[a-zA-Z0-9]+$/", $name)) {
|
||||||
|
$this->error(__('Addon name incorrect'));
|
||||||
|
}
|
||||||
|
if (!is_dir($addonTmpDir)) {
|
||||||
|
@mkdir($addonTmpDir, 0755, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$info = [];
|
||||||
try {
|
try {
|
||||||
|
$info = get_addon_info($name);
|
||||||
$uid = $this->request->post("uid");
|
$uid = $this->request->post("uid");
|
||||||
$token = $this->request->post("token");
|
$token = $this->request->post("token");
|
||||||
$version = $this->request->post("version");
|
$version = $this->request->post("version");
|
||||||
$faversion = $this->request->post("faversion");
|
$faversion = $this->request->post("faversion");
|
||||||
$extend = [
|
$extend = [
|
||||||
'uid' => $uid,
|
'uid' => $uid,
|
||||||
'token' => $token,
|
'token' => $token,
|
||||||
'version' => $version,
|
'version' => $version,
|
||||||
'faversion' => $faversion
|
'oldversion' => $info['version'] ?? '',
|
||||||
|
'faversion' => $faversion
|
||||||
];
|
];
|
||||||
//调用更新的方法
|
//调用更新的方法
|
||||||
Service::upgrade($name, $extend);
|
$info = Service::upgrade($name, $extend);
|
||||||
Cache::rm('__menu__');
|
Cache::rm('__menu__');
|
||||||
$this->success(__('Operate successful'));
|
|
||||||
} catch (AddonException $e) {
|
} catch (AddonException $e) {
|
||||||
$this->result($e->getData(), $e->getCode(), __($e->getMessage()));
|
$this->result($e->getData(), $e->getCode(), __($e->getMessage()));
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
$this->error(__($e->getMessage()));
|
$this->error(__($e->getMessage()));
|
||||||
}
|
}
|
||||||
|
$this->success(__('Operate successful'), '', ['addon' => $info]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试数据
|
||||||
|
*/
|
||||||
|
public function testdata()
|
||||||
|
{
|
||||||
|
$name = $this->request->post("name");
|
||||||
|
if (!$name) {
|
||||||
|
$this->error(__('Parameter %s can not be empty', 'name'));
|
||||||
|
}
|
||||||
|
if (!preg_match("/^[a-zA-Z0-9]+$/", $name)) {
|
||||||
|
$this->error(__('Addon name incorrect'));
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Service::importsql($name, 'testdata.sql');
|
||||||
|
} catch (AddonException $e) {
|
||||||
|
$this->result($e->getData(), $e->getCode(), __($e->getMessage()));
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$this->error(__($e->getMessage()), $e->getCode());
|
||||||
|
}
|
||||||
|
$this->success(__('Import successful'), '');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -273,43 +325,32 @@ class Addon extends Backend
|
||||||
{
|
{
|
||||||
$offset = (int)$this->request->get("offset");
|
$offset = (int)$this->request->get("offset");
|
||||||
$limit = (int)$this->request->get("limit");
|
$limit = (int)$this->request->get("limit");
|
||||||
$filter = $this->request->get("filter");
|
$filter = $this->request->get("filter", '');
|
||||||
$search = $this->request->get("search");
|
$search = $this->request->get("search", '', 'strip_tags,htmlspecialchars');
|
||||||
$search = htmlspecialchars(strip_tags($search));
|
$onlineaddons = $this->getAddonList();
|
||||||
$onlineaddons = Cache::get("onlineaddons");
|
|
||||||
if (!is_array($onlineaddons)) {
|
|
||||||
$onlineaddons = [];
|
|
||||||
$result = Http::sendRequest(config('fastadmin.api_url') . '/addon/index');
|
|
||||||
if ($result['ret']) {
|
|
||||||
$json = json_decode($result['msg'], TRUE);
|
|
||||||
$rows = isset($json['rows']) ? $json['rows'] : [];
|
|
||||||
foreach ($rows as $index => $row) {
|
|
||||||
$onlineaddons[$row['name']] = $row;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Cache::set("onlineaddons", $onlineaddons, 600);
|
|
||||||
}
|
|
||||||
$filter = (array)json_decode($filter, true);
|
$filter = (array)json_decode($filter, true);
|
||||||
$addons = get_addon_list();
|
$addons = get_addon_list();
|
||||||
$list = [];
|
$list = [];
|
||||||
foreach ($addons as $k => $v) {
|
foreach ($addons as $k => $v) {
|
||||||
if ($search && stripos($v['name'], $search) === FALSE && stripos($v['intro'], $search) === FALSE)
|
if ($search && stripos($v['name'], $search) === false && stripos($v['title'], $search) === false && stripos($v['intro'], $search) === false) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (isset($onlineaddons[$v['name']])) {
|
if (isset($onlineaddons[$v['name']])) {
|
||||||
$v = array_merge($v, $onlineaddons[$v['name']]);
|
$v = array_merge($v, $onlineaddons[$v['name']]);
|
||||||
|
$v['price'] = '-';
|
||||||
} else {
|
} else {
|
||||||
$v['category_id'] = 0;
|
$v['category_id'] = 0;
|
||||||
$v['flag'] = '';
|
$v['flag'] = '';
|
||||||
$v['banner'] = '';
|
$v['banner'] = '';
|
||||||
$v['image'] = '';
|
$v['image'] = '';
|
||||||
$v['donateimage'] = '';
|
|
||||||
$v['demourl'] = '';
|
$v['demourl'] = '';
|
||||||
$v['price'] = '0.00';
|
$v['price'] = __('None');
|
||||||
$v['screenshots'] = [];
|
$v['screenshots'] = [];
|
||||||
$v['releaselist'] = [];
|
$v['releaselist'] = [];
|
||||||
|
$v['url'] = addon_url($v['name']);
|
||||||
|
$v['url'] = str_replace($this->request->server('SCRIPT_NAME'), '', $v['url']);
|
||||||
}
|
}
|
||||||
$v['url'] = addon_url($v['name']);
|
|
||||||
$v['createtime'] = filemtime(ADDON_PATH . $v['name']);
|
$v['createtime'] = filemtime(ADDON_PATH . $v['name']);
|
||||||
if ($filter && isset($filter['category_id']) && is_numeric($filter['category_id']) && $filter['category_id'] != $v['category_id']) {
|
if ($filter && isset($filter['category_id']) && is_numeric($filter['category_id']) && $filter['category_id'] != $v['category_id']) {
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -326,4 +367,96 @@ class Addon extends Backend
|
||||||
return $callback($result);
|
return $callback($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检测
|
||||||
|
*/
|
||||||
|
public function isbuy()
|
||||||
|
{
|
||||||
|
$name = $this->request->post("name");
|
||||||
|
$uid = $this->request->post("uid");
|
||||||
|
$token = $this->request->post("token");
|
||||||
|
$version = $this->request->post("version");
|
||||||
|
$faversion = $this->request->post("faversion");
|
||||||
|
$extend = [
|
||||||
|
'uid' => $uid,
|
||||||
|
'token' => $token,
|
||||||
|
'version' => $version,
|
||||||
|
'faversion' => $faversion
|
||||||
|
];
|
||||||
|
try {
|
||||||
|
$result = Service::isBuy($name, $extend);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$this->error(__($e->getMessage()));
|
||||||
|
}
|
||||||
|
return json($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 刷新授权
|
||||||
|
*/
|
||||||
|
public function authorization()
|
||||||
|
{
|
||||||
|
$params = [
|
||||||
|
'uid' => $this->request->post('uid'),
|
||||||
|
'token' => $this->request->post('token'),
|
||||||
|
'faversion' => $this->request->post('faversion'),
|
||||||
|
];
|
||||||
|
try {
|
||||||
|
Service::authorization($params);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$this->error(__($e->getMessage()));
|
||||||
|
}
|
||||||
|
$this->success(__('Operate successful'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取插件相关表
|
||||||
|
*/
|
||||||
|
public function get_table_list()
|
||||||
|
{
|
||||||
|
$name = $this->request->post("name");
|
||||||
|
if (!preg_match("/^[a-zA-Z0-9]+$/", $name)) {
|
||||||
|
$this->error(__('Addon name incorrect'));
|
||||||
|
}
|
||||||
|
$tables = get_addon_tables($name);
|
||||||
|
$prefix = Config::get('database.prefix');
|
||||||
|
foreach ($tables as $index => $table) {
|
||||||
|
//忽略非插件标识的表名
|
||||||
|
if (!preg_match("/^{$prefix}{$name}/", $table)) {
|
||||||
|
unset($tables[$index]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$tables = array_values($tables);
|
||||||
|
$this->success('', null, ['tables' => $tables]);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getAddonList()
|
||||||
|
{
|
||||||
|
$onlineaddons = Cache::get("onlineaddons");
|
||||||
|
if (!is_array($onlineaddons) && config('fastadmin.api_url')) {
|
||||||
|
$onlineaddons = [];
|
||||||
|
$params = [
|
||||||
|
'uid' => $this->request->post('uid'),
|
||||||
|
'token' => $this->request->post('token'),
|
||||||
|
'version' => config('fastadmin.version'),
|
||||||
|
'faversion' => config('fastadmin.version'),
|
||||||
|
];
|
||||||
|
$json = [];
|
||||||
|
try {
|
||||||
|
$json = Service::addons($params);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
$rows = $json['rows'] ?? [];
|
||||||
|
foreach ($rows as $index => $row) {
|
||||||
|
if (!isset($row['name'])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$onlineaddons[$row['name']] = $row;
|
||||||
|
}
|
||||||
|
Cache::set("onlineaddons", $onlineaddons, 600);
|
||||||
|
}
|
||||||
|
return $onlineaddons;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,17 @@
|
||||||
namespace app\admin\controller;
|
namespace app\admin\controller;
|
||||||
|
|
||||||
use app\common\controller\Backend;
|
use app\common\controller\Backend;
|
||||||
|
use app\common\exception\UploadException;
|
||||||
|
use app\common\library\Upload;
|
||||||
use fast\Random;
|
use fast\Random;
|
||||||
use think\addons\Service;
|
use think\addons\Service;
|
||||||
use think\Cache;
|
use think\Cache;
|
||||||
use think\Config;
|
use think\Config;
|
||||||
use think\Db;
|
use think\Db;
|
||||||
use think\Lang;
|
use think\Lang;
|
||||||
|
use think\Loader;
|
||||||
|
use think\Response;
|
||||||
|
use think\Validate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ajax异步请求接口
|
* Ajax异步请求接口
|
||||||
|
|
@ -26,7 +31,7 @@ class Ajax extends Backend
|
||||||
parent::_initialize();
|
parent::_initialize();
|
||||||
|
|
||||||
//设置过滤方法
|
//设置过滤方法
|
||||||
$this->request->filter(['strip_tags', 'htmlspecialchars']);
|
$this->request->filter(['trim', 'strip_tags', 'htmlspecialchars']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -34,11 +39,30 @@ class Ajax extends Backend
|
||||||
*/
|
*/
|
||||||
public function lang()
|
public function lang()
|
||||||
{
|
{
|
||||||
header('Content-Type: application/javascript');
|
$this->request->get(['callback' => 'define']);
|
||||||
|
$header = ['Content-Type' => 'application/javascript'];
|
||||||
|
if (!config('app_debug')) {
|
||||||
|
$offset = 30 * 60 * 60 * 24; // 缓存一个月
|
||||||
|
$header['Cache-Control'] = 'public';
|
||||||
|
$header['Pragma'] = 'cache';
|
||||||
|
$header['Expires'] = gmdate("D, d M Y H:i:s", time() + $offset) . " GMT";
|
||||||
|
}
|
||||||
|
|
||||||
|
$controllername = $this->request->get('controllername');
|
||||||
|
$lang = $this->request->get('lang');
|
||||||
|
if (!$lang || !in_array($lang, config('allow_lang_list')) || !$controllername || !preg_match("/^[a-z0-9_\.]+$/i", $controllername)) {
|
||||||
|
return jsonp(['errmsg' => '参数错误'], 200, [], ['json_encode_param' => JSON_FORCE_OBJECT | JSON_UNESCAPED_UNICODE]);
|
||||||
|
}
|
||||||
|
|
||||||
$controllername = input("controllername");
|
$controllername = input("controllername");
|
||||||
//默认只加载了控制器对应的语言名,你还根据控制器名来加载额外的语言包
|
$className = Loader::parseClass($this->request->module(), 'controller', $controllername, false);
|
||||||
$this->loadlang($controllername);
|
|
||||||
return jsonp(Lang::get(), 200, [], ['json_encode_param' => JSON_FORCE_OBJECT | JSON_UNESCAPED_UNICODE]);
|
//存在对应的类才加载
|
||||||
|
if (class_exists($className)) {
|
||||||
|
$this->loadlang($controllername);
|
||||||
|
}
|
||||||
|
|
||||||
|
return jsonp(Lang::get(), 200, $header, ['json_encode_param' => JSON_FORCE_OBJECT | JSON_UNESCAPED_UNICODE]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -47,88 +71,63 @@ class Ajax extends Backend
|
||||||
public function upload()
|
public function upload()
|
||||||
{
|
{
|
||||||
Config::set('default_return_type', 'json');
|
Config::set('default_return_type', 'json');
|
||||||
$file = $this->request->file('file');
|
|
||||||
if (empty($file)) {
|
|
||||||
$this->error(__('No file upload or server upload limit exceeded'));
|
|
||||||
}
|
|
||||||
|
|
||||||
//判断是否已经存在附件
|
//必须还原upload配置,否则分片及cdnurl函数计算错误
|
||||||
$sha1 = $file->hash();
|
Config::load(APP_PATH . 'extra/upload.php', 'upload');
|
||||||
|
|
||||||
$upload = Config::get('upload');
|
$chunkid = $this->request->post("chunkid");
|
||||||
|
if ($chunkid) {
|
||||||
preg_match('/(\d+)(\w+)/', $upload['maxsize'], $matches);
|
if (!Config::get('upload.chunking')) {
|
||||||
$type = strtolower($matches[2]);
|
$this->error(__('Chunk file disabled'));
|
||||||
$typeDict = ['b' => 0, 'k' => 1, 'kb' => 1, 'm' => 2, 'mb' => 2, 'gb' => 3, 'g' => 3];
|
}
|
||||||
$size = (int)$upload['maxsize'] * pow(1024, isset($typeDict[$type]) ? $typeDict[$type] : 0);
|
$action = $this->request->post("action");
|
||||||
$fileInfo = $file->getInfo();
|
$chunkindex = $this->request->post("chunkindex/d");
|
||||||
$suffix = strtolower(pathinfo($fileInfo['name'], PATHINFO_EXTENSION));
|
$chunkcount = $this->request->post("chunkcount/d");
|
||||||
$suffix = $suffix ? $suffix : 'file';
|
$filename = $this->request->post("filename");
|
||||||
|
$method = $this->request->method(true);
|
||||||
$mimetypeArr = explode(',', strtolower($upload['mimetype']));
|
if ($action == 'merge') {
|
||||||
$typeArr = explode('/', $fileInfo['type']);
|
$attachment = null;
|
||||||
|
//合并分片文件
|
||||||
//验证文件后缀
|
try {
|
||||||
if ($upload['mimetype'] !== '*' &&
|
$upload = new Upload();
|
||||||
(
|
$attachment = $upload->merge($chunkid, $chunkcount, $filename);
|
||||||
!in_array($suffix, $mimetypeArr)
|
} catch (UploadException $e) {
|
||||||
|| (stripos($typeArr[0] . '/', $upload['mimetype']) !== false && (!in_array($fileInfo['type'], $mimetypeArr) && !in_array($typeArr[0] . '/*', $mimetypeArr)))
|
$this->error($e->getMessage());
|
||||||
)
|
}
|
||||||
) {
|
$this->success(__('Uploaded successful'), '', ['url' => $attachment->url, 'fullurl' => cdnurl($attachment->url, true)]);
|
||||||
$this->error(__('Uploaded file format is limited'));
|
} elseif ($method == 'clean') {
|
||||||
}
|
//删除冗余的分片文件
|
||||||
$replaceArr = [
|
try {
|
||||||
'{year}' => date("Y"),
|
$upload = new Upload();
|
||||||
'{mon}' => date("m"),
|
$upload->clean($chunkid);
|
||||||
'{day}' => date("d"),
|
} catch (UploadException $e) {
|
||||||
'{hour}' => date("H"),
|
$this->error($e->getMessage());
|
||||||
'{min}' => date("i"),
|
}
|
||||||
'{sec}' => date("s"),
|
$this->success();
|
||||||
'{random}' => Random::alnum(16),
|
} else {
|
||||||
'{random32}' => Random::alnum(32),
|
//上传分片文件
|
||||||
'{filename}' => $suffix ? substr($fileInfo['name'], 0, strripos($fileInfo['name'], '.')) : $fileInfo['name'],
|
//默认普通上传文件
|
||||||
'{suffix}' => $suffix,
|
$file = $this->request->file('file');
|
||||||
'{.suffix}' => $suffix ? '.' . $suffix : '',
|
try {
|
||||||
'{filemd5}' => md5_file($fileInfo['tmp_name']),
|
$upload = new Upload($file);
|
||||||
];
|
$upload->chunk($chunkid, $chunkindex, $chunkcount);
|
||||||
$savekey = $upload['savekey'];
|
} catch (UploadException $e) {
|
||||||
$savekey = str_replace(array_keys($replaceArr), array_values($replaceArr), $savekey);
|
$this->error($e->getMessage());
|
||||||
|
}
|
||||||
$uploadDir = substr($savekey, 0, strripos($savekey, '/') + 1);
|
$this->success();
|
||||||
$fileName = substr($savekey, strripos($savekey, '/') + 1);
|
|
||||||
//
|
|
||||||
$splInfo = $file->validate(['size' => $size])->move(ROOT_PATH . '/public' . $uploadDir, $fileName);
|
|
||||||
if ($splInfo) {
|
|
||||||
$imagewidth = $imageheight = 0;
|
|
||||||
if (in_array($suffix, ['gif', 'jpg', 'jpeg', 'bmp', 'png', 'swf'])) {
|
|
||||||
$imgInfo = getimagesize($splInfo->getPathname());
|
|
||||||
$imagewidth = isset($imgInfo[0]) ? $imgInfo[0] : $imagewidth;
|
|
||||||
$imageheight = isset($imgInfo[1]) ? $imgInfo[1] : $imageheight;
|
|
||||||
}
|
}
|
||||||
$params = array(
|
|
||||||
'admin_id' => (int)$this->auth->id,
|
|
||||||
'user_id' => 0,
|
|
||||||
'filesize' => $fileInfo['size'],
|
|
||||||
'imagewidth' => $imagewidth,
|
|
||||||
'imageheight' => $imageheight,
|
|
||||||
'imagetype' => $suffix,
|
|
||||||
'imageframes' => 0,
|
|
||||||
'mimetype' => $fileInfo['type'],
|
|
||||||
'url' => $uploadDir . $splInfo->getSaveName(),
|
|
||||||
'uploadtime' => time(),
|
|
||||||
'storage' => 'local',
|
|
||||||
'sha1' => $sha1,
|
|
||||||
);
|
|
||||||
$attachment = model("attachment");
|
|
||||||
$attachment->data(array_filter($params));
|
|
||||||
$attachment->save();
|
|
||||||
\think\Hook::listen("upload_after", $attachment);
|
|
||||||
$this->success(__('Upload successful'), null, [
|
|
||||||
'url' => $uploadDir . $splInfo->getSaveName()
|
|
||||||
]);
|
|
||||||
} else {
|
} else {
|
||||||
// 上传失败获取错误信息
|
$attachment = null;
|
||||||
$this->error($file->getError());
|
//默认普通上传文件
|
||||||
|
$file = $this->request->file('file');
|
||||||
|
try {
|
||||||
|
$upload = new Upload($file);
|
||||||
|
$attachment = $upload->upload();
|
||||||
|
} catch (UploadException $e) {
|
||||||
|
$this->error($e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->success(__('Uploaded successful'), '', ['url' => $attachment->url, 'fullurl' => cdnurl($attachment->url, true)]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -145,64 +144,58 @@ class Ajax extends Backend
|
||||||
$field = $this->request->post("field");
|
$field = $this->request->post("field");
|
||||||
//操作的数据表
|
//操作的数据表
|
||||||
$table = $this->request->post("table");
|
$table = $this->request->post("table");
|
||||||
|
if (!Validate::is($table, "alphaDash")) {
|
||||||
|
$this->error();
|
||||||
|
}
|
||||||
|
//主键
|
||||||
|
$pk = $this->request->post("pk");
|
||||||
//排序的方式
|
//排序的方式
|
||||||
$orderway = $this->request->post("orderway", 'strtolower');
|
$orderway = strtolower($this->request->post("orderway", ""));
|
||||||
$orderway = $orderway == 'asc' ? 'ASC' : 'DESC';
|
$orderway = $orderway == 'asc' ? 'ASC' : 'DESC';
|
||||||
$sour = $weighdata = [];
|
$sour = $weighdata = [];
|
||||||
$ids = explode(',', $ids);
|
$ids = explode(',', $ids);
|
||||||
$prikey = 'id';
|
$prikey = $pk && preg_match("/^[a-z0-9\-_]+$/i", $pk) ? $pk : (Db::name($table)->getPk() ?: 'id');
|
||||||
$pid = $this->request->post("pid");
|
$pid = $this->request->post("pid", "");
|
||||||
//限制更新的字段
|
//限制更新的字段
|
||||||
$field = in_array($field, ['weigh']) ? $field : 'weigh';
|
$field = in_array($field, ['weigh']) ? $field : 'weigh';
|
||||||
|
|
||||||
// 如果设定了pid的值,此时只匹配满足条件的ID,其它忽略
|
// 如果设定了pid的值,此时只匹配满足条件的ID,其它忽略
|
||||||
if ($pid !== '') {
|
if ($pid !== '') {
|
||||||
$hasids = [];
|
$hasids = [];
|
||||||
$list = Db::name($table)->where($prikey, 'in', $ids)->where('pid', 'in', $pid)->field('id,pid')->select();
|
$list = Db::name($table)->where($prikey, 'in', $ids)->where('pid', 'in', $pid)->field("{$prikey},pid")->select();
|
||||||
foreach ($list as $k => $v) {
|
foreach ($list as $k => $v) {
|
||||||
$hasids[] = $v['id'];
|
$hasids[] = $v[$prikey];
|
||||||
}
|
}
|
||||||
$ids = array_values(array_intersect($ids, $hasids));
|
$ids = array_values(array_intersect($ids, $hasids));
|
||||||
}
|
}
|
||||||
|
|
||||||
//直接修复排序
|
$list = Db::name($table)->field("$prikey,$field")->where($prikey, 'in', $ids)->order($field, $orderway)->select();
|
||||||
$one = Db::name($table)->field("{$field},COUNT(*) AS nums")->group($field)->having('nums > 1')->find();
|
foreach ($list as $k => $v) {
|
||||||
if ($one) {
|
$sour[] = $v[$prikey];
|
||||||
$list = Db::name($table)->field("$prikey,$field")->order($field, $orderway)->select();
|
$weighdata[$v[$prikey]] = $v[$field];
|
||||||
foreach ($list as $k => $v) {
|
|
||||||
Db::name($table)->where($prikey, $v[$prikey])->update([$field => $k + 1]);
|
|
||||||
}
|
|
||||||
$this->success();
|
|
||||||
} else {
|
|
||||||
$list = Db::name($table)->field("$prikey,$field")->where($prikey, 'in', $ids)->order($field, $orderway)->select();
|
|
||||||
foreach ($list as $k => $v) {
|
|
||||||
$sour[] = $v[$prikey];
|
|
||||||
$weighdata[$v[$prikey]] = $v[$field];
|
|
||||||
}
|
|
||||||
$position = array_search($changeid, $ids);
|
|
||||||
$desc_id = $sour[$position]; //移动到目标的ID值,取出所处改变前位置的值
|
|
||||||
$sour_id = $changeid;
|
|
||||||
$desc_value = $weighdata[$desc_id];
|
|
||||||
$sour_value = $weighdata[$sour_id];
|
|
||||||
//echo "移动的ID:{$sour_id}\n";
|
|
||||||
//echo "替换的ID:{$desc_id}\n";
|
|
||||||
$weighids = array();
|
|
||||||
$temp = array_values(array_diff_assoc($ids, $sour));
|
|
||||||
foreach ($temp as $m => $n) {
|
|
||||||
if ($n == $sour_id) {
|
|
||||||
$offset = $desc_id;
|
|
||||||
} else {
|
|
||||||
if ($sour_id == $temp[0]) {
|
|
||||||
$offset = isset($temp[$m + 1]) ? $temp[$m + 1] : $sour_id;
|
|
||||||
} else {
|
|
||||||
$offset = isset($temp[$m - 1]) ? $temp[$m - 1] : $sour_id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$weighids[$n] = $weighdata[$offset];
|
|
||||||
Db::name($table)->where($prikey, $n)->update([$field => $weighdata[$offset]]);
|
|
||||||
}
|
|
||||||
$this->success();
|
|
||||||
}
|
}
|
||||||
|
$position = array_search($changeid, $ids);
|
||||||
|
$desc_id = isset($sour[$position]) ? $sour[$position] : end($sour); //移动到目标的ID值,取出所处改变前位置的值
|
||||||
|
$sour_id = $changeid;
|
||||||
|
$weighids = array();
|
||||||
|
$temp = array_values(array_diff_assoc($ids, $sour));
|
||||||
|
foreach ($temp as $m => $n) {
|
||||||
|
if ($n == $sour_id) {
|
||||||
|
$offset = $desc_id;
|
||||||
|
} else {
|
||||||
|
if ($sour_id == $temp[0]) {
|
||||||
|
$offset = isset($temp[$m + 1]) ? $temp[$m + 1] : $sour_id;
|
||||||
|
} else {
|
||||||
|
$offset = isset($temp[$m - 1]) ? $temp[$m - 1] : $sour_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!isset($weighdata[$offset])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$weighids[$n] = $weighdata[$offset];
|
||||||
|
Db::name($table)->where($prikey, $n)->update([$field => $weighdata[$offset]]);
|
||||||
|
}
|
||||||
|
$this->success();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -210,21 +203,56 @@ class Ajax extends Backend
|
||||||
*/
|
*/
|
||||||
public function wipecache()
|
public function wipecache()
|
||||||
{
|
{
|
||||||
$type = $this->request->request("type");
|
try {
|
||||||
switch ($type) {
|
$type = $this->request->request("type");
|
||||||
case 'content' || 'all':
|
switch ($type) {
|
||||||
rmdirs(CACHE_PATH, false);
|
case 'all':
|
||||||
Cache::clear();
|
// no break
|
||||||
if ($type == 'content')
|
case 'content':
|
||||||
break;
|
//内容缓存
|
||||||
case 'template' || 'all':
|
rmdirs(CACHE_PATH, false);
|
||||||
rmdirs(TEMP_PATH, false);
|
Cache::clear();
|
||||||
if ($type == 'template')
|
if ($type == 'content') {
|
||||||
break;
|
break;
|
||||||
case 'addons' || 'all':
|
}
|
||||||
Service::refresh();
|
case 'template':
|
||||||
if ($type == 'addons')
|
// 模板缓存
|
||||||
break;
|
rmdirs(TEMP_PATH, false);
|
||||||
|
if ($type == 'template') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'addons':
|
||||||
|
// 插件缓存
|
||||||
|
Service::refresh();
|
||||||
|
if ($type == 'addons') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'browser':
|
||||||
|
// 浏览器缓存
|
||||||
|
// 只有生产环境下才修改
|
||||||
|
if (!config('app_debug')) {
|
||||||
|
$version = config('site.version');
|
||||||
|
$newversion = preg_replace_callback("/(.*)\.([0-9]+)\$/", function ($match) {
|
||||||
|
return $match[1] . '.' . ($match[2] + 1);
|
||||||
|
}, $version);
|
||||||
|
if ($newversion && $newversion != $version) {
|
||||||
|
Db::startTrans();
|
||||||
|
try {
|
||||||
|
\app\common\model\Config::where('name', 'version')->update(['value' => $newversion]);
|
||||||
|
\app\common\model\Config::refreshFile();
|
||||||
|
Db::commit();
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
Db::rollback();
|
||||||
|
exception($e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($type == 'browser') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->error($e->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
\think\Hook::listen("wipecache_after");
|
\think\Hook::listen("wipecache_after");
|
||||||
|
|
@ -236,21 +264,20 @@ class Ajax extends Backend
|
||||||
*/
|
*/
|
||||||
public function category()
|
public function category()
|
||||||
{
|
{
|
||||||
$type = $this->request->get('type');
|
$type = $this->request->get('type', '');
|
||||||
$pid = $this->request->get('pid');
|
$pid = $this->request->get('pid', '');
|
||||||
$where = ['status' => 'normal'];
|
$where = ['status' => 'normal'];
|
||||||
$categorylist = null;
|
$categorylist = null;
|
||||||
if ($pid !== '') {
|
if ($pid || $pid === '0') {
|
||||||
if ($type) {
|
$where['pid'] = $pid;
|
||||||
$where['type'] = $type;
|
|
||||||
}
|
|
||||||
if ($pid) {
|
|
||||||
$where['pid'] = $pid;
|
|
||||||
}
|
|
||||||
|
|
||||||
$categorylist = Db::name('category')->where($where)->field('id as value,name')->order('weigh desc,id desc')->select();
|
|
||||||
}
|
}
|
||||||
$this->success('', null, $categorylist);
|
if ($type) {
|
||||||
|
$where['type'] = $type;
|
||||||
|
}
|
||||||
|
|
||||||
|
$categorylist = Db::name('category')->where($where)->field('id as value,name')->order('weigh desc,id desc')->select();
|
||||||
|
|
||||||
|
$this->success('', '', $categorylist);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -258,24 +285,43 @@ class Ajax extends Backend
|
||||||
*/
|
*/
|
||||||
public function area()
|
public function area()
|
||||||
{
|
{
|
||||||
$province = $this->request->get('province');
|
$params = $this->request->get("row/a");
|
||||||
$city = $this->request->get('city');
|
if (!empty($params)) {
|
||||||
|
$province = isset($params['province']) ? $params['province'] : null;
|
||||||
|
$city = isset($params['city']) ? $params['city'] : null;
|
||||||
|
} else {
|
||||||
|
$province = $this->request->get('province');
|
||||||
|
$city = $this->request->get('city');
|
||||||
|
}
|
||||||
$where = ['pid' => 0, 'level' => 1];
|
$where = ['pid' => 0, 'level' => 1];
|
||||||
$provincelist = null;
|
$provincelist = null;
|
||||||
if ($province !== '') {
|
if ($province !== null) {
|
||||||
if ($province) {
|
$where['pid'] = $province;
|
||||||
$where['pid'] = $province;
|
$where['level'] = 2;
|
||||||
$where['level'] = 2;
|
if ($city !== null) {
|
||||||
}
|
$where['pid'] = $city;
|
||||||
if ($city !== '') {
|
$where['level'] = 3;
|
||||||
if ($city) {
|
|
||||||
$where['pid'] = $city;
|
|
||||||
$where['level'] = 3;
|
|
||||||
}
|
|
||||||
$provincelist = Db::name('area')->where($where)->field('id as value,name')->select();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->success('', null, $provincelist);
|
$provincelist = Db::name('area')->where($where)->field('id as value,name')->select();
|
||||||
|
$this->success('', '', $provincelist);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成后缀图标
|
||||||
|
*/
|
||||||
|
public function icon()
|
||||||
|
{
|
||||||
|
$suffix = $this->request->request("suffix");
|
||||||
|
$suffix = $suffix ? $suffix : "FILE";
|
||||||
|
$data = build_suffix_image($suffix);
|
||||||
|
$header = ['Content-Type' => 'image/svg+xml'];
|
||||||
|
$offset = 30 * 60 * 60 * 24; // 缓存一个月
|
||||||
|
$header['Cache-Control'] = 'public';
|
||||||
|
$header['Pragma'] = 'cache';
|
||||||
|
$header['Expires'] = gmdate("D, d M Y H:i:s", time() + $offset) . " GMT";
|
||||||
|
$response = Response::create($data, '', 200, $header);
|
||||||
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,12 +9,15 @@ use fast\Tree;
|
||||||
/**
|
/**
|
||||||
* 分类管理
|
* 分类管理
|
||||||
*
|
*
|
||||||
* @icon fa fa-list
|
* @icon fa fa-list
|
||||||
* @remark 用于统一管理网站的所有分类,分类可进行无限级分类
|
* @remark 用于管理网站的所有分类,分类可进行无限级分类,分类类型请在常规管理->系统配置->字典配置中添加
|
||||||
*/
|
*/
|
||||||
class Category extends Backend
|
class Category extends Backend
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \app\common\model\Category
|
||||||
|
*/
|
||||||
protected $model = null;
|
protected $model = null;
|
||||||
protected $categorylist = [];
|
protected $categorylist = [];
|
||||||
protected $noNeedRight = ['selectpage'];
|
protected $noNeedRight = ['selectpage'];
|
||||||
|
|
@ -22,20 +25,20 @@ class Category extends Backend
|
||||||
public function _initialize()
|
public function _initialize()
|
||||||
{
|
{
|
||||||
parent::_initialize();
|
parent::_initialize();
|
||||||
$this->request->filter(['strip_tags']);
|
|
||||||
$this->model = model('app\common\model\Category');
|
$this->model = model('app\common\model\Category');
|
||||||
|
|
||||||
$tree = Tree::instance();
|
$tree = Tree::instance();
|
||||||
$tree->init(collection($this->model->order('weigh desc,id desc')->select())->toArray(), 'pid');
|
$tree->init(collection($this->model->order('weigh desc,id desc')->select())->toArray(), 'pid');
|
||||||
$this->categorylist = $tree->getTreeList($tree->getTreeArray(0), 'name');
|
$this->categorylist = $tree->getTreeList($tree->getTreeArray(0), 'name');
|
||||||
$categorydata = [0 => ['type' => 'all', 'name' => __('None')]];
|
$categorydata = [0 => ['type' => 'all', 'name' => __('None')]];
|
||||||
foreach ($this->categorylist as $k => $v)
|
foreach ($this->categorylist as $k => $v) {
|
||||||
{
|
|
||||||
$categorydata[$v['id']] = $v;
|
$categorydata[$v['id']] = $v;
|
||||||
}
|
}
|
||||||
|
$typeList = CategoryModel::getTypeList();
|
||||||
$this->view->assign("flagList", $this->model->getFlagList());
|
$this->view->assign("flagList", $this->model->getFlagList());
|
||||||
$this->view->assign("typeList", CategoryModel::getTypeList());
|
$this->view->assign("typeList", $typeList);
|
||||||
$this->view->assign("parentList", $categorydata);
|
$this->view->assign("parentList", $categorydata);
|
||||||
|
$this->assignconfig('typeList', $typeList);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -43,35 +46,32 @@ class Category extends Backend
|
||||||
*/
|
*/
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
if ($this->request->isAjax())
|
//设置过滤方法
|
||||||
{
|
$this->request->filter(['strip_tags']);
|
||||||
|
if ($this->request->isAjax()) {
|
||||||
$search = $this->request->request("search");
|
$search = $this->request->request("search");
|
||||||
$type = $this->request->request("type");
|
$type = $this->request->request("type");
|
||||||
|
|
||||||
//构造父类select列表选项数据
|
//构造父类select列表选项数据
|
||||||
$list = [];
|
$list = [];
|
||||||
|
|
||||||
foreach ($this->categorylist as $k => $v)
|
foreach ($this->categorylist as $k => $v) {
|
||||||
{
|
if ($search) {
|
||||||
if ($search) {
|
if ($v['type'] == $type && stripos($v['name'], $search) !== false || stripos($v['nickname'], $search) !== false) {
|
||||||
if ($v['type'] == $type && stripos($v['name'], $search) !== false || stripos($v['nickname'], $search) !== false)
|
if ($type == "all" || $type == null) {
|
||||||
{
|
|
||||||
if($type == "all" || $type == null) {
|
|
||||||
$list = $this->categorylist;
|
|
||||||
} else {
|
|
||||||
$list[] = $v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if($type == "all" || $type == null) {
|
|
||||||
$list = $this->categorylist;
|
$list = $this->categorylist;
|
||||||
} else if ($v['type'] == $type){
|
} else {
|
||||||
$list[] = $v;
|
$list[] = $v;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if ($type == "all" || $type == null) {
|
||||||
|
$list = $this->categorylist;
|
||||||
|
} elseif ($v['type'] == $type) {
|
||||||
|
$list[] = $v;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$total = count($list);
|
$total = count($list);
|
||||||
$result = array("total" => $total, "rows" => $list);
|
$result = array("total" => $total, "rows" => $list);
|
||||||
|
|
@ -81,14 +81,78 @@ class Category extends Backend
|
||||||
return $this->view->fetch();
|
return $this->view->fetch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加
|
||||||
|
*/
|
||||||
|
public function add()
|
||||||
|
{
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$this->token();
|
||||||
|
}
|
||||||
|
return parent::add();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑
|
||||||
|
*/
|
||||||
|
public function edit($ids = null)
|
||||||
|
{
|
||||||
|
$row = $this->model->get($ids);
|
||||||
|
if (!$row) {
|
||||||
|
$this->error(__('No Results were found'));
|
||||||
|
}
|
||||||
|
$adminIds = $this->getDataLimitAdminIds();
|
||||||
|
if (is_array($adminIds)) {
|
||||||
|
if (!in_array($row[$this->dataLimitField], $adminIds)) {
|
||||||
|
$this->error(__('You have no permission'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$this->token();
|
||||||
|
$params = $this->request->post("row/a");
|
||||||
|
if ($params) {
|
||||||
|
$params = $this->preExcludeFields($params);
|
||||||
|
|
||||||
|
if ($params['pid'] != $row['pid']) {
|
||||||
|
$childrenIds = Tree::instance()->init(collection(\app\common\model\Category::select())->toArray())->getChildrenIds($row['id'], true);
|
||||||
|
if (in_array($params['pid'], $childrenIds)) {
|
||||||
|
$this->error(__('Can not change the parent to child or itself'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
//是否采用模型验证
|
||||||
|
if ($this->modelValidate) {
|
||||||
|
$name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
|
||||||
|
$validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate;
|
||||||
|
$row->validate($validate);
|
||||||
|
}
|
||||||
|
$result = $row->allowField(true)->save($params);
|
||||||
|
if ($result !== false) {
|
||||||
|
$this->success();
|
||||||
|
} else {
|
||||||
|
$this->error($row->getError());
|
||||||
|
}
|
||||||
|
} catch (\think\exception\PDOException $e) {
|
||||||
|
$this->error($e->getMessage());
|
||||||
|
} catch (\think\Exception $e) {
|
||||||
|
$this->error($e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->error(__('Parameter %s can not be empty', ''));
|
||||||
|
}
|
||||||
|
$this->view->assign("row", $row);
|
||||||
|
return $this->view->fetch();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Selectpage搜索
|
* Selectpage搜索
|
||||||
*
|
*
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
public function selectpage()
|
public function selectpage()
|
||||||
{
|
{
|
||||||
return parent::selectpage();
|
return parent::selectpage();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,17 @@
|
||||||
|
|
||||||
namespace app\admin\controller;
|
namespace app\admin\controller;
|
||||||
|
|
||||||
|
use app\admin\model\Admin;
|
||||||
|
use app\admin\model\User;
|
||||||
use app\common\controller\Backend;
|
use app\common\controller\Backend;
|
||||||
use think\Config;
|
use app\common\model\Attachment;
|
||||||
|
use fast\Date;
|
||||||
|
use think\Db;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 控制台
|
* 控制台
|
||||||
*
|
*
|
||||||
* @icon fa fa-dashboard
|
* @icon fa fa-dashboard
|
||||||
* @remark 用于展示当前系统中的统计数据、统计报表及重要实时数据
|
* @remark 用于展示当前系统中的统计数据、统计报表及重要实时数据
|
||||||
*/
|
*/
|
||||||
class Dashboard extends Backend
|
class Dashboard extends Backend
|
||||||
|
|
@ -19,37 +23,61 @@ class Dashboard extends Backend
|
||||||
*/
|
*/
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
$seventtime = \fast\Date::unixtime('day', -7);
|
try {
|
||||||
$paylist = $createlist = [];
|
\think\Db::execute("SET @@sql_mode='';");
|
||||||
for ($i = 0; $i < 7; $i++)
|
} catch (\Exception $e) {
|
||||||
{
|
|
||||||
$day = date("Y-m-d", $seventtime + ($i * 86400));
|
}
|
||||||
$createlist[$day] = mt_rand(20, 200);
|
$column = [];
|
||||||
$paylist[$day] = mt_rand(1, mt_rand(1, $createlist[$day]));
|
$starttime = Date::unixtime('day', -6);
|
||||||
|
$endtime = Date::unixtime('day', 0, 'end');
|
||||||
|
$joinlist = Db("user")->where('jointime', 'between time', [$starttime, $endtime])
|
||||||
|
->field('jointime, status, COUNT(*) AS nums, DATE_FORMAT(FROM_UNIXTIME(jointime), "%Y-%m-%d") AS join_date')
|
||||||
|
->group('join_date')
|
||||||
|
->select();
|
||||||
|
for ($time = $starttime; $time <= $endtime;) {
|
||||||
|
$column[] = date("Y-m-d", $time);
|
||||||
|
$time += 86400;
|
||||||
|
}
|
||||||
|
$userlist = array_fill_keys($column, 0);
|
||||||
|
foreach ($joinlist as $k => $v) {
|
||||||
|
$userlist[$v['join_date']] = $v['nums'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$dbTableList = Db::query("SHOW TABLE STATUS");
|
||||||
|
$addonList = get_addon_list();
|
||||||
|
$totalworkingaddon = 0;
|
||||||
|
$totaladdon = count($addonList);
|
||||||
|
foreach ($addonList as $index => $item) {
|
||||||
|
if ($item['state']) {
|
||||||
|
$totalworkingaddon += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$hooks = config('addons.hooks');
|
|
||||||
$uploadmode = isset($hooks['upload_config_init']) && $hooks['upload_config_init'] ? implode(',', $hooks['upload_config_init']) : 'local';
|
|
||||||
$addonComposerCfg = ROOT_PATH . '/vendor/karsonzhang/fastadmin-addons/composer.json';
|
|
||||||
Config::parse($addonComposerCfg, "json", "composer");
|
|
||||||
$config = Config::get("composer");
|
|
||||||
$addonVersion = isset($config['version']) ? $config['version'] : __('Unknown');
|
|
||||||
$this->view->assign([
|
$this->view->assign([
|
||||||
'totaluser' => 35200,
|
'totaluser' => User::count(),
|
||||||
'totalviews' => 219390,
|
'totaladdon' => $totaladdon,
|
||||||
'totalorder' => 32143,
|
'totaladmin' => Admin::count(),
|
||||||
'totalorderamount' => 174800,
|
'totalcategory' => \app\common\model\Category::count(),
|
||||||
'todayuserlogin' => 321,
|
'todayusersignup' => User::whereTime('jointime', 'today')->count(),
|
||||||
'todayusersignup' => 430,
|
'todayuserlogin' => User::whereTime('logintime', 'today')->count(),
|
||||||
'todayorder' => 2324,
|
'sevendau' => User::whereTime('jointime|logintime|prevtime', '-7 days')->count(),
|
||||||
'unsettleorder' => 132,
|
'thirtydau' => User::whereTime('jointime|logintime|prevtime', '-30 days')->count(),
|
||||||
'sevendnu' => '80%',
|
'threednu' => User::whereTime('jointime', '-3 days')->count(),
|
||||||
'sevendau' => '32%',
|
'sevendnu' => User::whereTime('jointime', '-7 days')->count(),
|
||||||
'paylist' => $paylist,
|
'dbtablenums' => count($dbTableList),
|
||||||
'createlist' => $createlist,
|
'dbsize' => array_sum(array_map(function ($item) {
|
||||||
'addonversion' => $addonVersion,
|
return $item['Data_length'] + $item['Index_length'];
|
||||||
'uploadmode' => $uploadmode
|
}, $dbTableList)),
|
||||||
|
'totalworkingaddon' => $totalworkingaddon,
|
||||||
|
'attachmentnums' => Attachment::count(),
|
||||||
|
'attachmentsize' => Attachment::sum('filesize'),
|
||||||
|
'picturenums' => Attachment::where('mimetype', 'like', 'image/%')->count(),
|
||||||
|
'picturesize' => Attachment::where('mimetype', 'like', 'image/%')->sum('filesize'),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$this->assignconfig('column', array_keys($userlist));
|
||||||
|
$this->assignconfig('userdata', array_values($userlist));
|
||||||
|
|
||||||
return $this->view->fetch();
|
return $this->view->fetch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ use app\admin\model\AdminLog;
|
||||||
use app\common\controller\Backend;
|
use app\common\controller\Backend;
|
||||||
use think\Config;
|
use think\Config;
|
||||||
use think\Hook;
|
use think\Hook;
|
||||||
|
use think\Session;
|
||||||
use think\Validate;
|
use think\Validate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -22,6 +23,8 @@ class Index extends Backend
|
||||||
public function _initialize()
|
public function _initialize()
|
||||||
{
|
{
|
||||||
parent::_initialize();
|
parent::_initialize();
|
||||||
|
//移除HTML标签
|
||||||
|
$this->request->filter('trim,strip_tags,htmlspecialchars');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -29,12 +32,18 @@ class Index extends Backend
|
||||||
*/
|
*/
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
|
$cookieArr = ['adminskin' => "/^skin\-([a-z\-]+)\$/i", 'multiplenav' => "/^(0|1)\$/", 'multipletab' => "/^(0|1)\$/", 'show_submenu' => "/^(0|1)\$/"];
|
||||||
|
foreach ($cookieArr as $key => $regex) {
|
||||||
|
$cookieValue = $this->request->cookie($key);
|
||||||
|
if (!is_null($cookieValue) && preg_match($regex, $cookieValue)) {
|
||||||
|
config('fastadmin.' . $key, $cookieValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
//左侧菜单
|
//左侧菜单
|
||||||
list($menulist, $navlist) = $this->auth->getSidebar([
|
list($menulist, $navlist, $fixedmenu, $referermenu) = $this->auth->getSidebar([
|
||||||
'dashboard' => 'hot',
|
'dashboard' => 'hot',
|
||||||
'addon' => ['new', 'red', 'badge'],
|
'addon' => ['new', 'red', 'badge'],
|
||||||
'auth/rule' => __('Menu'),
|
'auth/rule' => __('Menu'),
|
||||||
'general' => ['new', 'purple'],
|
|
||||||
], $this->view->site['fixedpage']);
|
], $this->view->site['fixedpage']);
|
||||||
$action = $this->request->request('action');
|
$action = $this->request->request('action');
|
||||||
if ($this->request->isPost()) {
|
if ($this->request->isPost()) {
|
||||||
|
|
@ -42,8 +51,11 @@ class Index extends Backend
|
||||||
$this->success('', null, ['menulist' => $menulist, 'navlist' => $navlist]);
|
$this->success('', null, ['menulist' => $menulist, 'navlist' => $navlist]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$this->assignconfig('cookie', ['prefix' => config('cookie.prefix')]);
|
||||||
$this->view->assign('menulist', $menulist);
|
$this->view->assign('menulist', $menulist);
|
||||||
$this->view->assign('navlist', $navlist);
|
$this->view->assign('navlist', $navlist);
|
||||||
|
$this->view->assign('fixedmenu', $fixedmenu);
|
||||||
|
$this->view->assign('referermenu', $referermenu);
|
||||||
$this->view->assign('title', __('Home'));
|
$this->view->assign('title', __('Home'));
|
||||||
return $this->view->fetch();
|
return $this->view->fetch();
|
||||||
}
|
}
|
||||||
|
|
@ -53,19 +65,22 @@ class Index extends Backend
|
||||||
*/
|
*/
|
||||||
public function login()
|
public function login()
|
||||||
{
|
{
|
||||||
$url = $this->request->get('url', 'index/index');
|
$url = $this->request->get('url', '', 'url_clean');
|
||||||
|
$url = $url ?: 'index/index';
|
||||||
if ($this->auth->isLogin()) {
|
if ($this->auth->isLogin()) {
|
||||||
$this->success(__("You've logged in, do not login again"), $url);
|
$this->success(__("You've logged in, do not login again"), $url);
|
||||||
}
|
}
|
||||||
|
//保持会话有效时长,单位:小时
|
||||||
|
$keeyloginhours = 24;
|
||||||
if ($this->request->isPost()) {
|
if ($this->request->isPost()) {
|
||||||
$username = $this->request->post('username');
|
$username = $this->request->post('username');
|
||||||
$password = $this->request->post('password');
|
$password = $this->request->post('password', '', null);
|
||||||
$keeplogin = $this->request->post('keeplogin');
|
$keeplogin = $this->request->post('keeplogin');
|
||||||
$token = $this->request->post('__token__');
|
$token = $this->request->post('__token__');
|
||||||
$rule = [
|
$rule = [
|
||||||
'username' => 'require|length:3,30',
|
'username' => 'require|length:3,30',
|
||||||
'password' => 'require|length:3,30',
|
'password' => 'require|length:3,30',
|
||||||
'__token__' => 'token',
|
'__token__' => 'require|token',
|
||||||
];
|
];
|
||||||
$data = [
|
$data = [
|
||||||
'username' => $username,
|
'username' => $username,
|
||||||
|
|
@ -82,7 +97,7 @@ class Index extends Backend
|
||||||
$this->error($validate->getError(), $url, ['token' => $this->request->token()]);
|
$this->error($validate->getError(), $url, ['token' => $this->request->token()]);
|
||||||
}
|
}
|
||||||
AdminLog::setTitle(__('Login'));
|
AdminLog::setTitle(__('Login'));
|
||||||
$result = $this->auth->login($username, $password, $keeplogin ? 86400 : 0);
|
$result = $this->auth->login($username, $password, $keeplogin ? $keeyloginhours * 3600 : 0);
|
||||||
if ($result === true) {
|
if ($result === true) {
|
||||||
Hook::listen("admin_login_after", $this->request);
|
Hook::listen("admin_login_after", $this->request);
|
||||||
$this->success(__('Login successful'), $url, ['url' => $url, 'id' => $this->auth->id, 'username' => $username, 'avatar' => $this->auth->avatar]);
|
$this->success(__('Login successful'), $url, ['url' => $url, 'id' => $this->auth->id, 'username' => $username, 'avatar' => $this->auth->avatar]);
|
||||||
|
|
@ -95,10 +110,12 @@ class Index extends Backend
|
||||||
|
|
||||||
// 根据客户端的cookie,判断是否可以自动登录
|
// 根据客户端的cookie,判断是否可以自动登录
|
||||||
if ($this->auth->autologin()) {
|
if ($this->auth->autologin()) {
|
||||||
|
Session::delete("referer");
|
||||||
$this->redirect($url);
|
$this->redirect($url);
|
||||||
}
|
}
|
||||||
$background = Config::get('fastadmin.login_background');
|
$background = Config::get('fastadmin.login_background');
|
||||||
$background = stripos($background, 'http') === 0 ? $background : config('site.cdnurl') . $background;
|
$background = $background ? (stripos($background, 'http') === 0 ? $background : config('site.cdnurl') . $background) : '';
|
||||||
|
$this->view->assign('keeyloginhours', $keeyloginhours);
|
||||||
$this->view->assign('background', $background);
|
$this->view->assign('background', $background);
|
||||||
$this->view->assign('title', __('Login'));
|
$this->view->assign('title', __('Login'));
|
||||||
Hook::listen("admin_login_init", $this->request);
|
Hook::listen("admin_login_init", $this->request);
|
||||||
|
|
@ -106,13 +123,19 @@ class Index extends Backend
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 注销登录
|
* 退出登录
|
||||||
*/
|
*/
|
||||||
public function logout()
|
public function logout()
|
||||||
{
|
{
|
||||||
$this->auth->logout();
|
if ($this->request->isPost()) {
|
||||||
Hook::listen("admin_logout_after", $this->request);
|
$this->auth->logout();
|
||||||
$this->success(__('Logout successful'), 'index/login');
|
Hook::listen("admin_logout_after", $this->request);
|
||||||
|
$this->success(__('Logout successful'), 'index/login');
|
||||||
|
}
|
||||||
|
$html = "<form id='logout_submit' name='logout_submit' action='' method='post'>" . token() . "<input type='submit' value='ok' style='display:none;'></form>";
|
||||||
|
$html .= "<script>document.forms['logout_submit'].submit();</script>";
|
||||||
|
|
||||||
|
return $html;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,17 +7,24 @@ use app\admin\model\AuthGroupAccess;
|
||||||
use app\common\controller\Backend;
|
use app\common\controller\Backend;
|
||||||
use fast\Random;
|
use fast\Random;
|
||||||
use fast\Tree;
|
use fast\Tree;
|
||||||
|
use think\Db;
|
||||||
|
use think\Validate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 管理员管理
|
* 管理员管理
|
||||||
*
|
*
|
||||||
* @icon fa fa-users
|
* @icon fa fa-users
|
||||||
* @remark 一个管理员可以有多个角色组,左侧的菜单根据管理员所拥有的权限进行生成
|
* @remark 一个管理员可以有多个角色组,左侧的菜单根据管理员所拥有的权限进行生成
|
||||||
*/
|
*/
|
||||||
class Admin extends Backend
|
class Admin extends Backend
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \app\admin\model\Admin
|
||||||
|
*/
|
||||||
protected $model = null;
|
protected $model = null;
|
||||||
|
protected $selectpageFields = 'id,username,nickname,avatar';
|
||||||
|
protected $searchFields = 'id,username,nickname';
|
||||||
protected $childrenGroupIds = [];
|
protected $childrenGroupIds = [];
|
||||||
protected $childrenAdminIds = [];
|
protected $childrenAdminIds = [];
|
||||||
|
|
||||||
|
|
@ -26,31 +33,25 @@ class Admin extends Backend
|
||||||
parent::_initialize();
|
parent::_initialize();
|
||||||
$this->model = model('Admin');
|
$this->model = model('Admin');
|
||||||
|
|
||||||
$this->childrenAdminIds = $this->auth->getChildrenAdminIds(true);
|
$this->childrenAdminIds = $this->auth->getChildrenAdminIds($this->auth->isSuperAdmin());
|
||||||
$this->childrenGroupIds = $this->auth->getChildrenGroupIds(true);
|
$this->childrenGroupIds = $this->auth->getChildrenGroupIds($this->auth->isSuperAdmin());
|
||||||
|
|
||||||
$groupList = collection(AuthGroup::where('id', 'in', $this->childrenGroupIds)->select())->toArray();
|
$groupList = collection(AuthGroup::where('id', 'in', $this->childrenGroupIds)->select())->toArray();
|
||||||
|
|
||||||
Tree::instance()->init($groupList);
|
Tree::instance()->init($groupList);
|
||||||
$groupdata = [];
|
$groupdata = [];
|
||||||
if ($this->auth->isSuperAdmin())
|
if ($this->auth->isSuperAdmin()) {
|
||||||
{
|
|
||||||
$result = Tree::instance()->getTreeList(Tree::instance()->getTreeArray(0));
|
$result = Tree::instance()->getTreeList(Tree::instance()->getTreeArray(0));
|
||||||
foreach ($result as $k => $v)
|
foreach ($result as $k => $v) {
|
||||||
{
|
|
||||||
$groupdata[$v['id']] = $v['name'];
|
$groupdata[$v['id']] = $v['name'];
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$result = [];
|
$result = [];
|
||||||
$groups = $this->auth->getGroups();
|
$groups = $this->auth->getGroups();
|
||||||
foreach ($groups as $m => $n)
|
foreach ($groups as $m => $n) {
|
||||||
{
|
|
||||||
$childlist = Tree::instance()->getTreeList(Tree::instance()->getTreeArray($n['id']));
|
$childlist = Tree::instance()->getTreeList(Tree::instance()->getTreeArray($n['id']));
|
||||||
$temp = [];
|
$temp = [];
|
||||||
foreach ($childlist as $k => $v)
|
foreach ($childlist as $k => $v) {
|
||||||
{
|
|
||||||
$temp[$v['id']] = $v['name'];
|
$temp[$v['id']] = $v['name'];
|
||||||
}
|
}
|
||||||
$result[__($n['name'])] = $temp;
|
$result[__($n['name'])] = $temp;
|
||||||
|
|
@ -67,53 +68,46 @@ class Admin extends Backend
|
||||||
*/
|
*/
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
if ($this->request->isAjax())
|
//设置过滤方法
|
||||||
{
|
$this->request->filter(['strip_tags', 'trim']);
|
||||||
|
if ($this->request->isAjax()) {
|
||||||
//如果发送的来源是Selectpage,则转发到Selectpage
|
//如果发送的来源是Selectpage,则转发到Selectpage
|
||||||
if ($this->request->request('keyField'))
|
if ($this->request->request('keyField')) {
|
||||||
{
|
|
||||||
return $this->selectpage();
|
return $this->selectpage();
|
||||||
}
|
}
|
||||||
$childrenGroupIds = $this->childrenGroupIds;
|
$childrenGroupIds = $this->childrenGroupIds;
|
||||||
$groupName = AuthGroup::where('id', 'in', $childrenGroupIds)
|
$groupName = AuthGroup::where('id', 'in', $childrenGroupIds)
|
||||||
->column('id,name');
|
->column('id,name');
|
||||||
$authGroupList = AuthGroupAccess::where('group_id', 'in', $childrenGroupIds)
|
$authGroupList = AuthGroupAccess::where('group_id', 'in', $childrenGroupIds)
|
||||||
->field('uid,group_id')
|
->field('uid,group_id')
|
||||||
->select();
|
->select();
|
||||||
|
|
||||||
$adminGroupName = [];
|
$adminGroupName = [];
|
||||||
foreach ($authGroupList as $k => $v)
|
foreach ($authGroupList as $k => $v) {
|
||||||
{
|
if (isset($groupName[$v['group_id']])) {
|
||||||
if (isset($groupName[$v['group_id']]))
|
|
||||||
$adminGroupName[$v['uid']][$v['group_id']] = $groupName[$v['group_id']];
|
$adminGroupName[$v['uid']][$v['group_id']] = $groupName[$v['group_id']];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$groups = $this->auth->getGroups();
|
$groups = $this->auth->getGroups();
|
||||||
foreach ($groups as $m => $n)
|
foreach ($groups as $m => $n) {
|
||||||
{
|
|
||||||
$adminGroupName[$this->auth->id][$n['id']] = $n['name'];
|
$adminGroupName[$this->auth->id][$n['id']] = $n['name'];
|
||||||
}
|
}
|
||||||
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
|
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
|
||||||
$total = $this->model
|
|
||||||
->where($where)
|
|
||||||
->where('id', 'in', $this->childrenAdminIds)
|
|
||||||
->order($sort, $order)
|
|
||||||
->count();
|
|
||||||
|
|
||||||
$list = $this->model
|
$list = $this->model
|
||||||
->where($where)
|
->where($where)
|
||||||
->where('id', 'in', $this->childrenAdminIds)
|
->where('id', 'in', $this->childrenAdminIds)
|
||||||
->field(['password', 'salt', 'token'], true)
|
->field(['password', 'salt', 'token'], true)
|
||||||
->order($sort, $order)
|
->order($sort, $order)
|
||||||
->limit($offset, $limit)
|
->paginate($limit);
|
||||||
->select();
|
|
||||||
foreach ($list as $k => &$v)
|
foreach ($list as $k => &$v) {
|
||||||
{
|
|
||||||
$groups = isset($adminGroupName[$v['id']]) ? $adminGroupName[$v['id']] : [];
|
$groups = isset($adminGroupName[$v['id']]) ? $adminGroupName[$v['id']] : [];
|
||||||
$v['groups'] = implode(',', array_keys($groups));
|
$v['groups'] = implode(',', array_keys($groups));
|
||||||
$v['groups_text'] = implode(',', array_values($groups));
|
$v['groups_text'] = implode(',', array_values($groups));
|
||||||
}
|
}
|
||||||
unset($v);
|
unset($v);
|
||||||
$result = array("total" => $total, "rows" => $list);
|
$result = array("total" => $list->total(), "rows" => $list->items());
|
||||||
|
|
||||||
return json($result);
|
return json($result);
|
||||||
}
|
}
|
||||||
|
|
@ -125,32 +119,43 @@ class Admin extends Backend
|
||||||
*/
|
*/
|
||||||
public function add()
|
public function add()
|
||||||
{
|
{
|
||||||
if ($this->request->isPost())
|
if ($this->request->isPost()) {
|
||||||
{
|
$this->token();
|
||||||
$params = $this->request->post("row/a");
|
$params = $this->request->post("row/a");
|
||||||
if ($params)
|
if ($params) {
|
||||||
{
|
Db::startTrans();
|
||||||
$params['salt'] = Random::alnum();
|
try {
|
||||||
$params['password'] = md5(md5($params['password']) . $params['salt']);
|
if (!Validate::is($params['password'], '\S{6,30}')) {
|
||||||
$params['avatar'] = '/assets/img/avatar.png'; //设置新管理员默认头像。
|
exception(__("Please input correct password"));
|
||||||
$result = $this->model->validate('Admin.add')->save($params);
|
}
|
||||||
if ($result === false)
|
$params['salt'] = Random::alnum();
|
||||||
{
|
$params['password'] = $this->auth->getEncryptPassword($params['password'], $params['salt']);
|
||||||
$this->error($this->model->getError());
|
$params['avatar'] = '/assets/img/avatar.png'; //设置新管理员默认头像。
|
||||||
}
|
$result = $this->model->validate('Admin.add')->save($params);
|
||||||
$group = $this->request->post("group/a");
|
if ($result === false) {
|
||||||
|
exception($this->model->getError());
|
||||||
|
}
|
||||||
|
$group = $this->request->post("group/a");
|
||||||
|
|
||||||
//过滤不允许的组别,避免越权
|
//过滤不允许的组别,避免越权
|
||||||
$group = array_intersect($this->childrenGroupIds, $group);
|
$group = array_intersect($this->childrenGroupIds, $group);
|
||||||
$dataset = [];
|
if (!$group) {
|
||||||
foreach ($group as $value)
|
exception(__('The parent group exceeds permission limit'));
|
||||||
{
|
}
|
||||||
$dataset[] = ['uid' => $this->model->id, 'group_id' => $value];
|
|
||||||
|
$dataset = [];
|
||||||
|
foreach ($group as $value) {
|
||||||
|
$dataset[] = ['uid' => $this->model->id, 'group_id' => $value];
|
||||||
|
}
|
||||||
|
model('AuthGroupAccess')->saveAll($dataset);
|
||||||
|
Db::commit();
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
Db::rollback();
|
||||||
|
$this->error($e->getMessage());
|
||||||
}
|
}
|
||||||
model('AuthGroupAccess')->saveAll($dataset);
|
|
||||||
$this->success();
|
$this->success();
|
||||||
}
|
}
|
||||||
$this->error();
|
$this->error(__('Parameter %s can not be empty', ''));
|
||||||
}
|
}
|
||||||
return $this->view->fetch();
|
return $this->view->fetch();
|
||||||
}
|
}
|
||||||
|
|
@ -158,59 +163,71 @@ class Admin extends Backend
|
||||||
/**
|
/**
|
||||||
* 编辑
|
* 编辑
|
||||||
*/
|
*/
|
||||||
public function edit($ids = NULL)
|
public function edit($ids = null)
|
||||||
{
|
{
|
||||||
$row = $this->model->get(['id' => $ids]);
|
$row = $this->model->get(['id' => $ids]);
|
||||||
if (!$row)
|
if (!$row) {
|
||||||
$this->error(__('No Results were found'));
|
$this->error(__('No Results were found'));
|
||||||
if ($this->request->isPost())
|
}
|
||||||
{
|
if (!in_array($row->id, $this->childrenAdminIds)) {
|
||||||
|
$this->error(__('You have no permission'));
|
||||||
|
}
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$this->token();
|
||||||
$params = $this->request->post("row/a");
|
$params = $this->request->post("row/a");
|
||||||
if ($params)
|
if ($params) {
|
||||||
{
|
Db::startTrans();
|
||||||
if ($params['password'])
|
try {
|
||||||
{
|
if ($params['password']) {
|
||||||
$params['salt'] = Random::alnum();
|
if (!Validate::is($params['password'], '\S{6,30}')) {
|
||||||
$params['password'] = md5(md5($params['password']) . $params['salt']);
|
exception(__("Please input correct password"));
|
||||||
}
|
}
|
||||||
else
|
$params['salt'] = Random::alnum();
|
||||||
{
|
$params['password'] = $this->auth->getEncryptPassword($params['password'], $params['salt']);
|
||||||
unset($params['password'], $params['salt']);
|
} else {
|
||||||
}
|
unset($params['password'], $params['salt']);
|
||||||
//这里需要针对username和email做唯一验证
|
}
|
||||||
$adminValidate = \think\Loader::validate('Admin');
|
//这里需要针对username和email做唯一验证
|
||||||
$adminValidate->rule([
|
$adminValidate = \think\Loader::validate('Admin');
|
||||||
'username' => 'require|max:50|unique:admin,username,' . $row->id,
|
$adminValidate->rule([
|
||||||
'email' => 'require|email|unique:admin,email,' . $row->id
|
'username' => 'require|regex:\w{3,30}|unique:admin,username,' . $row->id,
|
||||||
]);
|
'email' => 'require|email|unique:admin,email,' . $row->id,
|
||||||
$result = $row->validate('Admin.edit')->save($params);
|
'mobile' => 'regex:1[3-9]\d{9}|unique:admin,mobile,' . $row->id,
|
||||||
if ($result === false)
|
'password' => 'regex:\S{32}',
|
||||||
{
|
]);
|
||||||
$this->error($row->getError());
|
$result = $row->validate('Admin.edit')->save($params);
|
||||||
}
|
if ($result === false) {
|
||||||
|
exception($row->getError());
|
||||||
|
}
|
||||||
|
|
||||||
// 先移除所有权限
|
// 先移除所有权限
|
||||||
model('AuthGroupAccess')->where('uid', $row->id)->delete();
|
model('AuthGroupAccess')->where('uid', $row->id)->delete();
|
||||||
|
|
||||||
$group = $this->request->post("group/a");
|
$group = $this->request->post("group/a");
|
||||||
|
|
||||||
// 过滤不允许的组别,避免越权
|
// 过滤不允许的组别,避免越权
|
||||||
$group = array_intersect($this->childrenGroupIds, $group);
|
$group = array_intersect($this->childrenGroupIds, $group);
|
||||||
|
if (!$group) {
|
||||||
|
exception(__('The parent group exceeds permission limit'));
|
||||||
|
}
|
||||||
|
|
||||||
$dataset = [];
|
$dataset = [];
|
||||||
foreach ($group as $value)
|
foreach ($group as $value) {
|
||||||
{
|
$dataset[] = ['uid' => $row->id, 'group_id' => $value];
|
||||||
$dataset[] = ['uid' => $row->id, 'group_id' => $value];
|
}
|
||||||
|
model('AuthGroupAccess')->saveAll($dataset);
|
||||||
|
Db::commit();
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
Db::rollback();
|
||||||
|
$this->error($e->getMessage());
|
||||||
}
|
}
|
||||||
model('AuthGroupAccess')->saveAll($dataset);
|
|
||||||
$this->success();
|
$this->success();
|
||||||
}
|
}
|
||||||
$this->error();
|
$this->error(__('Parameter %s can not be empty', ''));
|
||||||
}
|
}
|
||||||
$grouplist = $this->auth->getGroups($row['id']);
|
$grouplist = $this->auth->getGroups($row['id']);
|
||||||
$groupids = [];
|
$groupids = [];
|
||||||
foreach ($grouplist as $k => $v)
|
foreach ($grouplist as $k => $v) {
|
||||||
{
|
|
||||||
$groupids[] = $v['id'];
|
$groupids[] = $v['id'];
|
||||||
}
|
}
|
||||||
$this->view->assign("row", $row);
|
$this->view->assign("row", $row);
|
||||||
|
|
@ -223,30 +240,39 @@ class Admin extends Backend
|
||||||
*/
|
*/
|
||||||
public function del($ids = "")
|
public function del($ids = "")
|
||||||
{
|
{
|
||||||
if ($ids)
|
if (!$this->request->isPost()) {
|
||||||
{
|
$this->error(__("Invalid parameters"));
|
||||||
|
}
|
||||||
|
$ids = $ids ? $ids : $this->request->post("ids");
|
||||||
|
if ($ids) {
|
||||||
|
$ids = array_intersect($this->childrenAdminIds, array_filter(explode(',', $ids)));
|
||||||
// 避免越权删除管理员
|
// 避免越权删除管理员
|
||||||
$childrenGroupIds = $this->childrenGroupIds;
|
$childrenGroupIds = $this->childrenGroupIds;
|
||||||
$adminList = $this->model->where('id', 'in', $ids)->where('id', 'in', function($query) use($childrenGroupIds) {
|
$adminList = $this->model->where('id', 'in', $ids)->where('id', 'in', function ($query) use ($childrenGroupIds) {
|
||||||
$query->name('auth_group_access')->where('group_id', 'in', $childrenGroupIds)->field('uid');
|
$query->name('auth_group_access')->where('group_id', 'in', $childrenGroupIds)->field('uid');
|
||||||
})->select();
|
})->select();
|
||||||
if ($adminList)
|
if ($adminList) {
|
||||||
{
|
|
||||||
$deleteIds = [];
|
$deleteIds = [];
|
||||||
foreach ($adminList as $k => $v)
|
foreach ($adminList as $k => $v) {
|
||||||
{
|
|
||||||
$deleteIds[] = $v->id;
|
$deleteIds[] = $v->id;
|
||||||
}
|
}
|
||||||
$deleteIds = array_diff($deleteIds, [$this->auth->id]);
|
$deleteIds = array_values(array_diff($deleteIds, [$this->auth->id]));
|
||||||
if ($deleteIds)
|
if ($deleteIds) {
|
||||||
{
|
Db::startTrans();
|
||||||
$this->model->destroy($deleteIds);
|
try {
|
||||||
model('AuthGroupAccess')->where('uid', 'in', $deleteIds)->delete();
|
$this->model->destroy($deleteIds);
|
||||||
|
model('AuthGroupAccess')->where('uid', 'in', $deleteIds)->delete();
|
||||||
|
Db::commit();
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
Db::rollback();
|
||||||
|
$this->error($e->getMessage());
|
||||||
|
}
|
||||||
$this->success();
|
$this->success();
|
||||||
}
|
}
|
||||||
|
$this->error(__('No rows were deleted'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->error();
|
$this->error(__('You have no permission'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -262,11 +288,10 @@ class Admin extends Backend
|
||||||
/**
|
/**
|
||||||
* 下拉搜索
|
* 下拉搜索
|
||||||
*/
|
*/
|
||||||
protected function selectpage()
|
public function selectpage()
|
||||||
{
|
{
|
||||||
$this->dataLimit = 'auth';
|
$this->dataLimit = 'auth';
|
||||||
$this->dataLimitField = 'id';
|
$this->dataLimitField = 'id';
|
||||||
return parent::selectpage();
|
return parent::selectpage();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,12 +8,15 @@ use app\common\controller\Backend;
|
||||||
/**
|
/**
|
||||||
* 管理员日志
|
* 管理员日志
|
||||||
*
|
*
|
||||||
* @icon fa fa-users
|
* @icon fa fa-users
|
||||||
* @remark 管理员可以查看自己所拥有的权限的管理员日志
|
* @remark 管理员可以查看自己所拥有的权限的管理员日志
|
||||||
*/
|
*/
|
||||||
class Adminlog extends Backend
|
class Adminlog extends Backend
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \app\admin\model\AdminLog
|
||||||
|
*/
|
||||||
protected $model = null;
|
protected $model = null;
|
||||||
protected $childrenGroupIds = [];
|
protected $childrenGroupIds = [];
|
||||||
protected $childrenAdminIds = [];
|
protected $childrenAdminIds = [];
|
||||||
|
|
@ -24,10 +27,10 @@ class Adminlog extends Backend
|
||||||
$this->model = model('AdminLog');
|
$this->model = model('AdminLog');
|
||||||
|
|
||||||
$this->childrenAdminIds = $this->auth->getChildrenAdminIds(true);
|
$this->childrenAdminIds = $this->auth->getChildrenAdminIds(true);
|
||||||
$this->childrenGroupIds = $this->auth->getChildrenGroupIds($this->auth->isSuperAdmin() ? true : false);
|
$this->childrenGroupIds = $this->auth->getChildrenGroupIds(true);
|
||||||
|
|
||||||
$groupName = AuthGroup::where('id', 'in', $this->childrenGroupIds)
|
$groupName = AuthGroup::where('id', 'in', $this->childrenGroupIds)
|
||||||
->column('id,name');
|
->column('id,name');
|
||||||
|
|
||||||
$this->view->assign('groupdata', $groupName);
|
$this->view->assign('groupdata', $groupName);
|
||||||
}
|
}
|
||||||
|
|
@ -37,22 +40,24 @@ class Adminlog extends Backend
|
||||||
*/
|
*/
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
if ($this->request->isAjax())
|
//设置过滤方法
|
||||||
{
|
$this->request->filter(['strip_tags', 'trim']);
|
||||||
|
if ($this->request->isAjax()) {
|
||||||
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
|
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
|
||||||
$total = $this->model
|
$isSuperAdmin = $this->auth->isSuperAdmin();
|
||||||
->where($where)
|
$childrenAdminIds = $this->childrenAdminIds;
|
||||||
->where('admin_id', 'in', $this->childrenAdminIds)
|
|
||||||
->order($sort, $order)
|
|
||||||
->count();
|
|
||||||
|
|
||||||
$list = $this->model
|
$list = $this->model
|
||||||
->where($where)
|
->where($where)
|
||||||
->where('admin_id', 'in', $this->childrenAdminIds)
|
->where(function ($query) use ($isSuperAdmin, $childrenAdminIds) {
|
||||||
->order($sort, $order)
|
if (!$isSuperAdmin) {
|
||||||
->limit($offset, $limit)
|
$query->where('admin_id', 'in', $childrenAdminIds);
|
||||||
->select();
|
}
|
||||||
$result = array("total" => $total, "rows" => $list);
|
})
|
||||||
|
->field('content,useragent', true)
|
||||||
|
->order($sort, $order)
|
||||||
|
->paginate($limit);
|
||||||
|
|
||||||
|
$result = array("total" => $list->total(), "rows" => $list->items());
|
||||||
|
|
||||||
return json($result);
|
return json($result);
|
||||||
}
|
}
|
||||||
|
|
@ -65,8 +70,14 @@ class Adminlog extends Backend
|
||||||
public function detail($ids)
|
public function detail($ids)
|
||||||
{
|
{
|
||||||
$row = $this->model->get(['id' => $ids]);
|
$row = $this->model->get(['id' => $ids]);
|
||||||
if (!$row)
|
if (!$row) {
|
||||||
$this->error(__('No Results were found'));
|
$this->error(__('No Results were found'));
|
||||||
|
}
|
||||||
|
if (!$this->auth->isSuperAdmin()) {
|
||||||
|
if (!$row['admin_id'] || !in_array($row['admin_id'], $this->childrenAdminIds)) {
|
||||||
|
$this->error(__('You have no permission'));
|
||||||
|
}
|
||||||
|
}
|
||||||
$this->view->assign("row", $row->toArray());
|
$this->view->assign("row", $row->toArray());
|
||||||
return $this->view->fetch();
|
return $this->view->fetch();
|
||||||
}
|
}
|
||||||
|
|
@ -84,7 +95,7 @@ class Adminlog extends Backend
|
||||||
* 编辑
|
* 编辑
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
public function edit($ids = NULL)
|
public function edit($ids = null)
|
||||||
{
|
{
|
||||||
$this->error();
|
$this->error();
|
||||||
}
|
}
|
||||||
|
|
@ -94,21 +105,26 @@ class Adminlog extends Backend
|
||||||
*/
|
*/
|
||||||
public function del($ids = "")
|
public function del($ids = "")
|
||||||
{
|
{
|
||||||
if ($ids)
|
if (!$this->request->isPost()) {
|
||||||
{
|
$this->error(__("Invalid parameters"));
|
||||||
$childrenGroupIds = $this->childrenGroupIds;
|
}
|
||||||
$adminList = $this->model->where('id', 'in', $ids)->where('admin_id', 'in', function($query) use($childrenGroupIds) {
|
$ids = $ids ? $ids : $this->request->post("ids");
|
||||||
$query->name('auth_group_access')->field('uid');
|
if ($ids) {
|
||||||
})->select();
|
$isSuperAdmin = $this->auth->isSuperAdmin();
|
||||||
if ($adminList)
|
$childrenAdminIds = $this->childrenAdminIds;
|
||||||
{
|
$adminList = $this->model->where('id', 'in', $ids)
|
||||||
|
->where(function ($query) use ($isSuperAdmin, $childrenAdminIds) {
|
||||||
|
if (!$isSuperAdmin) {
|
||||||
|
$query->where('admin_id', 'in', $childrenAdminIds);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
->select();
|
||||||
|
if ($adminList) {
|
||||||
$deleteIds = [];
|
$deleteIds = [];
|
||||||
foreach ($adminList as $k => $v)
|
foreach ($adminList as $k => $v) {
|
||||||
{
|
|
||||||
$deleteIds[] = $v->id;
|
$deleteIds[] = $v->id;
|
||||||
}
|
}
|
||||||
if ($deleteIds)
|
if ($deleteIds) {
|
||||||
{
|
|
||||||
$this->model->destroy($deleteIds);
|
$this->model->destroy($deleteIds);
|
||||||
$this->success();
|
$this->success();
|
||||||
}
|
}
|
||||||
|
|
@ -126,10 +142,5 @@ class Adminlog extends Backend
|
||||||
// 管理员禁止批量操作
|
// 管理员禁止批量操作
|
||||||
$this->error();
|
$this->error();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function selectpage()
|
|
||||||
{
|
|
||||||
return parent::selectpage();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,20 +5,26 @@ namespace app\admin\controller\auth;
|
||||||
use app\admin\model\AuthGroup;
|
use app\admin\model\AuthGroup;
|
||||||
use app\common\controller\Backend;
|
use app\common\controller\Backend;
|
||||||
use fast\Tree;
|
use fast\Tree;
|
||||||
|
use think\Db;
|
||||||
|
use think\Exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 角色组
|
* 角色组
|
||||||
*
|
*
|
||||||
* @icon fa fa-group
|
* @icon fa fa-group
|
||||||
* @remark 角色组可以有多个,角色有上下级层级关系,如果子角色有角色组和管理员的权限则可以派生属于自己组别下级的角色组或管理员
|
* @remark 角色组可以有多个,角色有上下级层级关系,如果子角色有角色组和管理员的权限则可以派生属于自己组别下级的角色组或管理员
|
||||||
*/
|
*/
|
||||||
class Group extends Backend
|
class Group extends Backend
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \app\admin\model\AuthGroup
|
||||||
|
*/
|
||||||
protected $model = null;
|
protected $model = null;
|
||||||
//当前登录管理员所有子组别
|
//当前登录管理员所有子组别
|
||||||
protected $childrenGroupIds = [];
|
protected $childrenGroupIds = [];
|
||||||
//当前组别列表数据
|
//当前组别列表数据
|
||||||
|
protected $grouplist = [];
|
||||||
protected $groupdata = [];
|
protected $groupdata = [];
|
||||||
//无需要权限判断的方法
|
//无需要权限判断的方法
|
||||||
protected $noNeedRight = ['roletree'];
|
protected $noNeedRight = ['roletree'];
|
||||||
|
|
@ -33,25 +39,28 @@ class Group extends Backend
|
||||||
$groupList = collection(AuthGroup::where('id', 'in', $this->childrenGroupIds)->select())->toArray();
|
$groupList = collection(AuthGroup::where('id', 'in', $this->childrenGroupIds)->select())->toArray();
|
||||||
|
|
||||||
Tree::instance()->init($groupList);
|
Tree::instance()->init($groupList);
|
||||||
$result = [];
|
$groupList = [];
|
||||||
if ($this->auth->isSuperAdmin())
|
if ($this->auth->isSuperAdmin()) {
|
||||||
{
|
$groupList = Tree::instance()->getTreeList(Tree::instance()->getTreeArray(0));
|
||||||
$result = Tree::instance()->getTreeList(Tree::instance()->getTreeArray(0));
|
} else {
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$groups = $this->auth->getGroups();
|
$groups = $this->auth->getGroups();
|
||||||
foreach ($groups as $m => $n)
|
$groupIds = [];
|
||||||
{
|
foreach ($groups as $m => $n) {
|
||||||
$result = array_merge($result, Tree::instance()->getTreeList(Tree::instance()->getTreeArray($n['pid'])));
|
if (in_array($n['id'], $groupIds) || in_array($n['pid'], $groupIds)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$groupList = array_merge($groupList, Tree::instance()->getTreeList(Tree::instance()->getTreeArray($n['pid'])));
|
||||||
|
foreach ($groupList as $index => $item) {
|
||||||
|
$groupIds[] = $item['id'];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$groupName = [];
|
$groupName = [];
|
||||||
foreach ($result as $k => $v)
|
foreach ($groupList as $k => $v) {
|
||||||
{
|
|
||||||
$groupName[$v['id']] = $v['name'];
|
$groupName[$v['id']] = $v['name'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->grouplist = $groupList;
|
||||||
$this->groupdata = $groupName;
|
$this->groupdata = $groupName;
|
||||||
$this->assignconfig("admin", ['id' => $this->auth->id, 'group_ids' => $this->auth->getGroupIds()]);
|
$this->assignconfig("admin", ['id' => $this->auth->id, 'group_ids' => $this->auth->getGroupIds()]);
|
||||||
|
|
||||||
|
|
@ -63,24 +72,8 @@ class Group extends Backend
|
||||||
*/
|
*/
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
if ($this->request->isAjax())
|
if ($this->request->isAjax()) {
|
||||||
{
|
$list = $this->grouplist;
|
||||||
$list = AuthGroup::all(array_keys($this->groupdata));
|
|
||||||
$list = collection($list)->toArray();
|
|
||||||
$groupList = [];
|
|
||||||
foreach ($list as $k => $v)
|
|
||||||
{
|
|
||||||
$groupList[$v['id']] = $v;
|
|
||||||
}
|
|
||||||
$list = [];
|
|
||||||
foreach ($this->groupdata as $k => $v)
|
|
||||||
{
|
|
||||||
if (isset($groupList[$k]))
|
|
||||||
{
|
|
||||||
$groupList[$k]['name'] = $v;
|
|
||||||
$list[] = $groupList[$k];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$total = count($list);
|
$total = count($list);
|
||||||
$result = array("total" => $total, "rows" => $list);
|
$result = array("total" => $total, "rows" => $list);
|
||||||
|
|
||||||
|
|
@ -94,17 +87,15 @@ class Group extends Backend
|
||||||
*/
|
*/
|
||||||
public function add()
|
public function add()
|
||||||
{
|
{
|
||||||
if ($this->request->isPost())
|
if ($this->request->isPost()) {
|
||||||
{
|
$this->token();
|
||||||
$params = $this->request->post("row/a", [], 'strip_tags');
|
$params = $this->request->post("row/a", [], 'strip_tags');
|
||||||
$params['rules'] = explode(',', $params['rules']);
|
$params['rules'] = explode(',', $params['rules']);
|
||||||
if (!in_array($params['pid'], $this->childrenGroupIds))
|
if (!in_array($params['pid'], $this->childrenGroupIds)) {
|
||||||
{
|
$this->error(__('The parent group exceeds permission limit'));
|
||||||
$this->error(__('The parent group can not be its own child'));
|
|
||||||
}
|
}
|
||||||
$parentmodel = model("AuthGroup")->get($params['pid']);
|
$parentmodel = model("AuthGroup")->get($params['pid']);
|
||||||
if (!$parentmodel)
|
if (!$parentmodel) {
|
||||||
{
|
|
||||||
$this->error(__('The parent group can not found'));
|
$this->error(__('The parent group can not found'));
|
||||||
}
|
}
|
||||||
// 父级别的规则节点
|
// 父级别的规则节点
|
||||||
|
|
@ -117,8 +108,7 @@ class Group extends Backend
|
||||||
// 如果当前组别不是超级管理员则需要过滤规则节点,不能超当前组别的权限
|
// 如果当前组别不是超级管理员则需要过滤规则节点,不能超当前组别的权限
|
||||||
$rules = in_array('*', $currentrules) ? $rules : array_intersect($currentrules, $rules);
|
$rules = in_array('*', $currentrules) ? $rules : array_intersect($currentrules, $rules);
|
||||||
$params['rules'] = implode(',', $rules);
|
$params['rules'] = implode(',', $rules);
|
||||||
if ($params)
|
if ($params) {
|
||||||
{
|
|
||||||
$this->model->create($params);
|
$this->model->create($params);
|
||||||
$this->success();
|
$this->success();
|
||||||
}
|
}
|
||||||
|
|
@ -130,24 +120,30 @@ class Group extends Backend
|
||||||
/**
|
/**
|
||||||
* 编辑
|
* 编辑
|
||||||
*/
|
*/
|
||||||
public function edit($ids = NULL)
|
public function edit($ids = null)
|
||||||
{
|
{
|
||||||
|
if (!in_array($ids, $this->childrenGroupIds)) {
|
||||||
|
$this->error(__('You have no permission'));
|
||||||
|
}
|
||||||
$row = $this->model->get(['id' => $ids]);
|
$row = $this->model->get(['id' => $ids]);
|
||||||
if (!$row)
|
if (!$row) {
|
||||||
$this->error(__('No Results were found'));
|
$this->error(__('No Results were found'));
|
||||||
if ($this->request->isPost())
|
}
|
||||||
{
|
if ($this->request->isPost()) {
|
||||||
|
$this->token();
|
||||||
$params = $this->request->post("row/a", [], 'strip_tags');
|
$params = $this->request->post("row/a", [], 'strip_tags');
|
||||||
// 父节点不能是它自身的子节点
|
//父节点不能是非权限内节点
|
||||||
if (!in_array($params['pid'], $this->childrenGroupIds))
|
if (!in_array($params['pid'], $this->childrenGroupIds)) {
|
||||||
{
|
$this->error(__('The parent group exceeds permission limit'));
|
||||||
$this->error(__('The parent group can not be its own child'));
|
}
|
||||||
|
// 父节点不能是它自身的子节点或自己本身
|
||||||
|
if (in_array($params['pid'], Tree::instance()->getChildrenIds($row->id, true))) {
|
||||||
|
$this->error(__('The parent group can not be its own child or itself'));
|
||||||
}
|
}
|
||||||
$params['rules'] = explode(',', $params['rules']);
|
$params['rules'] = explode(',', $params['rules']);
|
||||||
|
|
||||||
$parentmodel = model("AuthGroup")->get($params['pid']);
|
$parentmodel = model("AuthGroup")->get($params['pid']);
|
||||||
if (!$parentmodel)
|
if (!$parentmodel) {
|
||||||
{
|
|
||||||
$this->error(__('The parent group can not found'));
|
$this->error(__('The parent group can not found'));
|
||||||
}
|
}
|
||||||
// 父级别的规则节点
|
// 父级别的规则节点
|
||||||
|
|
@ -160,10 +156,23 @@ class Group extends Backend
|
||||||
// 如果当前组别不是超级管理员则需要过滤规则节点,不能超当前组别的权限
|
// 如果当前组别不是超级管理员则需要过滤规则节点,不能超当前组别的权限
|
||||||
$rules = in_array('*', $currentrules) ? $rules : array_intersect($currentrules, $rules);
|
$rules = in_array('*', $currentrules) ? $rules : array_intersect($currentrules, $rules);
|
||||||
$params['rules'] = implode(',', $rules);
|
$params['rules'] = implode(',', $rules);
|
||||||
if ($params)
|
if ($params) {
|
||||||
{
|
Db::startTrans();
|
||||||
$row->save($params);
|
try {
|
||||||
$this->success();
|
$row->save($params);
|
||||||
|
$children_auth_groups = model("AuthGroup")->all(['id' => ['in', implode(',', (Tree::instance()->getChildrenIds($row->id)))]]);
|
||||||
|
$childparams = [];
|
||||||
|
foreach ($children_auth_groups as $key => $children_auth_group) {
|
||||||
|
$childparams[$key]['id'] = $children_auth_group->id;
|
||||||
|
$childparams[$key]['rules'] = implode(',', array_intersect(explode(',', $children_auth_group->rules), $rules));
|
||||||
|
}
|
||||||
|
model("AuthGroup")->saveAll($childparams);
|
||||||
|
Db::commit();
|
||||||
|
$this->success();
|
||||||
|
} catch (Exception $e) {
|
||||||
|
Db::rollback();
|
||||||
|
$this->error($e->getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$this->error();
|
$this->error();
|
||||||
return;
|
return;
|
||||||
|
|
@ -177,11 +186,14 @@ class Group extends Backend
|
||||||
*/
|
*/
|
||||||
public function del($ids = "")
|
public function del($ids = "")
|
||||||
{
|
{
|
||||||
if ($ids)
|
if (!$this->request->isPost()) {
|
||||||
{
|
$this->error(__("Invalid parameters"));
|
||||||
|
}
|
||||||
|
$ids = $ids ? $ids : $this->request->post("ids");
|
||||||
|
if ($ids) {
|
||||||
$ids = explode(',', $ids);
|
$ids = explode(',', $ids);
|
||||||
$grouplist = $this->auth->getGroups();
|
$grouplist = $this->auth->getGroups();
|
||||||
$group_ids = array_map(function($group) {
|
$group_ids = array_map(function ($group) {
|
||||||
return $group['id'];
|
return $group['id'];
|
||||||
}, $grouplist);
|
}, $grouplist);
|
||||||
// 移除掉当前管理员所在组别
|
// 移除掉当前管理员所在组别
|
||||||
|
|
@ -190,30 +202,25 @@ class Group extends Backend
|
||||||
// 循环判断每一个组别是否可删除
|
// 循环判断每一个组别是否可删除
|
||||||
$grouplist = $this->model->where('id', 'in', $ids)->select();
|
$grouplist = $this->model->where('id', 'in', $ids)->select();
|
||||||
$groupaccessmodel = model('AuthGroupAccess');
|
$groupaccessmodel = model('AuthGroupAccess');
|
||||||
foreach ($grouplist as $k => $v)
|
foreach ($grouplist as $k => $v) {
|
||||||
{
|
|
||||||
// 当前组别下有管理员
|
// 当前组别下有管理员
|
||||||
$groupone = $groupaccessmodel->get(['group_id' => $v['id']]);
|
$groupone = $groupaccessmodel->get(['group_id' => $v['id']]);
|
||||||
if ($groupone)
|
if ($groupone) {
|
||||||
{
|
|
||||||
$ids = array_diff($ids, [$v['id']]);
|
$ids = array_diff($ids, [$v['id']]);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// 当前组别下有子组别
|
// 当前组别下有子组别
|
||||||
$groupone = $this->model->get(['pid' => $v['id']]);
|
$groupone = $this->model->get(['pid' => $v['id']]);
|
||||||
if ($groupone)
|
if ($groupone) {
|
||||||
{
|
|
||||||
$ids = array_diff($ids, [$v['id']]);
|
$ids = array_diff($ids, [$v['id']]);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!$ids)
|
if (!$ids) {
|
||||||
{
|
|
||||||
$this->error(__('You can not delete group that contain child group and administrators'));
|
$this->error(__('You can not delete group that contain child group and administrators'));
|
||||||
}
|
}
|
||||||
$count = $this->model->where('id', 'in', $ids)->delete();
|
$count = $this->model->where('id', 'in', $ids)->delete();
|
||||||
if ($count)
|
if ($count) {
|
||||||
{
|
|
||||||
$this->success();
|
$this->success();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -232,7 +239,7 @@ class Group extends Backend
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 读取角色权限树
|
* 读取角色权限树
|
||||||
*
|
*
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
public function roletree()
|
public function roletree()
|
||||||
|
|
@ -243,35 +250,32 @@ class Group extends Backend
|
||||||
$id = $this->request->post("id");
|
$id = $this->request->post("id");
|
||||||
$pid = $this->request->post("pid");
|
$pid = $this->request->post("pid");
|
||||||
$parentGroupModel = $model->get($pid);
|
$parentGroupModel = $model->get($pid);
|
||||||
$currentGroupModel = NULL;
|
$currentGroupModel = null;
|
||||||
if ($id)
|
if ($id) {
|
||||||
{
|
|
||||||
$currentGroupModel = $model->get($id);
|
$currentGroupModel = $model->get($id);
|
||||||
}
|
}
|
||||||
if (($pid || $parentGroupModel) && (!$id || $currentGroupModel))
|
if (($pid || $parentGroupModel) && (!$id || $currentGroupModel)) {
|
||||||
{
|
$id = $id ? $id : null;
|
||||||
$id = $id ? $id : NULL;
|
$ruleList = collection(model('AuthRule')->order('weigh', 'desc')->order('id', 'asc')->select())->toArray();
|
||||||
$ruleList = collection(model('AuthRule')->order('weigh', 'desc')->select())->toArray();
|
|
||||||
//读取父类角色所有节点列表
|
//读取父类角色所有节点列表
|
||||||
$parentRuleList = [];
|
$parentRuleList = [];
|
||||||
if (in_array('*', explode(',', $parentGroupModel->rules)))
|
if (in_array('*', explode(',', $parentGroupModel->rules))) {
|
||||||
{
|
|
||||||
$parentRuleList = $ruleList;
|
$parentRuleList = $ruleList;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$parentRuleIds = explode(',', $parentGroupModel->rules);
|
$parentRuleIds = explode(',', $parentGroupModel->rules);
|
||||||
foreach ($ruleList as $k => $v)
|
foreach ($ruleList as $k => $v) {
|
||||||
{
|
if (in_array($v['id'], $parentRuleIds)) {
|
||||||
if (in_array($v['id'], $parentRuleIds))
|
|
||||||
{
|
|
||||||
$parentRuleList[] = $v;
|
$parentRuleList[] = $v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$ruleTree = new Tree();
|
||||||
|
$groupTree = new Tree();
|
||||||
//当前所有正常规则列表
|
//当前所有正常规则列表
|
||||||
Tree::instance()->init($parentRuleList);
|
$ruleTree->init($parentRuleList);
|
||||||
|
//角色组列表
|
||||||
|
$groupTree->init(collection(model('AuthGroup')->where('id', 'in', $this->childrenGroupIds)->select())->toArray());
|
||||||
|
|
||||||
//读取当前角色下规则ID集合
|
//读取当前角色下规则ID集合
|
||||||
$adminRuleIds = $this->auth->getRuleIds();
|
$adminRuleIds = $this->auth->getRuleIds();
|
||||||
|
|
@ -280,39 +284,34 @@ class Group extends Backend
|
||||||
//当前拥有的规则ID集合
|
//当前拥有的规则ID集合
|
||||||
$currentRuleIds = $id ? explode(',', $currentGroupModel->rules) : [];
|
$currentRuleIds = $id ? explode(',', $currentGroupModel->rules) : [];
|
||||||
|
|
||||||
if (!$id || !in_array($pid, Tree::instance()->getChildrenIds($id, TRUE)))
|
if (!$id || !in_array($pid, $this->childrenGroupIds) || !in_array($pid, $groupTree->getChildrenIds($id, true))) {
|
||||||
{
|
$parentRuleList = $ruleTree->getTreeList($ruleTree->getTreeArray(0), 'name');
|
||||||
$parentRuleList = Tree::instance()->getTreeList(Tree::instance()->getTreeArray(0), 'name');
|
|
||||||
$hasChildrens = [];
|
$hasChildrens = [];
|
||||||
foreach ($parentRuleList as $k => $v)
|
foreach ($parentRuleList as $k => $v) {
|
||||||
{
|
if ($v['haschild']) {
|
||||||
if ($v['haschild'])
|
|
||||||
$hasChildrens[] = $v['id'];
|
$hasChildrens[] = $v['id'];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$parentRuleIds = array_map(function($item) {
|
$parentRuleIds = array_map(function ($item) {
|
||||||
return $item['id'];
|
return $item['id'];
|
||||||
}, $parentRuleList);
|
}, $parentRuleList);
|
||||||
$nodeList = [];
|
$nodeList = [];
|
||||||
foreach ($parentRuleList as $k => $v)
|
foreach ($parentRuleList as $k => $v) {
|
||||||
{
|
if (!$superadmin && !in_array($v['id'], $adminRuleIds)) {
|
||||||
if (!$superadmin && !in_array($v['id'], $adminRuleIds))
|
|
||||||
continue;
|
continue;
|
||||||
if ($v['pid'] && !in_array($v['pid'], $parentRuleIds))
|
}
|
||||||
|
if ($v['pid'] && !in_array($v['pid'], $parentRuleIds)) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
$state = array('selected' => in_array($v['id'], $currentRuleIds) && !in_array($v['id'], $hasChildrens));
|
$state = array('selected' => in_array($v['id'], $currentRuleIds) && !in_array($v['id'], $hasChildrens));
|
||||||
$nodeList[] = array('id' => $v['id'], 'parent' => $v['pid'] ? $v['pid'] : '#', 'text' => __($v['title']), 'type' => 'menu', 'state' => $state);
|
$nodeList[] = array('id' => $v['id'], 'parent' => $v['pid'] ? $v['pid'] : '#', 'text' => __($v['title']), 'type' => 'menu', 'state' => $state);
|
||||||
}
|
}
|
||||||
$this->success('', null, $nodeList);
|
$this->success('', null, $nodeList);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$this->error(__('Can not change the parent to child'));
|
$this->error(__('Can not change the parent to child'));
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$this->error(__('Group not found'));
|
$this->error(__('Group not found'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
namespace app\admin\controller\auth;
|
namespace app\admin\controller\auth;
|
||||||
|
|
||||||
|
use app\admin\model\AuthRule;
|
||||||
use app\common\controller\Backend;
|
use app\common\controller\Backend;
|
||||||
use fast\Tree;
|
use fast\Tree;
|
||||||
use think\Cache;
|
use think\Cache;
|
||||||
|
|
@ -9,12 +10,15 @@ use think\Cache;
|
||||||
/**
|
/**
|
||||||
* 规则管理
|
* 规则管理
|
||||||
*
|
*
|
||||||
* @icon fa fa-list
|
* @icon fa fa-list
|
||||||
* @remark 规则通常对应一个控制器的方法,同时左侧的菜单栏数据也从规则中体现,通常建议通过控制台进行生成规则节点
|
* @remark 规则通常对应一个控制器的方法,同时左侧的菜单栏数据也从规则中体现,通常建议通过控制台进行生成规则节点
|
||||||
*/
|
*/
|
||||||
class Rule extends Backend
|
class Rule extends Backend
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \app\admin\model\AuthRule
|
||||||
|
*/
|
||||||
protected $model = null;
|
protected $model = null;
|
||||||
protected $rulelist = [];
|
protected $rulelist = [];
|
||||||
protected $multiFields = 'ismenu,status';
|
protected $multiFields = 'ismenu,status';
|
||||||
|
|
@ -22,25 +26,29 @@ class Rule extends Backend
|
||||||
public function _initialize()
|
public function _initialize()
|
||||||
{
|
{
|
||||||
parent::_initialize();
|
parent::_initialize();
|
||||||
|
if (!$this->auth->isSuperAdmin()) {
|
||||||
|
$this->error(__('Access is allowed only to the super management group'));
|
||||||
|
}
|
||||||
$this->model = model('AuthRule');
|
$this->model = model('AuthRule');
|
||||||
// 必须将结果集转换为数组
|
// 必须将结果集转换为数组
|
||||||
$ruleList = collection($this->model->order('weigh', 'desc')->select())->toArray();
|
$ruleList = \think\Db::name("auth_rule")->field('type,condition,remark,createtime,updatetime', true)->order('weigh DESC,id ASC')->select();
|
||||||
foreach ($ruleList as $k => &$v)
|
foreach ($ruleList as $k => &$v) {
|
||||||
{
|
|
||||||
$v['title'] = __($v['title']);
|
$v['title'] = __($v['title']);
|
||||||
$v['remark'] = __($v['remark']);
|
|
||||||
}
|
}
|
||||||
unset($v);
|
unset($v);
|
||||||
Tree::instance()->init($ruleList);
|
Tree::instance()->init($ruleList)->icon = [' ', ' ', ' '];
|
||||||
$this->rulelist = Tree::instance()->getTreeList(Tree::instance()->getTreeArray(0), 'title');
|
$this->rulelist = Tree::instance()->getTreeList(Tree::instance()->getTreeArray(0), 'title');
|
||||||
$ruledata = [0 => __('None')];
|
$ruledata = [0 => __('None')];
|
||||||
foreach ($this->rulelist as $k => &$v)
|
foreach ($this->rulelist as $k => &$v) {
|
||||||
{
|
if (!$v['ismenu']) {
|
||||||
if (!$v['ismenu'])
|
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
$ruledata[$v['id']] = $v['title'];
|
$ruledata[$v['id']] = $v['title'];
|
||||||
|
unset($v['spacer']);
|
||||||
}
|
}
|
||||||
|
unset($v);
|
||||||
$this->view->assign('ruledata', $ruledata);
|
$this->view->assign('ruledata', $ruledata);
|
||||||
|
$this->view->assign("menutypeList", $this->model->getMenutypeList());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -48,11 +56,9 @@ class Rule extends Backend
|
||||||
*/
|
*/
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
if ($this->request->isAjax())
|
if ($this->request->isAjax()) {
|
||||||
{
|
|
||||||
$list = $this->rulelist;
|
$list = $this->rulelist;
|
||||||
$total = count($this->rulelist);
|
$total = count($this->rulelist);
|
||||||
|
|
||||||
$result = array("total" => $total, "rows" => $list);
|
$result = array("total" => $total, "rows" => $list);
|
||||||
|
|
||||||
return json($result);
|
return json($result);
|
||||||
|
|
@ -65,18 +71,15 @@ class Rule extends Backend
|
||||||
*/
|
*/
|
||||||
public function add()
|
public function add()
|
||||||
{
|
{
|
||||||
if ($this->request->isPost())
|
if ($this->request->isPost()) {
|
||||||
{
|
$this->token();
|
||||||
$params = $this->request->post("row/a", [], 'strip_tags');
|
$params = $this->request->post("row/a", [], 'strip_tags');
|
||||||
if ($params)
|
if ($params) {
|
||||||
{
|
if (!$params['ismenu'] && !$params['pid']) {
|
||||||
if (!$params['ismenu'] && !$params['pid'])
|
|
||||||
{
|
|
||||||
$this->error(__('The non-menu rule must have parent'));
|
$this->error(__('The non-menu rule must have parent'));
|
||||||
}
|
}
|
||||||
$result = $this->model->validate()->save($params);
|
$result = $this->model->validate()->save($params);
|
||||||
if ($result === FALSE)
|
if ($result === false) {
|
||||||
{
|
|
||||||
$this->error($this->model->getError());
|
$this->error($this->model->getError());
|
||||||
}
|
}
|
||||||
Cache::rm('__menu__');
|
Cache::rm('__menu__');
|
||||||
|
|
@ -90,28 +93,35 @@ class Rule extends Backend
|
||||||
/**
|
/**
|
||||||
* 编辑
|
* 编辑
|
||||||
*/
|
*/
|
||||||
public function edit($ids = NULL)
|
public function edit($ids = null)
|
||||||
{
|
{
|
||||||
$row = $this->model->get(['id' => $ids]);
|
$row = $this->model->get(['id' => $ids]);
|
||||||
if (!$row)
|
if (!$row) {
|
||||||
$this->error(__('No Results were found'));
|
$this->error(__('No Results were found'));
|
||||||
if ($this->request->isPost())
|
}
|
||||||
{
|
if ($this->request->isPost()) {
|
||||||
|
$this->token();
|
||||||
$params = $this->request->post("row/a", [], 'strip_tags');
|
$params = $this->request->post("row/a", [], 'strip_tags');
|
||||||
if ($params)
|
if ($params) {
|
||||||
{
|
if (!$params['ismenu'] && !$params['pid']) {
|
||||||
if (!$params['ismenu'] && !$params['pid'])
|
|
||||||
{
|
|
||||||
$this->error(__('The non-menu rule must have parent'));
|
$this->error(__('The non-menu rule must have parent'));
|
||||||
}
|
}
|
||||||
|
if ($params['pid'] == $row['id']) {
|
||||||
|
$this->error(__('Can not change the parent to self'));
|
||||||
|
}
|
||||||
|
if ($params['pid'] != $row['pid']) {
|
||||||
|
$childrenIds = Tree::instance()->init(collection(AuthRule::select())->toArray())->getChildrenIds($row['id']);
|
||||||
|
if (in_array($params['pid'], $childrenIds)) {
|
||||||
|
$this->error(__('Can not change the parent to child'));
|
||||||
|
}
|
||||||
|
}
|
||||||
//这里需要针对name做唯一验证
|
//这里需要针对name做唯一验证
|
||||||
$ruleValidate = \think\Loader::validate('AuthRule');
|
$ruleValidate = \think\Loader::validate('AuthRule');
|
||||||
$ruleValidate->rule([
|
$ruleValidate->rule([
|
||||||
'name' => 'require|format|unique:AuthRule,name,' . $row->id,
|
'name' => 'require|unique:AuthRule,name,' . $row->id,
|
||||||
]);
|
]);
|
||||||
$result = $row->validate()->save($params);
|
$result = $row->validate()->save($params);
|
||||||
if ($result === FALSE)
|
if ($result === false) {
|
||||||
{
|
|
||||||
$this->error($row->getError());
|
$this->error($row->getError());
|
||||||
}
|
}
|
||||||
Cache::rm('__menu__');
|
Cache::rm('__menu__');
|
||||||
|
|
@ -128,22 +138,22 @@ class Rule extends Backend
|
||||||
*/
|
*/
|
||||||
public function del($ids = "")
|
public function del($ids = "")
|
||||||
{
|
{
|
||||||
if ($ids)
|
if (!$this->request->isPost()) {
|
||||||
{
|
$this->error(__("Invalid parameters"));
|
||||||
|
}
|
||||||
|
$ids = $ids ? $ids : $this->request->post("ids");
|
||||||
|
if ($ids) {
|
||||||
$delIds = [];
|
$delIds = [];
|
||||||
foreach (explode(',', $ids) as $k => $v)
|
foreach (explode(',', $ids) as $k => $v) {
|
||||||
{
|
$delIds = array_merge($delIds, Tree::instance()->getChildrenIds($v, true));
|
||||||
$delIds = array_merge($delIds, Tree::instance()->getChildrenIds($v, TRUE));
|
|
||||||
}
|
}
|
||||||
$delIds = array_unique($delIds);
|
$delIds = array_unique($delIds);
|
||||||
$count = $this->model->where('id', 'in', $delIds)->delete();
|
$count = $this->model->where('id', 'in', $delIds)->delete();
|
||||||
if ($count)
|
if ($count) {
|
||||||
{
|
|
||||||
Cache::rm('__menu__');
|
Cache::rm('__menu__');
|
||||||
$this->success();
|
$this->success();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->error();
|
$this->error();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,18 +7,27 @@ use app\common\controller\Backend;
|
||||||
/**
|
/**
|
||||||
* 附件管理
|
* 附件管理
|
||||||
*
|
*
|
||||||
* @icon fa fa-circle-o
|
* @icon fa fa-circle-o
|
||||||
* @remark 主要用于管理上传到又拍云的数据或上传至本服务的上传数据
|
* @remark 主要用于管理上传到服务器或第三方存储的数据
|
||||||
*/
|
*/
|
||||||
class Attachment extends Backend
|
class Attachment extends Backend
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \app\common\model\Attachment
|
||||||
|
*/
|
||||||
protected $model = null;
|
protected $model = null;
|
||||||
|
|
||||||
|
protected $searchFields = 'id,filename,url';
|
||||||
|
protected $noNeedRight = ['classify'];
|
||||||
|
|
||||||
public function _initialize()
|
public function _initialize()
|
||||||
{
|
{
|
||||||
parent::_initialize();
|
parent::_initialize();
|
||||||
$this->model = model('Attachment');
|
$this->model = model('Attachment');
|
||||||
|
$this->view->assign("mimetypeList", \app\common\model\Attachment::getMimetypeList());
|
||||||
|
$this->view->assign("categoryList", \app\common\model\Attachment::getCategoryList());
|
||||||
|
$this->assignconfig("categoryList", \app\common\model\Attachment::getCategoryList());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -27,27 +36,41 @@ class Attachment extends Backend
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
//设置过滤方法
|
//设置过滤方法
|
||||||
$this->request->filter(['strip_tags']);
|
$this->request->filter(['strip_tags', 'trim']);
|
||||||
if ($this->request->isAjax())
|
if ($this->request->isAjax()) {
|
||||||
{
|
$mimetypeQuery = [];
|
||||||
|
$filter = $this->request->request('filter');
|
||||||
|
$filterArr = (array)json_decode($filter, true);
|
||||||
|
if (isset($filterArr['category']) && $filterArr['category'] == 'unclassed') {
|
||||||
|
$filterArr['category'] = ',unclassed';
|
||||||
|
$this->request->get(['filter' => json_encode(array_diff_key($filterArr, ['category' => '']))]);
|
||||||
|
}
|
||||||
|
if (isset($filterArr['mimetype']) && preg_match("/(\/|\,|\*)/", $filterArr['mimetype'])) {
|
||||||
|
$mimetype = $filterArr['mimetype'];
|
||||||
|
$filterArr = array_diff_key($filterArr, ['mimetype' => '']);
|
||||||
|
$mimetypeQuery = function ($query) use ($mimetype) {
|
||||||
|
$mimetypeArr = array_filter(explode(',', $mimetype));
|
||||||
|
foreach ($mimetypeArr as $index => $item) {
|
||||||
|
$query->whereOr('mimetype', 'like', '%' . str_replace("/*", "/", $item) . '%');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
$this->request->get(['filter' => json_encode($filterArr)]);
|
||||||
|
|
||||||
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
|
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
|
||||||
$total = $this->model
|
|
||||||
->where($where)
|
|
||||||
->order($sort, $order)
|
|
||||||
->count();
|
|
||||||
|
|
||||||
$list = $this->model
|
$list = $this->model
|
||||||
->where($where)
|
->where($mimetypeQuery)
|
||||||
->order($sort, $order)
|
->where($where)
|
||||||
->limit($offset, $limit)
|
->order($sort, $order)
|
||||||
->select();
|
->paginate($limit);
|
||||||
|
|
||||||
$cdnurl = preg_replace("/\/(\w+)\.php$/i", '', $this->request->root());
|
$cdnurl = preg_replace("/\/(\w+)\.php$/i", '', $this->request->root());
|
||||||
foreach ($list as $k => &$v)
|
foreach ($list as $k => &$v) {
|
||||||
{
|
|
||||||
$v['fullurl'] = ($v['storage'] == 'local' ? $cdnurl : $this->view->config['upload']['cdnurl']) . $v['url'];
|
$v['fullurl'] = ($v['storage'] == 'local' ? $cdnurl : $this->view->config['upload']['cdnurl']) . $v['url'];
|
||||||
}
|
}
|
||||||
unset($v);
|
unset($v);
|
||||||
$result = array("total" => $total, "rows" => $list);
|
$result = array("total" => $list->total(), "rows" => $list->items());
|
||||||
|
|
||||||
return json($result);
|
return json($result);
|
||||||
}
|
}
|
||||||
|
|
@ -59,10 +82,12 @@ class Attachment extends Backend
|
||||||
*/
|
*/
|
||||||
public function select()
|
public function select()
|
||||||
{
|
{
|
||||||
if ($this->request->isAjax())
|
if ($this->request->isAjax()) {
|
||||||
{
|
|
||||||
return $this->index();
|
return $this->index();
|
||||||
}
|
}
|
||||||
|
$mimetype = $this->request->get('mimetype', '');
|
||||||
|
$mimetype = substr($mimetype, -1) === '/' ? $mimetype . '*' : $mimetype;
|
||||||
|
$this->view->assign('mimetype', $mimetype);
|
||||||
return $this->view->fetch();
|
return $this->view->fetch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -71,8 +96,7 @@ class Attachment extends Backend
|
||||||
*/
|
*/
|
||||||
public function add()
|
public function add()
|
||||||
{
|
{
|
||||||
if ($this->request->isAjax())
|
if ($this->request->isAjax()) {
|
||||||
{
|
|
||||||
$this->error();
|
$this->error();
|
||||||
}
|
}
|
||||||
return $this->view->fetch();
|
return $this->view->fetch();
|
||||||
|
|
@ -84,18 +108,21 @@ class Attachment extends Backend
|
||||||
*/
|
*/
|
||||||
public function del($ids = "")
|
public function del($ids = "")
|
||||||
{
|
{
|
||||||
if ($ids)
|
if (!$this->request->isPost()) {
|
||||||
{
|
$this->error(__("Invalid parameters"));
|
||||||
\think\Hook::add('upload_delete', function($params) {
|
}
|
||||||
$attachmentFile = ROOT_PATH . '/public' . $params['url'];
|
$ids = $ids ? $ids : $this->request->post("ids");
|
||||||
if (is_file($attachmentFile))
|
if ($ids) {
|
||||||
{
|
\think\Hook::add('upload_delete', function ($params) {
|
||||||
@unlink($attachmentFile);
|
if ($params['storage'] == 'local') {
|
||||||
|
$attachmentFile = ROOT_PATH . '/public' . $params['url'];
|
||||||
|
if (is_file($attachmentFile)) {
|
||||||
|
@unlink($attachmentFile);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$attachmentlist = $this->model->where('id', 'in', $ids)->select();
|
$attachmentlist = $this->model->where('id', 'in', $ids)->select();
|
||||||
foreach ($attachmentlist as $attachment)
|
foreach ($attachmentlist as $attachment) {
|
||||||
{
|
|
||||||
\think\Hook::listen("upload_delete", $attachment);
|
\think\Hook::listen("upload_delete", $attachment);
|
||||||
$attachment->delete();
|
$attachment->delete();
|
||||||
}
|
}
|
||||||
|
|
@ -104,4 +131,30 @@ class Attachment extends Backend
|
||||||
$this->error(__('Parameter %s can not be empty', 'ids'));
|
$this->error(__('Parameter %s can not be empty', 'ids'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 归类
|
||||||
|
*/
|
||||||
|
public function classify()
|
||||||
|
{
|
||||||
|
if (!$this->auth->check('general/attachment/edit')) {
|
||||||
|
\think\Hook::listen('admin_nopermission', $this);
|
||||||
|
$this->error(__('You have no permission'), '');
|
||||||
|
}
|
||||||
|
if (!$this->request->isPost()) {
|
||||||
|
$this->error(__("Invalid parameters"));
|
||||||
|
}
|
||||||
|
$category = $this->request->post('category', '');
|
||||||
|
$ids = $this->request->post('ids');
|
||||||
|
if (!$ids) {
|
||||||
|
$this->error(__('Parameter %s can not be empty', 'ids'));
|
||||||
|
}
|
||||||
|
$categoryList = \app\common\model\Attachment::getCategoryList();
|
||||||
|
if ($category && !isset($categoryList[$category])) {
|
||||||
|
$this->error(__('Category not found'));
|
||||||
|
}
|
||||||
|
$category = $category == 'unclassed' ? '' : $category;
|
||||||
|
\app\common\model\Attachment::where('id', 'in', $ids)->update(['category' => $category]);
|
||||||
|
$this->success();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,24 +5,36 @@ namespace app\admin\controller\general;
|
||||||
use app\common\controller\Backend;
|
use app\common\controller\Backend;
|
||||||
use app\common\library\Email;
|
use app\common\library\Email;
|
||||||
use app\common\model\Config as ConfigModel;
|
use app\common\model\Config as ConfigModel;
|
||||||
|
use think\Cache;
|
||||||
|
use think\Db;
|
||||||
use think\Exception;
|
use think\Exception;
|
||||||
|
use think\Validate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 系统配置
|
* 系统配置
|
||||||
*
|
*
|
||||||
* @icon fa fa-cogs
|
* @icon fa fa-cogs
|
||||||
* @remark 可以在此增改系统的变量和分组,也可以自定义分组和变量,如果需要删除请从数据库中删除
|
* @remark 可以在此增改系统的变量和分组,也可以自定义分组和变量,如果需要删除请从数据库中删除
|
||||||
*/
|
*/
|
||||||
class Config extends Backend
|
class Config extends Backend
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \app\common\model\Config
|
||||||
|
*/
|
||||||
protected $model = null;
|
protected $model = null;
|
||||||
protected $noNeedRight = ['check'];
|
protected $noNeedRight = ['check', 'rulelist', 'selectpage', 'get_fields_list'];
|
||||||
|
|
||||||
public function _initialize()
|
public function _initialize()
|
||||||
{
|
{
|
||||||
parent::_initialize();
|
parent::_initialize();
|
||||||
$this->model = model('Config');
|
// $this->model = model('Config');
|
||||||
|
$this->model = new ConfigModel;
|
||||||
|
ConfigModel::event('before_write', function ($row) {
|
||||||
|
if (isset($row['name']) && $row['name'] == 'name' && preg_match("/fast" . "admin/i", $row['value'])) {
|
||||||
|
throw new Exception(__("Site name incorrect"));
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -47,7 +59,20 @@ class Config extends Backend
|
||||||
if (in_array($value['type'], ['select', 'selects', 'checkbox', 'radio'])) {
|
if (in_array($value['type'], ['select', 'selects', 'checkbox', 'radio'])) {
|
||||||
$value['value'] = explode(',', $value['value']);
|
$value['value'] = explode(',', $value['value']);
|
||||||
}
|
}
|
||||||
$value['content'] = json_decode($value['content'], TRUE);
|
$value['content'] = json_decode($value['content'], true);
|
||||||
|
if (in_array($value['name'], ['categorytype', 'configgroup', 'attachmentcategory'])) {
|
||||||
|
$dictValue = (array)json_decode($value['value'], true);
|
||||||
|
foreach ($dictValue as $index => &$item) {
|
||||||
|
$item = __($item);
|
||||||
|
}
|
||||||
|
unset($item);
|
||||||
|
$value['value'] = json_encode($dictValue, JSON_UNESCAPED_UNICODE);
|
||||||
|
}
|
||||||
|
$value['tip'] = htmlspecialchars($value['tip']);
|
||||||
|
if ($value['name'] == 'cdnurl') {
|
||||||
|
//cdnurl不支持在线修改
|
||||||
|
continue;
|
||||||
|
}
|
||||||
$siteList[$v['group']]['list'][] = $value;
|
$siteList[$v['group']]['list'][] = $value;
|
||||||
}
|
}
|
||||||
$index = 0;
|
$index = 0;
|
||||||
|
|
@ -57,6 +82,7 @@ class Config extends Backend
|
||||||
}
|
}
|
||||||
$this->view->assign('siteList', $siteList);
|
$this->view->assign('siteList', $siteList);
|
||||||
$this->view->assign('typeList', ConfigModel::getTypeList());
|
$this->view->assign('typeList', ConfigModel::getTypeList());
|
||||||
|
$this->view->assign('ruleList', ConfigModel::getRegexList());
|
||||||
$this->view->assign('groupList', ConfigModel::getGroupList());
|
$this->view->assign('groupList', ConfigModel::getGroupList());
|
||||||
return $this->view->fetch();
|
return $this->view->fetch();
|
||||||
}
|
}
|
||||||
|
|
@ -66,32 +92,36 @@ class Config extends Backend
|
||||||
*/
|
*/
|
||||||
public function add()
|
public function add()
|
||||||
{
|
{
|
||||||
|
if (!config('app_debug')) {
|
||||||
|
$this->error(__('Only work at development environment'));
|
||||||
|
}
|
||||||
if ($this->request->isPost()) {
|
if ($this->request->isPost()) {
|
||||||
$params = $this->request->post("row/a");
|
$this->token();
|
||||||
|
$params = $this->request->post("row/a", [], 'trim');
|
||||||
if ($params) {
|
if ($params) {
|
||||||
foreach ($params as $k => &$v) {
|
foreach ($params as $k => &$v) {
|
||||||
$v = is_array($v) ? implode(',', $v) : $v;
|
$v = is_array($v) && $k !== 'setting' ? implode(',', $v) : $v;
|
||||||
|
}
|
||||||
|
if (in_array($params['type'], ['select', 'selects', 'checkbox', 'radio', 'array'])) {
|
||||||
|
$params['content'] = json_encode(ConfigModel::decode($params['content']), JSON_UNESCAPED_UNICODE);
|
||||||
|
} else {
|
||||||
|
$params['content'] = '';
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
if (in_array($params['type'], ['select', 'selects', 'checkbox', 'radio', 'array'])) {
|
|
||||||
$params['content'] = json_encode(ConfigModel::decode($params['content']), JSON_UNESCAPED_UNICODE);
|
|
||||||
} else {
|
|
||||||
$params['content'] = '';
|
|
||||||
}
|
|
||||||
$result = $this->model->create($params);
|
$result = $this->model->create($params);
|
||||||
if ($result !== false) {
|
|
||||||
try {
|
|
||||||
$this->refreshFile();
|
|
||||||
$this->success();
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$this->error($e->getMessage());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$this->error($this->model->getError());
|
|
||||||
}
|
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
$this->error($e->getMessage());
|
$this->error($e->getMessage());
|
||||||
}
|
}
|
||||||
|
if ($result !== false) {
|
||||||
|
try {
|
||||||
|
ConfigModel::refreshFile();
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$this->error($e->getMessage());
|
||||||
|
}
|
||||||
|
$this->success();
|
||||||
|
} else {
|
||||||
|
$this->error($this->model->getError());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$this->error(__('Parameter %s can not be empty', ''));
|
$this->error(__('Parameter %s can not be empty', ''));
|
||||||
}
|
}
|
||||||
|
|
@ -102,10 +132,11 @@ class Config extends Backend
|
||||||
* 编辑
|
* 编辑
|
||||||
* @param null $ids
|
* @param null $ids
|
||||||
*/
|
*/
|
||||||
public function edit($ids = NULL)
|
public function edit($ids = null)
|
||||||
{
|
{
|
||||||
if ($this->request->isPost()) {
|
if ($this->request->isPost()) {
|
||||||
$row = $this->request->post("row/a");
|
$this->token();
|
||||||
|
$row = $this->request->post("row/a", [], 'trim');
|
||||||
if ($row) {
|
if ($row) {
|
||||||
$configList = [];
|
$configList = [];
|
||||||
foreach ($this->model->all() as $v) {
|
foreach ($this->model->all() as $v) {
|
||||||
|
|
@ -120,36 +151,44 @@ class Config extends Backend
|
||||||
$configList[] = $v->toArray();
|
$configList[] = $v->toArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->model->allowField(true)->saveAll($configList);
|
|
||||||
try {
|
try {
|
||||||
$this->refreshFile();
|
$this->model->allowField(true)->saveAll($configList);
|
||||||
$this->success();
|
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
$this->error($e->getMessage());
|
$this->error($e->getMessage());
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
ConfigModel::refreshFile();
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$this->error($e->getMessage());
|
||||||
|
}
|
||||||
|
$this->success();
|
||||||
}
|
}
|
||||||
$this->error(__('Parameter %s can not be empty', ''));
|
$this->error(__('Parameter %s can not be empty', ''));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 刷新配置文件
|
* 删除
|
||||||
|
* @param string $ids
|
||||||
*/
|
*/
|
||||||
protected function refreshFile()
|
public function del($ids = "")
|
||||||
{
|
{
|
||||||
$config = [];
|
if (!config('app_debug')) {
|
||||||
foreach ($this->model->all() as $k => $v) {
|
$this->error(__('Only work at development environment'));
|
||||||
|
}
|
||||||
$value = $v->toArray();
|
$name = $this->request->post('name');
|
||||||
if (in_array($value['type'], ['selects', 'checkbox', 'images', 'files'])) {
|
$config = ConfigModel::getByName($name);
|
||||||
$value['value'] = explode(',', $value['value']);
|
if ($name && $config) {
|
||||||
}
|
try {
|
||||||
if ($value['type'] == 'array') {
|
$config->delete();
|
||||||
$value['value'] = (array)json_decode($value['value'], TRUE);
|
ConfigModel::refreshFile();
|
||||||
}
|
} catch (Exception $e) {
|
||||||
$config[$value['name']] = $value['value'];
|
$this->error($e->getMessage());
|
||||||
|
}
|
||||||
|
$this->success();
|
||||||
|
} else {
|
||||||
|
$this->error(__('Invalid parameters'));
|
||||||
}
|
}
|
||||||
file_put_contents(APP_PATH . 'extra' . DS . 'site.php', '<?php' . "\n\nreturn " . var_export($config, true) . ";");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -160,18 +199,43 @@ class Config extends Backend
|
||||||
{
|
{
|
||||||
$params = $this->request->post("row/a");
|
$params = $this->request->post("row/a");
|
||||||
if ($params) {
|
if ($params) {
|
||||||
|
|
||||||
$config = $this->model->get($params);
|
$config = $this->model->get($params);
|
||||||
if (!$config) {
|
if (!$config) {
|
||||||
return $this->success();
|
$this->success();
|
||||||
} else {
|
} else {
|
||||||
return $this->error(__('Name already exist'));
|
$this->error(__('Name already exist'));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return $this->error(__('Invalid parameters'));
|
$this->error(__('Invalid parameters'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 规则列表
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
public function rulelist()
|
||||||
|
{
|
||||||
|
//主键
|
||||||
|
$primarykey = $this->request->request("keyField");
|
||||||
|
//主键值
|
||||||
|
$keyValue = $this->request->request("keyValue", "");
|
||||||
|
|
||||||
|
$keyValueArr = array_filter(explode(',', $keyValue));
|
||||||
|
$regexList = \app\common\model\Config::getRegexList();
|
||||||
|
$list = [];
|
||||||
|
foreach ($regexList as $k => $v) {
|
||||||
|
if ($keyValueArr) {
|
||||||
|
if (in_array($k, $keyValueArr)) {
|
||||||
|
$list[] = ['id' => $k, 'name' => $v];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$list[] = ['id' => $k, 'name' => $v];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return json(['list' => $list]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发送测试邮件
|
* 发送测试邮件
|
||||||
* @internal
|
* @internal
|
||||||
|
|
@ -179,19 +243,69 @@ class Config extends Backend
|
||||||
public function emailtest()
|
public function emailtest()
|
||||||
{
|
{
|
||||||
$row = $this->request->post('row/a');
|
$row = $this->request->post('row/a');
|
||||||
\think\Config::set('site', array_merge(\think\Config::get('site'), $row));
|
$receiver = $this->request->post("receiver");
|
||||||
$receiver = $this->request->request("receiver");
|
if ($receiver) {
|
||||||
$email = new Email;
|
if (!Validate::is($receiver, "email")) {
|
||||||
$result = $email
|
$this->error(__('Please input correct email'));
|
||||||
->to($receiver)
|
}
|
||||||
->subject(__("This is a test mail"))
|
\think\Config::set('site', array_merge(\think\Config::get('site'), $row));
|
||||||
->message('<div style="min-height:550px; padding: 100px 55px 200px;">' . __('This is a test mail content') . '</div>')
|
$email = new Email;
|
||||||
->send();
|
$result = $email
|
||||||
if ($result) {
|
->to($receiver)
|
||||||
$this->success();
|
->subject(__("This is a test mail", config('site.name')))
|
||||||
|
->message('<div style="min-height:550px; padding: 100px 55px 200px;">' . __('This is a test mail content', config('site.name')) . '</div>')
|
||||||
|
->send();
|
||||||
|
if ($result) {
|
||||||
|
$this->success();
|
||||||
|
} else {
|
||||||
|
$this->error($email->getError());
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$this->error($email->getError());
|
$this->error(__('Invalid parameters'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function selectpage()
|
||||||
|
{
|
||||||
|
$id = $this->request->get("id/d");
|
||||||
|
$config = \app\common\model\Config::get($id);
|
||||||
|
if (!$config) {
|
||||||
|
$this->error(__('Invalid parameters'));
|
||||||
|
}
|
||||||
|
$setting = $config['setting'];
|
||||||
|
//自定义条件
|
||||||
|
$custom = isset($setting['conditions']) ? (array)json_decode($setting['conditions'], true) : [];
|
||||||
|
$custom = array_filter($custom);
|
||||||
|
|
||||||
|
$this->request->request(['showField' => $setting['field'], 'keyField' => $setting['primarykey'], 'custom' => $custom, 'searchField' => [$setting['field'], $setting['primarykey']]]);
|
||||||
|
$this->model = \think\Db::connect()->setTable($setting['table']);
|
||||||
|
return parent::selectpage();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取表列表
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
public function get_table_list()
|
||||||
|
{
|
||||||
|
$tableList = [];
|
||||||
|
$dbname = \think\Config::get('database.database');
|
||||||
|
$tableList = \think\Db::query("SELECT `TABLE_NAME` AS `name`,`TABLE_COMMENT` AS `title` FROM `information_schema`.`TABLES` where `TABLE_SCHEMA` = '{$dbname}';");
|
||||||
|
$this->success('', null, ['tableList' => $tableList]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取表字段列表
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
public function get_fields_list()
|
||||||
|
{
|
||||||
|
$table = $this->request->request('table');
|
||||||
|
$dbname = \think\Config::get('database.database');
|
||||||
|
//从数据库中获取表字段信息
|
||||||
|
$sql = "SELECT `COLUMN_NAME` AS `name`,`COLUMN_COMMENT` AS `title`,`DATA_TYPE` AS `type` FROM `information_schema`.`columns` WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ? ORDER BY ORDINAL_POSITION";
|
||||||
|
//加载主表的列
|
||||||
|
$fieldList = Db::query($sql, [$dbname, $table]);
|
||||||
|
$this->success("", null, ['fieldList' => $fieldList]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ use app\admin\model\Admin;
|
||||||
use app\common\controller\Backend;
|
use app\common\controller\Backend;
|
||||||
use fast\Random;
|
use fast\Random;
|
||||||
use think\Session;
|
use think\Session;
|
||||||
|
use think\Validate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 个人配置
|
* 个人配置
|
||||||
|
|
@ -15,32 +16,26 @@ use think\Session;
|
||||||
class Profile extends Backend
|
class Profile extends Backend
|
||||||
{
|
{
|
||||||
|
|
||||||
|
protected $searchFields = 'id,title';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查看
|
* 查看
|
||||||
*/
|
*/
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
//设置过滤方法
|
//设置过滤方法
|
||||||
$this->request->filter(['strip_tags']);
|
$this->request->filter(['strip_tags', 'trim']);
|
||||||
if ($this->request->isAjax())
|
if ($this->request->isAjax()) {
|
||||||
{
|
$this->model = model('AdminLog');
|
||||||
$model = model('AdminLog');
|
|
||||||
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
|
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
|
||||||
|
|
||||||
$total = $model
|
$list = $this->model
|
||||||
->where($where)
|
->where($where)
|
||||||
->where('admin_id', $this->auth->id)
|
->where('admin_id', $this->auth->id)
|
||||||
->order($sort, $order)
|
->order($sort, $order)
|
||||||
->count();
|
->paginate($limit);
|
||||||
|
|
||||||
$list = $model
|
$result = array("total" => $list->total(), "rows" => $list->items());
|
||||||
->where($where)
|
|
||||||
->where('admin_id', $this->auth->id)
|
|
||||||
->order($sort, $order)
|
|
||||||
->limit($offset, $limit)
|
|
||||||
->select();
|
|
||||||
|
|
||||||
$result = array("total" => $total, "rows" => $list);
|
|
||||||
|
|
||||||
return json($result);
|
return json($result);
|
||||||
}
|
}
|
||||||
|
|
@ -52,27 +47,38 @@ class Profile extends Backend
|
||||||
*/
|
*/
|
||||||
public function update()
|
public function update()
|
||||||
{
|
{
|
||||||
if ($this->request->isPost())
|
if ($this->request->isPost()) {
|
||||||
{
|
$this->token();
|
||||||
$params = $this->request->post("row/a");
|
$params = $this->request->post("row/a");
|
||||||
$params = array_filter(array_intersect_key($params, array_flip(array('email', 'nickname', 'password', 'avatar'))));
|
$params = array_filter(array_intersect_key(
|
||||||
|
$params,
|
||||||
|
array_flip(array('email', 'nickname', 'password', 'avatar'))
|
||||||
|
));
|
||||||
unset($v);
|
unset($v);
|
||||||
if (isset($params['password']))
|
if (!Validate::is($params['email'], "email")) {
|
||||||
{
|
$this->error(__("Please input correct email"));
|
||||||
|
}
|
||||||
|
if (isset($params['password'])) {
|
||||||
|
if (!Validate::is($params['password'], "/^[\S]{6,30}$/")) {
|
||||||
|
$this->error(__("Please input correct password"));
|
||||||
|
}
|
||||||
$params['salt'] = Random::alnum();
|
$params['salt'] = Random::alnum();
|
||||||
$params['password'] = md5(md5($params['password']) . $params['salt']);
|
$params['password'] = md5(md5($params['password']) . $params['salt']);
|
||||||
}
|
}
|
||||||
if ($params)
|
$exist = Admin::where('email', $params['email'])->where('id', '<>', $this->auth->id)->find();
|
||||||
{
|
if ($exist) {
|
||||||
|
$this->error(__("Email already exists"));
|
||||||
|
}
|
||||||
|
if ($params) {
|
||||||
$admin = Admin::get($this->auth->id);
|
$admin = Admin::get($this->auth->id);
|
||||||
$admin->save($params);
|
$admin->save($params);
|
||||||
//因为个人资料面板读取的Session显示,修改自己资料后同时更新Session
|
//因为个人资料面板读取的Session显示,修改自己资料后同时更新Session
|
||||||
Session::set("admin", $admin->toArray());
|
Session::set("admin", $admin->toArray());
|
||||||
|
Session::set("admin.safecode", $this->auth->getEncryptSafecode($admin));
|
||||||
$this->success();
|
$this->success();
|
||||||
}
|
}
|
||||||
$this->error();
|
$this->error();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ class Group extends Backend
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UserGroup模型对象
|
* @var \app\admin\model\UserGroup
|
||||||
*/
|
*/
|
||||||
protected $model = null;
|
protected $model = null;
|
||||||
|
|
||||||
|
|
@ -26,16 +26,23 @@ class Group extends Backend
|
||||||
|
|
||||||
public function add()
|
public function add()
|
||||||
{
|
{
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$this->token();
|
||||||
|
}
|
||||||
$nodeList = \app\admin\model\UserRule::getTreeList();
|
$nodeList = \app\admin\model\UserRule::getTreeList();
|
||||||
$this->assign("nodeList", $nodeList);
|
$this->assign("nodeList", $nodeList);
|
||||||
return parent::add();
|
return parent::add();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function edit($ids = NULL)
|
public function edit($ids = null)
|
||||||
{
|
{
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$this->token();
|
||||||
|
}
|
||||||
$row = $this->model->get($ids);
|
$row = $this->model->get($ids);
|
||||||
if (!$row)
|
if (!$row) {
|
||||||
$this->error(__('No Results were found'));
|
$this->error(__('No Results were found'));
|
||||||
|
}
|
||||||
$rules = explode(',', $row['rules']);
|
$rules = explode(',', $row['rules']);
|
||||||
$nodeList = \app\admin\model\UserRule::getTreeList($rules);
|
$nodeList = \app\admin\model\UserRule::getTreeList($rules);
|
||||||
$this->assign("nodeList", $nodeList);
|
$this->assign("nodeList", $nodeList);
|
||||||
|
|
|
||||||
|
|
@ -14,10 +14,11 @@ class Rule extends Backend
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UserRule模型对象
|
* @var \app\admin\model\UserRule
|
||||||
*/
|
*/
|
||||||
protected $model = null;
|
protected $model = null;
|
||||||
protected $rulelist = [];
|
protected $rulelist = [];
|
||||||
|
protected $multiFields = 'ismenu,status';
|
||||||
|
|
||||||
public function _initialize()
|
public function _initialize()
|
||||||
{
|
{
|
||||||
|
|
@ -26,19 +27,18 @@ class Rule extends Backend
|
||||||
$this->view->assign("statusList", $this->model->getStatusList());
|
$this->view->assign("statusList", $this->model->getStatusList());
|
||||||
// 必须将结果集转换为数组
|
// 必须将结果集转换为数组
|
||||||
$ruleList = collection($this->model->order('weigh', 'desc')->select())->toArray();
|
$ruleList = collection($this->model->order('weigh', 'desc')->select())->toArray();
|
||||||
foreach ($ruleList as $k => &$v)
|
foreach ($ruleList as $k => &$v) {
|
||||||
{
|
|
||||||
$v['title'] = __($v['title']);
|
$v['title'] = __($v['title']);
|
||||||
$v['remark'] = __($v['remark']);
|
$v['remark'] = __($v['remark']);
|
||||||
}
|
}
|
||||||
unset($v);
|
unset($v);
|
||||||
Tree::instance()->init($ruleList);
|
Tree::instance()->init($ruleList)->icon = [' ', ' ', ' '];
|
||||||
$this->rulelist = Tree::instance()->getTreeList(Tree::instance()->getTreeArray(0), 'title');
|
$this->rulelist = Tree::instance()->getTreeList(Tree::instance()->getTreeArray(0), 'title');
|
||||||
$ruledata = [0 => __('None')];
|
$ruledata = [0 => __('None')];
|
||||||
foreach ($this->rulelist as $k => &$v)
|
foreach ($this->rulelist as $k => &$v) {
|
||||||
{
|
if (!$v['ismenu']) {
|
||||||
if (!$v['ismenu'])
|
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
$ruledata[$v['id']] = $v['title'];
|
$ruledata[$v['id']] = $v['title'];
|
||||||
}
|
}
|
||||||
$this->view->assign('ruledata', $ruledata);
|
$this->view->assign('ruledata', $ruledata);
|
||||||
|
|
@ -49,8 +49,7 @@ class Rule extends Backend
|
||||||
*/
|
*/
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
if ($this->request->isAjax())
|
if ($this->request->isAjax()) {
|
||||||
{
|
|
||||||
$list = $this->rulelist;
|
$list = $this->rulelist;
|
||||||
$total = count($this->rulelist);
|
$total = count($this->rulelist);
|
||||||
|
|
||||||
|
|
@ -61,22 +60,45 @@ class Rule extends Backend
|
||||||
return $this->view->fetch();
|
return $this->view->fetch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加
|
||||||
|
*/
|
||||||
|
public function add()
|
||||||
|
{
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$this->token();
|
||||||
|
}
|
||||||
|
return parent::add();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑
|
||||||
|
*/
|
||||||
|
public function edit($ids = null)
|
||||||
|
{
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$this->token();
|
||||||
|
}
|
||||||
|
return parent::edit($ids);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除
|
* 删除
|
||||||
*/
|
*/
|
||||||
public function del($ids = "")
|
public function del($ids = "")
|
||||||
{
|
{
|
||||||
if ($ids)
|
if (!$this->request->isPost()) {
|
||||||
{
|
$this->error(__("Invalid parameters"));
|
||||||
|
}
|
||||||
|
$ids = $ids ? $ids : $this->request->post("ids");
|
||||||
|
if ($ids) {
|
||||||
$delIds = [];
|
$delIds = [];
|
||||||
foreach (explode(',', $ids) as $k => $v)
|
foreach (explode(',', $ids) as $k => $v) {
|
||||||
{
|
$delIds = array_merge($delIds, Tree::instance()->getChildrenIds($v, true));
|
||||||
$delIds = array_merge($delIds, Tree::instance()->getChildrenIds($v, TRUE));
|
|
||||||
}
|
}
|
||||||
$delIds = array_unique($delIds);
|
$delIds = array_unique($delIds);
|
||||||
$count = $this->model->where('id', 'in', $delIds)->delete();
|
$count = $this->model->where('id', 'in', $delIds)->delete();
|
||||||
if ($count)
|
if ($count) {
|
||||||
{
|
|
||||||
$this->success();
|
$this->success();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
namespace app\admin\controller\user;
|
namespace app\admin\controller\user;
|
||||||
|
|
||||||
use app\common\controller\Backend;
|
use app\common\controller\Backend;
|
||||||
|
use app\common\library\Auth;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 会员管理
|
* 会员管理
|
||||||
|
|
@ -13,16 +14,17 @@ class User extends Backend
|
||||||
{
|
{
|
||||||
|
|
||||||
protected $relationSearch = true;
|
protected $relationSearch = true;
|
||||||
|
protected $searchFields = 'id,username,nickname';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User模型对象
|
* @var \app\admin\model\User
|
||||||
*/
|
*/
|
||||||
protected $model = null;
|
protected $model = null;
|
||||||
|
|
||||||
public function _initialize()
|
public function _initialize()
|
||||||
{
|
{
|
||||||
parent::_initialize();
|
parent::_initialize();
|
||||||
$this->model = model('User');
|
$this->model = new \app\admin\model\User;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -31,47 +33,73 @@ class User extends Backend
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
//设置过滤方法
|
//设置过滤方法
|
||||||
$this->request->filter(['strip_tags']);
|
$this->request->filter(['strip_tags', 'trim']);
|
||||||
if ($this->request->isAjax())
|
if ($this->request->isAjax()) {
|
||||||
{
|
|
||||||
//如果发送的来源是Selectpage,则转发到Selectpage
|
//如果发送的来源是Selectpage,则转发到Selectpage
|
||||||
if ($this->request->request('keyField'))
|
if ($this->request->request('keyField')) {
|
||||||
{
|
|
||||||
return $this->selectpage();
|
return $this->selectpage();
|
||||||
}
|
}
|
||||||
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
|
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
|
||||||
$total = $this->model
|
|
||||||
->with('group')
|
|
||||||
->where($where)
|
|
||||||
->order($sort, $order)
|
|
||||||
->count();
|
|
||||||
$list = $this->model
|
$list = $this->model
|
||||||
->with('group')
|
->with('group')
|
||||||
->where($where)
|
->where($where)
|
||||||
->order($sort, $order)
|
->order($sort, $order)
|
||||||
->limit($offset, $limit)
|
->paginate($limit);
|
||||||
->select();
|
foreach ($list as $k => $v) {
|
||||||
foreach ($list as $k => $v)
|
$v->avatar = $v->avatar ? cdnurl($v->avatar, true) : letter_avatar($v->nickname);
|
||||||
{
|
|
||||||
$v->hidden(['password', 'salt']);
|
$v->hidden(['password', 'salt']);
|
||||||
}
|
}
|
||||||
$result = array("total" => $total, "rows" => $list);
|
$result = array("total" => $list->total(), "rows" => $list->items());
|
||||||
|
|
||||||
return json($result);
|
return json($result);
|
||||||
}
|
}
|
||||||
return $this->view->fetch();
|
return $this->view->fetch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加
|
||||||
|
*/
|
||||||
|
public function add()
|
||||||
|
{
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$this->token();
|
||||||
|
}
|
||||||
|
return parent::add();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 编辑
|
* 编辑
|
||||||
*/
|
*/
|
||||||
public function edit($ids = NULL)
|
public function edit($ids = null)
|
||||||
{
|
{
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$this->token();
|
||||||
|
}
|
||||||
$row = $this->model->get($ids);
|
$row = $this->model->get($ids);
|
||||||
if (!$row)
|
$this->modelValidate = true;
|
||||||
|
if (!$row) {
|
||||||
$this->error(__('No Results were found'));
|
$this->error(__('No Results were found'));
|
||||||
|
}
|
||||||
$this->view->assign('groupList', build_select('row[group_id]', \app\admin\model\UserGroup::column('id,name'), $row['group_id'], ['class' => 'form-control selectpicker']));
|
$this->view->assign('groupList', build_select('row[group_id]', \app\admin\model\UserGroup::column('id,name'), $row['group_id'], ['class' => 'form-control selectpicker']));
|
||||||
return parent::edit($ids);
|
return parent::edit($ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除
|
||||||
|
*/
|
||||||
|
public function del($ids = "")
|
||||||
|
{
|
||||||
|
if (!$this->request->isPost()) {
|
||||||
|
$this->error(__("Invalid parameters"));
|
||||||
|
}
|
||||||
|
$ids = $ids ? $ids : $this->request->post("ids");
|
||||||
|
$row = $this->model->get($ids);
|
||||||
|
$this->modelValidate = true;
|
||||||
|
if (!$row) {
|
||||||
|
$this->error(__('No Results were found'));
|
||||||
|
}
|
||||||
|
Auth::instance()->delete($row['id']);
|
||||||
|
$this->success();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,12 @@ return [
|
||||||
'User id' => '会员ID',
|
'User id' => '会员ID',
|
||||||
'Username' => '用户名',
|
'Username' => '用户名',
|
||||||
'Nickname' => '昵称',
|
'Nickname' => '昵称',
|
||||||
|
'Mobile' => '手机',
|
||||||
|
'Email' => '邮箱',
|
||||||
'Password' => '密码',
|
'Password' => '密码',
|
||||||
'Sign up' => '注 册',
|
'Sign up' => '注 册',
|
||||||
'Sign in' => '登 录',
|
'Sign in' => '登 录',
|
||||||
'Sign out' => '注 销',
|
'Sign out' => '退 出',
|
||||||
'Keep login' => '保持会话',
|
'Keep login' => '保持会话',
|
||||||
'Guest' => '游客',
|
'Guest' => '游客',
|
||||||
'Welcome' => '%s,你好!',
|
'Welcome' => '%s,你好!',
|
||||||
|
|
@ -17,6 +19,8 @@ return [
|
||||||
'Del' => '删除',
|
'Del' => '删除',
|
||||||
'Delete' => '删除',
|
'Delete' => '删除',
|
||||||
'Import' => '导入',
|
'Import' => '导入',
|
||||||
|
'Export' => '导出',
|
||||||
|
'All' => '全部',
|
||||||
'Detail' => '详情',
|
'Detail' => '详情',
|
||||||
'Multi' => '批量更新',
|
'Multi' => '批量更新',
|
||||||
'Setting' => '配置',
|
'Setting' => '配置',
|
||||||
|
|
@ -41,6 +45,8 @@ return [
|
||||||
'Last month' => '上月',
|
'Last month' => '上月',
|
||||||
'This month' => '本月',
|
'This month' => '本月',
|
||||||
'Loading' => '加载中',
|
'Loading' => '加载中',
|
||||||
|
'Money' => '余额',
|
||||||
|
'Score' => '积分',
|
||||||
'More' => '更多',
|
'More' => '更多',
|
||||||
'Yes' => '是',
|
'Yes' => '是',
|
||||||
'No' => '否',
|
'No' => '否',
|
||||||
|
|
@ -52,6 +58,7 @@ return [
|
||||||
'Execute' => '执行',
|
'Execute' => '执行',
|
||||||
'Close' => '关闭',
|
'Close' => '关闭',
|
||||||
'Choose' => '选择',
|
'Choose' => '选择',
|
||||||
|
'Go' => '跳转',
|
||||||
'Search' => '搜索',
|
'Search' => '搜索',
|
||||||
'Refresh' => '刷新',
|
'Refresh' => '刷新',
|
||||||
'Install' => '安装',
|
'Install' => '安装',
|
||||||
|
|
@ -64,12 +71,11 @@ return [
|
||||||
'Home' => '主页',
|
'Home' => '主页',
|
||||||
'Online' => '在线',
|
'Online' => '在线',
|
||||||
'Login' => '登录',
|
'Login' => '登录',
|
||||||
'Logout' => '注销',
|
'Logout' => '退出',
|
||||||
'Profile' => '个人资料',
|
'Profile' => '个人资料',
|
||||||
'Index' => '首页',
|
'Index' => '首页',
|
||||||
'Hot' => '热门',
|
'Hot' => '热门',
|
||||||
'Recommend' => '推荐',
|
'Recommend' => '推荐',
|
||||||
'Dashboard' => '控制台',
|
|
||||||
'Upload' => '上传',
|
'Upload' => '上传',
|
||||||
'Uploading' => '上传中',
|
'Uploading' => '上传中',
|
||||||
'Code' => '编号',
|
'Code' => '编号',
|
||||||
|
|
@ -92,9 +98,14 @@ return [
|
||||||
'End time' => '结束时间',
|
'End time' => '结束时间',
|
||||||
'Create time' => '创建时间',
|
'Create time' => '创建时间',
|
||||||
'Update time' => '更新时间',
|
'Update time' => '更新时间',
|
||||||
|
'Createtime' => '创建时间',
|
||||||
|
'Updatetime' => '更新时间',
|
||||||
|
'Deletetime' => '删除时间',
|
||||||
'Flag' => '标志',
|
'Flag' => '标志',
|
||||||
'Drag to sort' => '拖动进行排序',
|
'Drag to sort' => '拖动进行排序',
|
||||||
'Redirect now' => '立即跳转',
|
'Redirect now' => '立即跳转',
|
||||||
|
'Key' => '键',
|
||||||
|
'Value' => '值',
|
||||||
'Common search' => '普通搜索',
|
'Common search' => '普通搜索',
|
||||||
'Search %s' => '搜索 %s',
|
'Search %s' => '搜索 %s',
|
||||||
'View %s' => '查看 %s',
|
'View %s' => '查看 %s',
|
||||||
|
|
@ -105,32 +116,69 @@ return [
|
||||||
'%d week%s ago' => '%d周前',
|
'%d week%s ago' => '%d周前',
|
||||||
'%d month%s ago' => '%d月前',
|
'%d month%s ago' => '%d月前',
|
||||||
'%d year%s ago' => '%d年前',
|
'%d year%s ago' => '%d年前',
|
||||||
|
'%d second%s after' => '%d秒后',
|
||||||
|
'%d minute%s after' => '%d分钟后',
|
||||||
|
'%d hour%s after' => '%d小时后',
|
||||||
|
'%d day%s after' => '%d天后',
|
||||||
|
'%d week%s after' => '%d周后',
|
||||||
|
'%d month%s after' => '%d月后',
|
||||||
|
'%d year%s after' => '%d年后',
|
||||||
'Set to normal' => '设为正常',
|
'Set to normal' => '设为正常',
|
||||||
'Set to hidden' => '设为隐藏',
|
'Set to hidden' => '设为隐藏',
|
||||||
|
'Set status to normal' => '设为正常',
|
||||||
|
'Set status to hidden' => '设为隐藏',
|
||||||
|
'Recycle bin' => '回收站',
|
||||||
|
'Restore' => '还原',
|
||||||
|
'Restore all' => '还原全部',
|
||||||
|
'Destroy' => '销毁',
|
||||||
|
'Destroy all' => '清空回收站',
|
||||||
|
'Nothing need restore' => '没有需要还原的数据',
|
||||||
//提示
|
//提示
|
||||||
'Go back' => '返回首页',
|
'Go back' => '返回首页',
|
||||||
'Jump now' => '立即跳转',
|
'Jump now' => '立即跳转',
|
||||||
'Click to search %s' => '点击搜索 %s',
|
'Click to search %s' => '点击搜索 %s',
|
||||||
|
'Click to toggle' => '点击切换',
|
||||||
'Operation completed' => '操作成功!',
|
'Operation completed' => '操作成功!',
|
||||||
'Operation failed' => '操作失败!',
|
'Operation failed' => '操作失败!',
|
||||||
'Unknown data format' => '未知的数据格式!',
|
'Unknown data format' => '未知的数据格式!',
|
||||||
'Network error' => '网络错误!',
|
'Network error' => '网络错误!',
|
||||||
'Invalid parameters' => '未知参数',
|
'Invalid parameters' => '未知参数',
|
||||||
'No results were found' => '记录未找到',
|
'No results were found' => '记录未找到',
|
||||||
|
'No rows were inserted' => '未插入任何行',
|
||||||
'No rows were deleted' => '未删除任何行',
|
'No rows were deleted' => '未删除任何行',
|
||||||
'No rows were updated' => '未更新任何行',
|
'No rows were updated' => '未更新任何行',
|
||||||
'Parameter %s can not be empty' => '参数%s不能为空',
|
'Parameter %s can not be empty' => '参数%s不能为空',
|
||||||
'Are you sure you want to delete the %s selected item?' => '确定删除选中的 %s 项?',
|
'Are you sure you want to delete the %s selected item?' => '确定删除选中的 %s 项?',
|
||||||
'Are you sure you want to delete this item?' => '确定删除此项?',
|
'Are you sure you want to delete this item?' => '确定删除此项?',
|
||||||
'Are you sure you want to delete or turncate?' => '确定删除或清空?',
|
'Are you sure you want to delete or turncate?' => '确定删除或清空?',
|
||||||
|
'Are you sure you want to truncate?' => '确定清空?',
|
||||||
|
'Token verification error' => 'Token验证错误!',
|
||||||
'You have no permission' => '你没有权限访问',
|
'You have no permission' => '你没有权限访问',
|
||||||
'Please enter your username' => '请输入你的用户名',
|
'Please enter your username' => '请输入你的用户名',
|
||||||
'Please enter your password' => '请输入你的密码',
|
'Please enter your password' => '请输入你的密码',
|
||||||
'Please login first' => '请登录后操作',
|
'Please login first' => '请登录后操作',
|
||||||
|
'Uploaded successful' => '上传成功',
|
||||||
'You can upload up to %d file%s' => '你最多还可以上传%d个文件',
|
'You can upload up to %d file%s' => '你最多还可以上传%d个文件',
|
||||||
'You can choose up to %d file%s' => '你最多还可以选择%d个文件',
|
'You can choose up to %d file%s' => '你最多还可以选择%d个文件',
|
||||||
|
'Chunk file write error' => '分片写入失败',
|
||||||
|
'Chunk file info error' => '分片文件错误',
|
||||||
|
'Chunk file merge error' => '分片合并错误',
|
||||||
|
'Chunk file disabled' => '未开启分片上传功能',
|
||||||
|
'Cancel upload' => '取消上传',
|
||||||
|
'Upload canceled' => '上传已取消',
|
||||||
|
'No file upload or server upload limit exceeded' => '未上传文件或超出服务器上传限制',
|
||||||
|
'Uploaded file format is limited' => '上传文件格式受限制',
|
||||||
|
'Uploaded file is not a valid image' => '上传文件不是有效的图片文件',
|
||||||
|
'Are you sure you want to cancel this upload?' => '确定取消上传?',
|
||||||
|
'Remove file' => '移除文件',
|
||||||
|
'You can only upload a maximum of %s files' => '你最多允许上传 %s 个文件',
|
||||||
|
'You can\'t upload files of this type' => '不允许上传的文件类型',
|
||||||
|
'Server responded with %s code' => '服务端响应(Code:%s)',
|
||||||
|
'File is too big (%sMiB), Max filesize: %sMiB' => '当前上传(%sM),最大允许上传文件大小:%sM',
|
||||||
'An unexpected error occurred' => '发生了一个意外错误,程序猿正在紧急处理中',
|
'An unexpected error occurred' => '发生了一个意外错误,程序猿正在紧急处理中',
|
||||||
'This page will be re-directed in %s seconds' => '页面将在 %s 秒后自动跳转',
|
'This page will be re-directed in %s seconds' => '页面将在 %s 秒后自动跳转',
|
||||||
|
'Click to uncheck all' => '点击取消全部',
|
||||||
|
'Multiple selection mode: %s checked' => '跨页选择模式,已选 %s 项',
|
||||||
//菜单
|
//菜单
|
||||||
'Dashboard' => '控制台',
|
'Dashboard' => '控制台',
|
||||||
'General' => '常规管理',
|
'General' => '常规管理',
|
||||||
|
|
@ -139,7 +187,6 @@ return [
|
||||||
'Auth' => '权限管理',
|
'Auth' => '权限管理',
|
||||||
'Config' => '系统配置',
|
'Config' => '系统配置',
|
||||||
'Attachment' => '附件管理',
|
'Attachment' => '附件管理',
|
||||||
'Profile' => '个人配置',
|
|
||||||
'Admin' => '管理员管理',
|
'Admin' => '管理员管理',
|
||||||
'Admin log' => '管理员日志',
|
'Admin log' => '管理员日志',
|
||||||
'Group' => '角色组',
|
'Group' => '角色组',
|
||||||
|
|
@ -157,12 +204,20 @@ return [
|
||||||
'Second group 2' => '二级管理组2',
|
'Second group 2' => '二级管理组2',
|
||||||
'Third group 2' => '三级管理组2',
|
'Third group 2' => '三级管理组2',
|
||||||
'Dashboard tips' => '用于展示当前系统中的统计数据、统计报表及重要实时数据',
|
'Dashboard tips' => '用于展示当前系统中的统计数据、统计报表及重要实时数据',
|
||||||
'Config tips' => '可以在此增改系统的变量和分组,也可以自定义分组和变量,如果需要删除请从数据库中删除',
|
'Config tips' => '可以在此增改系统的变量和分组,也可以自定义分组和变量',
|
||||||
'Category tips' => '用于统一管理网站的所有分类,分类可进行无限级分类',
|
'Category tips' => '分类类型请在常规管理->系统配置->字典配置中添加',
|
||||||
'Attachment tips' => '主要用于管理上传到服务器或第三方存储的数据',
|
'Attachment tips' => '主要用于管理上传到服务器或第三方存储的数据',
|
||||||
'Addon tips' => '可在线安装、卸载、禁用、启用插件,同时支持添加本地插件。FastAdmin已上线插件商店 ,你可以发布你的免费或付费插件:<a href="https://www.fastadmin.net/store.html" target="_blank">https://www.fastadmin.net/store.html</a>',
|
'Addon tips' => '可在线安装、卸载、禁用、启用、配置、升级插件,插件升级前请做好备份。',
|
||||||
'Admin tips' => '一个管理员可以有多个角色组,左侧的菜单根据管理员所拥有的权限进行生成',
|
'Admin tips' => '一个管理员可以有多个角色组,左侧的菜单根据管理员所拥有的权限进行生成',
|
||||||
'Admin log tips' => '管理员可以查看自己所拥有的权限的管理员日志',
|
'Admin log tips' => '管理员可以查看自己所拥有的权限的管理员日志',
|
||||||
'Group tips' => '角色组可以有多个,角色有上下级层级关系,如果子角色有角色组和管理员的权限则可以派生属于自己组别的下级角色组或管理员',
|
'Group tips' => '角色组可以有多个,角色有上下级层级关系,如果子角色有角色组和管理员的权限则可以派生属于自己组别的下级角色组或管理员',
|
||||||
'Rule tips' => '规则通常对应一个控制器的方法,同时左侧的菜单栏数据也从规则中体现,通常建议通过命令行进行生成规则节点',
|
'Rule tips' => '菜单规则通常对应一个控制器的方法,同时菜单栏数据也从规则中获取',
|
||||||
|
'Access is allowed only to the super management group' => '仅超级管理组能访问',
|
||||||
|
'Local addon' => '本地插件',
|
||||||
|
// 前台菜单
|
||||||
|
'Frontend' => '前台',
|
||||||
|
'API Interface' => 'API接口',
|
||||||
|
'User Module' => '会员模块',
|
||||||
|
'Register' => '注册',
|
||||||
|
'User Center' => '会员中心',
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -1,86 +1,114 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'Id' => 'ID',
|
'Id' => 'ID',
|
||||||
'Title' => '插件名称',
|
'Title' => '名称',
|
||||||
'Value' => '配置值',
|
'Value' => '配置值',
|
||||||
'Array key' => '键',
|
'Array key' => '键',
|
||||||
'Array value' => '值',
|
'Array value' => '值',
|
||||||
'File' => '文件',
|
'File' => '文件',
|
||||||
'Donate' => '打赏作者',
|
'Donate' => '打赏作者',
|
||||||
'Warmtips' => '温馨提示',
|
'Warmtips' => '温馨提示',
|
||||||
'Pay now' => '立即支付',
|
'Pay now' => '立即支付',
|
||||||
'Offline install' => '离线安装',
|
'Local install' => '本地安装',
|
||||||
'Refresh addon cache' => '刷新插件缓存',
|
'Refresh addon cache' => '刷新插件缓存',
|
||||||
'Userinfo' => '会员信息',
|
'Userinfo' => '会员信息',
|
||||||
'Online store' => '在线商店',
|
'Reload authorization' => '刷新授权',
|
||||||
'Local addon' => '本地插件',
|
'Local addon' => '本地插件',
|
||||||
'Conflict tips' => '此插件中发现和现有系统中部分文件发现冲突!以下文件将会被影响,请备份好相关文件后再继续操作',
|
'Conflict tips' => '此插件中发现和现有系统中部分文件发现冲突!以下文件将会被影响,请备份好相关文件后再继续操作',
|
||||||
'Login tips' => '此处登录账号为<a href="https://www.fastadmin.net" target="_blank">FastAdmin官网账号</a>',
|
'Pay tips' => '扫码支付后如果仍然无法安装,请不要重复支付,请稍后再重试安装!',
|
||||||
'Logined tips' => '你好!%s<br />当前你已经登录,将同步保存你的购买记录',
|
'Pay successful tips' => '购买成功!请点击继续安装按钮完成安装!',
|
||||||
'Pay tips' => '扫码支付后如果仍然无法立即下载,请不要重复支付,请加<a href="https://jq.qq.com/?_wv=1027&k=487PNBb" target="_blank">QQ群:636393962</a>向管理员反馈',
|
'Pay click tips' => '请点击这里在新窗口中进行支付!',
|
||||||
'Pay click tips' => '请点击这里在新窗口中进行支付!',
|
'Pay new window tips' => '请在新弹出的窗口中进行支付,支付完成后再重新点击安装按钮进行安装!',
|
||||||
'Pay new window tips' => '请在新弹出的窗口中进行支付,支付完成后再重新点击安装按钮进行安装!',
|
'Upgrade tips' => '确认升级<b>《%s》</b>?<p class="text-danger">1、请务必做好代码和数据库备份!备份!备份!<br>2、升级后如出现冗余数据,请根据需要移除即可!<br>3、不建议在生产环境升级,请在本地完成升级测试</p>如有重要数据请备份后再操作!',
|
||||||
'Uninstall tips' => '确认卸载插件?<p class="text-danger">卸载将会删除所有插件文件且不可找回!!! 插件如果有创建数据库表请手动删除!!!</p>如有重要数据请备份后再操作!',
|
'Offline installed tips' => '安装成功!清除浏览器缓存和框架缓存后生效!',
|
||||||
'Upgrade tips' => '确认升级插件?<p class="text-danger">如果之前购买插件时未登录,此次升级可能出现购买后才可以下载的提示!!!<br>升级后可能出现部分冗余数据记录,请根据需要移除即可!!!</p>如有重要数据请备份后再操作!',
|
'Online installed tips' => '安装成功!清除浏览器缓存和框架缓存后生效!',
|
||||||
'Offline installed tips' => '插件安装成功!清除浏览器缓存和框架缓存后生效!',
|
'Please login and try to install' => '请登录FastAdmin后再进行本地安装!',
|
||||||
'Online installed tips' => '插件安装成功!清除浏览器缓存和框架缓存后生效!',
|
'Not installed tips' => '请安装后再访问插件前台页面!',
|
||||||
'Not login tips' => '你当前未登录FastAdmin,登录后将同步已购买的记录,下载时无需二次付费!',
|
'Not enabled tips' => '插件已经禁用,请启用后再访问插件前台页面!',
|
||||||
'Not installed tips' => '请安装后再访问插件前台页面!',
|
'New version tips' => '发现新版本:%s 点击查看更新日志',
|
||||||
'Not enabled tips' => '插件已经禁用,请启用后再访问插件前台页面!',
|
'Testdata tips' => '你还可以继续导入测试数据!',
|
||||||
'Please disable addon first' => '请先禁用插件再进行升级',
|
'Import testdata' => '导入测试数据',
|
||||||
'Login now' => '立即登录',
|
'Skip testdata' => '暂不导入',
|
||||||
'Continue install' => '不登录,继续安装',
|
'Store not available tips' => '插件市场暂不可用,是否切换到本地插件?',
|
||||||
'View addon home page' => '查看插件介绍和帮助',
|
'Switch to the local' => '切换到本地插件',
|
||||||
'View addon index page' => '查看插件前台首页',
|
'try to reload' => '重新尝试加载',
|
||||||
'View addon screenshots' => '点击查看插件截图',
|
'Please disable addon first' => '请先禁用插件再进行操作',
|
||||||
'Click to toggle status' => '点击切换插件状态',
|
'Please disable the add before trying to upgrade' => '请先禁用插件再进行升级',
|
||||||
'Click to contact developer' => '点击与插件开发者取得联系',
|
'Please disable the add before trying to uninstall' => '请先禁用插件再进行卸载',
|
||||||
'Index' => '前台',
|
'Login now' => '立即登录',
|
||||||
'All' => '全部',
|
'Continue install' => '继续安装',
|
||||||
'Uncategoried' => '未归类',
|
'View addon home page' => '查看插件介绍和帮助',
|
||||||
'Recommend' => '推荐',
|
'View addon index page' => '查看插件前台首页',
|
||||||
'Hot' => '热门',
|
'View addon screenshots' => '点击查看插件截图',
|
||||||
'New' => '新',
|
'Click to toggle status' => '点击切换插件状态',
|
||||||
'Paying' => '付费',
|
'Click to contact developer' => '点击与插件开发者取得联系',
|
||||||
'Free' => '免费',
|
'Continue installation' => '继续安装',
|
||||||
'Sale' => '折扣',
|
'My addons' => '我购买的插件',
|
||||||
'No image' => '暂无缩略图',
|
'Index' => '前台',
|
||||||
'Price' => '价格',
|
'All' => '全部',
|
||||||
'Downloads' => '下载',
|
'Uncategoried' => '未归类',
|
||||||
'Author' => '作者',
|
'Recommend' => '推荐',
|
||||||
'Identify' => '标识',
|
'Hot' => '热门',
|
||||||
'Homepage' => '主页',
|
'New' => '新',
|
||||||
'Intro' => '介绍',
|
'Paying' => '付费',
|
||||||
'Version' => '版本',
|
'Free' => '免费',
|
||||||
'New version' => '新版本',
|
'Sale' => '折扣',
|
||||||
'Createtime' => '添加时间',
|
'No image' => '暂无缩略图',
|
||||||
'Releasetime' => '更新时间',
|
'Price' => '价格',
|
||||||
'Detail' => '插件详情',
|
'Downloads' => '下载',
|
||||||
'Document' => '文档',
|
'Author' => '作者',
|
||||||
'Demo' => '演示',
|
'Identify' => '标识',
|
||||||
'Feedback' => '反馈BUG',
|
'Homepage' => '主页',
|
||||||
'Install' => '安装',
|
'Intro' => '介绍',
|
||||||
'Uninstall' => '卸载',
|
'Version' => '版本',
|
||||||
'Upgrade' => '升级',
|
'New version' => '新版本',
|
||||||
'Setting' => '配置',
|
'Createtime' => '添加时间',
|
||||||
'Disable' => '禁用',
|
'Releasetime' => '更新时间',
|
||||||
'Enable' => '启用',
|
'Detail' => '插件详情',
|
||||||
'Your username or email' => '你的用户名或邮箱',
|
'Document' => '文档',
|
||||||
'Your password' => '你的密码',
|
'Demo' => '演示',
|
||||||
'Login FastAdmin' => '登录FastAdmin',
|
'Feedback' => '反馈BUG',
|
||||||
'Login' => '登录',
|
'Install' => '安装',
|
||||||
'Logout' => '退出登录',
|
'Uninstall' => '卸载',
|
||||||
'Register' => '注册账号',
|
'Upgrade' => '升级',
|
||||||
'You\'re not login' => '当前未登录',
|
'Setting' => '配置',
|
||||||
'Continue uninstall' => '继续卸载',
|
'Disable' => '禁用',
|
||||||
'Continue operate' => '继续操作',
|
'Enable' => '启用',
|
||||||
'Install successful' => '安装成功',
|
'Your username or email' => '你的手机号、用户名或邮箱',
|
||||||
'Uninstall successful' => '卸载成功',
|
'Your password' => '你的密码',
|
||||||
'Operate successful' => '操作成功',
|
'Login' => '登录',
|
||||||
'Addon info file was not found' => '插件配置文件未找到',
|
'Logout' => '退出登录',
|
||||||
'Addon info file data incorrect' => '插件配置信息不正确',
|
'Register' => '注册账号',
|
||||||
'Addon already exists' => '上传的插件已经存在',
|
'You\'re not login' => '当前未登录',
|
||||||
'Unable to open the zip file' => '无法打开ZIP文件',
|
'Continue uninstall' => '继续卸载',
|
||||||
'Unable to extract the file' => '无法解压ZIP文件',
|
'Continue operate' => '继续操作',
|
||||||
|
'Install successful' => '安装成功',
|
||||||
|
'Uninstall successful' => '卸载成功',
|
||||||
|
'Operate successful' => '操作成功',
|
||||||
|
'Import successful' => '导入测试数据成功!清除浏览器缓存和框架缓存后生效!',
|
||||||
|
'Initialize successful' => '初始化成功',
|
||||||
|
'Initialize template not found' => '初始化模板未找到',
|
||||||
|
'Addon name incorrect' => '插件名称不正确',
|
||||||
|
'Addon info file was not found' => '插件配置文件未找到',
|
||||||
|
'Addon info file data incorrect' => '插件配置信息不正确',
|
||||||
|
'Addon already exists' => '插件已经存在',
|
||||||
|
'Addon not exists' => '插件不存在',
|
||||||
|
'Addon package download failed' => '插件下载失败',
|
||||||
|
'Conflicting file found' => '发现冲突文件',
|
||||||
|
'Invalid addon package' => '未验证的插件',
|
||||||
|
'No initialize method' => '未找到初始化方法',
|
||||||
|
'No permission to write temporary files' => '没有权限写入临时文件',
|
||||||
|
'The addon file does not exist' => '插件主启动程序不存在',
|
||||||
|
'The configuration file content is incorrect' => '配置文件不完整',
|
||||||
|
'Unable to open the zip file' => '无法打开ZIP文件',
|
||||||
|
'Unable to extract the file' => '无法解压ZIP文件',
|
||||||
|
'Unable to open file \'%s\' for writing' => '文件(%s)没有写入权限',
|
||||||
|
'Are you sure you want to unstall %s?' => '确认卸载<b>《%s》</b>?',
|
||||||
|
'Are you sure you want to refresh authorization?' => '确认刷新应用插件授权?',
|
||||||
|
'Delete all the addon file and cannot be recovered!' => '卸载将会删除所有插件文件且不可找回!!!',
|
||||||
|
'Delete all the addon database and cannot be recovered!' => '删除所有插件相关数据表且不可找回!!!',
|
||||||
|
'Please backup important data manually before uninstall!' => '如有重要数据请备份后再操作!!!',
|
||||||
|
'The following data tables will be deleted' => '以下插件数据表将会被删除',
|
||||||
|
'The Addon did not create a data table' => '插件未创建任何数据表',
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,3 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
return [
|
return [];
|
||||||
'No file upload or server upload limit exceeded' => '未上传文件或超出服务器上传限制',
|
|
||||||
'Uploaded file format is limited' => '上传文件格式受限制',
|
|
||||||
'Upload successful' => '上传成功',
|
|
||||||
];
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,14 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'Group' => '所属组别',
|
'Email' => '电子邮箱',
|
||||||
'Loginfailure' => '登录失败次数',
|
'Mobile' => '手机号',
|
||||||
'Login time' => '最后登录',
|
'Group' => '所属组别',
|
||||||
|
'Loginfailure' => '登录失败次数',
|
||||||
|
'Login time' => '最后登录',
|
||||||
|
'The parent group exceeds permission limit' => '父组别超出权限范围',
|
||||||
|
'Please input correct username' => '用户名只能由3-30位数字、字母、下划线组合',
|
||||||
|
'Username must be 3 to 30 characters' => '用户名只能由3-30位数字、字母、下划线组合',
|
||||||
|
'Please input correct password' => '密码长度必须在6-30位之间,不能包含空格',
|
||||||
|
'Password must be 6 to 30 characters' => '密码长度必须在6-30位之间,不能包含空格',
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@ return [
|
||||||
'The parent group can not found' => '父组别未找到',
|
'The parent group can not found' => '父组别未找到',
|
||||||
'Group not found' => '组别未找到',
|
'Group not found' => '组别未找到',
|
||||||
'Can not change the parent to child' => '父组别不能是它的子组别',
|
'Can not change the parent to child' => '父组别不能是它的子组别',
|
||||||
'Can not change the parent to self' => '父组别不能是它的子组别',
|
'Can not change the parent to self' => '父组别不能是它自己',
|
||||||
'You can not delete group that contain child group and administrators' => '你不能删除含有子组和管理员的组',
|
'You can not delete group that contain child group and administrators' => '你不能删除含有子组和管理员的组',
|
||||||
|
'The parent group exceeds permission limit' => '父组别超出权限范围',
|
||||||
|
'The parent group can not be its own child or itself' => '父组别不能是它的子组别及本身',
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -9,11 +9,20 @@ return [
|
||||||
'Name' => '规则',
|
'Name' => '规则',
|
||||||
'Controller/Action' => '控制器名/方法名',
|
'Controller/Action' => '控制器名/方法名',
|
||||||
'Ismenu' => '菜单',
|
'Ismenu' => '菜单',
|
||||||
|
'Menutype' => '菜单类型',
|
||||||
|
'Addtabs' => '选项卡(默认)',
|
||||||
|
'Dialog' => '弹窗',
|
||||||
|
'Ajax' => 'Ajax请求',
|
||||||
|
'Blank' => '链接',
|
||||||
|
'Extend' => '扩展属性',
|
||||||
'Search icon' => '搜索图标',
|
'Search icon' => '搜索图标',
|
||||||
'Toggle menu visible' => '点击切换菜单显示',
|
'Toggle menu visible' => '点击切换菜单显示',
|
||||||
'Toggle sub menu' => '点击切换子菜单',
|
'Toggle sub menu' => '点击切换子菜单',
|
||||||
'Menu tips' => '父级菜单无需匹配控制器和方法,子级菜单请使用控制器名',
|
'Menu tips' => '父级菜单无需匹配控制器和方法,子级菜单请使用控制器名',
|
||||||
'Node tips' => '控制器/方法名,如果有目录请使用 目录名/控制器名/方法名',
|
'Node tips' => '控制器/方法名,如果有目录请使用 目录名/控制器名/方法名',
|
||||||
|
'Url tips' => '一般情况下留空即可,如果是外部链接或相对链接请输入',
|
||||||
'The non-menu rule must have parent' => '非菜单规则节点必须有父级',
|
'The non-menu rule must have parent' => '非菜单规则节点必须有父级',
|
||||||
|
'Can not change the parent to child' => '父级不能是它的子级',
|
||||||
|
'Can not change the parent to self' => '父级不能是它自己',
|
||||||
'Name only supports letters, numbers, underscore and slash' => 'URL规则只能是小写字母、数字、下划线和/组成',
|
'Name only supports letters, numbers, underscore and slash' => 'URL规则只能是小写字母、数字、下划线和/组成',
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,18 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'Id' => 'ID',
|
'Id' => 'ID',
|
||||||
'Pid' => '父ID',
|
'Pid' => '父ID',
|
||||||
'Type' => '栏目类型',
|
'Type' => '类型',
|
||||||
'All' => '全部',
|
'All' => '全部',
|
||||||
'Image' => '图片',
|
'Image' => '图片',
|
||||||
'Keywords' => '关键字',
|
'Keywords' => '关键字',
|
||||||
'Description' => '描述',
|
'Description' => '描述',
|
||||||
'Diyname' => '自定义名称',
|
'Diyname' => '自定义名称',
|
||||||
'Createtime' => '创建时间',
|
'Createtime' => '创建时间',
|
||||||
'Updatetime' => '更新时间',
|
'Updatetime' => '更新时间',
|
||||||
'Weigh' => '权重',
|
'Weigh' => '权重',
|
||||||
'Status' => '状态'
|
'Category warmtips' => '温馨提示:栏目类型请前往<b>常规管理</b>-><b>系统配置</b>-><b>字典配置</b>中进行管理',
|
||||||
|
'Can not change the parent to child or itself' => '父组别不能是它的子组别或它自己',
|
||||||
|
'Status' => '状态'
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -1,45 +1,50 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'Custom' => '自定义',
|
'Custom' => '自定义',
|
||||||
'Pid' => '父ID',
|
'Pid' => '父ID',
|
||||||
'Type' => '栏目类型',
|
'Type' => '栏目类型',
|
||||||
'Image' => '图片',
|
'Image' => '图片',
|
||||||
'Total user' => '总会员数',
|
'Total user' => '总会员数',
|
||||||
'Total view' => '总访问数',
|
'Total addon' => '总插件数',
|
||||||
'Total order' => '总订单数',
|
'Total category' => '总分类数',
|
||||||
'Total order amount' => '总金额',
|
'Total attachment' => '总附件数',
|
||||||
'Today user signup' => '今日注册',
|
'Total admin' => '总管理员数',
|
||||||
'Today user login' => '今日登录',
|
'Today user signup' => '今日注册',
|
||||||
'Today order' => '今日订单',
|
'Today user login' => '今日登录',
|
||||||
'Unsettle order' => '未处理订单',
|
'Today order' => '今日订单',
|
||||||
'Seven dnu' => '七日新增',
|
'Unsettle order' => '未处理订单',
|
||||||
'Seven dau' => '七日活跃',
|
'Three dnu' => '三日新增',
|
||||||
'Custom zone' => '这里是你的自定义数据',
|
'Seven dnu' => '七日新增',
|
||||||
'Sales' => '成交数',
|
'Seven dau' => '七日活跃',
|
||||||
'Orders' => '订单数',
|
'Thirty dau' => '月活跃',
|
||||||
'Real time' => '实时',
|
'Custom zone' => '这里是你的自定义数据',
|
||||||
'Category count' => '分类统计',
|
'Register user' => '注册用户数',
|
||||||
'Category count tips' => '当前分类总记录数',
|
'Real time' => '实时',
|
||||||
'Attachment count' => '附件统计',
|
'Category count' => '分类统计',
|
||||||
'Attachment count tips' => '当前上传的附件数量',
|
'Working addon count' => '运行中的插件',
|
||||||
'Article count' => '文章统计',
|
'Category count tips' => '当前分类总记录数',
|
||||||
'News count' => '新闻统计',
|
'Working addon count tips' => '当前运行中的插件数',
|
||||||
'Comment count' => '评论次数',
|
'Database count' => '数据库统计',
|
||||||
'Like count' => '点赞次数',
|
'Database table nums' => '数据表数量',
|
||||||
'Recent news' => '最新新闻',
|
'Database size' => '占用空间',
|
||||||
'Recent discussion' => '最新发贴',
|
'Attachment count' => '附件统计',
|
||||||
'Server info' => '服务器信息',
|
'Attachment nums' => '附件数量',
|
||||||
'PHP version' => 'PHP版本',
|
'Attachment size' => '附件大小',
|
||||||
'Fastadmin version' => 'FastAdmin版本',
|
'Attachment count tips' => '当前上传的附件数量',
|
||||||
'Fastadmin addon version' => 'FastAdmin插件版本',
|
'Picture count' => '图片统计',
|
||||||
'Sapi name' => '运行方式',
|
'Picture nums' => '图片数量',
|
||||||
'Debug mode' => '调试模式',
|
'Picture size' => '图片大小',
|
||||||
'Software' => '环境信息',
|
'Server info' => '服务器信息',
|
||||||
'Upload mode' => '上传模式',
|
'PHP version' => 'PHP版本',
|
||||||
'Upload url' => '上传URL',
|
'Sapi name' => '运行方式',
|
||||||
'Upload cdn url' => '上传CDN',
|
'Debug mode' => '调试模式',
|
||||||
'Cdn url' => '静态资源CDN',
|
'Software' => '环境信息',
|
||||||
'Timezone' => '时区',
|
'Upload mode' => '上传模式',
|
||||||
'Language' => '语言',
|
'Upload url' => '上传URL',
|
||||||
|
'Upload cdn url' => '上传CDN',
|
||||||
|
'Cdn url' => '静态资源CDN',
|
||||||
|
'Timezone' => '时区',
|
||||||
|
'Language' => '语言',
|
||||||
|
'View more' => '查看更多',
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,41 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'Id' => 'ID',
|
'Id' => 'ID',
|
||||||
'Url' => '物理路径',
|
'Admin_id' => '管理员ID',
|
||||||
'Imagewidth' => '宽度',
|
'User_id' => '会员ID',
|
||||||
'Imageheight' => '高度',
|
'Url' => '物理路径',
|
||||||
'Imagetype' => '图片类型',
|
'Imagewidth' => '宽度',
|
||||||
'Imageframes' => '图片帧数',
|
'Imageheight' => '高度',
|
||||||
'Preview' => '预览',
|
'Imagetype' => '图片类型',
|
||||||
'Filesize' => '文件大小',
|
'Imageframes' => '图片帧数',
|
||||||
'Mimetype' => 'Mime类型',
|
'Preview' => '预览',
|
||||||
'Extparam' => '透传数据',
|
'Filename' => '文件名',
|
||||||
'Createtime' => '创建日期',
|
'Filesize' => '文件大小',
|
||||||
'Uploadtime' => '上传时间',
|
'Mimetype' => 'Mime类型',
|
||||||
'Storage' => '存储引擎',
|
'Image' => '图片',
|
||||||
'Upload to third' => '上传到第三方',
|
'Audio' => '音频',
|
||||||
'Upload to local' => '上传到本地',
|
'Video' => '视频',
|
||||||
'Upload from editor' => '从编辑器上传'
|
'Text' => '文档',
|
||||||
|
'Application' => '应用',
|
||||||
|
'Zip' => '压缩包',
|
||||||
|
'Extparam' => '透传数据',
|
||||||
|
'Createtime' => '创建日期',
|
||||||
|
'Uploadtime' => '上传时间',
|
||||||
|
'Storage' => '存储引擎',
|
||||||
|
'Category1' => '分类一',
|
||||||
|
'Category2' => '分类二',
|
||||||
|
'Custom' => '自定义',
|
||||||
|
'Unclassed' => '未归类',
|
||||||
|
'Category' => '类别',
|
||||||
|
'Classify' => '归类',
|
||||||
|
'Filter Type' => '类型筛选',
|
||||||
|
'Upload to third' => '上传到第三方',
|
||||||
|
'Upload to local' => '上传到本地',
|
||||||
|
'Upload to third by chunk' => '上传到第三方(分片模式)',
|
||||||
|
'Upload to local by chunk' => '上传到本地(分片模式)',
|
||||||
|
'Please enter a new name' => '请输入新的类别名称',
|
||||||
|
'Please select category' => '请选择一个类别',
|
||||||
|
'Category not found' => '指定的类别未找到',
|
||||||
|
'Upload from editor' => '从编辑器上传'
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -1,59 +1,83 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'Name' => '变量名',
|
'Name' => '变量名',
|
||||||
'Tip' => '提示信息',
|
'Tip' => '提示信息',
|
||||||
'Group' => '分组',
|
'Group' => '分组',
|
||||||
'Type' => '类型',
|
'Type' => '类型',
|
||||||
'Title' => '变量标题',
|
'Title' => '变量标题',
|
||||||
'Value' => '变量值',
|
'Value' => '变量值',
|
||||||
'Basic' => '基础配置',
|
'Basic' => '基础配置',
|
||||||
'Email' => '邮件配置',
|
'Email' => '邮件配置',
|
||||||
'Attachment' => '附件配置',
|
'Attachment' => '附件配置',
|
||||||
'Dictionary' => '字典配置',
|
'Dictionary' => '字典配置',
|
||||||
'User' => '会员配置',
|
'User' => '会员配置',
|
||||||
'Example' => '示例分组',
|
'Example' => '示例分组',
|
||||||
'Extend' => '扩展属性',
|
'Extend' => '扩展属性',
|
||||||
'String' => '字符',
|
'String' => '字符',
|
||||||
'Text' => '文本',
|
'Password' => '密码',
|
||||||
'Editor' => '编辑器',
|
'Text' => '文本',
|
||||||
'Number' => '数字',
|
'Editor' => '编辑器',
|
||||||
'Date' => '日期',
|
'Number' => '数字',
|
||||||
'Time' => '时间',
|
'Date' => '日期',
|
||||||
'Datetime' => '日期时间',
|
'Time' => '时间',
|
||||||
'Image' => '图片',
|
'Datetime' => '日期时间',
|
||||||
'Images' => '图片(多)',
|
'Datetimerange' => '日期时间区间',
|
||||||
'File' => '文件',
|
'Image' => '图片',
|
||||||
'Files' => '文件(多)',
|
'Images' => '图片(多)',
|
||||||
'Select' => '列表',
|
'File' => '文件',
|
||||||
'Selects' => '列表(多选)',
|
'Files' => '文件(多)',
|
||||||
'Checkbox' => '复选',
|
'Select' => '列表',
|
||||||
'Radio' => '单选',
|
'Selects' => '列表(多选)',
|
||||||
'Array' => '数组',
|
'Switch' => '开关',
|
||||||
'Array key' => '键名',
|
'Checkbox' => '复选',
|
||||||
'Array value' => '键值',
|
'Radio' => '单选',
|
||||||
'Content' => '数据列表',
|
'Array' => '数组',
|
||||||
'Rule' => '校验规则',
|
'Array key' => '键名',
|
||||||
'Site name' => '站点名称',
|
'Array value' => '键值',
|
||||||
'Beian' => '备案号',
|
'City' => '城市地区',
|
||||||
'Cdn url' => 'CDN地址',
|
'Selectpage' => '关联表',
|
||||||
'Version' => '版本号',
|
'Selectpages' => '关联表(多选)',
|
||||||
'Timezone' => '时区',
|
'Custom' => '自定义',
|
||||||
'Forbidden ip' => '禁止IP',
|
'Please select table' => '关联表',
|
||||||
'Languages' => '语言',
|
'Selectpage table' => '关联表',
|
||||||
'Fixed page' => '后台固定页',
|
'Selectpage primarykey' => '存储字段',
|
||||||
'Category type' => '分类类型',
|
'Selectpage field' => '显示字段',
|
||||||
'Config group' => '配置分组',
|
'Selectpage conditions' => '筛选条件',
|
||||||
'Mail type' => '邮件发送方式',
|
'Field title' => '字段名',
|
||||||
'Mail smtp host' => 'SMTP服务器',
|
'Field value' => '字段值',
|
||||||
'Mail smtp port' => 'SMTP端口',
|
'Content' => '数据列表',
|
||||||
'Mail smtp user' => 'SMTP用户名',
|
'Rule' => '校验规则',
|
||||||
'Mail smtp password' => 'SMTP密码',
|
'Visible condition' => '可见条件',
|
||||||
'Mail vertify type' => 'SMTP验证方式',
|
'Site name' => '站点名称',
|
||||||
'Mail from' => '发件人邮箱',
|
'Beian' => '备案号',
|
||||||
'Name already exist' => '变量名称已经存在',
|
'Cdn url' => 'CDN地址',
|
||||||
'Send a test message' => '发送测试邮件',
|
'Version' => '版本号',
|
||||||
'This is a test mail content' => '这是一封来自FastAdmin校验邮件,用于校验邮件配置是否正常!',
|
'Timezone' => '时区',
|
||||||
'This is a test mail' => '这是一封来自FastAdmin的邮件',
|
'Forbidden ip' => '禁止IP',
|
||||||
'Please input your email' => '请输入测试接收者邮箱',
|
'Languages' => '语言',
|
||||||
|
'Fixed page' => '后台固定页',
|
||||||
|
'Category type' => '分类类型',
|
||||||
|
'Config group' => '配置分组',
|
||||||
|
'Attachment category' => '附件类别',
|
||||||
|
'Category1' => '分类一',
|
||||||
|
'Category2' => '分类二',
|
||||||
|
'Rule tips' => '校验规则使用请参考Nice-validator文档',
|
||||||
|
'Extend tips' => '扩展属性支持{id}、{name}、{group}、{title}、{value}、{content}、{rule}替换',
|
||||||
|
'Mail type' => '邮件发送方式',
|
||||||
|
'Mail smtp host' => 'SMTP服务器',
|
||||||
|
'Mail smtp port' => 'SMTP端口',
|
||||||
|
'Mail smtp user' => 'SMTP用户名',
|
||||||
|
'Mail smtp password' => 'SMTP密码',
|
||||||
|
'Mail vertify type' => 'SMTP验证方式',
|
||||||
|
'Mail from' => '发件人邮箱',
|
||||||
|
'Site name incorrect' => '网站名称错误',
|
||||||
|
'Name already exist' => '变量名称已经存在',
|
||||||
|
'Add new config' => '点击添加新的配置',
|
||||||
|
'Send a test message' => '发送测试邮件',
|
||||||
|
'Only work at development environment' => '只允许在开发环境开操作',
|
||||||
|
'This is a test mail content' => '这是一封来自%s的校验邮件,用于校验邮件配置是否正常!',
|
||||||
|
'This is a test mail' => '这是一封来自%s的邮件',
|
||||||
|
'Please input your email' => '请输入测试接收者邮箱',
|
||||||
|
'Please input correct email' => '请输入正确的邮箱地址',
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,13 @@
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'Url' => '链接',
|
'Url' => '链接',
|
||||||
'Userame' => '用户名',
|
'Username' => '用户名',
|
||||||
'Createtime' => '操作时间',
|
'Createtime' => '操作时间',
|
||||||
'Click to edit' => '点击编辑',
|
'Click to edit' => '点击编辑',
|
||||||
'Admin log' => '操作日志',
|
'Admin log' => '操作日志',
|
||||||
'Leave password blank if dont want to change' => '不修改密码请留空',
|
'Leave password blank if dont want to change' => '不修改密码请留空',
|
||||||
|
'Please input correct email' => '请输入正确的Email地址',
|
||||||
|
'Please input correct password' => '密码长度必须在6-30位之间,不能包含空格',
|
||||||
|
'Password must be 6 to 30 characters' => '密码长度必须在6-30位之间,不能包含空格',
|
||||||
|
'Email already exists' => '邮箱已经存在',
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -8,36 +8,53 @@ return [
|
||||||
'You can\'t use fixed and boxed layouts together' => '盒子模型和固定布局不能同时启作用',
|
'You can\'t use fixed and boxed layouts together' => '盒子模型和固定布局不能同时启作用',
|
||||||
'Boxed Layout' => '盒子布局',
|
'Boxed Layout' => '盒子布局',
|
||||||
'Activate the boxed layout' => '盒子布局最大宽度将被限定为1250px',
|
'Activate the boxed layout' => '盒子布局最大宽度将被限定为1250px',
|
||||||
'Toggle Sidebar' => '切换菜单栏',
|
'Toggle Sidebar' => '收起菜单栏',
|
||||||
'Toggle the left sidebar\'s state (open or collapse)' => '切换菜单栏的展示或收起',
|
'Toggle the left sidebar\'s state (open or collapse)' => '切换菜单栏的展开或收起',
|
||||||
'Sidebar Expand on Hover' => '菜单栏自动展开',
|
'Sidebar Expand on Hover' => '菜单栏自动展开',
|
||||||
'Let the sidebar mini expand on hover' => '鼠标移到菜单栏自动展开',
|
'Let the sidebar mini expand on hover' => '鼠标移到菜单栏自动展开',
|
||||||
'Toggle Right Sidebar Slide' => '切换右侧操作栏',
|
'Toggle Right Sidebar Slide' => '切换右侧操作栏',
|
||||||
'Toggle between slide over content and push content effects' => '切换右侧操作栏覆盖或独占',
|
'Toggle between slide over content and push content effects' => '切换右侧操作栏覆盖或独占',
|
||||||
'Toggle Right Sidebar Skin' => '切换右侧操作栏背景',
|
'Toggle Right Sidebar Skin' => '切换右侧操作栏背景',
|
||||||
'Toggle between dark and light skins for the right sidebar' => '将右侧操作栏背景亮色或深色切换',
|
'Toggle between dark and light skins for the right sidebar' => '将右侧操作栏背景亮色或深色切换',
|
||||||
|
'Multiple nav' => '多级菜单导航',
|
||||||
|
'Toggle the top menu state (multiple or single)' => '切换顶部菜单为多级菜单导航模式',
|
||||||
|
'Multiple tab' => '多选项卡',
|
||||||
|
'Always show multiple tab when multiple nav is set' => '当配置为多级菜单导航时是否启用多选项卡',
|
||||||
'Show sub menu' => '显示菜单栏子菜单',
|
'Show sub menu' => '显示菜单栏子菜单',
|
||||||
'Always show sub menu' => '菜单栏子菜单将始终显示',
|
'Always show sub menu' => '菜单栏子菜单将始终显示',
|
||||||
'Disable top menu badge' => '禁用顶部彩色小角标',
|
'Disable top menu badge' => '禁用顶部彩色小角标',
|
||||||
'Disable top menu badge without left menu' => '左边菜单栏的彩色小角标不受影响',
|
'Disable top menu badge without left menu' => '左边菜单栏的彩色小角标不受影响',
|
||||||
'Skins' => '皮肤',
|
'Skins' => '皮肤',
|
||||||
|
'Username must be 3 to 30 characters' => '用户名只能由3-30位数字、字母、下划线组合',
|
||||||
|
'Password must be 6 to 30 characters' => '密码长度必须在6-30位之间,不能包含空格',
|
||||||
'You\'ve logged in, do not login again' => '你已经登录,无需重复登录',
|
'You\'ve logged in, do not login again' => '你已经登录,无需重复登录',
|
||||||
'Username or password can not be empty' => '用户名密码不能为空',
|
'Username or password can not be empty' => '用户名密码不能为空',
|
||||||
'Username or password is incorrect' => '用户名或密码不正确',
|
'Username or password is incorrect' => '用户名或密码不正确',
|
||||||
'Username is incorrect' => '用户名不正确',
|
'Username is incorrect' => '用户名不正确',
|
||||||
'Password is incorrect' => '密码不正确',
|
'Password is incorrect' => '密码不正确',
|
||||||
|
'Admin is forbidden' => '管理员已经被禁止登录',
|
||||||
'Please try again after 1 day' => '请于1天后再尝试登录',
|
'Please try again after 1 day' => '请于1天后再尝试登录',
|
||||||
'Login successful' => '登录成功!',
|
'Login successful' => '登录成功!',
|
||||||
'Logout successful' => '退出成功!',
|
'Logout successful' => '退出成功!',
|
||||||
'Verification code is incorrect' => '验证码不正确',
|
'Verification code is incorrect' => '验证码不正确',
|
||||||
'Wipe cache completed' => '清除缓存成功',
|
'Wipe cache completed' => '清除缓存成功',
|
||||||
'Wipe cache failed' => '清除缓存失败',
|
'Wipe cache failed' => '清除缓存失败',
|
||||||
'Wipe cache' => '清空缓存',
|
'Wipe cache' => '清除缓存',
|
||||||
'Wipe all cache' => '一键清除缓存',
|
'Wipe all cache' => '一键清除缓存',
|
||||||
'Wipe content cache' => '清空内容缓存',
|
'Wipe content cache' => '清除内容缓存',
|
||||||
'Wipe template cache' => '清除模板缓存',
|
'Wipe template cache' => '清除模板缓存',
|
||||||
'Wipe addons cache' => '清除插件缓存',
|
'Wipe addons cache' => '清除插件缓存',
|
||||||
|
'Wipe browser cache' => '清除浏览器缓存',
|
||||||
|
'Wipe browser cache tips' => '清除浏览器端静态JS、CSS、图片等资源',
|
||||||
'Check for updates' => '检测更新',
|
'Check for updates' => '检测更新',
|
||||||
|
'Discover new version' => '发现新版本',
|
||||||
|
'Go to download' => '去下载更新',
|
||||||
|
'Currently is the latest version' => '当前已经是最新版本',
|
||||||
|
'Ignore this version' => '忽略此次更新',
|
||||||
|
'Do not remind again' => '不再提示',
|
||||||
|
'Your current version' => '你的版本是',
|
||||||
|
'New version' => '新版本',
|
||||||
|
'Release notes' => '更新说明',
|
||||||
'Latest news' => '最新消息',
|
'Latest news' => '最新消息',
|
||||||
'View more' => '查看更多',
|
'View more' => '查看更多',
|
||||||
'Links' => '相关链接',
|
'Links' => '相关链接',
|
||||||
|
|
@ -45,4 +62,6 @@ return [
|
||||||
'Forum' => '交流社区',
|
'Forum' => '交流社区',
|
||||||
'QQ qun' => 'QQ交流群',
|
'QQ qun' => 'QQ交流群',
|
||||||
'Captcha' => '验证码',
|
'Captcha' => '验证码',
|
||||||
|
'The duration of the session is %s hours' => '设定会话有效时长为%s小时',
|
||||||
|
'Security tips' => '<i class="fa fa-warning"></i> 安全提示:为了你的后台安全,请勿将后台管理入口设置为admin或admin.php',
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'Name' => '组名',
|
'Name' => '组名',
|
||||||
'Rules' => '权限节点',
|
'Rules' => '权限节点',
|
||||||
'Createtime' => '添加时间',
|
'Change password' => '修改密码',
|
||||||
'Updatetime' => '更新时间',
|
'Createtime' => '添加时间',
|
||||||
'Status' => '状态'
|
'Updatetime' => '更新时间',
|
||||||
|
'Status' => '状态'
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,19 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'Pid' => '父ID',
|
'Pid' => '父ID',
|
||||||
'Name' => '规则',
|
'Name' => '规则',
|
||||||
'Title' => '标题',
|
'Title' => '标题',
|
||||||
'Remark' => '备注',
|
'Remark' => '备注',
|
||||||
'Ismenu' => '是否菜单',
|
'Ismenu' => '是否菜单',
|
||||||
'Createtime' => '创建时间',
|
'Change password' => '修改密码',
|
||||||
'Updatetime' => '更新时间',
|
'Createtime' => '创建时间',
|
||||||
'Menu tips' => '规则任意,请不可重复,仅做层级显示,无需匹配控制器和方法',
|
'Updatetime' => '更新时间',
|
||||||
'Node tips' => '模块/控制器/方法名',
|
'Menu tips' => '规则任意,请不可重复,仅做层级显示,无需匹配控制器和方法',
|
||||||
'Weigh' => '权重',
|
'Node tips' => '模块/控制器/方法名',
|
||||||
'Status' => '状态'
|
'Weigh' => '权重',
|
||||||
|
'Status' => '状态',
|
||||||
|
'Toggle all' => '显示全部',
|
||||||
|
'Toggle menu visible' => '点击切换菜单显示',
|
||||||
|
'Toggle sub menu' => '点击切换子菜单',
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,12 @@ use fast\Random;
|
||||||
use fast\Tree;
|
use fast\Tree;
|
||||||
use think\Config;
|
use think\Config;
|
||||||
use think\Cookie;
|
use think\Cookie;
|
||||||
|
use think\Hook;
|
||||||
use think\Request;
|
use think\Request;
|
||||||
use think\Session;
|
use think\Session;
|
||||||
|
|
||||||
class Auth extends \fast\Auth
|
class Auth extends \fast\Auth
|
||||||
{
|
{
|
||||||
|
|
||||||
protected $_error = '';
|
protected $_error = '';
|
||||||
protected $requestUri = '';
|
protected $requestUri = '';
|
||||||
protected $breadcrumb = [];
|
protected $breadcrumb = [];
|
||||||
|
|
@ -31,9 +31,9 @@ class Auth extends \fast\Auth
|
||||||
/**
|
/**
|
||||||
* 管理员登录
|
* 管理员登录
|
||||||
*
|
*
|
||||||
* @param string $username 用户名
|
* @param string $username 用户名
|
||||||
* @param string $password 密码
|
* @param string $password 密码
|
||||||
* @param int $keeptime 有效时长
|
* @param int $keeptime 有效时长
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function login($username, $password, $keeptime = 0)
|
public function login($username, $password, $keeptime = 0)
|
||||||
|
|
@ -43,11 +43,15 @@ class Auth extends \fast\Auth
|
||||||
$this->setError('Username is incorrect');
|
$this->setError('Username is incorrect');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if ($admin['status'] == 'hidden') {
|
||||||
|
$this->setError('Admin is forbidden');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (Config::get('fastadmin.login_failure_retry') && $admin->loginfailure >= 10 && time() - $admin->updatetime < 86400) {
|
if (Config::get('fastadmin.login_failure_retry') && $admin->loginfailure >= 10 && time() - $admin->updatetime < 86400) {
|
||||||
$this->setError('Please try again after 1 day');
|
$this->setError('Please try again after 1 day');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ($admin->password != md5(md5($password) . $admin->salt)) {
|
if ($admin->password != $this->getEncryptPassword($password, $admin->salt)) {
|
||||||
$admin->loginfailure++;
|
$admin->loginfailure++;
|
||||||
$admin->save();
|
$admin->save();
|
||||||
$this->setError('Password is incorrect');
|
$this->setError('Password is incorrect');
|
||||||
|
|
@ -55,26 +59,29 @@ class Auth extends \fast\Auth
|
||||||
}
|
}
|
||||||
$admin->loginfailure = 0;
|
$admin->loginfailure = 0;
|
||||||
$admin->logintime = time();
|
$admin->logintime = time();
|
||||||
|
$admin->loginip = request()->ip();
|
||||||
$admin->token = Random::uuid();
|
$admin->token = Random::uuid();
|
||||||
$admin->save();
|
$admin->save();
|
||||||
Session::set("admin", $admin->toArray());
|
Session::set("admin", $admin->toArray());
|
||||||
$this->keeplogin($keeptime);
|
Session::set("admin.safecode", $this->getEncryptSafecode($admin));
|
||||||
|
$this->keeplogin($admin, $keeptime);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 注销登录
|
* 退出登录
|
||||||
*/
|
*/
|
||||||
public function logout()
|
public function logout()
|
||||||
{
|
{
|
||||||
$admin = Admin::get(intval($this->id));
|
$admin = Admin::get(intval($this->id));
|
||||||
if (!$admin) {
|
if ($admin) {
|
||||||
return true;
|
$admin->token = '';
|
||||||
|
$admin->save();
|
||||||
}
|
}
|
||||||
$admin->token = '';
|
$this->logined = false; //重置登录状态
|
||||||
$admin->save();
|
|
||||||
Session::delete("admin");
|
Session::delete("admin");
|
||||||
Cookie::delete("keeplogin");
|
Cookie::delete("keeplogin");
|
||||||
|
setcookie('fastadmin_userinfo', '', $_SERVER['REQUEST_TIME'] - 3600, rtrim(url("/" . request()->module(), '', false), '/'));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -95,12 +102,18 @@ class Auth extends \fast\Auth
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//token有变更
|
//token有变更
|
||||||
if ($key != md5(md5($id) . md5($keeptime) . md5($expiretime) . $admin->token)) {
|
if ($key != $this->getKeeploginKey($admin, $keeptime, $expiretime)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$ip = request()->ip();
|
||||||
|
//IP有变动
|
||||||
|
if ($admin->loginip != $ip) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Session::set("admin", $admin->toArray());
|
Session::set("admin", $admin->toArray());
|
||||||
|
Session::set("admin.safecode", $this->getEncryptSafecode($admin));
|
||||||
//刷新自动登录的时效
|
//刷新自动登录的时效
|
||||||
$this->keeplogin($keeptime);
|
$this->keeplogin($admin, $keeptime);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -110,47 +123,95 @@ class Auth extends \fast\Auth
|
||||||
/**
|
/**
|
||||||
* 刷新保持登录的Cookie
|
* 刷新保持登录的Cookie
|
||||||
*
|
*
|
||||||
* @param int $keeptime
|
* @param int $keeptime
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
protected function keeplogin($keeptime = 0)
|
protected function keeplogin($admin, $keeptime = 0)
|
||||||
{
|
{
|
||||||
if ($keeptime) {
|
if ($keeptime) {
|
||||||
$expiretime = time() + $keeptime;
|
$expiretime = time() + $keeptime;
|
||||||
$key = md5(md5($this->id) . md5($keeptime) . md5($expiretime) . $this->token);
|
$key = $this->getKeeploginKey($admin, $keeptime, $expiretime);
|
||||||
$data = [$this->id, $keeptime, $expiretime, $key];
|
Cookie::set('keeplogin', implode('|', [$admin['id'], $keeptime, $expiretime, $key]), $keeptime);
|
||||||
Cookie::set('keeplogin', implode('|', $data), 86400 * 30);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取密码加密后的字符串
|
||||||
|
* @param string $password 密码
|
||||||
|
* @param string $salt 密码盐
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getEncryptPassword($password, $salt = '')
|
||||||
|
{
|
||||||
|
return md5(md5($password) . $salt);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取密码加密后的自动登录码
|
||||||
|
* @param string $password 密码
|
||||||
|
* @param string $salt 密码盐
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getEncryptKeeplogin($params, $keeptime)
|
||||||
|
{
|
||||||
|
$expiretime = time() + $keeptime;
|
||||||
|
$key = md5(md5($params['id']) . md5($keeptime) . md5($expiretime) . $params['token'] . config('token.key'));
|
||||||
|
return implode('|', [$this->id, $keeptime, $expiretime, $key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取自动登录Key
|
||||||
|
* @param $params
|
||||||
|
* @param $keeptime
|
||||||
|
* @param $expiretime
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getKeeploginKey($params, $keeptime, $expiretime)
|
||||||
|
{
|
||||||
|
$key = md5(md5($params['id']) . md5($keeptime) . md5($expiretime) . $params['token'] . config('token.key'));
|
||||||
|
return $key;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取加密后的安全码
|
||||||
|
* @param $params
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getEncryptSafecode($params)
|
||||||
|
{
|
||||||
|
return md5(md5($params['username']) . md5(substr($params['password'], 0, 6)) . config('token.key'));
|
||||||
|
}
|
||||||
|
|
||||||
public function check($name, $uid = '', $relation = 'or', $mode = 'url')
|
public function check($name, $uid = '', $relation = 'or', $mode = 'url')
|
||||||
{
|
{
|
||||||
return parent::check($name, $this->id, $relation, $mode);
|
$uid = $uid ? $uid : $this->id;
|
||||||
|
return parent::check($name, $uid, $relation, $mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检测当前控制器和方法是否匹配传递的数组
|
* 检测当前控制器和方法是否匹配传递的数组
|
||||||
*
|
*
|
||||||
* @param array $arr 需要验证权限的数组
|
* @param array $arr 需要验证权限的数组
|
||||||
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function match($arr = [])
|
public function match($arr = [])
|
||||||
{
|
{
|
||||||
$request = Request::instance();
|
$request = Request::instance();
|
||||||
$arr = is_array($arr) ? $arr : explode(',', $arr);
|
$arr = is_array($arr) ? $arr : explode(',', $arr);
|
||||||
if (!$arr) {
|
if (!$arr) {
|
||||||
return FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$arr = array_map('strtolower', $arr);
|
$arr = array_map('strtolower', $arr);
|
||||||
// 是否存在
|
// 是否存在
|
||||||
if (in_array(strtolower($request->action()), $arr) || in_array('*', $arr)) {
|
if (in_array(strtolower($request->action()), $arr) || in_array('*', $arr)) {
|
||||||
return TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 没找到匹配
|
// 没找到匹配
|
||||||
return FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -167,10 +228,26 @@ class Auth extends \fast\Auth
|
||||||
if (!$admin) {
|
if (!$admin) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
$my = Admin::get($admin['id']);
|
||||||
|
if (!$my) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//校验安全码,可用于判断关键信息发生了变更需要重新登录
|
||||||
|
if (!isset($admin['safecode']) || $this->getEncryptSafecode($my) !== $admin['safecode']) {
|
||||||
|
$this->logout();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
//判断是否同一时间同一账号只能在一个地方登录
|
//判断是否同一时间同一账号只能在一个地方登录
|
||||||
if (Config::get('fastadmin.login_unique')) {
|
if (Config::get('fastadmin.login_unique')) {
|
||||||
$my = Admin::get($admin['id']);
|
if ($my['token'] != $admin['token']) {
|
||||||
if (!$my || $my['token'] != $admin['token']) {
|
$this->logout();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//判断管理员IP是否变动
|
||||||
|
if (Config::get('fastadmin.loginip_check')) {
|
||||||
|
if (!isset($admin['loginip']) || $admin['loginip'] != request()->ip()) {
|
||||||
|
$this->logout();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -223,7 +300,7 @@ class Auth extends \fast\Auth
|
||||||
|
|
||||||
public function isSuperAdmin()
|
public function isSuperAdmin()
|
||||||
{
|
{
|
||||||
return in_array('*', $this->getRuleIds()) ? TRUE : FALSE;
|
return in_array('*', $this->getRuleIds()) ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -254,17 +331,24 @@ class Auth extends \fast\Auth
|
||||||
foreach ($groups as $k => $v) {
|
foreach ($groups as $k => $v) {
|
||||||
$groupIds[] = $v['id'];
|
$groupIds[] = $v['id'];
|
||||||
}
|
}
|
||||||
|
$originGroupIds = $groupIds;
|
||||||
|
foreach ($groups as $k => $v) {
|
||||||
|
if (in_array($v['pid'], $originGroupIds)) {
|
||||||
|
$groupIds = array_diff($groupIds, [$v['id']]);
|
||||||
|
unset($groups[$k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
// 取出所有分组
|
// 取出所有分组
|
||||||
$groupList = \app\admin\model\AuthGroup::where(['status' => 'normal'])->select();
|
$groupList = \app\admin\model\AuthGroup::where($this->isSuperAdmin() ? '1=1' : ['status' => 'normal'])->select();
|
||||||
$objList = [];
|
$objList = [];
|
||||||
foreach ($groups as $K => $v) {
|
foreach ($groups as $k => $v) {
|
||||||
if ($v['rules'] === '*') {
|
if ($v['rules'] === '*') {
|
||||||
$objList = $groupList;
|
$objList = $groupList;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// 取出包含自己的所有子节点
|
// 取出包含自己的所有子节点
|
||||||
$childrenList = Tree::instance()->init($groupList)->getChildren($v['id'], true);
|
$childrenList = Tree::instance()->init($groupList, 'pid')->getChildren($v['id'], true);
|
||||||
$obj = Tree::instance()->init($childrenList)->getTreeArray($v['pid']);
|
$obj = Tree::instance()->init($childrenList, 'pid')->getTreeArray($v['pid']);
|
||||||
$objList = array_merge($objList, Tree::instance()->getTreeList($obj));
|
$objList = array_merge($objList, Tree::instance()->getTreeList($obj));
|
||||||
}
|
}
|
||||||
$childrenGroupIds = [];
|
$childrenGroupIds = [];
|
||||||
|
|
@ -287,11 +371,9 @@ class Auth extends \fast\Auth
|
||||||
$childrenAdminIds = [];
|
$childrenAdminIds = [];
|
||||||
if (!$this->isSuperAdmin()) {
|
if (!$this->isSuperAdmin()) {
|
||||||
$groupIds = $this->getChildrenGroupIds(false);
|
$groupIds = $this->getChildrenGroupIds(false);
|
||||||
$authGroupList = \app\admin\model\AuthGroupAccess::
|
$authGroupList = \app\admin\model\AuthGroupAccess::field('uid,group_id')
|
||||||
field('uid,group_id')
|
|
||||||
->where('group_id', 'in', $groupIds)
|
->where('group_id', 'in', $groupIds)
|
||||||
->select();
|
->select();
|
||||||
|
|
||||||
foreach ($authGroupList as $k => $v) {
|
foreach ($authGroupList as $k => $v) {
|
||||||
$childrenAdminIds[] = $v['uid'];
|
$childrenAdminIds[] = $v['uid'];
|
||||||
}
|
}
|
||||||
|
|
@ -316,44 +398,53 @@ class Auth extends \fast\Auth
|
||||||
*/
|
*/
|
||||||
public function getBreadCrumb($path = '')
|
public function getBreadCrumb($path = '')
|
||||||
{
|
{
|
||||||
if ($this->breadcrumb || !$path)
|
if ($this->breadcrumb || !$path) {
|
||||||
return $this->breadcrumb;
|
return $this->breadcrumb;
|
||||||
$path_rule_id = 0;
|
|
||||||
foreach ($this->rules as $rule) {
|
|
||||||
$path_rule_id = $rule['name'] == $path ? $rule['id'] : $path_rule_id;
|
|
||||||
}
|
}
|
||||||
if ($path_rule_id) {
|
$titleArr = [];
|
||||||
$this->breadcrumb = Tree::instance()->init($this->rules)->getParents($path_rule_id, true);
|
$menuArr = [];
|
||||||
foreach ($this->breadcrumb as $k => &$v) {
|
$urlArr = explode('/', $path);
|
||||||
$v['url'] = url($v['name']);
|
foreach ($urlArr as $index => $item) {
|
||||||
$v['title'] = __($v['title']);
|
$pathArr[implode('/', array_slice($urlArr, 0, $index + 1))] = $index;
|
||||||
|
}
|
||||||
|
if (!$this->rules && $this->id) {
|
||||||
|
$this->getRuleList();
|
||||||
|
}
|
||||||
|
foreach ($this->rules as $rule) {
|
||||||
|
if (isset($pathArr[$rule['name']])) {
|
||||||
|
$rule['title'] = __($rule['title']);
|
||||||
|
$rule['url'] = url($rule['name']);
|
||||||
|
$titleArr[$pathArr[$rule['name']]] = $rule['title'];
|
||||||
|
$menuArr[$pathArr[$rule['name']]] = $rule;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ksort($menuArr);
|
||||||
|
$this->breadcrumb = $menuArr;
|
||||||
return $this->breadcrumb;
|
return $this->breadcrumb;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取左侧和顶部菜单栏
|
* 获取左侧和顶部菜单栏
|
||||||
*
|
*
|
||||||
* @param array $params URL对应的badge数据
|
* @param array $params URL对应的badge数据
|
||||||
* @param string $fixedPage 默认页
|
* @param string $fixedPage 默认页
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function getSidebar($params = [], $fixedPage = 'dashboard')
|
public function getSidebar($params = [], $fixedPage = 'dashboard')
|
||||||
{
|
{
|
||||||
|
// 边栏开始
|
||||||
|
Hook::listen("admin_sidebar_begin", $params);
|
||||||
$colorArr = ['red', 'green', 'yellow', 'blue', 'teal', 'orange', 'purple'];
|
$colorArr = ['red', 'green', 'yellow', 'blue', 'teal', 'orange', 'purple'];
|
||||||
$colorNums = count($colorArr);
|
$colorNums = count($colorArr);
|
||||||
$badgeList = [];
|
$badgeList = [];
|
||||||
$module = request()->module();
|
$module = request()->module();
|
||||||
// 生成菜单的badge
|
// 生成菜单的badge
|
||||||
foreach ($params as $k => $v) {
|
foreach ($params as $k => $v) {
|
||||||
|
|
||||||
$url = $k;
|
$url = $k;
|
||||||
|
|
||||||
if (is_array($v)) {
|
if (is_array($v)) {
|
||||||
$nums = isset($v[0]) ? $v[0] : 0;
|
$nums = $v[0] ?? 0;
|
||||||
$color = isset($v[1]) ? $v[1] : $colorArr[(is_numeric($nums) ? $nums : strlen($nums)) % $colorNums];
|
$color = $v[1] ?? $colorArr[(is_numeric($nums) ? $nums : strlen($nums)) % $colorNums];
|
||||||
$class = isset($v[2]) ? $v[2] : 'label';
|
$class = $v[2] ?? 'label';
|
||||||
} else {
|
} else {
|
||||||
$nums = $v;
|
$nums = $v;
|
||||||
$color = $colorArr[(is_numeric($nums) ? $nums : strlen($nums)) % $colorNums];
|
$color = $colorArr[(is_numeric($nums) ? $nums : strlen($nums)) % $colorNums];
|
||||||
|
|
@ -367,24 +458,53 @@ class Auth extends \fast\Auth
|
||||||
|
|
||||||
// 读取管理员当前拥有的权限节点
|
// 读取管理员当前拥有的权限节点
|
||||||
$userRule = $this->getRuleList();
|
$userRule = $this->getRuleList();
|
||||||
$select_id = 0;
|
$selected = $referer = [];
|
||||||
$pinyin = new \Overtrue\Pinyin\Pinyin('Overtrue\Pinyin\MemoryFileDictLoader');
|
$refererUrl = Session::get('referer');
|
||||||
// 必须将结果集转换为数组
|
// 必须将结果集转换为数组
|
||||||
$ruleList = collection(\app\admin\model\AuthRule::where('status', 'normal')->where('ismenu', 1)->order('weigh', 'desc')->cache("__menu__")->select())->toArray();
|
$ruleList = collection(\app\admin\model\AuthRule::where('status', 'normal')
|
||||||
|
->where('ismenu', 1)
|
||||||
|
->order('weigh', 'desc')
|
||||||
|
->cache("__menu__")
|
||||||
|
->select())->toArray();
|
||||||
|
$indexRuleList = \app\admin\model\AuthRule::where('status', 'normal')
|
||||||
|
->where('ismenu', 0)
|
||||||
|
->where('name', 'like', '%/index')
|
||||||
|
->column('name,pid');
|
||||||
|
$pidArr = array_unique(array_filter(array_column($ruleList, 'pid')));
|
||||||
foreach ($ruleList as $k => &$v) {
|
foreach ($ruleList as $k => &$v) {
|
||||||
if (!in_array($v['name'], $userRule)) {
|
if (!in_array(strtolower($v['name']), $userRule)) {
|
||||||
unset($ruleList[$k]);
|
unset($ruleList[$k]);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$select_id = $v['name'] == $fixedPage ? $v['id'] : $select_id;
|
$indexRuleName = $v['name'] . '/index';
|
||||||
$v['url'] = '/' . $module . '/' . $v['name'];
|
if (isset($indexRuleList[$indexRuleName]) && !in_array($indexRuleName, $userRule)) {
|
||||||
$v['badge'] = isset($badgeList[$v['name']]) ? $badgeList[$v['name']] : '';
|
unset($ruleList[$k]);
|
||||||
$v['py'] = $pinyin->abbr($v['title'], '');
|
continue;
|
||||||
$v['pinyin'] = $pinyin->permalink($v['title'], '');
|
}
|
||||||
|
$v['icon'] = $v['icon'] . ' fa-fw';
|
||||||
|
$v['url'] = isset($v['url']) && $v['url'] ? $v['url'] : '/' . $module . '/' . $v['name'];
|
||||||
|
$v['badge'] = $badgeList[$v['name']] ?? '';
|
||||||
$v['title'] = __($v['title']);
|
$v['title'] = __($v['title']);
|
||||||
|
$v['url'] = preg_match("/^((?:[a-z]+:)?\/\/|data:image\/)(.*)/i", $v['url']) ? $v['url'] : url($v['url']);
|
||||||
|
$v['menuclass'] = in_array($v['menutype'], ['dialog', 'ajax']) ? 'btn-' . $v['menutype'] : '';
|
||||||
|
$v['menutabs'] = !$v['menutype'] || in_array($v['menutype'], ['default', 'addtabs']) ? 'addtabs="' . $v['id'] . '"' : '';
|
||||||
|
$selected = $v['name'] == $fixedPage ? $v : $selected;
|
||||||
|
$referer = $v['url'] == $refererUrl ? $v : $referer;
|
||||||
|
}
|
||||||
|
$lastArr = array_unique(array_filter(array_column($ruleList, 'pid')));
|
||||||
|
$pidDiffArr = array_diff($pidArr, $lastArr);
|
||||||
|
foreach ($ruleList as $index => $item) {
|
||||||
|
if (in_array($item['id'], $pidDiffArr)) {
|
||||||
|
unset($ruleList[$index]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($selected == $referer) {
|
||||||
|
$referer = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$select_id = $referer ? $referer['id'] : ($selected ? $selected['id'] : 0);
|
||||||
$menu = $nav = '';
|
$menu = $nav = '';
|
||||||
|
$showSubmenu = config('fastadmin.show_submenu');
|
||||||
if (Config::get('fastadmin.multiplenav')) {
|
if (Config::get('fastadmin.multiplenav')) {
|
||||||
$topList = [];
|
$topList = [];
|
||||||
foreach ($ruleList as $index => $item) {
|
foreach ($ruleList as $index => $item) {
|
||||||
|
|
@ -399,27 +519,51 @@ class Auth extends \fast\Auth
|
||||||
$selectParentIds = $tree->getParentsIds($select_id, true);
|
$selectParentIds = $tree->getParentsIds($select_id, true);
|
||||||
}
|
}
|
||||||
foreach ($topList as $index => $item) {
|
foreach ($topList as $index => $item) {
|
||||||
$childList = Tree::instance()->getTreeMenu($item['id'], '<li class="@class" pid="@pid"><a href="@url@addtabs" addtabs="@id" url="@url" py="@py" pinyin="@pinyin"><i class="@icon"></i> <span>@title</span> <span class="pull-right-container">@caret @badge</span></a> @childlist</li>', $select_id, '', 'ul', 'class="treeview-menu"');
|
$childList = Tree::instance()->getTreeMenu(
|
||||||
|
$item['id'],
|
||||||
|
'<li class="@class" pid="@pid"><a @extend href="@url@addtabs" addtabs="@id" class="@menuclass" url="@url" py="@py" pinyin="@pinyin"><i class="@icon"></i> <span>@title</span> <span class="pull-right-container">@caret @badge</span></a> @childlist</li>',
|
||||||
|
$select_id,
|
||||||
|
'',
|
||||||
|
'ul',
|
||||||
|
'class="treeview-menu' . ($showSubmenu ? ' menu-open' : '') . '"'
|
||||||
|
);
|
||||||
$current = in_array($item['id'], $selectParentIds);
|
$current = in_array($item['id'], $selectParentIds);
|
||||||
$url = $childList ? 'javascript:;' : $item['url'];
|
$url = $childList ? 'javascript:;' : $item['url'];
|
||||||
$childList = str_replace('" pid="' . $item['id'] . '"', ' treeview ' . ($current ? '' : 'hidden') . '" pid="' . $item['id'] . '"', $childList);
|
$addtabs = $childList || !$url ? "" : (stripos($url, "?") !== false ? "&" : "?") . "ref=" . ($item['menutype'] ? $item['menutype'] : 'addtabs');
|
||||||
$nav .= '<li class="' . ($current ? 'active' : '') . '"><a href="' . $url . '" addtabs="' . $item['id'] . '" url="' . $url . '"><i class="' . $item['icon'] . '"></i> <span>' . $item['title'] . '</span> <span class="pull-right-container"> </span></a> </li>';
|
$childList = str_replace(
|
||||||
|
'" pid="' . $item['id'] . '"',
|
||||||
|
' ' . ($current ? '' : 'hidden') . '" pid="' . $item['id'] . '"',
|
||||||
|
$childList
|
||||||
|
);
|
||||||
|
$nav .= '<li class="' . ($current ? 'active' : '') . '"><a ' . $item['extend'] . ' href="' . $url . $addtabs . '" ' . $item['menutabs'] . ' class="' . $item['menuclass'] . '" url="' . $url . '" title="' . $item['title'] . '"><i class="' . $item['icon'] . '"></i> <span>' . $item['title'] . '</span> <span class="pull-right-container"> </span></a> </li>';
|
||||||
$menu .= $childList;
|
$menu .= $childList;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 构造菜单数据
|
// 构造菜单数据
|
||||||
Tree::instance()->init($ruleList);
|
Tree::instance()->init($ruleList);
|
||||||
$menu = Tree::instance()->getTreeMenu(0, '<li class="@class"><a href="@url@addtabs" addtabs="@id" url="@url" py="@py" pinyin="@pinyin"><i class="@icon"></i> <span>@title</span> <span class="pull-right-container">@caret @badge</span></a> @childlist</li>', $select_id, '', 'ul', 'class="treeview-menu"');
|
$menu = Tree::instance()->getTreeMenu(
|
||||||
|
0,
|
||||||
|
'<li class="@class"><a @extend href="@url@addtabs" @menutabs class="@menuclass" url="@url" py="@py" pinyin="@pinyin"><i class="@icon"></i> <span>@title</span> <span class="pull-right-container">@caret @badge</span></a> @childlist</li>',
|
||||||
|
$select_id,
|
||||||
|
'',
|
||||||
|
'ul',
|
||||||
|
'class="treeview-menu' . ($showSubmenu ? ' menu-open' : '') . '"'
|
||||||
|
);
|
||||||
|
if ($selected) {
|
||||||
|
$nav .= '<li role="presentation" id="tab_' . $selected['id'] . '" class="' . ($referer ? '' : 'active') . '"><a href="#con_' . $selected['id'] . '" node-id="' . $selected['id'] . '" aria-controls="' . $selected['id'] . '" role="tab" data-toggle="tab"><i class="' . $selected['icon'] . ' fa-fw"></i> <span>' . $selected['title'] . '</span> </a></li>';
|
||||||
|
}
|
||||||
|
if ($referer) {
|
||||||
|
$nav .= '<li role="presentation" id="tab_' . $referer['id'] . '" class="active"><a href="#con_' . $referer['id'] . '" node-id="' . $referer['id'] . '" aria-controls="' . $referer['id'] . '" role="tab" data-toggle="tab"><i class="' . $referer['icon'] . ' fa-fw"></i> <span>' . $referer['title'] . '</span> </a> <i class="close-tab fa fa-remove"></i></li>';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return [$menu, $nav, $selected, $referer];
|
||||||
return [$menu, $nav];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置错误信息
|
* 设置错误信息
|
||||||
*
|
*
|
||||||
* @param $error 错误信息
|
* @param string $error 错误信息
|
||||||
* @return Auth
|
* @return Auth
|
||||||
*/
|
*/
|
||||||
public function setError($error)
|
public function setError($error)
|
||||||
|
|
@ -436,5 +580,4 @@ class Auth extends \fast\Auth
|
||||||
{
|
{
|
||||||
return $this->_error ? __($this->_error) : '';
|
return $this->_error ? __($this->_error) : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,248 +2,294 @@
|
||||||
|
|
||||||
namespace app\admin\library\traits;
|
namespace app\admin\library\traits;
|
||||||
|
|
||||||
|
use app\admin\library\Auth;
|
||||||
|
use Exception;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Reader\Xls;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Reader\Csv;
|
||||||
|
use think\Db;
|
||||||
|
use think\db\exception\BindParamException;
|
||||||
|
use think\db\exception\DataNotFoundException;
|
||||||
|
use think\db\exception\ModelNotFoundException;
|
||||||
|
use think\exception\DbException;
|
||||||
|
use think\exception\PDOException;
|
||||||
|
use think\exception\ValidateException;
|
||||||
|
use think\response\Json;
|
||||||
|
|
||||||
trait Backend
|
trait Backend
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* 排除前台提交过来的字段
|
||||||
|
* @param $params
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function preExcludeFields($params)
|
||||||
|
{
|
||||||
|
if (is_array($this->excludeFields)) {
|
||||||
|
foreach ($this->excludeFields as $field) {
|
||||||
|
if (array_key_exists($field, $params)) {
|
||||||
|
unset($params[$field]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (array_key_exists($this->excludeFields, $params)) {
|
||||||
|
unset($params[$this->excludeFields]);
|
||||||
|
}
|
||||||
|
return $params;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查看
|
* 查看
|
||||||
|
*
|
||||||
|
* @return string|Json
|
||||||
|
* @throws \think\Exception
|
||||||
|
* @throws DbException
|
||||||
*/
|
*/
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
//设置过滤方法
|
//设置过滤方法
|
||||||
$this->request->filter(['strip_tags']);
|
$this->request->filter(['strip_tags', 'trim']);
|
||||||
if ($this->request->isAjax())
|
if (false === $this->request->isAjax()) {
|
||||||
{
|
return $this->view->fetch();
|
||||||
//如果发送的来源是Selectpage,则转发到Selectpage
|
|
||||||
if ($this->request->request('keyField'))
|
|
||||||
{
|
|
||||||
return $this->selectpage();
|
|
||||||
}
|
|
||||||
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
|
|
||||||
$total = $this->model
|
|
||||||
->where($where)
|
|
||||||
->order($sort, $order)
|
|
||||||
->count();
|
|
||||||
|
|
||||||
$list = $this->model
|
|
||||||
->where($where)
|
|
||||||
->order($sort, $order)
|
|
||||||
->limit($offset, $limit)
|
|
||||||
->select();
|
|
||||||
|
|
||||||
$list = collection($list)->toArray();
|
|
||||||
$result = array("total" => $total, "rows" => $list);
|
|
||||||
|
|
||||||
return json($result);
|
|
||||||
}
|
}
|
||||||
return $this->view->fetch();
|
//如果发送的来源是 Selectpage,则转发到 Selectpage
|
||||||
|
if ($this->request->request('keyField')) {
|
||||||
|
return $this->selectpage();
|
||||||
|
}
|
||||||
|
[$where, $sort, $order, $offset, $limit] = $this->buildparams();
|
||||||
|
$list = $this->model
|
||||||
|
->where($where)
|
||||||
|
->order($sort, $order)
|
||||||
|
->paginate($limit);
|
||||||
|
$result = ['total' => $list->total(), 'rows' => $list->items()];
|
||||||
|
return json($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 回收站
|
* 回收站
|
||||||
|
*
|
||||||
|
* @return string|Json
|
||||||
|
* @throws \think\Exception
|
||||||
*/
|
*/
|
||||||
public function recyclebin()
|
public function recyclebin()
|
||||||
{
|
{
|
||||||
//设置过滤方法
|
//设置过滤方法
|
||||||
$this->request->filter(['strip_tags']);
|
$this->request->filter(['strip_tags', 'trim']);
|
||||||
if ($this->request->isAjax())
|
if (false === $this->request->isAjax()) {
|
||||||
{
|
return $this->view->fetch();
|
||||||
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
|
|
||||||
$total = $this->model
|
|
||||||
->onlyTrashed()
|
|
||||||
->where($where)
|
|
||||||
->order($sort, $order)
|
|
||||||
->count();
|
|
||||||
|
|
||||||
$list = $this->model
|
|
||||||
->onlyTrashed()
|
|
||||||
->where($where)
|
|
||||||
->order($sort, $order)
|
|
||||||
->limit($offset, $limit)
|
|
||||||
->select();
|
|
||||||
|
|
||||||
$result = array("total" => $total, "rows" => $list);
|
|
||||||
|
|
||||||
return json($result);
|
|
||||||
}
|
}
|
||||||
return $this->view->fetch();
|
[$where, $sort, $order, $offset, $limit] = $this->buildparams();
|
||||||
|
$list = $this->model
|
||||||
|
->onlyTrashed()
|
||||||
|
->where($where)
|
||||||
|
->order($sort, $order)
|
||||||
|
->paginate($limit);
|
||||||
|
$result = ['total' => $list->total(), 'rows' => $list->items()];
|
||||||
|
return json($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加
|
* 添加
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @throws \think\Exception
|
||||||
*/
|
*/
|
||||||
public function add()
|
public function add()
|
||||||
{
|
{
|
||||||
if ($this->request->isPost())
|
if (false === $this->request->isPost()) {
|
||||||
{
|
return $this->view->fetch();
|
||||||
$params = $this->request->post("row/a");
|
}
|
||||||
if ($params)
|
$params = $this->request->post('row/a');
|
||||||
{
|
if (empty($params)) {
|
||||||
if ($this->dataLimit && $this->dataLimitFieldAutoFill)
|
|
||||||
{
|
|
||||||
$params[$this->dataLimitField] = $this->auth->id;
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
//是否采用模型验证
|
|
||||||
if ($this->modelValidate)
|
|
||||||
{
|
|
||||||
$name = basename(str_replace('\\', '/', get_class($this->model)));
|
|
||||||
$validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : true) : $this->modelValidate;
|
|
||||||
$this->model->validate($validate);
|
|
||||||
}
|
|
||||||
$result = $this->model->allowField(true)->save($params);
|
|
||||||
if ($result !== false)
|
|
||||||
{
|
|
||||||
$this->success();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$this->error($this->model->getError());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (\think\exception\PDOException $e)
|
|
||||||
{
|
|
||||||
$this->error($e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$this->error(__('Parameter %s can not be empty', ''));
|
$this->error(__('Parameter %s can not be empty', ''));
|
||||||
}
|
}
|
||||||
return $this->view->fetch();
|
$params = $this->preExcludeFields($params);
|
||||||
|
|
||||||
|
if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
|
||||||
|
$params[$this->dataLimitField] = $this->auth->id;
|
||||||
|
}
|
||||||
|
$result = false;
|
||||||
|
Db::startTrans();
|
||||||
|
try {
|
||||||
|
//是否采用模型验证
|
||||||
|
if ($this->modelValidate) {
|
||||||
|
$name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
|
||||||
|
$validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : $name) : $this->modelValidate;
|
||||||
|
$this->model->validateFailException()->validate($validate);
|
||||||
|
}
|
||||||
|
$result = $this->model->allowField(true)->save($params);
|
||||||
|
Db::commit();
|
||||||
|
} catch (ValidateException|PDOException|Exception $e) {
|
||||||
|
Db::rollback();
|
||||||
|
$this->error($e->getMessage());
|
||||||
|
}
|
||||||
|
if ($result === false) {
|
||||||
|
$this->error(__('No rows were inserted'));
|
||||||
|
}
|
||||||
|
$this->success();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 编辑
|
* 编辑
|
||||||
|
*
|
||||||
|
* @param $ids
|
||||||
|
* @return string
|
||||||
|
* @throws DbException
|
||||||
|
* @throws \think\Exception
|
||||||
*/
|
*/
|
||||||
public function edit($ids = NULL)
|
public function edit($ids = null)
|
||||||
{
|
{
|
||||||
$row = $this->model->get($ids);
|
$row = $this->model->get($ids);
|
||||||
if (!$row)
|
if (!$row) {
|
||||||
$this->error(__('No Results were found'));
|
$this->error(__('No Results were found'));
|
||||||
$adminIds = $this->getDataLimitAdminIds();
|
|
||||||
if (is_array($adminIds))
|
|
||||||
{
|
|
||||||
if (!in_array($row[$this->dataLimitField], $adminIds))
|
|
||||||
{
|
|
||||||
$this->error(__('You have no permission'));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if ($this->request->isPost())
|
$adminIds = $this->getDataLimitAdminIds();
|
||||||
{
|
if (is_array($adminIds) && !in_array($row[$this->dataLimitField], $adminIds)) {
|
||||||
$params = $this->request->post("row/a");
|
$this->error(__('You have no permission'));
|
||||||
if ($params)
|
}
|
||||||
{
|
if (false === $this->request->isPost()) {
|
||||||
try
|
$this->view->assign('row', $row);
|
||||||
{
|
return $this->view->fetch();
|
||||||
//是否采用模型验证
|
}
|
||||||
if ($this->modelValidate)
|
$params = $this->request->post('row/a');
|
||||||
{
|
if (empty($params)) {
|
||||||
$name = basename(str_replace('\\', '/', get_class($this->model)));
|
|
||||||
$validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : true) : $this->modelValidate;
|
|
||||||
$row->validate($validate);
|
|
||||||
}
|
|
||||||
$result = $row->allowField(true)->save($params);
|
|
||||||
if ($result !== false)
|
|
||||||
{
|
|
||||||
$this->success();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$this->error($row->getError());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (\think\exception\PDOException $e)
|
|
||||||
{
|
|
||||||
$this->error($e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$this->error(__('Parameter %s can not be empty', ''));
|
$this->error(__('Parameter %s can not be empty', ''));
|
||||||
}
|
}
|
||||||
$this->view->assign("row", $row);
|
$params = $this->preExcludeFields($params);
|
||||||
return $this->view->fetch();
|
$result = false;
|
||||||
|
Db::startTrans();
|
||||||
|
try {
|
||||||
|
//是否采用模型验证
|
||||||
|
if ($this->modelValidate) {
|
||||||
|
$name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
|
||||||
|
$validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate;
|
||||||
|
$row->validateFailException()->validate($validate);
|
||||||
|
}
|
||||||
|
$result = $row->allowField(true)->save($params);
|
||||||
|
Db::commit();
|
||||||
|
} catch (ValidateException|PDOException|Exception $e) {
|
||||||
|
Db::rollback();
|
||||||
|
$this->error($e->getMessage());
|
||||||
|
}
|
||||||
|
if (false === $result) {
|
||||||
|
$this->error(__('No rows were updated'));
|
||||||
|
}
|
||||||
|
$this->success();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除
|
* 删除
|
||||||
|
*
|
||||||
|
* @param $ids
|
||||||
|
* @return void
|
||||||
|
* @throws DbException
|
||||||
|
* @throws DataNotFoundException
|
||||||
|
* @throws ModelNotFoundException
|
||||||
*/
|
*/
|
||||||
public function del($ids = "")
|
public function del($ids = null)
|
||||||
{
|
{
|
||||||
if ($ids)
|
if (false === $this->request->isPost()) {
|
||||||
{
|
$this->error(__("Invalid parameters"));
|
||||||
$pk = $this->model->getPk();
|
|
||||||
$adminIds = $this->getDataLimitAdminIds();
|
|
||||||
if (is_array($adminIds))
|
|
||||||
{
|
|
||||||
$count = $this->model->where($this->dataLimitField, 'in', $adminIds);
|
|
||||||
}
|
|
||||||
$list = $this->model->where($pk, 'in', $ids)->select();
|
|
||||||
$count = 0;
|
|
||||||
foreach ($list as $k => $v)
|
|
||||||
{
|
|
||||||
$count += $v->delete();
|
|
||||||
}
|
|
||||||
if ($count)
|
|
||||||
{
|
|
||||||
$this->success();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$this->error(__('No rows were deleted'));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
$this->error(__('Parameter %s can not be empty', 'ids'));
|
$ids = $ids ?: $this->request->post("ids");
|
||||||
|
if (empty($ids)) {
|
||||||
|
$this->error(__('Parameter %s can not be empty', 'ids'));
|
||||||
|
}
|
||||||
|
$pk = $this->model->getPk();
|
||||||
|
$adminIds = $this->getDataLimitAdminIds();
|
||||||
|
if (is_array($adminIds)) {
|
||||||
|
$this->model->where($this->dataLimitField, 'in', $adminIds);
|
||||||
|
}
|
||||||
|
$list = $this->model->where($pk, 'in', $ids)->select();
|
||||||
|
|
||||||
|
$count = 0;
|
||||||
|
Db::startTrans();
|
||||||
|
try {
|
||||||
|
foreach ($list as $item) {
|
||||||
|
$count += $item->delete();
|
||||||
|
}
|
||||||
|
Db::commit();
|
||||||
|
} catch (PDOException|Exception $e) {
|
||||||
|
Db::rollback();
|
||||||
|
$this->error($e->getMessage());
|
||||||
|
}
|
||||||
|
if ($count) {
|
||||||
|
$this->success();
|
||||||
|
}
|
||||||
|
$this->error(__('No rows were deleted'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 真实删除
|
* 真实删除
|
||||||
|
*
|
||||||
|
* @param $ids
|
||||||
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function destroy($ids = "")
|
public function destroy($ids = null)
|
||||||
{
|
{
|
||||||
|
if (false === $this->request->isPost()) {
|
||||||
|
$this->error(__("Invalid parameters"));
|
||||||
|
}
|
||||||
|
$ids = $ids ?: $this->request->post('ids');
|
||||||
$pk = $this->model->getPk();
|
$pk = $this->model->getPk();
|
||||||
$adminIds = $this->getDataLimitAdminIds();
|
$adminIds = $this->getDataLimitAdminIds();
|
||||||
if (is_array($adminIds))
|
if (is_array($adminIds)) {
|
||||||
{
|
$this->model->where($this->dataLimitField, 'in', $adminIds);
|
||||||
$count = $this->model->where($this->dataLimitField, 'in', $adminIds);
|
|
||||||
}
|
}
|
||||||
if ($ids)
|
if ($ids) {
|
||||||
{
|
|
||||||
$this->model->where($pk, 'in', $ids);
|
$this->model->where($pk, 'in', $ids);
|
||||||
}
|
}
|
||||||
$count = 0;
|
$count = 0;
|
||||||
$list = $this->model->onlyTrashed()->select();
|
Db::startTrans();
|
||||||
foreach ($list as $k => $v)
|
try {
|
||||||
{
|
$list = $this->model->onlyTrashed()->select();
|
||||||
$count += $v->delete(true);
|
foreach ($list as $item) {
|
||||||
|
$count += $item->delete(true);
|
||||||
|
}
|
||||||
|
Db::commit();
|
||||||
|
} catch (PDOException|Exception $e) {
|
||||||
|
Db::rollback();
|
||||||
|
$this->error($e->getMessage());
|
||||||
}
|
}
|
||||||
if ($count)
|
if ($count) {
|
||||||
{
|
|
||||||
$this->success();
|
$this->success();
|
||||||
}
|
}
|
||||||
else
|
$this->error(__('No rows were deleted'));
|
||||||
{
|
|
||||||
$this->error(__('No rows were deleted'));
|
|
||||||
}
|
|
||||||
$this->error(__('Parameter %s can not be empty', 'ids'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 还原
|
* 还原
|
||||||
|
*
|
||||||
|
* @param $ids
|
||||||
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function restore($ids = "")
|
public function restore($ids = null)
|
||||||
{
|
{
|
||||||
|
if (false === $this->request->isPost()) {
|
||||||
|
$this->error(__('Invalid parameters'));
|
||||||
|
}
|
||||||
|
$ids = $ids ?: $this->request->post('ids');
|
||||||
$pk = $this->model->getPk();
|
$pk = $this->model->getPk();
|
||||||
$adminIds = $this->getDataLimitAdminIds();
|
$adminIds = $this->getDataLimitAdminIds();
|
||||||
if (is_array($adminIds))
|
if (is_array($adminIds)) {
|
||||||
{
|
|
||||||
$this->model->where($this->dataLimitField, 'in', $adminIds);
|
$this->model->where($this->dataLimitField, 'in', $adminIds);
|
||||||
}
|
}
|
||||||
if ($ids)
|
if ($ids) {
|
||||||
{
|
|
||||||
$this->model->where($pk, 'in', $ids);
|
$this->model->where($pk, 'in', $ids);
|
||||||
}
|
}
|
||||||
$count = $this->model->restore('1=1');
|
$count = 0;
|
||||||
if ($count)
|
Db::startTrans();
|
||||||
{
|
try {
|
||||||
|
$list = $this->model->onlyTrashed()->select();
|
||||||
|
foreach ($list as $item) {
|
||||||
|
$count += $item->restore();
|
||||||
|
}
|
||||||
|
Db::commit();
|
||||||
|
} catch (PDOException|Exception $e) {
|
||||||
|
Db::rollback();
|
||||||
|
$this->error($e->getMessage());
|
||||||
|
}
|
||||||
|
if ($count) {
|
||||||
$this->success();
|
$this->success();
|
||||||
}
|
}
|
||||||
$this->error(__('No rows were updated'));
|
$this->error(__('No rows were updated'));
|
||||||
|
|
@ -251,70 +297,97 @@ trait Backend
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 批量更新
|
* 批量更新
|
||||||
|
*
|
||||||
|
* @param $ids
|
||||||
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function multi($ids = "")
|
public function multi($ids = null)
|
||||||
{
|
{
|
||||||
$ids = $ids ? $ids : $this->request->param("ids");
|
if (false === $this->request->isPost()) {
|
||||||
if ($ids)
|
$this->error(__('Invalid parameters'));
|
||||||
{
|
|
||||||
if ($this->request->has('params'))
|
|
||||||
{
|
|
||||||
parse_str($this->request->post("params"), $values);
|
|
||||||
$values = array_intersect_key($values, array_flip(is_array($this->multiFields) ? $this->multiFields : explode(',', $this->multiFields)));
|
|
||||||
if ($values)
|
|
||||||
{
|
|
||||||
$adminIds = $this->getDataLimitAdminIds();
|
|
||||||
if (is_array($adminIds))
|
|
||||||
{
|
|
||||||
$this->model->where($this->dataLimitField, 'in', $adminIds);
|
|
||||||
}
|
|
||||||
$this->model->where($this->model->getPk(), 'in', $ids);
|
|
||||||
$count = $this->model->allowField(true)->isUpdate(true)->save($values);
|
|
||||||
if ($count)
|
|
||||||
{
|
|
||||||
$this->success();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$this->error(__('No rows were updated'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$this->error(__('You have no permission'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
$this->error(__('Parameter %s can not be empty', 'ids'));
|
$ids = $ids ?: $this->request->post('ids');
|
||||||
|
if (empty($ids)) {
|
||||||
|
$this->error(__('Parameter %s can not be empty', 'ids'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (false === $this->request->has('params')) {
|
||||||
|
$this->error(__('No rows were updated'));
|
||||||
|
}
|
||||||
|
parse_str($this->request->post('params'), $values);
|
||||||
|
$values = $this->auth->isSuperAdmin() ? $values : array_intersect_key($values, array_flip(is_array($this->multiFields) ? $this->multiFields : explode(',', $this->multiFields)));
|
||||||
|
if (empty($values)) {
|
||||||
|
$this->error(__('You have no permission'));
|
||||||
|
}
|
||||||
|
$adminIds = $this->getDataLimitAdminIds();
|
||||||
|
if (is_array($adminIds)) {
|
||||||
|
$this->model->where($this->dataLimitField, 'in', $adminIds);
|
||||||
|
}
|
||||||
|
$count = 0;
|
||||||
|
Db::startTrans();
|
||||||
|
try {
|
||||||
|
$list = $this->model->where($this->model->getPk(), 'in', $ids)->select();
|
||||||
|
foreach ($list as $item) {
|
||||||
|
$count += $item->allowField(true)->isUpdate(true)->save($values);
|
||||||
|
}
|
||||||
|
Db::commit();
|
||||||
|
} catch (PDOException|Exception $e) {
|
||||||
|
Db::rollback();
|
||||||
|
$this->error($e->getMessage());
|
||||||
|
}
|
||||||
|
if ($count) {
|
||||||
|
$this->success();
|
||||||
|
}
|
||||||
|
$this->error(__('No rows were updated'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 导入
|
* 导入
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @throws PDOException
|
||||||
|
* @throws BindParamException
|
||||||
*/
|
*/
|
||||||
protected function import()
|
protected function import()
|
||||||
{
|
{
|
||||||
$file = $this->request->request('file');
|
$file = $this->request->request('file');
|
||||||
if (!$file)
|
if (!$file) {
|
||||||
{
|
|
||||||
$this->error(__('Parameter %s can not be empty', 'file'));
|
$this->error(__('Parameter %s can not be empty', 'file'));
|
||||||
}
|
}
|
||||||
$filePath = ROOT_PATH . DS . 'public' . DS . $file;
|
$filePath = ROOT_PATH . DS . 'public' . DS . $file;
|
||||||
if (!is_file($filePath))
|
if (!is_file($filePath)) {
|
||||||
{
|
|
||||||
$this->error(__('No results were found'));
|
$this->error(__('No results were found'));
|
||||||
}
|
}
|
||||||
$PHPReader = new \PHPExcel_Reader_Excel2007();
|
//实例化reader
|
||||||
if (!$PHPReader->canRead($filePath))
|
$ext = pathinfo($filePath, PATHINFO_EXTENSION);
|
||||||
{
|
if (!in_array($ext, ['csv', 'xls', 'xlsx'])) {
|
||||||
$PHPReader = new \PHPExcel_Reader_Excel5();
|
$this->error(__('Unknown data format'));
|
||||||
if (!$PHPReader->canRead($filePath))
|
}
|
||||||
{
|
if ($ext === 'csv') {
|
||||||
$PHPReader = new \PHPExcel_Reader_CSV();
|
$file = fopen($filePath, 'r');
|
||||||
if (!$PHPReader->canRead($filePath))
|
$filePath = tempnam(sys_get_temp_dir(), 'import_csv');
|
||||||
{
|
$fp = fopen($filePath, 'w');
|
||||||
$this->error(__('Unknown data format'));
|
$n = 0;
|
||||||
|
while ($line = fgets($file)) {
|
||||||
|
$line = rtrim($line, "\n\r\0");
|
||||||
|
$encoding = mb_detect_encoding($line, ['utf-8', 'gbk', 'latin1', 'big5']);
|
||||||
|
if ($encoding !== 'utf-8') {
|
||||||
|
$line = mb_convert_encoding($line, 'utf-8', $encoding);
|
||||||
}
|
}
|
||||||
|
if ($n == 0 || preg_match('/^".*"$/', $line)) {
|
||||||
|
fwrite($fp, $line . "\n");
|
||||||
|
} else {
|
||||||
|
fwrite($fp, '"' . str_replace(['"', ','], ['""', '","'], $line) . "\"\n");
|
||||||
|
}
|
||||||
|
$n++;
|
||||||
}
|
}
|
||||||
|
fclose($file) || fclose($fp);
|
||||||
|
|
||||||
|
$reader = new Csv();
|
||||||
|
} elseif ($ext === 'xls') {
|
||||||
|
$reader = new Xls();
|
||||||
|
} else {
|
||||||
|
$reader = new Xlsx();
|
||||||
}
|
}
|
||||||
|
|
||||||
//导入文件首行类型,默认是注释,如果需要使用字段名称请使用name
|
//导入文件首行类型,默认是注释,如果需要使用字段名称请使用name
|
||||||
|
|
@ -324,68 +397,85 @@ trait Backend
|
||||||
$database = \think\Config::get('database.database');
|
$database = \think\Config::get('database.database');
|
||||||
$fieldArr = [];
|
$fieldArr = [];
|
||||||
$list = db()->query("SELECT COLUMN_NAME,COLUMN_COMMENT FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ? AND TABLE_SCHEMA = ?", [$table, $database]);
|
$list = db()->query("SELECT COLUMN_NAME,COLUMN_COMMENT FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ? AND TABLE_SCHEMA = ?", [$table, $database]);
|
||||||
foreach ($list as $k => $v)
|
foreach ($list as $k => $v) {
|
||||||
{
|
if ($importHeadType == 'comment') {
|
||||||
if ($importHeadType == 'comment')
|
$v['COLUMN_COMMENT'] = explode(':', $v['COLUMN_COMMENT'])[0]; //字段备注有:时截取
|
||||||
{
|
|
||||||
$fieldArr[$v['COLUMN_COMMENT']] = $v['COLUMN_NAME'];
|
$fieldArr[$v['COLUMN_COMMENT']] = $v['COLUMN_NAME'];
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$fieldArr[$v['COLUMN_NAME']] = $v['COLUMN_NAME'];
|
$fieldArr[$v['COLUMN_NAME']] = $v['COLUMN_NAME'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$PHPExcel = $PHPReader->load($filePath); //加载文件
|
//加载文件
|
||||||
$currentSheet = $PHPExcel->getSheet(0); //读取文件中的第一个工作表
|
|
||||||
$allColumn = $currentSheet->getHighestDataColumn(); //取得最大的列号
|
|
||||||
$allRow = $currentSheet->getHighestRow(); //取得一共有多少行
|
|
||||||
$maxColumnNumber = \PHPExcel_Cell::columnIndexFromString($allColumn);
|
|
||||||
for ($currentRow = 1; $currentRow <= 1; $currentRow++)
|
|
||||||
{
|
|
||||||
for ($currentColumn = 0; $currentColumn < $maxColumnNumber; $currentColumn++)
|
|
||||||
{
|
|
||||||
$val = $currentSheet->getCellByColumnAndRow($currentColumn, $currentRow)->getValue();
|
|
||||||
$fields[] = $val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$insert = [];
|
$insert = [];
|
||||||
for ($currentRow = 2; $currentRow <= $allRow; $currentRow++)
|
try {
|
||||||
{
|
if (!$PHPExcel = $reader->load($filePath)) {
|
||||||
$values = [];
|
$this->error(__('Unknown data format'));
|
||||||
for ($currentColumn = 0; $currentColumn < $maxColumnNumber; $currentColumn++)
|
|
||||||
{
|
|
||||||
$val = $currentSheet->getCellByColumnAndRow($currentColumn, $currentRow)->getValue();
|
|
||||||
$values[] = is_null($val) ? '' : $val;
|
|
||||||
}
|
}
|
||||||
$row = [];
|
$currentSheet = $PHPExcel->getSheet(0); //读取文件中的第一个工作表
|
||||||
$temp = array_combine($fields, $values);
|
$allColumn = $currentSheet->getHighestDataColumn(); //取得最大的列号
|
||||||
foreach ($temp as $k => $v)
|
$allRow = $currentSheet->getHighestRow(); //取得一共有多少行
|
||||||
{
|
$maxColumnNumber = Coordinate::columnIndexFromString($allColumn);
|
||||||
if (isset($fieldArr[$k]) && $k !== '')
|
$fields = [];
|
||||||
{
|
for ($currentRow = 1; $currentRow <= 1; $currentRow++) {
|
||||||
$row[$fieldArr[$k]] = $v;
|
for ($currentColumn = 1; $currentColumn <= $maxColumnNumber; $currentColumn++) {
|
||||||
|
$val = $currentSheet->getCellByColumnAndRow($currentColumn, $currentRow)->getValue();
|
||||||
|
$fields[] = $val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($row)
|
|
||||||
{
|
for ($currentRow = 2; $currentRow <= $allRow; $currentRow++) {
|
||||||
$insert[] = $row;
|
$values = [];
|
||||||
|
for ($currentColumn = 1; $currentColumn <= $maxColumnNumber; $currentColumn++) {
|
||||||
|
$val = $currentSheet->getCellByColumnAndRow($currentColumn, $currentRow)->getValue();
|
||||||
|
$values[] = is_null($val) ? '' : $val;
|
||||||
|
}
|
||||||
|
$row = [];
|
||||||
|
$temp = array_combine($fields, $values);
|
||||||
|
foreach ($temp as $k => $v) {
|
||||||
|
if (isset($fieldArr[$k]) && $k !== '') {
|
||||||
|
$row[$fieldArr[$k]] = $v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($row) {
|
||||||
|
$insert[] = $row;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} catch (Exception $exception) {
|
||||||
|
$this->error($exception->getMessage());
|
||||||
}
|
}
|
||||||
if (!$insert)
|
if (!$insert) {
|
||||||
{
|
|
||||||
$this->error(__('No rows were updated'));
|
$this->error(__('No rows were updated'));
|
||||||
}
|
}
|
||||||
try
|
|
||||||
{
|
try {
|
||||||
|
//是否包含admin_id字段
|
||||||
|
$has_admin_id = false;
|
||||||
|
foreach ($fieldArr as $name => $key) {
|
||||||
|
if ($key == 'admin_id') {
|
||||||
|
$has_admin_id = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($has_admin_id) {
|
||||||
|
$auth = Auth::instance();
|
||||||
|
foreach ($insert as &$val) {
|
||||||
|
if (empty($val['admin_id'])) {
|
||||||
|
$val['admin_id'] = $auth->isLogin() ? $auth->id : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
$this->model->saveAll($insert);
|
$this->model->saveAll($insert);
|
||||||
}
|
} catch (PDOException $exception) {
|
||||||
catch (\think\exception\PDOException $exception)
|
$msg = $exception->getMessage();
|
||||||
{
|
if (preg_match("/.+Integrity constraint violation: 1062 Duplicate entry '(.+)' for key '(.+)'/is", $msg, $matches)) {
|
||||||
$this->error($exception->getMessage());
|
$msg = "导入失败,包含【{$matches[1]}】的记录已存在";
|
||||||
|
};
|
||||||
|
$this->error($msg);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$this->error($e->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->success();
|
$this->success();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,22 +13,20 @@ class Admin extends Model
|
||||||
// 定义时间戳字段名
|
// 定义时间戳字段名
|
||||||
protected $createTime = 'createtime';
|
protected $createTime = 'createtime';
|
||||||
protected $updateTime = 'updatetime';
|
protected $updateTime = 'updatetime';
|
||||||
|
protected $hidden = [
|
||||||
|
'password',
|
||||||
|
'salt'
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
public static function init()
|
||||||
* 重置用户密码
|
|
||||||
* @author baiyouwen
|
|
||||||
*/
|
|
||||||
public function resetPassword($uid, $NewPassword)
|
|
||||||
{
|
{
|
||||||
$passwd = $this->encryptPassword($NewPassword);
|
self::beforeWrite(function ($row) {
|
||||||
$ret = $this->where(['id' => $uid])->update(['password' => $passwd]);
|
$changed = $row->getChangedData();
|
||||||
return $ret;
|
//如果修改了用户或或密码则需要重新登录
|
||||||
}
|
if (isset($changed['username']) || isset($changed['password']) || isset($changed['salt'])) {
|
||||||
|
$row->token = '';
|
||||||
// 密码加密
|
}
|
||||||
protected function encryptPassword($password, $salt = '', $encrypt = 'md5')
|
});
|
||||||
{
|
|
||||||
return $encrypt($password . $salt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ namespace app\admin\model;
|
||||||
|
|
||||||
use app\admin\library\Auth;
|
use app\admin\library\Auth;
|
||||||
use think\Model;
|
use think\Model;
|
||||||
|
use think\Loader;
|
||||||
|
|
||||||
class AdminLog extends Model
|
class AdminLog extends Model
|
||||||
{
|
{
|
||||||
|
|
@ -17,6 +18,10 @@ class AdminLog extends Model
|
||||||
protected static $title = '';
|
protected static $title = '';
|
||||||
//自定义日志内容
|
//自定义日志内容
|
||||||
protected static $content = '';
|
protected static $content = '';
|
||||||
|
//忽略的链接正则列表
|
||||||
|
protected static $ignoreRegex = [
|
||||||
|
'/^(.*)\/(selectpage|index)$/i',
|
||||||
|
];
|
||||||
|
|
||||||
public static function setTitle($title)
|
public static function setTitle($title)
|
||||||
{
|
{
|
||||||
|
|
@ -28,48 +33,85 @@ class AdminLog extends Model
|
||||||
self::$content = $content;
|
self::$content = $content;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function record($title = '')
|
public static function setIgnoreRegex($regex = [])
|
||||||
|
{
|
||||||
|
$regex = is_array($regex) ? $regex : [$regex];
|
||||||
|
self::$ignoreRegex = array_merge(self::$ignoreRegex, $regex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 记录日志
|
||||||
|
* @param string $title 日志标题
|
||||||
|
* @param string $content 日志内容
|
||||||
|
*/
|
||||||
|
public static function record($title = '', $content = '')
|
||||||
{
|
{
|
||||||
$auth = Auth::instance();
|
$auth = Auth::instance();
|
||||||
$admin_id = $auth->isLogin() ? $auth->id : 0;
|
$admin_id = $auth->isLogin() ? $auth->id : 0;
|
||||||
$username = $auth->isLogin() ? $auth->username : __('Unknown');
|
$username = $auth->isLogin() ? $auth->username : __('Unknown');
|
||||||
$content = self::$content;
|
|
||||||
if (!$content)
|
// 设置过滤函数
|
||||||
{
|
request()->filter('trim,strip_tags,htmlspecialchars');
|
||||||
$content = request()->param();
|
|
||||||
foreach ($content as $k => $v)
|
$controllername = Loader::parseName(request()->controller());
|
||||||
{
|
$actionname = strtolower(request()->action());
|
||||||
if (is_string($v) && strlen($v) > 200 || stripos($k, 'password') !== false)
|
$path = str_replace('.', '/', $controllername) . '/' . $actionname;
|
||||||
{
|
if (self::$ignoreRegex) {
|
||||||
unset($content[$k]);
|
foreach (self::$ignoreRegex as $index => $item) {
|
||||||
|
if (preg_match($item, $path)) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$title = self::$title;
|
$content = $content ?: self::$content;
|
||||||
if (!$title)
|
if (!$content) {
|
||||||
{
|
$content = request()->param('') ?: file_get_contents("php://input");
|
||||||
|
$content = self::getPureContent($content);
|
||||||
|
}
|
||||||
|
$title = $title ?: self::$title;
|
||||||
|
if (!$title) {
|
||||||
$title = [];
|
$title = [];
|
||||||
$breadcrumb = Auth::instance()->getBreadcrumb();
|
$breadcrumb = Auth::instance()->getBreadcrumb($path);
|
||||||
foreach ($breadcrumb as $k => $v)
|
foreach ($breadcrumb as $k => $v) {
|
||||||
{
|
|
||||||
$title[] = $v['title'];
|
$title[] = $v['title'];
|
||||||
}
|
}
|
||||||
$title = implode(' ', $title);
|
$title = implode(' / ', $title);
|
||||||
}
|
}
|
||||||
self::create([
|
self::create([
|
||||||
'title' => $title,
|
'title' => $title,
|
||||||
'content' => !is_scalar($content) ? json_encode($content) : $content,
|
'content' => !is_scalar($content) ? json_encode($content, JSON_UNESCAPED_UNICODE) : $content,
|
||||||
'url' => request()->url(),
|
'url' => substr(xss_clean(strip_tags(request()->url())), 0, 1500),
|
||||||
'admin_id' => $admin_id,
|
'admin_id' => $admin_id,
|
||||||
'username' => $username,
|
'username' => $username,
|
||||||
'useragent' => request()->server('HTTP_USER_AGENT'),
|
'useragent' => substr(request()->server('HTTP_USER_AGENT'), 0, 255),
|
||||||
'ip' => request()->ip()
|
'ip' => xss_clean(strip_tags(request()->ip()))
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取已屏蔽关键信息的数据
|
||||||
|
* @param $content
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected static function getPureContent($content)
|
||||||
|
{
|
||||||
|
if (!is_array($content)) {
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
|
foreach ($content as $index => &$item) {
|
||||||
|
if (preg_match("/(password|salt|token)/i", $index)) {
|
||||||
|
$item = "***";
|
||||||
|
} else {
|
||||||
|
if (is_array($item)) {
|
||||||
|
$item = self::getPureContent($item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
|
|
||||||
public function admin()
|
public function admin()
|
||||||
{
|
{
|
||||||
return $this->belongsTo('Admin', 'admin_id')->setEagerlyType(0);
|
return $this->belongsTo('Admin', 'admin_id')->setEagerlyType(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,22 @@ class AuthRule extends Model
|
||||||
// 定义时间戳字段名
|
// 定义时间戳字段名
|
||||||
protected $createTime = 'createtime';
|
protected $createTime = 'createtime';
|
||||||
protected $updateTime = 'updatetime';
|
protected $updateTime = 'updatetime';
|
||||||
|
// 数据自动完成字段
|
||||||
|
protected $insert = ['py', 'pinyin'];
|
||||||
|
protected $update = ['py', 'pinyin'];
|
||||||
|
// 拼音对象
|
||||||
|
protected static $pinyin = null;
|
||||||
|
|
||||||
protected static function init()
|
protected static function init()
|
||||||
{
|
{
|
||||||
|
self::$pinyin = new \Overtrue\Pinyin\Pinyin('Overtrue\Pinyin\MemoryFileDictLoader');
|
||||||
|
|
||||||
|
self::beforeWrite(function ($row) {
|
||||||
|
if (isset($_POST['row']) && is_array($_POST['row']) && isset($_POST['row']['condition'])) {
|
||||||
|
$originRow = $_POST['row'];
|
||||||
|
$row['condition'] = $originRow['condition'] ?? '';
|
||||||
|
}
|
||||||
|
});
|
||||||
self::afterWrite(function ($row) {
|
self::afterWrite(function ($row) {
|
||||||
Cache::rm('__menu__');
|
Cache::rm('__menu__');
|
||||||
});
|
});
|
||||||
|
|
@ -26,4 +39,24 @@ class AuthRule extends Model
|
||||||
return __($value);
|
return __($value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getMenutypeList()
|
||||||
|
{
|
||||||
|
return ['addtabs' => __('Addtabs'), 'dialog' => __('Dialog'), 'ajax' => __('Ajax'), 'blank' => __('Blank')];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setPyAttr($value, $data)
|
||||||
|
{
|
||||||
|
if (isset($data['title']) && $data['title']) {
|
||||||
|
return self::$pinyin->abbr(__($data['title']));
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setPinyinAttr($value, $data)
|
||||||
|
{
|
||||||
|
if (isset($data['title']) && $data['title']) {
|
||||||
|
return self::$pinyin->permalink(__($data['title']), '');
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
namespace app\admin\model;
|
namespace app\admin\model;
|
||||||
|
|
||||||
|
use app\common\model\MoneyLog;
|
||||||
|
use app\common\model\ScoreLog;
|
||||||
use think\Model;
|
use think\Model;
|
||||||
|
|
||||||
class User extends Model
|
class User extends Model
|
||||||
|
|
@ -21,6 +23,11 @@ class User extends Model
|
||||||
'jointime_text'
|
'jointime_text'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
public function getOriginData()
|
||||||
|
{
|
||||||
|
return $this->origin;
|
||||||
|
}
|
||||||
|
|
||||||
protected static function init()
|
protected static function init()
|
||||||
{
|
{
|
||||||
self::beforeUpdate(function ($row) {
|
self::beforeUpdate(function ($row) {
|
||||||
|
|
@ -36,6 +43,18 @@ class User extends Model
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
self::beforeUpdate(function ($row) {
|
||||||
|
$changedata = $row->getChangedData();
|
||||||
|
$origin = $row->getOriginData();
|
||||||
|
if (isset($changedata['money']) && (function_exists('bccomp') ? bccomp($changedata['money'], $origin['money'], 2) !== 0 : (double)$changedata['money'] !== (double)$origin['money'])) {
|
||||||
|
MoneyLog::create(['user_id' => $row['id'], 'money' => $changedata['money'] - $origin['money'], 'before' => $origin['money'], 'after' => $changedata['money'], 'memo' => '管理员变更金额']);
|
||||||
|
}
|
||||||
|
if (isset($changedata['score']) && (int)$changedata['score'] !== (int)$origin['score']) {
|
||||||
|
ScoreLog::create(['user_id' => $row['id'], 'score' => $changedata['score'] - $origin['score'], 'before' => $origin['score'], 'after' => $changedata['score'], 'memo' => '管理员变更积分']);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getGenderList()
|
public function getGenderList()
|
||||||
|
|
@ -48,21 +67,22 @@ class User extends Model
|
||||||
return ['normal' => __('Normal'), 'hidden' => __('Hidden')];
|
return ['normal' => __('Normal'), 'hidden' => __('Hidden')];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function getPrevtimeTextAttr($value, $data)
|
public function getPrevtimeTextAttr($value, $data)
|
||||||
{
|
{
|
||||||
$value = $value ? $value : $data['prevtime'];
|
$value = $value ? $value : ($data['prevtime'] ?? "");
|
||||||
return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
|
return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getLogintimeTextAttr($value, $data)
|
public function getLogintimeTextAttr($value, $data)
|
||||||
{
|
{
|
||||||
$value = $value ? $value : $data['logintime'];
|
$value = $value ? $value : ($data['logintime'] ?? "");
|
||||||
return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
|
return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getJointimeTextAttr($value, $data)
|
public function getJointimeTextAttr($value, $data)
|
||||||
{
|
{
|
||||||
$value = $value ? $value : $data['jointime'];
|
$value = $value ? $value : ($data['jointime'] ?? "");
|
||||||
return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
|
return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -81,6 +101,11 @@ class User extends Model
|
||||||
return $value && !is_numeric($value) ? strtotime($value) : $value;
|
return $value && !is_numeric($value) ? strtotime($value) : $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function setBirthdayAttr($value)
|
||||||
|
{
|
||||||
|
return $value ? $value : null;
|
||||||
|
}
|
||||||
|
|
||||||
public function group()
|
public function group()
|
||||||
{
|
{
|
||||||
return $this->belongsTo('UserGroup', 'group_id', 'id', [], 'LEFT')->setEagerlyType(0);
|
return $this->belongsTo('UserGroup', 'group_id', 'id', [], 'LEFT')->setEagerlyType(0);
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ class UserGroup extends Model
|
||||||
{
|
{
|
||||||
$value = $value ? $value : $data['status'];
|
$value = $value ? $value : $data['status'];
|
||||||
$list = $this->getStatusList();
|
$list = $this->getStatusList();
|
||||||
return isset($list[$value]) ? $list[$value] : '';
|
return $list[$value] ?? '';
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
namespace app\admin\model;
|
namespace app\admin\model;
|
||||||
|
|
||||||
|
use fast\Tree;
|
||||||
use think\Model;
|
use think\Model;
|
||||||
|
|
||||||
class UserRule extends Model
|
class UserRule extends Model
|
||||||
|
|
@ -22,11 +23,18 @@ class UserRule extends Model
|
||||||
protected static function init()
|
protected static function init()
|
||||||
{
|
{
|
||||||
self::afterInsert(function ($row) {
|
self::afterInsert(function ($row) {
|
||||||
$pk = $row->getPk();
|
if (!$row['weigh']) {
|
||||||
$row->getQuery()->where($pk, $row[$pk])->update(['weigh' => $row[$pk]]);
|
$pk = $row->getPk();
|
||||||
|
$row->getQuery()->where($pk, $row[$pk])->update(['weigh' => $row[$pk]]);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getTitleAttr($value, $data)
|
||||||
|
{
|
||||||
|
return __($value);
|
||||||
|
}
|
||||||
|
|
||||||
public function getStatusList()
|
public function getStatusList()
|
||||||
{
|
{
|
||||||
return ['normal' => __('Normal'), 'hidden' => __('Hidden')];
|
return ['normal' => __('Normal'), 'hidden' => __('Hidden')];
|
||||||
|
|
@ -36,16 +44,23 @@ class UserRule extends Model
|
||||||
{
|
{
|
||||||
$value = $value ? $value : $data['status'];
|
$value = $value ? $value : $data['status'];
|
||||||
$list = $this->getStatusList();
|
$list = $this->getStatusList();
|
||||||
return isset($list[$value]) ? $list[$value] : '';
|
return $list[$value] ?? '';
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getTreeList($selected = [])
|
public static function getTreeList($selected = [])
|
||||||
{
|
{
|
||||||
$ruleList = collection(self::where('status', 'normal')->select())->toArray();
|
$ruleList = collection(self::where('status', 'normal')->order('weigh desc,id desc')->select())->toArray();
|
||||||
$nodeList = [];
|
$nodeList = [];
|
||||||
|
Tree::instance()->init($ruleList);
|
||||||
|
$ruleList = Tree::instance()->getTreeList(Tree::instance()->getTreeArray(0), 'name');
|
||||||
|
$hasChildrens = [];
|
||||||
foreach ($ruleList as $k => $v)
|
foreach ($ruleList as $k => $v)
|
||||||
{
|
{
|
||||||
$state = array('selected' => $v['ismenu'] ? false : in_array($v['id'], $selected));
|
if ($v['haschild'])
|
||||||
|
$hasChildrens[] = $v['id'];
|
||||||
|
}
|
||||||
|
foreach ($ruleList as $k => $v) {
|
||||||
|
$state = array('selected' => in_array($v['id'], $selected) && !in_array($v['id'], $hasChildrens));
|
||||||
$nodeList[] = array('id' => $v['id'], 'parent' => $v['pid'] ? $v['pid'] : '#', 'text' => __($v['title']), 'type' => 'menu', 'state' => $state);
|
$nodeList[] = array('id' => $v['id'], 'parent' => $v['pid'] ? $v['pid'] : '#', 'text' => __($v['title']), 'type' => 'menu', 'state' => $state);
|
||||||
}
|
}
|
||||||
return $nodeList;
|
return $nodeList;
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,11 @@ class Admin extends Validate
|
||||||
* 验证规则
|
* 验证规则
|
||||||
*/
|
*/
|
||||||
protected $rule = [
|
protected $rule = [
|
||||||
'username' => 'require|max:50|unique:admin',
|
'username' => 'require|regex:\w{3,30}|unique:admin',
|
||||||
'nickname' => 'require',
|
'nickname' => 'require',
|
||||||
'password' => 'require',
|
'password' => 'require|regex:\S{32}',
|
||||||
'email' => 'require|email|unique:admin,email',
|
'email' => 'require|email|unique:admin,email',
|
||||||
|
'mobile' => 'regex:1[3-9]\d{9}|unique:admin,mobile',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -33,8 +34,8 @@ class Admin extends Validate
|
||||||
* 验证场景
|
* 验证场景
|
||||||
*/
|
*/
|
||||||
protected $scene = [
|
protected $scene = [
|
||||||
'add' => ['username', 'email', 'nickname', 'password'],
|
'add' => ['username', 'email', 'nickname', 'password', 'mobile'],
|
||||||
'edit' => ['username', 'email', 'nickname'],
|
'edit' => ['username', 'email', 'nickname', 'password', 'mobile'],
|
||||||
];
|
];
|
||||||
|
|
||||||
public function __construct(array $rules = [], $message = [], $field = [])
|
public function __construct(array $rules = [], $message = [], $field = [])
|
||||||
|
|
@ -44,7 +45,12 @@ class Admin extends Validate
|
||||||
'nickname' => __('Nickname'),
|
'nickname' => __('Nickname'),
|
||||||
'password' => __('Password'),
|
'password' => __('Password'),
|
||||||
'email' => __('Email'),
|
'email' => __('Email'),
|
||||||
|
'mobile' => __('Mobile'),
|
||||||
];
|
];
|
||||||
|
$this->message = array_merge($this->message, [
|
||||||
|
'username.regex' => __('Please input correct username'),
|
||||||
|
'password.regex' => __('Please input correct password')
|
||||||
|
]);
|
||||||
parent::__construct($rules, $message, $field);
|
parent::__construct($rules, $message, $field);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ class AuthRule extends Validate
|
||||||
* 验证规则
|
* 验证规则
|
||||||
*/
|
*/
|
||||||
protected $rule = [
|
protected $rule = [
|
||||||
'name' => 'require|format|unique:AuthRule',
|
'name' => 'require|unique:AuthRule',
|
||||||
'title' => 'require',
|
'title' => 'require',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,17 @@ class User extends Validate
|
||||||
* 验证规则
|
* 验证规则
|
||||||
*/
|
*/
|
||||||
protected $rule = [
|
protected $rule = [
|
||||||
|
'username' => 'require|regex:\w{3,30}|unique:user',
|
||||||
|
'nickname' => 'require|unique:user',
|
||||||
|
'password' => 'regex:\S{6,30}',
|
||||||
|
'email' => 'require|email|unique:user',
|
||||||
|
'mobile' => 'unique:user'
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 字段描述
|
||||||
|
*/
|
||||||
|
protected $field = [
|
||||||
];
|
];
|
||||||
/**
|
/**
|
||||||
* 提示消息
|
* 提示消息
|
||||||
|
|
@ -21,7 +32,19 @@ class User extends Validate
|
||||||
*/
|
*/
|
||||||
protected $scene = [
|
protected $scene = [
|
||||||
'add' => [],
|
'add' => [],
|
||||||
'edit' => [],
|
'edit' => ['username', 'nickname', 'password', 'email', 'mobile'],
|
||||||
];
|
];
|
||||||
|
|
||||||
|
public function __construct(array $rules = [], $message = [], $field = [])
|
||||||
|
{
|
||||||
|
$this->field = [
|
||||||
|
'username' => __('Username'),
|
||||||
|
'nickname' => __('Nickname'),
|
||||||
|
'password' => __('Password'),
|
||||||
|
'email' => __('Email'),
|
||||||
|
'mobile' => __('Mobile')
|
||||||
|
];
|
||||||
|
parent::__construct($rules, $message, $field);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,95 +1,142 @@
|
||||||
<form id="config-form" class="edit-form form-horizontal" role="form" data-toggle="validator" method="POST" action="">
|
<form id="config-form" class="edit-form form-horizontal" role="form" data-toggle="validator" method="POST" action="">
|
||||||
<table class="table table-striped">
|
{if $addon.tips && $addon.tips.value}
|
||||||
<thead>
|
<div class="alert {$addon.tips.extend|default='alert-info-light'}" style="margin-bottom:10px;">
|
||||||
<tr>
|
{if $addon.tips.title}
|
||||||
<th width="15%">{:__('Title')}</th>
|
<b>{$addon.tips.title}</b><br>
|
||||||
<th width="85%">{:__('Value')}</th>
|
{/if}
|
||||||
</tr>
|
{$addon.tips.value}
|
||||||
</thead>
|
</div>
|
||||||
<tbody>
|
{/if}
|
||||||
{foreach $addon.config as $item}
|
|
||||||
<tr>
|
|
||||||
<td>{$item.title}</td>
|
|
||||||
<td>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-8 col-xs-12">
|
|
||||||
{switch $item.type}
|
|
||||||
{case string}
|
|
||||||
<input type="text" name="row[{$item.name}]" value="{$item.value}" class="form-control" data-rule="{$item.rule}" data-tip="{$item.tip}" {$item.extend} />
|
|
||||||
{/case}
|
|
||||||
{case text}
|
|
||||||
<textarea name="row[{$item.name}]" class="form-control" data-rule="{$item.rule}" rows="5" data-tip="{$item.tip}" {$item.extend}>{$item.value}</textarea>
|
|
||||||
{/case}
|
|
||||||
{case array}
|
|
||||||
<dl class="fieldlist" data-name="row[{$item.name}]">
|
|
||||||
<dd>
|
|
||||||
<ins>{:__('Array key')}</ins>
|
|
||||||
<ins>{:__('Array value')}</ins>
|
|
||||||
</dd>
|
|
||||||
<dd><a href="javascript:;" class="btn btn-sm btn-success btn-append"><i class="fa fa-plus"></i> {:__('Append')}</a></dd>
|
|
||||||
<textarea name="row[{$item.name}]" cols="30" rows="5" class="hide">{$item.value|json_encode}</textarea>
|
|
||||||
</dl>
|
|
||||||
{/case}
|
|
||||||
{case datetime}
|
|
||||||
<input type="text" name="row[{$item.name}]" value="{$item.value}" class="form-control datetimepicker" data-tip="{$item.tip}" data-rule="{$item.rule}" {$item.extend} />
|
|
||||||
{/case}
|
|
||||||
{case number}
|
|
||||||
<input type="number" name="row[{$item.name}]" value="{$item.value}" class="form-control" data-tip="{$item.tip}" data-rule="{$item.rule}" {$item.extend} />
|
|
||||||
{/case}
|
|
||||||
{case checkbox}
|
|
||||||
{foreach name="item.content" item="vo"}
|
|
||||||
<label for="row[{$item.name}][]-{$key}"><input id="row[{$item.name}][]-{$key}" name="row[{$item.name}][]" type="checkbox" value="{$key}" data-tip="{$item.tip}" {in name="key" value="$item.value"}checked{/in} /> {$vo}</label>
|
|
||||||
{/foreach}
|
|
||||||
{/case}
|
|
||||||
{case radio}
|
|
||||||
{foreach name="item.content" item="vo"}
|
|
||||||
<label for="row[{$item.name}]-{$key}"><input id="row[{$item.name}]-{$key}" name="row[{$item.name}]" type="radio" value="{$key}" data-tip="{$item.tip}" {in name="key" value="$item.value"}checked{/in} /> {$vo}</label>
|
|
||||||
{/foreach}
|
|
||||||
{/case}
|
|
||||||
{case value="select" break="0"}{/case}
|
|
||||||
{case value="selects"}
|
|
||||||
<select name="row[{$item.name}]{$item.type=='selects'?'[]':''}" class="form-control selectpicker" data-tip="{$item.tip}" {$item.type=='selects'?'multiple':''}>
|
|
||||||
{foreach name="item.content" item="vo"}
|
|
||||||
<option value="{$key}" {in name="key" value="$item.value"}selected{/in}>{$vo}</option>
|
|
||||||
{/foreach}
|
|
||||||
</select>
|
|
||||||
{/case}
|
|
||||||
{case value="image" break="0"}{/case}
|
|
||||||
{case value="images"}
|
|
||||||
<div class="form-inline">
|
|
||||||
<input id="c-{$item.name}" class="form-control" size="37" name="row[{$item.name}]" type="text" value="{$item.value}" data-tip="{$item.tip}">
|
|
||||||
<span><button type="button" id="plupload-{$item.name}" class="btn btn-danger plupload" data-input-id="c-{$item.name}" data-mimetype="image/*" data-multiple="{$item.type=='image'?'false':'true'}" data-preview-id="p-{$item.name}"><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
|
|
||||||
<span><button type="button" id="fachoose-{$item.name}" class="btn btn-primary fachoose" data-input-id="c-{$item.name}" data-mimetype="image/*" data-multiple="{$item.type=='image'?'false':'true'}"><i class="fa fa-list"></i> {:__('Choose')}</button></span>
|
|
||||||
<ul class="row list-inline plupload-preview" id="p-{$item.name}"></ul>
|
|
||||||
</div>
|
|
||||||
{/case}
|
|
||||||
{case value="file" break="0"}{/case}
|
|
||||||
{case value="files"}
|
|
||||||
<div class="form-inline">
|
|
||||||
<input id="c-{$item.name}" class="form-control" size="37" name="row[{$item.name}]" type="text" value="{$item.value}" data-tip="{$item.tip}">
|
|
||||||
<span><button type="button" id="plupload-{$item.name}" class="btn btn-danger plupload" data-input-id="c-{$item.name}" data-multiple="{$item.type=='file'?'false':'true'}"><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
|
|
||||||
<span><button type="button" id="fachoose-{$item.name}" class="btn btn-primary fachoose" data-input-id="c-{$item.name}" data-multiple="{$item.type=='file'?'false':'true'}"><i class="fa fa-list"></i> {:__('Choose')}</button></span>
|
|
||||||
</div>
|
|
||||||
{/case}
|
|
||||||
{case bool}
|
|
||||||
<label for="row[{$item.name}]-yes"><input id="row[{$item.name}]-yes" name="row[{$item.name}]" type="radio" value="1" {$item.value?'checked':''} data-tip="{$item.tip}" /> {:__('Yes')}</label>
|
|
||||||
<label for="row[{$item.name}]-no"><input id="row[{$item.name}]-no" name="row[{$item.name}]" type="radio" value="0" {$item.value?'':'checked'} data-tip="{$item.tip}" /> {:__('No')}</label>
|
|
||||||
{/case}
|
|
||||||
{/switch}
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-4"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</td>
|
<div class="panel panel-default panel-intro">
|
||||||
</tr>
|
{if count($groupList)>1}
|
||||||
{/foreach}
|
<div class="panel-heading mb-3">
|
||||||
</tbody>
|
<ul class="nav nav-tabs nav-group">
|
||||||
</table>
|
<li class="active"><a href="#all" data-toggle="tab">全部</a></li>
|
||||||
<div class="form-group layer-footer">
|
{foreach name="groupList" id="tab"}
|
||||||
<label class="control-label col-xs-12 col-sm-2"></label>
|
<li><a href="#tab-{$key}" title="{$tab}" data-toggle="tab">{$tab}</a></li>
|
||||||
<div class="col-xs-12 col-sm-8">
|
{/foreach}
|
||||||
<button type="submit" class="btn btn-success btn-embossed disabled">{:__('OK')}</button>
|
</ul>
|
||||||
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<div class="panel-body no-padding">
|
||||||
|
<div id="myTabContent" class="tab-content">
|
||||||
|
{foreach name="groupList" id="group" key="groupName"}
|
||||||
|
<div class="tab-pane fade active in" id="tab-{$groupName}">
|
||||||
|
|
||||||
|
<table class="table table-striped table-config mb-0">
|
||||||
|
<tbody>
|
||||||
|
{foreach name="$addon.config" id="item"}
|
||||||
|
{if ((!isset($item['group']) || $item['group']=='') && $groupName=='other') || (isset($item['group']) && $item['group']==$group)}
|
||||||
|
<tr data-favisible="{$item.visible|default=''|htmlentities}" data-name="{$item.name}" class="{if $item.visible??''}hidden{/if}">
|
||||||
|
<td width="15%">{$item.title}</td>
|
||||||
|
<td>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-8 col-xs-12">
|
||||||
|
{switch $item.type}
|
||||||
|
{case string}
|
||||||
|
<input {$item.extend} type="text" name="row[{$item.name}]" value="{$item.value|htmlentities}" class="form-control" data-rule="{$item.rule}" data-tip="{$item.tip}"/>
|
||||||
|
{/case}
|
||||||
|
{case password}
|
||||||
|
<input {$item.extend} type="password" name="row[{$item.name}]" value="{$item.value|htmlentities}" class="form-control" data-rule="{$item.rule}" data-tip="{$item.tip}"/>
|
||||||
|
{/case}
|
||||||
|
{case text}
|
||||||
|
<textarea {$item.extend} name="row[{$item.name}]" class="form-control" data-rule="{$item.rule}" rows="5" data-tip="{$item.tip}">{$item.value|htmlentities}</textarea>
|
||||||
|
{/case}
|
||||||
|
{case array}
|
||||||
|
<dl class="fieldlist" data-name="row[{$item.name}]">
|
||||||
|
<dd>
|
||||||
|
<ins>{:__('Array key')}</ins>
|
||||||
|
<ins>{:__('Array value')}</ins>
|
||||||
|
</dd>
|
||||||
|
<dd><a href="javascript:;" class="btn btn-sm btn-success btn-append"><i class="fa fa-plus"></i> {:__('Append')}</a></dd>
|
||||||
|
<textarea name="row[{$item.name}]" cols="30" rows="5" class="hide">{$item.value|json_encode|htmlentities}</textarea>
|
||||||
|
</dl>
|
||||||
|
{/case}
|
||||||
|
{case date}
|
||||||
|
<input {$item.extend} type="text" name="row[{$item.name}]" value="{$item.value|htmlentities}" class="form-control datetimepicker" data-date-format="YYYY-MM-DD" data-tip="{$item.tip}" data-rule="{$item.rule}"/>
|
||||||
|
{/case}
|
||||||
|
{case time}
|
||||||
|
<input {$item.extend} type="text" name="row[{$item.name}]" value="{$item.value|htmlentities}" class="form-control datetimepicker" data-date-format="HH:mm:ss" data-tip="{$item.tip}" data-rule="{$item.rule}"/>
|
||||||
|
{/case}
|
||||||
|
{case datetime}
|
||||||
|
<input {$item.extend} type="text" name="row[{$item.name}]" value="{$item.value|htmlentities}" class="form-control datetimepicker" data-date-format="YYYY-MM-DD HH:mm:ss" data-tip="{$item.tip}" data-rule="{$item.rule}"/>
|
||||||
|
{/case}
|
||||||
|
{case number}
|
||||||
|
<input {$item.extend} type="number" name="row[{$item.name}]" value="{$item.value|htmlentities}" class="form-control" data-tip="{$item.tip}" data-rule="{$item.rule}"/>
|
||||||
|
{/case}
|
||||||
|
{case checkbox}
|
||||||
|
{foreach name="item.content" item="vo"}
|
||||||
|
<label for="row[{$item.name}][]-{$key}"><input id="row[{$item.name}][]-{$key}" name="row[{$item.name}][]" type="checkbox" value="{$key}" data-tip="{$item.tip}" {in name="key" value="$item.value" }checked{/in} /> {$vo}</label>
|
||||||
|
{/foreach}
|
||||||
|
<span class="msg-box n-right" for="row[{$item.name}]"></span>
|
||||||
|
{/case}
|
||||||
|
{case radio}
|
||||||
|
{foreach name="item.content" item="vo"}
|
||||||
|
<label for="row[{$item.name}]-{$key}"><input id="row[{$item.name}]-{$key}" name="row[{$item.name}]" type="radio" value="{$key}" data-tip="{$item.tip}" {in name="key" value="$item.value" }checked{/in} /> {$vo}</label>
|
||||||
|
{/foreach}
|
||||||
|
<span class="msg-box n-right" for="row[{$item.name}]"></span>
|
||||||
|
{/case}
|
||||||
|
{case value="select" break="0"}{/case}
|
||||||
|
{case value="selects"}
|
||||||
|
<select {$item.extend} name="row[{$item.name}]{$item.type=='selects'?'[]':''}" class="form-control selectpicker" data-tip="{$item.tip}" {$item.type=='selects'?'multiple':''}>
|
||||||
|
{foreach name="item.content" item="vo"}
|
||||||
|
<option value="{$key}" {in name="key" value="$item.value" }selected{/in}>{$vo}</option>
|
||||||
|
{/foreach}
|
||||||
|
</select>
|
||||||
|
{/case}
|
||||||
|
{case value="image" break="0"}{/case}
|
||||||
|
{case value="images"}
|
||||||
|
<div class="form-inline">
|
||||||
|
<input id="c-{$item.name}" class="form-control" size="28" name="row[{$item.name}]" type="text" value="{$item.value|htmlentities}" data-tip="{$item.tip}">
|
||||||
|
<span><button type="button" id="plupload-{$item.name}" class="btn btn-danger plupload" data-input-id="c-{$item.name}" data-mimetype="image/*" data-multiple="{$item.type=='image'?'false':'true'}" data-preview-id="p-{$item.name}"><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
|
||||||
|
<span><button type="button" id="fachoose-{$item.name}" class="btn btn-primary fachoose" data-input-id="c-{$item.name}" data-mimetype="image/*" data-multiple="{$item.type=='image'?'false':'true'}"><i class="fa fa-list"></i> {:__('Choose')}</button></span>
|
||||||
|
<ul class="row list-inline plupload-preview" id="p-{$item.name}"></ul>
|
||||||
|
<span class="msg-box n-right" for="c-{$item.name}"></span>
|
||||||
|
</div>
|
||||||
|
{/case}
|
||||||
|
{case value="file" break="0"}{/case}
|
||||||
|
{case value="files"}
|
||||||
|
<div class="form-inline">
|
||||||
|
<input id="c-{$item.name}" class="form-control" size="28" name="row[{$item.name}]" type="text" value="{$item.value|htmlentities}" data-tip="{$item.tip}">
|
||||||
|
<span><button type="button" id="plupload-{$item.name}" class="btn btn-danger plupload" data-input-id="c-{$item.name}" data-multiple="{$item.type=='file'?'false':'true'}"><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
|
||||||
|
<span><button type="button" id="fachoose-{$item.name}" class="btn btn-primary fachoose" data-input-id="c-{$item.name}" data-multiple="{$item.type=='file'?'false':'true'}"><i class="fa fa-list"></i> {:__('Choose')}</button></span>
|
||||||
|
<span class="msg-box n-right" for="c-{$item.name}"></span>
|
||||||
|
</div>
|
||||||
|
{/case}
|
||||||
|
{case switch}
|
||||||
|
<input id="c-{$item.name}" name="row[{$item.name}]" type="hidden" value="{:$item.value?1:0}">
|
||||||
|
<a href="javascript:;" data-toggle="switcher" class="btn-switcher" data-input-id="c-{$item.name}" data-yes="1" data-no="0">
|
||||||
|
<i class="fa fa-toggle-on text-success {if !$item.value}fa-flip-horizontal text-gray{/if} fa-2x"></i>
|
||||||
|
</a>
|
||||||
|
{/case}
|
||||||
|
{case bool}
|
||||||
|
<label for="row[{$item.name}]-yes"><input id="row[{$item.name}]-yes" name="row[{$item.name}]" type="radio" value="1" {$item.value?'checked':''} data-tip="{$item.tip}" /> {:__('Yes')}</label>
|
||||||
|
<label for="row[{$item.name}]-no"><input id="row[{$item.name}]-no" name="row[{$item.name}]" type="radio" value="0" {$item.value?'':'checked'} data-tip="{$item.tip}" /> {:__('No')}</label>
|
||||||
|
{/case}
|
||||||
|
{default /}{$item.value}
|
||||||
|
{/switch}
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-4"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{/if}
|
||||||
|
{/foreach}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{/foreach}
|
||||||
|
<div class="form-group layer-footer">
|
||||||
|
<label class="control-label col-xs-12 col-sm-2" style="width:15%;"></label>
|
||||||
|
<div class="col-xs-12 col-sm-8">
|
||||||
|
<button type="submit" class="btn btn-primary btn-embossed disabled">{:__('OK')}</button>
|
||||||
|
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
||||||
|
|
@ -53,15 +53,29 @@
|
||||||
position: absolute;
|
position: absolute;
|
||||||
box-shadow: 0px 0px 2px #f11414;
|
box-shadow: 0px 0px 2px #f11414;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.form-userinfo .breadcrumb {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-toggle {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.operate .dropup .dropdown-menu, .navbar-fixed-bottom .dropdown .dropdown-menu {
|
||||||
|
bottom: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
<div class="panel panel-default panel-intro">
|
<div class="panel panel-default panel-intro">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
{:build_heading(null,FALSE)}
|
{:build_heading(null,FALSE)}
|
||||||
|
{if $Think.config.fastadmin.api_url}
|
||||||
<ul class="nav nav-tabs nav-category">
|
<ul class="nav nav-tabs nav-category">
|
||||||
<li class="active"><a href="javascript:;" data-id="">{:__('All')}</a></li>
|
<li class="active"><a href="javascript:;" data-id="">{:__('All')}</a></li>
|
||||||
<li><a href="javascript:;" data-id="0">{:__('Uncategoried')}</a></li>
|
<li><a href="javascript:;" data-id="0">{:__('Uncategoried')}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
|
|
@ -69,26 +83,19 @@
|
||||||
<div class="tab-pane fade active in" id="one">
|
<div class="tab-pane fade active in" id="one">
|
||||||
<div class="widget-body no-padding">
|
<div class="widget-body no-padding">
|
||||||
<div id="toolbar" class="toolbar">
|
<div id="toolbar" class="toolbar">
|
||||||
{:build_toolbar('refresh')}
|
<a href="javascript:;" class="btn btn-primary btn-refresh" title="{:__('Refresh')}" data-force-refresh="false"><i class="fa fa-refresh"></i> </a>
|
||||||
<button type="button" id="plupload-addon" class="btn btn-danger plupload" data-url="addon/local"
|
{if $Think.config.fastadmin.api_url}
|
||||||
data-mimetype="application/zip" data-multiple="false"><i class="fa fa-upload"></i>
|
<button type="button" id="faupload-addon" class="btn btn-danger faupload btn-mini-xs" data-url="addon/local" data-chunking="false" data-mimetype="zip,fastaddon" data-multiple="false"><i class="fa fa-upload"></i>
|
||||||
{:__('Offline install')}
|
{:__('Local install')}
|
||||||
</button>
|
</button>
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
<a href="#" class="btn btn-info btn-switch active" data-type="all"
|
<a href="#" class="btn btn-info btn-switch active btn-mini-xs" data-type="all"><i class="fa fa-list"></i> {:__('All')}</a>
|
||||||
data-url="{$config.fastadmin.api_url}/addon/index"><i class="fa fa-list"></i>
|
<a href="#" class="btn btn-info btn-switch btn-mini-xs" data-type="free"><i class="fa fa-gift"></i> {:__('Free')}</a>
|
||||||
{:__('All')}</a>
|
<a href="#" class="btn btn-info btn-switch btn-mini-xs" data-type="price"><i class="fa fa-rmb"></i> {:__('Paying')}</a>
|
||||||
<a href="#" class="btn btn-info btn-switch" data-type="free"
|
<a href="#" class="btn btn-info btn-switch btn-mini-xs" data-type="local" data-url="addon/downloaded"><i class="fa fa-laptop"></i> {:__('Local addon')}</a>
|
||||||
data-url="{$config.fastadmin.api_url}/addon/index"><i class="fa fa-gift"></i>
|
|
||||||
{:__('Free')}</a>
|
|
||||||
<a href="#" class="btn btn-info btn-switch" data-type="price"
|
|
||||||
data-url="{$config.fastadmin.api_url}/addon/index"><i class="fa fa-rmb"></i>
|
|
||||||
{:__('Paying')}</a>
|
|
||||||
<a href="#" class="btn btn-info btn-switch" data-type="local" data-url="addon/downloaded"><i
|
|
||||||
class="fa fa-laptop"></i> {:__('Local addon')}</a>
|
|
||||||
</div>
|
</div>
|
||||||
<a class="btn btn-primary btn-userinfo" href="javascript:;"><i class="fa fa-user"></i>
|
<a class="btn btn-primary btn-userinfo btn-mini-xs" href="javascript:;"><i class="fa fa-user"></i> {:__('Userinfo')}</a>
|
||||||
{:__('Userinfo')}</a>
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<table id="table" class="table table-striped table-bordered table-hover" width="100%">
|
<table id="table" class="table table-striped table-bordered table-hover" width="100%">
|
||||||
|
|
||||||
|
|
@ -129,7 +136,7 @@
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="control-label">{:__('Version')}</label>
|
<label class="control-label">{:__('Version')}</label>
|
||||||
<input type="hidden" class="operate" data-name="faversion" value="="/>
|
<input type="hidden" class="operate" data-name="faversion" value="="/>
|
||||||
<input class="form-control" name="faversion" type="text" value="{$config.fastadmin.version}">
|
<input class="form-control" name="faversion" type="text" value="{$Think.config.fastadmin.version}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xs-12 col-sm-6 col-md-3">
|
<div class="col-xs-12 col-sm-6 col-md-3">
|
||||||
|
|
@ -149,54 +156,20 @@
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</script>
|
</script>
|
||||||
<script id="logintpl" type="text/html">
|
<script id="uninstalltpl" type="text/html">
|
||||||
<div>
|
<div class="">
|
||||||
<form class="form-horizontal">
|
<div class=""><%=#__("Are you sure you want to unstall %s?", addon['title'])%>
|
||||||
<fieldset>
|
<p class="text-danger">{:__('Delete all the addon file and cannot be recovered!')} </p>
|
||||||
<div class="alert alert-dismissable alert-danger">
|
{if config('app_debug')}
|
||||||
<button type="button" class="close" data-dismiss="alert">×</button>
|
<p class="text-danger"><input type="checkbox" name="droptables" id="droptables" data-name="<%=addon['name']%>"/> {:__('Delete all the addon database and cannot be recovered!')} </p>
|
||||||
<strong>{:__('Warning')}</strong><br/>{:__('Login tips')}
|
{/if}
|
||||||
</div>
|
<p class="text-danger">{:__('Please backup important data manually before uninstall!')}</p>
|
||||||
<div class="form-group">
|
</div>
|
||||||
<label for="inputAccount" class="col-lg-3 control-label">{:__('Username')}</label>
|
|
||||||
<div class="col-lg-9">
|
|
||||||
<input type="text" class="form-control" id="inputAccount" value=""
|
|
||||||
placeholder="{:__('Your username or email')}">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="inputPassword" class="col-lg-3 control-label">{:__('Password')}</label>
|
|
||||||
<div class="col-lg-9">
|
|
||||||
<input type="password" class="form-control" id="inputPassword" value=""
|
|
||||||
placeholder="{:__('Your password')}">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</fieldset>
|
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
</script>
|
</script>
|
||||||
<script id="userinfotpl" type="text/html">
|
<script id="upgradetpl" type="text/html">
|
||||||
<div>
|
<div class="">
|
||||||
<form class="form-horizontal">
|
<div class=""><%=#__("Upgrade tips", addon['title'])%></div>
|
||||||
<fieldset>
|
|
||||||
<div class="alert alert-dismissable alert-success">
|
|
||||||
<button type="button" class="close" data-dismiss="alert">×</button>
|
|
||||||
<strong>{:__('Warning')}</strong><br/>{:__('Logined tips', '<%=username%>')}
|
|
||||||
</div>
|
|
||||||
</fieldset>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</script>
|
|
||||||
<script id="paytpl" type="text/html">
|
|
||||||
<div class="payimg" style="background:url('<%=payimg%>') 0 0 no-repeat;background-size:cover;">
|
|
||||||
<%if(paycode){%>
|
|
||||||
<div class="alipaycode">
|
|
||||||
<%=paycode%>
|
|
||||||
</div>
|
|
||||||
<div class="wechatcode">
|
|
||||||
<%=paycode%>
|
|
||||||
</div>
|
|
||||||
<%}%>
|
|
||||||
</div>
|
</div>
|
||||||
</script>
|
</script>
|
||||||
<script id="conflicttpl" type="text/html">
|
<script id="conflicttpl" type="text/html">
|
||||||
|
|
@ -221,70 +194,75 @@
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</script>
|
</script>
|
||||||
|
<!--@formatter:off-->
|
||||||
<script id="operatetpl" type="text/html">
|
<script id="operatetpl" type="text/html">
|
||||||
<% var labelarr = ['primary', 'success', 'info', 'danger', 'warning']; %>
|
<% var labelarr = ['primary', 'success', 'info', 'danger', 'warning']; %>
|
||||||
<% var label = labelarr[item.id % 5]; %>
|
<% var label = labelarr[item.id % 5]; %>
|
||||||
<% var addon = item.addon; %>
|
<% var addon = item.addon; %>
|
||||||
|
|
||||||
<div class="operate" data-id="<%=item.id%>" data-name="<%=item.name%>">
|
<span class="operate" data-id="<%=item.id%>" data-name="<%=item.name%>">
|
||||||
<% if(!addon){ %>
|
<% if(!addon){ %>
|
||||||
<% if(typeof item.releaselist !="undefined" && item.releaselist.length>1){%>
|
<% if(typeof item.releaselist !="undefined" && item.releaselist.length>1){%>
|
||||||
<span class="btn-group">
|
<span class="btn-group">
|
||||||
|
<a href="javascript:;" class="btn btn-xs btn-primary btn-success btn-install"
|
||||||
|
data-type="<%=item.price<=0?'free':'price';%>"
|
||||||
|
data-version="<%=item.version%>"><i class="fa fa-cloud-download"></i> {:__('Install')}</a>
|
||||||
|
<a class="btn btn-xs btn-success dropdown-toggle" data-toggle="dropdown" href="javascript:;">
|
||||||
|
<span class="fa fa-caret-down"></span>
|
||||||
|
</a>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
<% for(var j=0;j< item.releaselist.length;j++){ %>
|
||||||
|
<li><a href="javascript:;" class="btn-install" data-type="<%=item.price<=0?'free':'price';%>"
|
||||||
|
data-version="<%=item.releaselist[j].version%>"><%=item.releaselist[j].version%></a></li>
|
||||||
|
<% } %>
|
||||||
|
</ul>
|
||||||
|
</span>
|
||||||
|
<% }else if(typeof item.releaselist !="undefined" && item.releaselist.length>0){%>
|
||||||
<a href="javascript:;" class="btn btn-xs btn-primary btn-success btn-install"
|
<a href="javascript:;" class="btn btn-xs btn-primary btn-success btn-install"
|
||||||
data-type="<%=item.price<=0?'free':'price';%>" data-donateimage="<%=item.donateimage%>"
|
data-type="<%=item.price<=0?'free':'price';%>"
|
||||||
data-version="<%=item.version%>"><i class="fa fa-cloud-download"></i> {:__('Install')}</a>
|
data-version="<%=item.version%>"><i class="fa fa-cloud-download"></i> {:__('Install')}</a>
|
||||||
<a class="btn btn-xs btn-success dropdown-toggle" data-toggle="dropdown" href="javascript:;">
|
<% } %>
|
||||||
<span class="fa fa-caret-down"></span>
|
|
||||||
|
<% if(item.demourl){ %>
|
||||||
|
<a href="<%=item.demourl%>" class="btn btn-xs btn-primary btn-info btn-demo" target="_blank">
|
||||||
|
<i class="fa fa-flash"></i> {:__('Demo')}
|
||||||
</a>
|
</a>
|
||||||
<ul class="dropdown-menu">
|
<% } %>
|
||||||
<% for(var j=0;j< item.releaselist.length;j++){ %>
|
|
||||||
<li><a href="javascript:;" class="btn-install" data-type="<%=item.price<=0?'free':'price';%>"
|
|
||||||
data-donateimage="<%=item.donateimage%>"
|
|
||||||
data-version="<%=item.releaselist[j].version%>"><%=item.releaselist[j].version%></a></li>
|
|
||||||
<% } %>
|
|
||||||
</ul>
|
|
||||||
</span>
|
|
||||||
<% }else{%>
|
|
||||||
<a href="javascript:;" class="btn btn-xs btn-primary btn-success btn-install"
|
|
||||||
data-type="<%=item.price<=0?'free':'price';%>" data-donateimage="<%=item.donateimage%>"
|
|
||||||
data-version="<%=item.version%>"><i class="fa fa-cloud-download"></i> {:__('Install')}</a>
|
|
||||||
<% } %>
|
|
||||||
|
|
||||||
<% if(item.demourl){ %>
|
<% if(item.button){ %>
|
||||||
<a href="<%=item.demourl%>" class="btn btn-xs btn-primary btn-info btn-demo" target="_blank">
|
<a href="<%=item.url%>" class="btn btn-xs btn-primary btn-info" target="_blank">
|
||||||
<i class="fa fa-flash"></i> {:__('Demo')}
|
<%=item.button%>
|
||||||
</a>
|
</a>
|
||||||
<% } %>
|
<% } %>
|
||||||
<% } else {%>
|
<% } else {%>
|
||||||
<% if(addon.version!=item.version){%>
|
<% if(addon.version!=item.version){%>
|
||||||
<% if(typeof item.releaselist !="undefined" && item.releaselist.length>1){%>
|
<% if(typeof item.releaselist !="undefined" && item.releaselist.length>1){%>
|
||||||
<span class="btn-group">
|
<span class="btn-group">
|
||||||
<a href="javascript:;" class="btn btn-xs btn-info btn-success btn-upgrade"
|
<a href="javascript:;" class="btn btn-xs btn-info btn-success btn-upgrade"
|
||||||
data-version="<%=item.version%>"><i class="fa fa-cloud"></i> {:__('Upgrade')}</a>
|
data-version="<%=item.version%>"><i class="fa fa-cloud"></i> {:__('Upgrade')}</a>
|
||||||
<a class="btn btn-xs btn-info dropdown-toggle" data-toggle="dropdown"
|
<a class="btn btn-xs btn-info dropdown-toggle" data-toggle="dropdown"
|
||||||
href="javascript:;">
|
href="javascript:;">
|
||||||
<span class="fa fa-caret-down"></span>
|
<span class="fa fa-caret-down"></span>
|
||||||
</a>
|
</a>
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
<% for(var j=0;j< item.releaselist.length;j++){ %>
|
<% for(var j=0;j< item.releaselist.length;j++){ %>
|
||||||
<li><a href="javascript:;" class="btn-upgrade"
|
<li><a href="javascript:;" class="btn-upgrade"
|
||||||
data-version="<%=item.releaselist[j].version%>"><%=item.releaselist[j].version%></a></li>
|
data-version="<%=item.releaselist[j].version%>"><%=item.releaselist[j].version%></a></li>
|
||||||
<% } %>
|
<% } %>
|
||||||
</ul>
|
</ul>
|
||||||
</span>
|
</span>
|
||||||
<% }else{%>
|
<% }else{%>
|
||||||
<a href="javascript:;" class="btn btn-xs btn-info btn-upgrade" data-version="<%=item.version%>"><i
|
<a href="javascript:;" class="btn btn-xs btn-info btn-upgrade" title="{:__('Upgrade')}" data-version="<%=item.version%>"><i
|
||||||
class="fa fa-cloud"></i> {:__('Upgrade')}</a>
|
class="fa fa-cloud"></i> {:__('Upgrade')}</a>
|
||||||
<% }%>
|
<% }%>
|
||||||
<% }%>
|
<% }%>
|
||||||
<% if(addon.config){ %>
|
<% if(addon.config){ %>
|
||||||
<a href="javascript:;" class="btn btn-xs btn-primary btn-config"><i class="fa fa-pencil"></i>
|
<a href="javascript:;" class="btn btn-xs btn-primary btn-config" title="{:__('Setting')}"><i class="fa fa-pencil"></i>
|
||||||
{:__('Setting')}</a>
|
{:__('Setting')}</a>
|
||||||
|
<% } %>
|
||||||
|
<a href="javascript:;" class="btn btn-xs btn-danger btn-uninstall" title="{:__('Uninstall')}"><i class="fa fa-times"></i>
|
||||||
|
{:__('Uninstall')}</a>
|
||||||
<% } %>
|
<% } %>
|
||||||
<a href="javascript:;" class="btn btn-xs btn-danger btn-uninstall"><i class="fa fa-times"></i>
|
</span>
|
||||||
{:__('Uninstall')}</a>
|
</script>
|
||||||
<% } %>
|
<!--@formatter:on-->
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</script>
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
<form id="add-form" class="form-horizontal form-ajax" role="form" data-toggle="validator" method="POST" action="">
|
<form id="add-form" class="form-horizontal form-ajax" role="form" data-toggle="validator" method="POST" action="">
|
||||||
|
{:token()}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="control-label col-xs-12 col-sm-2">{:__('Group')}:</label>
|
<label class="control-label col-xs-12 col-sm-2">{:__('Group')}:</label>
|
||||||
<div class="col-xs-12 col-sm-8">
|
<div class="col-xs-12 col-sm-8">
|
||||||
|
|
@ -17,6 +18,12 @@
|
||||||
<input type="email" class="form-control" id="email" name="row[email]" value="" data-rule="required;email" />
|
<input type="email" class="form-control" id="email" name="row[email]" value="" data-rule="required;email" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="mobile" class="control-label col-xs-12 col-sm-2">{:__('Mobile')}:</label>
|
||||||
|
<div class="col-xs-12 col-sm-8">
|
||||||
|
<input type="text" class="form-control" id="mobile" name="row[mobile]" value="" data-rule="mobile" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="nickname" class="control-label col-xs-12 col-sm-2">{:__('Nickname')}:</label>
|
<label for="nickname" class="control-label col-xs-12 col-sm-2">{:__('Nickname')}:</label>
|
||||||
<div class="col-xs-12 col-sm-8">
|
<div class="col-xs-12 col-sm-8">
|
||||||
|
|
@ -38,8 +45,8 @@
|
||||||
<div class="form-group hidden layer-footer">
|
<div class="form-group hidden layer-footer">
|
||||||
<label class="control-label col-xs-12 col-sm-2"></label>
|
<label class="control-label col-xs-12 col-sm-2"></label>
|
||||||
<div class="col-xs-12 col-sm-8">
|
<div class="col-xs-12 col-sm-8">
|
||||||
<button type="submit" class="btn btn-success btn-embossed disabled">{:__('OK')}</button>
|
<button type="submit" class="btn btn-primary btn-embossed disabled">{:__('OK')}</button>
|
||||||
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
|
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
<form id="edit-form" class="form-horizontal form-ajax" role="form" data-toggle="validator" method="POST" action="">
|
<form id="edit-form" class="form-horizontal form-ajax" role="form" data-toggle="validator" method="POST" action="">
|
||||||
|
{:token()}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="control-label col-xs-12 col-sm-2">{:__('Group')}:</label>
|
<label class="control-label col-xs-12 col-sm-2">{:__('Group')}:</label>
|
||||||
<div class="col-xs-12 col-sm-8">
|
<div class="col-xs-12 col-sm-8">
|
||||||
|
|
@ -8,19 +9,25 @@
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="username" class="control-label col-xs-12 col-sm-2">{:__('Username')}:</label>
|
<label for="username" class="control-label col-xs-12 col-sm-2">{:__('Username')}:</label>
|
||||||
<div class="col-xs-12 col-sm-8">
|
<div class="col-xs-12 col-sm-8">
|
||||||
<input type="text" class="form-control" id="username" name="row[username]" value="{$row.username}" data-rule="required;username" />
|
<input type="text" class="form-control" id="username" name="row[username]" value="{$row.username|htmlentities}" data-rule="required;username" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="email" class="control-label col-xs-12 col-sm-2">{:__('Email')}:</label>
|
<label for="email" class="control-label col-xs-12 col-sm-2">{:__('Email')}:</label>
|
||||||
<div class="col-xs-12 col-sm-8">
|
<div class="col-xs-12 col-sm-8">
|
||||||
<input type="email" class="form-control" id="email" name="row[email]" value="{$row.email}" data-rule="required;email" />
|
<input type="email" class="form-control" id="email" name="row[email]" value="{$row.email|htmlentities}" data-rule="required;email" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="mobile" class="control-label col-xs-12 col-sm-2">{:__('Mobile')}:</label>
|
||||||
|
<div class="col-xs-12 col-sm-8">
|
||||||
|
<input type="text" class="form-control" id="mobile" name="row[mobile]" value="{$row.mobile|default=''|htmlentities}" data-rule="mobile" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="nickname" class="control-label col-xs-12 col-sm-2">{:__('Nickname')}:</label>
|
<label for="nickname" class="control-label col-xs-12 col-sm-2">{:__('Nickname')}:</label>
|
||||||
<div class="col-xs-12 col-sm-8">
|
<div class="col-xs-12 col-sm-8">
|
||||||
<input type="text" class="form-control" id="nickname" name="row[nickname]" autocomplete="off" value="{$row.nickname}" data-rule="required" />
|
<input type="text" class="form-control" id="nickname" name="row[nickname]" autocomplete="off" value="{$row.nickname|htmlentities}" data-rule="required" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|
@ -32,7 +39,7 @@
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="loginfailure" class="control-label col-xs-12 col-sm-2">{:__('Loginfailure')}:</label>
|
<label for="loginfailure" class="control-label col-xs-12 col-sm-2">{:__('Loginfailure')}:</label>
|
||||||
<div class="col-xs-12 col-sm-8">
|
<div class="col-xs-12 col-sm-8">
|
||||||
<input type="number" class="form-control" id="loginfailure" name="row[loginfailure]" value="{$row.loginfailure}" data-rule="required" />
|
<input type="number" class="form-control" id="loginfailure" name="row[loginfailure]" value="{$row.loginfailure|htmlentities}" data-rule="required" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|
@ -44,8 +51,8 @@
|
||||||
<div class="form-group hidden layer-footer">
|
<div class="form-group hidden layer-footer">
|
||||||
<label class="control-label col-xs-12 col-sm-2"></label>
|
<label class="control-label col-xs-12 col-sm-2"></label>
|
||||||
<div class="col-xs-12 col-sm-8">
|
<div class="col-xs-12 col-sm-8">
|
||||||
<button type="submit" class="btn btn-success btn-embossed disabled">{:__('OK')}</button>
|
<button type="submit" class="btn btn-primary btn-embossed disabled">{:__('OK')}</button>
|
||||||
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
|
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,9 @@
|
||||||
<div id="toolbar" class="toolbar">
|
<div id="toolbar" class="toolbar">
|
||||||
{:build_toolbar('refresh,add,delete')}
|
{:build_toolbar('refresh,add,delete')}
|
||||||
</div>
|
</div>
|
||||||
<table id="table" class="table table-striped table-bordered table-hover"
|
<table id="table" class="table table-striped table-bordered table-hover table-nowrap"
|
||||||
data-operate-edit="{:$auth->check('auth/admin/edit')}"
|
data-operate-edit="{:$auth->check('auth/admin/edit')}"
|
||||||
data-operate-del="{:$auth->check('auth/admin/del')}"
|
data-operate-del="{:$auth->check('auth/admin/del')}"
|
||||||
width="100%">
|
width="100%">
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -18,4 +18,4 @@
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,22 @@
|
||||||
<table class="table table-striped">
|
<style>
|
||||||
|
.table-adminlog tr td {
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<table class="table table-striped table-adminlog">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{:__('Title')}</th>
|
<th width="100">{:__('Title')}</th>
|
||||||
<th>{:__('Content')}</th>
|
<th>{:__('Content')}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{volist name="row" id="vo" }
|
{volist name="row" id="vo" }
|
||||||
<tr>
|
<tr>
|
||||||
<td>{:__($key)}</td>
|
<td>{:__($key)}</td>
|
||||||
<td>{$vo}</td>
|
<td>{if $key=='createtime'}{$vo|datetime}{else/}{$vo|htmlentities}{/if}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{/volist}
|
{/volist}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<div class="hide layer-footer">
|
<div class="hide layer-footer">
|
||||||
|
|
@ -19,4 +24,4 @@
|
||||||
<div class="col-xs-12 col-sm-8">
|
<div class="col-xs-12 col-sm-8">
|
||||||
<button type="reset" class="btn btn-primary btn-embossed btn-close" onclick="Layer.closeAll();">{:__('Close')}</button>
|
<button type="reset" class="btn btn-primary btn-embossed btn-close" onclick="Layer.closeAll();">{:__('Close')}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,9 @@
|
||||||
<div id="toolbar" class="toolbar">
|
<div id="toolbar" class="toolbar">
|
||||||
{:build_toolbar('refresh,delete')}
|
{:build_toolbar('refresh,delete')}
|
||||||
</div>
|
</div>
|
||||||
<table id="table" class="table table-striped table-bordered table-hover"
|
<table id="table" class="table table-striped table-bordered table-hover table-nowrap"
|
||||||
data-operate-detail="{:$auth->check('auth/adminlog/index')}"
|
data-operate-detail="{:$auth->check('auth/adminlog/index')}"
|
||||||
data-operate-del="{:$auth->check('auth/adminlog/del')}"
|
data-operate-del="{:$auth->check('auth/adminlog/del')}"
|
||||||
width="100%">
|
width="100%">
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -18,4 +18,4 @@
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
<form id="add-form" class="form-horizontal form-ajax" role="form" data-toggle="validator" method="POST" action="">
|
<form id="add-form" class="form-horizontal form-ajax" role="form" data-toggle="validator" method="POST" action="">
|
||||||
|
{:token()}
|
||||||
<input type="hidden" name="row[rules]" value="" />
|
<input type="hidden" name="row[rules]" value="" />
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="control-label col-xs-12 col-sm-2">{:__('Parent')}:</label>
|
<label class="control-label col-xs-12 col-sm-2">{:__('Parent')}:</label>
|
||||||
|
|
@ -15,8 +16,8 @@
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="control-label col-xs-12 col-sm-2">{:__('Permission')}:</label>
|
<label class="control-label col-xs-12 col-sm-2">{:__('Permission')}:</label>
|
||||||
<div class="col-xs-12 col-sm-8">
|
<div class="col-xs-12 col-sm-8">
|
||||||
<span class="text-muted"><input type="checkbox" name="" id="checkall" /> <label for="checkall"><small>{:__('Check all')}</small></label></span>
|
<span class="text-muted"><input type="checkbox" name="" id="checkall" /> <label for="checkall"><span>{:__('Check all')}</span></label></span>
|
||||||
<span class="text-muted"><input type="checkbox" name="" id="expandall" /> <label for="expandall"><small>{:__('Expand all')}</small></label></span>
|
<span class="text-muted"><input type="checkbox" name="" id="expandall" /> <label for="expandall"><span>{:__('Expand all')}</span></label></span>
|
||||||
|
|
||||||
<div id="treeview"></div>
|
<div id="treeview"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -30,7 +31,7 @@
|
||||||
<div class="form-group hidden layer-footer">
|
<div class="form-group hidden layer-footer">
|
||||||
<label class="control-label col-xs-12 col-sm-2"></label>
|
<label class="control-label col-xs-12 col-sm-2"></label>
|
||||||
<div class="col-xs-12 col-sm-8">
|
<div class="col-xs-12 col-sm-8">
|
||||||
<button type="submit" class="btn btn-success btn-embossed disabled">{:__('OK')}</button>
|
<button type="submit" class="btn btn-primary btn-embossed disabled">{:__('OK')}</button>
|
||||||
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
|
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
<form id="edit-form" class="form-horizontal form-ajax" role="form" method="POST" action="">
|
<form id="edit-form" class="form-horizontal form-ajax" role="form" method="POST" action="">
|
||||||
|
{:token()}
|
||||||
<input type="hidden" name="row[rules]" value="" />
|
<input type="hidden" name="row[rules]" value="" />
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="control-label col-xs-12 col-sm-2">{:__('Parent')}:</label>
|
<label class="control-label col-xs-12 col-sm-2">{:__('Parent')}:</label>
|
||||||
|
|
@ -9,14 +10,14 @@
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="control-label col-xs-12 col-sm-2">{:__('Name')}:</label>
|
<label class="control-label col-xs-12 col-sm-2">{:__('Name')}:</label>
|
||||||
<div class="col-xs-12 col-sm-8">
|
<div class="col-xs-12 col-sm-8">
|
||||||
<input type="text" class="form-control" id="name" name="row[name]" value="{$row.name}" data-rule="required" />
|
<input type="text" class="form-control" id="name" name="row[name]" value="{$row.name|htmlentities}" data-rule="required" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="control-label col-xs-12 col-sm-2">{:__('Permission')}:</label>
|
<label class="control-label col-xs-12 col-sm-2">{:__('Permission')}:</label>
|
||||||
<div class="col-xs-12 col-sm-8">
|
<div class="col-xs-12 col-sm-8">
|
||||||
<span class="text-muted"><input type="checkbox" name="" id="checkall" /> <label for="checkall"><small>{:__('Check all')}</small></label></span>
|
<span class="text-muted"><input type="checkbox" name="" id="checkall" /> <label for="checkall"><span>{:__('Check all')}</span></label></span>
|
||||||
<span class="text-muted"><input type="checkbox" name="" id="expandall" /> <label for="expandall"><small>{:__('Expand all')}</small></label></span>
|
<span class="text-muted"><input type="checkbox" name="" id="expandall" /> <label for="expandall"><span>{:__('Expand all')}</span></label></span>
|
||||||
|
|
||||||
<div id="treeview"></div>
|
<div id="treeview"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -30,7 +31,7 @@
|
||||||
<div class="form-group hidden layer-footer">
|
<div class="form-group hidden layer-footer">
|
||||||
<label class="control-label col-xs-12 col-sm-2 col-xs-2"></label>
|
<label class="control-label col-xs-12 col-sm-2 col-xs-2"></label>
|
||||||
<div class="col-xs-12 col-sm-8">
|
<div class="col-xs-12 col-sm-8">
|
||||||
<button type="submit" class="btn btn-success btn-embossed disabled">{:__('OK')}</button>
|
<button type="submit" class="btn btn-primary btn-embossed disabled">{:__('OK')}</button>
|
||||||
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
|
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,9 @@
|
||||||
<div id="toolbar" class="toolbar">
|
<div id="toolbar" class="toolbar">
|
||||||
{:build_toolbar('refresh,add,delete')}
|
{:build_toolbar('refresh,add,delete')}
|
||||||
</div>
|
</div>
|
||||||
<table id="table" class="table table-striped table-bordered table-hover"
|
<table id="table" class="table table-striped table-bordered table-hover table-nowrap"
|
||||||
data-operate-edit="{:$auth->check('auth/group/edit')}"
|
data-operate-edit="{:$auth->check('auth/group/edit')}"
|
||||||
data-operate-del="{:$auth->check('auth/group/del')}"
|
data-operate-del="{:$auth->check('auth/group/del')}"
|
||||||
width="100%">
|
width="100%">
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
<form id="add-form" class="form-horizontal form-ajax" role="form" data-toggle="validator" method="POST" action="">
|
<form id="add-form" class="form-horizontal form-ajax" role="form" data-toggle="validator" method="POST" action="">
|
||||||
|
{:token()}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="control-label col-xs-12 col-sm-2">{:__('Ismenu')}:</label>
|
<label class="control-label col-xs-12 col-sm-2">{:__('Ismenu')}:</label>
|
||||||
<div class="col-xs-12 col-sm-8">
|
<div class="col-xs-12 col-sm-8">
|
||||||
|
|
@ -14,7 +15,6 @@
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="name" class="control-label col-xs-12 col-sm-2">{:__('Name')}:</label>
|
<label for="name" class="control-label col-xs-12 col-sm-2">{:__('Name')}:</label>
|
||||||
<div class="col-xs-12 col-sm-8">
|
<div class="col-xs-12 col-sm-8">
|
||||||
<a href="javascript:;" data-toggle="tooltip" title="提示">测试</a>
|
|
||||||
<input type="text" class="form-control" id="name" name="row[name]" data-placeholder-node="{:__('Node tips')}" data-placeholder-menu="{:__('Menu tips')}" value="" data-rule="required" />
|
<input type="text" class="form-control" id="name" name="row[name]" data-placeholder-node="{:__('Node tips')}" data-placeholder-menu="{:__('Menu tips')}" value="" data-rule="required" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -24,33 +24,52 @@
|
||||||
<input type="text" class="form-control" id="title" name="row[title]" value="" data-rule="required" />
|
<input type="text" class="form-control" id="title" name="row[title]" value="" data-rule="required" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group" data-type="menu">
|
||||||
|
<label class="control-label col-xs-12 col-sm-2">{:__('Url')}:</label>
|
||||||
|
<div class="col-xs-12 col-sm-8">
|
||||||
|
<input type="text" class="form-control" id="url" name="row[url]" value="" data-rule="" placeholder="{:__('Url tips')}" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="icon" class="control-label col-xs-12 col-sm-2">{:__('Icon')}:</label>
|
<label for="icon" class="control-label col-xs-12 col-sm-2">{:__('Icon')}:</label>
|
||||||
<div class="col-xs-12 col-sm-8">
|
<div class="col-xs-12 col-sm-8">
|
||||||
<div class="input-group input-groupp-md">
|
<div class="input-group input-groupp-md">
|
||||||
|
<span class="input-group-addon"><i class="fa fa-circle-o" id="icon-style"></i></span>
|
||||||
<input type="text" class="form-control" id="icon" name="row[icon]" value="fa fa-circle-o" />
|
<input type="text" class="form-control" id="icon" name="row[icon]" value="fa fa-circle-o" />
|
||||||
<a href="javascript:;" class="btn-search-icon input-group-addon">{:__('Search icon')}</a>
|
<a href="javascript:;" class="btn-search-icon input-group-addon">{:__('Search icon')}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
|
||||||
<label for="weigh" class="control-label col-xs-12 col-sm-2">{:__('Weigh')}:</label>
|
|
||||||
<div class="col-xs-12 col-sm-8">
|
|
||||||
<input type="text" class="form-control" id="weigh" name="row[weigh]" value="0" data-rule="required" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="remark" class="control-label col-xs-12 col-sm-2">{:__('Condition')}:</label>
|
<label for="remark" class="control-label col-xs-12 col-sm-2">{:__('Condition')}:</label>
|
||||||
<div class="col-xs-12 col-sm-8">
|
<div class="col-xs-12 col-sm-8">
|
||||||
<textarea class="form-control" id="condition" name="row[condition]"></textarea>
|
<textarea class="form-control" id="condition" name="row[condition]"></textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group" data-type="menu">
|
||||||
|
<label for="remark" class="control-label col-xs-12 col-sm-2">{:__('Menutype')}:</label>
|
||||||
|
<div class="col-xs-12 col-sm-8">
|
||||||
|
{:build_radios('row[menutype]', $menutypeList)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group" data-type="menu">
|
||||||
|
<label for="remark" class="control-label col-xs-12 col-sm-2">{:__('Extend')}:</label>
|
||||||
|
<div class="col-xs-12 col-sm-8">
|
||||||
|
<textarea class="form-control" id="extend" name="row[extend]"></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="remark" class="control-label col-xs-12 col-sm-2">{:__('Remark')}:</label>
|
<label for="remark" class="control-label col-xs-12 col-sm-2">{:__('Remark')}:</label>
|
||||||
<div class="col-xs-12 col-sm-8">
|
<div class="col-xs-12 col-sm-8">
|
||||||
<textarea class="form-control" id="remark" name="row[remark]"></textarea>
|
<textarea class="form-control" id="remark" name="row[remark]"></textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="weigh" class="control-label col-xs-12 col-sm-2">{:__('Weigh')}:</label>
|
||||||
|
<div class="col-xs-12 col-sm-8">
|
||||||
|
<input type="text" class="form-control" id="weigh" name="row[weigh]" value="0" data-rule="required" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label>
|
<label class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label>
|
||||||
<div class="col-xs-12 col-sm-8">
|
<div class="col-xs-12 col-sm-8">
|
||||||
|
|
@ -60,9 +79,9 @@
|
||||||
<div class="form-group hidden layer-footer">
|
<div class="form-group hidden layer-footer">
|
||||||
<div class="col-xs-2"></div>
|
<div class="col-xs-2"></div>
|
||||||
<div class="col-xs-12 col-sm-8">
|
<div class="col-xs-12 col-sm-8">
|
||||||
<button type="submit" class="btn btn-success btn-embossed disabled">{:__('OK')}</button>
|
<button type="submit" class="btn btn-primary btn-embossed disabled">{:__('OK')}</button>
|
||||||
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
|
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
{include file="auth/rule/tpl" /}
|
{include file="auth/rule/tpl" /}
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue