Compare commits
2383 Commits
9694525fc7
...
f344d2deab
| Author | SHA1 | Date |
|---|---|---|
|
|
f344d2deab | |
|
|
8674f1125c | |
|
|
bb7a6aad0d | |
|
|
2b12969d3a | |
|
|
a3d35f6f09 | |
|
|
47a6ea5297 | |
|
|
d8b9be889c | |
|
|
7ec745c52c | |
|
|
746b0382d9 | |
|
|
99f87cc9e6 | |
|
|
7e3f2be082 | |
|
|
b23a926dd5 | |
|
|
c07bdda87f | |
|
|
a1ba2917f8 | |
|
|
a78d61e96e | |
|
|
def439de4d | |
|
|
8750c828f7 | |
|
|
41ba00a3b3 | |
|
|
e4e6601f21 | |
|
|
3063e764f9 | |
|
|
b3e70910ff | |
|
|
df96ffafa5 | |
|
|
1a3b7d134f | |
|
|
2d28ca8e68 | |
|
|
d0c4bc77e7 | |
|
|
69e9a051c1 | |
|
|
f72b61a4a3 | |
|
|
2e7d2b7cb2 | |
|
|
2430791a25 | |
|
|
33784ebbdb | |
|
|
e1a4d1b3cc | |
|
|
9529d68d38 | |
|
|
ef14e65e31 | |
|
|
2ad26852f0 | |
|
|
5649d40560 | |
|
|
7e3ee84096 | |
|
|
a531cc0173 | |
|
|
754ddb58a4 | |
|
|
a418db518b | |
|
|
13285c6cbc | |
|
|
86fa909e44 | |
|
|
cac2adc614 | |
|
|
65a6808c00 | |
|
|
7f585d6b51 | |
|
|
2704c42f71 | |
|
|
35543ed409 | |
|
|
5b262df391 | |
|
|
f0058fa6b4 | |
|
|
6d274a74d9 | |
|
|
fe0c328c76 | |
|
|
b8ee27e84f | |
|
|
530e5f22fe | |
|
|
20131129fe | |
|
|
9eb9a43fce | |
|
|
0b11ada7a2 | |
|
|
4cffc1a159 | |
|
|
d61c0a5e12 | |
|
|
e9aa555609 | |
|
|
5af461e617 | |
|
|
391f28ede7 | |
|
|
b4ddf33810 | |
|
|
cb3a9951b3 | |
|
|
d89dd1b7c6 | |
|
|
e33431f59a | |
|
|
b2811aafce | |
|
|
0e9395b98e | |
|
|
e71a98e915 | |
|
|
b86cee3b3e | |
|
|
b28712e2d5 | |
|
|
473ed35cd9 | |
|
|
975cfa1d69 | |
|
|
b074e2a6c1 | |
|
|
2c460d696e | |
|
|
9287e0fc47 | |
|
|
1cbf9af4a4 | |
|
|
2ea6cdd49b | |
|
|
56ef2dece8 | |
|
|
1ec759c7e4 | |
|
|
e7019a9722 | |
|
|
523b8a3e7c | |
|
|
05da652822 | |
|
|
130a4544cc | |
|
|
9ecf31aecd | |
|
|
2b7b0a9011 | |
|
|
fb1c2e4c1c | |
|
|
8d165eadf8 | |
|
|
0a5518d801 | |
|
|
d935eb4ff3 | |
|
|
6d85aac561 | |
|
|
271732fa2b | |
|
|
43f6fdbb40 | |
|
|
fdbe7120c0 | |
|
|
25fd03c3c7 | |
|
|
0c18aedbb1 | |
|
|
65f8023891 | |
|
|
6a16540d1b | |
|
|
a29245b5d4 | |
|
|
fb8ac8dea4 | |
|
|
8f167ac2b0 | |
|
|
3aec43abb7 | |
|
|
a55b1f5a63 | |
|
|
168f65ed8e | |
|
|
f98c93f099 | |
|
|
b320aab6b6 | |
|
|
39d8d85425 | |
|
|
607751abc6 | |
|
|
fc609a9b67 | |
|
|
8b711fa653 | |
|
|
64cedc39d4 | |
|
|
68f91b589f | |
|
|
78ed309eec | |
|
|
d6f518dff6 | |
|
|
5b83f02098 | |
|
|
619523c472 | |
|
|
b5cc1ba786 | |
|
|
1574805a5a | |
|
|
0bd592b648 | |
|
|
2fd52c1761 | |
|
|
204d91e5d0 | |
|
|
8ea52fb8ff | |
|
|
f4657a9bed | |
|
|
fcb6c888dc | |
|
|
812b7655af | |
|
|
b88d889861 | |
|
|
a1626dc21b | |
|
|
9d020adaee | |
|
|
56c6c7f055 | |
|
|
d2a68741d4 | |
|
|
f26e239668 | |
|
|
ffaef2312b | |
|
|
b595085b7e | |
|
|
0b6609b419 | |
|
|
f60aa84886 | |
|
|
8de7f7e08c | |
|
|
89adc4d8d1 | |
|
|
ab549d1cd8 | |
|
|
8c5178fa77 | |
|
|
d434eafec9 | |
|
|
6636986904 | |
|
|
c4e0d4a52e | |
|
|
5e869252c9 | |
|
|
07276ed14c | |
|
|
e33521f60e | |
|
|
52fbd72915 | |
|
|
fe170590db | |
|
|
203c937230 | |
|
|
edcc4afca8 | |
|
|
7ba52a3bf3 | |
|
|
7955534530 | |
|
|
0085f2dd2d | |
|
|
1f7e2e9942 | |
|
|
6ed7d11368 | |
|
|
a431e3785d | |
|
|
3da30a2ff7 | |
|
|
a961ab8277 | |
|
|
8fcd26dcd7 | |
|
|
4ef9eeac5b | |
|
|
77bf0bca1a | |
|
|
4869e4252e | |
|
|
775171b14a | |
|
|
c6d07b1834 | |
|
|
773d1469bd | |
|
|
10eb858ef1 | |
|
|
1cc2bf53a5 | |
|
|
3e2a27d2b8 | |
|
|
c1d6c48f5b | |
|
|
67d1b85952 | |
|
|
920689fbee | |
|
|
76b37ed867 | |
|
|
2956a536ff | |
|
|
4e5fe381b4 | |
|
|
2a2067204a | |
|
|
d1fed8b618 | |
|
|
a3470b27c0 | |
|
|
f744dc6b02 | |
|
|
e7734f2551 | |
|
|
6e1b2a4347 | |
|
|
5c99565d69 | |
|
|
399eeb0547 | |
|
|
318d2d9cfa | |
|
|
c4858b5875 | |
|
|
5f9eeb74d8 | |
|
|
98e962a6fd | |
|
|
d4b8c148a1 | |
|
|
d8027054bc | |
|
|
237b777c0a | |
|
|
4b4f0ea2e9 | |
|
|
19f15b54a8 | |
|
|
5c4ae14dbc | |
|
|
e1e3ee9568 | |
|
|
11626a73af | |
|
|
6213226a99 | |
|
|
b5be111f41 | |
|
|
fb6ef5d512 | |
|
|
0362952282 | |
|
|
d074c123d9 | |
|
|
634a4a2bd2 | |
|
|
86b3d33d6d | |
|
|
d233cd2fca | |
|
|
76edc24c77 | |
|
|
3266cb4924 | |
|
|
9ee28acf64 | |
|
|
a9b39b1632 | |
|
|
12600ee14e | |
|
|
b8889cb9c5 | |
|
|
b7195e2d01 | |
|
|
835a7b3098 | |
|
|
73c0b9ebf3 | |
|
|
3de48b35de | |
|
|
e61c9a6def | |
|
|
ed10fe3df8 | |
|
|
cfc922ae46 | |
|
|
5831ea962d | |
|
|
439be0068e | |
|
|
8e49870218 | |
|
|
423ed6a145 | |
|
|
37cb7d30a8 | |
|
|
aacda723b2 | |
|
|
ee06e1dbf5 | |
|
|
ebc96147c5 | |
|
|
a30c12d86d | |
|
|
9fe36070c1 | |
|
|
d1cc1bea61 | |
|
|
1ca5545459 | |
|
|
f2f50efb79 | |
|
|
7e934151f0 | |
|
|
024a2190f2 | |
|
|
a75d795098 | |
|
|
68231b0538 | |
|
|
dff24e9675 | |
|
|
88255f6e7b | |
|
|
8ab99143b9 | |
|
|
7bf19e2c92 | |
|
|
688f6a2511 | |
|
|
d84393b237 | |
|
|
e907a1adae | |
|
|
3e727a6cf9 | |
|
|
4d5f217a1e | |
|
|
265eb68f22 | |
|
|
bf5ef979c0 | |
|
|
7eb8fe3477 | |
|
|
56f17772ca | |
|
|
af6f079b43 | |
|
|
3a456ceb58 | |
|
|
92b005d25c | |
|
|
736388eb7b | |
|
|
ad56dc561f | |
|
|
5192ebc897 | |
|
|
fc9b71e052 | |
|
|
1527721142 | |
|
|
a329f280d9 | |
|
|
c3ce7bdcc1 | |
|
|
873954614a | |
|
|
b023ee7a1c | |
|
|
c66ef7738a | |
|
|
87a37d6252 | |
|
|
8933cbbdd4 | |
|
|
d038ad3f56 | |
|
|
88187b8b91 | |
|
|
f4e5705175 | |
|
|
c24b22dc9d | |
|
|
43a3b6b10a | |
|
|
726c6e2528 | |
|
|
ca02f9c2cf | |
|
|
ac217f36ed | |
|
|
571eba695d | |
|
|
e54d9bbc45 | |
|
|
5190f39577 | |
|
|
75e7fe01ea | |
|
|
a1b1f6ba15 | |
|
|
3971ad5977 | |
|
|
c7338ba877 | |
|
|
9f68330ad5 | |
|
|
a11607c6c3 | |
|
|
72e003e166 | |
|
|
0dd46eba0b | |
|
|
40cad5c50f | |
|
|
077cf6c099 | |
|
|
26188255ad | |
|
|
4ab15cc605 | |
|
|
44f288e817 | |
|
|
ea15f19fcb | |
|
|
0f871a483c | |
|
|
5401b1559c | |
|
|
d8ccb852e3 | |
|
|
f844a9bd70 | |
|
|
2dc6a1242f | |
|
|
c1670c6442 | |
|
|
2053e6add7 | |
|
|
ff094d8cfd | |
|
|
68aacec7d4 | |
|
|
ff6c2211a0 | |
|
|
575469ca3d | |
|
|
532057689b | |
|
|
c85a5b7575 | |
|
|
06735bc0e4 | |
|
|
0be2a71a8e | |
|
|
32b35e32c1 | |
|
|
46b9ebfa41 | |
|
|
43c7a5461e | |
|
|
e1430873a1 | |
|
|
313ebe2be5 | |
|
|
4a2ebec30f | |
|
|
9ddf91578b | |
|
|
107a7371b3 | |
|
|
c988b851a8 | |
|
|
b4586bd452 | |
|
|
bb85406c62 | |
|
|
1b1fbf3a4c | |
|
|
0b118df670 | |
|
|
49fd22944b | |
|
|
8ffd3b77c2 | |
|
|
688d4f42d3 | |
|
|
3ff13b3c70 | |
|
|
59bcdb0fda | |
|
|
fdac7066ed | |
|
|
e0c2acc630 | |
|
|
33cb20d436 | |
|
|
f0d3762b66 | |
|
|
01650b8f11 | |
|
|
41aa11bbf2 | |
|
|
0aa7c345a1 | |
|
|
0a501c26f0 | |
|
|
e5b6a38057 | |
|
|
80c6135711 | |
|
|
6803b0e05d | |
|
|
13e46886a8 | |
|
|
31f42458fe | |
|
|
d0c7b43cce | |
|
|
d381396062 | |
|
|
30f7e5d2a2 | |
|
|
0307831081 | |
|
|
cd0136c892 | |
|
|
d0cee69fc6 | |
|
|
d8039cead5 | |
|
|
f94fb84a80 | |
|
|
07a9417343 | |
|
|
46172e4fa8 | |
|
|
cd7a764b01 | |
|
|
d25ac50551 | |
|
|
90c1f0ed15 | |
|
|
5566633370 | |
|
|
d35aeeb86d | |
|
|
e939088104 | |
|
|
7e342e54ef | |
|
|
417da1899e | |
|
|
d7276d2f4a | |
|
|
1675a07c9b | |
|
|
26d8f562ee | |
|
|
23f46124cd | |
|
|
f2d7f76ab9 | |
|
|
63638f9588 | |
|
|
a5191440c6 | |
|
|
34c45dcde9 | |
|
|
6957eefae6 | |
|
|
407c03bea3 | |
|
|
85edc96d41 | |
|
|
7e972a8723 | |
|
|
1276d0a98b | |
|
|
27bfe41623 | |
|
|
0f0ba924ce | |
|
|
a55d234e94 | |
|
|
c0482e5f1c | |
|
|
b744abfadf | |
|
|
3ad6129740 | |
|
|
0a0a9ab25f | |
|
|
9191f51176 | |
|
|
1a653be8fa | |
|
|
74f8cdafe9 | |
|
|
6b125a0aa9 | |
|
|
f0239b8f62 | |
|
|
572e23b2bb | |
|
|
c95d9be140 | |
|
|
9fe2b28655 | |
|
|
c60e32b401 | |
|
|
72a385efbb | |
|
|
ed5a43b692 | |
|
|
6095b5de23 | |
|
|
393b25f34e | |
|
|
65c65a11fb | |
|
|
6eeeea11cc | |
|
|
c17e1fb651 | |
|
|
6d4c9ba9a7 | |
|
|
3a65ad5233 | |
|
|
c455e5a949 | |
|
|
33644b40c9 | |
|
|
4d6c89cf6c | |
|
|
76e45fd16e | |
|
|
b36ebb3cb0 | |
|
|
e19a5b42d5 | |
|
|
c022e1f75b | |
|
|
72f7004cf2 | |
|
|
7a142b7c6c | |
|
|
f0526c1177 | |
|
|
ee833b9eaa | |
|
|
db6614e7a3 | |
|
|
02855c5fb3 | |
|
|
e69f9f819a | |
|
|
0aaccebccf | |
|
|
3fb202cebc | |
|
|
8be5c71871 | |
|
|
7100d83d61 | |
|
|
59da252a18 | |
|
|
59f47ec84c | |
|
|
2743057667 | |
|
|
843bdb73fe | |
|
|
bf632700a0 | |
|
|
1220abb705 | |
|
|
588d3b0e90 | |
|
|
0c47803a90 | |
|
|
632b18006a | |
|
|
ed1badd404 | |
|
|
bd14ecf41b | |
|
|
8451c0b819 | |
|
|
ed31084759 | |
|
|
9b484e03f2 | |
|
|
e00ad4f241 | |
|
|
5d4f0c99df | |
|
|
d35952fe5c | |
|
|
fcee9191ad | |
|
|
f643c76632 | |
|
|
9579ae8c08 | |
|
|
b61c8cf9b6 | |
|
|
1b4c5bf027 | |
|
|
30b7f7e33f | |
|
|
35e3655ae6 | |
|
|
1a53a7fbeb | |
|
|
f3de1b098a | |
|
|
e41d366f60 | |
|
|
7e569330d7 | |
|
|
0eda9b8cec | |
|
|
459bb3db51 | |
|
|
50ca3e4aff | |
|
|
8634a9a861 | |
|
|
6a600d1f16 | |
|
|
470d5cf21c | |
|
|
d0aeeb522b | |
|
|
216bf84a2c | |
|
|
7443f9d74c | |
|
|
1e2583b421 | |
|
|
d3624990e8 | |
|
|
853b2b03b9 | |
|
|
2012d2b0f5 | |
|
|
ef6185b13d | |
|
|
0c74f77fcc | |
|
|
13936b36c2 | |
|
|
1a23c49f90 | |
|
|
100333d56f | |
|
|
181faeb4a1 | |
|
|
2f66a6b945 | |
|
|
71ab7a5da8 | |
|
|
5919f0d971 | |
|
|
fe66b21e9c | |
|
|
79f6f77e2d | |
|
|
421c73fe7e | |
|
|
b071433bef | |
|
|
0927019297 | |
|
|
1eb219cc0e | |
|
|
a3d2236df8 | |
|
|
671a7f18d0 | |
|
|
8cf154bbab | |
|
|
9052087431 | |
|
|
af58eb52f1 | |
|
|
b177e7d7fd | |
|
|
4a157a8e8f | |
|
|
71d1d39a47 | |
|
|
9f3946253a | |
|
|
1f15bbda6f | |
|
|
434d94c01d | |
|
|
0911ba6102 | |
|
|
5d58662e82 | |
|
|
4a423b7500 | |
|
|
17e2af1e2a | |
|
|
581afaf330 | |
|
|
0b1bb96039 | |
|
|
4d2e11057f | |
|
|
89725cb383 | |
|
|
53689a70c2 | |
|
|
81013aaeb0 | |
|
|
5300993c7b | |
|
|
799e689d9f | |
|
|
1948aeb866 | |
|
|
cee6fbe296 | |
|
|
c1db80eaaa | |
|
|
6e8d7f295f | |
|
|
c5da315a30 | |
|
|
2852732891 | |
|
|
c05b21efc7 | |
|
|
de7df33788 | |
|
|
1613adc3fa | |
|
|
a91477bf25 | |
|
|
b7e402a732 | |
|
|
fe0f922de0 | |
|
|
4f5b2821e6 | |
|
|
8384db4911 | |
|
|
9dbc004044 | |
|
|
726b607a88 | |
|
|
102ffb4fa4 | |
|
|
969399525c | |
|
|
f46ca53bf3 | |
|
|
81a99fa32e | |
|
|
3e28593746 | |
|
|
98f02dd7b4 | |
|
|
15302b3c28 | |
|
|
7d48a7e140 | |
|
|
4cb3bfda91 | |
|
|
99c32242cb | |
|
|
79a88bfb63 | |
|
|
a0382782d0 | |
|
|
2b8cbdf1ac | |
|
|
94c3094c18 | |
|
|
b91d0184a2 | |
|
|
9e8f4e3ea7 | |
|
|
cfd2c9911a | |
|
|
f07e511256 | |
|
|
70b2d83682 | |
|
|
f26cbaf0dd | |
|
|
3c6442d698 | |
|
|
c2b82b4bee | |
|
|
fb02010079 | |
|
|
03d0ba9b42 | |
|
|
08d951fe90 | |
|
|
282987f1ff | |
|
|
dbae784622 | |
|
|
d7b7c173e4 | |
|
|
6109d7c5c4 | |
|
|
4a98a53b99 | |
|
|
e338aa07aa | |
|
|
1867349057 | |
|
|
7dbf37bcfa | |
|
|
a3787d4cab | |
|
|
63b41e54a6 | |
|
|
d90d55fc82 | |
|
|
a65caab2f9 | |
|
|
3ac1152c65 | |
|
|
7c3670dd22 | |
|
|
06604a3d19 | |
|
|
548405a983 | |
|
|
970419a175 | |
|
|
83b468907b | |
|
|
85cfe3ecf5 | |
|
|
88160552c4 | |
|
|
b91373a093 | |
|
|
4696b75bf3 | |
|
|
f97496d6de | |
|
|
fe16241f26 | |
|
|
40f8cf8c9c | |
|
|
6aa4c4b24e | |
|
|
dbf6963475 | |
|
|
67adb1b79f | |
|
|
2243b63e76 | |
|
|
2288afd01f | |
|
|
ce2626e8e8 | |
|
|
051e1d9790 | |
|
|
f5e20ce2da | |
|
|
3f81dec2eb | |
|
|
cadc91d2da | |
|
|
f55255ba8b | |
|
|
5a94945dee | |
|
|
28c9e44ef9 | |
|
|
96577ab1d6 | |
|
|
2bbff19a86 | |
|
|
9a09a42f81 | |
|
|
fa7a31ec9c | |
|
|
bb346ab584 | |
|
|
9f67ec43f0 | |
|
|
ec30668fa4 | |
|
|
6a21576f06 | |
|
|
9bec24b2cb | |
|
|
4441ad5fec | |
|
|
9451ab57a6 | |
|
|
fc496aa4dd | |
|
|
55423be548 | |
|
|
cc6f47a99d | |
|
|
b48342403a | |
|
|
0b372e0325 | |
|
|
9413de29c7 | |
|
|
a6322880d0 | |
|
|
126755cf89 | |
|
|
42b86f3cec | |
|
|
088d3103fe | |
|
|
58223f5ea8 | |
|
|
04c3385ef1 | |
|
|
6f5147edb8 | |
|
|
b5db580ee5 | |
|
|
52d55d18e8 | |
|
|
a22b63198c | |
|
|
a3000ab36f | |
|
|
5eadd65981 | |
|
|
9fe3b46dc1 | |
|
|
b4fc5948f0 | |
|
|
7710b0a0b7 | |
|
|
3bf40cdc96 | |
|
|
fc663f6c14 | |
|
|
940b82cdeb | |
|
|
eb16ddf105 | |
|
|
3ecff0b803 | |
|
|
d3089a6d50 | |
|
|
daf5de8973 | |
|
|
55da96c94f | |
|
|
50d414f5e7 | |
|
|
8e67faf4fb | |
|
|
f893a77545 | |
|
|
bfa77f6cbd | |
|
|
3b5917d27f | |
|
|
8f01392c74 | |
|
|
49c1fd49a7 | |
|
|
257b9c620d | |
|
|
f8d70ca46b | |
|
|
3877b1f0d9 | |
|
|
71237ca31d | |
|
|
e086c2f570 | |
|
|
34d91c1bf6 | |
|
|
7cd4fba72f | |
|
|
cd8bed7d30 | |
|
|
b61d560f49 | |
|
|
8573766ccd | |
|
|
03cf8159b2 | |
|
|
50c33fd9d2 | |
|
|
02cdd6b040 | |
|
|
b0c0c8b9fa | |
|
|
eb1a29d69f | |
|
|
43edd08b64 | |
|
|
24063e9d7d | |
|
|
d658d16edb | |
|
|
1677664285 | |
|
|
97f3db810a | |
|
|
aa76941cf7 | |
|
|
7bb7939f76 | |
|
|
874cf8f84b | |
|
|
3e6d1db82a | |
|
|
d766dfbe36 | |
|
|
b1ac15af0e | |
|
|
fc3dd67fae | |
|
|
27ca333817 | |
|
|
8cddc5fa5a | |
|
|
683145f45a | |
|
|
cbf56ba55d | |
|
|
5916ea0b31 | |
|
|
73ee668c8b | |
|
|
de1c40121b | |
|
|
eb0b08bd6c | |
|
|
f1a8d55eec | |
|
|
4ce6a39d38 | |
|
|
354d43028d | |
|
|
103826fdb4 | |
|
|
97cbbba590 | |
|
|
8a9eef81e7 | |
|
|
458041e66d | |
|
|
a45ff32259 | |
|
|
315c31b5bd | |
|
|
e38a6a8ab4 | |
|
|
971158a11c | |
|
|
1127186f7f | |
|
|
3942ffe36b | |
|
|
ad0376c077 | |
|
|
1768a7fb77 | |
|
|
d8abb038b0 | |
|
|
77b3167d36 | |
|
|
14be551526 | |
|
|
171b1a4b05 | |
|
|
8ca284f762 | |
|
|
dbc403550c | |
|
|
aeb6312f4c | |
|
|
b818cb8037 | |
|
|
8cfe7f2660 | |
|
|
3993a229f7 | |
|
|
cc322ca23b | |
|
|
61fc6ab82a | |
|
|
581a8eb9d7 | |
|
|
5bd60354a3 | |
|
|
604d55127d | |
|
|
687c3a99c5 | |
|
|
8d0d349fec | |
|
|
3249bbe0ba | |
|
|
1d6267b172 | |
|
|
d6a8a23c26 | |
|
|
e77f861efb | |
|
|
ab79c6751b | |
|
|
a07d38a6b0 | |
|
|
7947596b8b | |
|
|
77951b54ee | |
|
|
370364002b | |
|
|
526827ff64 | |
|
|
977fe8cd2f | |
|
|
99eb8c2cbd | |
|
|
cdf7c6724d | |
|
|
8e038cdac4 | |
|
|
75aca94d09 | |
|
|
bfa4088b7b | |
|
|
13a6969511 | |
|
|
34c959b222 | |
|
|
f46c8925d1 | |
|
|
13fcbfbe20 | |
|
|
acc85159bd | |
|
|
f4ac449ffc | |
|
|
458357dba5 | |
|
|
cac7d30e0a | |
|
|
0e17f523e2 | |
|
|
7029befc57 | |
|
|
6074f08c6f | |
|
|
ad49e97200 | |
|
|
1085238859 | |
|
|
e89272aeec | |
|
|
5671f2d2bf | |
|
|
77f28a598e | |
|
|
d6263e6db6 | |
|
|
48837d4e04 | |
|
|
f3a664f8ca | |
|
|
fc21a56188 | |
|
|
c91cf02915 | |
|
|
36610480e9 | |
|
|
35e1de6b5d | |
|
|
2a38c6c228 | |
|
|
d687f0636d | |
|
|
65ef508256 | |
|
|
605371ca63 | |
|
|
9acda217c8 | |
|
|
cccdf77800 | |
|
|
ae5c8f13ff | |
|
|
c860ac3576 | |
|
|
7bf59dfc86 | |
|
|
22cce28b3b | |
|
|
f4992691aa | |
|
|
cd36f8153d | |
|
|
3e76716d36 | |
|
|
786dfccbfd | |
|
|
bd2b81c9df | |
|
|
fae1588d18 | |
|
|
b435b0b807 | |
|
|
b585cc5d7a | |
|
|
d84aee1cd5 | |
|
|
a4525802c4 | |
|
|
760e74f81a | |
|
|
e92fc3eb31 | |
|
|
46913d88f6 | |
|
|
b7b24ece6b | |
|
|
1edce65c79 | |
|
|
1b1459d06c | |
|
|
cf223caeab | |
|
|
2d86529eb8 | |
|
|
71d743d34a | |
|
|
8f22790abd | |
|
|
b54f9cb89e | |
|
|
2ab8ba876b | |
|
|
9ec42fb6f7 | |
|
|
f399bd04cb | |
|
|
b1fc78e6cb | |
|
|
65d678c225 | |
|
|
3ab2808b14 | |
|
|
7e3860fcd5 | |
|
|
7d562b04f7 | |
|
|
a761e03f5b | |
|
|
e863b1c97b | |
|
|
0d8fd327b5 | |
|
|
8de027e9bc | |
|
|
4f7d0aea94 | |
|
|
1729264e67 | |
|
|
8680901d83 | |
|
|
a0bf115f56 | |
|
|
21727e2b7a | |
|
|
0e1b102146 | |
|
|
ea032fe4a7 | |
|
|
9cd6934a02 | |
|
|
e1ca1e35d0 | |
|
|
611ddd5e3a | |
|
|
8dff40add6 | |
|
|
7a2b89fb29 | |
|
|
4e39972676 | |
|
|
e005981fb7 | |
|
|
a1f8238152 | |
|
|
49e8df844b | |
|
|
5b89353afe | |
|
|
9d65337fbd | |
|
|
7111fdfa2b | |
|
|
e296d11b19 | |
|
|
397c2faf04 | |
|
|
fe26f3fc3d | |
|
|
26e0e90c9b | |
|
|
050e152e1c | |
|
|
219b1e0ecf | |
|
|
38f050bb54 | |
|
|
0ea1809b24 | |
|
|
f1c5db8a20 | |
|
|
6368877934 | |
|
|
afd3e9904f | |
|
|
ec9ebe09eb | |
|
|
4e67dcdff4 | |
|
|
83a626812e | |
|
|
94ccacfafa | |
|
|
a7266f78a0 | |
|
|
563bb29704 | |
|
|
3fe4fc8e46 | |
|
|
a580ece7b3 | |
|
|
1ab37520b0 | |
|
|
d17777a055 | |
|
|
2e6bf802d4 | |
|
|
760be5eda8 | |
|
|
15fc690c1a | |
|
|
43a31f478b | |
|
|
24145203f9 | |
|
|
e9af38bda6 | |
|
|
9d0e71d6c8 | |
|
|
1e091fdc8c | |
|
|
f8bbd05156 | |
|
|
a5aab1fcd6 | |
|
|
64088f4c3e | |
|
|
7a64fffcfc | |
|
|
2a1c04c4ec | |
|
|
f8be721fec | |
|
|
5982417078 | |
|
|
5fdbc4b538 | |
|
|
66220b3dfd | |
|
|
42caca4405 | |
|
|
c934723260 | |
|
|
f8eac18cc5 | |
|
|
51651ff787 | |
|
|
089ef22cd6 | |
|
|
a7f55ba1cb | |
|
|
f8db5ebf18 | |
|
|
a00b9748e0 | |
|
|
87abf47087 | |
|
|
19a740f3be | |
|
|
3b633951a0 | |
|
|
bb86dd1bd1 | |
|
|
9cd7ea8ac7 | |
|
|
e5cb71adbc | |
|
|
68bbdfe59d | |
|
|
5a808133ef | |
|
|
85048e4cfb | |
|
|
a3ce0b63d0 | |
|
|
542f777fb0 | |
|
|
70c172136c | |
|
|
99ed272346 | |
|
|
055e16fd9b | |
|
|
04320a707e | |
|
|
2aef836a9b | |
|
|
a03396ba12 | |
|
|
88b12065b8 | |
|
|
62eb321079 | |
|
|
822ab3d6d3 | |
|
|
0bffa6c77a | |
|
|
64fdcfa712 | |
|
|
0305c28373 | |
|
|
f94e780462 | |
|
|
ffa2c7d370 | |
|
|
81b38ade1d | |
|
|
a592dc4cf7 | |
|
|
9c9abd5ea9 | |
|
|
cd370fb6c3 | |
|
|
00f67ea7da | |
|
|
5708660d67 | |
|
|
716d617e78 | |
|
|
cfebf09a74 | |
|
|
3b4f3b1e8c | |
|
|
58c3b518c0 | |
|
|
804fb97ac7 | |
|
|
19dd2f75d8 | |
|
|
848b091720 | |
|
|
1c2bb06b0d | |
|
|
2c999f65eb | |
|
|
52f40302fd | |
|
|
b23746c125 | |
|
|
35677a7dd2 | |
|
|
adf9f84684 | |
|
|
62092ac70d | |
|
|
ae7da23394 | |
|
|
f400e77d97 | |
|
|
70531b87f9 | |
|
|
96288ddc23 | |
|
|
12863c0f6e | |
|
|
211711dfee | |
|
|
46a23e8be3 | |
|
|
ebfa9471d2 | |
|
|
9d35dee8de | |
|
|
c7fc8937b1 | |
|
|
7c39bfdb03 | |
|
|
491c82be52 | |
|
|
6319408298 | |
|
|
d69571b07c | |
|
|
efa48abb53 | |
|
|
79bc196e15 | |
|
|
2ad3d6047b | |
|
|
b78eeae8b2 | |
|
|
b087d4efe7 | |
|
|
fe1eadc550 | |
|
|
ff87b819fc | |
|
|
3ddaec6960 | |
|
|
d7527a9d06 | |
|
|
5e1f89aa81 | |
|
|
9426a42120 | |
|
|
e694408e87 | |
|
|
c6c9c5252f | |
|
|
7378f1997b | |
|
|
49a80db477 | |
|
|
b2b985daf9 | |
|
|
c3c94acaff | |
|
|
a3e19e0c06 | |
|
|
bb83fce199 | |
|
|
19afee7ff6 | |
|
|
eabfd69e9f | |
|
|
88f00f21c4 | |
|
|
d9523418a1 | |
|
|
8627c755f0 | |
|
|
81b7ae932a | |
|
|
038ceeaa1a | |
|
|
4396b1f133 | |
|
|
a74e52eb4f | |
|
|
9eac695df4 | |
|
|
ddd9fad9a4 | |
|
|
459cf6ee00 | |
|
|
9e5b6a840d | |
|
|
e248d596f4 | |
|
|
9c05241727 | |
|
|
858b386d6a | |
|
|
39794da2ea | |
|
|
44f72291e2 | |
|
|
618a356406 | |
|
|
f58bb18fe7 | |
|
|
167ee5c1df | |
|
|
5fa4492c8e | |
|
|
7fa995ab87 | |
|
|
3c1eb1f6f9 | |
|
|
26983bcf8c | |
|
|
f636ffc08d | |
|
|
b01903b8c6 | |
|
|
4a0e0c6b61 | |
|
|
66136547c5 | |
|
|
9677a902ea | |
|
|
4227a98f7b | |
|
|
9938e66658 | |
|
|
6c9e2d8124 | |
|
|
62cde1dbf2 | |
|
|
7559b57bc8 | |
|
|
3c1ffdc0f8 | |
|
|
5c233f1bc5 | |
|
|
dcc1640b1c | |
|
|
e5f6a4d319 | |
|
|
b88afed286 | |
|
|
ed6eea3382 | |
|
|
0ba62d4ada | |
|
|
766fa9c2e0 | |
|
|
c9f26d2935 | |
|
|
460a1b846c | |
|
|
d9cbfe79fa | |
|
|
a93da78132 | |
|
|
7fcca73b1d | |
|
|
4b773c6b18 | |
|
|
84940bd41b | |
|
|
cbac2513d7 | |
|
|
c5f6c22f33 | |
|
|
9212617242 | |
|
|
752200ea93 | |
|
|
f802f48299 | |
|
|
ffd688cfc6 | |
|
|
6f731804c6 | |
|
|
229831408d | |
|
|
06b812d5e2 | |
|
|
e2a1621fe6 | |
|
|
234ac1032a | |
|
|
d2034636ef | |
|
|
740e1661de | |
|
|
cdc0ea4304 | |
|
|
17cac83ada | |
|
|
4564cc7358 | |
|
|
dcd7ba47c3 | |
|
|
949bd99946 | |
|
|
1596c985b8 | |
|
|
46b9f9b967 | |
|
|
c33480aac3 | |
|
|
3beeeffd02 | |
|
|
1e3a799bdb | |
|
|
60122b82bc | |
|
|
4643926768 | |
|
|
4b0f31ad52 | |
|
|
8f72766115 | |
|
|
731faf5367 | |
|
|
c29cf811fc | |
|
|
9b6d341ba2 | |
|
|
3c765bd641 | |
|
|
8340fc781e | |
|
|
623fed1af3 | |
|
|
28f8655a92 | |
|
|
f98df0ff36 | |
|
|
80a0c6b5a7 | |
|
|
361e352c5e | |
|
|
0fecf2a4b6 | |
|
|
38f12d70e0 | |
|
|
a975b764f1 | |
|
|
1f44791384 | |
|
|
9c5154ceb0 | |
|
|
2e8d9b4083 | |
|
|
fcc95039f9 | |
|
|
1edae323ab | |
|
|
236b8cb8b1 | |
|
|
b964a7ea73 | |
|
|
38d26b7b67 | |
|
|
13a2097621 | |
|
|
e7335b9582 | |
|
|
51034d5308 | |
|
|
6b860fb2be | |
|
|
d3f88d4a72 | |
|
|
051564d32c | |
|
|
081b0d81a0 | |
|
|
748bc43df9 | |
|
|
1fbb409602 | |
|
|
101b07cabd | |
|
|
711c62d9b7 | |
|
|
d591a6ce38 | |
|
|
ab8c3f20dd | |
|
|
e72d64a4cb | |
|
|
6063e26661 | |
|
|
f1c3707302 | |
|
|
f24b298307 | |
|
|
379c052e94 | |
|
|
b9b2ef7525 | |
|
|
df8b7db1cd | |
|
|
b048499795 | |
|
|
bc547194fa | |
|
|
40a8891c07 | |
|
|
2e6fa3479f | |
|
|
b8dd4f3fb3 | |
|
|
3503560202 | |
|
|
87e8b16a38 | |
|
|
65b5efb904 | |
|
|
c57b96ba8d | |
|
|
dc16ece325 | |
|
|
0ff6615cad | |
|
|
0e7f144f63 | |
|
|
054359af34 | |
|
|
54bfb88e12 | |
|
|
725c888a6b | |
|
|
45c1366ec5 | |
|
|
cbed7f0c34 | |
|
|
e2dd6c6086 | |
|
|
729fdf2f9a | |
|
|
06533e15e6 | |
|
|
4d2e9b3efd | |
|
|
d7deeb62df | |
|
|
52fd9ce208 | |
|
|
7d40d7e6e0 | |
|
|
122af22e6f | |
|
|
92178afd19 | |
|
|
b65c2590b7 | |
|
|
2503012cd8 | |
|
|
0d28e4765e | |
|
|
d0fea5ec2d | |
|
|
4cb0078572 | |
|
|
04e2b39f1c | |
|
|
e04d25d8af | |
|
|
2da64d98b7 | |
|
|
1252708660 | |
|
|
68deac8aa1 | |
|
|
3256469e1c | |
|
|
3b469512aa | |
|
|
7c3b5f27a5 | |
|
|
106471ea2e | |
|
|
fbb35e59be | |
|
|
739aceb8bd | |
|
|
bb640e53de | |
|
|
c82284154f | |
|
|
fff09b9684 | |
|
|
e1063eb3f2 | |
|
|
69090d84ca | |
|
|
6bbb4d1cbd | |
|
|
088234a922 | |
|
|
c1465b321c | |
|
|
c151453167 | |
|
|
2a556c8684 | |
|
|
614757ecaf | |
|
|
b194c7670f | |
|
|
c97c715bd8 | |
|
|
6a072f886e | |
|
|
5f9fae29b4 | |
|
|
aecc9a547a | |
|
|
636650ad45 | |
|
|
d8149e8b1e | |
|
|
6af43a0547 | |
|
|
9c6c38aef4 | |
|
|
c85159de1b | |
|
|
1daca70b3a | |
|
|
a53898ed78 | |
|
|
9c1597eb6d | |
|
|
d3968c3a02 | |
|
|
2ed93cd88a | |
|
|
ea69096b34 | |
|
|
f140e541e1 | |
|
|
68e10f001b | |
|
|
f4930768ee | |
|
|
e548fa845a | |
|
|
6d9081e4e2 | |
|
|
43fb0ceb76 | |
|
|
cbd1338aff | |
|
|
e7017fa8b9 | |
|
|
ca0320253d | |
|
|
ba32addfdb | |
|
|
05410da29e | |
|
|
fc9c826b0c | |
|
|
367f334c4d | |
|
|
54345c0b18 | |
|
|
d66566fe04 | |
|
|
7b87e42f53 | |
|
|
5bfc4b84a2 | |
|
|
9c7080b379 | |
|
|
c3616e5b33 | |
|
|
6d01a6515d | |
|
|
802ae9dbd9 | |
|
|
60e49ee22a | |
|
|
419f29debe | |
|
|
a1ee7cda6e | |
|
|
9d8c40a81b | |
|
|
2686a8f40f | |
|
|
5b7cc2bcbc | |
|
|
a13a310efb | |
|
|
6090c3fe14 | |
|
|
1f34cf67fa | |
|
|
497d33a08d | |
|
|
8af086162f | |
|
|
700390790f | |
|
|
8659720060 | |
|
|
0717ecccba | |
|
|
8bc503482f | |
|
|
529640cbf6 | |
|
|
6fd0fb353b | |
|
|
fac2319826 | |
|
|
7866d0adc0 | |
|
|
3a2a7cf49f | |
|
|
8f5261d660 | |
|
|
7d16765883 | |
|
|
a82b7462e6 | |
|
|
5198f647b0 | |
|
|
c6512f3189 | |
|
|
e39fad0f2e | |
|
|
8b89df5be3 | |
|
|
f861261b3c | |
|
|
28e1bbfe9a | |
|
|
ff831f0741 | |
|
|
dffc6e6799 | |
|
|
f394b20d31 | |
|
|
c504ab90d8 | |
|
|
b77f500fac | |
|
|
0265def552 | |
|
|
f1304f51bf | |
|
|
5c4b9d6f2d | |
|
|
12cd640353 | |
|
|
f98ab08b5e | |
|
|
180f6f0b2c | |
|
|
785f08fa01 | |
|
|
bf76f1758a | |
|
|
b1393a2720 | |
|
|
8d192b9a90 | |
|
|
9fdc1491b4 | |
|
|
52fa511d52 | |
|
|
ee185aedf3 | |
|
|
53810c492a | |
|
|
e389c3b184 | |
|
|
8394ab5c6b | |
|
|
b4c5874ddf | |
|
|
27cc1e9529 | |
|
|
47d00e5308 | |
|
|
226e5a7e99 | |
|
|
17d0e28aec | |
|
|
d42cd187dc | |
|
|
a01c57c025 | |
|
|
d670a46c32 | |
|
|
f0dd991d1e | |
|
|
728c5a7671 | |
|
|
3002721a48 | |
|
|
efc2bc6227 | |
|
|
2eda2bc745 | |
|
|
d7d6028974 | |
|
|
26eb9989d2 | |
|
|
d6eee750ec | |
|
|
2e989a3382 | |
|
|
3aa20d084a | |
|
|
67be2fd9fa | |
|
|
6053e67915 | |
|
|
e1d01356b0 | |
|
|
25dc11c69f | |
|
|
44cc4f6c72 | |
|
|
ac0f1ac48e | |
|
|
2d104a0f2c | |
|
|
a610c9231f | |
|
|
6efe768138 | |
|
|
62c9921750 | |
|
|
9c977e00bf | |
|
|
72801d1b75 | |
|
|
1f81608fed | |
|
|
393d0416d2 | |
|
|
edcb1fe46b | |
|
|
b292c3e174 | |
|
|
bb7ba05f82 | |
|
|
2ba15ab156 | |
|
|
f9246bd436 | |
|
|
61417c4e58 | |
|
|
bf2346d2c1 | |
|
|
b310755a55 | |
|
|
da28dcdcc8 | |
|
|
714c720bcf | |
|
|
7838e20337 | |
|
|
9e17fbb956 | |
|
|
ece7f64ba9 | |
|
|
e9d3ba13cd | |
|
|
f62863876f | |
|
|
62a6c89696 | |
|
|
45d9d629cf | |
|
|
28c188d5ce | |
|
|
6ffb987275 | |
|
|
b512f6260d | |
|
|
a350b867cd | |
|
|
173af2594f | |
|
|
ffe91e5bdc | |
|
|
d23d07cdf0 | |
|
|
31f163d56d | |
|
|
8f07c8448a | |
|
|
e38626d2f4 | |
|
|
5bc7e004fb | |
|
|
162771bdfe | |
|
|
73de2614c1 | |
|
|
bef8d6fe76 | |
|
|
334a321bfc | |
|
|
36208c0c35 | |
|
|
35c464f47e | |
|
|
d60e00d993 | |
|
|
a0b60ffad5 | |
|
|
22944781c3 | |
|
|
d6d82dc2ef | |
|
|
a86136ba15 | |
|
|
c07de5c130 | |
|
|
d02f8e354b | |
|
|
13582f2559 | |
|
|
519193fef9 | |
|
|
6d2c7de17e | |
|
|
f475313e27 | |
|
|
20ddc21147 | |
|
|
e7734e02d1 | |
|
|
0c6bc6c220 | |
|
|
827272dbb2 | |
|
|
1eba785fac | |
|
|
17f862be2a | |
|
|
829ecfb759 | |
|
|
0bd3580af5 | |
|
|
b95cffb9ff | |
|
|
7b4c1ab407 | |
|
|
8259973dc4 | |
|
|
83bda1760b | |
|
|
76475832e0 | |
|
|
c9ae8a56ec | |
|
|
773c01c4c5 | |
|
|
2aeba25590 | |
|
|
4835250392 | |
|
|
822df95290 | |
|
|
6cbecf90e6 | |
|
|
0f27656ec0 | |
|
|
0bcdc4e222 | |
|
|
02dd913ec1 | |
|
|
cd096c6cf2 | |
|
|
2e201dd789 | |
|
|
59ead57e17 | |
|
|
9959a0a128 | |
|
|
fdd434aa64 | |
|
|
495b0047cb | |
|
|
473868fd09 | |
|
|
f5a7004ea3 | |
|
|
945d3cb7e3 | |
|
|
7f08b8c97c | |
|
|
d76933dcca | |
|
|
23b1b2dd15 | |
|
|
baa790e60d | |
|
|
6ea370ad61 | |
|
|
06193e9a1c | |
|
|
979db45a89 | |
|
|
c5ae46389d | |
|
|
0ddfde5e0c | |
|
|
b5a8e46b2b | |
|
|
a6a0b4cfbc | |
|
|
ac9ecb3f9d | |
|
|
58b32aa523 | |
|
|
9984dfd3d0 | |
|
|
2cc9159f94 | |
|
|
d387d49da9 | |
|
|
6046959f84 | |
|
|
c15be1e737 | |
|
|
e916e943c2 | |
|
|
97780cb2f9 | |
|
|
db4c22cf31 | |
|
|
1ea67b0a35 | |
|
|
2655bb8895 | |
|
|
5b503d9038 | |
|
|
86b9bf4c60 | |
|
|
9df4565d7c | |
|
|
dca5bdd4a3 | |
|
|
d2a9056802 | |
|
|
bc713a5976 | |
|
|
315c3e8a2e | |
|
|
dd1828a94a | |
|
|
026f5008e5 | |
|
|
550d95679f | |
|
|
8831abec50 | |
|
|
fbd4f61128 | |
|
|
ba67262e9e | |
|
|
f6e02c9990 | |
|
|
e49a778f2b | |
|
|
728871ef14 | |
|
|
00790c1d6c | |
|
|
b0f1472d2b | |
|
|
0405a9a855 | |
|
|
2790fe648f | |
|
|
789c2f4fa6 | |
|
|
0d6dcf1d98 | |
|
|
152f8379b9 | |
|
|
de8b8525ea | |
|
|
a3cfcf9df5 | |
|
|
a45dbc1f22 | |
|
|
2f40420032 | |
|
|
92125c6542 | |
|
|
af6d9ceabf | |
|
|
7354b0c6e5 | |
|
|
d011cf2803 | |
|
|
3eb3b3a37b | |
|
|
064291a05e | |
|
|
e19735f5a7 | |
|
|
2bee77437c | |
|
|
638686f9ff | |
|
|
49a2a25489 | |
|
|
9170cf49cb | |
|
|
481c06a15a | |
|
|
036b6a466e | |
|
|
f911ddbd68 | |
|
|
5d6a84a473 | |
|
|
630c4e193e | |
|
|
4648eb4064 | |
|
|
2ccc43163c | |
|
|
63181c5acd | |
|
|
66eeca3b7f | |
|
|
93a27cc2ad | |
|
|
649af7a262 | |
|
|
e819b2f731 | |
|
|
090d238d11 | |
|
|
5f154deec3 | |
|
|
fe9f91e970 | |
|
|
746376c9f4 | |
|
|
910186a284 | |
|
|
ef64b06977 | |
|
|
06b6967285 | |
|
|
cd021027ed | |
|
|
ceb0aa0686 | |
|
|
51a7638b47 | |
|
|
b5186bdb9d | |
|
|
0094116ef9 | |
|
|
c0acb4fb4d | |
|
|
8ca50a622d | |
|
|
a91e403350 | |
|
|
a9e2d920f1 | |
|
|
d1f0a7c403 | |
|
|
e629a794d1 | |
|
|
87e5ef5800 | |
|
|
c369003a28 | |
|
|
8014a361da | |
|
|
5a06a7511e | |
|
|
69ef6e9355 | |
|
|
3326be05cd | |
|
|
f3cef76a4f | |
|
|
a45406aec2 | |
|
|
edb860774d | |
|
|
7753e11f8b | |
|
|
14e6055bf9 | |
|
|
3ecea9db53 | |
|
|
8a391f7f53 | |
|
|
1da21fc8bb | |
|
|
4737893f59 | |
|
|
aac3ad7c90 | |
|
|
20fbf8109d | |
|
|
4027bb3631 | |
|
|
1b8e643880 | |
|
|
acec51efdd | |
|
|
ad90a9f5ca | |
|
|
0dbf34348c | |
|
|
3b633d2801 | |
|
|
41c84432ef | |
|
|
0935d95e97 | |
|
|
838eec4bcc | |
|
|
0a22238629 | |
|
|
d269352143 | |
|
|
0303420679 | |
|
|
f95af926c1 | |
|
|
9fb56b1e4b | |
|
|
b33ebd65bb | |
|
|
1f98b34339 | |
|
|
10a70d5e28 | |
|
|
7aa0a2047e | |
|
|
77197021cd | |
|
|
7b53d76a43 | |
|
|
ebc81a3363 | |
|
|
c733c82681 | |
|
|
0e2ef8a96e | |
|
|
9d7ff6e116 | |
|
|
a6801ef182 | |
|
|
8eb65c3f9d | |
|
|
38d8496aef | |
|
|
8cc4e416cc | |
|
|
f7e9ec5070 | |
|
|
c2a9ae1771 | |
|
|
a8a42195ca | |
|
|
d881e4e795 | |
|
|
de4f48065b | |
|
|
ab39f23dff | |
|
|
f327089f0c | |
|
|
427d754b0d | |
|
|
6e6321a1a0 | |
|
|
2bb83153a9 | |
|
|
59eb050d11 | |
|
|
9fba918f72 | |
|
|
364cb4ed84 | |
|
|
959e10d194 | |
|
|
9999d99fd6 | |
|
|
77bc06ad01 | |
|
|
ad26df2af7 | |
|
|
f63ebe7241 | |
|
|
76cde0a92a | |
|
|
652c703523 | |
|
|
7e499faaca | |
|
|
26d9454aa0 | |
|
|
2a3fbe2a1c | |
|
|
a818c0c9f7 | |
|
|
0ce474df27 | |
|
|
c4a82b6e9d | |
|
|
06b8b9f12d | |
|
|
95ad14093a | |
|
|
622901eaf5 | |
|
|
224d8d6693 | |
|
|
72536a702b | |
|
|
846b2ce7a1 | |
|
|
98f4a25520 | |
|
|
8731be2ab1 | |
|
|
262031236f | |
|
|
607e48b8dc | |
|
|
ede0cd9fe2 | |
|
|
78a932ea7a | |
|
|
75d6b3ed34 | |
|
|
060f10e5ac | |
|
|
c76a81cdda | |
|
|
abd7a3afc9 | |
|
|
80d68c811a | |
|
|
116c7c5c45 | |
|
|
0bf5b06163 | |
|
|
e247632af2 | |
|
|
c51e580dac | |
|
|
71c675fb84 | |
|
|
d910da229b | |
|
|
1c68777112 | |
|
|
770d24f656 | |
|
|
c898aa3e94 | |
|
|
7ad626da07 | |
|
|
47137d6a64 | |
|
|
4d0e0b2b86 | |
|
|
80140aa9d6 | |
|
|
8e114d16c4 | |
|
|
9743af143f | |
|
|
e67c0b555c | |
|
|
32cd2765d7 | |
|
|
d253c64613 | |
|
|
8b8fe1730d | |
|
|
32dfe47037 | |
|
|
4f88ce7570 | |
|
|
0c3185691a | |
|
|
64e5921a25 | |
|
|
45818e5e85 | |
|
|
a08bc47403 | |
|
|
4deb48b09a | |
|
|
877f9205d0 | |
|
|
da8854a62f | |
|
|
3920639f34 | |
|
|
aa4d8f2903 | |
|
|
083c0f653d | |
|
|
61800bb7e4 | |
|
|
03b9d18071 | |
|
|
678969331b | |
|
|
fc6cb5c8dc | |
|
|
55ea7eb031 | |
|
|
d50b1eb907 | |
|
|
68b596bbbe | |
|
|
5bb0fb7e61 | |
|
|
944b50969b | |
|
|
c93b3cf643 | |
|
|
fb398b2663 | |
|
|
c5c73005e9 | |
|
|
2d7f5e9ddd | |
|
|
dc9d9c43a4 | |
|
|
16b7519258 | |
|
|
5898c5abd0 | |
|
|
e9a90c08aa | |
|
|
f621f41039 | |
|
|
b8d2ae6cfb | |
|
|
cb484688d2 | |
|
|
7cc8056af9 | |
|
|
af70118116 | |
|
|
b1aa079c31 | |
|
|
bc8fb4f929 | |
|
|
36afc88779 | |
|
|
32896c07c0 | |
|
|
9c33863e07 | |
|
|
8aa0982fb4 | |
|
|
850e306f2b | |
|
|
b3e97082fd | |
|
|
352badce6b | |
|
|
7310e822c5 | |
|
|
476a7c89dc | |
|
|
5de6d87f9d | |
|
|
4fe4dfdef6 | |
|
|
47e71a7b21 | |
|
|
de2a6161c5 | |
|
|
09db47f1e3 | |
|
|
e3db4613b4 | |
|
|
5bf30c4649 | |
|
|
d064095e92 | |
|
|
1031b2e89f | |
|
|
07111c8396 | |
|
|
657f4d67bb | |
|
|
147d680c4a | |
|
|
69346f9f86 | |
|
|
055f897106 | |
|
|
34a8f9bb2b | |
|
|
c5ea49428d | |
|
|
e221f3804f | |
|
|
4b23f93884 | |
|
|
078d93ee24 | |
|
|
702d13d560 | |
|
|
8ebe6a0979 | |
|
|
5f212c3740 | |
|
|
d451113e6e | |
|
|
50aff2df9e | |
|
|
093ef7c4a5 | |
|
|
ce9d2e9399 | |
|
|
ec7dbb1da2 | |
|
|
2e4115dbe6 | |
|
|
c273d52f54 | |
|
|
c84ff9fa86 | |
|
|
ff092ce042 | |
|
|
e840541280 | |
|
|
4a78e0cf67 | |
|
|
6aa541d761 | |
|
|
9e7ddd2ac0 | |
|
|
7320c2e7d7 | |
|
|
965d6ff0f5 | |
|
|
fce7f41f5d | |
|
|
640f8d139a | |
|
|
a3d2ce92f7 | |
|
|
9df01b2900 | |
|
|
96b7481123 | |
|
|
5c4f167915 | |
|
|
07aeabd87c | |
|
|
a6e2f430e4 | |
|
|
e7b2124bad | |
|
|
d7691c3970 | |
|
|
c194e78903 | |
|
|
5ec9e2365b | |
|
|
e7254d5ef6 | |
|
|
2c42140329 | |
|
|
b4d25ce7c6 | |
|
|
3dc300e6be | |
|
|
8a2d39d6c9 | |
|
|
ba53d3f844 | |
|
|
fd88d859aa | |
|
|
7f438877b3 | |
|
|
4c7ddfc30b | |
|
|
7f8c248d14 | |
|
|
34a6faf3d7 | |
|
|
9fe3037f6d | |
|
|
0c74fc87eb | |
|
|
ff10ec9370 | |
|
|
e66d5f115b | |
|
|
53f7530cee | |
|
|
b64d3b223f | |
|
|
4e16cf4e16 | |
|
|
2cd58f48c2 | |
|
|
f2b7d18704 | |
|
|
ab4b827b75 | |
|
|
1e79d950ba | |
|
|
075e0dac7a | |
|
|
72b0ca6640 | |
|
|
9f4ebf7ffe | |
|
|
3332927af8 | |
|
|
35cb596557 | |
|
|
971db18c19 | |
|
|
028e5c3ae3 | |
|
|
c20e3a556a | |
|
|
b67f53cd5a | |
|
|
14d13e0ce1 | |
|
|
a7377c7e9f | |
|
|
93cdb22fb9 | |
|
|
b7bd77ba76 | |
|
|
6773546efd | |
|
|
1e204a5223 | |
|
|
72c2ea0bb0 | |
|
|
8574301902 | |
|
|
f63efa5f5e | |
|
|
ac9fffd532 | |
|
|
c3f38d9a84 | |
|
|
e6b42fd2a2 | |
|
|
fe778a4273 | |
|
|
1635178f80 | |
|
|
045fb2fcf5 | |
|
|
1f4c3914dd | |
|
|
b3bff6f829 | |
|
|
641dce77e8 | |
|
|
bdb36da1f7 | |
|
|
e36f3b6b7a | |
|
|
30a76e22a9 | |
|
|
006750c9bc | |
|
|
4942180b5f | |
|
|
9ebe2f604e | |
|
|
dda399f1db | |
|
|
3b1eaca6fb | |
|
|
f14ef5a029 | |
|
|
bcbd5db00f | |
|
|
c431ffbb83 | |
|
|
9e77667360 | |
|
|
be240bb21a | |
|
|
a294e2cf04 | |
|
|
8caac6ab9f | |
|
|
474bac5955 | |
|
|
71489cc733 | |
|
|
12e86c7bcc | |
|
|
cc3bdfc7b5 | |
|
|
5372de0b6a | |
|
|
3b86cb97d5 | |
|
|
677fa5c25d | |
|
|
231988fdd7 | |
|
|
8f5dc98f7e | |
|
|
c63af2b89b | |
|
|
5890db5e08 | |
|
|
be9a795a0f | |
|
|
43979bfc4c | |
|
|
c40f743d69 | |
|
|
8b86d42793 | |
|
|
230749b98b | |
|
|
bd531e3514 | |
|
|
455de33cbb | |
|
|
de8e574a29 | |
|
|
d16b6f2c4a | |
|
|
f8d5f15c16 | |
|
|
7d67dd0d5c | |
|
|
75a20bbf1a | |
|
|
f9fbb8bbde | |
|
|
8a6c66fb83 | |
|
|
70283cade3 | |
|
|
918d3b385d | |
|
|
7cabf52ec7 | |
|
|
92b1655f9d | |
|
|
7e99c1821c | |
|
|
01f1822c27 | |
|
|
78f3a181d7 | |
|
|
10e6fd87bd | |
|
|
b55c42a151 | |
|
|
af2302ccf5 | |
|
|
d434f50abc | |
|
|
217bdbadc3 | |
|
|
79846ed46f | |
|
|
2a4b3e2e5e | |
|
|
4e6bcceba3 | |
|
|
c9e0822075 | |
|
|
f355a7c22c | |
|
|
d10e46b466 | |
|
|
8e0330b01c | |
|
|
e118705324 | |
|
|
6f73e1aa95 | |
|
|
98bcb8c939 | |
|
|
6b81f266ee | |
|
|
e9bb58ebd5 | |
|
|
7524e69868 | |
|
|
3ee8b90e78 | |
|
|
4950e361c6 | |
|
|
92507b04cb | |
|
|
63efb506f7 | |
|
|
25ec233e16 | |
|
|
53356d0f24 | |
|
|
3ea38a9d76 | |
|
|
41cdd02729 | |
|
|
1fae241ccb | |
|
|
0d846b65b5 | |
|
|
2657855d0b | |
|
|
19e5ecc29a | |
|
|
26f0c2caa4 | |
|
|
fddda16a07 | |
|
|
2f16280609 | |
|
|
c4ca33ec32 | |
|
|
c06e0c5725 | |
|
|
31759e8448 | |
|
|
d8c698f32e | |
|
|
35d5d08796 | |
|
|
2ae5c54cb0 | |
|
|
07074142d8 | |
|
|
53763ad8eb | |
|
|
75e8dcd6e4 | |
|
|
4c9f47bca1 | |
|
|
a3327dda5e | |
|
|
fd315a1348 | |
|
|
4662761255 | |
|
|
9007cc8a41 | |
|
|
da37c49705 | |
|
|
98e8501f53 | |
|
|
af5dceb6c0 | |
|
|
d95889813e | |
|
|
05f41a39a2 | |
|
|
1dad0a3e6d | |
|
|
09bf086724 | |
|
|
15c9d9e8d0 | |
|
|
c54969d587 | |
|
|
cb0f626790 | |
|
|
fe523d6628 | |
|
|
9d4c117c44 | |
|
|
7280c7e3c2 | |
|
|
95ac80ee36 | |
|
|
13f952d25d | |
|
|
4d7aaa0c8a | |
|
|
61d931785a | |
|
|
ad31828c5f | |
|
|
c6779e7bc3 | |
|
|
a24b5d5c4c | |
|
|
0be99e30fb | |
|
|
8a36d5ea3d | |
|
|
e4d384dd2c | |
|
|
37b4feff6c | |
|
|
7976bb7d3a | |
|
|
5b66c075a6 | |
|
|
d36e991ab0 | |
|
|
55a57244f9 | |
|
|
bf3a1bedfa | |
|
|
c279cede8b | |
|
|
2120581011 | |
|
|
e3abd5e7fb | |
|
|
2cc07af5e8 | |
|
|
e002acbf71 | |
|
|
e3df76729f | |
|
|
bd63951402 | |
|
|
cb970ce18d | |
|
|
bceae1a6b3 | |
|
|
e3a5043b95 | |
|
|
0705c31ab0 | |
|
|
7b22326c98 | |
|
|
a57181d386 | |
|
|
2f35268205 | |
|
|
abe56e99b2 | |
|
|
782cc0d571 | |
|
|
18798aab5b | |
|
|
22f5683b63 | |
|
|
5b5630cd95 | |
|
|
28d92d8b40 | |
|
|
316085e4e2 | |
|
|
94b7ec588a | |
|
|
8cf90c601c | |
|
|
4721cb49b3 | |
|
|
08fc2f8525 | |
|
|
cdbd42c464 | |
|
|
3cddcd8ce8 | |
|
|
db43cfa8a3 | |
|
|
9f6ad09ef8 | |
|
|
ef0d22ca93 | |
|
|
badabe39cb | |
|
|
9da2cd8234 | |
|
|
6fa5818e82 | |
|
|
acfad8a621 | |
|
|
21fb3e07ed | |
|
|
e7480df0c5 | |
|
|
3539d32cbc | |
|
|
ef3e5dc70d | |
|
|
2d8ff03822 | |
|
|
b125165f2b | |
|
|
bdb156662d | |
|
|
15af10665d | |
|
|
58298575cb | |
|
|
72ff8f34bb | |
|
|
a7a8c5c844 | |
|
|
917197533e | |
|
|
fa61a18e92 | |
|
|
565c1d78d1 | |
|
|
a17ed15393 | |
|
|
43f3771b17 | |
|
|
f62926bc81 | |
|
|
7254ab4b06 | |
|
|
fad0422534 | |
|
|
8a56d7cbdd | |
|
|
de3fb017f2 | |
|
|
0fd6b1afc0 | |
|
|
85e9958503 | |
|
|
70fb76b4df | |
|
|
b062726646 | |
|
|
b6638db628 | |
|
|
41a699c43c | |
|
|
4fe74bff27 | |
|
|
2fcfeaf8c0 | |
|
|
3046dff6a0 | |
|
|
aba64f5d14 | |
|
|
1c9f981891 | |
|
|
8677bae4f4 | |
|
|
c8167099ef | |
|
|
a92bbf50ac | |
|
|
9986f62fa4 | |
|
|
8aa7ec697f | |
|
|
3abfb798c5 | |
|
|
e531c1ade0 | |
|
|
46afdc8f09 | |
|
|
8025bb9160 | |
|
|
891e1db59d | |
|
|
70b0cfdd44 | |
|
|
9561514271 | |
|
|
d8f893e5ed | |
|
|
6fc85bf127 | |
|
|
7470ca3a82 | |
|
|
6fcd8141b3 | |
|
|
18945b8843 | |
|
|
e31d582754 | |
|
|
cfc6af6536 | |
|
|
78302f4591 | |
|
|
e1949b330f | |
|
|
6ce395f544 | |
|
|
b8c21f66e5 | |
|
|
4b9c77a630 | |
|
|
ea0e4296cd | |
|
|
b313636592 | |
|
|
3bcece155e | |
|
|
789fef8f1f | |
|
|
ed8a5fa1f1 | |
|
|
210325cf05 | |
|
|
e240b8363a | |
|
|
2d0de819ea | |
|
|
e9b66f64e4 | |
|
|
a45a119db8 | |
|
|
3f71eef985 | |
|
|
383c0c8fcf | |
|
|
ccc883ece7 | |
|
|
d91b54c06a | |
|
|
eba9c802c1 | |
|
|
408f0b3e84 | |
|
|
6e9c8064c0 | |
|
|
5ffcfaeb00 | |
|
|
b2a8699edf | |
|
|
91aaa2296a | |
|
|
18b9752ce1 | |
|
|
4ed20f7acb | |
|
|
2591357bf8 | |
|
|
5296e55671 | |
|
|
43bba3fbe0 | |
|
|
07a9e7e41f | |
|
|
aebe92ac71 | |
|
|
08d028eeda | |
|
|
19d4cfff0d | |
|
|
24b56d00c2 | |
|
|
dcd8281ae8 | |
|
|
4683d0f404 | |
|
|
f65f4129ee | |
|
|
eb0044618d | |
|
|
9801e2612f | |
|
|
b44745d484 | |
|
|
e7c4f56968 | |
|
|
1a622c5bbc | |
|
|
bac2113a2d | |
|
|
ed975a94fe | |
|
|
4f80078a15 | |
|
|
afdf24eecf | |
|
|
a11291ff18 | |
|
|
182539abcb | |
|
|
1d634be011 | |
|
|
f6f9f9add9 | |
|
|
86c842556a | |
|
|
c4c8fca9ac | |
|
|
02300099f5 | |
|
|
1210597305 | |
|
|
e8996fb98e | |
|
|
bd2eddb196 | |
|
|
39c05d051d | |
|
|
21dfea692f | |
|
|
2b58f96081 | |
|
|
8d134c96c8 | |
|
|
71705ae9d6 | |
|
|
db2ebdb8da | |
|
|
faf3d09084 | |
|
|
b5f6249f87 | |
|
|
31724b3660 | |
|
|
4444c4cc61 | |
|
|
8ba8e89256 | |
|
|
607f9ee280 | |
|
|
7a52380fa3 | |
|
|
55df50520a | |
|
|
925f372fb4 | |
|
|
e8d1fd1942 | |
|
|
66a6360105 | |
|
|
efb31b2797 | |
|
|
cf575cea8d | |
|
|
947548c160 | |
|
|
2b737aa63e | |
|
|
9f4e408340 | |
|
|
c1a8d50822 | |
|
|
0a7277b673 | |
|
|
421e51a092 | |
|
|
f62a2bf503 | |
|
|
1b9039b630 | |
|
|
59854c52b1 | |
|
|
350765e160 | |
|
|
70b820e011 | |
|
|
545fff234b | |
|
|
24b29207ca | |
|
|
b88035c68c | |
|
|
46d38c0cce | |
|
|
5fc7893764 | |
|
|
0a70373fc1 | |
|
|
6bcec9cf37 | |
|
|
32f0e836d1 | |
|
|
689c3c62f6 | |
|
|
70df115c6e | |
|
|
fc6174f940 | |
|
|
986d2ba157 | |
|
|
f28bbbdb92 | |
|
|
192e020fc0 | |
|
|
f3811cb0f3 | |
|
|
1892272191 | |
|
|
1b7aa7026d | |
|
|
f78d8f6214 | |
|
|
6a36c68e50 | |
|
|
e004cffc05 | |
|
|
e0685c9069 | |
|
|
89e4a0c98a | |
|
|
b04b7bb6fc | |
|
|
ae12fcffd1 | |
|
|
856e51ee65 | |
|
|
3f18ce69ca | |
|
|
9eac191b3a | |
|
|
532b286b8c | |
|
|
75c85b7832 | |
|
|
ce79996249 | |
|
|
9f3768cc07 | |
|
|
d158d6c370 | |
|
|
44854c301d | |
|
|
e53f331381 | |
|
|
6124ab3780 | |
|
|
9468fbd0de | |
|
|
960ec9de66 | |
|
|
0a3f26c7c7 | |
|
|
2770fe5de2 | |
|
|
e2499a9153 | |
|
|
3c366c7c6d | |
|
|
f3f593ee9e | |
|
|
2d15a8baa7 | |
|
|
caa4e16c9c | |
|
|
79304cb18b | |
|
|
408a785844 | |
|
|
b01c12479b | |
|
|
cf035f824e | |
|
|
c45bc8ca29 | |
|
|
9d195a573a | |
|
|
bd63d6ce15 | |
|
|
f2020be44e | |
|
|
831b5e53b2 | |
|
|
cfce41dac3 | |
|
|
91ece063b4 | |
|
|
946988b65c | |
|
|
06b9675a1f | |
|
|
14afb9cdd7 | |
|
|
9d89bdbef0 | |
|
|
d5b48e667b | |
|
|
3ed2b19c78 | |
|
|
d32ec82d70 | |
|
|
83f5d95864 | |
|
|
095ca44038 | |
|
|
58d8dae892 | |
|
|
d1c9f34093 | |
|
|
ad59f37bb3 | |
|
|
d219388aca | |
|
|
ded3518819 | |
|
|
b9ad5d7c10 | |
|
|
41f163edf1 | |
|
|
3500482767 | |
|
|
3905a7fcfc | |
|
|
b55b2ecfa5 | |
|
|
952e184b87 | |
|
|
685be77dbf | |
|
|
a9a1f21e12 | |
|
|
1df633dc64 | |
|
|
120c8fc977 | |
|
|
414fb90ec0 | |
|
|
0eb8f7aefb | |
|
|
dc081084ff | |
|
|
a28ce5a15f | |
|
|
174b8f3438 | |
|
|
ef1b14fe54 | |
|
|
e333b42f4d | |
|
|
4009649e45 | |
|
|
e8a5f6c466 | |
|
|
b5fd4718ae | |
|
|
3aa42e8055 | |
|
|
8e16e3a484 | |
|
|
c428ccf8e2 | |
|
|
99bd9727ca | |
|
|
cc3932a9f5 | |
|
|
cf20f93917 | |
|
|
adda79ad0e | |
|
|
ef21b0fd11 | |
|
|
95c9e48c0f | |
|
|
f759f7b1b4 | |
|
|
629e9bad66 | |
|
|
07d4cb8b34 | |
|
|
64dac39d6b | |
|
|
6beb14b25d | |
|
|
cfe1e6d987 | |
|
|
be69a68a08 | |
|
|
aa9871f1d9 | |
|
|
290f85b4a3 | |
|
|
4c012d62d5 | |
|
|
860f718459 | |
|
|
ecb09c87cb | |
|
|
c30810ae49 | |
|
|
c4d73d4185 | |
|
|
16be2c27eb | |
|
|
f5c980714a | |
|
|
43c7832832 | |
|
|
35d6795c2b | |
|
|
5f3cb2fbea | |
|
|
6d738ce34b | |
|
|
8e0665926a | |
|
|
0cf96d257d | |
|
|
db9b659385 | |
|
|
fc3dbd4ddb | |
|
|
32a840a4a2 | |
|
|
4ae9035673 | |
|
|
996b2491de | |
|
|
31dc8888b0 | |
|
|
35242c3d4c | |
|
|
385427562d | |
|
|
fbdb541b48 | |
|
|
9869a4b89c | |
|
|
46eb687519 | |
|
|
d86266922e | |
|
|
a417999def | |
|
|
a210d9c26b | |
|
|
b83d8aabfc | |
|
|
9929324034 | |
|
|
ff26e62d06 | |
|
|
e0cb232909 | |
|
|
6fcfd1c4b2 | |
|
|
2c1264fe93 | |
|
|
39bc33d453 | |
|
|
4489f28506 | |
|
|
0996412787 | |
|
|
d87063e6e5 | |
|
|
a9b5010045 | |
|
|
3909475219 | |
|
|
c2d3d099c5 | |
|
|
81595a5b18 | |
|
|
1cec3c3fc3 | |
|
|
bff987c68f | |
|
|
c908243e79 | |
|
|
053c2927dd | |
|
|
ff715581ad | |
|
|
bbadce27ea | |
|
|
0d051210b0 | |
|
|
bfb6db0be9 | |
|
|
4db5fe57ec | |
|
|
5b30a4b4ab | |
|
|
63ae7aa74c | |
|
|
080cceba88 | |
|
|
4b8e4f839e | |
|
|
3e2a1e463d | |
|
|
cf847a253f | |
|
|
a64bff4f6f | |
|
|
dfbd3cc04d | |
|
|
52c4222736 | |
|
|
ec6d90439b | |
|
|
bbc6302359 | |
|
|
c67a46362e | |
|
|
57a20d363b | |
|
|
9e408dd017 | |
|
|
a5bab93134 | |
|
|
5d8bd758d5 | |
|
|
6ee3aacc0f | |
|
|
2e577bbd8c | |
|
|
6a5aebce69 | |
|
|
8b072bbb3c | |
|
|
f69f295fd8 | |
|
|
8c80026876 | |
|
|
32af642169 | |
|
|
1c3349eb46 | |
|
|
d2a135f275 | |
|
|
70d01b7fa2 | |
|
|
5ebfc8a447 | |
|
|
c1c9f1ec5b | |
|
|
cff07400da | |
|
|
b05b3b68b2 | |
|
|
6f27f76f80 | |
|
|
76a4713960 | |
|
|
3a3fb4ea08 | |
|
|
c4c6dfcaa9 | |
|
|
898750c916 | |
|
|
fb7378ed52 | |
|
|
ea9924b13f | |
|
|
700b1070a5 | |
|
|
03190064ad | |
|
|
fda45c9c8c | |
|
|
a02e95b2dc | |
|
|
95c7326bbc | |
|
|
ea7fc90c3a | |
|
|
566080cb9f | |
|
|
004cbf3d76 | |
|
|
f06f71033e | |
|
|
c22c66e6d7 | |
|
|
eebaabe7d9 | |
|
|
2842005daa | |
|
|
33887a3cdf | |
|
|
f91310de78 | |
|
|
71395b5e40 | |
|
|
e3335cfb26 | |
|
|
7a56083e3e | |
|
|
97588de88d | |
|
|
ea53ca1810 | |
|
|
b68c1e91c5 | |
|
|
e6143629ff | |
|
|
09f5acef41 | |
|
|
493b7f0f1e | |
|
|
04e8bb594a | |
|
|
c2430e6f0d | |
|
|
1c1dbca6b7 | |
|
|
383c5723fb | |
|
|
0123b004eb | |
|
|
1523b81ea5 | |
|
|
859768f42b | |
|
|
a1ee85ac5c | |
|
|
9701002c05 | |
|
|
81dce619a5 | |
|
|
0f8ae94e22 | |
|
|
6640ec2728 | |
|
|
35e0335c36 | |
|
|
3d06f305db | |
|
|
3f0546a6e2 | |
|
|
339560cf9d | |
|
|
e0e841071b | |
|
|
c4c2f81478 | |
|
|
6cbd4d80de | |
|
|
03e285239c | |
|
|
3b62b00b95 | |
|
|
d92793e24e | |
|
|
34c7a84123 | |
|
|
dae4ed6ce4 | |
|
|
a3b8d1f016 | |
|
|
e086401619 | |
|
|
00ede7adcd | |
|
|
fd3afc5595 | |
|
|
99adfbc56d | |
|
|
25cbf7f8ef | |
|
|
b648967524 | |
|
|
dfc22f4702 | |
|
|
c3ba1cc895 | |
|
|
3421dec217 | |
|
|
6f5244d561 | |
|
|
34e95dd136 | |
|
|
4117d2ad98 | |
|
|
9417f09675 | |
|
|
19c4e9291c | |
|
|
9ce0f333c2 | |
|
|
f64255d4bc | |
|
|
fc40c586ab | |
|
|
b01ae254e2 | |
|
|
ce6a6d31d8 | |
|
|
87157d859f | |
|
|
19a141a9c9 | |
|
|
0a8d86fce8 | |
|
|
5358f7f183 | |
|
|
329bdb0a9c | |
|
|
467699dc15 | |
|
|
9a1ec90338 | |
|
|
59b675203e | |
|
|
b982adf47b | |
|
|
7e9a99c85a | |
|
|
21c2338f2b | |
|
|
31697c0093 | |
|
|
3dd229f919 | |
|
|
d0b2ccfa20 | |
|
|
77057227d3 | |
|
|
90d72f2851 | |
|
|
f66a2eb0d9 | |
|
|
2c9c2fc361 | |
|
|
81da48f7b2 | |
|
|
3c4a2bdeba | |
|
|
4ee7e7f08f | |
|
|
bf6650fdc2 | |
|
|
f88d659198 | |
|
|
f2d6187236 | |
|
|
f75848afcf | |
|
|
6b1663f54b | |
|
|
c661e30eca | |
|
|
dbf3a3ebe6 | |
|
|
02a2db2ff5 | |
|
|
65c9f3d185 | |
|
|
bc3cc334c0 | |
|
|
64422cec3f | |
|
|
f5576daa93 | |
|
|
42ba3a0236 | |
|
|
dd650e4fdc | |
|
|
e397ca7899 | |
|
|
f5a48b3539 | |
|
|
4f264f3205 | |
|
|
26e79c0e92 | |
|
|
33f843cc1f | |
|
|
4135dcb8a8 | |
|
|
fa1b2ba7e1 | |
|
|
2b18477df1 | |
|
|
297eb25225 | |
|
|
160b0bd3fe | |
|
|
fdde2c56d7 | |
|
|
f42b378d78 | |
|
|
4519a93599 | |
|
|
a365fe9a23 | |
|
|
b968596fc5 | |
|
|
da9a007bac | |
|
|
2556a2227f | |
|
|
2e02752652 | |
|
|
a9e68fe8d1 | |
|
|
e85a3f58e3 | |
|
|
b549299d17 | |
|
|
39dd8c9f82 | |
|
|
1bad99dd0e | |
|
|
a29bdd09ae | |
|
|
66dd20ab83 | |
|
|
0fd592760e | |
|
|
4445cd1f65 | |
|
|
c291b65583 | |
|
|
f80fc4d310 | |
|
|
1ee55af5a0 | |
|
|
394a74ee1b | |
|
|
850fe1cec4 | |
|
|
3ecf6c22a8 | |
|
|
3f3e2affa6 | |
|
|
160840a214 | |
|
|
878555c3af | |
|
|
e171233df5 | |
|
|
d32d72ec64 | |
|
|
c731d50d2d | |
|
|
cbc97dfcd6 | |
|
|
18bc9478df | |
|
|
69bfe9468b | |
|
|
21a466666a | |
|
|
fd409dc1c6 | |
|
|
ee7472c10a | |
|
|
ae318f0dd7 | |
|
|
d179130fd4 | |
|
|
b82df7984c | |
|
|
f5efcc1b8d | |
|
|
1822a71840 | |
|
|
057f05281a | |
|
|
7ce3602a71 | |
|
|
0cf02ec117 | |
|
|
2873019c71 | |
|
|
8a3e3fdc6b | |
|
|
69ad73e873 | |
|
|
516e38d49c | |
|
|
1838ffa1b0 | |
|
|
2bf68bd195 | |
|
|
eca27b0966 | |
|
|
524e316d1e | |
|
|
21daa9cd9a | |
|
|
2eaf2f1e69 | |
|
|
b72fe9f31e | |
|
|
30821b5a2c | |
|
|
6bd52e1a8a | |
|
|
5d30cbbad9 | |
|
|
911dbac5ca | |
|
|
6299ca7754 | |
|
|
c80be51a0d | |
|
|
09bded4a32 | |
|
|
3aeacf0bf6 | |
|
|
fdc8053259 | |
|
|
fa48875dde | |
|
|
15f69a283f | |
|
|
3027d85965 | |
|
|
1cdb67f6dc | |
|
|
bce05bc40c | |
|
|
477009c020 | |
|
|
e8d46d7278 | |
|
|
d64b9bad82 | |
|
|
dd82f73dfe | |
|
|
c0603b0bb1 | |
|
|
33a887c5f2 | |
|
|
2d6cc23da8 | |
|
|
a3d2e6f0e6 | |
|
|
74f470d5ef | |
|
|
b168036034 | |
|
|
b055c91c3f | |
|
|
01a032d69e | |
|
|
2f4aed3922 | |
|
|
8ed66a2e58 | |
|
|
9eea717441 | |
|
|
cf4dd8fb81 | |
|
|
28710ed50a | |
|
|
876cb45215 | |
|
|
a6e1218315 | |
|
|
c0c9c7716c | |
|
|
423f8e7ede | |
|
|
34200fe032 | |
|
|
6c8ec6d645 | |
|
|
7c734754b5 | |
|
|
79b44a5bc6 | |
|
|
17e49723d6 | |
|
|
67932745e7 | |
|
|
e522a263fe | |
|
|
9d5dda3522 | |
|
|
bacdd5278c | |
|
|
ed4d678c80 | |
|
|
c3fff65925 | |
|
|
ed40c22072 | |
|
|
f9d86bdaf5 | |
|
|
714f8b5f80 | |
|
|
82a60b71df | |
|
|
dc4a11f43c | |
|
|
86c33778a6 | |
|
|
a67b754b8f | |
|
|
223aeaa46f | |
|
|
e45e72b4a2 | |
|
|
5ccc4f89fe | |
|
|
ec60ccfba6 | |
|
|
c3178517ae | |
|
|
ffd31babcb | |
|
|
fb1a2a16f1 | |
|
|
a5b7cb2bb8 | |
|
|
d234d82792 | |
|
|
4872dc48f9 | |
|
|
d421521dbf | |
|
|
c17dca5450 | |
|
|
44757d45a0 | |
|
|
4681723d80 | |
|
|
5a8baa5b26 | |
|
|
474c0bfdf6 | |
|
|
7c9b2da180 | |
|
|
dea657e341 | |
|
|
6aa4469565 | |
|
|
7498bcdb11 | |
|
|
9146add594 | |
|
|
447eb80968 | |
|
|
797065e505 | |
|
|
7604c0c215 | |
|
|
a54d521ba5 | |
|
|
eb6d07ea0f | |
|
|
464b2e5d77 | |
|
|
336e4ae2d6 | |
|
|
af91641ae4 | |
|
|
fea082bb0b | |
|
|
d098b4cd1b | |
|
|
e4fee9c047 | |
|
|
bb56840db7 | |
|
|
4ad4dc3080 | |
|
|
7510aca48f | |
|
|
dd15a65acd | |
|
|
af1637641b | |
|
|
a7f97e7bd2 | |
|
|
8e06c89c92 | |
|
|
b0b4917b7d | |
|
|
438ddb21ec | |
|
|
1b07e010f8 | |
|
|
b394063f0f | |
|
|
e2cb93b6dc | |
|
|
d3c0b617cb | |
|
|
4d408c2d50 | |
|
|
ca1ab01624 | |
|
|
e8d63718c9 | |
|
|
aa9219a23b | |
|
|
85cbdc7b97 | |
|
|
5aa46f026b | |
|
|
790cff21a4 | |
|
|
67e1098402 | |
|
|
56c5aea7e6 | |
|
|
37ebd4d065 | |
|
|
22b7783312 | |
|
|
bc91c4a323 | |
|
|
71be6d9bfd | |
|
|
2e6dc556b0 | |
|
|
834334efdb | |
|
|
de462ce77f | |
|
|
274918cb8f | |
|
|
42830e4938 | |
|
|
c688f18ac8 | |
|
|
f0cd3e8fd4 | |
|
|
bc3e5a89ed | |
|
|
d6c0377ee5 | |
|
|
fb211a6441 | |
|
|
849e0138d8 |
|
|
@ -0,0 +1,61 @@
|
||||||
|
APP_NAME=BeikeShop
|
||||||
|
APP_ENV=local
|
||||||
|
APP_KEY=base64:3RBtk9D81bfkLAjZ8UK7TSsIsHU+UBukSXx754Rkw1I=
|
||||||
|
APP_DEBUG=true
|
||||||
|
APP_URL=
|
||||||
|
APP_TIMEZONE=PRC
|
||||||
|
APP_FORCE_HTTPS=false
|
||||||
|
ASSET_URL=
|
||||||
|
|
||||||
|
BEIKE_API_URL=https://beikeshop.com
|
||||||
|
|
||||||
|
LOG_CHANNEL=stack
|
||||||
|
LOG_DEPRECATIONS_CHANNEL=null
|
||||||
|
LOG_LEVEL=debug
|
||||||
|
|
||||||
|
DB_CONNECTION=mysql
|
||||||
|
DB_HOST=127.0.0.1
|
||||||
|
DB_PORT=3306
|
||||||
|
DB_DATABASE=beike
|
||||||
|
DB_USERNAME=root
|
||||||
|
DB_PASSWORD=
|
||||||
|
|
||||||
|
BROADCAST_DRIVER=log
|
||||||
|
CACHE_DRIVER=file
|
||||||
|
FILESYSTEM_DRIVER=local
|
||||||
|
QUEUE_CONNECTION=sync
|
||||||
|
SESSION_DRIVER=file
|
||||||
|
SESSION_LIFETIME=120
|
||||||
|
|
||||||
|
MEMCACHED_HOST=127.0.0.1
|
||||||
|
|
||||||
|
REDIS_HOST=127.0.0.1
|
||||||
|
REDIS_PASSWORD=null
|
||||||
|
REDIS_PORT=6379
|
||||||
|
|
||||||
|
MAIL_MAILER=smtp
|
||||||
|
MAIL_HOST=mailhog
|
||||||
|
MAIL_PORT=1025
|
||||||
|
MAIL_USERNAME=null
|
||||||
|
MAIL_PASSWORD=null
|
||||||
|
MAIL_ENCRYPTION=null
|
||||||
|
MAIL_FROM_ADDRESS=null
|
||||||
|
MAIL_FROM_NAME="${APP_NAME}"
|
||||||
|
|
||||||
|
AWS_ACCESS_KEY_ID=
|
||||||
|
AWS_SECRET_ACCESS_KEY=
|
||||||
|
AWS_DEFAULT_REGION=us-east-1
|
||||||
|
AWS_BUCKET=
|
||||||
|
AWS_USE_PATH_STYLE_ENDPOINT=false
|
||||||
|
|
||||||
|
PUSHER_APP_ID=
|
||||||
|
PUSHER_APP_KEY=
|
||||||
|
PUSHER_APP_SECRET=
|
||||||
|
PUSHER_APP_CLUSTER=mt1
|
||||||
|
|
||||||
|
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
|
||||||
|
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
|
||||||
|
|
||||||
|
# Dusk Browser Test
|
||||||
|
DUSK_START_MAXIMIZED=true
|
||||||
|
DUSK_HEADLESS_DISABLED=false
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
* text=auto
|
||||||
|
*.css linguist-vendored
|
||||||
|
*.scss linguist-vendored
|
||||||
|
*.js linguist-vendored
|
||||||
|
CHANGELOG.md export-ignore
|
||||||
|
|
@ -1,6 +1,26 @@
|
||||||
/node_modules/
|
/node_modules
|
||||||
/vendor/
|
/public/.htaccess
|
||||||
.idea
|
/public/cache
|
||||||
|
/public/hot
|
||||||
|
/public/storage
|
||||||
|
/public/upload/avatar
|
||||||
/public/build/beike/*
|
/public/build/beike/*
|
||||||
/public/install/css/*
|
/public/install/css/*
|
||||||
|
/public/sitemap.xml
|
||||||
|
/storage/*.key
|
||||||
|
/storage/installed
|
||||||
|
/vendor
|
||||||
|
Envoy.blade.php
|
||||||
|
.env
|
||||||
|
.env.backup
|
||||||
|
.phpunit.result.cache
|
||||||
|
docker-compose.override.yml
|
||||||
|
Homestead.json
|
||||||
|
Homestead.yaml
|
||||||
|
npm-debug.log
|
||||||
|
yarn-error.log
|
||||||
|
/.idea
|
||||||
|
/.vscode
|
||||||
mix-manifest.json
|
mix-manifest.json
|
||||||
|
package-lock.json
|
||||||
|
dist
|
||||||
|
|
|
||||||
47
README.md
47
README.md
|
|
@ -5,8 +5,8 @@
|
||||||
|
|
||||||
|
|
||||||
## BeikeShop介绍
|
## BeikeShop介绍
|
||||||
BeikeShop 是基于 Laravel 开发的一款开源商城系统,主要面向外贸,跨境行业提供的商品管理、订单管理、会员管理、支付、物流、系统管理等功能。
|
BeikeShop 是基于 Laravel 开发的一款开源商城系统
|
||||||
<br>
|
主要面向外贸,跨境行业提供的商品管理、订单管理、会员管理、支付、物流、系统管理等功能
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -14,17 +14,22 @@ BeikeShop 是基于 Laravel 开发的一款开源商城系统,主要面向外
|
||||||
<img src="https://beikeshop.com/readme/README-1.png">
|
<img src="https://beikeshop.com/readme/README-1.png">
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
请保留我公司版权信息,如要移除,需要我公司授权。
|
注意:请保留我公司版权信息,如要移除,需要我公司授权!
|
||||||
|
|
||||||
|
|
||||||
## BeikeShop系统亮点
|
## BeikeShop系统亮点
|
||||||
- **全新!支持ChatGPT:BeikeShop1.3.2 集成ChatGPT,打造高效智能化跨境电商系统**
|
- 0元起步:BeikeShop 是真正的独立站,代码100%开源,数据信息100%自主可控
|
||||||
- 开源免费:BeikeShop以开源方式发布,OSL-3.0协议允许用户自由使用、修改。
|
- 基于 Laravel 9 框架:BeikeShop 使用 Laravel 9 框架进行开发,拥有成熟的框架支持
|
||||||
- 轻量级框架:BeikeShop基于Laravel框架开发,具有高效、灵活、易用等特点。
|
- 无佣金和手续费:BeikeShop 没有佣金、年费或手续费,降低了建站成本
|
||||||
- 灵活的插件机制:BeikeShop提供灵活的Hook插件机制,可以方便地扩展和定制系统功能。
|
- 微内核和插件化:采用微内核架构和插件化设计,使系统易维护 & 扩展
|
||||||
- 多语言多货币支持:支持多种语言/货币切换,可灵活扩展其他语言/货币。
|
- 清晰的代码分层和格式规范:系统代码采用分层清晰、格式规范的结构,提高代码的可读性和可维护性
|
||||||
- 多种支付方式:支持 PayPal、Stripe、Alipay、WeChat Pay 等多种支付方式,覆盖全球主要外贸国家
|
- Event 机制实现 Hook 功能:通过 Event 机制实现了灵活的 Hook 功能,方便扩展和定制化开发
|
||||||
- 快速搭建:向VIP提供一键安装脚本,帮助用户快速搭建起一个稳定、高效、易用的跨境电商独立站。
|
- 丰富的插件市场:官方提供了丰富的插件市场,可以方便地购买需要的功能
|
||||||
|
- 多语言和多货币支持:系统支持多语言和多货币,方便面向不同地区和国家的用户
|
||||||
|
- 界面美观和可视化装修:系统界面设计美观,支持可视化装修,提供良好的用户体验
|
||||||
|
- 严格遵循 MVC 架构:系统严格遵循 MVC 架构,提高了代码的可维护性和可扩展性
|
||||||
|
- 操作简单易上手:BeikeShop 操作简单,易于上手,可以快速上线使用
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
@ -38,27 +43,32 @@ BeikeShop 是基于 Laravel 开发的一款开源商城系统,主要面向外
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a href="https://demo.beikeshop.com/" target="_blank">点击立刻体验:BeikeShop演示站</a>
|
<a href="https://demo.beikeshop.com/" target="_blank">点击立刻体验:BeikeShop演示站</a>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
## 页面展示
|
## 页面展示
|
||||||
|
|
||||||

|

|
||||||

|

|
||||||

|

|
||||||

|

|
||||||
|

|
||||||
|
|
||||||
|
## 技术服务展示
|
||||||
|

|
||||||
|
|
||||||
## 软件架构
|
## 软件架构
|
||||||
PHP语言开发,基于 Laravel 框架,前端 Blade 模板 + Vue
|
使用语言 PHP 8.0
|
||||||
|
基于 Laravel 9 框架
|
||||||
|
前端 Blade 模板 + Vue
|
||||||
|
|
||||||
## 环境要求
|
## 环境要求
|
||||||
|
- 独立服务器(不能使用虚拟空间)
|
||||||
|
- CentOS 7.0+ 或 Ubuntu 20.04+
|
||||||
- PHP 8.0.2+
|
- PHP 8.0.2+
|
||||||
- MySQL 5.7+
|
- MySQL 5.7+
|
||||||
- Apache httpd 2.4+ 或者 Nginx 1.10+
|
- Apache httpd 2.4+ 或者 Nginx 1.10+
|
||||||
|
|
@ -89,13 +99,13 @@ PHP语言开发,基于 Laravel 框架,前端 Blade 模板 + Vue
|
||||||
1. 将解压文件夹下的 public 设置为网站根目录
|
1. 将解压文件夹下的 public 设置为网站根目录
|
||||||
1. 通过浏览器访问网站根据提示完成安装
|
1. 通过浏览器访问网站根据提示完成安装
|
||||||
1. <a href="https://docs.beikeshop.com/install/bt.html" target="_blank">BeikeShop详细安装指引</a>
|
1. <a href="https://docs.beikeshop.com/install/bt.html" target="_blank">BeikeShop详细安装指引</a>
|
||||||
1. 如需升级请下载最新版覆盖到服务器后网站根目录运行`composer install && php artisan migrate`
|
1. 如需升级, 请下载最新版覆盖到服务器(必须保留原有.env文件), 然后在网站根目录运行`php artisan migrate`
|
||||||
|
|
||||||
## 安装教程(面向开发者)
|
## 安装教程(面向开发者)
|
||||||
1. 打开命令行克隆代码 `git clone https://gitee.com/beikeshop/beikeshop.git`
|
1. 打开命令行克隆代码 `git clone https://gitee.com/beikeshop/beikeshop.git`
|
||||||
1. 命令行进入 `beikeshop` 目录, 执行 `composer install` 安装第三方包
|
1. 命令行进入 `beikeshop` 目录, 执行 `composer install` 安装第三方包
|
||||||
1. 接着执行 `cp .env.example .env` 创建配置文件
|
1. 接着执行 `cp .env.example .env` 创建配置文件
|
||||||
1. 接着执行 `npm install`(node 版本需16+) 以及 `npm run dev` 编译前端 js 和 css 文件
|
1. 接着执行 `npm install`(node 版本需16+) 以及 `npm run prod` 编译前端 js 和 css 文件
|
||||||
1. 将项目文件夹下的 `public` 设置为网站根目录
|
1. 将项目文件夹下的 `public` 设置为网站根目录
|
||||||
1. 通过浏览器访问网站, 根据提示完成安装
|
1. 通过浏览器访问网站, 根据提示完成安装
|
||||||
1. 如需升级请在服务器端网站根目录运行`git pull && composer install && php artisan migrate`
|
1. 如需升级请在服务器端网站根目录运行`git pull && composer install && php artisan migrate`
|
||||||
|
|
@ -106,5 +116,10 @@ PHP语言开发,基于 Laravel 框架,前端 Blade 模板 + Vue
|
||||||
1. 提交代码
|
1. 提交代码
|
||||||
1. 新建 Merge Request
|
1. 新建 Merge Request
|
||||||
|
|
||||||
|
## 特别鸣谢
|
||||||
|
插件开发者:撸串青年、Aegis
|
||||||
|
PR贡献者:nilsir、what_村长、tanxiaoyong、Lucky、So、licy、老北、Teemo
|
||||||
|
感谢你们参与到BeikeShop的开发中,共同为BeikeShop添砖加瓦!
|
||||||
|
|
||||||
## QQ交流群:
|
## QQ交流群:
|
||||||
群1: 639108380
|
群1: 639108380
|
||||||
|
|
|
||||||
|
|
@ -64,11 +64,18 @@ class Kernel extends HttpKernel
|
||||||
\App\Http\Middleware\VerifyCsrfToken::class,
|
\App\Http\Middleware\VerifyCsrfToken::class,
|
||||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||||
],
|
],
|
||||||
|
|
||||||
'api' => [
|
'api' => [
|
||||||
// \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
|
// \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
|
||||||
'throttle:api',
|
'throttle:api',
|
||||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||||
],
|
],
|
||||||
|
|
||||||
|
'admin_api' => [
|
||||||
|
\App\Http\Middleware\AdminApiAuthenticate::class,
|
||||||
|
'throttle:api',
|
||||||
|
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||||
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,99 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* AdminAuthenticate.php
|
||||||
|
*
|
||||||
|
* @copyright 2023 beikeshop.com - All Rights Reserved
|
||||||
|
* @link https://beikeshop.com
|
||||||
|
* @author Edward Yang <yangjin@guangda.work>
|
||||||
|
* @created 2023-04-20 14:44:54
|
||||||
|
* @modified 2023-04-20 14:44:54
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Http\Middleware;
|
||||||
|
|
||||||
|
use Beike\Repositories\AdminUserTokenRepo;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Route;
|
||||||
|
use Illuminate\Validation\UnauthorizedException;
|
||||||
|
|
||||||
|
class AdminApiAuthenticate
|
||||||
|
{
|
||||||
|
public const ADMIN_API_PREFIX = 'admin_api.';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle an incoming request.
|
||||||
|
*
|
||||||
|
* @param Request $request
|
||||||
|
* @param \Closure $next
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function handle(Request $request, \Closure $next)
|
||||||
|
{
|
||||||
|
$token = $request->header('token');
|
||||||
|
if (empty($token)) {
|
||||||
|
$token = $request->get('token');
|
||||||
|
}
|
||||||
|
|
||||||
|
$token = AdminUserTokenRepo::getAdminUserTokenByToken($token);
|
||||||
|
if (empty($token)) {
|
||||||
|
throw new UnauthorizedException(trans('customer.unauthorized_without_token'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$adminUser = $token->adminUser;
|
||||||
|
if (! $this->hasPermission($adminUser)) {
|
||||||
|
throw new UnauthorizedException(trans('customer.unauthorized_without_permission'));
|
||||||
|
}
|
||||||
|
|
||||||
|
register('admin_user', $adminUser);
|
||||||
|
|
||||||
|
return $next($request);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function hasPermission($adminUser)
|
||||||
|
{
|
||||||
|
// $routeUri = Route::current()->uri();
|
||||||
|
$routeName = Route::currentRouteName();
|
||||||
|
|
||||||
|
$routePath = str_replace(self::ADMIN_API_PREFIX, '', $routeName);
|
||||||
|
if ($routePath == 'me') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$permissionName = $this->mapPermissionByRoute($routePath);
|
||||||
|
if (empty($permissionName)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $adminUser->can($permissionName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function mapPermissionByRoute($routePath)
|
||||||
|
{
|
||||||
|
$maps = [
|
||||||
|
'categories.index' => 'categories_index',
|
||||||
|
'categories.show' => 'categories_show',
|
||||||
|
'categories.create' => 'categories_create',
|
||||||
|
'categories.update' => 'categories_update',
|
||||||
|
'categories.delete' => 'categories_delete',
|
||||||
|
|
||||||
|
'brands.index' => 'brands_index',
|
||||||
|
'brands.show' => 'brands_show',
|
||||||
|
'brands.create' => 'brands_create',
|
||||||
|
'brands.update' => 'brands_update',
|
||||||
|
'brands.delete' => 'brands_delete',
|
||||||
|
|
||||||
|
'orders.index' => 'orders_index',
|
||||||
|
'orders.show' => 'orders_show',
|
||||||
|
'orders.update_status' => 'orders_update_status',
|
||||||
|
'orders.update_shipment' => 'orders_update_status',
|
||||||
|
|
||||||
|
'products.index' => 'products_index',
|
||||||
|
'products.show' => 'products_show',
|
||||||
|
'products.create' => 'products_create',
|
||||||
|
'products.update' => 'products_update',
|
||||||
|
'products.delete' => 'products_delete',
|
||||||
|
];
|
||||||
|
|
||||||
|
return $maps[$routePath] ?? '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -13,5 +13,6 @@ class VerifyCsrfToken extends Middleware
|
||||||
*/
|
*/
|
||||||
protected $except = [
|
protected $except = [
|
||||||
'callback/*',
|
'callback/*',
|
||||||
|
'api/*',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"php_ext":"opcache,ioncube",
|
||||||
|
"chmod":[
|
||||||
|
{"mode":755,"path":"/storage"},
|
||||||
|
{"mode":755,"path":"/bootstrap/cache"},
|
||||||
|
{"mode":755,"path":"/public/cache"}
|
||||||
|
],
|
||||||
|
"success_url":"/index.php",
|
||||||
|
"php_versions":"80,81,82",
|
||||||
|
"db_config":"",
|
||||||
|
"admin_username":"",
|
||||||
|
"admin_password":"",
|
||||||
|
"run_path":"/public",
|
||||||
|
"remove_file":["/.user.ini"],
|
||||||
|
"enable_functions":["putenv"]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,100 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* BrandController.php
|
||||||
|
*
|
||||||
|
* @copyright 2023 beikeshop.com - All Rights Reserved
|
||||||
|
* @link https://beikeshop.com
|
||||||
|
* @author Edward Yang <yangjin@guangda.work>
|
||||||
|
* @created 2023-04-20 17:19:51
|
||||||
|
* @modified 2023-04-20 17:19:51
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Beike\API\Controllers\Admin;
|
||||||
|
|
||||||
|
use Beike\Models\Brand;
|
||||||
|
use Beike\Repositories\BrandRepo;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class BrandController
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 显示品牌列表
|
||||||
|
* @param Request $request
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function index(Request $request)
|
||||||
|
{
|
||||||
|
$brands = BrandRepo::list($request->only('name', 'first', 'status'));
|
||||||
|
$data = [
|
||||||
|
'brands' => $brands,
|
||||||
|
];
|
||||||
|
|
||||||
|
return hook_filter('admin_api.brand.index.data', $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建品牌
|
||||||
|
*
|
||||||
|
* @param Request $request
|
||||||
|
* @param Brand $brand
|
||||||
|
* @return Brand
|
||||||
|
*/
|
||||||
|
public function show(Request $request, Brand $brand): Brand
|
||||||
|
{
|
||||||
|
return hook_filter('admin_api.brand.show.data', $brand);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建品牌
|
||||||
|
*
|
||||||
|
* @param Request $request
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function store(Request $request): array
|
||||||
|
{
|
||||||
|
$requestData = $request->all();
|
||||||
|
$data = [
|
||||||
|
'request_data' => $requestData,
|
||||||
|
];
|
||||||
|
|
||||||
|
hook_action('admin_api.brand.store.before', $data);
|
||||||
|
$brand = BrandRepo::create($requestData);
|
||||||
|
hook_action('admin_api.brand.store.after', ['brand' => $brand, 'request_data' => $requestData]);
|
||||||
|
|
||||||
|
return json_success(trans('common.created_success'), $brand);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Request $request
|
||||||
|
* @param Brand $brand
|
||||||
|
* @return array
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public function update(Request $request, Brand $brand): array
|
||||||
|
{
|
||||||
|
$requestData = $request->all();
|
||||||
|
$data = [
|
||||||
|
'brand_id' => $brand,
|
||||||
|
'request_data' => $requestData,
|
||||||
|
];
|
||||||
|
hook_action('admin_api.brand.update.before', $data);
|
||||||
|
$brand = BrandRepo::update($brand, $requestData);
|
||||||
|
hook_action('admin_api.brand.update.after', $data);
|
||||||
|
|
||||||
|
return json_success(trans('common.updated_success'), $brand);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Request $request
|
||||||
|
* @param Brand $brand
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function destroy(Request $request, Brand $brand): array
|
||||||
|
{
|
||||||
|
hook_action('admin_api.brand.destroy.before', $brand);
|
||||||
|
BrandRepo::delete($brand);
|
||||||
|
hook_action('admin_api.brand.destroy.after', $brand);
|
||||||
|
|
||||||
|
return json_success(trans('common.deleted_success'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,112 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* CategoryController.php
|
||||||
|
*
|
||||||
|
* @copyright 2023 beikeshop.com - All Rights Reserved
|
||||||
|
* @link https://beikeshop.com
|
||||||
|
* @author Edward Yang <yangjin@guangda.work>
|
||||||
|
* @created 2023-04-20 17:00:40
|
||||||
|
* @modified 2023-04-20 17:00:40
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Beike\API\Controllers\Admin;
|
||||||
|
|
||||||
|
use Beike\Admin\Http\Requests\CategoryRequest;
|
||||||
|
use Beike\Admin\Http\Resources\CategoryResource;
|
||||||
|
use Beike\Admin\Services\CategoryService;
|
||||||
|
use Beike\Models\Category;
|
||||||
|
use Beike\Repositories\CategoryRepo;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class CategoryController
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 商品分类列表
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$categories = CategoryRepo::getAdminList();
|
||||||
|
$data = [
|
||||||
|
'categories' => CategoryResource::collection($categories),
|
||||||
|
];
|
||||||
|
|
||||||
|
return hook_filter('admin_api.category.index.data', $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单个商品分类
|
||||||
|
*
|
||||||
|
* @param Request $request
|
||||||
|
* @param Category $category
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function show(Request $request, Category $category)
|
||||||
|
{
|
||||||
|
if (! $category->active) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
$category->load('description');
|
||||||
|
|
||||||
|
return hook_filter('admin_api.category.show.data', $category);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存商品分类
|
||||||
|
*
|
||||||
|
* @param CategoryRequest $request
|
||||||
|
* @return array
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public function store(CategoryRequest $request)
|
||||||
|
{
|
||||||
|
$requestData = $request->all();
|
||||||
|
$category = (new CategoryService())->createOrUpdate($requestData, null);
|
||||||
|
$data = [
|
||||||
|
'category' => $category,
|
||||||
|
'request_data' => $requestData,
|
||||||
|
];
|
||||||
|
|
||||||
|
hook_action('admin_api.category.save.after', $data);
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新产品分类
|
||||||
|
*
|
||||||
|
* @param CategoryRequest $request
|
||||||
|
* @param Category $category
|
||||||
|
* @return array
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public function update(CategoryRequest $request, Category $category)
|
||||||
|
{
|
||||||
|
$requestData = $request->all();
|
||||||
|
$category = (new CategoryService())->createOrUpdate($requestData, $category);
|
||||||
|
$data = [
|
||||||
|
'category' => $category,
|
||||||
|
'request_data' => $requestData,
|
||||||
|
];
|
||||||
|
|
||||||
|
hook_action('admin_api.category.save.after', $data);
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除分类
|
||||||
|
* @param Request $request
|
||||||
|
* @param Category $category
|
||||||
|
* @return array
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public function destroy(Request $request, Category $category): array
|
||||||
|
{
|
||||||
|
CategoryRepo::delete($category);
|
||||||
|
hook_action('admin.category.destroy.after', $category);
|
||||||
|
|
||||||
|
return json_success(trans('common.deleted_success'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,95 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* OrderController.php
|
||||||
|
*
|
||||||
|
* @copyright 2023 beikeshop.com - All Rights Reserved
|
||||||
|
* @link https://beikeshop.com
|
||||||
|
* @author Edward Yang <yangjin@guangda.work>
|
||||||
|
* @created 2023-04-20 16:40:35
|
||||||
|
* @modified 2023-04-20 16:40:35
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Beike\API\Controllers\Admin;
|
||||||
|
|
||||||
|
use Beike\Models\Order;
|
||||||
|
use Beike\Models\OrderShipment;
|
||||||
|
use Beike\Repositories\OrderRepo;
|
||||||
|
use Beike\Services\ShipmentService;
|
||||||
|
use Beike\Services\StateMachineService;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class OrderController
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 获取订单列表
|
||||||
|
*
|
||||||
|
* @param Request $request
|
||||||
|
* @return mixed
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public function index(Request $request)
|
||||||
|
{
|
||||||
|
$orders = OrderRepo::filterOrders($request->all());
|
||||||
|
|
||||||
|
return hook_filter('admin_api.order.index.data', $orders);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查看单个订单
|
||||||
|
*
|
||||||
|
* @param Request $request
|
||||||
|
* @param Order $order
|
||||||
|
* @return mixed
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public function show(Request $request, Order $order)
|
||||||
|
{
|
||||||
|
$order->load(['orderTotals', 'orderHistories', 'orderShipments']);
|
||||||
|
$data = hook_filter('admin.order.show.data', ['order' => $order, 'html_items' => []]);
|
||||||
|
$data['statuses'] = StateMachineService::getInstance($order)->nextBackendStatuses();
|
||||||
|
|
||||||
|
return hook_filter('admin_api.order.show.data', $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新订单状态,添加订单更新日志
|
||||||
|
*
|
||||||
|
* @param Request $request
|
||||||
|
* @param Order $order
|
||||||
|
* @return array
|
||||||
|
* @throws \Throwable
|
||||||
|
*/
|
||||||
|
public function updateStatus(Request $request, Order $order)
|
||||||
|
{
|
||||||
|
$status = $request->get('status');
|
||||||
|
$comment = $request->get('comment');
|
||||||
|
$notify = $request->get('notify');
|
||||||
|
|
||||||
|
$shipment = ShipmentService::handleShipment(\request('express_code'), \request('express_number'));
|
||||||
|
|
||||||
|
$stateMachine = new StateMachineService($order);
|
||||||
|
$stateMachine->setShipment($shipment)->changeStatus($status, $comment, $notify);
|
||||||
|
|
||||||
|
$orderStatusData = $request->all();
|
||||||
|
|
||||||
|
hook_action('admin.order.update_status.after', $orderStatusData);
|
||||||
|
|
||||||
|
return json_success(trans('common.updated_success'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新发货信息
|
||||||
|
*/
|
||||||
|
public function updateShipment(Request $request, Order $order, int $orderShipmentId): array
|
||||||
|
{
|
||||||
|
$data = $request->all();
|
||||||
|
$orderShipment = OrderShipment::query()->where('order_id', $order->id)->findOrFail($orderShipmentId);
|
||||||
|
ShipmentService::updateShipment($orderShipment, $data);
|
||||||
|
hook_action('admin.order.update_shipment.after', [
|
||||||
|
'request_data' => $data,
|
||||||
|
'shipment' => $orderShipment,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return json_success(trans('common.updated_success'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,125 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* ProductController.php
|
||||||
|
*
|
||||||
|
* @copyright 2023 beikeshop.com - All Rights Reserved
|
||||||
|
* @link https://beikeshop.com
|
||||||
|
* @author Edward Yang <yangjin@guangda.work>
|
||||||
|
* @created 2023-04-20 16:48:47
|
||||||
|
* @modified 2023-04-20 16:48:47
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Beike\API\Controllers\Admin;
|
||||||
|
|
||||||
|
use Beike\Admin\Http\Requests\ProductRequest;
|
||||||
|
use Beike\Admin\Http\Resources\ProductResource;
|
||||||
|
use Beike\Admin\Services\ProductService;
|
||||||
|
use Beike\Models\Product;
|
||||||
|
use Beike\Repositories\ProductRepo;
|
||||||
|
use Beike\Shop\Http\Resources\ProductDetail;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class ProductController
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 产品列表
|
||||||
|
*
|
||||||
|
* @param Request $request
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function index(Request $request)
|
||||||
|
{
|
||||||
|
$requestData = $request->all();
|
||||||
|
if (! isset($requestData['sort'])) {
|
||||||
|
$requestData['sort'] = 'products.updated_at';
|
||||||
|
}
|
||||||
|
$productList = ProductRepo::list($requestData);
|
||||||
|
$products = ProductResource::collection($productList);
|
||||||
|
|
||||||
|
return hook_filter('admin_api.product.index.data', $products);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 产品列表
|
||||||
|
*
|
||||||
|
* @param Request $request
|
||||||
|
* @param Product $product
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function show(Request $request, Product $product)
|
||||||
|
{
|
||||||
|
$relationIds = $product->relations->pluck('id')->toArray();
|
||||||
|
$product = ProductRepo::getProductDetail($product);
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'product' => (new ProductDetail($product))->jsonSerialize(),
|
||||||
|
'relations' => ProductRepo::getProductsByIds($relationIds)->jsonSerialize(),
|
||||||
|
];
|
||||||
|
|
||||||
|
return hook_filter('admin_api.product.show.data', $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建商品
|
||||||
|
*
|
||||||
|
* @param ProductRequest $request
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function store(ProductRequest $request)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$requestData = $request->all();
|
||||||
|
$product = (new ProductService)->create($requestData);
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'request_data' => $requestData,
|
||||||
|
'product' => $product,
|
||||||
|
];
|
||||||
|
hook_action('admin_api.product.store.after', $data);
|
||||||
|
|
||||||
|
return json_success(trans('common.created_success'));
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return json_fail($e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑商品
|
||||||
|
*
|
||||||
|
* @param ProductRequest $request
|
||||||
|
* @param Product $product
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function update(ProductRequest $request, Product $product)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$requestData = $request->all();
|
||||||
|
$product = (new ProductService)->update($product, $requestData);
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'request_data' => $requestData,
|
||||||
|
'product' => $product,
|
||||||
|
];
|
||||||
|
hook_action('admin_api.product.update.after', $data);
|
||||||
|
|
||||||
|
return json_success(trans('common.updated_success'));
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return json_fail($e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除商品
|
||||||
|
*
|
||||||
|
* @param Request $request
|
||||||
|
* @param Product $product
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function destroy(Request $request, Product $product)
|
||||||
|
{
|
||||||
|
$product->delete();
|
||||||
|
hook_action('admin_api.product.destroy.after', $product);
|
||||||
|
|
||||||
|
return json_success(trans('common.deleted_success'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* UserController.php
|
||||||
|
*
|
||||||
|
* @copyright 2023 beikeshop.com - All Rights Reserved
|
||||||
|
* @link https://beikeshop.com
|
||||||
|
* @author Edward Yang <yangjin@guangda.work>
|
||||||
|
* @created 2023-04-20 14:51:26
|
||||||
|
* @modified 2023-04-20 14:51:26
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Beike\API\Controllers\Admin;
|
||||||
|
|
||||||
|
class UserController
|
||||||
|
{
|
||||||
|
public function me()
|
||||||
|
{
|
||||||
|
return registry('admin_user');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,94 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* AuthController.php
|
||||||
|
*
|
||||||
|
* @copyright 2023 beikeshop.com - All Rights Reserved
|
||||||
|
* @link https://beikeshop.com
|
||||||
|
* @author Edward Yang <yangjin@guangda.work>
|
||||||
|
* @created 2023-04-11 17:44:26
|
||||||
|
* @modified 2023-04-11 17:44:26
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Beike\API\Controllers;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use Beike\Shop\Http\Resources\CustomerResource;
|
||||||
|
|
||||||
|
class AuthController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Create a new AuthController instance.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
// $this->middleware('auth:api', ['except' => ['login']]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a JWT via given credentials.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Http\JsonResponse
|
||||||
|
*/
|
||||||
|
public function login()
|
||||||
|
{
|
||||||
|
$credentials = request(['email', 'password']);
|
||||||
|
|
||||||
|
if (! $token = auth('api_customer')->attempt($credentials)) {
|
||||||
|
return response()->json(['error' => 'Unauthorized'], 401);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->respondWithToken($token);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the authenticated User.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Http\JsonResponse
|
||||||
|
*/
|
||||||
|
public function me()
|
||||||
|
{
|
||||||
|
$customer = auth('api_customer')->user();
|
||||||
|
|
||||||
|
return response()->json(new CustomerResource($customer));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log the user out (Invalidate the token).
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Http\JsonResponse
|
||||||
|
*/
|
||||||
|
public function logout()
|
||||||
|
{
|
||||||
|
auth('api_customer')->logout();
|
||||||
|
|
||||||
|
return response()->json(['message' => 'Successfully logged out']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refresh a token.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Http\JsonResponse
|
||||||
|
*/
|
||||||
|
public function refresh()
|
||||||
|
{
|
||||||
|
return $this->respondWithToken(auth('api_customer')->refresh());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the token array structure.
|
||||||
|
*
|
||||||
|
* @param string $token
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Http\JsonResponse
|
||||||
|
*/
|
||||||
|
protected function respondWithToken($token)
|
||||||
|
{
|
||||||
|
return response()->json([
|
||||||
|
'access_token' => $token,
|
||||||
|
'token_type' => 'bearer',
|
||||||
|
'expires_in' => auth('api_customer')->factory()->getTTL() * 60,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* APIServiceProvider.php
|
||||||
|
*
|
||||||
|
* @copyright 2023 beikeshop.com - All Rights Reserved
|
||||||
|
* @link https://beikeshop.com
|
||||||
|
* @author Edward Yang <yangjin@guangda.work>
|
||||||
|
* @created 2023-04-11 16:08:04
|
||||||
|
* @modified 2023-04-11 16:08:04
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Beike\API\Providers;
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Config;
|
||||||
|
use Illuminate\Support\ServiceProvider;
|
||||||
|
|
||||||
|
class APIServiceProvider extends ServiceProvider
|
||||||
|
{
|
||||||
|
public function boot()
|
||||||
|
{
|
||||||
|
if (is_installer()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$this->loadRoutesFrom(__DIR__ . '/../Routes/api.php');
|
||||||
|
$this->registerGuard();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注册后台用户 guard
|
||||||
|
*/
|
||||||
|
protected function registerGuard()
|
||||||
|
{
|
||||||
|
Config::set('auth.guards.api_customer', [
|
||||||
|
'driver' => 'jwt',
|
||||||
|
'provider' => 'shop_customer',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* api.php
|
||||||
|
*
|
||||||
|
* @copyright 2023 beikeshop.com - All Rights Reserved
|
||||||
|
* @link https://beikeshop.com
|
||||||
|
* @author Edward Yang <yangjin@guangda.work>
|
||||||
|
* @created 2023-04-11 17:36:05
|
||||||
|
* @modified 2023-04-11 17:36:05
|
||||||
|
*/
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Route;
|
||||||
|
|
||||||
|
Route::prefix('api')
|
||||||
|
->middleware(['api'])
|
||||||
|
->name('api.')
|
||||||
|
->group(function () {
|
||||||
|
Route::post('login', [\Beike\API\Controllers\AuthController::class, 'login']);
|
||||||
|
Route::post('logout', [\Beike\API\Controllers\AuthController::class, 'logout']);
|
||||||
|
Route::post('refresh', [\Beike\API\Controllers\AuthController::class, 'refresh']);
|
||||||
|
Route::get('me', [\Beike\API\Controllers\AuthController::class, 'me']);
|
||||||
|
});
|
||||||
|
|
||||||
|
Route::prefix('admin_api')
|
||||||
|
->middleware(['admin_api'])
|
||||||
|
->name('admin_api.')
|
||||||
|
->group(function () {
|
||||||
|
Route::get('brands', [\Beike\API\Controllers\Admin\BrandController::class, 'index'])->name('brands.index');
|
||||||
|
Route::get('brands/{brand}', [\Beike\API\Controllers\Admin\BrandController::class, 'show'])->name('brands.show');
|
||||||
|
Route::post('brands', [\Beike\API\Controllers\Admin\BrandController::class, 'store'])->name('brands.create');
|
||||||
|
Route::put('brands/{brand}', [\Beike\API\Controllers\Admin\BrandController::class, 'update'])->name('brands.update');
|
||||||
|
Route::delete('brands/{brand}', [\Beike\API\Controllers\Admin\BrandController::class, 'destroy'])->name('brands.delete');
|
||||||
|
|
||||||
|
Route::get('categories', [\Beike\API\Controllers\Admin\CategoryController::class, 'index'])->name('categories.index');
|
||||||
|
Route::get('categories/{category}', [\Beike\API\Controllers\Admin\CategoryController::class, 'show'])->name('categories.show');
|
||||||
|
Route::post('categories', [\Beike\API\Controllers\Admin\CategoryController::class, 'store'])->name('categories.create');
|
||||||
|
Route::put('categories/{category}', [\Beike\API\Controllers\Admin\CategoryController::class, 'update'])->name('categories.update');
|
||||||
|
Route::delete('categories/{category}', [\Beike\API\Controllers\Admin\CategoryController::class, 'destroy'])->name('categories.delete');
|
||||||
|
|
||||||
|
Route::get('me', [\Beike\API\Controllers\Admin\UserController::class, 'me'])->name('me');
|
||||||
|
|
||||||
|
Route::get('orders', [\Beike\API\Controllers\Admin\OrderController::class, 'index'])->name('orders.index');
|
||||||
|
Route::get('orders/{order}', [\Beike\API\Controllers\Admin\OrderController::class, 'show'])->name('orders.show');
|
||||||
|
Route::put('orders/{order}/status', [\Beike\API\Controllers\Admin\OrderController::class, 'updateStatus'])->name('orders.update_status');
|
||||||
|
Route::put('orders/{order}/shipments/{shipment}', [\Beike\API\Controllers\Admin\OrderController::class, 'updateShipment'])->name('orders.update_shipment');
|
||||||
|
|
||||||
|
Route::get('products', [\Beike\API\Controllers\Admin\ProductController::class, 'index'])->name('products.index');
|
||||||
|
Route::get('products/{product}', [\Beike\API\Controllers\Admin\ProductController::class, 'show'])->name('products.show');
|
||||||
|
Route::post('products', [\Beike\API\Controllers\Admin\ProductController::class, 'store'])->name('products.create');
|
||||||
|
Route::put('products/{product}', [\Beike\API\Controllers\Admin\ProductController::class, 'update'])->name('products.update');
|
||||||
|
Route::delete('products/{product}', [\Beike\API\Controllers\Admin\ProductController::class, 'destroy'])->name('products.delete');
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* BrandController.php
|
||||||
|
*
|
||||||
|
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||||
|
* @link https://beikeshop.com
|
||||||
|
* @author TL <mengwb@guangda.work>
|
||||||
|
* @created 2022-07-27 21:17:04
|
||||||
|
* @modified 2022-07-27 21:17:04
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Beike\Admin\Http\Controllers;
|
||||||
|
|
||||||
|
use Beike\Admin\Repositories\AdminUserRepo;
|
||||||
|
use Beike\Repositories\AdminUserTokenRepo;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class AccountController extends Controller
|
||||||
|
{
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$user = current_user();
|
||||||
|
$data = [
|
||||||
|
'current_user' => $user,
|
||||||
|
'tokens' => AdminUserTokenRepo::getTokenByAdminUser($user)->pluck('token')->toArray(),
|
||||||
|
];
|
||||||
|
|
||||||
|
return view('admin::pages.account.index', $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function update(Request $request)
|
||||||
|
{
|
||||||
|
$user = current_user();
|
||||||
|
|
||||||
|
$adminUserData = $request->all();
|
||||||
|
AdminUserRepo::updateAdminUser($user->id, $adminUserData);
|
||||||
|
|
||||||
|
return response()->redirectTo('admin/account')->with('success', trans('common.updated_success'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -26,10 +26,10 @@ class AttributeController extends Controller
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$attributes = AttributeRepo::getList();
|
$attributes = AttributeRepo::getList();
|
||||||
$data = [
|
$data = [
|
||||||
'attribute_list' => $attributes,
|
'attribute_list' => $attributes,
|
||||||
'attribute_list_format' => AttributeResource::collection($attributes),
|
'attribute_list_format' => AttributeResource::collection($attributes),
|
||||||
'attribute_group' => AttributeGroupRepo::getList(),
|
'attribute_group' => AttributeGroupRepo::getList(),
|
||||||
];
|
];
|
||||||
$data = hook_filter('admin.attribute.index.data', $data);
|
$data = hook_filter('admin.attribute.index.data', $data);
|
||||||
if ($request->expectsJson()) {
|
if ($request->expectsJson()) {
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ class AttributeGroupController extends Controller
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$requestData = json_decode($request->getContent(), true);
|
$requestData = json_decode($request->getContent(), true);
|
||||||
$item = AttributeGroupRepo::create($requestData);
|
$item = AttributeGroupRepo::create($requestData);
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
return json_fail($e->getMessage(), []);
|
return json_fail($e->getMessage(), []);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@
|
||||||
namespace Beike\Admin\Http\Controllers;
|
namespace Beike\Admin\Http\Controllers;
|
||||||
|
|
||||||
use Beike\Admin\Http\Requests\CurrencyRequest;
|
use Beike\Admin\Http\Requests\CurrencyRequest;
|
||||||
|
use Beike\Models\Order;
|
||||||
use Beike\Repositories\CurrencyRepo;
|
use Beike\Repositories\CurrencyRepo;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
|
@ -66,9 +67,19 @@ class CurrencyController extends Controller
|
||||||
|
|
||||||
public function destroy(Request $request, int $currencyId)
|
public function destroy(Request $request, int $currencyId)
|
||||||
{
|
{
|
||||||
CurrencyRepo::delete($currencyId);
|
try {
|
||||||
hook_action('admin.currency.destroy.after', $currencyId);
|
$currency = CurrencyRepo::find($currencyId);
|
||||||
|
$orderExist = Order::query()->where('currency_code', $currency->code)->exists();
|
||||||
|
if ($orderExist) {
|
||||||
|
throw new \Exception(trans('admin/currency.order_exist'));
|
||||||
|
}
|
||||||
|
|
||||||
return json_success(trans('common.deleted_success'));
|
CurrencyRepo::delete($currencyId);
|
||||||
|
hook_action('admin.currency.destroy.after', $currencyId);
|
||||||
|
|
||||||
|
return json_success(trans('common.deleted_success'));
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return json_fail($e->getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,10 +31,12 @@ class FileManagerController extends Controller
|
||||||
public function getFiles(Request $request): array
|
public function getFiles(Request $request): array
|
||||||
{
|
{
|
||||||
$baseFolder = $request->get('base_folder');
|
$baseFolder = $request->get('base_folder');
|
||||||
|
$sort = $request->get('sort', 'created');
|
||||||
|
$order = $request->get('order', 'desc');
|
||||||
$page = (int) $request->get('page');
|
$page = (int) $request->get('page');
|
||||||
$perPage = (int) $request->get('per_page');
|
$perPage = (int) $request->get('per_page');
|
||||||
|
|
||||||
$data = (new FileManagerService)->getFiles($baseFolder, $page, $perPage);
|
$data = (new FileManagerService)->getFiles($baseFolder, $sort, $order, $page, $perPage);
|
||||||
|
|
||||||
return hook_filter('admin.file_manager.files.data', $data);
|
return hook_filter('admin.file_manager.files.data', $data);
|
||||||
}
|
}
|
||||||
|
|
@ -124,7 +126,7 @@ class FileManagerController extends Controller
|
||||||
$savePath = $request->get('path');
|
$savePath = $request->get('path');
|
||||||
|
|
||||||
$originName = $file->getClientOriginalName();
|
$originName = $file->getClientOriginalName();
|
||||||
$filePath = $file->storeAs($savePath, $originName, 'catalog');
|
$filePath = (new FileManagerService)->uploadFile($file, $savePath, $originName);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'name' => $originName,
|
'name' => $originName,
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,16 @@ namespace Beike\Admin\Http\Controllers;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use Beike\Admin\Repositories\DashboardRepo;
|
use Beike\Admin\Repositories\DashboardRepo;
|
||||||
use Beike\Admin\Repositories\Report\OrderReportRepo;
|
use Beike\Admin\Repositories\Report\OrderReportRepo;
|
||||||
|
use Illuminate\Support\Facades\Route;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
class HomeController extends Controller
|
class HomeController extends Controller
|
||||||
{
|
{
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
$data = [
|
$data = [
|
||||||
'views' => DashboardRepo::getCustomerViewData(),
|
'products' => DashboardRepo::getProductData(),
|
||||||
|
// 'views' => DashboardRepo::getCustomerViewData(),
|
||||||
'orders' => DashboardRepo::getOrderData(),
|
'orders' => DashboardRepo::getOrderData(),
|
||||||
'customers' => DashboardRepo::getCustomerData(),
|
'customers' => DashboardRepo::getCustomerData(),
|
||||||
'order_totals' => DashboardRepo::getTotalData(),
|
'order_totals' => DashboardRepo::getTotalData(),
|
||||||
|
|
@ -24,4 +27,54 @@ class HomeController extends Controller
|
||||||
|
|
||||||
return view('admin::pages.home', $data);
|
return view('admin::pages.home', $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过关键字搜索菜单
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function menus()
|
||||||
|
{
|
||||||
|
$keyword = trim(request('keyword'));
|
||||||
|
$menus = [];
|
||||||
|
$routes = Route::getRoutes();
|
||||||
|
foreach ($routes as $route) {
|
||||||
|
$routeName = $route->getName();
|
||||||
|
if (! Str::startsWith($routeName, 'admin')) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$method = $route->methods()[0];
|
||||||
|
if ($method != 'GET') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$routeName = str_replace('admin.', '', $routeName);
|
||||||
|
$permissionRoute = str_replace('.', '_', $routeName);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$url = admin_route($routeName);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$url = '';
|
||||||
|
}
|
||||||
|
if (empty($url)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$title = trans("admin/common.{$permissionRoute}");
|
||||||
|
if (stripos($title, 'admin/common.') !== false) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($keyword && stripos($title, $keyword) !== false) {
|
||||||
|
$menus[] = [
|
||||||
|
'route' => $routeName,
|
||||||
|
'url' => admin_route($routeName),
|
||||||
|
'title' => $title,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $menus;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* AttributeController.php
|
||||||
|
*
|
||||||
|
* @copyright 2023 beikeshop.com - All Rights Reserved
|
||||||
|
* @link https://beikeshop.com
|
||||||
|
* @author TL <mengwb@guangda.work>
|
||||||
|
* @created 2023-01-04 19:45:41
|
||||||
|
* @modified 2023-01-04 19:45:41
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Beike\Admin\Http\Controllers;
|
||||||
|
|
||||||
|
use Beike\Admin\Repositories\AttributeRepo;
|
||||||
|
use Beike\Repositories\SettingRepo;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class MultiFilterController extends Controller
|
||||||
|
{
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$multiFilter = system_setting('base.multi_filter') ?: [];
|
||||||
|
$multiFilter['attribute'] = $multiFilter['attribute'] ?? [];
|
||||||
|
|
||||||
|
if ($attributeIds = $multiFilter['attribute'] ?? []) {
|
||||||
|
$multiFilter['attribute'] = AttributeRepo::getByIds($attributeIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'multi_filter' => $multiFilter,
|
||||||
|
];
|
||||||
|
|
||||||
|
return view('admin::pages.multi_filter.index', $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function store(Request $request)
|
||||||
|
{
|
||||||
|
$settings = $request->all();
|
||||||
|
foreach ($settings as $key => $value) {
|
||||||
|
SettingRepo::storeValue($key, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return redirect(admin_route('multi_filter.index'))->with('success', trans('common.updated_success'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -71,7 +71,7 @@ class OrderController extends Controller
|
||||||
*/
|
*/
|
||||||
public function show(Request $request, Order $order)
|
public function show(Request $request, Order $order)
|
||||||
{
|
{
|
||||||
$order->load(['orderTotals', 'orderHistories', 'orderShipments']);
|
$order->load(['orderTotals', 'orderHistories', 'orderShipments', 'orderPayments']);
|
||||||
$data = hook_filter('admin.order.show.data', ['order' => $order, 'html_items' => []]);
|
$data = hook_filter('admin.order.show.data', ['order' => $order, 'html_items' => []]);
|
||||||
$data['statuses'] = StateMachineService::getInstance($order)->nextBackendStatuses();
|
$data['statuses'] = StateMachineService::getInstance($order)->nextBackendStatuses();
|
||||||
$data = hook_filter('admin.order.show.data', $data);
|
$data = hook_filter('admin.order.show.data', $data);
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,111 @@ class PluginController extends Controller
|
||||||
return view('admin::pages.plugins.index', $data);
|
return view('admin::pages.plugins.index', $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function shipping()
|
||||||
|
{
|
||||||
|
$type = 'shipping';
|
||||||
|
$plugins = app('plugin')->getPlugins();
|
||||||
|
$plugins = $plugins->where('type', $type);
|
||||||
|
$data['plugins'] = array_values(PluginResource::collection($plugins)->jsonSerialize());
|
||||||
|
$data['type'] = $type;
|
||||||
|
$data = hook_filter('admin.plugin.index.data', $data);
|
||||||
|
|
||||||
|
return view('admin::pages.plugins.index', $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function payment()
|
||||||
|
{
|
||||||
|
$type = 'payment';
|
||||||
|
$plugins = app('plugin')->getPlugins();
|
||||||
|
$plugins = $plugins->where('type', $type);
|
||||||
|
$data['plugins'] = array_values(PluginResource::collection($plugins)->jsonSerialize());
|
||||||
|
$data['type'] = $type;
|
||||||
|
$data = hook_filter('admin.plugin.index.data', $data);
|
||||||
|
|
||||||
|
return view('admin::pages.plugins.index', $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function total()
|
||||||
|
{
|
||||||
|
$type = 'total';
|
||||||
|
$plugins = app('plugin')->getPlugins();
|
||||||
|
$plugins = $plugins->where('type', $type);
|
||||||
|
$data['plugins'] = array_values(PluginResource::collection($plugins)->jsonSerialize());
|
||||||
|
$data['type'] = $type;
|
||||||
|
$data = hook_filter('admin.plugin.index.data', $data);
|
||||||
|
|
||||||
|
return view('admin::pages.plugins.index', $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function social()
|
||||||
|
{
|
||||||
|
$type = 'social';
|
||||||
|
$plugins = app('plugin')->getPlugins();
|
||||||
|
$plugins = $plugins->where('type', $type);
|
||||||
|
$data['plugins'] = array_values(PluginResource::collection($plugins)->jsonSerialize());
|
||||||
|
$data['type'] = $type;
|
||||||
|
$data = hook_filter('admin.plugin.index.data', $data);
|
||||||
|
|
||||||
|
return view('admin::pages.plugins.index', $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function feature()
|
||||||
|
{
|
||||||
|
$type = 'feature';
|
||||||
|
$plugins = app('plugin')->getPlugins();
|
||||||
|
$plugins = $plugins->where('type', $type);
|
||||||
|
$data['plugins'] = array_values(PluginResource::collection($plugins)->jsonSerialize());
|
||||||
|
$data['type'] = $type;
|
||||||
|
$data = hook_filter('admin.plugin.index.data', $data);
|
||||||
|
|
||||||
|
return view('admin::pages.plugins.index', $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function language()
|
||||||
|
{
|
||||||
|
$type = 'language';
|
||||||
|
$plugins = app('plugin')->getPlugins();
|
||||||
|
$plugins = $plugins->where('type', $type);
|
||||||
|
$data['plugins'] = array_values(PluginResource::collection($plugins)->jsonSerialize());
|
||||||
|
$data['type'] = $type;
|
||||||
|
$data = hook_filter('admin.plugin.index.data', $data);
|
||||||
|
|
||||||
|
return view('admin::pages.plugins.index', $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function theme()
|
||||||
|
{
|
||||||
|
$type = 'theme';
|
||||||
|
$plugins = app('plugin')->getPlugins();
|
||||||
|
$plugins = $plugins->where('type', $type);
|
||||||
|
$data['plugins'] = array_values(PluginResource::collection($plugins)->jsonSerialize());
|
||||||
|
$data['type'] = $type;
|
||||||
|
$data = hook_filter('admin.plugin.index.data', $data);
|
||||||
|
|
||||||
|
return view('admin::pages.plugins.index', $data);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 上传插件
|
* 上传插件
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ use Beike\Admin\Http\Resources\ProductAttributeResource;
|
||||||
use Beike\Admin\Http\Resources\ProductResource;
|
use Beike\Admin\Http\Resources\ProductResource;
|
||||||
use Beike\Admin\Repositories\TaxClassRepo;
|
use Beike\Admin\Repositories\TaxClassRepo;
|
||||||
use Beike\Admin\Services\ProductService;
|
use Beike\Admin\Services\ProductService;
|
||||||
|
use Beike\Libraries\Weight;
|
||||||
use Beike\Models\Product;
|
use Beike\Models\Product;
|
||||||
use Beike\Repositories\CategoryRepo;
|
use Beike\Repositories\CategoryRepo;
|
||||||
use Beike\Repositories\LanguageRepo;
|
use Beike\Repositories\LanguageRepo;
|
||||||
|
|
@ -20,6 +21,9 @@ class ProductController extends Controller
|
||||||
public function index(Request $request)
|
public function index(Request $request)
|
||||||
{
|
{
|
||||||
$requestData = $request->all();
|
$requestData = $request->all();
|
||||||
|
if (! isset($requestData['sort'])) {
|
||||||
|
$requestData['sort'] = 'products.updated_at';
|
||||||
|
}
|
||||||
$productList = ProductRepo::list($requestData);
|
$productList = ProductRepo::list($requestData);
|
||||||
$products = ProductResource::collection($productList);
|
$products = ProductResource::collection($productList);
|
||||||
$productsFormat = $products->jsonSerialize();
|
$productsFormat = $products->jsonSerialize();
|
||||||
|
|
@ -145,15 +149,16 @@ class ProductController extends Controller
|
||||||
array_unshift($taxClasses, ['title' => trans('admin/builder.text_no'), 'id' => 0]);
|
array_unshift($taxClasses, ['title' => trans('admin/builder.text_no'), 'id' => 0]);
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
'product' => $product,
|
'product' => $product,
|
||||||
'descriptions' => $descriptions ?? [],
|
'descriptions' => $descriptions ?? [],
|
||||||
'category_ids' => $categoryIds ?? [],
|
'category_ids' => $categoryIds ?? [],
|
||||||
'product_attributes' => ProductAttributeResource::collection($product->attributes),
|
'product_attributes' => ProductAttributeResource::collection($product->attributes),
|
||||||
'relations' => ProductResource::collection($product->relations)->resource,
|
'relations' => ProductResource::collection($product->relations)->resource,
|
||||||
'languages' => LanguageRepo::all(),
|
'languages' => LanguageRepo::all(),
|
||||||
'tax_classes' => $taxClasses,
|
'tax_classes' => $taxClasses,
|
||||||
'source' => [
|
'weight_classes' => Weight::getWeightUnits(),
|
||||||
'categories' => CategoryRepo::flatten(locale()),
|
'source' => [
|
||||||
|
'categories' => CategoryRepo::flatten(locale(), false),
|
||||||
],
|
],
|
||||||
'_redirect' => $this->getRedirect(),
|
'_redirect' => $this->getRedirect(),
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ class SettingController extends Controller
|
||||||
{
|
{
|
||||||
$themes = ThemeRepo::getAllThemes();
|
$themes = ThemeRepo::getAllThemes();
|
||||||
|
|
||||||
$tax_address = [
|
$taxAddress = [
|
||||||
['value' => 'shipping', 'label' => trans('admin/setting.shipping_address')],
|
['value' => 'shipping', 'label' => trans('admin/setting.shipping_address')],
|
||||||
['value' => 'payment', 'label' => trans('admin/setting.payment_address')],
|
['value' => 'payment', 'label' => trans('admin/setting.payment_address')],
|
||||||
];
|
];
|
||||||
|
|
@ -38,7 +38,7 @@ class SettingController extends Controller
|
||||||
$data = [
|
$data = [
|
||||||
'countries' => CountryRepo::listEnabled(),
|
'countries' => CountryRepo::listEnabled(),
|
||||||
'currencies' => CurrencyRepo::listEnabled(),
|
'currencies' => CurrencyRepo::listEnabled(),
|
||||||
'tax_address' => $tax_address,
|
'tax_address' => $taxAddress,
|
||||||
'customer_groups' => CustomerGroupDetail::collection(CustomerGroupRepo::list())->jsonSerialize(),
|
'customer_groups' => CustomerGroupDetail::collection(CustomerGroupRepo::list())->jsonSerialize(),
|
||||||
'themes' => $themes,
|
'themes' => $themes,
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ class PageRequest extends FormRequest
|
||||||
{
|
{
|
||||||
$rules = [
|
$rules = [
|
||||||
'descriptions.*.title' => 'required|string|min:3|max:128',
|
'descriptions.*.title' => 'required|string|min:3|max:128',
|
||||||
|
'descriptions.*.summary' => 'string|max:180',
|
||||||
'descriptions.*.content' => 'required|string',
|
'descriptions.*.content' => 'required|string',
|
||||||
'descriptions.*.locale' => 'required|string',
|
'descriptions.*.locale' => 'required|string',
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ class TaxRateRequest extends FormRequest
|
||||||
public function rules(): array
|
public function rules(): array
|
||||||
{
|
{
|
||||||
$rule = [
|
$rule = [
|
||||||
'name' => 'required|string|max:10',
|
'name' => 'required|string|max:32',
|
||||||
'rate' => 'required|numeric',
|
'rate' => 'required|numeric',
|
||||||
'type' => 'required|in:percent,flat',
|
'type' => 'required|in:percent,flat',
|
||||||
'region_id' => 'required|int',
|
'region_id' => 'required|int',
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ class UploadRequest extends FormRequest
|
||||||
public function rules()
|
public function rules()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'file' => 'required|image|mimes:jpg,png,jpeg,gif,svg|max:2048',
|
'file' => 'required|mimes:jpg,png,jpeg,gif,svg,mp4|max:20480',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,13 +22,13 @@ class PageCategoryResource extends JsonResource
|
||||||
return [
|
return [
|
||||||
'id' => $this->id,
|
'id' => $this->id,
|
||||||
'active' => $this->active,
|
'active' => $this->active,
|
||||||
'title' => $description->title,
|
'title' => $description->title ?? '',
|
||||||
'title_format' => sub_string($description->title, 64),
|
'title_format' => sub_string($description->title ?? '', 64),
|
||||||
'summary' => $description->summary,
|
'summary' => $description->summary ?? '',
|
||||||
'summary_format' => sub_string($description->summary, 128),
|
'summary_format' => sub_string($description->summary ?? '', 128),
|
||||||
'meta_title' => $description->meta_title,
|
'meta_title' => $description->meta_title ?? '',
|
||||||
'meta_description' => $description->meta_description,
|
'meta_description' => $description->meta_description ?? '',
|
||||||
'meta_keywords' => $description->meta_keywords,
|
'meta_keywords' => $description->meta_keywords ?? '',
|
||||||
'created_at' => time_format($this->created_at),
|
'created_at' => time_format($this->created_at),
|
||||||
'updated_at' => time_format($this->updated_at),
|
'updated_at' => time_format($this->updated_at),
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,8 @@ class ProductResource extends JsonResource
|
||||||
return image_resize($image);
|
return image_resize($image);
|
||||||
}, $this->images ?? []),
|
}, $this->images ?? []),
|
||||||
'name' => $this->description->name ?? '',
|
'name' => $this->description->name ?? '',
|
||||||
|
'model' => $masterSku->model,
|
||||||
|
'quantity' => $masterSku->quantity,
|
||||||
'price_formatted' => currency_format($masterSku->price),
|
'price_formatted' => currency_format($masterSku->price),
|
||||||
'active' => $this->active,
|
'active' => $this->active,
|
||||||
'position' => $this->position,
|
'position' => $this->position,
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@ class AdminServiceProvider extends ServiceProvider
|
||||||
|
|
||||||
load_settings();
|
load_settings();
|
||||||
$this->loadRoutesFrom(__DIR__ . '/../Routes/admin.php');
|
$this->loadRoutesFrom(__DIR__ . '/../Routes/admin.php');
|
||||||
|
$this->registerGuard();
|
||||||
|
|
||||||
$adminName = admin_name();
|
$adminName = admin_name();
|
||||||
if (! Str::startsWith($uri, "/{$adminName}")) {
|
if (! Str::startsWith($uri, "/{$adminName}")) {
|
||||||
|
|
@ -69,8 +70,6 @@ class AdminServiceProvider extends ServiceProvider
|
||||||
|
|
||||||
$this->loadAdminViewComponents();
|
$this->loadAdminViewComponents();
|
||||||
|
|
||||||
$this->registerGuard();
|
|
||||||
|
|
||||||
Config::set('filesystems.disks.catalog', [
|
Config::set('filesystems.disks.catalog', [
|
||||||
'driver' => 'local',
|
'driver' => 'local',
|
||||||
'root' => public_path('catalog'),
|
'root' => public_path('catalog'),
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ namespace Beike\Admin\Repositories;
|
||||||
|
|
||||||
use Beike\Admin\Http\Resources\AdminUserDetail;
|
use Beike\Admin\Http\Resources\AdminUserDetail;
|
||||||
use Beike\Models\AdminUser;
|
use Beike\Models\AdminUser;
|
||||||
|
use Beike\Repositories\AdminUserTokenRepo;
|
||||||
use Symfony\Component\HttpKernel\Exception\NotAcceptableHttpException;
|
use Symfony\Component\HttpKernel\Exception\NotAcceptableHttpException;
|
||||||
|
|
||||||
class AdminUserRepo
|
class AdminUserRepo
|
||||||
|
|
@ -73,7 +74,14 @@ class AdminUserRepo
|
||||||
$userData['password'] = bcrypt($password);
|
$userData['password'] = bcrypt($password);
|
||||||
}
|
}
|
||||||
$adminUser->update($userData);
|
$adminUser->update($userData);
|
||||||
$adminUser->syncRoles($data['roles']);
|
|
||||||
|
$roles = $data['roles'] ?? [];
|
||||||
|
if ($roles) {
|
||||||
|
$adminUser->syncRoles($roles);
|
||||||
|
}
|
||||||
|
|
||||||
|
$tokens = $data['tokens'] ?? [];
|
||||||
|
AdminUserTokenRepo::updateTokensByUser($adminUser, $tokens);
|
||||||
|
|
||||||
return $adminUser;
|
return $adminUser;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,9 @@ class AttributeGroupRepo
|
||||||
|
|
||||||
public static function delete($id)
|
public static function delete($id)
|
||||||
{
|
{
|
||||||
|
if ($id == 1) {
|
||||||
|
throw new \Exception(trans('admin/attribute_group.error_cannot_delete_default_group'));
|
||||||
|
}
|
||||||
$group = AttributeGroup::query()->findOrFail($id);
|
$group = AttributeGroup::query()->findOrFail($id);
|
||||||
if ($group->attributes->count()) {
|
if ($group->attributes->count()) {
|
||||||
throw new \Exception(trans('admin/attribute_group.error_cannot_delete_attribute_used', ['attributes' => implode(', ', $group->attributes->pluck('id')->toArray())]));
|
throw new \Exception(trans('admin/attribute_group.error_cannot_delete_attribute_used', ['attributes' => implode(', ', $group->attributes->pluck('id')->toArray())]));
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@
|
||||||
namespace Beike\Admin\Repositories;
|
namespace Beike\Admin\Repositories;
|
||||||
|
|
||||||
use Beike\Models\Attribute;
|
use Beike\Models\Attribute;
|
||||||
|
use Beike\Models\AttributeDescription;
|
||||||
use Beike\Models\AttributeValue;
|
use Beike\Models\AttributeValue;
|
||||||
use Beike\Models\ProductAttribute;
|
use Beike\Models\ProductAttribute;
|
||||||
|
|
||||||
|
|
@ -138,4 +139,14 @@ class AttributeRepo
|
||||||
|
|
||||||
return $builder->limit(10)->get();
|
return $builder->limit(10)->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function getByIds($ids)
|
||||||
|
{
|
||||||
|
return AttributeDescription::query()
|
||||||
|
->where('locale', locale())
|
||||||
|
->whereIn('attribute_id', $ids)
|
||||||
|
->select(['attribute_id as id', 'name'])
|
||||||
|
->get()
|
||||||
|
->toArray();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,9 @@
|
||||||
|
|
||||||
namespace Beike\Admin\Repositories;
|
namespace Beike\Admin\Repositories;
|
||||||
|
|
||||||
use Beike\Models\Product;
|
|
||||||
use Beike\Repositories\CustomerRepo;
|
use Beike\Repositories\CustomerRepo;
|
||||||
use Beike\Repositories\OrderRepo;
|
use Beike\Repositories\OrderRepo;
|
||||||
|
use Beike\Repositories\ProductRepo;
|
||||||
|
|
||||||
class DashboardRepo
|
class DashboardRepo
|
||||||
{
|
{
|
||||||
|
|
@ -21,12 +21,22 @@ class DashboardRepo
|
||||||
* 获取商品总数
|
* 获取商品总数
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public static function getProductData(): array
|
public static function getProductData(): array
|
||||||
{
|
{
|
||||||
|
$today = ProductRepo::getBuilder(['created_start' => today()->subDay(), 'created_end' => today()])->count();
|
||||||
|
$yesterday = ProductRepo::getBuilder(['created_start' => today()->subDays(2), 'created_end' => today()->subDay()])->count();
|
||||||
|
$difference = $today - $yesterday;
|
||||||
|
if ($difference && $yesterday) {
|
||||||
|
$percentage = round(($difference / $yesterday) * 100);
|
||||||
|
} else {
|
||||||
|
$percentage = 0;
|
||||||
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'total' => quantity_format(Product::query()->count()),
|
'total' => $today,
|
||||||
'percentage' => 0,
|
'percentage' => $percentage,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -83,6 +83,8 @@ class PageRepo
|
||||||
$page->descriptions()->createMany($data['descriptions']);
|
$page->descriptions()->createMany($data['descriptions']);
|
||||||
|
|
||||||
$products = $data['products'] ?? [];
|
$products = $data['products'] ?? [];
|
||||||
|
$page->pageProducts()->delete();
|
||||||
|
|
||||||
if ($products) {
|
if ($products) {
|
||||||
$items = [];
|
$items = [];
|
||||||
foreach ($products as $item) {
|
foreach ($products as $item) {
|
||||||
|
|
@ -90,7 +92,6 @@ class PageRepo
|
||||||
'product_id' => $item,
|
'product_id' => $item,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
$page->pageProducts()->delete();
|
|
||||||
$page->pageProducts()->createMany($items);
|
$page->pageProducts()->createMany($items);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -138,7 +138,7 @@ class PermissionRepo
|
||||||
*/
|
*/
|
||||||
private function getProductPermissions(): array
|
private function getProductPermissions(): array
|
||||||
{
|
{
|
||||||
$routes = ['products_index', 'products_create', 'products_show', 'products_update', 'products_delete', 'products_trashed', 'products_restore'];
|
$routes = ['products_index', 'products_create', 'products_show', 'products_update', 'products_delete', 'products_trashed', 'products_restore', 'products_filter_index', 'products_filter_update'];
|
||||||
$items = $this->getPermissionList('product', $routes);
|
$items = $this->getPermissionList('product', $routes);
|
||||||
|
|
||||||
return hook_filter('role.product_permissions', $items);
|
return hook_filter('role.product_permissions', $items);
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,11 @@ Route::prefix($adminName)
|
||||||
Route::middleware('admin_auth:' . \Beike\Models\AdminUser::AUTH_GUARD)
|
Route::middleware('admin_auth:' . \Beike\Models\AdminUser::AUTH_GUARD)
|
||||||
->group(function () {
|
->group(function () {
|
||||||
Route::get('/', [Controllers\HomeController::class, 'index'])->name('home.index');
|
Route::get('/', [Controllers\HomeController::class, 'index'])->name('home.index');
|
||||||
|
Route::get('/menus', [Controllers\HomeController::class, 'menus'])->name('home.menus');
|
||||||
|
|
||||||
|
//个人中心
|
||||||
|
Route::middleware('can:account_index')->get('account', [Controllers\AccountController::class, 'index'])->name('account.index');
|
||||||
|
Route::middleware('can:account_update')->put('account', [Controllers\AccountController::class, 'update'])->name('account.update');
|
||||||
|
|
||||||
// 属性
|
// 属性
|
||||||
Route::middleware('can:attributes_update')->post('attributes/{id}/values', [Controllers\AttributeController::class, 'storeValue'])->name('attributes.values.store');
|
Route::middleware('can:attributes_update')->post('attributes/{id}/values', [Controllers\AttributeController::class, 'storeValue'])->name('attributes.values.store');
|
||||||
|
|
@ -32,6 +37,10 @@ Route::prefix($adminName)
|
||||||
Route::middleware('can:attributes_update')->put('attributes/{id}', [Controllers\AttributeController::class, 'update'])->name('attributes.update');
|
Route::middleware('can:attributes_update')->put('attributes/{id}', [Controllers\AttributeController::class, 'update'])->name('attributes.update');
|
||||||
Route::middleware('can:attributes_delete')->delete('attributes/{id}', [Controllers\AttributeController::class, 'destroy'])->name('attributes.destroy');
|
Route::middleware('can:attributes_delete')->delete('attributes/{id}', [Controllers\AttributeController::class, 'destroy'])->name('attributes.destroy');
|
||||||
|
|
||||||
|
// 高级筛选
|
||||||
|
Route::middleware('can:products_filter_index')->get('multi_filter', [Controllers\MultiFilterController::class, 'index'])->name('multi_filter.index');
|
||||||
|
Route::middleware('can:products_filter_update')->post('multi_filter', [Controllers\MultiFilterController::class, 'store'])->name('multi_filter.store');
|
||||||
|
|
||||||
// 属性组
|
// 属性组
|
||||||
Route::middleware('can:attribute_groups_index')->get('attribute_groups', [Controllers\AttributeGroupController::class, 'index'])->name('attribute_groups.index');
|
Route::middleware('can:attribute_groups_index')->get('attribute_groups', [Controllers\AttributeGroupController::class, 'index'])->name('attribute_groups.index');
|
||||||
Route::middleware('can:attribute_groups_create')->post('attribute_groups', [Controllers\AttributeGroupController::class, 'store'])->name('attribute_groups.store');
|
Route::middleware('can:attribute_groups_create')->post('attribute_groups', [Controllers\AttributeGroupController::class, 'store'])->name('attribute_groups.store');
|
||||||
|
|
@ -153,6 +162,15 @@ Route::prefix($adminName)
|
||||||
Route::middleware('can:plugins_install')->post('plugins/{code}/install', [Controllers\PluginController::class, 'install'])->name('plugins.install');
|
Route::middleware('can:plugins_install')->post('plugins/{code}/install', [Controllers\PluginController::class, 'install'])->name('plugins.install');
|
||||||
Route::middleware('can:plugins_uninstall')->post('plugins/{code}/uninstall', [Controllers\PluginController::class, 'uninstall'])->name('plugins.uninstall');
|
Route::middleware('can:plugins_uninstall')->post('plugins/{code}/uninstall', [Controllers\PluginController::class, 'uninstall'])->name('plugins.uninstall');
|
||||||
|
|
||||||
|
// 插件分组
|
||||||
|
Route::middleware('can:plugins_index')->get('plugins/shipping', [Controllers\PluginController::class, 'shipping'])->name('plugins.shipping');
|
||||||
|
Route::middleware('can:plugins_index')->get('plugins/payment', [Controllers\PluginController::class, 'payment'])->name('plugins.payment');
|
||||||
|
Route::middleware('can:plugins_index')->get('plugins/total', [Controllers\PluginController::class, 'total'])->name('plugins.total');
|
||||||
|
Route::middleware('can:plugins_index')->get('plugins/social', [Controllers\PluginController::class, 'social'])->name('plugins.social');
|
||||||
|
Route::middleware('can:plugins_index')->get('plugins/feature', [Controllers\PluginController::class, 'feature'])->name('plugins.feature');
|
||||||
|
Route::middleware('can:plugins_index')->get('plugins/language', [Controllers\PluginController::class, 'language'])->name('plugins.language');
|
||||||
|
Route::middleware('can:plugins_index')->get('plugins/theme', [Controllers\PluginController::class, 'theme'])->name('plugins.theme');
|
||||||
|
|
||||||
// 插件市场
|
// 插件市场
|
||||||
Route::middleware('can:marketing_index')->get('marketing', [Controllers\MarketingController::class, 'index'])->name('marketing.index');
|
Route::middleware('can:marketing_index')->get('marketing', [Controllers\MarketingController::class, 'index'])->name('marketing.index');
|
||||||
Route::middleware('can:marketing_show')->get('marketing/{code}', [Controllers\MarketingController::class, 'show'])->name('marketing.show');
|
Route::middleware('can:marketing_show')->get('marketing/{code}', [Controllers\MarketingController::class, 'show'])->name('marketing.show');
|
||||||
|
|
@ -196,7 +214,7 @@ Route::prefix($adminName)
|
||||||
Route::middleware('can:products_index')->get('products', [Controllers\ProductController::class, 'index'])->name('products.index');
|
Route::middleware('can:products_index')->get('products', [Controllers\ProductController::class, 'index'])->name('products.index');
|
||||||
Route::middleware('can:products_create')->get('products/create', [Controllers\ProductController::class, 'create'])->name('products.create');
|
Route::middleware('can:products_create')->get('products/create', [Controllers\ProductController::class, 'create'])->name('products.create');
|
||||||
Route::middleware('can:products_create')->post('products', [Controllers\ProductController::class, 'store'])->name('products.store');
|
Route::middleware('can:products_create')->post('products', [Controllers\ProductController::class, 'store'])->name('products.store');
|
||||||
Route::middleware('can:products_update')->get('products/{product}/edit', [Controllers\ProductController::class, 'edit'])->name('products.edit');
|
Route::middleware('can:products_show')->get('products/{product}/edit', [Controllers\ProductController::class, 'edit'])->name('products.edit');
|
||||||
Route::middleware('can:products_update')->put('products/{product}', [Controllers\ProductController::class, 'update'])->name('products.update');
|
Route::middleware('can:products_update')->put('products/{product}', [Controllers\ProductController::class, 'update'])->name('products.update');
|
||||||
Route::middleware('can:products_delete')->delete('products/{product}', [Controllers\ProductController::class, 'destroy'])->name('products.destroy');
|
Route::middleware('can:products_delete')->delete('products/{product}', [Controllers\ProductController::class, 'destroy'])->name('products.destroy');
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,11 +13,13 @@ namespace Beike\Admin\Services;
|
||||||
|
|
||||||
class FileManagerService
|
class FileManagerService
|
||||||
{
|
{
|
||||||
private $fileBasePath = '';
|
protected $fileBasePath = '';
|
||||||
|
|
||||||
|
protected $basePath = '';
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->fileBasePath = public_path('catalog');
|
$this->fileBasePath = public_path('catalog') . $this->basePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -26,6 +28,7 @@ class FileManagerService
|
||||||
public function getDirectories($baseFolder = '/'): array
|
public function getDirectories($baseFolder = '/'): array
|
||||||
{
|
{
|
||||||
$currentBasePath = rtrim($this->fileBasePath . $baseFolder, '/');
|
$currentBasePath = rtrim($this->fileBasePath . $baseFolder, '/');
|
||||||
|
|
||||||
$directories = glob("{$currentBasePath}/*", GLOB_ONLYDIR);
|
$directories = glob("{$currentBasePath}/*", GLOB_ONLYDIR);
|
||||||
|
|
||||||
$result = [];
|
$result = [];
|
||||||
|
|
@ -49,18 +52,34 @@ class FileManagerService
|
||||||
* 获取某个目录下的文件和文件夹
|
* 获取某个目录下的文件和文件夹
|
||||||
*
|
*
|
||||||
* @param $baseFolder
|
* @param $baseFolder
|
||||||
|
* @param $sort
|
||||||
|
* @param $order
|
||||||
* @param int $page
|
* @param int $page
|
||||||
* @param int $perPage
|
* @param int $perPage
|
||||||
* @return array
|
* @return array
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function getFiles($baseFolder, int $page = 1, int $perPage = 20): array
|
public function getFiles($baseFolder, $sort, $order, int $page = 1, int $perPage = 20): array
|
||||||
{
|
{
|
||||||
$currentBasePath = rtrim($this->fileBasePath . $baseFolder, '/');
|
$currentBasePath = rtrim($this->fileBasePath . $baseFolder, '/');
|
||||||
$files = glob($currentBasePath . '/*');
|
$files = glob($currentBasePath . '/*');
|
||||||
usort($files, function ($a, $b) {
|
|
||||||
return filemtime($a) - filemtime($b) < 0;
|
if ($sort == 'created') {
|
||||||
});
|
if ($order == 'desc') {
|
||||||
|
usort($files, function ($a, $b) {
|
||||||
|
return filemtime($a) - filemtime($b) < 0;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
usort($files, function ($a, $b) {
|
||||||
|
return filemtime($a) - filemtime($b) >= 0;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
natcasesort($files);
|
||||||
|
if ($order == 'desc') {
|
||||||
|
$files = array_reverse($files);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$images = [];
|
$images = [];
|
||||||
foreach ($files as $file) {
|
foreach ($files as $file) {
|
||||||
|
|
@ -68,7 +87,7 @@ class FileManagerService
|
||||||
if ($baseName == 'index.html') {
|
if ($baseName == 'index.html') {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$fileName = str_replace($this->fileBasePath, '', $file);
|
$fileName = str_replace(public_path('catalog'), '', $file);
|
||||||
if (is_file($file)) {
|
if (is_file($file)) {
|
||||||
$images[] = $this->handleImage($fileName, $baseName);
|
$images[] = $this->handleImage($fileName, $baseName);
|
||||||
}
|
}
|
||||||
|
|
@ -98,7 +117,7 @@ class FileManagerService
|
||||||
*/
|
*/
|
||||||
public function createDirectory($folderName)
|
public function createDirectory($folderName)
|
||||||
{
|
{
|
||||||
$catalogFolderPath = "catalog/{$folderName}";
|
$catalogFolderPath = "catalog{$this->basePath}/{$folderName}";
|
||||||
$folderPath = public_path($catalogFolderPath);
|
$folderPath = public_path($catalogFolderPath);
|
||||||
if (is_dir($folderPath)) {
|
if (is_dir($folderPath)) {
|
||||||
throw new \Exception(trans('admin/file_manager.directory_already_exist'));
|
throw new \Exception(trans('admin/file_manager.directory_already_exist'));
|
||||||
|
|
@ -114,7 +133,7 @@ class FileManagerService
|
||||||
*/
|
*/
|
||||||
public function deleteDirectoryOrFile($filePath)
|
public function deleteDirectoryOrFile($filePath)
|
||||||
{
|
{
|
||||||
$filePath = public_path("catalog/{$filePath}");
|
$filePath = public_path("catalog{$this->basePath}/{$filePath}");
|
||||||
if (is_dir($filePath)) {
|
if (is_dir($filePath)) {
|
||||||
$files = glob($filePath . '/*');
|
$files = glob($filePath . '/*');
|
||||||
if ($files) {
|
if ($files) {
|
||||||
|
|
@ -138,7 +157,7 @@ class FileManagerService
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
foreach ($files as $file) {
|
foreach ($files as $file) {
|
||||||
$filePath = public_path("catalog/{$basePath}/$file");
|
$filePath = public_path("catalog{$this->basePath}/{$basePath}/$file");
|
||||||
if (file_exists($filePath)) {
|
if (file_exists($filePath)) {
|
||||||
@unlink($filePath);
|
@unlink($filePath);
|
||||||
}
|
}
|
||||||
|
|
@ -154,7 +173,7 @@ class FileManagerService
|
||||||
*/
|
*/
|
||||||
public function updateName($originPath, $newPath)
|
public function updateName($originPath, $newPath)
|
||||||
{
|
{
|
||||||
$originPath = public_path("catalog/{$originPath}");
|
$originPath = public_path("catalog{$this->basePath}/{$originPath}");
|
||||||
if (! is_dir($originPath) && ! file_exists($originPath)) {
|
if (! is_dir($originPath) && ! file_exists($originPath)) {
|
||||||
throw new \Exception(trans('admin/file_manager.target_not_exist'));
|
throw new \Exception(trans('admin/file_manager.target_not_exist'));
|
||||||
}
|
}
|
||||||
|
|
@ -166,6 +185,13 @@ class FileManagerService
|
||||||
@rename($originPath, $newPath);
|
@rename($originPath, $newPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function uploadFile($file, $savePath, $originName)
|
||||||
|
{
|
||||||
|
$savePath = $this->basePath . $savePath;
|
||||||
|
|
||||||
|
return $file->storeAs($savePath, $originName, 'catalog');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理文件夹
|
* 处理文件夹
|
||||||
*
|
*
|
||||||
|
|
@ -189,7 +215,7 @@ class FileManagerService
|
||||||
*/
|
*/
|
||||||
private function hasSubFolders($folderPath): bool
|
private function hasSubFolders($folderPath): bool
|
||||||
{
|
{
|
||||||
$path = public_path("catalog/{$folderPath}");
|
$path = public_path("catalog{$this->basePath}/{$folderPath}");
|
||||||
$subFiles = glob($path . '/*');
|
$subFiles = glob($path . '/*');
|
||||||
foreach ($subFiles as $subFile) {
|
foreach ($subFiles as $subFile) {
|
||||||
if (is_dir($subFile)) {
|
if (is_dir($subFile)) {
|
||||||
|
|
@ -210,12 +236,19 @@ class FileManagerService
|
||||||
*/
|
*/
|
||||||
private function handleImage($filePath, $baseName): array
|
private function handleImage($filePath, $baseName): array
|
||||||
{
|
{
|
||||||
$path = "catalog{$filePath}";
|
$path = "catalog{$filePath}";
|
||||||
|
$realPath = $this->fileBasePath . $filePath;
|
||||||
|
|
||||||
|
$mime = '';
|
||||||
|
if(file_exists($realPath)) {
|
||||||
|
$mime = mime_content_type($realPath);
|
||||||
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'path' => $path,
|
'path' => $path,
|
||||||
'name' => $baseName,
|
'name' => $baseName,
|
||||||
'origin_url' => image_origin($path),
|
'origin_url' => image_origin($path),
|
||||||
|
'mime' => $mime,
|
||||||
'selected' => false,
|
'selected' => false,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ class MarketingService
|
||||||
*/
|
*/
|
||||||
public function getPlugin($pluginCode): mixed
|
public function getPlugin($pluginCode): mixed
|
||||||
{
|
{
|
||||||
$url = config('beike.api_url') . "/api/plugins/{$pluginCode}";
|
$url = config('beike.api_url') . "/api/plugins/{$pluginCode}?version=" . config('beike.version');
|
||||||
$plugin = $this->httpClient->get($url)->json();
|
$plugin = $this->httpClient->get($url)->json();
|
||||||
if (empty($plugin)) {
|
if (empty($plugin)) {
|
||||||
throw new NotFoundHttpException('该插件不存在或已下架');
|
throw new NotFoundHttpException('该插件不存在或已下架');
|
||||||
|
|
|
||||||
|
|
@ -26,9 +26,12 @@ class ProductService
|
||||||
try {
|
try {
|
||||||
DB::beginTransaction();
|
DB::beginTransaction();
|
||||||
|
|
||||||
$data['brand_id'] = (int) $data['brand_id'];
|
$data['brand_id'] = (int) ($data['brand_id'] ?? 0);
|
||||||
$data['variables'] = json_decode($data['variables']);
|
$data['position'] = (int) ($data['position'] ?? 0);
|
||||||
|
$data['weight'] = (float) ($data['weight'] ?? 0);
|
||||||
|
$data['variables'] = json_decode($data['variables'] ?? '[]');
|
||||||
$product->fill($data);
|
$product->fill($data);
|
||||||
|
$product->updated_at = now();
|
||||||
$product->save();
|
$product->save();
|
||||||
|
|
||||||
if ($isUpdating) {
|
if ($isUpdating) {
|
||||||
|
|
|
||||||
|
|
@ -14,16 +14,19 @@ class Select extends Component
|
||||||
|
|
||||||
public array $options;
|
public array $options;
|
||||||
|
|
||||||
|
public string $width;
|
||||||
|
|
||||||
public string $key;
|
public string $key;
|
||||||
|
|
||||||
public string $label;
|
public string $label;
|
||||||
|
|
||||||
public function __construct(string $name, string $value, string $title, array $options, ?string $key = 'value', ?string $label = 'label')
|
public function __construct(string $name, string $value, string $title, array $options, string $width = '400', ?string $key = 'value', ?string $label = 'label')
|
||||||
{
|
{
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
$this->title = $title;
|
$this->title = $title;
|
||||||
$this->value = $value;
|
$this->value = $value;
|
||||||
$this->options = $options;
|
$this->options = $options;
|
||||||
|
$this->width = $width;
|
||||||
$this->key = $key;
|
$this->key = $key;
|
||||||
$this->label = $label;
|
$this->label = $label;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
namespace Beike\Admin\View\Components;
|
namespace Beike\Admin\View\Components;
|
||||||
|
|
||||||
use Beike\Models\AdminUser;
|
use Beike\Models\AdminUser;
|
||||||
|
use Illuminate\Support\Facades\View;
|
||||||
use Illuminate\View\Component;
|
use Illuminate\View\Component;
|
||||||
|
|
||||||
class Header extends Component
|
class Header extends Component
|
||||||
|
|
@ -11,6 +12,10 @@ class Header extends Component
|
||||||
|
|
||||||
private ?AdminUser $adminUser;
|
private ?AdminUser $adminUser;
|
||||||
|
|
||||||
|
public array $commonLinks;
|
||||||
|
|
||||||
|
public array $historyLinks;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new component instance.
|
* Create a new component instance.
|
||||||
*
|
*
|
||||||
|
|
@ -28,82 +33,102 @@ class Header extends Component
|
||||||
*/
|
*/
|
||||||
public function render()
|
public function render()
|
||||||
{
|
{
|
||||||
$sidebar = new Sidebar();
|
$this->commonLinks = $this->getCommonLinks();
|
||||||
$preparedMenus = $this->prepareMenus();
|
$this->historyLinks = $this->handleHistoryLinks();
|
||||||
|
|
||||||
foreach ($preparedMenus as $menu) {
|
|
||||||
$menuCode = $menu['code'] ?? '';
|
|
||||||
if ($menuCode) {
|
|
||||||
$routes = [];
|
|
||||||
$subRoutesMethod = "get{$menu['code']}SubRoutes";
|
|
||||||
if (method_exists($sidebar, $subRoutesMethod)) {
|
|
||||||
$sideMenuRoutes = $sidebar->{"get{$menu['code']}SubRoutes"}();
|
|
||||||
foreach ($sideMenuRoutes as $route) {
|
|
||||||
$routeFirst = explode('.', $route['route'])[0] ?? '';
|
|
||||||
$routes[] = 'admin.' . $route['route'];
|
|
||||||
$routes[] = 'admin.' . $routeFirst . '.edit';
|
|
||||||
$routes[] = 'admin.' . $routeFirst . '.show';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$data = [
|
|
||||||
'menu_code' => $menuCode,
|
|
||||||
'routes' => $routes,
|
|
||||||
];
|
|
||||||
$filterRoutes = hook_filter('admin.components.header.routes', $data);
|
|
||||||
$routes = $filterRoutes['routes'] ?? [];
|
|
||||||
if (empty($routes)) {
|
|
||||||
$is_route = equal_route('admin.' . $menu['route']);
|
|
||||||
} else {
|
|
||||||
$is_route = equal_route($routes);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$is_route = equal_route('admin.' . $menu['route']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->addLink($menu['name'], $menu['route'], $is_route);
|
|
||||||
}
|
|
||||||
|
|
||||||
return view('admin::components.header');
|
return view('admin::components.header');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 默认菜单
|
* 常用功能链接
|
||||||
*/
|
*/
|
||||||
private function prepareMenus()
|
private function getCommonLinks()
|
||||||
{
|
{
|
||||||
$menus = [
|
$commonLinks = [
|
||||||
['name' => trans('admin/common.home'), 'route' => 'home.index', 'code' => ''],
|
['route' => 'design.index', 'icon' => 'bi bi-palette', 'blank' => true],
|
||||||
['name' => trans('admin/common.order'), 'route' => 'orders.index', 'code' => 'Order'],
|
['route' => 'design_footer.index', 'icon' => 'bi bi-palette', 'blank' => true],
|
||||||
['name' => trans('admin/common.product'), 'route' => 'products.index', 'code' => 'Product'],
|
['route' => 'design_menu.index', 'icon' => 'bi bi-list', 'blank' => false],
|
||||||
['name' => trans('admin/common.customer'), 'route' => 'customers.index', 'code' => 'Customer'],
|
['route' => 'languages.index', 'icon' => 'bi bi-globe2', 'blank' => false],
|
||||||
['name' => trans('admin/common.page'), 'route' => 'pages.index', 'code' => 'Page'],
|
['route' => 'currencies.index', 'icon' => 'bi bi-currency-dollar', 'blank' => false],
|
||||||
['name' => trans('admin/common.setting'), 'route' => 'settings.index', 'code' => 'Setting'],
|
['route' => 'plugins.index', 'icon' => 'bi bi-plug', 'blank' => false],
|
||||||
['name' => trans('admin/common.inquiry'), 'route' => 'inquiry.index', 'code' => 'Inquiry'],
|
|
||||||
];
|
];
|
||||||
|
|
||||||
return hook_filter('admin.header_menus', $menus);
|
foreach ($commonLinks as $index => $commonLink) {
|
||||||
|
$route = $commonLink['route'];
|
||||||
|
$permissionRoute = str_replace('.', '_', $route);
|
||||||
|
$commonLinks[$index]['url'] = admin_route($route);
|
||||||
|
$commonLinks[$index]['title'] = trans("admin/common.{$permissionRoute}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return hook_filter('admin.components.header.common_links', $commonLinks);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加后台顶部菜单链接
|
* 处理最近访问链接
|
||||||
*
|
|
||||||
* @param $title
|
|
||||||
* @param $route
|
|
||||||
* @param false $active
|
|
||||||
*/
|
*/
|
||||||
private function addLink($title, $route, bool $active = false)
|
private function handleHistoryLinks(): array
|
||||||
{
|
{
|
||||||
$permissionRoute = str_replace('.', '_', $route);
|
$links = [];
|
||||||
if ($this->adminUser->cannot($permissionRoute) && $route != 'home.index') {
|
$histories = $this->getHistoryRoutesFromSession();
|
||||||
return;
|
foreach ($histories as $history) {
|
||||||
|
$routeName = str_replace('admin.', '', $history);
|
||||||
|
$permissionRoute = str_replace('.', '_', $routeName);
|
||||||
|
|
||||||
|
if (stripos($routeName, 'plugins.') !== false) {
|
||||||
|
$type = str_replace('plugins.', '', $routeName);
|
||||||
|
if ($type == 'index') {
|
||||||
|
$title = trans("admin/common.{$permissionRoute}");
|
||||||
|
} else {
|
||||||
|
$title = trans("admin/plugin.{$type}");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$title = trans("admin/common.{$permissionRoute}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stripos($title, 'admin/common.') !== false) {
|
||||||
|
$tempRouteName = str_replace('s.index', '', $routeName);
|
||||||
|
$title = trans("admin/common.{$tempRouteName}");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$url = admin_route($routeName);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$url = '';
|
||||||
|
}
|
||||||
|
if (empty($url)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$links[] = [
|
||||||
|
'route' => $routeName,
|
||||||
|
'url' => $url,
|
||||||
|
'title' => $title,
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
$url = admin_route($route);
|
return $links;
|
||||||
$this->links[] = [
|
}
|
||||||
'title' => $title,
|
|
||||||
'url' => $url,
|
/**
|
||||||
'active' => $active,
|
* 从 session 获取最近访问的链接
|
||||||
];
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function getHistoryRoutesFromSession(): array
|
||||||
|
{
|
||||||
|
$histories = session('histories', []);
|
||||||
|
|
||||||
|
$currentRoute = request()->route()->getName();
|
||||||
|
$routeName = str_replace('admin.', '', $currentRoute);
|
||||||
|
|
||||||
|
if (in_array($routeName, ['edit.locale', 'home.menus'])) {
|
||||||
|
return $histories;
|
||||||
|
}
|
||||||
|
|
||||||
|
array_unshift($histories, $currentRoute);
|
||||||
|
$histories = array_slice(array_unique($histories), 0, 6);
|
||||||
|
session(['histories' => $histories]);
|
||||||
|
|
||||||
|
return $histories;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,17 +3,23 @@
|
||||||
namespace Beike\Admin\View\Components;
|
namespace Beike\Admin\View\Components;
|
||||||
|
|
||||||
use Beike\Models\AdminUser;
|
use Beike\Models\AdminUser;
|
||||||
use Illuminate\Support\Str;
|
use Beike\Plugin\Plugin;
|
||||||
use Illuminate\View\Component;
|
use Illuminate\View\Component;
|
||||||
|
|
||||||
class Sidebar extends Component
|
class Sidebar extends Component
|
||||||
{
|
{
|
||||||
public array $links = [];
|
public array $links = [];
|
||||||
|
|
||||||
|
public ?array $currentLink;
|
||||||
|
|
||||||
private string $adminName;
|
private string $adminName;
|
||||||
|
|
||||||
private ?string $routeNameWithPrefix;
|
private ?string $routeNameWithPrefix;
|
||||||
|
|
||||||
|
private ?string $currentRouteName;
|
||||||
|
|
||||||
|
private ?string $currentPrefix;
|
||||||
|
|
||||||
private ?AdminUser $adminUser;
|
private ?AdminUser $adminUser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -23,9 +29,14 @@ class Sidebar extends Component
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->adminName = admin_name();
|
$this->adminName = admin_name();
|
||||||
|
$this->adminUser = current_user();
|
||||||
|
|
||||||
$this->routeNameWithPrefix = request()->route()->getName();
|
$this->routeNameWithPrefix = request()->route()->getName();
|
||||||
$this->adminUser = current_user();
|
$this->currentRouteName = str_replace($this->adminName . '.', '', $this->routeNameWithPrefix);
|
||||||
|
|
||||||
|
$routeData = explode('.', $this->currentRouteName);
|
||||||
|
$this->currentPrefix = $routeData[0] ?? '';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -35,81 +46,168 @@ class Sidebar extends Component
|
||||||
*/
|
*/
|
||||||
public function render()
|
public function render()
|
||||||
{
|
{
|
||||||
$adminName = $this->adminName;
|
$this->links = $this->getMenus();
|
||||||
$routeNameWithPrefix = request()->route()->getName();
|
$this->handleMenus();
|
||||||
$routeName = str_replace($adminName . '.', '', $routeNameWithPrefix);
|
$this->currentLink = $this->getCurrentLink();
|
||||||
|
|
||||||
if (Str::startsWith($routeName, $this->getHomeSubPrefix())) {
|
|
||||||
$routes = $this->getHomeSubRoutes();
|
|
||||||
foreach ($routes as $route) {
|
|
||||||
$this->addLink($route, $this->equalRoute($route['route']), (bool) ($route['blank'] ?? false), $route['hide_mobile'] ?? 0);
|
|
||||||
}
|
|
||||||
} elseif (Str::startsWith($routeName, $this->getProductSubPrefix())) {
|
|
||||||
$routes = $this->getProductSubRoutes();
|
|
||||||
foreach ($routes as $route) {
|
|
||||||
$this->addLink($route, $this->equalRoute($route['route']), (bool) ($route['blank'] ?? false), $route['hide_mobile'] ?? 0);
|
|
||||||
}
|
|
||||||
} elseif (Str::startsWith($routeName, $this->getCustomerSubPrefix())) {
|
|
||||||
$routes = $this->getCustomerSubRoutes();
|
|
||||||
foreach ($routes as $route) {
|
|
||||||
$this->addLink($route, $this->equalRoute($route['route']), (bool) ($route['blank'] ?? false), $route['hide_mobile'] ?? 0);
|
|
||||||
}
|
|
||||||
} elseif (Str::startsWith($routeName, $this->getOrderSubPrefix())) {
|
|
||||||
$routes = $this->getOrderSubRoutes();
|
|
||||||
foreach ($routes as $route) {
|
|
||||||
$this->addLink($route, $this->equalRoute($route['route']), (bool) ($route['blank'] ?? false), $route['hide_mobile'] ?? 0);
|
|
||||||
}
|
|
||||||
} elseif (Str::startsWith($routeName, $this->getPageSubPrefix())) {
|
|
||||||
$routes = $this->getPageSubRoutes();
|
|
||||||
foreach ($routes as $route) {
|
|
||||||
$this->addLink($route, $this->equalRoute($route['route']), (bool) ($route['blank'] ?? false), $route['hide_mobile'] ?? 0);
|
|
||||||
}
|
|
||||||
} elseif (Str::startsWith($routeName, $this->getSettingSubPrefix())) {
|
|
||||||
$routes = $this->getSettingSubRoutes();
|
|
||||||
foreach ($routes as $route) {
|
|
||||||
$this->addLink($route, $this->equalRoute($route['route']), (bool) ($route['blank'] ?? false), $route['hide_mobile'] ?? 0);
|
|
||||||
}
|
|
||||||
} elseif (Str::startsWith($routeName, $this->getInquirySubPrefix())) {
|
|
||||||
$routes = $this->getInquirySubRoutes();
|
|
||||||
foreach ($routes as $route) {
|
|
||||||
$this->addLink($route, $this->equalRoute($route['route']), (bool) ($route['blank'] ?? false), $route['hide_mobile'] ?? 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return view('admin::components.sidebar');
|
return view('admin::components.sidebar');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加左侧菜单链接
|
* 返回所有菜单
|
||||||
|
* 小图标地址 https://icons.getbootstrap.com/
|
||||||
*
|
*
|
||||||
* @param $routeData
|
* @return mixed
|
||||||
* @param $active
|
|
||||||
* @param false $newWindow
|
|
||||||
* @param int $hide_mobile
|
|
||||||
*/
|
*/
|
||||||
private function addLink($routeData, $active, bool $newWindow = false, int $hide_mobile = 0)
|
private function getMenus(): mixed
|
||||||
{
|
{
|
||||||
$route = $routeData['route'];
|
$menus = [
|
||||||
$icon = $routeData['icon'] ?? '';
|
[
|
||||||
$title = $routeData['title'] ?? '';
|
'route' => 'home.index',
|
||||||
|
'title' => trans('admin/common.home'),
|
||||||
$permissionRoute = str_replace('.', '_', $route);
|
'icon' => 'bi bi-house',
|
||||||
if ($this->adminUser->cannot($permissionRoute)) {
|
'prefixes' => $this->getHomeSubPrefix(),
|
||||||
return;
|
],
|
||||||
}
|
[
|
||||||
|
'route' => 'orders.index',
|
||||||
if (empty($title)) {
|
'title' => trans('admin/common.order'),
|
||||||
$title = trans("admin/common.{$permissionRoute}");
|
'icon' => 'bi bi-clipboard-check',
|
||||||
}
|
'prefixes' => $this->getOrderSubPrefix(),
|
||||||
$url = admin_route($route);
|
'children' => $this->getOrderSubRoutes(),
|
||||||
$this->links[] = [
|
],
|
||||||
'title' => $title,
|
[
|
||||||
'url' => $url,
|
'route' => 'products.index',
|
||||||
'icon' => $icon,
|
'title' => trans('admin/common.product'),
|
||||||
'active' => $active,
|
'icon' => 'bi bi-box-seam',
|
||||||
'hide_mobile' => $hide_mobile,
|
'prefixes' => $this->getProductSubPrefix(),
|
||||||
'new_window' => $newWindow,
|
'children' => $this->getProductSubRoutes(),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'route' => 'customers.index',
|
||||||
|
'title' => trans('admin/common.customer'),
|
||||||
|
'icon' => 'bi bi-person-circle',
|
||||||
|
'prefixes' => $this->getCustomerSubPrefix(),
|
||||||
|
'children' => $this->getCustomerSubRoutes(),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'route' => 'pages.index',
|
||||||
|
'title' => trans('admin/common.page'),
|
||||||
|
'icon' => 'bi bi-file-earmark-text',
|
||||||
|
'prefixes' => $this->getPageSubPrefix(),
|
||||||
|
'children' => $this->getPageSubRoutes(),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'route' => 'theme.index',
|
||||||
|
'title' => trans('admin/common.design'),
|
||||||
|
'icon' => 'bi bi-palette',
|
||||||
|
'prefixes' => $this->getDesignSubPrefix(),
|
||||||
|
'children' => $this->getDesignSubRoutes(),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'route' => 'plugins.index',
|
||||||
|
'title' => trans('admin/common.plugin'),
|
||||||
|
'icon' => 'bi bi-shop',
|
||||||
|
'prefixes' => $this->getPluginSubPrefix(),
|
||||||
|
'children' => $this->getPluginSubRoutes(),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'route' => 'settings.index',
|
||||||
|
'title' => trans('admin/common.setting'),
|
||||||
|
'icon' => 'bi bi-gear',
|
||||||
|
'prefixes' => $this->getSettingSubPrefix(),
|
||||||
|
'children' => $this->getSettingSubRoutes(),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'route' => 'inquiry.index',
|
||||||
|
'title' => trans('admin/common.inquiry'),
|
||||||
|
'icon' => 'bi bi-gear',
|
||||||
|
'prefixes' => $this->getInquirySubPrefix(),
|
||||||
|
'children' => $this->getInquirySubRoutes(),
|
||||||
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
|
return hook_filter('admin.components.sidebar.menus', $menus);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取二级菜单
|
||||||
|
*
|
||||||
|
* @return array|null
|
||||||
|
*/
|
||||||
|
private function getCurrentLink(): array|null
|
||||||
|
{
|
||||||
|
foreach ($this->links as $link) {
|
||||||
|
$prefixes = $link['prefixes'] ?? [];
|
||||||
|
if ($prefixes && in_array($this->currentPrefix, $prefixes)) {
|
||||||
|
return $link;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理是否选中等数据
|
||||||
|
*/
|
||||||
|
private function handleMenus()
|
||||||
|
{
|
||||||
|
foreach ($this->links as $index => $link) {
|
||||||
|
$prefixes = $link['prefixes'] ?? [];
|
||||||
|
if ($prefixes && in_array($this->currentPrefix, $prefixes)) {
|
||||||
|
$this->links[$index]['active'] = true;
|
||||||
|
} else {
|
||||||
|
$this->links[$index]['active'] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$url = $link['url'] ?? '';
|
||||||
|
if (empty($url)) {
|
||||||
|
$this->links[$index]['url'] = admin_route($link['route']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$title = $link['title'] ?? '';
|
||||||
|
if (empty($title)) {
|
||||||
|
$permissionRoute = str_replace('.', '_', $this->currentRouteName);
|
||||||
|
$this->links[$index]['title'] = trans("admin/common.{$permissionRoute}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! isset($link['blank'])) {
|
||||||
|
$this->links[$index]['blank'] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$icon = $link['icon'] ?? '';
|
||||||
|
if (empty($icon)) {
|
||||||
|
$this->links[$index]['icon'] = 'bi bi-link-45deg';
|
||||||
|
}
|
||||||
|
|
||||||
|
$children = $link['children'] ?? [];
|
||||||
|
if ($children) {
|
||||||
|
foreach ($children as $key => $item) {
|
||||||
|
$childPrefixes = $item['prefixes'] ?? [];
|
||||||
|
$excludes = $item['excludes'] ?? [];
|
||||||
|
if ($prefixes && in_array($this->currentPrefix, $childPrefixes)
|
||||||
|
&& (! $excludes || ! in_array($this->currentRouteName, $excludes))) {
|
||||||
|
$this->links[$index]['children'][$key]['active'] = true;
|
||||||
|
} else {
|
||||||
|
$this->links[$index]['children'][$key]['active'] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$url = $item['url'] ?? '';
|
||||||
|
if (empty($url)) {
|
||||||
|
$this->links[$index]['children'][$key]['url'] = admin_route($item['route']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$title = $item['title'] ?? '';
|
||||||
|
if (empty($title)) {
|
||||||
|
$permissionRoute = str_replace('.', '_', $item['route']);
|
||||||
|
$this->links[$index]['children'][$key]['title'] = trans("admin/common.{$permissionRoute}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! isset($item['blank'])) {
|
||||||
|
$this->links[$index]['children'][$key]['blank'] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -117,7 +215,7 @@ class Sidebar extends Component
|
||||||
*/
|
*/
|
||||||
private function getHomeSubPrefix()
|
private function getHomeSubPrefix()
|
||||||
{
|
{
|
||||||
$prefix = ['home.'];
|
$prefix = ['home'];
|
||||||
|
|
||||||
return hook_filter('admin.sidebar.home.prefix', $prefix);
|
return hook_filter('admin.sidebar.home.prefix', $prefix);
|
||||||
}
|
}
|
||||||
|
|
@ -127,7 +225,7 @@ class Sidebar extends Component
|
||||||
*/
|
*/
|
||||||
private function getProductSubPrefix()
|
private function getProductSubPrefix()
|
||||||
{
|
{
|
||||||
$prefix = ['products.', 'categories.', 'brands.', 'attribute_groups.', 'attributes.'];
|
$prefix = ['products', 'multi_filter', 'categories', 'brands', 'attribute_groups', 'attributes'];
|
||||||
|
|
||||||
return hook_filter('admin.sidebar.product.prefix', $prefix);
|
return hook_filter('admin.sidebar.product.prefix', $prefix);
|
||||||
}
|
}
|
||||||
|
|
@ -137,7 +235,7 @@ class Sidebar extends Component
|
||||||
*/
|
*/
|
||||||
private function getCustomerSubPrefix()
|
private function getCustomerSubPrefix()
|
||||||
{
|
{
|
||||||
$prefix = ['customers.', 'customer_groups.'];
|
$prefix = ['customers', 'customer_groups'];
|
||||||
|
|
||||||
return hook_filter('admin.sidebar.customer.prefix', $prefix);
|
return hook_filter('admin.sidebar.customer.prefix', $prefix);
|
||||||
}
|
}
|
||||||
|
|
@ -147,7 +245,7 @@ class Sidebar extends Component
|
||||||
*/
|
*/
|
||||||
private function getOrderSubPrefix()
|
private function getOrderSubPrefix()
|
||||||
{
|
{
|
||||||
$prefix = ['orders.', 'rmas.', 'rma_reasons.'];
|
$prefix = ['orders', 'rmas', 'rma_reasons'];
|
||||||
|
|
||||||
return hook_filter('admin.sidebar.order.prefix', $prefix);
|
return hook_filter('admin.sidebar.order.prefix', $prefix);
|
||||||
}
|
}
|
||||||
|
|
@ -157,7 +255,7 @@ class Sidebar extends Component
|
||||||
*/
|
*/
|
||||||
private function getPageSubPrefix()
|
private function getPageSubPrefix()
|
||||||
{
|
{
|
||||||
$prefix = ['pages.', 'page_categories.'];
|
$prefix = ['pages', 'page_categories'];
|
||||||
|
|
||||||
return hook_filter('admin.sidebar.page.prefix', $prefix);
|
return hook_filter('admin.sidebar.page.prefix', $prefix);
|
||||||
}
|
}
|
||||||
|
|
@ -172,12 +270,35 @@ class Sidebar extends Component
|
||||||
return hook_filter('admin.sidebar.page.prefix', $prefix);
|
return hook_filter('admin.sidebar.page.prefix', $prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取后台设计子页面路由前缀列表
|
||||||
|
*/
|
||||||
|
private function getDesignSubPrefix()
|
||||||
|
{
|
||||||
|
$prefix = ['theme', 'design_menu'];
|
||||||
|
|
||||||
|
return hook_filter('admin.sidebar.design.prefix', $prefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取后台设计子页面路由前缀列表
|
||||||
|
*/
|
||||||
|
private function getPluginSubPrefix()
|
||||||
|
{
|
||||||
|
$prefix = ['plugins', 'marketing'];
|
||||||
|
|
||||||
|
return hook_filter('admin.sidebar.plugin.prefix', $prefix);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取后台系统设置子页面路由前缀列表
|
* 获取后台系统设置子页面路由前缀列表
|
||||||
*/
|
*/
|
||||||
private function getSettingSubPrefix()
|
private function getSettingSubPrefix()
|
||||||
{
|
{
|
||||||
$prefix = ['settings.', 'admin_users.', 'admin_roles.', 'plugins.', 'theme.', 'marketing.', 'tax_classes', 'tax_rates', 'regions', 'currencies', 'languages', 'design_menu', 'countries', 'zones'];
|
$prefix = [
|
||||||
|
'settings', 'admin_users', 'admin_roles', 'tax_classes', 'tax_rates',
|
||||||
|
'regions', 'currencies', 'languages', 'countries', 'zones', 'account',
|
||||||
|
];
|
||||||
|
|
||||||
return hook_filter('admin.sidebar.setting.prefix', $prefix);
|
return hook_filter('admin.sidebar.setting.prefix', $prefix);
|
||||||
}
|
}
|
||||||
|
|
@ -187,14 +308,7 @@ class Sidebar extends Component
|
||||||
*/
|
*/
|
||||||
public function getHomeSubRoutes()
|
public function getHomeSubRoutes()
|
||||||
{
|
{
|
||||||
$routes = [
|
$routes = [];
|
||||||
['route' => 'design.index', 'icon' => 'fa fa-tachometer-alt', 'blank' => 1, 'hide_mobile' => 1],
|
|
||||||
['route' => 'design_footer.index', 'icon' => 'fa fa-tachometer-alt', 'blank' => 1, 'hide_mobile' => 1],
|
|
||||||
['route' => 'design_menu.index', 'icon' => 'fa fa-tachometer-alt', 'hide_mobile' => 1],
|
|
||||||
['route' => 'languages.index', 'icon' => 'fa fa-tachometer-alt', 'hide_mobile' => 1],
|
|
||||||
['route' => 'currencies.index', 'icon' => 'fa fa-tachometer-alt', 'hide_mobile' => 1],
|
|
||||||
['route' => 'plugins.index', 'icon' => 'fa fa-tachometer-alt', 'hide_mobile' => 1],
|
|
||||||
];
|
|
||||||
|
|
||||||
return hook_filter('admin.sidebar.home_routes', $routes);
|
return hook_filter('admin.sidebar.home_routes', $routes);
|
||||||
}
|
}
|
||||||
|
|
@ -205,12 +319,13 @@ class Sidebar extends Component
|
||||||
public function getProductSubRoutes()
|
public function getProductSubRoutes()
|
||||||
{
|
{
|
||||||
$routes = [
|
$routes = [
|
||||||
['route' => 'categories.index', 'icon' => 'fa fa-tachometer-alt'],
|
['route' => 'products.index', 'prefixes' => ['products'], 'excludes' => ['products.trashed']],
|
||||||
['route' => 'products.index', 'icon' => 'fa fa-tachometer-alt'],
|
['route' => 'categories.index', 'prefixes' => ['categories']],
|
||||||
['route' => 'brands.index', 'icon' => 'fa fa-tachometer-alt', 'hide_mobile' => 1],
|
['route' => 'brands.index', 'prefixes' => ['brands']],
|
||||||
['route' => 'attribute_groups.index', 'icon' => 'fa fa-tachometer-alt'],
|
['route' => 'attribute_groups.index', 'prefixes' => ['attribute_groups']],
|
||||||
['route' => 'attributes.index', 'icon' => 'fa fa-tachometer-alt'],
|
['route' => 'attributes.index', 'prefixes' => ['attributes']],
|
||||||
['route' => 'products.trashed', 'icon' => 'fa fa-tachometer-alt'],
|
['route' => 'multi_filter.index', 'prefixes' => ['multi_filter']],
|
||||||
|
['route' => 'products.trashed', 'prefixes' => ['products'], 'excludes' => ['products.index', 'products.edit']],
|
||||||
];
|
];
|
||||||
|
|
||||||
return hook_filter('admin.sidebar.product_routes', $routes);
|
return hook_filter('admin.sidebar.product_routes', $routes);
|
||||||
|
|
@ -222,9 +337,9 @@ class Sidebar extends Component
|
||||||
public function getCustomerSubRoutes()
|
public function getCustomerSubRoutes()
|
||||||
{
|
{
|
||||||
$routes = [
|
$routes = [
|
||||||
['route' => 'customers.index', 'icon' => 'fa fa-tachometer-alt'],
|
['route' => 'customers.index', 'prefixes' => ['customers'], 'excludes' => ['customers.trashed']],
|
||||||
['route' => 'customer_groups.index', 'icon' => 'fa fa-tachometer-alt'],
|
['route' => 'customer_groups.index', 'prefixes' => ['customer_groups']],
|
||||||
['route' => 'customers.trashed', 'icon' => 'fa fa-tachometer-alt'],
|
['route' => 'customers.trashed', 'prefixes' => ['customers'], 'excludes' => ['customers.index', 'customers.edit']],
|
||||||
];
|
];
|
||||||
|
|
||||||
return hook_filter('admin.sidebar.customer_routes', $routes);
|
return hook_filter('admin.sidebar.customer_routes', $routes);
|
||||||
|
|
@ -236,9 +351,9 @@ class Sidebar extends Component
|
||||||
public function getOrderSubRoutes()
|
public function getOrderSubRoutes()
|
||||||
{
|
{
|
||||||
$routes = [
|
$routes = [
|
||||||
['route' => 'orders.index', 'icon' => 'fa fa-tachometer-alt'],
|
['route' => 'orders.index', 'prefixes' => ['orders']],
|
||||||
['route' => 'rmas.index', 'icon' => 'fa fa-tachometer-alt'],
|
['route' => 'rmas.index', 'prefixes' => ['rmas']],
|
||||||
['route' => 'rma_reasons.index', 'icon' => 'fa fa-tachometer-alt'],
|
['route' => 'rma_reasons.index', 'prefixes' => ['rma_reasons']],
|
||||||
];
|
];
|
||||||
|
|
||||||
return hook_filter('admin.sidebar.order_routes', $routes);
|
return hook_filter('admin.sidebar.order_routes', $routes);
|
||||||
|
|
@ -251,8 +366,8 @@ class Sidebar extends Component
|
||||||
public function getPageSubRoutes()
|
public function getPageSubRoutes()
|
||||||
{
|
{
|
||||||
$routes = [
|
$routes = [
|
||||||
['route' => 'page_categories.index', 'icon' => 'fa fa-tachometer-alt'],
|
['route' => 'pages.index', 'prefixes' => ['pages']],
|
||||||
['route' => 'pages.index', 'icon' => 'fa fa-tachometer-alt'],
|
['route' => 'page_categories.index', 'prefixes' => ['page_categories']],
|
||||||
];
|
];
|
||||||
|
|
||||||
return hook_filter('admin.sidebar.pages_routes', $routes);
|
return hook_filter('admin.sidebar.pages_routes', $routes);
|
||||||
|
|
@ -271,6 +386,46 @@ class Sidebar extends Component
|
||||||
return hook_filter('admin.sidebar.pages_routes', $routes);
|
return hook_filter('admin.sidebar.pages_routes', $routes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取设计子页面路由
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function getDesignSubRoutes()
|
||||||
|
{
|
||||||
|
$routes = [
|
||||||
|
['route' => 'theme.index', 'prefixes' => ['theme'], 'hide_mobile' => true],
|
||||||
|
['route' => 'design_menu.index', 'prefixes' => ['design_menu'], 'hide_mobile' => 1],
|
||||||
|
['route' => 'design.index', 'prefixes' => ['design'], 'blank' => true, 'hide_mobile' => true],
|
||||||
|
['route' => 'design_footer.index', 'prefixes' => ['design_footer'], 'blank' => true, 'hide_mobile' => true],
|
||||||
|
];
|
||||||
|
|
||||||
|
return hook_filter('admin.sidebar.design_routes', $routes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取插件子页面路由
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function getPluginSubRoutes()
|
||||||
|
{
|
||||||
|
$types = collect(Plugin::TYPES);
|
||||||
|
$types = $types->map(function ($item) {
|
||||||
|
return 'plugins.' . $item;
|
||||||
|
});
|
||||||
|
|
||||||
|
$routes[] = ['route' => 'plugins.index', 'prefixes' => ['plugins'], 'excludes' => $types->toArray()];
|
||||||
|
|
||||||
|
$originTypes = $types->push('plugins.index', 'plugins.edit')->push();
|
||||||
|
foreach (Plugin::TYPES as $type) {
|
||||||
|
$types = $originTypes->reject("plugins.{$type}");
|
||||||
|
$routes[] = ['route' => "plugins.{$type}", 'prefixes' => ['plugins'], 'title' => trans("admin/plugin.{$type}"), 'excludes' => $types->toArray()];
|
||||||
|
}
|
||||||
|
|
||||||
|
$routes[] = ['route' => 'marketing.index', 'prefixes' => ['marketing']];
|
||||||
|
|
||||||
|
return hook_filter('admin.sidebar.plugins_routes', $routes);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取系统设置子页面路由
|
* 获取系统设置子页面路由
|
||||||
* @return mixed
|
* @return mixed
|
||||||
|
|
@ -278,36 +433,18 @@ class Sidebar extends Component
|
||||||
public function getSettingSubRoutes()
|
public function getSettingSubRoutes()
|
||||||
{
|
{
|
||||||
$routes = [
|
$routes = [
|
||||||
['route' => 'settings.index', 'icon' => 'fa fa-tachometer-alt'],
|
['route' => 'settings.index', 'prefixes' => ['settings']],
|
||||||
['route' => 'admin_users.index', 'icon' => 'fa fa-tachometer-alt'],
|
['route' => 'account.index', 'prefixes' => ['account']],
|
||||||
['route' => 'plugins.index', 'icon' => 'fa fa-tachometer-alt', 'hide_mobile' => 1],
|
['route' => 'admin_users.index', 'prefixes' => ['admin_users', 'admin_roles']],
|
||||||
['route' => 'theme.index', 'icon' => 'fa fa-tachometer-alt', 'hide_mobile' => 1],
|
['route' => 'regions.index', 'prefixes' => ['regions']],
|
||||||
['route' => 'marketing.index', 'icon' => 'fa fa-tachometer-alt', 'hide_mobile' => 1],
|
['route' => 'tax_rates.index', 'prefixes' => ['tax_rates']],
|
||||||
['route' => 'regions.index', 'icon' => 'fa fa-tachometer-alt'],
|
['route' => 'tax_classes.index', 'prefixes' => ['tax_classes']],
|
||||||
['route' => 'tax_rates.index', 'icon' => 'fa fa-tachometer-alt'],
|
['route' => 'currencies.index', 'prefixes' => ['currencies']],
|
||||||
['route' => 'tax_classes.index', 'icon' => 'fa fa-tachometer-alt'],
|
['route' => 'languages.index', 'prefixes' => ['languages']],
|
||||||
['route' => 'currencies.index', 'icon' => 'fa fa-tachometer-alt'],
|
['route' => 'countries.index', 'prefixes' => ['countries']],
|
||||||
['route' => 'languages.index', 'icon' => 'fa fa-tachometer-alt'],
|
['route' => 'zones.index', 'prefixes' => ['zones']],
|
||||||
['route' => 'countries.index', 'icon' => 'fa fa-tachometer-alt'],
|
|
||||||
['route' => 'zones.index', 'icon' => 'fa fa-tachometer-alt'],
|
|
||||||
['route' => 'design.index', 'icon' => 'fa fa-tachometer-alt', 'blank' => true, 'hide_mobile' => 1],
|
|
||||||
['route' => 'design_footer.index', 'icon' => 'fa fa-tachometer-alt', 'blank' => true, 'hide_mobile' => 1],
|
|
||||||
['route' => 'design_menu.index', 'icon' => 'fa fa-tachometer-alt', 'hide_mobile' => 1],
|
|
||||||
];
|
];
|
||||||
|
|
||||||
return hook_filter('admin.sidebar.setting_routes', $routes);
|
return hook_filter('admin.sidebar.setting_routes', $routes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否为当前访问路由
|
|
||||||
*
|
|
||||||
* @param $routeName
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
private function equalRoute($routeName): bool
|
|
||||||
{
|
|
||||||
$currentRouteName = str_replace($this->adminName . '.', '', $this->routeNameWithPrefix);
|
|
||||||
|
|
||||||
return $routeName == $currentRouteName;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,8 @@
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'api_url' => env('BEIKE_API_URL', 'https://beikeshop.com'),
|
'api_url' => env('BEIKE_API_URL', 'https://beikeshop.com'),
|
||||||
'version' => '1.3.4',
|
'version' => '1.3.8',
|
||||||
'build' => '20230318',
|
'build' => '20230719',
|
||||||
|
|
||||||
'admin_name' => env('ADMIN_NAME'),
|
'admin_name' => env('ADMIN_NAME'),
|
||||||
'force_url_https' => env('APP_FORCE_HTTPS', false),
|
'force_url_https' => env('APP_FORCE_HTTPS', false),
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* CartException.php
|
||||||
|
*
|
||||||
|
* @copyright 2023 beikeshop.com - All Rights Reserved
|
||||||
|
* @link https://beikeshop.com
|
||||||
|
* @author Edward Yang <yangjin@guangda.work>
|
||||||
|
* @created 2023-06-02 17:08:18
|
||||||
|
* @modified 2023-06-02 17:08:18
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Beike\Exceptions;
|
||||||
|
|
||||||
|
class CartException extends \Exception
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* InvalidException.php
|
||||||
|
*
|
||||||
|
* @copyright 2023 beikeshop.com - All Rights Reserved
|
||||||
|
* @link https://beikeshop.com
|
||||||
|
* @author Edward Yang <yangjin@guangda.work>
|
||||||
|
* @created 2023-05-25 14:48:12
|
||||||
|
* @modified 2023-05-25 14:48:12
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Beike\Exceptions;
|
||||||
|
|
||||||
|
class InvalidException extends \Exception
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
@ -11,6 +11,7 @@ use Beike\Repositories\CurrencyRepo;
|
||||||
use Beike\Repositories\LanguageRepo;
|
use Beike\Repositories\LanguageRepo;
|
||||||
use Beike\Services\CurrencyService;
|
use Beike\Services\CurrencyService;
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
use Illuminate\Support\Facades\Session;
|
use Illuminate\Support\Facades\Session;
|
||||||
|
|
@ -209,7 +210,12 @@ function equal_route($routeName): bool
|
||||||
*/
|
*/
|
||||||
function current_user(): ?AdminUser
|
function current_user(): ?AdminUser
|
||||||
{
|
{
|
||||||
return auth()->guard(AdminUser::AUTH_GUARD)->user();
|
$user = auth()->guard(AdminUser::AUTH_GUARD)->user();
|
||||||
|
if (empty($user)) {
|
||||||
|
$user = registry('admin_user');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $user;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -515,25 +521,28 @@ function quantity_format($quantity)
|
||||||
/**
|
/**
|
||||||
* 返回json序列化结果
|
* 返回json序列化结果
|
||||||
*/
|
*/
|
||||||
function json_success($message, $data = []): array
|
function json_success($message, $data = [])
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'status' => 'success',
|
'status' => 'success',
|
||||||
'message' => $message,
|
'message' => $message,
|
||||||
'data' => $data,
|
'data' => $data,
|
||||||
];
|
];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 返回json序列化结果
|
* 返回json序列化结果
|
||||||
*/
|
*/
|
||||||
function json_fail($message, $data = []): array
|
function json_fail($message, $data = [], $status = 422): JsonResponse
|
||||||
{
|
{
|
||||||
return [
|
$data = [
|
||||||
'status' => 'fail',
|
'status' => 'fail',
|
||||||
'message' => $message,
|
'message' => $message,
|
||||||
'data' => $data,
|
'data' => $data,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
return response()->json($data, $status);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! function_exists('sub_string')) {
|
if (! function_exists('sub_string')) {
|
||||||
|
|
@ -768,3 +777,42 @@ function list_sort_by($list, $field, $sortby='asc') {
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $key
|
||||||
|
* @param $value
|
||||||
|
* @param bool $force
|
||||||
|
*/
|
||||||
|
function register($key, $value, bool $force = false)
|
||||||
|
{
|
||||||
|
\Beike\Libraries\Registry::set($key, $value, $force);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $key
|
||||||
|
* @param null $default
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
function registry($key, $default = null): mixed
|
||||||
|
{
|
||||||
|
return \Beike\Libraries\Registry::get($key, $default);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check domain ha license.
|
||||||
|
* 删除版权信息, 请先购买授权 https://beikeshop.com/vip/subscription
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
function check_license(): bool
|
||||||
|
{
|
||||||
|
$configLicenceCode = system_setting('base.license_code');
|
||||||
|
$appDomain = config('app.url');
|
||||||
|
$domain = new \Utopia\Domains\Domain($appDomain);
|
||||||
|
$registerDomain = $domain->getRegisterable();
|
||||||
|
if (empty($registerDomain)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $configLicenceCode == md5(mb_substr(md5($registerDomain), 2, 8));
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,10 +49,10 @@ class Hook
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $hook
|
* @param string $hook
|
||||||
* @param array $params
|
* @param array $params
|
||||||
* @param callable|null $callback
|
* @param callable|null $callback
|
||||||
* @param string $htmlContent
|
* @param string $htmlContent
|
||||||
* @return string|void|null
|
* @return string|void|null
|
||||||
*/
|
*/
|
||||||
public function getHook(string $hook, array $params = [], callable $callback = null, string $htmlContent = '')
|
public function getHook(string $hook, array $params = [], callable $callback = null, string $htmlContent = '')
|
||||||
|
|
@ -64,12 +64,11 @@ class Hook
|
||||||
return $this->get($hook, $params, $callback, $htmlContent);
|
return $this->get($hook, $params, $callback, $htmlContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $hook
|
* @param string $hook
|
||||||
* @param array $params
|
* @param array $params
|
||||||
* @param callable|null $callback
|
* @param callable|null $callback
|
||||||
* @param string $htmlContent
|
* @param string $htmlContent
|
||||||
* @return string|void|null
|
* @return string|void|null
|
||||||
*/
|
*/
|
||||||
public function getWrapper(string $hook, array $params = [], callable $callback = null, string $htmlContent = '')
|
public function getWrapper(string $hook, array $params = [], callable $callback = null, string $htmlContent = '')
|
||||||
|
|
@ -114,11 +113,15 @@ class Hook
|
||||||
$priority = null;
|
$priority = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isset($this->watch[$hook][$priority])) {
|
||||||
|
$priority++;
|
||||||
|
}
|
||||||
|
|
||||||
$this->watch[$hook][$priority] = [
|
$this->watch[$hook][$priority] = [
|
||||||
'function' => $function,
|
'function' => $function,
|
||||||
'caller' => [
|
'caller' => [
|
||||||
//'file' => $caller['file'],
|
'file' => $caller['file'],
|
||||||
//'line' => $caller['line'],
|
'line' => $caller['line'],
|
||||||
'class' => Arr::get($caller, 'class'),
|
'class' => Arr::get($caller, 'class'),
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|
@ -192,7 +195,7 @@ class Hook
|
||||||
* Return a new callback object.
|
* Return a new callback object.
|
||||||
*
|
*
|
||||||
* @param callable $callback function
|
* @param callable $callback function
|
||||||
* @param array $params parameters
|
* @param array $params parameters
|
||||||
*
|
*
|
||||||
* @return Callback
|
* @return Callback
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ namespace Beike\Hook;
|
||||||
use Beike\Hook\Console\HookListeners;
|
use Beike\Hook\Console\HookListeners;
|
||||||
use Illuminate\Support\Facades\Blade;
|
use Illuminate\Support\Facades\Blade;
|
||||||
use Illuminate\Support\ServiceProvider;
|
use Illuminate\Support\ServiceProvider;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
class HookServiceProvider extends ServiceProvider
|
class HookServiceProvider extends ServiceProvider
|
||||||
{
|
{
|
||||||
|
|
@ -19,7 +20,6 @@ class HookServiceProvider extends ServiceProvider
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function boot()
|
public function boot()
|
||||||
{
|
{
|
||||||
$this->bootHookDirectives();
|
$this->bootHookDirectives();
|
||||||
|
|
@ -33,10 +33,11 @@ class HookServiceProvider extends ServiceProvider
|
||||||
protected function bootHookDirectives()
|
protected function bootHookDirectives()
|
||||||
{
|
{
|
||||||
Blade::directive('hook', function ($parameter) {
|
Blade::directive('hook', function ($parameter) {
|
||||||
$parameter = trim($parameter, '()');
|
$parameter = trim($parameter, '()');
|
||||||
$parameters = explode(',', $parameter);
|
$parameters = explode(',', $parameter);
|
||||||
|
|
||||||
$name = trim($parameters[0], "'");
|
$name = trim($parameters[0], "'");
|
||||||
|
$definedVars = $this->parseParameters($parameters);
|
||||||
|
|
||||||
return ' <?php
|
return ' <?php
|
||||||
$__definedVars = (get_defined_vars()["__data"]);
|
$__definedVars = (get_defined_vars()["__data"]);
|
||||||
|
|
@ -44,6 +45,7 @@ class HookServiceProvider extends ServiceProvider
|
||||||
{
|
{
|
||||||
$__definedVars = [];
|
$__definedVars = [];
|
||||||
}
|
}
|
||||||
|
'. $definedVars .'
|
||||||
$output = \Hook::getHook("' . $name . '",["data"=>$__definedVars],function($data) { return null; });
|
$output = \Hook::getHook("' . $name . '",["data"=>$__definedVars],function($data) { return null; });
|
||||||
if ($output)
|
if ($output)
|
||||||
echo $output;
|
echo $output;
|
||||||
|
|
@ -51,7 +53,6 @@ class HookServiceProvider extends ServiceProvider
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加 blade wrapper hook 标签
|
* 添加 blade wrapper hook 标签
|
||||||
*
|
*
|
||||||
|
|
@ -60,9 +61,9 @@ class HookServiceProvider extends ServiceProvider
|
||||||
protected function bootWrapperHookDirectives()
|
protected function bootWrapperHookDirectives()
|
||||||
{
|
{
|
||||||
Blade::directive('hookwrapper', function ($parameter) {
|
Blade::directive('hookwrapper', function ($parameter) {
|
||||||
$parameter = trim($parameter, '()');
|
$parameter = trim($parameter, '()');
|
||||||
$parameters = explode(',', $parameter);
|
$parameters = explode(',', $parameter);
|
||||||
$name = trim($parameters[0], "'");
|
$name = trim($parameters[0], "'");
|
||||||
|
|
||||||
return ' <?php
|
return ' <?php
|
||||||
$__hook_name="' . $name . '";
|
$__hook_name="' . $name . '";
|
||||||
|
|
@ -86,4 +87,23 @@ class HookServiceProvider extends ServiceProvider
|
||||||
?>';
|
?>';
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse parameters from Blade
|
||||||
|
*
|
||||||
|
* @param $parameters
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function parseParameters($parameters):string
|
||||||
|
{
|
||||||
|
$definedVars = '';
|
||||||
|
foreach ($parameters as $paraItem) {
|
||||||
|
$paraItem = trim($paraItem);
|
||||||
|
if (Str::startsWith($paraItem,'$')) {
|
||||||
|
$paraKey = trim($paraItem, '$');
|
||||||
|
$definedVars .= '$__definedVars["'.$paraKey.'"] = $'.$paraKey.';';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $definedVars;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Beike\Installer\Controllers;
|
||||||
|
|
||||||
|
use Illuminate\Routing\Controller;
|
||||||
|
|
||||||
|
class BaseController extends Controller
|
||||||
|
{
|
||||||
|
protected function checkInstalled()
|
||||||
|
{
|
||||||
|
if (installed()) {
|
||||||
|
exit('Already installed');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -5,11 +5,10 @@ namespace Beike\Installer\Controllers;
|
||||||
use Beike\Admin\Repositories\AdminUserRepo;
|
use Beike\Admin\Repositories\AdminUserRepo;
|
||||||
use Beike\Installer\Helpers\DatabaseManager;
|
use Beike\Installer\Helpers\DatabaseManager;
|
||||||
use Illuminate\Http\RedirectResponse;
|
use Illuminate\Http\RedirectResponse;
|
||||||
use Illuminate\Routing\Controller;
|
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Facades\Schema;
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
class DatabaseController extends Controller
|
class DatabaseController extends BaseController
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var DatabaseManager
|
* @var DatabaseManager
|
||||||
|
|
@ -31,6 +30,7 @@ class DatabaseController extends Controller
|
||||||
*/
|
*/
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
|
$this->checkInstalled();
|
||||||
DB::statement('SET FOREIGN_KEY_CHECKS = 0');
|
DB::statement('SET FOREIGN_KEY_CHECKS = 0');
|
||||||
$rows = DB::select('SHOW TABLES');
|
$rows = DB::select('SHOW TABLES');
|
||||||
$database = config('database.connections.mysql.database');
|
$database = config('database.connections.mysql.database');
|
||||||
|
|
|
||||||
|
|
@ -3,14 +3,14 @@
|
||||||
namespace Beike\Installer\Controllers;
|
namespace Beike\Installer\Controllers;
|
||||||
|
|
||||||
use Beike\Installer\Helpers\EnvironmentManager;
|
use Beike\Installer\Helpers\EnvironmentManager;
|
||||||
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Http\RedirectResponse;
|
use Illuminate\Http\RedirectResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Routing\Controller;
|
|
||||||
use Illuminate\Routing\Redirector;
|
use Illuminate\Routing\Redirector;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Facades\Validator;
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
|
||||||
class EnvironmentController extends Controller
|
class EnvironmentController extends BaseController
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var EnvironmentManager
|
* @var EnvironmentManager
|
||||||
|
|
@ -32,6 +32,7 @@ class EnvironmentController extends Controller
|
||||||
*/
|
*/
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
|
$this->checkInstalled();
|
||||||
$steps = 4;
|
$steps = 4;
|
||||||
|
|
||||||
return view('installer::environment-wizard', compact('steps'));
|
return view('installer::environment-wizard', compact('steps'));
|
||||||
|
|
@ -46,6 +47,7 @@ class EnvironmentController extends Controller
|
||||||
*/
|
*/
|
||||||
public function saveWizard(Request $request, Redirector $redirect): RedirectResponse
|
public function saveWizard(Request $request, Redirector $redirect): RedirectResponse
|
||||||
{
|
{
|
||||||
|
$this->checkInstalled();
|
||||||
$rules = config('installer.environment.form.rules');
|
$rules = config('installer.environment.form.rules');
|
||||||
$messages = [
|
$messages = [
|
||||||
'environment_custom.required_if' => trans('installer::installer_messages.environment.name_required'),
|
'environment_custom.required_if' => trans('installer::installer_messages.environment.name_required'),
|
||||||
|
|
@ -74,10 +76,11 @@ class EnvironmentController extends Controller
|
||||||
* 数据库信息检测
|
* 数据库信息检测
|
||||||
*
|
*
|
||||||
* @param Request $request
|
* @param Request $request
|
||||||
* @return array
|
* @return JsonResponse|array
|
||||||
*/
|
*/
|
||||||
public function validateDatabase(Request $request): array
|
public function validateDatabase(Request $request): JsonResponse|array
|
||||||
{
|
{
|
||||||
|
$this->checkInstalled();
|
||||||
$rules = config('installer.environment.form.rules');
|
$rules = config('installer.environment.form.rules');
|
||||||
$messages = [
|
$messages = [
|
||||||
'environment_custom.required_if' => trans('installer::installer_messages.environment.name_required'),
|
'environment_custom.required_if' => trans('installer::installer_messages.environment.name_required'),
|
||||||
|
|
@ -108,6 +111,7 @@ class EnvironmentController extends Controller
|
||||||
*/
|
*/
|
||||||
private function checkDatabaseConnection(Request $request): bool|array
|
private function checkDatabaseConnection(Request $request): bool|array
|
||||||
{
|
{
|
||||||
|
$this->checkInstalled();
|
||||||
$connection = $request->input('database_connection');
|
$connection = $request->input('database_connection');
|
||||||
|
|
||||||
$settings = config("database.connections.$connection");
|
$settings = config("database.connections.$connection");
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,8 @@ namespace Beike\Installer\Controllers;
|
||||||
use Beike\Installer\Helpers\EnvironmentManager;
|
use Beike\Installer\Helpers\EnvironmentManager;
|
||||||
use Beike\Installer\Helpers\FinalInstallManager;
|
use Beike\Installer\Helpers\FinalInstallManager;
|
||||||
use Beike\Installer\Helpers\InstalledFileManager;
|
use Beike\Installer\Helpers\InstalledFileManager;
|
||||||
use Illuminate\Routing\Controller;
|
|
||||||
|
|
||||||
class FinalController extends Controller
|
class FinalController extends BaseController
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Update installed file and display finished view.
|
* Update installed file and display finished view.
|
||||||
|
|
@ -19,6 +18,8 @@ class FinalController extends Controller
|
||||||
*/
|
*/
|
||||||
public function index(InstalledFileManager $fileManager, FinalInstallManager $finalInstall, EnvironmentManager $environment)
|
public function index(InstalledFileManager $fileManager, FinalInstallManager $finalInstall, EnvironmentManager $environment)
|
||||||
{
|
{
|
||||||
|
$this->checkInstalled();
|
||||||
|
|
||||||
$finalMessages = $finalInstall->runFinal();
|
$finalMessages = $finalInstall->runFinal();
|
||||||
$finalStatusMessage = $fileManager->update();
|
$finalStatusMessage = $fileManager->update();
|
||||||
$finalEnvFile = $environment->getEnvContent();
|
$finalEnvFile = $environment->getEnvContent();
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,8 @@
|
||||||
namespace Beike\Installer\Controllers;
|
namespace Beike\Installer\Controllers;
|
||||||
|
|
||||||
use Beike\Installer\Helpers\PermissionsChecker;
|
use Beike\Installer\Helpers\PermissionsChecker;
|
||||||
use Illuminate\Routing\Controller;
|
|
||||||
|
|
||||||
class PermissionsController extends Controller
|
class PermissionsController extends BaseController
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var PermissionsChecker
|
* @var PermissionsChecker
|
||||||
|
|
@ -27,6 +26,7 @@ class PermissionsController extends Controller
|
||||||
*/
|
*/
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
|
$this->checkInstalled();
|
||||||
$permissions = $this->permissions->check(
|
$permissions = $this->permissions->check(
|
||||||
config('installer.permissions')
|
config('installer.permissions')
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,8 @@
|
||||||
namespace Beike\Installer\Controllers;
|
namespace Beike\Installer\Controllers;
|
||||||
|
|
||||||
use Beike\Installer\Helpers\RequirementsChecker;
|
use Beike\Installer\Helpers\RequirementsChecker;
|
||||||
use Illuminate\Routing\Controller;
|
|
||||||
|
|
||||||
class RequirementsController extends Controller
|
class RequirementsController extends BaseController
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var RequirementsChecker
|
* @var RequirementsChecker
|
||||||
|
|
@ -27,6 +26,7 @@ class RequirementsController extends Controller
|
||||||
*/
|
*/
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
|
$this->checkInstalled();
|
||||||
$phpSupportInfo = $this->requirements->checkPHPversion(
|
$phpSupportInfo = $this->requirements->checkPHPversion(
|
||||||
config('installer.core.minPhpVersion')
|
config('installer.core.minPhpVersion')
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,9 @@
|
||||||
|
|
||||||
namespace Beike\Installer\Controllers;
|
namespace Beike\Installer\Controllers;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use Illuminate\Support\Facades\Redirect;
|
use Illuminate\Support\Facades\Redirect;
|
||||||
|
|
||||||
class WelcomeController extends Controller
|
class WelcomeController extends BaseController
|
||||||
{
|
{
|
||||||
private $languages = [
|
private $languages = [
|
||||||
'zh_cn' => '简体中文',
|
'zh_cn' => '简体中文',
|
||||||
|
|
@ -23,10 +22,7 @@ class WelcomeController extends Controller
|
||||||
|
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
if (installed()) {
|
$this->checkInstalled();
|
||||||
exit('Already installed');
|
|
||||||
}
|
|
||||||
|
|
||||||
$data['languages'] = $this->languages;
|
$data['languages'] = $this->languages;
|
||||||
$data['locale'] = $_COOKIE['locale'] ?? 'zh_cn';
|
$data['locale'] = $_COOKIE['locale'] ?? 'zh_cn';
|
||||||
$data['steps'] = 1;
|
$data['steps'] = 1;
|
||||||
|
|
|
||||||
|
|
@ -230,29 +230,27 @@
|
||||||
$('.database-loading').addClass('d-none');
|
$('.database-loading').addClass('d-none');
|
||||||
},
|
},
|
||||||
success: function(json) {
|
success: function(json) {
|
||||||
if (json.status == 'fail') {
|
$('.database-link-wrap input').addClass('is-valid')
|
||||||
var data = Object.keys(json.data);
|
$('.title-status .text-success').removeClass('d-none')
|
||||||
|
$('.admin-data-wrap').removeClass('d-none')
|
||||||
|
},
|
||||||
|
error: function(json) {
|
||||||
|
json = json.responseJSON;
|
||||||
|
var data = Object.keys(json.data);
|
||||||
|
|
||||||
data.forEach((e)=> {
|
data.forEach((e)=> {
|
||||||
$('.database-link-wrap input[name="' + e + '"]').addClass('is-invalid').next('.invalid-feedback').text(json.data[e])
|
$('.database-link-wrap input[name="' + e + '"]').addClass('is-invalid').next('.invalid-feedback').text(json.data[e])
|
||||||
})
|
})
|
||||||
|
|
||||||
if (json.data.database_version) {
|
if (json.data.database_version) {
|
||||||
$('.title-status .text-danger').removeClass('d-none').find('span').text(json.data.database_version);
|
$('.title-status .text-danger').removeClass('d-none').find('span').text(json.data.database_version);
|
||||||
}
|
|
||||||
|
|
||||||
if (json.data.database_other) {
|
|
||||||
$('.title-status .text-danger').removeClass('d-none').find('span').text(json.data.database_other);
|
|
||||||
}
|
|
||||||
|
|
||||||
$('.admin-data-wrap').addClass('d-none')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (json.status == 'success') {
|
if (json.data.database_other) {
|
||||||
$('.database-link-wrap input').addClass('is-valid')
|
$('.title-status .text-danger').removeClass('d-none').find('span').text(json.data.database_other);
|
||||||
$('.title-status .text-success').removeClass('d-none')
|
|
||||||
$('.admin-data-wrap').removeClass('d-none')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$('.admin-data-wrap').addClass('d-none')
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,7 @@
|
||||||
<script src="{{ asset('vendor/jquery/jquery-3.6.0.min.js') }}"></script>
|
<script src="{{ asset('vendor/jquery/jquery-3.6.0.min.js') }}"></script>
|
||||||
<script src="{{ asset('vendor/layer/3.5.1/layer.js') }}"></script>
|
<script src="{{ asset('vendor/layer/3.5.1/layer.js') }}"></script>
|
||||||
<link rel="shortcut icon" href="{{ asset('/image/favicon.png') }}">
|
<link rel="shortcut icon" href="{{ asset('/image/favicon.png') }}">
|
||||||
{{-- <script src="{{ asset('vendor/bootstrap/5.1.3/js/bootstrap.min.js') }}"></script> --}}
|
<script src="{{ asset('vendor/bootstrap/js/bootstrap.bundle.min.js') }}"></script>
|
||||||
<script src="{{ asset('vendor/bootstrap/5.1.3/js/bootstrap.bundle.min.js') }}"></script>
|
|
||||||
<link rel="stylesheet" type="text/css" href="{{ asset('/install/css/app.css') }}">
|
<link rel="stylesheet" type="text/css" href="{{ asset('/install/css/app.css') }}">
|
||||||
@yield('style')
|
@yield('style')
|
||||||
</head>
|
</head>
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,8 @@
|
||||||
$primary: #fd560f;
|
$primary: #fd560f;
|
||||||
|
|
||||||
body {
|
body {
|
||||||
|
background-color: #f3f6f8;
|
||||||
|
|
||||||
.install-box {
|
.install-box {
|
||||||
background-color: #f3f6f8;
|
background-color: #f3f6f8;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
@ -45,6 +47,10 @@ body {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.table {
|
||||||
|
--bs-table-bg: transparent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@import "steps";
|
@import "steps";
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,9 @@ return [
|
||||||
'PDO',
|
'PDO',
|
||||||
'Tokenizer',
|
'Tokenizer',
|
||||||
'XML',
|
'XML',
|
||||||
|
'ZIP',
|
||||||
|
'GD',
|
||||||
|
'PDO_MYSQL',
|
||||||
],
|
],
|
||||||
'apache' => [
|
'apache' => [
|
||||||
'mod_rewrite',
|
'mod_rewrite',
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,84 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Registry.php
|
||||||
|
*
|
||||||
|
* @copyright 2023 beikeshop.com - All Rights Reserved
|
||||||
|
* @link https://beikeshop.com
|
||||||
|
* @author Edward Yang <yangjin@guangda.work>
|
||||||
|
* @created 2023-04-20 16:29:54
|
||||||
|
* @modified 2023-04-20 16:29:54
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Beike\Libraries;
|
||||||
|
|
||||||
|
class Registry
|
||||||
|
{
|
||||||
|
private array $data = [];
|
||||||
|
|
||||||
|
private static $registry;
|
||||||
|
|
||||||
|
public static function getSingleton(): self
|
||||||
|
{
|
||||||
|
if (self::$registry instanceof self) {
|
||||||
|
return self::$registry;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$registry = new self();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $key
|
||||||
|
* @param null $default
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public static function get($key, $default = null): mixed
|
||||||
|
{
|
||||||
|
return self::getSingleton()->getValue($key, $default);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $key
|
||||||
|
* @param $value
|
||||||
|
* @param bool $force
|
||||||
|
*/
|
||||||
|
public static function set($key, $value, bool $force = false)
|
||||||
|
{
|
||||||
|
if (self::getSingleton()->has($key) && ! $force) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self::getSingleton()->setValue($key, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function destroy()
|
||||||
|
{
|
||||||
|
self::$registry = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $key
|
||||||
|
* @param null $default
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function getValue($key, $default = null): mixed
|
||||||
|
{
|
||||||
|
return $this->data[$key] ?? $default;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $key
|
||||||
|
* @param $value
|
||||||
|
*/
|
||||||
|
public function setValue($key, $value)
|
||||||
|
{
|
||||||
|
$this->data[$key] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $key
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function has($key): bool
|
||||||
|
{
|
||||||
|
return isset($this->data[$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -65,7 +65,7 @@ class Url
|
||||||
return $value->url ?? '';
|
return $value->url ?? '';
|
||||||
} elseif ($type == 'page') {
|
} elseif ($type == 'page') {
|
||||||
if (! $value instanceof \Beike\Models\Page) {
|
if (! $value instanceof \Beike\Models\Page) {
|
||||||
$value = \Beike\Models\Page::query()->find($value);
|
$value = \Beike\Models\Page::query()->where('active', 1)->find($value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $value->url ?? '';
|
return $value->url ?? '';
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Weight.php
|
||||||
|
*
|
||||||
|
* @copyright 2023 beikeshop.com - All Rights Reserved
|
||||||
|
* @link https://beikeshop.com
|
||||||
|
* @author TL <mengwb@guangda.work>
|
||||||
|
* @created 2023-03-21 16:29:54
|
||||||
|
* @modified 2023-03-21 16:29:54
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Beike\Libraries;
|
||||||
|
|
||||||
|
class Weight
|
||||||
|
{
|
||||||
|
public const WEIGHT_CLASS = [
|
||||||
|
'kg' => 0.001,
|
||||||
|
'g' => 1,
|
||||||
|
'oz' => 0.035,
|
||||||
|
'lb' => 0.0022046,
|
||||||
|
];
|
||||||
|
|
||||||
|
public const DEFAULT_CLASS = 'g';
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getWeightUnits(): array
|
||||||
|
{
|
||||||
|
return array_keys(self::WEIGHT_CLASS);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function convert($weight, $from, $to = '')
|
||||||
|
{
|
||||||
|
if (! $to) {
|
||||||
|
$to = self::DEFAULT_CLASS;
|
||||||
|
}
|
||||||
|
if (empty($weight)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $weight * self::WEIGHT_CLASS[$to] / self::WEIGHT_CLASS[$from];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,11 +4,13 @@ namespace Beike\Models;
|
||||||
|
|
||||||
use Beike\Notifications\AdminForgottenNotification;
|
use Beike\Notifications\AdminForgottenNotification;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
use Illuminate\Foundation\Auth\User as AuthUser;
|
use Illuminate\Foundation\Auth\User as AuthUser;
|
||||||
use Illuminate\Notifications\Notifiable;
|
use Illuminate\Notifications\Notifiable;
|
||||||
use Spatie\Permission\Traits\HasRoles;
|
use Spatie\Permission\Traits\HasRoles;
|
||||||
|
use Tymon\JWTAuth\Contracts\JWTSubject;
|
||||||
|
|
||||||
class AdminUser extends AuthUser
|
class AdminUser extends AuthUser implements JWTSubject
|
||||||
{
|
{
|
||||||
use HasFactory, HasRoles;
|
use HasFactory, HasRoles;
|
||||||
use Notifiable;
|
use Notifiable;
|
||||||
|
|
@ -17,6 +19,11 @@ class AdminUser extends AuthUser
|
||||||
|
|
||||||
protected $fillable = ['name', 'email', 'locale', 'password', 'active'];
|
protected $fillable = ['name', 'email', 'locale', 'password', 'active'];
|
||||||
|
|
||||||
|
public function tokens(): HasMany
|
||||||
|
{
|
||||||
|
return $this->hasMany(AdminUserToken::class);
|
||||||
|
}
|
||||||
|
|
||||||
public function notifyVerifyCodeForForgotten($code)
|
public function notifyVerifyCodeForForgotten($code)
|
||||||
{
|
{
|
||||||
$useQueue = system_setting('base.use_queue', true);
|
$useQueue = system_setting('base.use_queue', true);
|
||||||
|
|
@ -26,4 +33,24 @@ class AdminUser extends AuthUser
|
||||||
$this->notifyNow(new AdminForgottenNotification($this, $code));
|
$this->notifyNow(new AdminForgottenNotification($this, $code));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the identifier that will be stored in the subject claim of the JWT.
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function getJWTIdentifier()
|
||||||
|
{
|
||||||
|
return $this->getKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a key value array, containing any custom claims to be added to the JWT.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getJWTCustomClaims()
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* AdminUserToken.php
|
||||||
|
*
|
||||||
|
* @copyright 2023 beikeshop.com - All Rights Reserved
|
||||||
|
* @link https://beikeshop.com
|
||||||
|
* @author Edward Yang <yangjin@guangda.work>
|
||||||
|
* @created 2023-04-20 10:18:56
|
||||||
|
* @modified 2023-04-20 10:18:56
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Beike\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
|
||||||
|
class AdminUserToken extends Base
|
||||||
|
{
|
||||||
|
protected $fillable = ['admin_user_id', 'token'];
|
||||||
|
|
||||||
|
public function adminUser(): BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo(AdminUser::class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -11,8 +11,9 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||||
use Illuminate\Notifications\Notifiable;
|
use Illuminate\Notifications\Notifiable;
|
||||||
|
use Tymon\JWTAuth\Contracts\JWTSubject;
|
||||||
|
|
||||||
class Customer extends Authenticatable
|
class Customer extends Authenticatable implements JWTSubject
|
||||||
{
|
{
|
||||||
use HasFactory;
|
use HasFactory;
|
||||||
use SoftDeletes;
|
use SoftDeletes;
|
||||||
|
|
@ -66,4 +67,24 @@ class Customer extends Authenticatable
|
||||||
$this->notifyNow(new ForgottenNotification($this, $code));
|
$this->notifyNow(new ForgottenNotification($this, $code));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the identifier that will be stored in the subject claim of the JWT.
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function getJWTIdentifier()
|
||||||
|
{
|
||||||
|
return $this->getKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a key value array, containing any custom claims to be added to the JWT.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getJWTCustomClaims()
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,11 @@ class Order extends Base
|
||||||
return $this->hasMany(OrderShipment::class);
|
return $this->hasMany(OrderShipment::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function orderPayments(): HasMany
|
||||||
|
{
|
||||||
|
return $this->hasMany(OrderPayment::class);
|
||||||
|
}
|
||||||
|
|
||||||
public function subTotal()
|
public function subTotal()
|
||||||
{
|
{
|
||||||
$totals = $this->orderTotals;
|
$totals = $this->orderTotals;
|
||||||
|
|
@ -68,7 +73,9 @@ class Order extends Base
|
||||||
|
|
||||||
public function getStatusFormatAttribute()
|
public function getStatusFormatAttribute()
|
||||||
{
|
{
|
||||||
return trans('order.' . $this->status);
|
$statusMap = array_column(StateMachineService::getAllStatuses(), 'name', 'status');
|
||||||
|
|
||||||
|
return $statusMap[$this->status];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTotalFormatAttribute()
|
public function getTotalFormatAttribute()
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,8 @@
|
||||||
|
|
||||||
namespace Beike\Models;
|
namespace Beike\Models;
|
||||||
|
|
||||||
|
use Beike\Services\StateMachineService;
|
||||||
|
|
||||||
class OrderHistory extends Base
|
class OrderHistory extends Base
|
||||||
{
|
{
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
|
|
@ -21,6 +23,8 @@ class OrderHistory extends Base
|
||||||
|
|
||||||
public function getStatusFormatAttribute()
|
public function getStatusFormatAttribute()
|
||||||
{
|
{
|
||||||
return trans("order.{$this->status}");
|
$statusMap = array_column(StateMachineService::getAllStatuses(), 'name', 'status');
|
||||||
|
|
||||||
|
return $statusMap[$this->status];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* OrderPayment.php
|
||||||
|
*
|
||||||
|
* @copyright 2023 beikeshop.com - All Rights Reserved
|
||||||
|
* @link https://beikeshop.com
|
||||||
|
* @author Edward Yang <yangjin@guangda.work>
|
||||||
|
* @created 2023-05-25 10:02:52
|
||||||
|
* @modified 2023-05-25 10:02:52
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Beike\Models;
|
||||||
|
|
||||||
|
class OrderPayment extends Base
|
||||||
|
{
|
||||||
|
protected $table = 'order_payments';
|
||||||
|
|
||||||
|
protected $fillable = [
|
||||||
|
'order_id', 'transaction_id', 'request', 'response', 'callback', 'receipt',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
@ -11,12 +11,11 @@
|
||||||
|
|
||||||
namespace Beike\Models;
|
namespace Beike\Models;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||||
|
|
||||||
class PageCategory extends Model
|
class PageCategory extends Base
|
||||||
{
|
{
|
||||||
protected $table = 'page_categories';
|
protected $table = 'page_categories';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,7 @@
|
||||||
|
|
||||||
namespace Beike\Models;
|
namespace Beike\Models;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
class PageCategoryDescription extends Base
|
||||||
|
|
||||||
class PageCategoryDescription extends Model
|
|
||||||
{
|
{
|
||||||
protected $table = 'page_category_descriptions';
|
protected $table = 'page_category_descriptions';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,9 @@
|
||||||
|
|
||||||
namespace Beike\Models;
|
namespace Beike\Models;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
|
||||||
class PageProduct extends Model
|
class PageProduct extends Base
|
||||||
{
|
{
|
||||||
protected $table = 'page_products';
|
protected $table = 'page_products';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ class Product extends Base
|
||||||
use HasFactory;
|
use HasFactory;
|
||||||
use SoftDeletes;
|
use SoftDeletes;
|
||||||
|
|
||||||
protected $fillable = ['images', 'video', 'position', 'brand_id', 'tax_class_id', 'active', 'variables', 'price_setting'];
|
protected $fillable = ['images', 'video', 'position', 'brand_id', 'tax_class_id', 'weight', 'weight_class', 'active', 'variables', 'price_setting'];
|
||||||
|
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
'active' => 'boolean',
|
'active' => 'boolean',
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,11 @@ class ProductSku extends Base
|
||||||
$product = $this->product;
|
$product = $this->product;
|
||||||
$localeCode = locale();
|
$localeCode = locale();
|
||||||
$variantLabel = '';
|
$variantLabel = '';
|
||||||
|
|
||||||
|
if(empty($product->variables)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($product->variables as $index => $variable) {
|
foreach ($product->variables as $index => $variable) {
|
||||||
$valueIndex = $this->variants[$index];
|
$valueIndex = $this->variants[$index];
|
||||||
$variantName = $variable['name'][$localeCode] ?? '';
|
$variantName = $variable['name'][$localeCode] ?? '';
|
||||||
|
|
|
||||||
|
|
@ -21,13 +21,13 @@ use Illuminate\Support\Str;
|
||||||
class Plugin implements Arrayable, \ArrayAccess
|
class Plugin implements Arrayable, \ArrayAccess
|
||||||
{
|
{
|
||||||
public const TYPES = [
|
public const TYPES = [
|
||||||
'shipping', // 配送方式
|
|
||||||
'payment', // 支付方式
|
'payment', // 支付方式
|
||||||
|
'shipping', // 配送方式
|
||||||
|
'theme', // 主题模板
|
||||||
|
'feature', // 功能模块
|
||||||
'total', // 订单金额
|
'total', // 订单金额
|
||||||
'social', // 社交网络
|
'social', // 社交网络
|
||||||
'feature', // 功能模块
|
|
||||||
'language', // 语言翻译
|
'language', // 语言翻译
|
||||||
'theme', // 主题模板
|
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $type;
|
protected $type;
|
||||||
|
|
@ -171,6 +171,13 @@ class Plugin implements Arrayable, \ArrayAccess
|
||||||
$item['label'] = trans($languageKey);
|
$item['label'] = trans($languageKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$descriptionKey = $item['description_key'] ?? '';
|
||||||
|
$description = $item['description'] ?? '';
|
||||||
|
if (empty($description) && $descriptionKey) {
|
||||||
|
$languageKey = "{$this->dirName}::{$descriptionKey}";
|
||||||
|
$item['description'] = trans($languageKey);
|
||||||
|
}
|
||||||
|
|
||||||
return $item;
|
return $item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,82 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* AdminUserTokenRepo.php
|
||||||
|
*
|
||||||
|
* @copyright 2023 beikeshop.com - All Rights Reserved
|
||||||
|
* @link https://beikeshop.com
|
||||||
|
* @author Edward Yang <yangjin@guangda.work>
|
||||||
|
* @created 2023-04-20 10:21:25
|
||||||
|
* @modified 2023-04-20 10:21:25
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Beike\Repositories;
|
||||||
|
|
||||||
|
use Beike\Models\AdminUser;
|
||||||
|
use Beike\Models\AdminUserToken;
|
||||||
|
|
||||||
|
class AdminUserTokenRepo
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param $adminUser
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public static function getTokenByAdminUser($adminUser)
|
||||||
|
{
|
||||||
|
$adminUserId = self::getAdminUserId($adminUser);
|
||||||
|
if (empty($adminUserId)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return AdminUserToken::query()->where('admin_user_id', $adminUserId)->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $token
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public static function getAdminUserTokenByToken($token)
|
||||||
|
{
|
||||||
|
return AdminUserToken::query()->where('token', $token)->first();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $adminUser
|
||||||
|
* @param $tokens
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function updateTokensByUser($adminUser, $tokens)
|
||||||
|
{
|
||||||
|
$adminUserId = self::getAdminUserId($adminUser);
|
||||||
|
if (empty($adminUserId)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AdminUserToken::query()->where('admin_user_id', $adminUserId)->delete();
|
||||||
|
if (empty($tokens)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($tokens as $token) {
|
||||||
|
AdminUserToken::query()->create([
|
||||||
|
'admin_user_id' => $adminUserId,
|
||||||
|
'token' => $token,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $adminUser
|
||||||
|
* @return int|mixed
|
||||||
|
*/
|
||||||
|
private static function getAdminUserId($adminUser)
|
||||||
|
{
|
||||||
|
$adminUserId = 0;
|
||||||
|
if ($adminUser instanceof AdminUser) {
|
||||||
|
$adminUserId = $adminUser->id;
|
||||||
|
} elseif (is_int($adminUser)) {
|
||||||
|
$adminUserId = $adminUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $adminUserId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -55,14 +55,18 @@ class CategoryRepo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function flatten(string $locale, $separator = ' > '): array
|
public static function flatten(string $locale, $includeInactive = true, $separator = ' > '): array
|
||||||
{
|
{
|
||||||
$sql = "SELECT cp.category_id AS id, TRIM(LOWER(GROUP_CONCAT(cd1.name ORDER BY cp.level SEPARATOR '{$separator}'))) AS name, c1.parent_id, c1.position";
|
$sql = "SELECT cp.category_id AS id, TRIM(LOWER(GROUP_CONCAT(cd1.name ORDER BY cp.level SEPARATOR '{$separator}'))) AS name, c1.parent_id, c1.position";
|
||||||
$sql .= ' FROM category_paths cp';
|
$sql .= ' FROM category_paths cp';
|
||||||
$sql .= ' LEFT JOIN categories c1 ON (cp.category_id = c1.id)';
|
$sql .= ' LEFT JOIN categories c1 ON (cp.category_id = c1.id)';
|
||||||
$sql .= ' LEFT JOIN categories c2 ON (cp.path_id = c2.id)';
|
$sql .= ' LEFT JOIN categories c2 ON (cp.path_id = c2.id)';
|
||||||
$sql .= ' LEFT JOIN category_descriptions cd1 ON (cp.path_id = cd1.category_id)';
|
$sql .= ' LEFT JOIN category_descriptions cd1 ON (cp.path_id = cd1.category_id)';
|
||||||
$sql .= " WHERE cd1.locale = '" . $locale . "' GROUP BY cp.category_id ORDER BY name ASC";
|
$sql .= " WHERE cd1.locale = '" . $locale . "' ";
|
||||||
|
if (! $includeInactive) {
|
||||||
|
$sql .= ' AND c1.active = 1 ';
|
||||||
|
}
|
||||||
|
$sql .= ' GROUP BY cp.category_id ORDER BY c1.position ASC';
|
||||||
|
|
||||||
return DB::select($sql);
|
return DB::select($sql);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -98,6 +98,6 @@ class LanguageRepo
|
||||||
*/
|
*/
|
||||||
public static function enabled()
|
public static function enabled()
|
||||||
{
|
{
|
||||||
return Language::query()->where('status', true)->get();
|
return Language::query()->where('status', true)->orderBy('sort_order', 'asc')->get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* OrderPaymentRepo.php
|
||||||
|
*
|
||||||
|
* @copyright 2023 beikeshop.com - All Rights Reserved
|
||||||
|
* @link https://beikeshop.com
|
||||||
|
* @author Edward Yang <yangjin@guangda.work>
|
||||||
|
* @created 2023-05-25 10:02:39
|
||||||
|
* @modified 2023-05-25 10:02:39
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Beike\Repositories;
|
||||||
|
|
||||||
|
use Beike\Models\OrderPayment;
|
||||||
|
|
||||||
|
class OrderPaymentRepo
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param $orderId
|
||||||
|
* @param $data
|
||||||
|
* @return mixed
|
||||||
|
* @throws \Throwable
|
||||||
|
*/
|
||||||
|
public static function createOrUpdatePayment($orderId, $data): mixed
|
||||||
|
{
|
||||||
|
$orderId = (int) $orderId;
|
||||||
|
if (empty($orderId) || empty($data)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$orderPayment = OrderPayment::query()->where('order_id', $orderId)->first();
|
||||||
|
if (empty($orderPayment)) {
|
||||||
|
$orderPayment = new OrderPayment();
|
||||||
|
}
|
||||||
|
|
||||||
|
$paymentData = [
|
||||||
|
'order_id' => $orderId,
|
||||||
|
];
|
||||||
|
|
||||||
|
if (isset($data['transaction_id'])) {
|
||||||
|
$paymentData['transaction_id'] = $data['transaction_id'];
|
||||||
|
}
|
||||||
|
if (isset($data['request'])) {
|
||||||
|
$paymentData['request'] = json_encode($data['request'] ?? []);
|
||||||
|
}
|
||||||
|
if (isset($data['response'])) {
|
||||||
|
$paymentData['response'] = json_encode($data['response'] ?? []);
|
||||||
|
}
|
||||||
|
if (isset($data['callback'])) {
|
||||||
|
$paymentData['callback'] = json_encode($data['callback'] ?? []);
|
||||||
|
}
|
||||||
|
if (isset($data['receipt'])) {
|
||||||
|
$paymentData['receipt'] = $data['receipt'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$orderPayment->fill($paymentData);
|
||||||
|
$orderPayment->saveOrFail();
|
||||||
|
|
||||||
|
return $orderPayment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -31,7 +31,7 @@ class OrderRepo
|
||||||
*/
|
*/
|
||||||
public static function filterAll(array $filters = [])
|
public static function filterAll(array $filters = [])
|
||||||
{
|
{
|
||||||
$builder = self::getListBuilder($filters)->orderByDesc('created_at');
|
$builder = static::getListBuilder($filters)->orderByDesc('created_at');
|
||||||
|
|
||||||
return $builder->get();
|
return $builder->get();
|
||||||
}
|
}
|
||||||
|
|
@ -44,7 +44,7 @@ class OrderRepo
|
||||||
*/
|
*/
|
||||||
public static function getListByCustomer($customer): LengthAwarePaginator
|
public static function getListByCustomer($customer): LengthAwarePaginator
|
||||||
{
|
{
|
||||||
$builder = self::getListBuilder(['customer' => $customer])->orderByDesc('created_at');
|
$builder = static::getListBuilder(['customer' => $customer])->orderByDesc('created_at');
|
||||||
|
|
||||||
return $builder->paginate(perPage());
|
return $builder->paginate(perPage());
|
||||||
}
|
}
|
||||||
|
|
@ -56,7 +56,7 @@ class OrderRepo
|
||||||
*/
|
*/
|
||||||
public static function getLatestOrders($customer, $limit)
|
public static function getLatestOrders($customer, $limit)
|
||||||
{
|
{
|
||||||
return self::getListBuilder(['customer' => $customer])
|
return static::getListBuilder(['customer' => $customer])
|
||||||
->orderByDesc('created_at')
|
->orderByDesc('created_at')
|
||||||
->take($limit)
|
->take($limit)
|
||||||
->get();
|
->get();
|
||||||
|
|
@ -68,7 +68,7 @@ class OrderRepo
|
||||||
*/
|
*/
|
||||||
public static function filterOrders(array $filters = []): LengthAwarePaginator
|
public static function filterOrders(array $filters = []): LengthAwarePaginator
|
||||||
{
|
{
|
||||||
$builder = self::getListBuilder($filters)->orderByDesc('created_at');
|
$builder = static::getListBuilder($filters)->orderByDesc('created_at');
|
||||||
|
|
||||||
return $builder->paginate(perPage());
|
return $builder->paginate(perPage());
|
||||||
}
|
}
|
||||||
|
|
@ -79,7 +79,7 @@ class OrderRepo
|
||||||
*/
|
*/
|
||||||
public static function getListBuilder(array $filters = []): Builder
|
public static function getListBuilder(array $filters = []): Builder
|
||||||
{
|
{
|
||||||
$builder = Order::query()->with(['orderProducts']);
|
$builder = Order::query()->with(['orderProducts'])->where('status', '<>', StateMachineService::CREATED);
|
||||||
|
|
||||||
$number = $filters['number'] ?? 0;
|
$number = $filters['number'] ?? 0;
|
||||||
if ($number) {
|
if ($number) {
|
||||||
|
|
@ -199,14 +199,12 @@ class OrderRepo
|
||||||
|
|
||||||
$shippingAddress = Address::query()->findOrFail($shippingAddressId);
|
$shippingAddress = Address::query()->findOrFail($shippingAddressId);
|
||||||
$paymentAddress = Address::query()->findOrFail($paymentAddressId);
|
$paymentAddress = Address::query()->findOrFail($paymentAddressId);
|
||||||
|
$email = $customer->email;
|
||||||
$email = $customer->email;
|
|
||||||
} else {
|
} else {
|
||||||
$shippingAddress = new Address($current['guest_shipping_address'] ?? []);
|
$shippingAddress = new Address($current['guest_shipping_address'] ?? []);
|
||||||
$paymentAddress = new Address($current['guest_payment_address'] ?? []);
|
$paymentAddress = new Address($current['guest_payment_address'] ?? []);
|
||||||
$email = $current['guest_shipping_address']['email'];
|
$email = $current['guest_shipping_address']['email'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$shippingAddress->country = $shippingAddress->country->name ?? '';
|
$shippingAddress->country = $shippingAddress->country->name ?? '';
|
||||||
$shippingAddress->country_id = $shippingAddress->country->id ?? 0;
|
$shippingAddress->country_id = $shippingAddress->country->id ?? 0;
|
||||||
$paymentAddress->country = $paymentAddress->country->name ?? '';
|
$paymentAddress->country = $paymentAddress->country->name ?? '';
|
||||||
|
|
@ -268,6 +266,8 @@ class OrderRepo
|
||||||
OrderProductRepo::createOrderProducts($order, $carts['carts']);
|
OrderProductRepo::createOrderProducts($order, $carts['carts']);
|
||||||
OrderTotalRepo::createTotals($order, $totals);
|
OrderTotalRepo::createTotals($order, $totals);
|
||||||
|
|
||||||
|
hook_filter('repository.order.create.after', ['order' => $order, 'data' => $data]);
|
||||||
|
|
||||||
return $order;
|
return $order;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,12 +31,16 @@ class PageCategoryRepo
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $filters
|
* @param array $filters
|
||||||
* @return LengthAwarePaginator
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public static function getActiveList(array $filters = []): LengthAwarePaginator
|
public static function getActiveList(array $filters = []): mixed
|
||||||
{
|
{
|
||||||
$filters['is_active'] = 1;
|
$filters['is_active'] = 1;
|
||||||
|
$limit = (int) ($filters['limit'] ?? 0);
|
||||||
$builder = self::getBuilder($filters);
|
$builder = self::getBuilder($filters);
|
||||||
|
if ($limit > 0) {
|
||||||
|
return $builder->limit($limit)->get();
|
||||||
|
}
|
||||||
|
|
||||||
return $builder->paginate(perPage());
|
return $builder->paginate(perPage());
|
||||||
}
|
}
|
||||||
|
|
@ -150,11 +154,20 @@ class PageCategoryRepo
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $page
|
* @param $pageCategory
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function getName($page)
|
public static function getName($pageCategory): string
|
||||||
{
|
{
|
||||||
return $page->description->title ?? '';
|
if ($pageCategory instanceof PageCategory) {
|
||||||
|
return $pageCategory->description->title ?? '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$pageCategoryId = (int) $pageCategory;
|
||||||
|
$pageCategory = PageCategory::query()->whereHas('description', function ($query) use ($pageCategoryId) {
|
||||||
|
$query->where('page_category_id', $pageCategoryId);
|
||||||
|
})->first();
|
||||||
|
|
||||||
|
return $pageCategory->description->title ?? '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -189,20 +189,6 @@ class PluginRepo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get plugin by code
|
|
||||||
*
|
|
||||||
* @param $code
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
public static function getPlugin($code): mixed
|
|
||||||
{
|
|
||||||
$code = Str::camel($code);
|
|
||||||
$plugins = self::getPluginsByCode();
|
|
||||||
|
|
||||||
return $plugins->get($code);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断插件是否安装
|
* 判断插件是否安装
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ class ProductRepo
|
||||||
*/
|
*/
|
||||||
public static function getProductsByCategory($categoryId, $filterData)
|
public static function getProductsByCategory($categoryId, $filterData)
|
||||||
{
|
{
|
||||||
$builder = self::getBuilder(array_merge(['category_id' => $categoryId, 'active' => 1], $filterData));
|
$builder = static::getBuilder(array_merge(['category_id' => $categoryId, 'active' => 1], $filterData));
|
||||||
|
|
||||||
return $builder->with('inCurrentWishlist')
|
return $builder->with('inCurrentWishlist')
|
||||||
->paginate($filterData['per_page'] ?? perPage())
|
->paginate($filterData['per_page'] ?? perPage())
|
||||||
|
|
@ -72,7 +72,7 @@ class ProductRepo
|
||||||
if (! $productIds) {
|
if (! $productIds) {
|
||||||
return ProductSimple::collection(new Collection());
|
return ProductSimple::collection(new Collection());
|
||||||
}
|
}
|
||||||
$builder = self::getBuilder(['product_ids' => $productIds])->whereHas('masterSku');
|
$builder = static::getBuilder(['product_ids' => $productIds])->whereHas('masterSku');
|
||||||
$products = $builder->with('inCurrentWishlist')->get();
|
$products = $builder->with('inCurrentWishlist')->get();
|
||||||
|
|
||||||
return ProductSimple::collection($products);
|
return ProductSimple::collection($products);
|
||||||
|
|
@ -81,10 +81,11 @@ class ProductRepo
|
||||||
/**
|
/**
|
||||||
* 获取商品筛选对象
|
* 获取商品筛选对象
|
||||||
*
|
*
|
||||||
* @param array $data
|
* @param array $filters
|
||||||
* @return Builder
|
* @return Builder
|
||||||
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public static function getBuilder(array $data = []): Builder
|
public static function getBuilder(array $filters = []): Builder
|
||||||
{
|
{
|
||||||
$builder = Product::query()->with('description', 'skus', 'masterSku', 'attributes');
|
$builder = Product::query()->with('description', 'skus', 'masterSku', 'attributes');
|
||||||
|
|
||||||
|
|
@ -99,26 +100,26 @@ class ProductRepo
|
||||||
});
|
});
|
||||||
$builder->select(['products.*', 'pd.name', 'pd.content', 'pd.meta_title', 'pd.meta_description', 'pd.meta_keywords', 'pd.name', 'product_skus.price']);
|
$builder->select(['products.*', 'pd.name', 'pd.content', 'pd.meta_title', 'pd.meta_description', 'pd.meta_keywords', 'pd.name', 'product_skus.price']);
|
||||||
|
|
||||||
if (isset($data['category_id'])) {
|
if (isset($filters['category_id'])) {
|
||||||
$builder->whereHas('categories', function ($query) use ($data) {
|
$builder->whereHas('categories', function ($query) use ($filters) {
|
||||||
if (is_array($data['category_id'])) {
|
if (is_array($filters['category_id'])) {
|
||||||
$query->whereIn('category_id', $data['category_id']);
|
$query->whereIn('category_id', $filters['category_id']);
|
||||||
} else {
|
} else {
|
||||||
$query->where('category_id', $data['category_id']);
|
$query->where('category_id', $filters['category_id']);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
$productIds = $data['product_ids'] ?? [];
|
$productIds = $filters['product_ids'] ?? [];
|
||||||
if ($productIds) {
|
if ($productIds) {
|
||||||
$builder->whereIn('products.id', $productIds);
|
$builder->whereIn('products.id', $productIds);
|
||||||
$productIds = implode(',', $productIds);
|
$productIds = implode(',', $productIds);
|
||||||
$builder->orderByRaw("FIELD(products.id, {$productIds})");
|
$builder->orderByRaw("FIELD(products.id, {$productIds})");
|
||||||
}
|
}
|
||||||
|
|
||||||
// attr 格式:attr=10:10/13|11:34/23|3:4
|
// attr 格式:attr=10:10,13|11:34,23|3:4
|
||||||
if (isset($data['attr']) && $data['attr']) {
|
if (isset($filters['attr']) && $filters['attr']) {
|
||||||
$attributes = self::parseFilterParamsAttr($data['attr']);
|
$attributes = self::parseFilterParamsAttr($filters['attr']);
|
||||||
foreach ($attributes as $attribute) {
|
foreach ($attributes as $attribute) {
|
||||||
$builder->whereHas('attributes', function ($query) use ($attribute) {
|
$builder->whereHas('attributes', function ($query) use ($attribute) {
|
||||||
$query->where('attribute_id', $attribute['attr'])
|
$query->where('attribute_id', $attribute['attr'])
|
||||||
|
|
@ -127,21 +128,21 @@ class ProductRepo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($data['sku']) || isset($data['model'])) {
|
if (isset($filters['sku']) || isset($filters['model'])) {
|
||||||
$builder->whereHas('skus', function ($query) use ($data) {
|
$builder->whereHas('skus', function ($query) use ($filters) {
|
||||||
if (isset($data['sku'])) {
|
if (isset($filters['sku'])) {
|
||||||
$query->where('sku', 'like', "%{$data['sku']}%");
|
$query->where('sku', 'like', "%{$filters['sku']}%");
|
||||||
}
|
}
|
||||||
if (isset($data['model'])) {
|
if (isset($filters['model'])) {
|
||||||
$query->where('model', 'like', "%{$data['model']}%");
|
$query->where('model', 'like', "%{$filters['model']}%");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($data['price']) && $data['price']) {
|
if (isset($filters['price']) && $filters['price']) {
|
||||||
$builder->whereHas('skus', function ($query) use ($data) {
|
$builder->whereHas('skus', function ($query) use ($filters) {
|
||||||
// price 格式:price=30-100
|
// price 格式:price=30-100
|
||||||
$prices = explode('-', $data['price']);
|
$prices = explode('-', $filters['price']);
|
||||||
if (! $prices[1]) {
|
if (! $prices[1]) {
|
||||||
$query->where('price', '>', $prices[0] ?: 0)->where('is_default', 1);
|
$query->where('price', '>', $prices[0] ?: 0)->where('is_default', 1);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -150,34 +151,54 @@ class ProductRepo
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($data['name'])) {
|
if (isset($filters['name'])) {
|
||||||
$builder->where('pd.name', 'like', "%{$data['name']}%");
|
$builder->where('pd.name', 'like', "%{$filters['name']}%");
|
||||||
}
|
}
|
||||||
|
|
||||||
$keyword = $data['keyword'] ?? '';
|
$keyword = trim($filters['keyword'] ?? '');
|
||||||
if ($keyword) {
|
if ($keyword) {
|
||||||
$builder->where(function (Builder $query) use ($keyword) {
|
$keywords = explode(' ', $keyword);
|
||||||
$query->whereHas('skus', function (Builder $query) use ($keyword) {
|
$keywords = array_unique($keywords);
|
||||||
$query->where('sku', 'like', "%{$keyword}%")
|
$keywords = array_diff($keywords, ['']);
|
||||||
->orWhere('model', 'like', "%{$keyword}%");
|
$builder->where(function (Builder $query) use ($keywords) {
|
||||||
})->orWhere('pd.name', 'like', "%{$keyword}%");
|
$query->whereHas('skus', function (Builder $query) use ($keywords) {
|
||||||
|
$keywordFirst = array_shift($keywords);
|
||||||
|
$query->where('sku', 'like', "%{$keywordFirst}%")
|
||||||
|
->orWhere('model', 'like', "%{$keywordFirst}%");
|
||||||
|
|
||||||
|
foreach ($keywords as $keyword) {
|
||||||
|
$query->orWhere('sku', 'like', "%{$keyword}%")
|
||||||
|
->orWhere('model', 'like', "%{$keyword}%");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
foreach ($keywords as $keyword) {
|
||||||
|
$query->orWhere('pd.name', 'like', "%{$keyword}%");
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($data['active'])) {
|
if (isset($filters['created_start'])) {
|
||||||
$builder->where('active', (int) $data['active']);
|
$builder->where('products.created_at', '>', $filters['created_start']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($filters['created_end'])) {
|
||||||
|
$builder->where('products.created_at', '>', $filters['created_end']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($filters['active'])) {
|
||||||
|
$builder->where('active', (int) $filters['active']);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 回收站
|
// 回收站
|
||||||
if (isset($data['trashed']) && $data['trashed']) {
|
if (isset($filters['trashed']) && $filters['trashed']) {
|
||||||
$builder->onlyTrashed();
|
$builder->onlyTrashed();
|
||||||
}
|
}
|
||||||
|
|
||||||
$sort = $data['sort'] ?? 'products.position';
|
$sort = $filters['sort'] ?? 'products.position';
|
||||||
$order = $data['order'] ?? 'desc';
|
$order = $filters['order'] ?? 'desc';
|
||||||
$builder->orderBy($sort, $order);
|
$builder->orderBy($sort, $order);
|
||||||
|
|
||||||
return $builder;
|
return hook_filter('repo.product.builder', $builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function parseFilterParamsAttr($attr)
|
public static function parseFilterParamsAttr($attr)
|
||||||
|
|
@ -191,7 +212,7 @@ class ProductRepo
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'attr' => $itemArr[0],
|
'attr' => $itemArr[0],
|
||||||
'value' => explode('/', $itemArr[1]),
|
'value' => explode(',', $itemArr[1]),
|
||||||
];
|
];
|
||||||
}, $attributes);
|
}, $attributes);
|
||||||
|
|
||||||
|
|
@ -200,13 +221,18 @@ class ProductRepo
|
||||||
|
|
||||||
public static function getFilterAttribute($data): array
|
public static function getFilterAttribute($data): array
|
||||||
{
|
{
|
||||||
$builder = self::getBuilder($data)
|
$builder = static::getBuilder(array_diff_key($data, ['attr' => '', 'price' => '']))
|
||||||
->select(['pa.attribute_id', 'pa.attribute_value_id'])
|
->select(['pa.attribute_id', 'pa.attribute_value_id'])
|
||||||
->with(['attributes.attribute.description', 'attributes.attribute_value.description'])
|
->with(['attributes.attribute.description', 'attributes.attribute_value.description'])
|
||||||
->leftJoin('product_attributes as pa', 'pa.product_id', 'products.id')
|
->leftJoin('product_attributes as pa', 'pa.product_id', 'products.id')
|
||||||
->whereNotNull('pa.attribute_id')
|
->whereNotNull('pa.attribute_id')
|
||||||
->distinct()
|
->distinct()
|
||||||
->reorder('pa.attribute_id');
|
->reorder('pa.attribute_id');
|
||||||
|
|
||||||
|
if ($attributesIds = system_setting('base.multi_filter', [])['attribute'] ?? []) {
|
||||||
|
$builder->whereIn('pa.attribute_id', $attributesIds);
|
||||||
|
}
|
||||||
|
|
||||||
$productAttributes = $builder->get()->toArray();
|
$productAttributes = $builder->get()->toArray();
|
||||||
|
|
||||||
$attributeMap = array_column(Attribute::query()->with('description')->orderBy('sort_order')->get()->toArray(), null, 'id');
|
$attributeMap = array_column(Attribute::query()->with('description')->orderBy('sort_order')->get()->toArray(), null, 'id');
|
||||||
|
|
@ -249,7 +275,7 @@ class ProductRepo
|
||||||
{
|
{
|
||||||
$selectPrice = $data['price'] ?? '-';
|
$selectPrice = $data['price'] ?? '-';
|
||||||
// unset($data['price']);
|
// unset($data['price']);
|
||||||
$builder = self::getBuilder(['category_id' => $data['category_id']])->leftJoin('product_skus as ps', 'products.id', 'ps.product_id')
|
$builder = static::getBuilder(['category_id' => $data['category_id']])->leftJoin('product_skus as ps', 'products.id', 'ps.product_id')
|
||||||
->where('ps.is_default', 1);
|
->where('ps.is_default', 1);
|
||||||
$min = $builder->min('ps.price');
|
$min = $builder->min('ps.price');
|
||||||
$max = $builder->max('ps.price');
|
$max = $builder->max('ps.price');
|
||||||
|
|
@ -268,7 +294,7 @@ class ProductRepo
|
||||||
|
|
||||||
public static function list($data = [])
|
public static function list($data = [])
|
||||||
{
|
{
|
||||||
return self::getBuilder($data)->paginate($data['per_page'] ?? 20);
|
return static::getBuilder($data)->paginate($data['per_page'] ?? 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function autocomplete($name)
|
public static function autocomplete($name)
|
||||||
|
|
@ -328,7 +354,7 @@ class ProductRepo
|
||||||
}
|
}
|
||||||
|
|
||||||
$items = [];
|
$items = [];
|
||||||
$products = self::getBuilder()->select('id')->get();
|
$products = static::getBuilder()->select('id')->get();
|
||||||
foreach ($products as $product) {
|
foreach ($products as $product) {
|
||||||
$items[$product->id] = [
|
$items[$product->id] = [
|
||||||
'id' => $product->id,
|
'id' => $product->id,
|
||||||
|
|
|
||||||
|
|
@ -95,9 +95,9 @@ class RmaRepo
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $data
|
* @param $data
|
||||||
* @return LengthAwarePaginator
|
* @return Builder
|
||||||
*/
|
*/
|
||||||
public static function list($data): LengthAwarePaginator
|
public static function getBuilder($data): Builder
|
||||||
{
|
{
|
||||||
$builder = Rma::query();
|
$builder = Rma::query();
|
||||||
|
|
||||||
|
|
@ -124,7 +124,16 @@ class RmaRepo
|
||||||
}
|
}
|
||||||
$builder->orderBy('id', 'DESC');
|
$builder->orderBy('id', 'DESC');
|
||||||
|
|
||||||
return $builder->paginate(perPage())->withQueryString();
|
return $builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $data
|
||||||
|
* @return LengthAwarePaginator
|
||||||
|
*/
|
||||||
|
public static function list($data): LengthAwarePaginator
|
||||||
|
{
|
||||||
|
return self::getBuilder($data)->paginate(perPage())->withQueryString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ namespace Beike\Repositories;
|
||||||
|
|
||||||
use Beike\Models\Setting;
|
use Beike\Models\Setting;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
|
use Illuminate\Support\Facades\Artisan;
|
||||||
|
|
||||||
class SettingRepo
|
class SettingRepo
|
||||||
{
|
{
|
||||||
|
|
@ -117,6 +118,7 @@ class SettingRepo
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
Setting::query()->insert($rows);
|
Setting::query()->insert($rows);
|
||||||
|
self::clearCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -154,5 +156,17 @@ class SettingRepo
|
||||||
} else {
|
} else {
|
||||||
$setting->update($settingData);
|
$setting->update($settingData);
|
||||||
}
|
}
|
||||||
|
self::clearCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear all cache.
|
||||||
|
*/
|
||||||
|
public static function clearCache()
|
||||||
|
{
|
||||||
|
Artisan::call('cache:clear');
|
||||||
|
Artisan::call('config:clear');
|
||||||
|
Artisan::call('view:clear');
|
||||||
|
Artisan::call('optimize:clear');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,12 +42,17 @@ class CurrencyService
|
||||||
return $amount;
|
return $amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
$symbol_left = $this->currencies[$currency]->symbol_left;
|
$currencyRow = $this->currencies[$currency] ?? null;
|
||||||
$symbol_right = $this->currencies[$currency]->symbol_right;
|
if (empty($currencyRow)) {
|
||||||
$decimal_place = $this->currencies[$currency]->decimal_place;
|
return $amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
$symbol_left = $currencyRow->symbol_left;
|
||||||
|
$symbol_right = $currencyRow->symbol_right;
|
||||||
|
$decimal_place = $currencyRow->decimal_place;
|
||||||
|
|
||||||
if (! $value) {
|
if (! $value) {
|
||||||
$value = $this->currencies[$currency]->value;
|
$value = $currencyRow->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
$amount = $value ? (float) $amount * $value : (float) $amount;
|
$amount = $value ? (float) $amount * $value : (float) $amount;
|
||||||
|
|
@ -70,7 +75,7 @@ class CurrencyService
|
||||||
$string .= number_format(abs($amount), (int) $decimal_place, __('currency.decimal_point'), __('currency.thousand_point'));
|
$string .= number_format(abs($amount), (int) $decimal_place, __('currency.decimal_point'), __('currency.thousand_point'));
|
||||||
|
|
||||||
if ($symbol_right) {
|
if ($symbol_right) {
|
||||||
$string .= $symbol_right;
|
$string .= ' ' . $symbol_right;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $string;
|
return $string;
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ class DesignService
|
||||||
return self::handleRichText($content);
|
return self::handleRichText($content);
|
||||||
}
|
}
|
||||||
|
|
||||||
return hook_filter('admin.service.design.module.content', $content);
|
return hook_filter('service.design.module.content', $content);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ class ImageService
|
||||||
|
|
||||||
private $imagePath;
|
private $imagePath;
|
||||||
|
|
||||||
public const PLACEHOLDER_IMAGE = 'catalog/placeholder.png';
|
private $placeholderImage = 'catalog/placeholder.png';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $image
|
* @param $image
|
||||||
|
|
@ -28,8 +28,9 @@ class ImageService
|
||||||
*/
|
*/
|
||||||
public function __construct($image)
|
public function __construct($image)
|
||||||
{
|
{
|
||||||
$this->image = $image ?: self::PLACEHOLDER_IMAGE;
|
$this->placeholderImage = system_setting('base.placeholder');
|
||||||
$this->imagePath = public_path($this->image);
|
$this->image = $image ?: $this->placeholderImage;
|
||||||
|
$this->imagePath = public_path($this->image);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -40,7 +41,7 @@ class ImageService
|
||||||
public function setPluginDirName($dirName): static
|
public function setPluginDirName($dirName): static
|
||||||
{
|
{
|
||||||
$originImage = $this->image;
|
$originImage = $this->image;
|
||||||
if ($this->image == self::PLACEHOLDER_IMAGE) {
|
if ($this->image == $this->placeholderImage) {
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -48,7 +49,7 @@ class ImageService
|
||||||
if (file_exists($this->imagePath)) {
|
if (file_exists($this->imagePath)) {
|
||||||
$this->image = strtolower('plugin/' . $dirName . $originImage);
|
$this->image = strtolower('plugin/' . $dirName . $originImage);
|
||||||
} else {
|
} else {
|
||||||
$this->image = self::PLACEHOLDER_IMAGE;
|
$this->image = $this->placeholderImage;
|
||||||
$this->imagePath = public_path($this->image);
|
$this->imagePath = public_path($this->image);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -65,7 +66,7 @@ class ImageService
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
if (! file_exists($this->imagePath)) {
|
if (! file_exists($this->imagePath)) {
|
||||||
$this->image = self::PLACEHOLDER_IMAGE;
|
$this->image = $this->placeholderImage;
|
||||||
$this->imagePath = public_path($this->image);
|
$this->imagePath = public_path($this->image);
|
||||||
}
|
}
|
||||||
if (! file_exists($this->imagePath)) {
|
if (! file_exists($this->imagePath)) {
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ use Beike\Models\Order;
|
||||||
use Beike\Models\OrderHistory;
|
use Beike\Models\OrderHistory;
|
||||||
use Beike\Models\OrderShipment;
|
use Beike\Models\OrderShipment;
|
||||||
use Beike\Models\Product;
|
use Beike\Models\Product;
|
||||||
|
use Beike\Repositories\OrderPaymentRepo;
|
||||||
use Throwable;
|
use Throwable;
|
||||||
|
|
||||||
class StateMachineService
|
class StateMachineService
|
||||||
|
|
@ -29,6 +30,8 @@ class StateMachineService
|
||||||
|
|
||||||
private array $shipment;
|
private array $shipment;
|
||||||
|
|
||||||
|
private array $payment;
|
||||||
|
|
||||||
public const CREATED = 'created'; // 已创建
|
public const CREATED = 'created'; // 已创建
|
||||||
|
|
||||||
public const UNPAID = 'unpaid'; // 待支付
|
public const UNPAID = 'unpaid'; // 待支付
|
||||||
|
|
@ -116,6 +119,19 @@ class StateMachineService
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置支付信息
|
||||||
|
*
|
||||||
|
* @param array $payment
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function setPayment(array $payment = []): self
|
||||||
|
{
|
||||||
|
$this->payment = $payment;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取所有订单状态列表
|
* 获取所有订单状态列表
|
||||||
*
|
*
|
||||||
|
|
@ -136,7 +152,25 @@ class StateMachineService
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result;
|
return hook_filter('service.state_machine.all_statuses', $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有有效订单状态
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
|
public static function getValidStatuses(): array
|
||||||
|
{
|
||||||
|
$statuses = [
|
||||||
|
self::CREATED,
|
||||||
|
self::UNPAID,
|
||||||
|
self::PAID,
|
||||||
|
self::SHIPPED,
|
||||||
|
self::COMPLETED,
|
||||||
|
self::CANCELLED,
|
||||||
|
];
|
||||||
|
|
||||||
|
return $statuses;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -198,6 +232,8 @@ class StateMachineService
|
||||||
}
|
}
|
||||||
$this->{$function}($oldStatusCode, $status);
|
$this->{$function}($oldStatusCode, $status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hook_filter('service.state_machine.change_status.after', ['order' => $order, 'status' => $status, 'comment' => $comment, 'notify' => $notify]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -208,11 +244,6 @@ class StateMachineService
|
||||||
*/
|
*/
|
||||||
private function validStatusCode($statusCode)
|
private function validStatusCode($statusCode)
|
||||||
{
|
{
|
||||||
if (! in_array($statusCode, self::ORDER_STATUS)) {
|
|
||||||
$statusCodeString = implode(', ', self::ORDER_STATUS);
|
|
||||||
|
|
||||||
throw new \Exception("Invalid order status, must be one of the '{$statusCodeString}'");
|
|
||||||
}
|
|
||||||
$orderId = $this->orderId;
|
$orderId = $this->orderId;
|
||||||
$orderNumber = $this->order->number;
|
$orderNumber = $this->order->number;
|
||||||
$currentStatusCode = $this->order->status;
|
$currentStatusCode = $this->order->status;
|
||||||
|
|
@ -340,6 +371,18 @@ class StateMachineService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加发货单号
|
||||||
|
* @throws Throwable
|
||||||
|
*/
|
||||||
|
private function addPayment($oldCode, $newCode)
|
||||||
|
{
|
||||||
|
if (empty($this->payment)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
OrderPaymentRepo::createOrUpdatePayment($this->orderId, $this->payment);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发送新订单通知
|
* 发送新订单通知
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ class AddressController extends Controller
|
||||||
{
|
{
|
||||||
$addresses = AddressRepo::listByCustomer(current_customer());
|
$addresses = AddressRepo::listByCustomer(current_customer());
|
||||||
$data = [
|
$data = [
|
||||||
'countries' => CountryRepo::all(),
|
'countries' => CountryRepo::listEnabled(),
|
||||||
'addresses' => AddressResource::collection($addresses),
|
'addresses' => AddressResource::collection($addresses),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ class EditController extends Controller
|
||||||
{
|
{
|
||||||
$customer = current_customer();
|
$customer = current_customer();
|
||||||
$data['customer'] = $customer;
|
$data['customer'] = $customer;
|
||||||
|
$data = hook_filter('account.edit.index', $data);
|
||||||
|
|
||||||
return view('account/edit', $data);
|
return view('account/edit', $data);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,20 +35,30 @@ class LoginController extends Controller
|
||||||
|
|
||||||
public function store(LoginRequest $request)
|
public function store(LoginRequest $request)
|
||||||
{
|
{
|
||||||
$guestCartProduct = CartRepo::allCartProducts(0);
|
$data = [
|
||||||
if (! auth(Customer::AUTH_GUARD)->attempt($request->only('email', 'password'))) {
|
'request_data' => $request->all(),
|
||||||
throw new NotAcceptableHttpException(trans('shop/login.email_or_password_error'));
|
];
|
||||||
|
|
||||||
|
try {
|
||||||
|
hook_action('shop.account.login.before', $data);
|
||||||
|
|
||||||
|
$guestCartProduct = CartRepo::allCartProducts(0);
|
||||||
|
if (! auth(Customer::AUTH_GUARD)->attempt($request->only('email', 'password'))) {
|
||||||
|
throw new NotAcceptableHttpException(trans('shop/login.email_or_password_error'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$customer = current_customer();
|
||||||
|
if ($customer && $customer->status != 1) {
|
||||||
|
Auth::guard(Customer::AUTH_GUARD)->logout();
|
||||||
|
|
||||||
|
throw new NotFoundHttpException(trans('shop/login.customer_inactive'));
|
||||||
|
}
|
||||||
|
|
||||||
|
CartRepo::mergeGuestCart($customer, $guestCartProduct);
|
||||||
|
|
||||||
|
return json_success(trans('shop/login.login_successfully'));
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return json_fail($e->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
$customer = current_customer();
|
|
||||||
if ($customer && $customer->status != 1) {
|
|
||||||
Auth::guard(Customer::AUTH_GUARD)->logout();
|
|
||||||
|
|
||||||
throw new NotFoundHttpException(trans('shop/login.customer_inactive'));
|
|
||||||
}
|
|
||||||
|
|
||||||
CartRepo::mergeGuestCart($customer, $guestCartProduct);
|
|
||||||
|
|
||||||
return json_success(trans('shop/login.login_successfully'));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -57,21 +57,6 @@ class OrderController extends Controller
|
||||||
return view('account/order_info', $data);
|
return view('account/order_info', $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 订单提交成功页
|
|
||||||
*
|
|
||||||
* @param Request $request
|
|
||||||
* @param $number
|
|
||||||
* @return View
|
|
||||||
*/
|
|
||||||
public function success(Request $request, $number): View
|
|
||||||
{
|
|
||||||
$customer = current_customer();
|
|
||||||
$order = OrderRepo::getOrderByNumber($number, $customer);
|
|
||||||
|
|
||||||
return view('account/order_success', ['order' => $order]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 订单支付页面
|
* 订单支付页面
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -86,15 +86,15 @@ class CartController extends Controller
|
||||||
public function update(CartRequest $request, $cartId): array
|
public function update(CartRequest $request, $cartId): array
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$customer = current_customer();
|
$customer = current_customer();
|
||||||
$quantity = (int) $request->get('quantity');
|
$quantity = (int) $request->get('quantity');
|
||||||
CartService::updateQuantity($customer, $cartId, $quantity);
|
CartService::updateQuantity($customer, $cartId, $quantity);
|
||||||
|
|
||||||
$data = CartService::reloadData();
|
$data = CartService::reloadData();
|
||||||
|
|
||||||
$data = hook_filter('cart.update.data', $data);
|
$data = hook_filter('cart.update.data', $data);
|
||||||
|
|
||||||
return json_success(trans('common.updated_success'), $data);
|
return json_success(trans('common.updated_success'), $data);
|
||||||
|
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
return json_fail($e->getMessage());
|
return json_fail($e->getMessage());
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
namespace Beike\Shop\Http\Controllers;
|
namespace Beike\Shop\Http\Controllers;
|
||||||
|
|
||||||
|
use Beike\Repositories\OrderRepo;
|
||||||
use Beike\Shop\Services\CheckoutService;
|
use Beike\Shop\Services\CheckoutService;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
|
@ -32,9 +33,9 @@ class CheckoutController extends Controller
|
||||||
* 更改结算信息
|
* 更改结算信息
|
||||||
*
|
*
|
||||||
* @param Request $request
|
* @param Request $request
|
||||||
* @return array
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function update(Request $request): array
|
public function update(Request $request): mixed
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$requestData = $request->all();
|
$requestData = $request->all();
|
||||||
|
|
@ -55,8 +56,23 @@ class CheckoutController extends Controller
|
||||||
*/
|
*/
|
||||||
public function confirm()
|
public function confirm()
|
||||||
{
|
{
|
||||||
$data = (new CheckoutService)->confirm();
|
try {
|
||||||
|
$data = (new CheckoutService)->confirm();
|
||||||
|
|
||||||
return hook_filter('checkout.confirm.data', $data);
|
return hook_filter('checkout.confirm.data', $data);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return json_fail($e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function success()
|
||||||
|
{
|
||||||
|
$order_number = request('order_number');
|
||||||
|
|
||||||
|
$customer = current_customer();
|
||||||
|
$order = OrderRepo::getOrderByNumber($order_number, $customer);
|
||||||
|
$data = hook_filter('account.order.show.data', ['order' => $order, 'html_items' => []]);
|
||||||
|
|
||||||
|
return view('checkout/success', $data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,35 @@ namespace Beike\Shop\Http\Controllers;
|
||||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||||
|
use League\Csv\CannotInsertRecord;
|
||||||
|
|
||||||
class Controller extends \App\Http\Controllers\Controller
|
class Controller extends \App\Http\Controllers\Controller
|
||||||
{
|
{
|
||||||
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
|
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $filename
|
||||||
|
* @param $header
|
||||||
|
* @param $records
|
||||||
|
* @return mixed
|
||||||
|
* @throws CannotInsertRecord
|
||||||
|
*/
|
||||||
|
public function downloadCsv($filename, $header, $records): mixed
|
||||||
|
{
|
||||||
|
if (! str_contains($filename, '.csv')) {
|
||||||
|
$filename = $filename . '-' . date('YmdHis') . '.csv';
|
||||||
|
}
|
||||||
|
|
||||||
|
$headers = [
|
||||||
|
'Content-Type' => 'application/octet-stream',
|
||||||
|
'Content-Transfer-Encoding' => 'binary',
|
||||||
|
'Content-Disposition' => 'attachment; filename=' . $filename,
|
||||||
|
];
|
||||||
|
|
||||||
|
$csv = \League\Csv\Writer::createFromString('');
|
||||||
|
$csv->insertOne($header);
|
||||||
|
$csv->insertAll($records);
|
||||||
|
|
||||||
|
return response($csv, 200, $headers);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue