forked from Trustie/forgeplus
Compare commits
1690 Commits
Author | SHA1 | Date |
---|---|---|
|
09e674f0c1 | |
|
6b68de130c | |
|
67d7d11c62 | |
|
6c26450924 | |
|
c91b986bec | |
|
881acd2480 | |
|
e815b0a8ac | |
|
a578b7277a | |
|
421a64e8ca | |
|
a38ebeaca2 | |
|
71862ba6d6 | |
|
82ba843d7d | |
|
031f276983 | |
|
f078c59cf4 | |
|
578acd7845 | |
|
348f7b71ba | |
|
71bf2137ac | |
|
8ac7b6a7e7 | |
|
16dbb87526 | |
|
2c3b7c6fa2 | |
![]() |
1e7cffd716 | |
|
6eea21821f | |
|
64f34cc868 | |
|
e7598642fd | |
|
a69e4e5014 | |
|
1e3ad9e988 | |
|
4bd60d458e | |
|
3769e13c1c | |
|
0830850518 | |
|
ccede16716 | |
|
f64afb8f55 | |
|
8663efc73b | |
|
ef10155387 | |
|
bea2831149 | |
|
afa1cdf842 | |
|
7f0989f69d | |
|
1a3a7967fd | |
|
ee20824639 | |
![]() |
661d1c2c06 | |
![]() |
39c2166c12 | |
|
cd489d3b97 | |
![]() |
769c8a0194 | |
|
91dfc94a7b | |
|
b4672929dc | |
|
17279c56f4 | |
|
d59e99feca | |
|
f81772064d | |
|
3c70bfe267 | |
|
60b0ee6b28 | |
|
d8eba81afd | |
|
eabf404682 | |
|
39a851b74b | |
|
4329236237 | |
|
63196e018a | |
|
7a6d549fa0 | |
|
08f89fd113 | |
|
1f7a1ce73d | |
|
b336a1f334 | |
|
7fdbc3dad1 | |
|
b9998ecf4b | |
|
1e3fd4dfbc | |
|
844d121c7f | |
|
05b3317152 | |
|
adce0c9627 | |
|
6f0595616d | |
|
5226196f4e | |
|
56790f8558 | |
|
53458dab8f | |
|
c78badf091 | |
|
b1ebee31a3 | |
|
e1b17d1dfa | |
|
4bf14974df | |
|
1e75c8c079 | |
|
a9ecb5e47e | |
|
67fb6fce94 | |
|
f5db3273cd | |
|
01467a3d2a | |
|
b37ff07bcf | |
|
2683b03a69 | |
|
d6888a03e3 | |
|
0fc705fcde | |
|
b127323589 | |
|
a1cec48c81 | |
|
a02a15ac12 | |
|
33606c8cd2 | |
|
132eb79b9f | |
|
50696de804 | |
|
26ea240303 | |
|
565dc5f837 | |
|
230ab8e937 | |
|
1ce55b27f4 | |
![]() |
7da1c7e13b | |
![]() |
0a7c41d97c | |
|
a630753485 | |
![]() |
ac49edc8e8 | |
|
ed712b0dc8 | |
|
c02ea218b3 | |
|
cd25e0183d | |
![]() |
bd110bac00 | |
|
c65896c11d | |
|
24fe22398e | |
|
9c1b21f246 | |
|
2c9d2746ba | |
|
5a2e642579 | |
|
b551f97c54 | |
|
77b3c20e15 | |
|
5207d90174 | |
|
7bda0fd126 | |
|
13e266aa28 | |
|
d9b2e98110 | |
|
222de17437 | |
|
36dbf76d80 | |
|
de1e931c2f | |
|
54b7cef1bd | |
|
8463518ade | |
|
718457888d | |
|
ad9c5fe0fb | |
|
2326bde96d | |
|
8e9c2232b0 | |
|
fca06c9816 | |
|
4318293c1f | |
|
d3f10d0814 | |
|
b33c040874 | |
|
2b63d48ecb | |
|
9c5d1e2900 | |
|
6f7b40ec24 | |
|
d993df7df4 | |
|
917bae4321 | |
|
4b618d1a61 | |
|
620ed26e45 | |
|
5580a96fe7 | |
|
2827e28b07 | |
|
b5383bfa5a | |
|
bc862f8d98 | |
|
5216e61479 | |
|
ce70378fc3 | |
|
cbb0a639b2 | |
|
a654a08e0c | |
|
b8724c02f7 | |
|
e59e4e4bd5 | |
|
ec44376e4d | |
|
a80b4d954e | |
|
2842df87c6 | |
|
6f9d902e70 | |
|
4091872091 | |
|
5a7aaff112 | |
|
558d720203 | |
|
46da5a0d84 | |
|
f59ab5bcf1 | |
|
f8350c4043 | |
|
ed7f5a08bb | |
|
acaa28cd02 | |
|
ddb5010e6d | |
|
f05cf0c000 | |
|
ff025e07dd | |
|
4c26085e58 | |
|
a30a3c56b6 | |
|
2e0b32f86b | |
|
dab636d122 | |
|
b616c971db | |
|
35bb8fbc11 | |
|
267279df2d | |
|
e53d6cd763 | |
|
3fd04109d6 | |
|
8487c67bab | |
|
dc01d7fc3e | |
|
7cb2321c02 | |
|
c589fcc6a4 | |
|
1fcdbe9dce | |
|
dc9ca7d0ca | |
|
edc00d28a7 | |
|
317ff3c76b | |
|
c781ca0da1 | |
|
a07da79e89 | |
|
54a85a60fa | |
|
895cd8f737 | |
![]() |
54b7f2c726 | |
![]() |
e440ee8483 | |
|
ed5d12654e | |
|
8239f13eaa | |
|
6c1f9cabda | |
|
5f3d51027e | |
|
84029bf49a | |
![]() |
ee77be7c8a | |
![]() |
05f103b0c4 | |
![]() |
ac8372d7e1 | |
![]() |
b9e2a3736c | |
|
311776a004 | |
|
12eaec0319 | |
|
47a5fe24c8 | |
|
4a3d1e5a69 | |
|
3a5d8e75df | |
|
23a65798df | |
|
cab5466ae4 | |
|
b18051ec31 | |
|
02526878fe | |
|
4657618753 | |
|
cb3bb23e79 | |
|
656d5b69b6 | |
|
121fa2bff4 | |
|
c63a86a797 | |
|
15d71bfd24 | |
|
df38df45d5 | |
|
b85913e485 | |
|
3427fa6768 | |
|
e92b288f41 | |
|
0725ef74de | |
|
00bb1e82af | |
|
f93e665239 | |
|
d578c5c8df | |
|
c872f50685 | |
|
368be1849c | |
|
7d3d95c406 | |
|
5c3c47d13b | |
|
676d2ddce1 | |
|
3d0fa0d50c | |
|
3c51d69555 | |
|
1d9df770b5 | |
|
c0fcf3445a | |
|
6fe16c7c82 | |
|
5e7fe0f28c | |
|
1cd43de75b | |
|
2a8e0d2be8 | |
|
c38a4e4e08 | |
|
202be8246b | |
|
774210206e | |
|
2899f3b18e | |
|
404a6a00e7 | |
|
f0c1e9e319 | |
|
7d17b654f6 | |
|
db2d398d94 | |
|
c0271707a1 | |
|
0af87a67ec | |
|
7bce320113 | |
|
4a8e3324af | |
|
3a14aa10ce | |
|
b799780637 | |
|
53c2ffffb3 | |
|
934b42f1a1 | |
|
c1d791741c | |
|
1aeed8236d | |
|
f0750333f9 | |
|
4085da7837 | |
|
ade03c5e2f | |
|
fe972f1141 | |
|
af67d984b4 | |
|
241bbc06ca | |
|
587facfb3d | |
|
8210404f4a | |
|
128c5c48e6 | |
|
99be556d5b | |
|
353449c53c | |
|
c983df57ee | |
|
39ae14bce7 | |
|
8c8925f3ae | |
|
6cfb5dfbe2 | |
|
0eb17aa90f | |
|
7c911f5b86 | |
|
0800f9e6e0 | |
|
726453ea99 | |
|
bef1350933 | |
|
2772b97e32 | |
|
f2a456c6ed | |
|
4bc945028b | |
|
8b90164247 | |
|
f2cdba29ea | |
|
3f78899c58 | |
|
5fc433d130 | |
|
bfe14352c0 | |
|
a746e791b0 | |
|
87412643cd | |
|
e4b5427725 | |
|
9fe3b5ae3e | |
|
a03d1efcb0 | |
|
2668630f2a | |
|
785ae13649 | |
|
c4b93f2bd3 | |
|
913eb62923 | |
|
112ee39efd | |
|
08d8abd163 | |
|
0229d99e74 | |
|
40873fe95d | |
|
dfe56d9f75 | |
|
5f46d205a9 | |
|
fdb713b76d | |
|
3677bf1bbc | |
|
56d9a4f46b | |
|
7c80f74e26 | |
|
e1c600a2f5 | |
|
ead5753f65 | |
|
a274fa913d | |
|
dd979eb1d0 | |
|
6b9adefde2 | |
|
872a2b334b | |
|
cec764127e | |
|
b8af22e3bc | |
|
18ad80c51c | |
|
05933c9eff | |
|
6047d6a91b | |
|
a04cad32cf | |
|
346ca9eb27 | |
|
0a44e84540 | |
|
87ee19e882 | |
|
3459054349 | |
|
d821006cb5 | |
|
aba1dad1ea | |
|
859d72f7d7 | |
|
b2310fb98b | |
|
672107412b | |
|
454baf8010 | |
|
1de784e9c7 | |
|
46f388999d | |
|
1a0390bf55 | |
|
2f9a514837 | |
|
311852234f | |
|
0f8d2e6a5d | |
|
309ba151be | |
|
69065d1e5a | |
|
45aa49f27d | |
|
d9833ef1bf | |
|
68c05c8df1 | |
|
f796d1be42 | |
|
a15d0827b7 | |
|
204554b34c | |
|
bc2992cc3d | |
|
a631d423c6 | |
|
edd1d27b0a | |
|
3edac3656a | |
|
487630ad1c | |
|
3db761e2ae | |
|
988ebf3fc3 | |
|
6350d2e5a9 | |
|
d0b638cbc0 | |
|
1c16b74f1b | |
|
1aab51104f | |
|
983f488177 | |
|
a01c98164a | |
|
dfa0f1161d | |
|
bc6f5cec4d | |
|
7b724cfeca | |
|
2238c8fcbb | |
|
ee27c90205 | |
|
73d89a89e2 | |
|
534ee80523 | |
|
daf7514afe | |
|
e41adbc4a8 | |
|
ed7c5b0a2d | |
|
ea187a59a0 | |
|
77087345c8 | |
|
05702872b3 | |
|
1fc79535ad | |
|
af8183485e | |
|
4b1f1c697e | |
|
77c7acd582 | |
|
025a6a53e9 | |
|
0747fc6849 | |
|
cbe10b4b89 | |
|
5717d0c69f | |
|
6b846b10bb | |
|
feb8c66e4b | |
|
763d7b499e | |
|
4683b20b3d | |
|
9b39446dfb | |
|
c6e77ac7ee | |
|
f5cdb6f02d | |
|
ed335375bb | |
|
f818a3ac91 | |
|
520ed80224 | |
|
90ef8f2f2e | |
|
f7ca03db81 | |
|
66a1be944a | |
|
8da8b021f6 | |
|
70ba78a9b5 | |
|
6191ddd233 | |
|
ee0f09c8fa | |
|
35cf298f5d | |
|
04814bafbb | |
|
ee5d959404 | |
|
15cbb9ee72 | |
|
7f47cd8d46 | |
|
b68ab63eba | |
|
5da6330f57 | |
|
4e244bed3a | |
|
fd2b20ed87 | |
|
aeff21f7df | |
|
29d2ca63ed | |
|
06c0ac65bf | |
|
8f8dab10c3 | |
|
ae63f735dc | |
|
a6923bf7ed | |
![]() |
1c71eab72e | |
![]() |
667dca0553 | |
![]() |
f23f02cb80 | |
![]() |
a01831e416 | |
![]() |
98f30b4a3e | |
![]() |
19d32799a9 | |
![]() |
4e6e654e1f | |
|
8b85fc11c2 | |
|
6d3c7ddac4 | |
|
38a8191b74 | |
|
e183f48c02 | |
![]() |
0d9accfb35 | |
![]() |
8ff5ee1eec | |
![]() |
a1731f91a9 | |
|
ea7cf1cd1f | |
|
9f74651a2b | |
|
255b615327 | |
![]() |
0cb6f233f3 | |
![]() |
134a395ffa | |
|
64c6f69f56 | |
![]() |
62a9941e22 | |
![]() |
b05e08a1c5 | |
![]() |
64fdfd3b01 | |
![]() |
005687442e | |
![]() |
d4762d2900 | |
![]() |
518f373b88 | |
![]() |
e0588b7863 | |
![]() |
69037beee2 | |
![]() |
babcb16c41 | |
|
6e46b683e1 | |
|
49abadfa3f | |
|
4cde7c374e | |
|
84bfdf749f | |
|
b56930b9ab | |
|
4a7dcf8a91 | |
|
f98886b3a0 | |
|
30572aa41c | |
|
7492662f7d | |
|
ef83697cb8 | |
|
6dc06fc088 | |
|
570f664c27 | |
|
e92588cf6d | |
|
e24921bba3 | |
|
f75e05bb84 | |
|
e4d62c5335 | |
|
c3703a7f69 | |
|
6d9cf8aad2 | |
|
33a3d7f48c | |
|
e3179dfd6e | |
|
7817487ab7 | |
|
83b46fcb50 | |
![]() |
8ce3fac96d | |
![]() |
1f2af50091 | |
![]() |
7cc9d207b6 | |
![]() |
abfb62f342 | |
![]() |
f4794f6489 | |
![]() |
575dbb0544 | |
![]() |
ccbbab0741 | |
|
2b2a44831e | |
|
3e5c1da2c5 | |
|
0a06b2098b | |
|
07aefa79eb | |
![]() |
79d46231ba | |
![]() |
2618dc5798 | |
![]() |
2bd723fc64 | |
![]() |
79dae01a69 | |
![]() |
63ea4808c9 | |
![]() |
c7a6d78c15 | |
![]() |
3ff3502bbc | |
|
7f91ebb509 | |
|
423d5a9316 | |
|
2548b0e9c0 | |
|
9664ca001e | |
|
d665d0edb1 | |
|
e15809c186 | |
|
4235c3ee63 | |
|
7d4c0df691 | |
|
761c311a88 | |
|
e72dfa4973 | |
|
b29b297f7e | |
|
84a8339a04 | |
|
893f6c04a5 | |
|
3d5b2e76d7 | |
|
6e9962e0da | |
|
8b14ee3c72 | |
![]() |
a4c892ec0a | |
![]() |
2945570a51 | |
![]() |
969cbcfe60 | |
|
4d61127e49 | |
|
3f7366fbcd | |
|
97a661cd95 | |
|
cfdbc5a682 | |
|
f557994f8a | |
|
9b880e3209 | |
![]() |
47aba3528d | |
![]() |
b80b89e81d | |
|
04642497df | |
|
c2ef23b746 | |
|
292167b47e | |
|
8a33ea6707 | |
|
2da84146eb | |
|
9ee4c85b7c | |
![]() |
4cc4ed5864 | |
![]() |
0a5dd2f1ee | |
|
e9b23d6577 | |
|
64d9c334ce | |
|
cad7e24299 | |
|
3b15dd84fc | |
|
58a43a8b80 | |
|
e25231738a | |
|
35965f542a | |
|
fa48e3f5ca | |
|
13e2738fb5 | |
|
a494a905fa | |
|
30437d828c | |
|
dcc7ab6738 | |
|
57a7a17f73 | |
|
5196f33f24 | |
![]() |
b3cbed2963 | |
![]() |
dd1af6712c | |
|
8807be6e4d | |
|
8d41c27044 | |
|
77ec7e5a69 | |
|
53fe554d1e | |
![]() |
4e02dbe06b | |
![]() |
620ddff9bb | |
|
732d1a1adb | |
|
630a7aadeb | |
|
2cdcd5f117 | |
|
6383384287 | |
|
6b6c0791cd | |
|
2df259c927 | |
|
83f1263f85 | |
![]() |
4b0609931a | |
![]() |
c2742f0ae7 | |
![]() |
483c8d5410 | |
![]() |
c2673bd48d | |
![]() |
f031cd4720 | |
![]() |
bf1e722084 | |
![]() |
8b1f06f010 | |
![]() |
6d2a6e0331 | |
![]() |
c668fd3530 | |
![]() |
e7bbe252de | |
|
9c11cd79e8 | |
|
a516363763 | |
|
a7384bc1c3 | |
|
3d475fdedd | |
|
55170c7693 | |
|
2cde13eabb | |
|
d68e7f38a3 | |
|
649d9c4ea6 | |
![]() |
e33448db4d | |
![]() |
628d815a5c | |
![]() |
c08868b26a | |
![]() |
fce8166ba7 | |
![]() |
ae0efc1115 | |
![]() |
dfc2edd62d | |
|
a030a01050 | |
|
d7f3a21add | |
|
d9eb335b2a | |
|
ef9592ef30 | |
|
af7a779af6 | |
|
cc42683316 | |
![]() |
28656ad6cd | |
![]() |
b832a8ecc6 | |
![]() |
5c123fba17 | |
|
b7193aa768 | |
|
70f1e6827f | |
|
b4e0cc6dc1 | |
|
b5188e3272 | |
|
ff881732d2 | |
![]() |
2adf87a289 | |
![]() |
b3afa15d2e | |
![]() |
b40f48f87e | |
![]() |
6954a860af | |
![]() |
b07e5d6993 | |
![]() |
bb8e6aeaf8 | |
![]() |
ac8959f36f | |
![]() |
6d7b7dd058 | |
|
dfc2c68225 | |
|
6a2cfc5fde | |
|
007b90c284 | |
|
4994179a33 | |
|
481d1b7db0 | |
|
a1b2bdd048 | |
|
733f64eaec | |
|
383660c778 | |
![]() |
2c2c45476d | |
|
ecd43dbd12 | |
|
4bd77a870b | |
|
9022fdcb80 | |
|
b1f460d760 | |
![]() |
dd35a053cf | |
![]() |
4a08c9be88 | |
![]() |
200d5e0d69 | |
|
a0413be4b9 | |
|
a438ab6f3e | |
![]() |
3a34d8682c | |
![]() |
60894f00b1 | |
![]() |
925b05e004 | |
|
ce432d9ad3 | |
|
4878d66620 | |
|
d240d4f4fa | |
|
632ade9d25 | |
|
36443a54d8 | |
|
5acd45bf85 | |
|
d03b45eecf | |
![]() |
f2b55977c9 | |
![]() |
fd66a3149d | |
![]() |
4a6e94a98f | |
![]() |
c60e80da98 | |
![]() |
eb1a3f8e23 | |
![]() |
a7c24dea64 | |
![]() |
32a9d762d8 | |
![]() |
0a79950046 | |
![]() |
d51bb7030f | |
![]() |
4b7c58b13f | |
![]() |
7148957368 | |
|
1613cf7376 | |
|
aa50c50254 | |
|
43a41399ac | |
|
60b3c7925d | |
|
0f41cabe71 | |
![]() |
8f4cb2667f | |
![]() |
d04ed7e008 | |
|
5c5b4b5d92 | |
|
43e07ade99 | |
|
6168256897 | |
|
7a7a1efc46 | |
|
4b167dacbb | |
|
98446220a1 | |
|
911c47df8d | |
|
1e4aed71fe | |
|
a37d7b9840 | |
![]() |
c7e098d507 | |
![]() |
dbdb860bb7 | |
![]() |
217ab920a9 | |
![]() |
98ae62d181 | |
![]() |
98f1723411 | |
|
144fbac843 | |
|
68a38e75bc | |
![]() |
81b64c18b6 | |
![]() |
0c10f3ff10 | |
![]() |
c6034ed33f | |
![]() |
4618f4effa | |
![]() |
b2af43ee2a | |
![]() |
f211fbaec3 | |
![]() |
14c1be1bea | |
|
63cdaed3ac | |
|
ee29c6be5c | |
|
c0ee0a694c | |
![]() |
12cc870dc7 | |
![]() |
e5989b219f | |
![]() |
25fa6f427b | |
![]() |
467d722d25 | |
|
04cd427c5f | |
|
9992a78161 | |
|
3e352d3c7c | |
|
6bb1dcf718 | |
|
13472b2311 | |
|
71b42e462e | |
![]() |
bdddd655bf | |
![]() |
6ec7a13293 | |
![]() |
716b29c25f | |
![]() |
5c4930a362 | |
![]() |
ad8fed9440 | |
![]() |
964bef7896 | |
![]() |
7e48e5e8b8 | |
![]() |
48846a7e31 | |
|
32db15aad5 | |
![]() |
8ec3e4bbaa | |
![]() |
c167c39050 | |
![]() |
58368277c0 | |
![]() |
4918fda2e1 | |
![]() |
9ce7cdf0c3 | |
![]() |
e46c934b2c | |
![]() |
b949ee260d | |
![]() |
c60572e31f | |
![]() |
1efff8a97a | |
![]() |
4199f4097c | |
|
a0dcc289c8 | |
|
4b05838498 | |
|
0699c768a5 | |
![]() |
e7aa05b535 | |
![]() |
99ba523084 | |
![]() |
14f4b290cb | |
![]() |
5ffc603f61 | |
![]() |
eac06382fe | |
|
65e1cd2c01 | |
|
b8be0c23cb | |
|
d4405b8827 | |
|
d20a7b1318 | |
|
0993e5a3ae | |
|
f8268accc0 | |
![]() |
690ddcb4a7 | |
![]() |
72a4549fe9 | |
![]() |
4fb2003f64 | |
![]() |
5c361207f5 | |
![]() |
4941e08684 | |
|
7e711cfdab | |
|
a9811768d4 | |
![]() |
ebe8df8221 | |
![]() |
1b3a4bc146 | |
![]() |
7332e4a58b | |
![]() |
1a2352c535 | |
|
958ee42fa2 | |
|
024bc289de | |
|
90a621ed8e | |
|
96d34d0237 | |
|
64e608ffd7 | |
|
fea11bdc2e | |
|
0be06c8282 | |
|
ab5d273f98 | |
![]() |
8bf4e9b8d2 | |
![]() |
bf6a11dadd | |
![]() |
9d385845a6 | |
|
d4d8153003 | |
|
096b0b954d | |
|
b06e29260a | |
|
29bfeabb20 | |
|
df57312056 | |
![]() |
7597f1fd8f | |
![]() |
8dba81bfca | |
![]() |
531747024d | |
![]() |
a560a5034c | |
![]() |
34504ddc39 | |
![]() |
29342e11fb | |
|
adb55c0910 | |
|
902c66d490 | |
![]() |
8a187df5f4 | |
![]() |
93fd9333ec | |
![]() |
487c6dc21a | |
![]() |
0936bbd1c8 | |
![]() |
2b31b683dd | |
![]() |
27fae8d27b | |
![]() |
f12cfabee3 | |
![]() |
b22909a654 | |
![]() |
579b45dfa4 | |
![]() |
99850e45ad | |
![]() |
0908e61f59 | |
![]() |
321f367e3e | |
![]() |
fbc1f95cd1 | |
![]() |
4ccf8ea5ff | |
|
bc580e1bac | |
|
d5c141f892 | |
|
2d0f1ab94c | |
|
35c6cb98db | |
|
c93c4ad657 | |
|
f417e42864 | |
|
bc0222ac21 | |
|
6e54203ebb | |
![]() |
79a6841bbc | |
![]() |
b3d78741a3 | |
|
445ae6fbc3 | |
|
935f3ddf7f | |
|
a2549f7ff1 | |
|
d6b5dc326a | |
![]() |
d6c6ac9a0a | |
![]() |
f3233b145b | |
![]() |
d8d841d800 | |
![]() |
bcea5bc669 | |
![]() |
003bfe7884 | |
![]() |
df5efa0dc6 | |
|
a35db9fe80 | |
![]() |
5be93d5de8 | |
![]() |
99d9e13edc | |
![]() |
4686b5241e | |
|
5025bf6961 | |
|
6183f1f76d | |
|
034170372e | |
|
e72273f3b2 | |
|
70220638fd | |
|
cc09f724cc | |
|
7a54c5f536 | |
![]() |
b1809909db | |
![]() |
bb3f5cec76 | |
![]() |
19ffd9fea1 | |
![]() |
6f9db6b314 | |
![]() |
5877474f59 | |
![]() |
1bbde165c2 | |
|
3f5754a3a5 | |
|
5463c22518 | |
|
5db43bf768 | |
|
1feb166fd5 | |
|
db4e98ec37 | |
|
56b1110e4d | |
|
0df1e5fdd0 | |
|
8ba70a33be | |
|
3a12b7b16c | |
|
4aebba2f25 | |
|
95cf55993d | |
|
81b684e469 | |
![]() |
0b167026f8 | |
![]() |
913057658e | |
![]() |
b21f44b59e | |
|
8645642612 | |
|
abac8b9c46 | |
|
88fb11ea92 | |
|
545ec28561 | |
|
7793eacf75 | |
|
25afedcdfd | |
![]() |
c41c4f5813 | |
|
d95a689815 | |
|
b386dc51e4 | |
|
1882120df3 | |
|
274cd81655 | |
|
52bd568789 | |
|
d9b78acb8e | |
|
bfd2c1d5c7 | |
|
92be882e54 | |
|
6273349334 | |
|
7638cd00fb | |
|
e8deb83004 | |
|
f161349bd7 | |
|
52701d1c2f | |
|
b248f770f1 | |
|
04b9e43382 | |
|
07518f0d00 | |
|
e71d28736d | |
|
3580a8653d | |
|
2c799bd0a5 | |
|
d9653e461e | |
|
00f4e100c6 | |
|
d9a1d32ec8 | |
|
38c5e3487f | |
|
b5dfd83527 | |
|
e6e1b56309 | |
|
df7b91a8ba | |
|
8dae15225e | |
|
5fcf789e63 | |
|
ed0655452c | |
|
6de6e34a4e | |
|
0dd062ce1c | |
|
c30c56f77b | |
|
bd3cbf33fd | |
|
b8d4b15b40 | |
|
63cd6bb0a4 | |
|
24d83133e7 | |
|
4ed3a9d478 | |
|
3cb97ed830 | |
|
a5d1058ea9 | |
|
9b50b9df00 | |
|
fbbacfa983 | |
|
07ec114e9a | |
|
25375b32c2 | |
|
d7a970e7d5 | |
|
915e689ef9 | |
|
221c439a1d | |
|
4c7498a046 | |
|
e919b03e90 | |
|
4fa1a433fa | |
|
e4ec8e8ed5 | |
|
d0988e42b4 | |
|
ed22ff921e | |
|
d154f0aecc | |
|
cf24e01c2a | |
|
29d9410e42 | |
|
f8b63ff02e | |
|
3b62f09669 | |
|
5864352049 | |
|
1d6d48fc94 | |
|
8781720f31 | |
|
484c91a581 | |
|
d1d7ae5b7f | |
|
eb0bda81e9 | |
|
c50913495e | |
|
1bc7c48876 | |
|
14dd7a3b60 | |
|
959191c8bb | |
|
850d743b16 | |
|
f01da70e8a | |
|
1a2d01df17 | |
|
abfefdf8eb | |
|
7b91ad37e5 | |
|
9dbb9a42d6 | |
|
a608803aa8 | |
|
76cc185a1d | |
|
bf2e6269f9 | |
|
620d2eeb51 | |
|
d97888ad16 | |
|
bdaca48fde | |
|
41eedff819 | |
|
3a1a7d7140 | |
|
e76503ae26 | |
|
fb2e2d9534 | |
|
50991f503f | |
|
acd031ca7d | |
|
b59b76be4a | |
|
211581cef0 | |
|
7cad953413 | |
|
fe58175ee0 | |
|
5d0849a148 | |
|
d14bf35ca1 | |
|
d7dd3901b8 | |
|
aefd6c08dc | |
|
5c793088fa | |
|
3c2c742121 | |
|
430582aa3d | |
|
9221e55752 | |
|
d6bbc7554f | |
|
ba1fa8b685 | |
|
7ba77680ac | |
|
29e3a55a0c | |
|
c426467a68 | |
|
9fe8df3c1b | |
|
79cbeb846b | |
|
531495429c | |
|
e75f5f655f | |
|
bed2469014 | |
|
7e5d5e31e5 | |
|
45b7f70d9f | |
|
1ebb6cb561 | |
|
21ccedab9c | |
|
8f45bcf959 | |
|
1f9caeece5 | |
|
f4737d88d8 | |
|
5b4e6f4902 | |
|
c0c259a5fc | |
|
3d0e323801 | |
|
f6fb50529c | |
|
c42f3d5928 | |
|
0fa5bb2211 | |
|
42d2b51f7f | |
|
66c40d4791 | |
|
dd03b9f147 | |
|
ce467736a7 | |
|
f727e8f94e | |
|
cc2c0e8e26 | |
|
43792d3100 | |
|
6f42889b06 | |
|
7a0dbaaefb | |
|
3e4dd90e17 | |
|
8a7dc75907 | |
|
8ae5587516 | |
|
15a0b85ae6 | |
|
0b543f7dda | |
|
a07204111a | |
|
a7ce3f3728 | |
|
7290cd6495 | |
|
e69fe13745 | |
|
038df804c0 | |
|
877948b0cd | |
|
9a17c4865f | |
|
4a23878185 | |
|
dc787a35d4 | |
|
b785406ab8 | |
|
9427db3e5a | |
|
2d52dbfc2f | |
|
81da71d478 | |
|
169dc84e22 | |
|
f66e951f31 | |
|
d6fd85f536 | |
|
331dfa4b12 | |
|
6448a30e03 | |
|
17fb43cea8 | |
|
e76822eb34 | |
|
1220223322 | |
|
0b35f56212 | |
|
95f98710d6 | |
|
40a987116f | |
|
a00b1d4530 | |
|
48cf92a2cf | |
|
2a387ad997 | |
|
a6e50d2a25 | |
|
f6e8f24480 | |
|
bd16ca476d | |
|
19ec81e975 | |
|
2ea78b4f20 | |
|
ad9bb8e542 | |
|
e36c7a4b6a | |
|
9979c87d0c | |
|
8e8ec821f2 | |
|
94166a363c | |
|
ebe5fad7dd | |
|
85a36ca2e7 | |
|
75cef14605 | |
|
93f8b659a1 | |
|
b45ee11239 | |
|
33fa55bcb6 | |
|
643a99fdf1 | |
|
38c5432c2a | |
|
5cf257c3cc | |
|
aa18fe0ad4 | |
|
1358c23ca6 | |
|
183eb15c7d | |
|
fb43268444 | |
|
c27cc063e6 | |
|
b673909f9e | |
|
ee3a14fa28 | |
|
26bfc2c0bf | |
|
56721930a2 | |
|
2959414d56 | |
|
6223cf41e2 | |
|
1d3f79e777 | |
|
b0092487e6 | |
|
0ae3544235 | |
|
05b3f2a2fb | |
|
97fe157279 | |
|
fbebd0a623 | |
|
02681abaee | |
|
fe23c2afbf | |
|
b06ad71082 | |
|
3212bc4842 | |
|
779c86108a | |
|
e4779926bd | |
|
803fdfc49e | |
|
83e43f0c97 | |
|
ccec3494bc | |
|
e237fd46f7 | |
|
6dc2f0b062 | |
|
ca3c564529 | |
|
f79e4f8e81 | |
|
9cd18397f7 | |
|
bfd3298cd0 | |
|
077926de18 | |
|
4fade5d0b7 | |
|
f51ebaad67 | |
|
8ae6a0deb2 | |
|
d9b3711e08 | |
|
77620f7735 | |
|
acbd0d376c | |
|
2f4ffe3d8e | |
|
a6efae8b10 | |
|
5a728e7d4d | |
|
04a733d99f | |
|
9e8c576ff6 | |
|
94881dd72a | |
|
2c7bb1b5cd | |
|
0e4c0a46c2 | |
|
7fcbbb7922 | |
|
3d9fe5bba5 | |
|
4dccdfde97 | |
|
00fc83235f | |
|
498ee26f59 | |
|
5d771c824b | |
|
3eccd6be64 | |
|
9b3336c0a0 | |
|
12c961d70d | |
|
7750cbe272 | |
|
1f13bba52e | |
|
5dcee1b4dc | |
|
cf09b28f5e | |
|
f31796f344 | |
|
2d9bde134a | |
|
59db914bcc | |
|
a0a7f908f4 | |
|
17ccf3d576 | |
|
72a32ed8c4 | |
|
c64fa5135b | |
|
12cc37443e | |
|
f5efbcfc04 | |
|
50dc5cce5d | |
|
0afac46778 | |
|
a6cee63d17 | |
|
20af4a7d82 | |
|
000197b0d1 | |
|
67b386d947 | |
|
6aa3321d17 | |
|
82df2fd6d8 | |
|
9d8df2b4d9 | |
|
d44308fc82 | |
|
ae7d0d1329 | |
|
071542bcb4 | |
|
676024b6db | |
|
55c74de8e4 | |
|
52c94effdc | |
|
7c88ea3d67 | |
|
d799d329ff | |
|
f15cd44dff | |
|
91ea5ca96a | |
|
3abd6037d9 | |
|
11724bf63f | |
|
ec3a556a6f | |
|
1d7c7eba24 | |
|
793cbb372a | |
|
396ac55429 | |
|
e1b4622ede | |
|
088c617cc1 | |
|
246b484ad8 | |
|
fc3cf01d3f | |
|
345fd31834 | |
|
8f5bb0e2d9 | |
|
7aea481ccf | |
|
37317f82bf | |
|
2dfd69ae21 | |
|
a132154136 | |
|
720c073f32 | |
|
185cb308ac | |
|
0076468a15 | |
|
910ae48556 | |
|
6e86f9d9f3 | |
|
6d280ed8f2 | |
|
3f85f88c92 | |
|
f60cd409b6 | |
|
9d46f2743d | |
|
aaf2b43986 | |
|
75a9a65b9b | |
|
17f2436118 | |
|
eac7331070 | |
|
2243697184 | |
|
551f333261 | |
|
18cf1d3ecb | |
|
4cefaa7e92 | |
|
dec264d169 | |
|
8aa935ad5c | |
|
4bdff8313a | |
|
c4f91fb054 | |
|
fde01e62ef | |
|
7055974443 | |
|
1f6ac05bad | |
|
c5dd099169 | |
|
3536918938 | |
|
d56da6d020 | |
|
56278b84f2 | |
|
882a50cf56 | |
|
234f5b900c | |
|
db4031b8bf | |
|
dd3236e310 | |
|
ecfc39565c | |
|
7fd41e13e4 | |
|
9ced678f91 | |
|
b25db9d37f | |
|
7951ca28d5 | |
|
4bbb843edf | |
|
747646cd9d | |
|
a5be4a9502 | |
|
d0d906d04c | |
|
4c69c4d20f | |
|
183315bbd9 | |
|
4dc3546124 | |
|
d796d59557 | |
|
bc639488aa | |
|
930805704a | |
|
9912ad0779 | |
|
d9ae4e4ba0 | |
|
23dc2d7fb6 | |
|
fe5c18c019 | |
|
fa6f015128 | |
|
7f1b95c7d7 | |
|
2346b0f848 | |
|
c0e97409cb | |
|
99fbecc834 | |
|
4cc8dd70f4 | |
|
8d0a6d267a | |
|
0db1820557 | |
|
b1c03ed5e8 | |
|
1c660213a7 | |
|
748f6cdd4d | |
|
1fe8d1defc | |
|
ef12f85687 | |
|
e120c4dac2 | |
|
e1cf2fcdeb | |
|
c4f380873e | |
|
5cb2e55f74 | |
|
664b806c0a | |
|
1dd3fbc69a | |
|
94d259ea03 | |
|
3091593d14 | |
|
c5d2fad913 | |
|
b97c42d0ae | |
|
c76466a883 | |
|
217e0fdd97 | |
|
f0b8489828 | |
|
a2612d8009 | |
|
2f2655525f | |
|
70ade7b27b | |
|
57c60b2fe9 | |
|
aa643430fa | |
|
1a93477635 | |
|
8f9aedd7d6 | |
|
ab989ed7d7 | |
|
28d07d5c54 | |
|
53d094784b | |
|
7c664addbd | |
|
6167834bfa | |
|
1bb754e9d8 | |
|
f2f2ce8252 | |
|
c6b79f82bc | |
|
4e3f9cc019 | |
|
5ed7b3e4ad | |
|
4e2c46260c | |
|
9ba00b21c9 | |
|
1100309038 | |
|
b11f5fd228 | |
|
af5f2b2fe3 | |
|
90dbe0730a | |
|
f39e8b7668 | |
|
d6633cb73a | |
|
86ef890f8b | |
|
a7a6abd22a | |
|
6fd47b56a5 | |
|
c956667ce0 | |
|
898453c88c | |
|
5701c818ed | |
|
1ac2ddfaa5 | |
|
0bd274f813 | |
|
4aac05d4e1 | |
|
b028a70646 | |
|
3c7da85bee | |
|
9751c954df | |
|
84b56bfcb8 | |
|
ac07c88f84 | |
|
7485564bb9 | |
|
5e696ae905 | |
|
b5acf2308a | |
|
e3f4313c80 | |
|
b223abe229 | |
|
b3bede308c | |
|
2f170a54c6 | |
|
22293572ac | |
|
d262da7c65 | |
|
2050559077 | |
|
8720cab1e9 | |
|
959c1e8d95 | |
|
52bde548fa | |
|
ea11672fff | |
|
09c4f8db0e | |
|
29dc3fff39 | |
|
da863c3963 | |
|
8d18149537 | |
|
8050af23fc | |
|
298abdd1b1 | |
|
eb0ced39f5 | |
|
2738d950d4 | |
|
3ce9b2d145 | |
|
26f87fba16 | |
|
465f38bca7 | |
|
1e9a32a93e | |
|
04bc6d363f | |
|
2dc79052c2 | |
|
f6ff8ac209 | |
|
b9e2a6edf1 | |
|
e0f5337fdd | |
|
380ca3a066 | |
|
7d19849968 | |
|
237b0afb08 | |
|
67914201bf | |
|
e14936e820 | |
|
655c85851f | |
|
1c7e414aa4 | |
|
099fc52e00 | |
|
490957ec3b | |
|
b1884d30d5 | |
|
98d8ee1fb6 | |
|
2ca77732c8 | |
|
1760b42127 | |
|
9f7725b097 | |
|
612101498c | |
|
70d22f7c4f | |
|
25d0e784bb | |
|
5d45b24299 | |
|
b6b8befde7 | |
|
f33b9559cd | |
|
ab6ac05a7d | |
|
cf69628f85 | |
|
4a8f8af896 | |
|
f9bc2258ec | |
|
f168fe3d03 | |
|
05f5982a53 | |
|
f76dad680a | |
|
2a09ced1ce | |
|
7a1e6cfbad | |
|
47d1f727ce | |
|
a7665df0ea | |
|
84f12adce8 | |
|
7fde1e0e12 | |
|
499734ebf9 | |
|
f339df699e | |
|
cfd94cb3b7 | |
|
43e0617429 | |
|
25e4a817f6 | |
|
2021cbbd5b | |
|
5a43239ad9 | |
|
650dbea38b | |
|
abde13f061 | |
|
0619c5a4d9 | |
|
e26871728f | |
|
ec444f3855 | |
|
7beed940e9 | |
|
d6b66d5324 | |
|
0c1df3b2cb | |
|
fa86d3ea10 | |
|
8c99b754fb | |
|
f3cf2c87c9 | |
|
ef55e44063 | |
|
a9df1ca75f | |
|
4f63caa86c | |
|
96b0f2d167 | |
|
8e4e6fc0ac | |
|
75f3166ffa | |
|
04bf423fcb | |
|
51e8c9d908 | |
|
4304a35b80 | |
|
076375633a | |
|
dbf5e711a5 | |
|
4432e65683 | |
|
dcf44a78f0 | |
|
12edc620df | |
|
4ce03145df | |
|
3e04a37ece | |
|
78f464ccba | |
|
64423f1999 | |
|
05c3f60dab | |
|
0083ef33cb | |
|
36b68df273 | |
|
e1a5918c22 | |
|
e9835796f6 | |
|
26ae9b35df | |
|
8e79b43aaf | |
|
056c145ff8 | |
|
c105785105 | |
|
c2bd78d70d | |
|
d28eba6423 | |
|
688be1bb7d | |
|
df69dee282 | |
|
ee6404a3b3 | |
|
fae8313df6 | |
|
45a77e5c07 | |
|
7849bd0ebf | |
|
7f58b870d4 | |
|
0c7499842f | |
|
ab361d8009 | |
|
3649bf1fd0 | |
|
bcfb544cca | |
|
edb1114d39 | |
|
a24d33d2ee | |
|
6ffc2938a1 | |
|
aa60de1dac | |
|
29f98513e2 | |
|
e35cdf39fb | |
|
3f98e78942 | |
|
bec98bbc9d | |
|
af160084c4 | |
|
e51b86538b | |
|
da4fd3a762 | |
|
9c1ed28627 | |
|
01e7d857c8 | |
|
06635e8bb6 | |
|
96d1a7440d | |
|
8a34699acd | |
|
efc82b9841 | |
|
e3df503dd2 | |
|
6a2ad67386 | |
|
3d12db3a07 | |
|
9c5ff55b70 | |
|
82bae9159b | |
|
1d13b3686b | |
|
1faaf1d7d1 | |
|
f8a6f62342 | |
|
b816b6a449 | |
|
d48700d200 | |
|
66d1246a6c | |
|
f79beef3f9 | |
|
81e6691632 | |
|
38d6519381 | |
|
16418675ac | |
|
102858bc8c | |
|
0d64768e4b | |
|
beccac652f | |
|
30eb1958c1 | |
|
33e17e8439 | |
|
5445206716 | |
|
1c19c05fd8 | |
|
957980fc71 | |
|
657e2cf169 | |
|
e0c47c2abd | |
|
9e64a4842d | |
|
ba9e74f373 | |
|
93dd5b5d84 | |
|
422549f9e7 | |
|
0358229b95 | |
|
c4586fbb36 | |
|
0a5a75dc0d | |
|
d4ee468435 | |
|
a26d8be0b0 | |
|
f94006abfd | |
|
5618887e7a | |
|
3480e15c48 | |
|
d85a446edc | |
|
4d61e7618a | |
|
9a8ddffb5a | |
|
2116af759d | |
|
38862b9843 | |
|
f889849b6b | |
|
3501ff6bd4 | |
|
badd950ff9 | |
|
8f70d4f604 | |
|
20bfbdc06f | |
|
b7bebcd736 | |
|
d4663e410d | |
|
1b385f4377 | |
|
5c445b9ea0 | |
|
36286d9003 | |
|
f533a6253b | |
|
0f9d33e755 | |
|
51356da7f3 | |
|
ebe893022f | |
|
c5f22e6c70 | |
|
30135ccad7 | |
|
eac97c6698 | |
|
8ee52440c7 | |
|
d9925db510 | |
|
34bcf9ed57 | |
|
b22c65e5c2 | |
|
922561afb1 | |
|
6479ac8696 | |
|
f4e4015a89 | |
|
cd4ba9c1d9 | |
|
f12b10fa23 | |
|
4a3275a15e | |
|
6f7899d16f | |
|
24170fc2cb | |
|
4e3c8e414c | |
|
d588a78f62 | |
|
a7d681c4dd | |
|
7a93db9ed2 | |
|
74e5fa0e31 | |
|
80b83c5230 | |
|
6ffc702209 | |
|
de995c8714 | |
|
16f37a3729 | |
|
ea156cec7e | |
|
f76df2c629 | |
|
7499d8af89 | |
|
f8654edc3b | |
|
d16f290aa6 | |
|
9385d346f1 | |
|
22f3371090 | |
|
c0a4f8f4ec | |
|
7586a0fb21 | |
|
c0e3a91a46 | |
|
7c765817c9 | |
|
7ebd8681fa | |
|
72553dec57 | |
|
dee68808b1 | |
|
96d7917bbf | |
|
abca0fe432 | |
|
d7612a0921 | |
|
c54950a95f | |
|
e25e2fdd77 | |
|
be0f68cede | |
|
1b92b53099 | |
|
5634413cac | |
|
1eb1d25040 | |
|
a4a431e9bb | |
|
515307139a | |
|
0a3df09089 | |
|
399558550e | |
|
1a9ed1425e | |
|
f9d4316a8e | |
|
6f7f815fd4 | |
|
ddb826733b | |
|
1f989d0a37 | |
|
72ec7bc213 | |
|
d63626424e | |
|
55ab694505 | |
|
0885575cc4 | |
|
a188648287 | |
|
8011dabaac | |
|
88a08e73c0 | |
|
6713f9b280 | |
![]() |
651bf34cfc | |
|
3a7355c73e | |
![]() |
77ad959a8c | |
![]() |
9d05973700 | |
![]() |
7ad3789fe2 | |
![]() |
7ebfaf915f | |
|
e3588291b2 | |
|
7a14949063 | |
![]() |
8d3b674321 | |
|
2ece9908a6 | |
![]() |
a549dc1e25 | |
![]() |
6607758c25 | |
![]() |
e02237a9e0 | |
|
59711b54bc | |
![]() |
538d2113f1 | |
|
18cf2ca78a | |
|
0d1fa2995a | |
|
e243a61d0c | |
![]() |
06cf52c384 | |
|
a3f57d3cbc | |
|
18bbbce7b3 | |
![]() |
8d60b271f7 | |
![]() |
be96e7e5eb | |
|
35f04afe91 | |
|
385f45ddde | |
|
94075717e2 | |
|
a033ddeeca | |
|
7b5452fdcc | |
![]() |
b40cbfbfbb | |
![]() |
41022950a5 | |
![]() |
d9e4f26819 | |
![]() |
683c00a73e | |
![]() |
74a7bc62ea | |
![]() |
a5e5dbb6bf | |
|
da30ba189c | |
|
b5047392a6 | |
![]() |
5b19a333ef | |
|
62e8cf76b9 | |
![]() |
33a5b7f4f9 | |
|
4567c32b97 | |
|
9899a8aab6 | |
|
da3625a0a8 | |
|
6f5f42c23a | |
![]() |
3c44ffe7df | |
![]() |
4ebb6a5e74 | |
|
5cbe83f9d4 | |
|
7030e0b5bc | |
|
01377bc20a | |
|
976c4b26c3 | |
![]() |
d5e9005253 | |
|
f01bfe6435 | |
|
1f451779de | |
![]() |
c4c3a451c8 | |
|
ac6aa7559d | |
|
829e36cfce | |
|
fb73fa458c | |
![]() |
7c8843fda7 | |
|
40654061ce | |
|
3325ec842d | |
|
194a2f4e36 | |
|
bd1cd7ee13 | |
|
fdbc657846 | |
![]() |
317205d185 | |
![]() |
14949c0bfd | |
|
0cbfc895ca | |
|
2fab120118 | |
|
629729436c | |
|
00ed177089 | |
|
26c0d36227 | |
|
86c98a1716 | |
|
143e88593f | |
|
99e3aaf780 | |
|
7d12a25088 | |
|
85d1aa3a85 | |
|
0f57844106 | |
|
c3b9d2e0b5 | |
![]() |
299e8534d1 | |
![]() |
d7362925f2 | |
![]() |
43945b00b8 | |
![]() |
b11d515ec6 | |
|
07a38ac3f7 | |
|
18227c232b | |
![]() |
f1d79e4d9f | |
![]() |
20e2e22be5 | |
![]() |
27e5febef2 | |
|
fb23e733d6 | |
|
512bff426d | |
|
671c2c2257 | |
|
c6f2021017 | |
![]() |
581b147b3c | |
![]() |
deebfc3292 | |
|
6c4d17bed8 | |
|
e68c13f1a2 | |
|
15eb1f4a17 | |
|
a1cb9a11d6 | |
|
0884a0de1b | |
|
900fdd2691 | |
|
4520055de2 | |
|
193d1b21df | |
|
ed8e079595 | |
|
55a0bcfb82 | |
|
8f1aa3f4b1 | |
![]() |
b054094798 | |
![]() |
2d648e516e | |
|
7c23b40661 | |
|
ff21916f18 | |
|
d9162cb3bf | |
|
ca1fd3cd4f | |
![]() |
913bc45a9f | |
![]() |
8131d8cd48 | |
|
b45ab12279 | |
|
259090b8e3 | |
|
c3bc4166d9 | |
![]() |
7e474cab70 | |
![]() |
01341d4389 | |
![]() |
3a475a4674 | |
![]() |
83b7b8cd9c | |
|
c298ff02b8 | |
|
16ea03dcc8 | |
![]() |
7bb4cf7391 | |
![]() |
23f7439a8c | |
![]() |
6f19093dc2 | |
|
fa8f1155f5 | |
![]() |
484f8a854a | |
![]() |
7bedac263d | |
![]() |
f0b1c9e80b | |
![]() |
dc23be9001 | |
![]() |
e24269c2a7 | |
|
e31176c696 | |
![]() |
bf390c8366 | |
![]() |
fc60278f9a | |
![]() |
b59376d3e3 | |
|
c5d73b7cf8 | |
![]() |
632a06e575 | |
![]() |
04c7887319 | |
|
b012740195 | |
![]() |
d75b79670d | |
|
0f79238f0e | |
![]() |
2c5fa8492f | |
|
fdfbf505ed | |
![]() |
6d845eeb3b | |
|
a7695b16a4 | |
![]() |
83e666a387 | |
|
1a0fd38d15 | |
![]() |
8a10a183e0 | |
![]() |
5eaaf0070f | |
![]() |
aeeaedbd7a | |
![]() |
6d1bcabd51 | |
![]() |
72b89d4b2b | |
![]() |
b0b224fe76 | |
![]() |
38f6254edc | |
|
57d9da002e | |
![]() |
8a4b0ba966 | |
![]() |
84927c2361 | |
![]() |
b568ac4e97 | |
![]() |
91bbb58d4f | |
![]() |
f278b38e6c | |
![]() |
4023b8980e | |
![]() |
1c1be18151 | |
![]() |
e5f591e509 | |
![]() |
60b22b3912 | |
|
86f03ffafc | |
|
27ee32054b | |
![]() |
3e3fd46cad | |
![]() |
7a752b177d | |
![]() |
abbabfdefd | |
![]() |
edd76b9286 | |
![]() |
a3ca94d433 | |
![]() |
91a804caf7 | |
![]() |
663deae21b | |
![]() |
dae5c9690f | |
![]() |
e65df07d79 | |
![]() |
246b6b52ec | |
![]() |
b9789183e3 | |
![]() |
7cf2c6021f | |
![]() |
e0f9a3d43d | |
![]() |
c1ef39b262 | |
![]() |
51643dc02c | |
![]() |
a078c07b59 | |
![]() |
b984790d5c | |
![]() |
876591100e | |
![]() |
ba9848ebe7 | |
![]() |
41c621cf55 | |
![]() |
09ac49dda5 | |
![]() |
b161b66d79 | |
![]() |
341a810afc | |
![]() |
2282c52efb | |
![]() |
34edd78ae7 | |
![]() |
8a536e83af | |
![]() |
016cf648da | |
![]() |
713e0bba18 | |
![]() |
36fb5a118c | |
![]() |
b756be1d6a | |
![]() |
348c2244f7 | |
![]() |
31738fc227 | |
![]() |
a93c98fb7c | |
![]() |
39193324e9 | |
![]() |
81743ce3bc | |
![]() |
e9ae536f04 | |
![]() |
186955fe4a | |
![]() |
8ce7fd95cb | |
![]() |
0867e5130f | |
![]() |
db476a1a9b | |
![]() |
fa1fd8a4ba | |
![]() |
0d7a11f3ab | |
![]() |
879e45e106 | |
![]() |
b3b0f75e9b | |
![]() |
3af75e1a1c | |
![]() |
5c8e561bd8 | |
![]() |
2b0c987558 | |
![]() |
6796805b21 | |
![]() |
5752f19b2f | |
|
eb52f05417 | |
|
786629dbff | |
|
7a00541375 | |
|
1d832a1723 | |
|
80ce40e492 | |
|
91f6dae56a | |
|
8c5a834b14 | |
|
57f420848e | |
|
fba58800a7 | |
|
c4a43c4392 | |
|
1153bd5ab6 | |
|
f732b0374c | |
![]() |
0852d0ac61 | |
![]() |
ee5090de96 | |
|
0d97d7d4f0 | |
![]() |
37005342ab | |
![]() |
9591c0a82a | |
![]() |
ffee782591 | |
![]() |
c55c04b137 | |
![]() |
049e5a6d5f | |
![]() |
be6bb690d2 | |
![]() |
7c2aa2209d | |
![]() |
a56ee23224 | |
![]() |
fc95fe9b82 | |
![]() |
838fd8b4c9 | |
![]() |
8ca1311626 | |
![]() |
869750e774 |
|
@ -37,13 +37,11 @@ public/react/yarn.lock
|
|||
|
||||
# Ignore react node_modules
|
||||
public/system/*
|
||||
public/react/*
|
||||
/public/react/.cache
|
||||
/public/react/node_modules/
|
||||
/public/react/config/stats.json
|
||||
/public/react/stats.json
|
||||
/public/react/.idea/*
|
||||
/public/react/build/*
|
||||
/public/h5build
|
||||
/public/npm-debug.log
|
||||
|
||||
|
@ -87,3 +85,4 @@ Dockerfile
|
|||
dump.rdb
|
||||
.tags*
|
||||
ceshi_user.xlsx
|
||||
public/trace_task_results
|
|
@ -23,7 +23,7 @@
|
|||
* Fix 版本库中附件下载400(#51625)
|
||||
* Fix loading页面优化(#51588)
|
||||
* Fix 提交详情页面优化(#51577)
|
||||
* Fix 修复易修复制功能(#51569)
|
||||
* Fix 修复疑修复制功能(#51569)
|
||||
* Fix 修复新建发行版用户信息显示错误的问题(#51665)
|
||||
* Fix 修复查看文件详细信息报错的问题(#51561)
|
||||
* Fix 修复提交记录中时间显示格式问题(#51526)
|
||||
|
@ -62,7 +62,7 @@
|
|||
## [v3.0.3](https://forgeplus.trustie.net/projects/jasder/forgeplus/releases) - 2021-05-08
|
||||
|
||||
* BUGFIXES
|
||||
* Fix 解决易修标题过长导致的排版问题(45469)
|
||||
* Fix 解决疑修标题过长导致的排版问题(45469)
|
||||
* Fix 解决合并请求详情页面排版错误的问题(45457)
|
||||
* FIX 解决转移仓库界面专有名词描述错误的问题(45455)
|
||||
* Fix 解决markdown格式文件自动生成数字排序的问题(45454)
|
||||
|
|
18
Gemfile
18
Gemfile
|
@ -1,4 +1,5 @@
|
|||
source 'https://gems.ruby-china.com'
|
||||
#source 'https://gems.ruby-china.com'
|
||||
source 'https://mirrors.cloud.tencent.com/rubygems/'
|
||||
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
|
||||
|
||||
gem 'rails', '~> 5.2.0'
|
||||
|
@ -69,6 +70,9 @@ group :development do
|
|||
gem 'web-console', '>= 3.3.0'
|
||||
gem 'listen', '>= 3.0.5', '< 3.2'
|
||||
gem 'spring'
|
||||
gem 'pry-rails'
|
||||
gem 'pry-remote'
|
||||
gem 'byebug', platforms: [:mri,:mingw,:x64_mingw]
|
||||
gem 'spring-watcher-listen', '~> 2.0.0'
|
||||
gem "annotate", "~> 2.6.0"
|
||||
end
|
||||
|
@ -118,6 +122,10 @@ gem 'deep_cloneable', '~> 3.0.0'
|
|||
# oauth2
|
||||
gem 'omniauth', '~> 1.9.0'
|
||||
gem 'omniauth-oauth2', '~> 1.6.0'
|
||||
gem "omniauth-github"
|
||||
gem "omniauth-rails_csrf_protection"
|
||||
gem 'omniauth-gitee', '~> 1.0.0'
|
||||
gem "omniauth-wechat-oauth2"
|
||||
|
||||
# global var
|
||||
gem 'request_store'
|
||||
|
@ -128,3 +136,11 @@ gem 'harmonious_dictionary', '~> 0.0.1'
|
|||
gem 'parallel', '~> 1.19', '>= 1.19.1'
|
||||
|
||||
gem 'letter_avatar'
|
||||
|
||||
gem 'jwt'
|
||||
|
||||
gem 'doorkeeper'
|
||||
|
||||
gem 'doorkeeper-jwt'
|
||||
|
||||
gem 'gitea-client', '~> 1.4.2'
|
||||
|
|
59
Gemfile.lock
59
Gemfile.lock
|
@ -1,5 +1,5 @@
|
|||
GEM
|
||||
remote: https://gems.ruby-china.com/
|
||||
remote: https://mirrors.cloud.tencent.com/rubygems/
|
||||
specs:
|
||||
aasm (5.0.6)
|
||||
concurrent-ruby (~> 1.0)
|
||||
|
@ -84,6 +84,7 @@ GEM
|
|||
builder (3.2.4)
|
||||
bulk_insert (1.7.0)
|
||||
activerecord (>= 3.2.0)
|
||||
byebug (11.1.3)
|
||||
capybara (3.15.1)
|
||||
addressable
|
||||
mini_mime (>= 0.1.3)
|
||||
|
@ -99,6 +100,7 @@ GEM
|
|||
archive-zip (~> 0.10)
|
||||
nokogiri (~> 1.8)
|
||||
chunky_png (1.3.11)
|
||||
coderay (1.1.3)
|
||||
concurrent-ruby (1.1.6)
|
||||
connection_pool (2.2.2)
|
||||
crass (1.0.6)
|
||||
|
@ -106,6 +108,12 @@ GEM
|
|||
activerecord (>= 3.1.0, < 7)
|
||||
diff-lcs (1.3)
|
||||
diffy (3.3.0)
|
||||
domain_name (0.5.20190701)
|
||||
unf (>= 0.0.5, < 1.0.0)
|
||||
doorkeeper (5.5.1)
|
||||
railties (>= 5)
|
||||
doorkeeper-jwt (0.4.1)
|
||||
jwt (>= 2.1)
|
||||
e2mmap (0.1.0)
|
||||
elasticsearch (7.5.0)
|
||||
elasticsearch-api (= 7.5.0)
|
||||
|
@ -129,6 +137,8 @@ GEM
|
|||
fugit (1.4.1)
|
||||
et-orbi (~> 1.1, >= 1.1.8)
|
||||
raabro (~> 1.4)
|
||||
gitea-client (1.4.1)
|
||||
rest-client (~> 2.1.0)
|
||||
globalid (0.4.2)
|
||||
activesupport (>= 4.2.0)
|
||||
grape-entity (0.7.1)
|
||||
|
@ -139,6 +149,9 @@ GEM
|
|||
harmonious_dictionary (0.0.1)
|
||||
hashie (3.6.0)
|
||||
htmlentities (4.3.4)
|
||||
http-accept (1.7.0)
|
||||
http-cookie (1.0.5)
|
||||
domain_name (~> 0.5)
|
||||
i18n (1.8.2)
|
||||
concurrent-ruby (~> 1.0)
|
||||
io-like (0.3.1)
|
||||
|
@ -176,6 +189,9 @@ GEM
|
|||
mimemagic (~> 0.3.2)
|
||||
maruku (0.7.3)
|
||||
method_source (0.9.2)
|
||||
mime-types (3.4.1)
|
||||
mime-types-data (~> 3.2015)
|
||||
mime-types-data (3.2023.0218.1)
|
||||
mimemagic (0.3.10)
|
||||
nokogiri (~> 1)
|
||||
rake
|
||||
|
@ -189,6 +205,7 @@ GEM
|
|||
mustermann (1.1.1)
|
||||
ruby2_keywords (~> 0.0.1)
|
||||
mysql2 (0.5.3)
|
||||
netrc (0.11.0)
|
||||
nio4r (2.5.2)
|
||||
nokogiri (1.10.8)
|
||||
mini_portile2 (~> 2.4.0)
|
||||
|
@ -205,9 +222,21 @@ GEM
|
|||
addressable (~> 2.3)
|
||||
nokogiri (~> 1.5)
|
||||
omniauth (~> 1.2)
|
||||
omniauth-gitee (1.0.0)
|
||||
omniauth (>= 1.5, < 3.0)
|
||||
omniauth-oauth2 (>= 1.4.0, < 2.0)
|
||||
omniauth-github (1.4.0)
|
||||
omniauth (~> 1.5)
|
||||
omniauth-oauth2 (>= 1.4.0, < 2.0)
|
||||
omniauth-oauth2 (1.6.0)
|
||||
oauth2 (~> 1.1)
|
||||
omniauth (~> 1.9)
|
||||
omniauth-rails_csrf_protection (0.1.2)
|
||||
actionpack (>= 4.2)
|
||||
omniauth (>= 1.3.1)
|
||||
omniauth-wechat-oauth2 (0.2.2)
|
||||
omniauth (>= 1.3.2)
|
||||
omniauth-oauth2 (>= 1.1.1)
|
||||
parallel (1.19.1)
|
||||
parser (2.7.1.1)
|
||||
ast (~> 2.4.0)
|
||||
|
@ -217,6 +246,14 @@ GEM
|
|||
popper_js (1.16.0)
|
||||
powerpack (0.1.2)
|
||||
prettier (0.18.2)
|
||||
pry (0.12.2)
|
||||
coderay (~> 1.1.0)
|
||||
method_source (~> 0.9.0)
|
||||
pry-rails (0.3.9)
|
||||
pry (>= 0.10.4)
|
||||
pry-remote (0.1.8)
|
||||
pry (~> 0.9)
|
||||
slop (~> 3.0)
|
||||
public_suffix (4.0.3)
|
||||
puma (3.12.2)
|
||||
raabro (1.4.0)
|
||||
|
@ -288,6 +325,11 @@ GEM
|
|||
regexp_parser (1.7.0)
|
||||
request_store (1.5.0)
|
||||
rack (>= 1.4)
|
||||
rest-client (2.1.0)
|
||||
http-accept (>= 1.7.0, < 2.0)
|
||||
http-cookie (>= 1.0.2, < 2.0)
|
||||
mime-types (>= 1.16, < 4.0)
|
||||
netrc (~> 0.8)
|
||||
reverse_markdown (1.4.0)
|
||||
nokogiri
|
||||
roo (2.8.3)
|
||||
|
@ -376,6 +418,7 @@ GEM
|
|||
rack (~> 2.0)
|
||||
rack-protection (= 2.0.8.1)
|
||||
tilt (~> 2.0)
|
||||
slop (3.6.0)
|
||||
solargraph (0.38.6)
|
||||
backport (~> 1.1)
|
||||
benchmark
|
||||
|
@ -414,6 +457,9 @@ GEM
|
|||
thread_safe (~> 0.1)
|
||||
uglifier (4.2.0)
|
||||
execjs (>= 0.3.0, < 3)
|
||||
unf (0.1.4)
|
||||
unf_ext
|
||||
unf_ext (0.0.8.2)
|
||||
unicode-display_width (1.6.1)
|
||||
web-console (3.7.0)
|
||||
actionview (>= 5.0)
|
||||
|
@ -444,20 +490,25 @@ DEPENDENCIES
|
|||
bootsnap (>= 1.1.0)
|
||||
bootstrap (~> 4.3.1)
|
||||
bulk_insert
|
||||
byebug
|
||||
capybara (>= 2.15, < 4.0)
|
||||
chartkick
|
||||
chinese_pinyin
|
||||
chromedriver-helper
|
||||
deep_cloneable (~> 3.0.0)
|
||||
diffy
|
||||
doorkeeper
|
||||
doorkeeper-jwt
|
||||
enumerize
|
||||
faraday (~> 0.15.4)
|
||||
font-awesome-sass (= 4.7.0)
|
||||
gitea-client (~> 1.4.1)
|
||||
grape-entity (~> 0.7.1)
|
||||
groupdate (~> 4.1.0)
|
||||
harmonious_dictionary (~> 0.0.1)
|
||||
jbuilder (~> 2.5)
|
||||
jquery-rails
|
||||
jwt
|
||||
kaminari (~> 1.1, >= 1.1.1)
|
||||
letter_avatar
|
||||
listen (>= 3.0.5, < 3.2)
|
||||
|
@ -465,10 +516,16 @@ DEPENDENCIES
|
|||
oauth2
|
||||
omniauth (~> 1.9.0)
|
||||
omniauth-cas
|
||||
omniauth-gitee (~> 1.0.0)
|
||||
omniauth-github
|
||||
omniauth-oauth2 (~> 1.6.0)
|
||||
omniauth-rails_csrf_protection
|
||||
omniauth-wechat-oauth2
|
||||
parallel (~> 1.19, >= 1.19.1)
|
||||
pdfkit
|
||||
prettier
|
||||
pry-rails
|
||||
pry-remote
|
||||
puma (~> 3.11)
|
||||
rack-cors
|
||||
rack-mini-profiler
|
||||
|
|
|
@ -75,6 +75,7 @@ gitea:
|
|||
access_key_secret: 'password'
|
||||
domain: 'http://www.gitea.example.com'
|
||||
base_url: '/api/v1'
|
||||
hat_base_url: '/api/hat'
|
||||
```
|
||||
|
||||
#### 6. 安装redis环境
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
//= require bootstrap-datepicker
|
||||
//= require bootstrap-datetimepicker
|
||||
//= require bootstrap.viewer
|
||||
//= require bootstrap/bootstrap-toggle
|
||||
//= require jquery.mloading
|
||||
//= require jquery-confirm.min
|
||||
//= require common
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
// Place all the behaviors and hooks related to the matching controller here.
|
||||
// All this logic will automatically be available in application.js.
|
|
@ -94,6 +94,20 @@ $(document).on('turbolinks:load', function(){
|
|||
}
|
||||
});
|
||||
});
|
||||
// reset user login times
|
||||
$('.users-list-container').on('click', '.fresh-gitea-token-action', function(){
|
||||
var $action = $(this);
|
||||
|
||||
var userId = $action.data('id');
|
||||
$.ajax({
|
||||
url: '/admins/users/' + userId + '/fresh_gitea_token',
|
||||
method: 'POST',
|
||||
dataType: 'json',
|
||||
success: function() {
|
||||
showSuccessNotify();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// ***************** reward grade modal *****************
|
||||
var $rewardGradeModal = $('.admin-users-reward-grade-modal');
|
||||
|
|
|
@ -0,0 +1,180 @@
|
|||
/*! ========================================================================
|
||||
* Bootstrap Toggle: bootstrap-toggle.js v2.2.0
|
||||
* http://www.bootstraptoggle.com
|
||||
* ========================================================================
|
||||
* Copyright 2014 Min Hur, The New York Times Company
|
||||
* Licensed under MIT
|
||||
* ======================================================================== */
|
||||
|
||||
|
||||
+function ($) {
|
||||
'use strict';
|
||||
|
||||
// TOGGLE PUBLIC CLASS DEFINITION
|
||||
// ==============================
|
||||
|
||||
var Toggle = function (element, options) {
|
||||
this.$element = $(element)
|
||||
this.options = $.extend({}, this.defaults(), options)
|
||||
this.render()
|
||||
}
|
||||
|
||||
Toggle.VERSION = '2.2.0'
|
||||
|
||||
Toggle.DEFAULTS = {
|
||||
on: 'On',
|
||||
off: 'Off',
|
||||
onstyle: 'primary',
|
||||
offstyle: 'default',
|
||||
size: 'normal',
|
||||
style: '',
|
||||
width: null,
|
||||
height: null
|
||||
}
|
||||
|
||||
Toggle.prototype.defaults = function() {
|
||||
return {
|
||||
on: this.$element.attr('data-on') || Toggle.DEFAULTS.on,
|
||||
off: this.$element.attr('data-off') || Toggle.DEFAULTS.off,
|
||||
onstyle: this.$element.attr('data-onstyle') || Toggle.DEFAULTS.onstyle,
|
||||
offstyle: this.$element.attr('data-offstyle') || Toggle.DEFAULTS.offstyle,
|
||||
size: this.$element.attr('data-size') || Toggle.DEFAULTS.size,
|
||||
style: this.$element.attr('data-style') || Toggle.DEFAULTS.style,
|
||||
width: this.$element.attr('data-width') || Toggle.DEFAULTS.width,
|
||||
height: this.$element.attr('data-height') || Toggle.DEFAULTS.height
|
||||
}
|
||||
}
|
||||
|
||||
Toggle.prototype.render = function () {
|
||||
this._onstyle = 'btn-' + this.options.onstyle
|
||||
this._offstyle = 'btn-' + this.options.offstyle
|
||||
var size = this.options.size === 'large' ? 'btn-lg'
|
||||
: this.options.size === 'small' ? 'btn-sm'
|
||||
: this.options.size === 'mini' ? 'btn-xs'
|
||||
: ''
|
||||
var $toggleOn = $('<label class="btn">').html(this.options.on)
|
||||
.addClass(this._onstyle + ' ' + size)
|
||||
var $toggleOff = $('<label class="btn">').html(this.options.off)
|
||||
.addClass(this._offstyle + ' ' + size + ' active')
|
||||
var $toggleHandle = $('<span class="toggle-handle btn btn-default">')
|
||||
.addClass(size)
|
||||
var $toggleGroup = $('<div class="toggle-group">')
|
||||
.append($toggleOn, $toggleOff, $toggleHandle)
|
||||
var $toggle = $('<div class="toggle btn" data-toggle="toggle">')
|
||||
.addClass( this.$element.prop('checked') ? this._onstyle : this._offstyle+' off' )
|
||||
.addClass(size).addClass(this.options.style)
|
||||
|
||||
this.$element.wrap($toggle)
|
||||
$.extend(this, {
|
||||
$toggle: this.$element.parent(),
|
||||
$toggleOn: $toggleOn,
|
||||
$toggleOff: $toggleOff,
|
||||
$toggleGroup: $toggleGroup
|
||||
})
|
||||
this.$toggle.append($toggleGroup)
|
||||
|
||||
var width = this.options.width || Math.max($toggleOn.outerWidth(), $toggleOff.outerWidth())+($toggleHandle.outerWidth()/2)
|
||||
var height = this.options.height || Math.max($toggleOn.outerHeight(), $toggleOff.outerHeight())
|
||||
$toggleOn.addClass('toggle-on')
|
||||
$toggleOff.addClass('toggle-off')
|
||||
this.$toggle.css({ width: width, height: height })
|
||||
if (this.options.height) {
|
||||
$toggleOn.css('line-height', $toggleOn.height() + 'px')
|
||||
$toggleOff.css('line-height', $toggleOff.height() + 'px')
|
||||
}
|
||||
this.update(true)
|
||||
this.trigger(true)
|
||||
}
|
||||
|
||||
Toggle.prototype.toggle = function () {
|
||||
if (this.$element.prop('checked')) this.off()
|
||||
else this.on()
|
||||
}
|
||||
|
||||
Toggle.prototype.on = function (silent) {
|
||||
if (this.$element.prop('disabled')) return false
|
||||
this.$toggle.removeClass(this._offstyle + ' off').addClass(this._onstyle)
|
||||
this.$element.prop('checked', true)
|
||||
if (!silent) this.trigger()
|
||||
}
|
||||
|
||||
Toggle.prototype.off = function (silent) {
|
||||
if (this.$element.prop('disabled')) return false
|
||||
this.$toggle.removeClass(this._onstyle).addClass(this._offstyle + ' off')
|
||||
this.$element.prop('checked', false)
|
||||
if (!silent) this.trigger()
|
||||
}
|
||||
|
||||
Toggle.prototype.enable = function () {
|
||||
this.$toggle.removeAttr('disabled')
|
||||
this.$element.prop('disabled', false)
|
||||
}
|
||||
|
||||
Toggle.prototype.disable = function () {
|
||||
this.$toggle.attr('disabled', 'disabled')
|
||||
this.$element.prop('disabled', true)
|
||||
}
|
||||
|
||||
Toggle.prototype.update = function (silent) {
|
||||
if (this.$element.prop('disabled')) this.disable()
|
||||
else this.enable()
|
||||
if (this.$element.prop('checked')) this.on(silent)
|
||||
else this.off(silent)
|
||||
}
|
||||
|
||||
Toggle.prototype.trigger = function (silent) {
|
||||
this.$element.off('change.bs.toggle')
|
||||
if (!silent) this.$element.change()
|
||||
this.$element.on('change.bs.toggle', $.proxy(function() {
|
||||
this.update()
|
||||
}, this))
|
||||
}
|
||||
|
||||
Toggle.prototype.destroy = function() {
|
||||
this.$element.off('change.bs.toggle')
|
||||
this.$toggleGroup.remove()
|
||||
this.$element.removeData('bs.toggle')
|
||||
this.$element.unwrap()
|
||||
}
|
||||
|
||||
// TOGGLE PLUGIN DEFINITION
|
||||
// ========================
|
||||
|
||||
function Plugin(option) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
var data = $this.data('bs.toggle')
|
||||
var options = typeof option == 'object' && option
|
||||
|
||||
if (!data) $this.data('bs.toggle', (data = new Toggle(this, options)))
|
||||
if (typeof option == 'string' && data[option]) data[option]()
|
||||
})
|
||||
}
|
||||
|
||||
var old = $.fn.bootstrapToggle
|
||||
|
||||
$.fn.bootstrapToggle = Plugin
|
||||
$.fn.bootstrapToggle.Constructor = Toggle
|
||||
|
||||
// TOGGLE NO CONFLICT
|
||||
// ==================
|
||||
|
||||
$.fn.toggle.noConflict = function () {
|
||||
$.fn.bootstrapToggle = old
|
||||
return this
|
||||
}
|
||||
|
||||
// TOGGLE DATA-API
|
||||
// ===============
|
||||
|
||||
$(function() {
|
||||
$('input[type=checkbox][data-toggle^=toggle]').bootstrapToggle()
|
||||
})
|
||||
|
||||
$(document).on('click.bs.toggle', 'div[data-toggle^=toggle]', function(e) {
|
||||
var $checkbox = $(this).find('input[type=checkbox]')
|
||||
$checkbox.bootstrapToggle('toggle')
|
||||
e.preventDefault()
|
||||
})
|
||||
|
||||
}(jQuery);
|
|
@ -0,0 +1,9 @@
|
|||
/*! ========================================================================
|
||||
* Bootstrap Toggle: bootstrap-toggle.js v2.2.0
|
||||
* http://www.bootstraptoggle.com
|
||||
* ========================================================================
|
||||
* Copyright 2014 Min Hur, The New York Times Company
|
||||
* Licensed under MIT
|
||||
* ======================================================================== */
|
||||
+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.toggle"),f="object"==typeof b&&b;e||d.data("bs.toggle",e=new c(this,f)),"string"==typeof b&&e[b]&&e[b]()})}var c=function(b,c){this.$element=a(b),this.options=a.extend({},this.defaults(),c),this.render()};c.VERSION="2.2.0",c.DEFAULTS={on:"On",off:"Off",onstyle:"primary",offstyle:"default",size:"normal",style:"",width:null,height:null},c.prototype.defaults=function(){return{on:this.$element.attr("data-on")||c.DEFAULTS.on,off:this.$element.attr("data-off")||c.DEFAULTS.off,onstyle:this.$element.attr("data-onstyle")||c.DEFAULTS.onstyle,offstyle:this.$element.attr("data-offstyle")||c.DEFAULTS.offstyle,size:this.$element.attr("data-size")||c.DEFAULTS.size,style:this.$element.attr("data-style")||c.DEFAULTS.style,width:this.$element.attr("data-width")||c.DEFAULTS.width,height:this.$element.attr("data-height")||c.DEFAULTS.height}},c.prototype.render=function(){this._onstyle="btn-"+this.options.onstyle,this._offstyle="btn-"+this.options.offstyle;var b="large"===this.options.size?"btn-lg":"small"===this.options.size?"btn-sm":"mini"===this.options.size?"btn-xs":"",c=a('<label class="btn">').html(this.options.on).addClass(this._onstyle+" "+b),d=a('<label class="btn">').html(this.options.off).addClass(this._offstyle+" "+b+" active"),e=a('<span class="toggle-handle btn btn-default">').addClass(b),f=a('<div class="toggle-group">').append(c,d,e),g=a('<div class="toggle btn" data-toggle="toggle">').addClass(this.$element.prop("checked")?this._onstyle:this._offstyle+" off").addClass(b).addClass(this.options.style);this.$element.wrap(g),a.extend(this,{$toggle:this.$element.parent(),$toggleOn:c,$toggleOff:d,$toggleGroup:f}),this.$toggle.append(f);var h=this.options.width||Math.max(c.outerWidth(),d.outerWidth())+e.outerWidth()/2,i=this.options.height||Math.max(c.outerHeight(),d.outerHeight());c.addClass("toggle-on"),d.addClass("toggle-off"),this.$toggle.css({width:h,height:i}),this.options.height&&(c.css("line-height",c.height()+"px"),d.css("line-height",d.height()+"px")),this.update(!0),this.trigger(!0)},c.prototype.toggle=function(){this.$element.prop("checked")?this.off():this.on()},c.prototype.on=function(a){return this.$element.prop("disabled")?!1:(this.$toggle.removeClass(this._offstyle+" off").addClass(this._onstyle),this.$element.prop("checked",!0),void(a||this.trigger()))},c.prototype.off=function(a){return this.$element.prop("disabled")?!1:(this.$toggle.removeClass(this._onstyle).addClass(this._offstyle+" off"),this.$element.prop("checked",!1),void(a||this.trigger()))},c.prototype.enable=function(){this.$toggle.removeAttr("disabled"),this.$element.prop("disabled",!1)},c.prototype.disable=function(){this.$toggle.attr("disabled","disabled"),this.$element.prop("disabled",!0)},c.prototype.update=function(a){this.$element.prop("disabled")?this.disable():this.enable(),this.$element.prop("checked")?this.on(a):this.off(a)},c.prototype.trigger=function(b){this.$element.off("change.bs.toggle"),b||this.$element.change(),this.$element.on("change.bs.toggle",a.proxy(function(){this.update()},this))},c.prototype.destroy=function(){this.$element.off("change.bs.toggle"),this.$toggleGroup.remove(),this.$element.removeData("bs.toggle"),this.$element.unwrap()};var d=a.fn.bootstrapToggle;a.fn.bootstrapToggle=b,a.fn.bootstrapToggle.Constructor=c,a.fn.toggle.noConflict=function(){return a.fn.bootstrapToggle=d,this},a(function(){a("input[type=checkbox][data-toggle^=toggle]").bootstrapToggle()}),a(document).on("click.bs.toggle","div[data-toggle^=toggle]",function(b){var c=a(this).find("input[type=checkbox]");c.bootstrapToggle("toggle"),b.preventDefault()})}(jQuery);
|
||||
//# sourceMappingURL=bootstrap-toggle.min.js.map
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"bootstrap-toggle.min.js","sources":["bootstrap-toggle.js"],"names":["$","Plugin","option","this","each","$this","data","options","Toggle","element","$element","extend","defaults","render","VERSION","DEFAULTS","on","off","onstyle","offstyle","size","style","width","height","prototype","attr","_onstyle","_offstyle","$toggleOn","html","addClass","$toggleOff","$toggleHandle","$toggleGroup","append","$toggle","prop","wrap","parent","Math","max","outerWidth","outerHeight","css","update","trigger","toggle","silent","removeClass","enable","removeAttr","disable","change","proxy","destroy","remove","removeData","unwrap","old","fn","bootstrapToggle","Constructor","noConflict","document","e","$checkbox","find","preventDefault","jQuery"],"mappings":";;;;;;;CASE,SAAUA,GACV,YAoID,SAASC,GAAOC,GACf,MAAOC,MAAKC,KAAK,WAChB,GAAIC,GAAUL,EAAEG,MACZG,EAAUD,EAAMC,KAAK,aACrBC,EAA2B,gBAAVL,IAAsBA,CAEtCI,IAAMD,EAAMC,KAAK,YAAcA,EAAO,GAAIE,GAAOL,KAAMI,IACvC,gBAAVL,IAAsBI,EAAKJ,IAASI,EAAKJ,OAtItD,GAAIM,GAAS,SAAUC,EAASF,GAC/BJ,KAAKO,SAAYV,EAAES,GACnBN,KAAKI,QAAYP,EAAEW,UAAWR,KAAKS,WAAYL,GAC/CJ,KAAKU,SAGNL,GAAOM,QAAW,QAElBN,EAAOO,UACNC,GAAI,KACJC,IAAK,MACLC,QAAS,UACTC,SAAU,UACVC,KAAM,SACNC,MAAO,GACPC,MAAO,KACPC,OAAQ,MAGTf,EAAOgB,UAAUZ,SAAW,WAC3B,OACCI,GAAIb,KAAKO,SAASe,KAAK,YAAcjB,EAAOO,SAASC,GACrDC,IAAKd,KAAKO,SAASe,KAAK,aAAejB,EAAOO,SAASE,IACvDC,QAASf,KAAKO,SAASe,KAAK,iBAAmBjB,EAAOO,SAASG,QAC/DC,SAAUhB,KAAKO,SAASe,KAAK,kBAAoBjB,EAAOO,SAASI,SACjEC,KAAMjB,KAAKO,SAASe,KAAK,cAAgBjB,EAAOO,SAASK,KACzDC,MAAOlB,KAAKO,SAASe,KAAK,eAAiBjB,EAAOO,SAASM,MAC3DC,MAAOnB,KAAKO,SAASe,KAAK,eAAiBjB,EAAOO,SAASO,MAC3DC,OAAQpB,KAAKO,SAASe,KAAK,gBAAkBjB,EAAOO,SAASQ,SAI/Df,EAAOgB,UAAUX,OAAS,WACzBV,KAAKuB,SAAW,OAASvB,KAAKI,QAAQW,QACtCf,KAAKwB,UAAY,OAASxB,KAAKI,QAAQY,QACvC,IAAIC,GAA6B,UAAtBjB,KAAKI,QAAQa,KAAmB,SAClB,UAAtBjB,KAAKI,QAAQa,KAAmB,SACV,SAAtBjB,KAAKI,QAAQa,KAAkB,SAC/B,GACCQ,EAAY5B,EAAE,uBAAuB6B,KAAK1B,KAAKI,QAAQS,IACzDc,SAAS3B,KAAKuB,SAAW,IAAMN,GAC7BW,EAAa/B,EAAE,uBAAuB6B,KAAK1B,KAAKI,QAAQU,KAC1Da,SAAS3B,KAAKwB,UAAY,IAAMP,EAAO,WACrCY,EAAgBhC,EAAE,gDACpB8B,SAASV,GACPa,EAAejC,EAAE,8BACnBkC,OAAON,EAAWG,EAAYC,GAC5BG,EAAUnC,EAAE,iDACd8B,SAAU3B,KAAKO,SAAS0B,KAAK,WAAajC,KAAKuB,SAAWvB,KAAKwB,UAAU,QACzEG,SAASV,GAAMU,SAAS3B,KAAKI,QAAQc,MAEvClB,MAAKO,SAAS2B,KAAKF,GACnBnC,EAAEW,OAAOR,MACRgC,QAAShC,KAAKO,SAAS4B,SACvBV,UAAWA,EACXG,WAAYA,EACZE,aAAcA,IAEf9B,KAAKgC,QAAQD,OAAOD,EAEpB,IAAIX,GAAQnB,KAAKI,QAAQe,OAASiB,KAAKC,IAAIZ,EAAUa,aAAcV,EAAWU,cAAeT,EAAcS,aAAa,EACpHlB,EAASpB,KAAKI,QAAQgB,QAAUgB,KAAKC,IAAIZ,EAAUc,cAAeX,EAAWW,cACjFd,GAAUE,SAAS,aACnBC,EAAWD,SAAS,cACpB3B,KAAKgC,QAAQQ,KAAMrB,MAAOA,EAAOC,OAAQA,IACrCpB,KAAKI,QAAQgB,SAChBK,EAAUe,IAAI,cAAef,EAAUL,SAAW,MAClDQ,EAAWY,IAAI,cAAeZ,EAAWR,SAAW,OAErDpB,KAAKyC,QAAO,GACZzC,KAAK0C,SAAQ,IAGdrC,EAAOgB,UAAUsB,OAAS,WACrB3C,KAAKO,SAAS0B,KAAK,WAAYjC,KAAKc,MACnCd,KAAKa,MAGXR,EAAOgB,UAAUR,GAAK,SAAU+B,GAC/B,MAAI5C,MAAKO,SAAS0B,KAAK,aAAoB,GAC3CjC,KAAKgC,QAAQa,YAAY7C,KAAKwB,UAAY,QAAQG,SAAS3B,KAAKuB,UAChEvB,KAAKO,SAAS0B,KAAK,WAAW,QACzBW,GAAQ5C,KAAK0C,aAGnBrC,EAAOgB,UAAUP,IAAM,SAAU8B,GAChC,MAAI5C,MAAKO,SAAS0B,KAAK,aAAoB,GAC3CjC,KAAKgC,QAAQa,YAAY7C,KAAKuB,UAAUI,SAAS3B,KAAKwB,UAAY,QAClExB,KAAKO,SAAS0B,KAAK,WAAW,QACzBW,GAAQ5C,KAAK0C,aAGnBrC,EAAOgB,UAAUyB,OAAS,WACzB9C,KAAKgC,QAAQe,WAAW,YACxB/C,KAAKO,SAAS0B,KAAK,YAAY,IAGhC5B,EAAOgB,UAAU2B,QAAU,WAC1BhD,KAAKgC,QAAQV,KAAK,WAAY,YAC9BtB,KAAKO,SAAS0B,KAAK,YAAY,IAGhC5B,EAAOgB,UAAUoB,OAAS,SAAUG,GAC/B5C,KAAKO,SAAS0B,KAAK,YAAajC,KAAKgD,UACpChD,KAAK8C,SACN9C,KAAKO,SAAS0B,KAAK,WAAYjC,KAAKa,GAAG+B,GACtC5C,KAAKc,IAAI8B,IAGfvC,EAAOgB,UAAUqB,QAAU,SAAUE,GACpC5C,KAAKO,SAASO,IAAI,oBACb8B,GAAQ5C,KAAKO,SAAS0C,SAC3BjD,KAAKO,SAASM,GAAG,mBAAoBhB,EAAEqD,MAAM,WAC5ClD,KAAKyC,UACHzC,QAGJK,EAAOgB,UAAU8B,QAAU,WAC1BnD,KAAKO,SAASO,IAAI,oBAClBd,KAAK8B,aAAasB,SAClBpD,KAAKO,SAAS8C,WAAW,aACzBrD,KAAKO,SAAS+C,SAiBf,IAAIC,GAAM1D,EAAE2D,GAAGC,eAEf5D,GAAE2D,GAAGC,gBAA8B3D,EACnCD,EAAE2D,GAAGC,gBAAgBC,YAAcrD,EAKnCR,EAAE2D,GAAGb,OAAOgB,WAAa,WAExB,MADA9D,GAAE2D,GAAGC,gBAAkBF,EAChBvD,MAMRH,EAAE,WACDA,EAAE,6CAA6C4D,oBAGhD5D,EAAE+D,UAAU/C,GAAG,kBAAmB,2BAA4B,SAASgD,GACtE,GAAIC,GAAYjE,EAAEG,MAAM+D,KAAK,uBAC7BD,GAAUL,gBAAgB,UAC1BI,EAAEG,oBAGFC"}
|
|
@ -0,0 +1,180 @@
|
|||
/*! ========================================================================
|
||||
* Bootstrap Toggle: bootstrap2-toggle.js v2.2.0
|
||||
* http://www.bootstraptoggle.com
|
||||
* ========================================================================
|
||||
* Copyright 2014 Min Hur, The New York Times Company
|
||||
* Licensed under MIT
|
||||
* ======================================================================== */
|
||||
|
||||
|
||||
+function ($) {
|
||||
'use strict';
|
||||
|
||||
// TOGGLE PUBLIC CLASS DEFINITION
|
||||
// ==============================
|
||||
|
||||
var Toggle = function (element, options) {
|
||||
this.$element = $(element)
|
||||
this.options = $.extend({}, this.defaults(), options)
|
||||
this.render()
|
||||
}
|
||||
|
||||
Toggle.VERSION = '2.2.0'
|
||||
|
||||
Toggle.DEFAULTS = {
|
||||
on: 'On',
|
||||
off: 'Off',
|
||||
onstyle: 'primary',
|
||||
offstyle: 'default',
|
||||
size: 'normal',
|
||||
style: '',
|
||||
width: null,
|
||||
height: null
|
||||
}
|
||||
|
||||
Toggle.prototype.defaults = function() {
|
||||
return {
|
||||
on: this.$element.attr('data-on') || Toggle.DEFAULTS.on,
|
||||
off: this.$element.attr('data-off') || Toggle.DEFAULTS.off,
|
||||
onstyle: this.$element.attr('data-onstyle') || Toggle.DEFAULTS.onstyle,
|
||||
offstyle: this.$element.attr('data-offstyle') || Toggle.DEFAULTS.offstyle,
|
||||
size: this.$element.attr('data-size') || Toggle.DEFAULTS.size,
|
||||
style: this.$element.attr('data-style') || Toggle.DEFAULTS.style,
|
||||
width: this.$element.attr('data-width') || Toggle.DEFAULTS.width,
|
||||
height: this.$element.attr('data-height') || Toggle.DEFAULTS.height
|
||||
}
|
||||
}
|
||||
|
||||
Toggle.prototype.render = function () {
|
||||
this._onstyle = 'btn-' + this.options.onstyle
|
||||
this._offstyle = 'btn-' + this.options.offstyle
|
||||
var size = this.options.size === 'large' ? 'btn-large'
|
||||
: this.options.size === 'small' ? 'btn-small'
|
||||
: this.options.size === 'mini' ? 'btn-mini'
|
||||
: ''
|
||||
var $toggleOn = $('<label class="btn">').html(this.options.on)
|
||||
.addClass(this._onstyle + ' ' + size)
|
||||
var $toggleOff = $('<label class="btn">').html(this.options.off)
|
||||
.addClass(this._offstyle + ' ' + size + ' active')
|
||||
var $toggleHandle = $('<span class="toggle-handle btn btn-default">')
|
||||
.addClass(size)
|
||||
var $toggleGroup = $('<div class="toggle-group">')
|
||||
.append($toggleOn, $toggleOff, $toggleHandle)
|
||||
var $toggle = $('<div class="toggle btn" data-toggle="toggle">')
|
||||
.addClass( this.$element.prop('checked') ? this._onstyle : this._offstyle+' off' )
|
||||
.addClass(size).addClass(this.options.style)
|
||||
|
||||
this.$element.wrap($toggle)
|
||||
$.extend(this, {
|
||||
$toggle: this.$element.parent(),
|
||||
$toggleOn: $toggleOn,
|
||||
$toggleOff: $toggleOff,
|
||||
$toggleGroup: $toggleGroup
|
||||
})
|
||||
this.$toggle.append($toggleGroup)
|
||||
|
||||
var width = this.options.width || Math.max($toggleOn.width(), $toggleOff.width())+($toggleHandle.outerWidth()/2)
|
||||
var height = this.options.height || Math.max($toggleOn.height(), $toggleOff.height())
|
||||
$toggleOn.addClass('toggle-on')
|
||||
$toggleOff.addClass('toggle-off')
|
||||
this.$toggle.css({ width: width, height: height })
|
||||
if (this.options.height) {
|
||||
$toggleOn.css('line-height', $toggleOn.height() + 'px')
|
||||
$toggleOff.css('line-height', $toggleOff.height() + 'px')
|
||||
}
|
||||
this.update(true)
|
||||
this.trigger(true)
|
||||
}
|
||||
|
||||
Toggle.prototype.toggle = function () {
|
||||
if (this.$element.prop('checked')) this.off()
|
||||
else this.on()
|
||||
}
|
||||
|
||||
Toggle.prototype.on = function (silent) {
|
||||
if (this.$element.prop('disabled')) return false
|
||||
this.$toggle.removeClass(this._offstyle + ' off').addClass(this._onstyle)
|
||||
this.$element.prop('checked', true)
|
||||
if (!silent) this.trigger()
|
||||
}
|
||||
|
||||
Toggle.prototype.off = function (silent) {
|
||||
if (this.$element.prop('disabled')) return false
|
||||
this.$toggle.removeClass(this._onstyle).addClass(this._offstyle + ' off')
|
||||
this.$element.prop('checked', false)
|
||||
if (!silent) this.trigger()
|
||||
}
|
||||
|
||||
Toggle.prototype.enable = function () {
|
||||
this.$toggle.removeAttr('disabled')
|
||||
this.$element.prop('disabled', false)
|
||||
}
|
||||
|
||||
Toggle.prototype.disable = function () {
|
||||
this.$toggle.attr('disabled', 'disabled')
|
||||
this.$element.prop('disabled', true)
|
||||
}
|
||||
|
||||
Toggle.prototype.update = function (silent) {
|
||||
if (this.$element.prop('disabled')) this.disable()
|
||||
else this.enable()
|
||||
if (this.$element.prop('checked')) this.on(silent)
|
||||
else this.off(silent)
|
||||
}
|
||||
|
||||
Toggle.prototype.trigger = function (silent) {
|
||||
this.$element.off('change.bs.toggle')
|
||||
if (!silent) this.$element.change()
|
||||
this.$element.on('change.bs.toggle', $.proxy(function() {
|
||||
this.update()
|
||||
}, this))
|
||||
}
|
||||
|
||||
Toggle.prototype.destroy = function() {
|
||||
this.$element.off('change.bs.toggle')
|
||||
this.$toggleGroup.remove()
|
||||
this.$element.removeData('bs.toggle')
|
||||
this.$element.unwrap()
|
||||
}
|
||||
|
||||
// TOGGLE PLUGIN DEFINITION
|
||||
// ========================
|
||||
|
||||
function Plugin(option) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
var data = $this.data('bs.toggle')
|
||||
var options = typeof option == 'object' && option
|
||||
|
||||
if (!data) $this.data('bs.toggle', (data = new Toggle(this, options)))
|
||||
if (typeof option == 'string' && data[option]) data[option]()
|
||||
})
|
||||
}
|
||||
|
||||
var old = $.fn.bootstrapToggle
|
||||
|
||||
$.fn.bootstrapToggle = Plugin
|
||||
$.fn.bootstrapToggle.Constructor = Toggle
|
||||
|
||||
// TOGGLE NO CONFLICT
|
||||
// ==================
|
||||
|
||||
$.fn.toggle.noConflict = function () {
|
||||
$.fn.bootstrapToggle = old
|
||||
return this
|
||||
}
|
||||
|
||||
// TOGGLE DATA-API
|
||||
// ===============
|
||||
|
||||
$(function() {
|
||||
$('input[type=checkbox][data-toggle^=toggle]').bootstrapToggle()
|
||||
})
|
||||
|
||||
$(document).on('click.bs.toggle', 'div[data-toggle^=toggle]', function(e) {
|
||||
var $checkbox = $(this).find('input[type=checkbox]')
|
||||
$checkbox.bootstrapToggle('toggle')
|
||||
e.preventDefault()
|
||||
})
|
||||
|
||||
}(jQuery);
|
|
@ -0,0 +1,9 @@
|
|||
/*! ========================================================================
|
||||
* Bootstrap Toggle: bootstrap2-toggle.js v2.2.0
|
||||
* http://www.bootstraptoggle.com
|
||||
* ========================================================================
|
||||
* Copyright 2014 Min Hur, The New York Times Company
|
||||
* Licensed under MIT
|
||||
* ======================================================================== */
|
||||
+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.toggle"),f="object"==typeof b&&b;e||d.data("bs.toggle",e=new c(this,f)),"string"==typeof b&&e[b]&&e[b]()})}var c=function(b,c){this.$element=a(b),this.options=a.extend({},this.defaults(),c),this.render()};c.VERSION="2.2.0",c.DEFAULTS={on:"On",off:"Off",onstyle:"primary",offstyle:"default",size:"normal",style:"",width:null,height:null},c.prototype.defaults=function(){return{on:this.$element.attr("data-on")||c.DEFAULTS.on,off:this.$element.attr("data-off")||c.DEFAULTS.off,onstyle:this.$element.attr("data-onstyle")||c.DEFAULTS.onstyle,offstyle:this.$element.attr("data-offstyle")||c.DEFAULTS.offstyle,size:this.$element.attr("data-size")||c.DEFAULTS.size,style:this.$element.attr("data-style")||c.DEFAULTS.style,width:this.$element.attr("data-width")||c.DEFAULTS.width,height:this.$element.attr("data-height")||c.DEFAULTS.height}},c.prototype.render=function(){this._onstyle="btn-"+this.options.onstyle,this._offstyle="btn-"+this.options.offstyle;var b="large"===this.options.size?"btn-large":"small"===this.options.size?"btn-small":"mini"===this.options.size?"btn-mini":"",c=a('<label class="btn">').html(this.options.on).addClass(this._onstyle+" "+b),d=a('<label class="btn">').html(this.options.off).addClass(this._offstyle+" "+b+" active"),e=a('<span class="toggle-handle btn btn-default">').addClass(b),f=a('<div class="toggle-group">').append(c,d,e),g=a('<div class="toggle btn" data-toggle="toggle">').addClass(this.$element.prop("checked")?this._onstyle:this._offstyle+" off").addClass(b).addClass(this.options.style);this.$element.wrap(g),a.extend(this,{$toggle:this.$element.parent(),$toggleOn:c,$toggleOff:d,$toggleGroup:f}),this.$toggle.append(f);var h=this.options.width||Math.max(c.width(),d.width())+e.outerWidth()/2,i=this.options.height||Math.max(c.height(),d.height());c.addClass("toggle-on"),d.addClass("toggle-off"),this.$toggle.css({width:h,height:i}),this.options.height&&(c.css("line-height",c.height()+"px"),d.css("line-height",d.height()+"px")),this.update(!0),this.trigger(!0)},c.prototype.toggle=function(){this.$element.prop("checked")?this.off():this.on()},c.prototype.on=function(a){return this.$element.prop("disabled")?!1:(this.$toggle.removeClass(this._offstyle+" off").addClass(this._onstyle),this.$element.prop("checked",!0),void(a||this.trigger()))},c.prototype.off=function(a){return this.$element.prop("disabled")?!1:(this.$toggle.removeClass(this._onstyle).addClass(this._offstyle+" off"),this.$element.prop("checked",!1),void(a||this.trigger()))},c.prototype.enable=function(){this.$toggle.removeAttr("disabled"),this.$element.prop("disabled",!1)},c.prototype.disable=function(){this.$toggle.attr("disabled","disabled"),this.$element.prop("disabled",!0)},c.prototype.update=function(a){this.$element.prop("disabled")?this.disable():this.enable(),this.$element.prop("checked")?this.on(a):this.off(a)},c.prototype.trigger=function(b){this.$element.off("change.bs.toggle"),b||this.$element.change(),this.$element.on("change.bs.toggle",a.proxy(function(){this.update()},this))},c.prototype.destroy=function(){this.$element.off("change.bs.toggle"),this.$toggleGroup.remove(),this.$element.removeData("bs.toggle"),this.$element.unwrap()};var d=a.fn.bootstrapToggle;a.fn.bootstrapToggle=b,a.fn.bootstrapToggle.Constructor=c,a.fn.toggle.noConflict=function(){return a.fn.bootstrapToggle=d,this},a(function(){a("input[type=checkbox][data-toggle^=toggle]").bootstrapToggle()}),a(document).on("click.bs.toggle","div[data-toggle^=toggle]",function(b){var c=a(this).find("input[type=checkbox]");c.bootstrapToggle("toggle"),b.preventDefault()})}(jQuery);
|
||||
//# sourceMappingURL=bootstrap2-toggle.min.js.map
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"bootstrap2-toggle.min.js","sources":["bootstrap2-toggle.js"],"names":["$","Plugin","option","this","each","$this","data","options","Toggle","element","$element","extend","defaults","render","VERSION","DEFAULTS","on","off","onstyle","offstyle","size","style","width","height","prototype","attr","_onstyle","_offstyle","$toggleOn","html","addClass","$toggleOff","$toggleHandle","$toggleGroup","append","$toggle","prop","wrap","parent","Math","max","outerWidth","css","update","trigger","toggle","silent","removeClass","enable","removeAttr","disable","change","proxy","destroy","remove","removeData","unwrap","old","fn","bootstrapToggle","Constructor","noConflict","document","e","$checkbox","find","preventDefault","jQuery"],"mappings":";;;;;;;CASE,SAAUA,GACV,YAoID,SAASC,GAAOC,GACf,MAAOC,MAAKC,KAAK,WAChB,GAAIC,GAAUL,EAAEG,MACZG,EAAUD,EAAMC,KAAK,aACrBC,EAA2B,gBAAVL,IAAsBA,CAEtCI,IAAMD,EAAMC,KAAK,YAAcA,EAAO,GAAIE,GAAOL,KAAMI,IACvC,gBAAVL,IAAsBI,EAAKJ,IAASI,EAAKJ,OAtItD,GAAIM,GAAS,SAAUC,EAASF,GAC/BJ,KAAKO,SAAYV,EAAES,GACnBN,KAAKI,QAAYP,EAAEW,UAAWR,KAAKS,WAAYL,GAC/CJ,KAAKU,SAGNL,GAAOM,QAAW,QAElBN,EAAOO,UACNC,GAAI,KACJC,IAAK,MACLC,QAAS,UACTC,SAAU,UACVC,KAAM,SACNC,MAAO,GACPC,MAAO,KACPC,OAAQ,MAGTf,EAAOgB,UAAUZ,SAAW,WAC3B,OACCI,GAAIb,KAAKO,SAASe,KAAK,YAAcjB,EAAOO,SAASC,GACrDC,IAAKd,KAAKO,SAASe,KAAK,aAAejB,EAAOO,SAASE,IACvDC,QAASf,KAAKO,SAASe,KAAK,iBAAmBjB,EAAOO,SAASG,QAC/DC,SAAUhB,KAAKO,SAASe,KAAK,kBAAoBjB,EAAOO,SAASI,SACjEC,KAAMjB,KAAKO,SAASe,KAAK,cAAgBjB,EAAOO,SAASK,KACzDC,MAAOlB,KAAKO,SAASe,KAAK,eAAiBjB,EAAOO,SAASM,MAC3DC,MAAOnB,KAAKO,SAASe,KAAK,eAAiBjB,EAAOO,SAASO,MAC3DC,OAAQpB,KAAKO,SAASe,KAAK,gBAAkBjB,EAAOO,SAASQ,SAI/Df,EAAOgB,UAAUX,OAAS,WACzBV,KAAKuB,SAAW,OAASvB,KAAKI,QAAQW,QACtCf,KAAKwB,UAAY,OAASxB,KAAKI,QAAQY,QACvC,IAAIC,GAA6B,UAAtBjB,KAAKI,QAAQa,KAAmB,YAClB,UAAtBjB,KAAKI,QAAQa,KAAmB,YACV,SAAtBjB,KAAKI,QAAQa,KAAkB,WAC/B,GACCQ,EAAY5B,EAAE,uBAAuB6B,KAAK1B,KAAKI,QAAQS,IACzDc,SAAS3B,KAAKuB,SAAW,IAAMN,GAC7BW,EAAa/B,EAAE,uBAAuB6B,KAAK1B,KAAKI,QAAQU,KAC1Da,SAAS3B,KAAKwB,UAAY,IAAMP,EAAO,WACrCY,EAAgBhC,EAAE,gDACpB8B,SAASV,GACPa,EAAejC,EAAE,8BACnBkC,OAAON,EAAWG,EAAYC,GAC5BG,EAAUnC,EAAE,iDACd8B,SAAU3B,KAAKO,SAAS0B,KAAK,WAAajC,KAAKuB,SAAWvB,KAAKwB,UAAU,QACzEG,SAASV,GAAMU,SAAS3B,KAAKI,QAAQc,MAEvClB,MAAKO,SAAS2B,KAAKF,GACnBnC,EAAEW,OAAOR,MACRgC,QAAShC,KAAKO,SAAS4B,SACvBV,UAAWA,EACXG,WAAYA,EACZE,aAAcA,IAEf9B,KAAKgC,QAAQD,OAAOD,EAEpB,IAAIX,GAAQnB,KAAKI,QAAQe,OAASiB,KAAKC,IAAIZ,EAAUN,QAASS,EAAWT,SAAUU,EAAcS,aAAa,EAC1GlB,EAASpB,KAAKI,QAAQgB,QAAUgB,KAAKC,IAAIZ,EAAUL,SAAUQ,EAAWR,SAC5EK,GAAUE,SAAS,aACnBC,EAAWD,SAAS,cACpB3B,KAAKgC,QAAQO,KAAMpB,MAAOA,EAAOC,OAAQA,IACrCpB,KAAKI,QAAQgB,SAChBK,EAAUc,IAAI,cAAed,EAAUL,SAAW,MAClDQ,EAAWW,IAAI,cAAeX,EAAWR,SAAW,OAErDpB,KAAKwC,QAAO,GACZxC,KAAKyC,SAAQ,IAGdpC,EAAOgB,UAAUqB,OAAS,WACrB1C,KAAKO,SAAS0B,KAAK,WAAYjC,KAAKc,MACnCd,KAAKa,MAGXR,EAAOgB,UAAUR,GAAK,SAAU8B,GAC/B,MAAI3C,MAAKO,SAAS0B,KAAK,aAAoB,GAC3CjC,KAAKgC,QAAQY,YAAY5C,KAAKwB,UAAY,QAAQG,SAAS3B,KAAKuB,UAChEvB,KAAKO,SAAS0B,KAAK,WAAW,QACzBU,GAAQ3C,KAAKyC,aAGnBpC,EAAOgB,UAAUP,IAAM,SAAU6B,GAChC,MAAI3C,MAAKO,SAAS0B,KAAK,aAAoB,GAC3CjC,KAAKgC,QAAQY,YAAY5C,KAAKuB,UAAUI,SAAS3B,KAAKwB,UAAY,QAClExB,KAAKO,SAAS0B,KAAK,WAAW,QACzBU,GAAQ3C,KAAKyC,aAGnBpC,EAAOgB,UAAUwB,OAAS,WACzB7C,KAAKgC,QAAQc,WAAW,YACxB9C,KAAKO,SAAS0B,KAAK,YAAY,IAGhC5B,EAAOgB,UAAU0B,QAAU,WAC1B/C,KAAKgC,QAAQV,KAAK,WAAY,YAC9BtB,KAAKO,SAAS0B,KAAK,YAAY,IAGhC5B,EAAOgB,UAAUmB,OAAS,SAAUG,GAC/B3C,KAAKO,SAAS0B,KAAK,YAAajC,KAAK+C,UACpC/C,KAAK6C,SACN7C,KAAKO,SAAS0B,KAAK,WAAYjC,KAAKa,GAAG8B,GACtC3C,KAAKc,IAAI6B,IAGftC,EAAOgB,UAAUoB,QAAU,SAAUE,GACpC3C,KAAKO,SAASO,IAAI,oBACb6B,GAAQ3C,KAAKO,SAASyC,SAC3BhD,KAAKO,SAASM,GAAG,mBAAoBhB,EAAEoD,MAAM,WAC5CjD,KAAKwC,UACHxC,QAGJK,EAAOgB,UAAU6B,QAAU,WAC1BlD,KAAKO,SAASO,IAAI,oBAClBd,KAAK8B,aAAaqB,SAClBnD,KAAKO,SAAS6C,WAAW,aACzBpD,KAAKO,SAAS8C,SAiBf,IAAIC,GAAMzD,EAAE0D,GAAGC,eAEf3D,GAAE0D,GAAGC,gBAA8B1D,EACnCD,EAAE0D,GAAGC,gBAAgBC,YAAcpD,EAKnCR,EAAE0D,GAAGb,OAAOgB,WAAa,WAExB,MADA7D,GAAE0D,GAAGC,gBAAkBF,EAChBtD,MAMRH,EAAE,WACDA,EAAE,6CAA6C2D,oBAGhD3D,EAAE8D,UAAU9C,GAAG,kBAAmB,2BAA4B,SAAS+C,GACtE,GAAIC,GAAYhE,EAAEG,MAAM8D,KAAK,uBAC7BD,GAAUL,gBAAgB,UAC1BI,EAAEG,oBAGFC"}
|
|
@ -8,6 +8,7 @@
|
|||
@import "jquery.mloading";
|
||||
@import "jquery-confirm.min";
|
||||
@import "bootstrap-datetimepicker.min";
|
||||
@import "bootstrap/bootstrap-toggle.min";
|
||||
|
||||
@import "codemirror/lib/codemirror";
|
||||
@import "editormd/css/editormd.min";
|
||||
|
@ -204,3 +205,13 @@ input.form-control {
|
|||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.table th, .table td {
|
||||
padding: 0.75rem 0.1rem;
|
||||
vertical-align: top;
|
||||
border-top: 1px solid #dee2e6;
|
||||
}
|
||||
|
||||
.table .thead-light th{
|
||||
white-space: nowrap;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
// Place all the styles related to the admins/organizations controller here.
|
||||
// They will automatically be included in application.css.
|
||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
|
@ -0,0 +1,83 @@
|
|||
/*! ========================================================================
|
||||
* Bootstrap Toggle: bootstrap-toggle.css v2.2.0
|
||||
* http://www.bootstraptoggle.com
|
||||
* ========================================================================
|
||||
* Copyright 2014 Min Hur, The New York Times Company
|
||||
* Licensed under MIT
|
||||
* ======================================================================== */
|
||||
|
||||
|
||||
.checkbox label .toggle,
|
||||
.checkbox-inline .toggle {
|
||||
margin-left: -20px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.toggle {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.toggle input[type="checkbox"] {
|
||||
display: none;
|
||||
}
|
||||
.toggle-group {
|
||||
position: absolute;
|
||||
width: 200%;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
transition: left 0.35s;
|
||||
-webkit-transition: left 0.35s;
|
||||
-moz-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
.toggle.off .toggle-group {
|
||||
left: -100%;
|
||||
}
|
||||
.toggle-on {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 50%;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
.toggle-off {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
right: 0;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
.toggle-handle {
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
padding-top: 0px;
|
||||
padding-bottom: 0px;
|
||||
height: 100%;
|
||||
width: 0px;
|
||||
border-width: 0 1px;
|
||||
}
|
||||
|
||||
.toggle.btn { min-width: 59px; min-height: 34px; }
|
||||
.toggle-on.btn { padding-right: 24px; }
|
||||
.toggle-off.btn { padding-left: 24px; }
|
||||
|
||||
.toggle.btn-lg { min-width: 79px; min-height: 45px; }
|
||||
.toggle-on.btn-lg { padding-right: 31px; }
|
||||
.toggle-off.btn-lg { padding-left: 31px; }
|
||||
.toggle-handle.btn-lg { width: 40px; }
|
||||
|
||||
.toggle.btn-sm { min-width: 50px; min-height: 30px;}
|
||||
.toggle-on.btn-sm { padding-right: 20px; }
|
||||
.toggle-off.btn-sm { padding-left: 20px; }
|
||||
|
||||
.toggle.btn-xs { min-width: 35px; min-height: 22px;}
|
||||
.toggle-on.btn-xs { padding-right: 12px; }
|
||||
.toggle-off.btn-xs { padding-left: 12px; }
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/*! ========================================================================
|
||||
* Bootstrap Toggle: bootstrap-toggle.css v2.2.0
|
||||
* http://www.bootstraptoggle.com
|
||||
* ========================================================================
|
||||
* Copyright 2014 Min Hur, The New York Times Company
|
||||
* Licensed under MIT
|
||||
* ======================================================================== */
|
||||
.checkbox label .toggle,.checkbox-inline .toggle{margin-left:-20px;margin-right:5px}
|
||||
.toggle{position:relative;overflow:hidden}
|
||||
.toggle input[type=checkbox]{display:none}
|
||||
.toggle-group{position:absolute;width:200%;top:0;bottom:0;left:0;transition:left .35s;-webkit-transition:left .35s;-moz-user-select:none;-webkit-user-select:none}
|
||||
.toggle.off .toggle-group{left:-100%}
|
||||
.toggle-on{position:absolute;top:0;bottom:0;left:0;right:50%;margin:0;border:0;border-radius:0}
|
||||
.toggle-off{position:absolute;top:0;bottom:0;left:50%;right:0;margin:0;border:0;border-radius:0}
|
||||
.toggle-handle{position:relative;margin:0 auto;padding-top:0;padding-bottom:0;height:100%;width:0;border-width:0 1px}
|
||||
.toggle.btn{min-width:59px;min-height:34px}
|
||||
.toggle-on.btn{padding-right:24px}
|
||||
.toggle-off.btn{padding-left:24px}
|
||||
.toggle.btn-lg{min-width:79px;min-height:45px}
|
||||
.toggle-on.btn-lg{padding-right:31px}
|
||||
.toggle-off.btn-lg{padding-left:31px}
|
||||
.toggle-handle.btn-lg{width:40px}
|
||||
.toggle.btn-sm{min-width:50px;min-height:30px}
|
||||
.toggle-on.btn-sm{padding-right:20px}
|
||||
.toggle-off.btn-sm{padding-left:20px}
|
||||
.toggle.btn-xs{min-width:35px;min-height:22px}
|
||||
.toggle-on.btn-xs{padding-right:12px}
|
||||
.toggle-off.btn-xs{padding-left:12px}
|
|
@ -0,0 +1,85 @@
|
|||
/*! ========================================================================
|
||||
* Bootstrap Toggle: bootstrap2-toggle.css v2.2.0
|
||||
* http://www.bootstraptoggle.com
|
||||
* ========================================================================
|
||||
* Copyright 2014 Min Hur, The New York Times Company
|
||||
* Licensed under MIT
|
||||
* ======================================================================== */
|
||||
|
||||
|
||||
label.checkbox .toggle,
|
||||
label.checkbox.inline .toggle {
|
||||
margin-left: -20px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.toggle {
|
||||
min-width: 40px;
|
||||
height: 20px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.toggle input[type="checkbox"] {
|
||||
display: none;
|
||||
}
|
||||
.toggle-group {
|
||||
position: absolute;
|
||||
width: 200%;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
transition: left 0.35s;
|
||||
-webkit-transition: left 0.35s;
|
||||
-moz-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
.toggle.off .toggle-group {
|
||||
left: -100%;
|
||||
}
|
||||
.toggle-on {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 50%;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
.toggle-off {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
right: 0;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
.toggle-handle {
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
padding-top: 0px;
|
||||
padding-bottom: 0px;
|
||||
height: 100%;
|
||||
width: 0px;
|
||||
border-width: 0 1px;
|
||||
}
|
||||
.toggle-handle.btn-mini {
|
||||
top: -1px;
|
||||
}
|
||||
.toggle.btn { min-width: 30px; }
|
||||
.toggle-on.btn { padding-right: 24px; }
|
||||
.toggle-off.btn { padding-left: 24px; }
|
||||
|
||||
.toggle.btn-large { min-width: 40px; }
|
||||
.toggle-on.btn-large { padding-right: 35px; }
|
||||
.toggle-off.btn-large { padding-left: 35px; }
|
||||
|
||||
.toggle.btn-small { min-width: 25px; }
|
||||
.toggle-on.btn-small { padding-right: 20px; }
|
||||
.toggle-off.btn-small { padding-left: 20px; }
|
||||
|
||||
.toggle.btn-mini { min-width: 20px; }
|
||||
.toggle-on.btn-mini { padding-right: 12px; }
|
||||
.toggle-off.btn-mini { padding-left: 12px; }
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/*! ========================================================================
|
||||
* Bootstrap Toggle: bootstrap2-toggle.css v2.2.0
|
||||
* http://www.bootstraptoggle.com
|
||||
* ========================================================================
|
||||
* Copyright 2014 Min Hur, The New York Times Company
|
||||
* Licensed under MIT
|
||||
* ======================================================================== */
|
||||
label.checkbox .toggle,label.checkbox.inline .toggle{margin-left:-20px;margin-right:5px}
|
||||
.toggle{min-width:40px;height:20px;position:relative;overflow:hidden}
|
||||
.toggle input[type=checkbox]{display:none}
|
||||
.toggle-group{position:absolute;width:200%;top:0;bottom:0;left:0;transition:left .35s;-webkit-transition:left .35s;-moz-user-select:none;-webkit-user-select:none}
|
||||
.toggle.off .toggle-group{left:-100%}
|
||||
.toggle-on{position:absolute;top:0;bottom:0;left:0;right:50%;margin:0;border:0;border-radius:0}
|
||||
.toggle-off{position:absolute;top:0;bottom:0;left:50%;right:0;margin:0;border:0;border-radius:0}
|
||||
.toggle-handle{position:relative;margin:0 auto;padding-top:0;padding-bottom:0;height:100%;width:0;border-width:0 1px}
|
||||
.toggle-handle.btn-mini{top:-1px}
|
||||
.toggle.btn{min-width:30px}
|
||||
.toggle-on.btn{padding-right:24px}
|
||||
.toggle-off.btn{padding-left:24px}
|
||||
.toggle.btn-large{min-width:40px}
|
||||
.toggle-on.btn-large{padding-right:35px}
|
||||
.toggle-off.btn-large{padding-left:35px}
|
||||
.toggle.btn-small{min-width:25px}
|
||||
.toggle-on.btn-small{padding-right:20px}
|
||||
.toggle-off.btn-small{padding-left:20px}
|
||||
.toggle.btn-mini{min-width:20px}
|
||||
.toggle-on.btn-mini{padding-right:12px}
|
||||
.toggle-off.btn-mini{padding-left:12px}
|
|
@ -1,14 +1,33 @@
|
|||
class AccountsController < ApplicationController
|
||||
before_action :require_login, only: [:login_check, :simple_update]
|
||||
include ApplicationHelper
|
||||
|
||||
#skip_before_action :check_account, :only => [:logout]
|
||||
|
||||
def simple_update
|
||||
simple_update_params.merge!(username: params[:username]&.gsub(/\s+/, ""))
|
||||
simple_update_params.merge!(email: params[:email]&.gsub(/\s+/, ""))
|
||||
simple_update_params.merge!(platform: (params[:platform] || 'forge')&.gsub(/\s+/, ""))
|
||||
Register::RemoteForm.new(simple_update_params).validate!
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
result = auto_update(current_user, simple_update_params)
|
||||
if result[:message].blank?
|
||||
UserAction.create(:action_id => current_user.id, :action_type => "sync_educoder_user", :user_id => current_user.id, :ip => request.remote_ip) if params[:platform] == "educoder"
|
||||
render_ok
|
||||
else
|
||||
render_error(result[:message])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def index
|
||||
render json: session
|
||||
end
|
||||
|
||||
# 其他平台同步注册的用户
|
||||
def remote_register
|
||||
Register::RemoteForm.new(remote_register_params).validate!
|
||||
username = params[:username]&.gsub(/\s+/, "")
|
||||
tip_exception("无法使用以下关键词:#{username},请重新命名") if ReversedKeyword.check_exists?(username)
|
||||
email = params[:email]&.gsub(/\s+/, "")
|
||||
|
@ -93,7 +112,9 @@ class AccountsController < ApplicationController
|
|||
|
||||
sync_params = {
|
||||
password: params[:password].to_s,
|
||||
email: @user.mail
|
||||
email: @user.mail,
|
||||
login_name: @user.login,
|
||||
source_id: 0
|
||||
}
|
||||
|
||||
interactor = Gitea::User::UpdateInteractor.call(@user.login, sync_params)
|
||||
|
@ -121,6 +142,7 @@ class AccountsController < ApplicationController
|
|||
Register::Form.new(register_params).validate!
|
||||
|
||||
user = Users::RegisterService.call(register_params)
|
||||
user.mail = "#{user.login}@example.org" if user.mail.blank?
|
||||
password = register_params[:password].strip
|
||||
|
||||
# gitea用户注册, email, username, password
|
||||
|
@ -132,6 +154,10 @@ class AccountsController < ApplicationController
|
|||
user.gitea_uid = gitea_user[:body]['id']
|
||||
if user.save!
|
||||
UserExtension.create!(user_id: user.id)
|
||||
# 绑定授权账号
|
||||
if ["qq", "wechat", "gitee", "github", "educoder"].include?(params[:type].to_s) && session[:unionid].present?
|
||||
"OpenUsers::#{params[:type].to_s.capitalize}".constantize.create!(user: user, uid: session[:unionid])
|
||||
end
|
||||
successful_authentication(user)
|
||||
render_ok
|
||||
end
|
||||
|
@ -139,15 +165,17 @@ class AccountsController < ApplicationController
|
|||
tip_exception(-1, interactor.error)
|
||||
end
|
||||
rescue Register::BaseForm::EmailError => e
|
||||
render_error(-2, e.message)
|
||||
render_result(-2, e.message)
|
||||
rescue Register::BaseForm::LoginError => e
|
||||
render_error(-3, e.message)
|
||||
render_result(-3, e.message)
|
||||
rescue Register::BaseForm::PhoneError => e
|
||||
render_error(-4, e.message)
|
||||
render_result(-4, e.message)
|
||||
rescue Register::BaseForm::PasswordFormatError => e
|
||||
render_error(-5, e.message)
|
||||
render_result(-5, e.message)
|
||||
rescue Register::BaseForm::PasswordConfirmationError => e
|
||||
render_result(-7, e.message)
|
||||
rescue Register::BaseForm::VerifiCodeError => e
|
||||
render_error(-6, e.message)
|
||||
render_result(-6, e.message)
|
||||
rescue Exception => e
|
||||
Gitea::User::DeleteService.call(user.login) unless user.nil?
|
||||
uid_logger_error(e.message)
|
||||
|
@ -157,7 +185,7 @@ class AccountsController < ApplicationController
|
|||
|
||||
# 用户登录
|
||||
def login
|
||||
Users::LoginForm.new(account_params).validate!
|
||||
Users::LoginForm.new(login_params).validate!
|
||||
@user = User.try_to_login(params[:login], params[:password])
|
||||
|
||||
return normal_status(-2, "错误的账号或密码") if @user.blank?
|
||||
|
@ -178,6 +206,7 @@ class AccountsController < ApplicationController
|
|||
return
|
||||
end
|
||||
|
||||
LimitForbidControl::UserLogin.new(@user).clear
|
||||
successful_authentication(@user)
|
||||
sync_pwd_to_gitea!(@user, {password: params[:password].to_s}) # TODO用户密码未同步
|
||||
|
||||
|
@ -191,7 +220,9 @@ class AccountsController < ApplicationController
|
|||
|
||||
sync_params = {
|
||||
password: params[:password].to_s,
|
||||
email: @user.mail
|
||||
email: @user.mail,
|
||||
login_name: @user.name,
|
||||
source_id: 0
|
||||
}
|
||||
|
||||
interactor = Gitea::User::UpdateInteractor.call(@user.login, sync_params)
|
||||
|
@ -206,28 +237,27 @@ class AccountsController < ApplicationController
|
|||
# 忘记密码
|
||||
def reset_password
|
||||
begin
|
||||
code = params[:code]
|
||||
login_type = phone_mail_type(params[:login].strip)
|
||||
# 获取验证码
|
||||
if login_type == 1
|
||||
phone = params[:login]
|
||||
verifi_code = VerificationCode.where(phone: phone, code: code, code_type: 2).last
|
||||
user = User.find_by_phone(phone)
|
||||
else
|
||||
email = params[:login]
|
||||
verifi_code = VerificationCode.where(email: email, code: code, code_type: 3).last
|
||||
user = User.find_by_mail(email) #这里有问题,应该是为email,而不是mail 6.13-hs
|
||||
end
|
||||
return normal_status(-2, "验证码不正确") if verifi_code.try(:code) != code.strip
|
||||
return normal_status(-2, "验证码已失效") if !verifi_code&.effective?
|
||||
return normal_status(-1, "8~16位密码,支持字母数字和符号") unless params[:new_password] =~ CustomRegexp::PASSWORD
|
||||
Accounts::ResetPasswordForm.new(reset_password_params).validate!
|
||||
|
||||
user.password, user.password_confirmation = params[:new_password], params[:new_password_confirmation]
|
||||
ActiveRecord::Base.transaction do
|
||||
user.save!
|
||||
LimitForbidControl::UserLogin.new(user).clear
|
||||
end
|
||||
sucess_status
|
||||
user = find_user
|
||||
return render_error('未找到相关账号') if user.blank?
|
||||
|
||||
user = Accounts::ResetPasswordService.call(user, reset_password_params)
|
||||
LimitForbidControl::UserLogin.new(user).clear if user.save!
|
||||
|
||||
render_ok
|
||||
rescue Register::BaseForm::EmailError => e
|
||||
render_result(-2, e.message)
|
||||
rescue Register::BaseForm::PhoneError => e
|
||||
render_result(-4, e.message)
|
||||
rescue Register::BaseForm::PasswordFormatError => e
|
||||
render_result(-5, e.message)
|
||||
rescue Register::BaseForm::PasswordConfirmationError => e
|
||||
render_result(-7, e.message)
|
||||
rescue Register::BaseForm::VerifiCodeError => e
|
||||
render_result(-6, e.message)
|
||||
rescue ActiveRecord::Rollback => e
|
||||
render_result(-1, "服务器异常")
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
tip_exception(e.message)
|
||||
|
@ -251,7 +281,7 @@ class AccountsController < ApplicationController
|
|||
|
||||
def set_autologin_cookie(user)
|
||||
token = Token.get_or_create_permanent_login_token(user, "autologin")
|
||||
sync_user_token_to_trustie(user.login, token.value)
|
||||
# sync_user_token_to_trustie(user.login, token.value)
|
||||
|
||||
cookie_options = {
|
||||
:value => token.value,
|
||||
|
@ -295,6 +325,8 @@ class AccountsController < ApplicationController
|
|||
send_type = verify_type(login_type, type)
|
||||
verification_code = code.sample(6).join
|
||||
|
||||
status, message = InfoRiskControlService.call(value, request.remote_ip)
|
||||
tip_exception(420, message) if status == 0
|
||||
sign = Digest::MD5.hexdigest("#{OPENKEY}#{value}")
|
||||
tip_exception(501, "请求不合理") if sign != params[:smscode]
|
||||
|
||||
|
@ -314,6 +346,11 @@ class AccountsController < ApplicationController
|
|||
render_ok
|
||||
end
|
||||
|
||||
def login_check
|
||||
Register::LoginCheckColumnsForm.new(check_params.merge(user: current_user)).validate!
|
||||
render_ok
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# type 事件类型 1:用户注册 2:忘记密码 3: 绑定手机 4: 绑定邮箱, 5: 验证手机号是否有效 # 如果有新的继续后面加
|
||||
|
@ -356,7 +393,7 @@ class AccountsController < ApplicationController
|
|||
params.require(:user).permit(:login, :email, :phone)
|
||||
end
|
||||
|
||||
def account_params
|
||||
def login_params
|
||||
params.require(:account).permit(:login, :password)
|
||||
end
|
||||
|
||||
|
@ -365,7 +402,23 @@ class AccountsController < ApplicationController
|
|||
end
|
||||
|
||||
def register_params
|
||||
params.permit(:login, :namespace, :password, :code)
|
||||
params.permit(:login, :namespace, :password, :password_confirmation, :code, :type)
|
||||
end
|
||||
|
||||
def reset_password_params
|
||||
params.permit(:login, :password, :password_confirmation, :code)
|
||||
end
|
||||
|
||||
def find_user
|
||||
phone_or_mail = strip(reset_password_params[:login])
|
||||
User.where("phone = :search OR mail = :search", search: phone_or_mail).last
|
||||
end
|
||||
|
||||
def remote_register_params
|
||||
params.permit(:username, :email, :password, :platform)
|
||||
end
|
||||
|
||||
def simple_update_params
|
||||
params.permit(:username, :email, :password, :platform)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,10 +1,33 @@
|
|||
class Admins::DashboardsController < Admins::BaseController
|
||||
def index
|
||||
@active_user_count = User.where(last_login_on: today).count
|
||||
@weekly_active_user_count = User.where(last_login_on: current_week).count
|
||||
@month_active_user_count = User.where(last_login_on: current_month).count
|
||||
# 用户活跃数
|
||||
day_user_ids = CommitLog.where(created_at: today).pluck(:user_id).uniq
|
||||
weekly_user_ids = CommitLog.where(created_at: current_week).pluck(:user_id).uniq
|
||||
month_user_ids = CommitLog.where(created_at: current_month).pluck(:user_id).uniq
|
||||
@active_user_count = User.where(last_login_on: today).or(User.where(id: day_user_ids)).count
|
||||
@weekly_active_user_count = User.where(last_login_on: current_week).or(User.where(id: weekly_user_ids)).count
|
||||
@month_active_user_count = User.where(last_login_on: current_month).or(User.where(id: month_user_ids)).count
|
||||
user_ids = User.where(created_on: pre_week).pluck(:id).uniq
|
||||
weekly_keep_user_count = User.where(id: user_ids).where(last_login_on: current_week).count
|
||||
@weekly_keep_rate = format("%.2f", user_ids.size > 0 ? weekly_keep_user_count.to_f / user_ids.size : 0)
|
||||
|
||||
@new_user_count = User.where(created_on: current_month).count
|
||||
# 新用户注册数
|
||||
@day_new_user_count = User.where(created_on: today).count
|
||||
@weekly_new_user_count = User.where(created_on: current_week).count
|
||||
@month_new_user_count = User.where(created_on: current_month).count
|
||||
|
||||
# 活跃项目数
|
||||
day_project_ids = (CommitLog.where(created_at: today).pluck(:project_id).uniq + Issue.where(created_on: today).pluck(:project_id).uniq).uniq
|
||||
weekly_project_ids = (CommitLog.where(created_at: current_week).pluck(:project_id).uniq + Issue.where(created_on: current_week).pluck(:project_id).uniq).uniq
|
||||
month_project_ids = (CommitLog.where(created_at: current_month).pluck(:project_id).uniq + Issue.where(created_on: current_month).pluck(:project_id).uniq).uniq
|
||||
@day_active_project_count = Project.where(updated_on: today).or(Project.where(id: day_project_ids)).count
|
||||
@weekly_active_project_count = Project.where(updated_on: current_week).or(Project.where(id: weekly_project_ids)).count
|
||||
@month_active_project_count = Project.where(updated_on: current_month).or(Project.where(id: month_project_ids)).count
|
||||
|
||||
# 新增项目数
|
||||
@day_new_project_count = Project.where(created_on: today).count
|
||||
@weekly_new_project_count = Project.where(created_on: current_week).count
|
||||
@month_new_project_count = Project.where(created_on: current_month).count
|
||||
end
|
||||
|
||||
def month_active_user
|
||||
|
@ -16,7 +39,6 @@ class Admins::DashboardsController < Admins::BaseController
|
|||
{ value: count['professional'].to_i, name: '专业人士' },
|
||||
{ value: count[nil].to_i, name: '未选职业' },
|
||||
]
|
||||
|
||||
render_ok(data: data)
|
||||
end
|
||||
|
||||
|
@ -42,10 +64,14 @@ class Admins::DashboardsController < Admins::BaseController
|
|||
end
|
||||
|
||||
def current_week
|
||||
7.days.ago.beginning_of_day..Time.now.end_of_day
|
||||
7.days.ago.end_of_day..Time.now.end_of_day
|
||||
end
|
||||
|
||||
def current_month
|
||||
30.days.ago.beginning_of_day..Time.now.end_of_day
|
||||
30.days.ago.end_of_day..Time.now.end_of_day
|
||||
end
|
||||
|
||||
def pre_week
|
||||
14.days.ago.end_of_day..7.days.ago.end_of_day
|
||||
end
|
||||
end
|
|
@ -0,0 +1,49 @@
|
|||
class Admins::FeedbacksController < Admins::BaseController
|
||||
before_action :get_feedback, only: [:new_history, :create_history, :destroy]
|
||||
|
||||
def index
|
||||
sort_by = Feedback.column_names.include?(params[:sort_by]) ? params[:sort_by] : 'created_at'
|
||||
sort_direction = %w(desc asc).include?(params[:sort_direction]) ? params[:sort_direction] : 'desc'
|
||||
feedbacks = Feedback.order("#{sort_by} #{sort_direction}")
|
||||
@feedbacks = paginate(feedbacks)
|
||||
end
|
||||
|
||||
def destroy
|
||||
if @feedback.destroy
|
||||
redirect_to admins_feedbacks_path
|
||||
flash[:success] = "反馈意见删除成功"
|
||||
else
|
||||
redirect_to admins_feedbacks_path
|
||||
flash[:danger] = "反馈意见删除失败"
|
||||
end
|
||||
end
|
||||
|
||||
def new_history
|
||||
@feedback_message_history = FeedbackMessageHistory.new
|
||||
end
|
||||
|
||||
def create_history
|
||||
@feedback_message_history = @feedback.feedback_message_histories.new(feedback_message_history_params)
|
||||
@feedback_message_history.user = current_user
|
||||
if @feedback_message_history.save
|
||||
redirect_to admins_feedbacks_path
|
||||
flash[:success] = "发送通知成功"
|
||||
else
|
||||
redirect_to admins_feedbacks_path
|
||||
flash[:danger] = @feedback_message_history.errors.full_messages.join(", ")
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def feedback_params
|
||||
params.require(:feedback).permit!
|
||||
end
|
||||
|
||||
def feedback_message_history_params
|
||||
params.require(:feedback_message_history).permit(:title, :content)
|
||||
end
|
||||
|
||||
def get_feedback
|
||||
@feedback = Feedback.find_by_id(params[:id])
|
||||
end
|
||||
end
|
|
@ -2,7 +2,7 @@ class Admins::ImportUsersController < Admins::BaseController
|
|||
def create
|
||||
return render_error('请上传正确的文件') if params[:file].blank? || !params[:file].is_a?(ActionDispatch::Http::UploadedFile)
|
||||
|
||||
result = Admins::ImportUserService.call(params[:file].to_io)
|
||||
result = Admins::ImportUserFromExcelService.call(params[:file].to_io)
|
||||
render_ok(result)
|
||||
rescue Admins::ImportUserService::Error => ex
|
||||
render_error(ex)
|
||||
|
|
|
@ -2,8 +2,24 @@ class Admins::MessageTemplatesController < Admins::BaseController
|
|||
before_action :get_template, only: [:edit, :update, :destroy]
|
||||
|
||||
def index
|
||||
message_templates = MessageTemplate.group(:type).count.keys
|
||||
@message_templates = kaminari_array_paginate(message_templates)
|
||||
message_templates = MessageTemplate.ransack(sys_notice_or_email_or_email_title_cont: params[:search]).result
|
||||
@message_templates = kaminari_paginate(message_templates)
|
||||
end
|
||||
|
||||
def new
|
||||
@message_template = MessageTemplate.new
|
||||
end
|
||||
|
||||
def create
|
||||
@message_template = MessageTemplate::CustomTip.new(message_template_params)
|
||||
@message_template.type = "MessageTemplate::CustomTip"
|
||||
if @message_template.save!
|
||||
redirect_to admins_message_templates_path
|
||||
flash[:success] = "创建消息模板成功"
|
||||
else
|
||||
render :new
|
||||
flash[:danger] = "创建消息模板失败"
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
|
@ -31,7 +47,9 @@ class Admins::MessageTemplatesController < Admins::BaseController
|
|||
|
||||
private
|
||||
def message_template_params
|
||||
params.require(@message_template.type.split("::").join("_").underscore.to_sym).permit!
|
||||
# type = @message_template.present? ? @message_template.type : "MessageTemplate::CustomTip"
|
||||
# params.require(type.split("::").join("_").underscore.to_sym).permit!
|
||||
params.require(:message_template).permit!
|
||||
end
|
||||
|
||||
def get_template
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
class Admins::NpsController < Admins::BaseController
|
||||
def index
|
||||
@on_off_switch = EduSetting.get("nps-on-off-switch").to_s == 'true'
|
||||
@user_nps = UserNp.joins(:user).order(created_at: :desc)
|
||||
keyword = params[:keyword].to_s.strip.presence
|
||||
if keyword
|
||||
sql = 'CONCAT(users.lastname, users.firstname) LIKE :keyword OR users.nickname LIKE :keyword OR users.login LIKE :keyword OR users.mail LIKE :keyword OR users.phone LIKE :keyword'
|
||||
@user_nps = @user_nps.where(sql, keyword: "%#{keyword}%")
|
||||
end
|
||||
@user_nps = @user_nps.where("action_type != 'close'") if params[:done_score].present?
|
||||
@min_score = @user_nps.where("action_type != 'close'").minimum("score")
|
||||
@max_score = @user_nps.where("action_type != 'close'").maximum("score")
|
||||
@score_total_count = UserNp.where("action_type !='close'").count
|
||||
@user_nps = paginate @user_nps.includes(:user)
|
||||
end
|
||||
|
||||
def switch_change
|
||||
edu_setting = EduSetting.find_by(name: "nps-on-off-switch")
|
||||
if edu_setting.blank?
|
||||
edu_setting = EduSetting.new(name: "nps-on-off-switch")
|
||||
end
|
||||
edu_setting.value = params[:switch].to_s
|
||||
edu_setting.save
|
||||
render_ok
|
||||
end
|
||||
end
|
|
@ -0,0 +1,27 @@
|
|||
class Admins::OrganizationsController < Admins::BaseController
|
||||
before_action :finder_org, except: [:index]
|
||||
|
||||
def index
|
||||
params[:sort_by] = params[:sort_by].presence || 'created_on'
|
||||
params[:sort_direction] = params[:sort_direction].presence || 'desc'
|
||||
|
||||
orgs = Admins::OrganizationQuery.call(params)
|
||||
@orgs = paginate orgs
|
||||
end
|
||||
|
||||
def show
|
||||
end
|
||||
|
||||
def destroy
|
||||
@org.destroy!
|
||||
Admins::DeleteOrganizationService.call(@org.login)
|
||||
render_delete_success
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def finder_org
|
||||
@org = Organization.find(params[:id])
|
||||
end
|
||||
|
||||
end
|
|
@ -1,6 +1,6 @@
|
|||
class Admins::ProjectIgnoresController < Admins::BaseController
|
||||
before_action :set_ignore, only: [:edit,:update, :destroy,:show]
|
||||
before_action :validate_params, only: [:create, :update]
|
||||
# before_action :validate_params, only: [:create, :update]
|
||||
|
||||
def index
|
||||
sort_by = Ignore.column_names.include?(params[:sort_by]) ? params[:sort_by] : 'created_at'
|
||||
|
@ -31,12 +31,12 @@ class Admins::ProjectIgnoresController < Admins::BaseController
|
|||
# }
|
||||
@project_ignore = Ignore.new(ignore_params)
|
||||
|
||||
if @project_ignore.save!
|
||||
if @project_ignore.save
|
||||
redirect_to admins_project_ignores_path
|
||||
flash[:success] = "创建成功"
|
||||
else
|
||||
render :new
|
||||
flash[:danger] = "创建失败"
|
||||
redirect_to admins_project_ignores_path
|
||||
flash[:danger] = @project_ignore.errors.full_messages.join(",")
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -58,8 +58,8 @@ class Admins::ProjectIgnoresController < Admins::BaseController
|
|||
redirect_to admins_project_ignores_path
|
||||
flash[:success] = "更新成功"
|
||||
else
|
||||
render :edit
|
||||
flash[:danger] = "更新失败"
|
||||
redirect_to admins_project_ignores_path
|
||||
flash[:danger] = @project_ignore.errors.full_messages.join(",")
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -98,23 +98,23 @@ class Admins::ProjectIgnoresController < Admins::BaseController
|
|||
params.require(:ignore).permit(:name,:content)
|
||||
end
|
||||
|
||||
def validate_params
|
||||
name = params[:ignore][:name]
|
||||
if name.blank?
|
||||
flash[:danger] = "名称不允许为空"
|
||||
redirect_to admins_project_ignores_path
|
||||
elsif check_ignore_present?(name) && @project_ignore.blank?
|
||||
flash[:danger] = "创建失败:名称已存在"
|
||||
redirect_to admins_project_ignores_path
|
||||
end
|
||||
end
|
||||
# def validate_params
|
||||
# name = params[:ignore][:name]
|
||||
# if name.blank?
|
||||
# flash[:danger] = "名称不允许为空"
|
||||
# redirect_to admins_project_ignores_path
|
||||
# elsif check_ignore_present?(name) && @project_ignore.blank?
|
||||
# flash[:danger] = "创建失败:名称已存在"
|
||||
# redirect_to admins_project_ignores_path
|
||||
# end
|
||||
# end
|
||||
|
||||
def check_ignore_present?(name)
|
||||
return true if name.blank?
|
||||
name_downcase = name.downcase
|
||||
name_upcase = name.upcase
|
||||
name_first_big = name.capitalize
|
||||
Ignore.exists?(name: name_downcase) || Ignore.exists?(name: name_upcase) || Ignore.exists?(name: name_first_big)
|
||||
end
|
||||
# def check_ignore_present?(name)
|
||||
# return true if name.blank?
|
||||
# name_downcase = name.downcase
|
||||
# name_upcase = name.upcase
|
||||
# name_first_big = name.capitalize
|
||||
# Ignore.exists?(name: name_downcase) || Ignore.exists?(name: name_upcase) || Ignore.exists?(name: name_first_big)
|
||||
# end
|
||||
|
||||
end
|
||||
|
|
|
@ -27,17 +27,18 @@ class Admins::ProjectLanguagesController < Admins::BaseController
|
|||
flash[:success] = '创建成功'
|
||||
else
|
||||
redirect_to admins_project_languages_path
|
||||
flash[:danger] = '创建失败'
|
||||
flash[:danger] = @project_language.errors.full_messages.join(",")
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
if @project_language.update_attribute(:name, @name)
|
||||
@project_language.attributes = {name: @name}
|
||||
if @project_language.save
|
||||
redirect_to admins_project_languages_path
|
||||
flash[:success] = '更新成功'
|
||||
else
|
||||
redirect_to admins_project_languages_path
|
||||
flash[:success] = '更新失败'
|
||||
flash[:danger] = @project_language.errors.full_messages.join(",")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
class Admins::ProjectLicensesController < Admins::BaseController
|
||||
before_action :set_license, only: [:edit,:update, :destroy,:show]
|
||||
before_action :validate_params, only: [:create, :update]
|
||||
# before_action :validate_params, only: [:create, :update]
|
||||
|
||||
def index
|
||||
sort_by = License.column_names.include?(params[:sort_by]) ? params[:sort_by] : 'created_at'
|
||||
|
@ -30,13 +30,12 @@ class Admins::ProjectLicensesController < Admins::BaseController
|
|||
# position: max_position
|
||||
# }
|
||||
@project_license = License.new(license_params)
|
||||
|
||||
if @project_license.save!
|
||||
if @project_license.save
|
||||
redirect_to admins_project_licenses_path
|
||||
flash[:success] = "创建成功"
|
||||
else
|
||||
render :new
|
||||
flash[:danger] = "创建失败"
|
||||
redirect_to admins_project_licenses_path
|
||||
flash[:danger] = @project_license.errors.full_messages.join(",")
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -54,12 +53,13 @@ class Admins::ProjectLicensesController < Admins::BaseController
|
|||
# permissions: permissions.to_s,
|
||||
# limitations: limitations.to_s
|
||||
# }
|
||||
if @project_license.update_attributes(license_params)
|
||||
@project_license.attributes = license_params
|
||||
if @project_license.save
|
||||
redirect_to admins_project_licenses_path
|
||||
flash[:success] = "更新成功"
|
||||
else
|
||||
render :edit
|
||||
flash[:danger] = "更新失败"
|
||||
render admins_project_licenses_path
|
||||
flash[:danger] = @project_license.errors.full_messages.join(",")
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -98,23 +98,23 @@ class Admins::ProjectLicensesController < Admins::BaseController
|
|||
params.require(:license).permit(:name,:content)
|
||||
end
|
||||
|
||||
def validate_params
|
||||
name = params[:license][:name]
|
||||
if name.blank?
|
||||
flash[:danger] = "名称不允许为空"
|
||||
redirect_to admins_project_licenses_path
|
||||
elsif check_license_present?(name) && @project_license.blank?
|
||||
flash[:danger] = "创建失败:名称已存在"
|
||||
redirect_to admins_project_licenses_path
|
||||
end
|
||||
end
|
||||
# def validate_params
|
||||
# name = params[:license][:name]
|
||||
# if name.blank?
|
||||
# flash[:danger] = "名称不允许为空"
|
||||
# redirect_to admins_project_licenses_path
|
||||
# elsif check_license_present?(name) && @project_license.blank?
|
||||
# flash[:danger] = "创建失败:名称已存在"
|
||||
# redirect_to admins_project_licenses_path
|
||||
# end
|
||||
# end
|
||||
|
||||
def check_license_present?(name)
|
||||
return true if name.blank?
|
||||
name_downcase = name.downcase
|
||||
name_upcase = name.upcase
|
||||
name_first_big = name.capitalize
|
||||
License.exists?(name: name_downcase) || License.exists?(name: name_upcase) || License.exists?(name: name_first_big)
|
||||
end
|
||||
# def check_license_present?(name)
|
||||
# return true if name.blank?
|
||||
# name_downcase = name.downcase
|
||||
# name_upcase = name.upcase
|
||||
# name_first_big = name.capitalize
|
||||
# License.exists?(name: name_downcase) || License.exists?(name: name_upcase) || License.exists?(name: name_first_big)
|
||||
# end
|
||||
|
||||
end
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
class Admins::ProjectsRankController < Admins::BaseController
|
||||
|
||||
def index
|
||||
@rank_date = rank_date
|
||||
deleted_data = $redis_cache.smembers("v2-project-rank-deleted")
|
||||
$redis_cache.zrem("v2-project-rank-#{rank_date}", deleted_data) unless deleted_data.blank?
|
||||
@date_rank = $redis_cache.zrevrange("v2-project-rank-#{rank_date}", 0, -1, withscores: true)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def rank_date
|
||||
params.fetch(:date, Date.today.to_s)
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,57 @@
|
|||
class Admins::Topic::ActivityForumsController < Admins::Topic::BaseController
|
||||
before_action :find_activity_forum, only: [:edit, :update, :destroy]
|
||||
|
||||
def index
|
||||
q = ::Topic::ActivityForum.ransack(title_cont: params[:search])
|
||||
activity_forums = q.result(distinct: true)
|
||||
@activity_forums = paginate(activity_forums)
|
||||
end
|
||||
|
||||
def new
|
||||
@activity_forum = ::Topic::ActivityForum.new
|
||||
end
|
||||
|
||||
def create
|
||||
@activity_forum = ::Topic::ActivityForum.new(activity_forum_params)
|
||||
if @activity_forum.save
|
||||
redirect_to admins_topic_activity_forums_path
|
||||
flash[:success] = "新增平台动态成功"
|
||||
else
|
||||
redirect_to admins_topic_activity_forums_path
|
||||
flash[:danger] = "新增平台动态失败"
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def update
|
||||
@activity_forum.attributes = activity_forum_params
|
||||
if @activity_forum.save
|
||||
redirect_to admins_topic_activity_forums_path
|
||||
flash[:success] = "更新平台动态成功"
|
||||
else
|
||||
redirect_to admins_topic_activity_forums_path
|
||||
flash[:danger] = "更新平台动态失败"
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
if @activity_forum.destroy
|
||||
redirect_to admins_topic_activity_forums_path
|
||||
flash[:success] = "删除平台动态成功"
|
||||
else
|
||||
redirect_to admins_topic_activity_forums_path
|
||||
flash[:danger] = "删除平台动态失败"
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def find_activity_forum
|
||||
@activity_forum = ::Topic::ActivityForum.find_by_id(params[:id])
|
||||
end
|
||||
|
||||
def activity_forum_params
|
||||
params.require(:topic_activity_forum).permit(:title, :uuid, :url, :order_index)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,58 @@
|
|||
class Admins::Topic::BannersController < Admins::Topic::BaseController
|
||||
before_action :find_banner, only: [:edit, :update, :destroy]
|
||||
|
||||
def index
|
||||
@banners = paginate(::Topic::Banner)
|
||||
@banners = paginate(::Topic::Banner.where("title like ?", "%#{params[:search]}%")) if params[:search].present?
|
||||
end
|
||||
|
||||
def new
|
||||
@banner = ::Topic::Banner.new
|
||||
end
|
||||
|
||||
def create
|
||||
@banner = ::Topic::Banner.new(banner_params)
|
||||
if @banner.save
|
||||
save_image_file(params[:image], @banner)
|
||||
redirect_to admins_topic_banners_path
|
||||
flash[:success] = "新增banner成功"
|
||||
else
|
||||
redirect_to admins_topic_banners_path
|
||||
flash[:danger] = "新增banner失败"
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def update
|
||||
@banner.attributes = banner_params
|
||||
if @banner.save
|
||||
save_image_file(params[:image], @banner)
|
||||
redirect_to admins_topic_banners_path
|
||||
flash[:success] = "更新banner成功"
|
||||
else
|
||||
redirect_to admins_topic_banners_path
|
||||
flash[:danger] = "更新banner失败"
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
if @banner.destroy
|
||||
redirect_to admins_topic_banners_path
|
||||
flash[:success] = "删除banner成功"
|
||||
else
|
||||
redirect_to admins_topic_banners_path
|
||||
flash[:danger] = "删除banner失败"
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def find_banner
|
||||
@banner = ::Topic::Banner.find_by_id(params[:id])
|
||||
end
|
||||
|
||||
def banner_params
|
||||
params.require(:topic_banner).permit(:title, :order_index, :url)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,11 @@
|
|||
class Admins::Topic::BaseController < Admins::BaseController
|
||||
|
||||
protected
|
||||
def save_image_file(file, topic)
|
||||
return unless file.present? && file.is_a?(ActionDispatch::Http::UploadedFile)
|
||||
|
||||
file_path = Util::FileManage.source_disk_filename(topic, 'image')
|
||||
File.delete(file_path) if File.exist?(file_path) # 删除之前的文件
|
||||
Util.write_file(file, file_path)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,57 @@
|
|||
class Admins::Topic::CardsController < Admins::Topic::BaseController
|
||||
before_action :find_card, only: [:edit, :update, :destroy]
|
||||
|
||||
def index
|
||||
q = ::Topic::Card.ransack(title_cont: params[:search])
|
||||
cards = q.result(distinct: true)
|
||||
@cards = paginate(cards)
|
||||
end
|
||||
|
||||
def new
|
||||
@card = ::Topic::Card.new
|
||||
end
|
||||
|
||||
def create
|
||||
@card = ::Topic::Card.new(card_params)
|
||||
if @card.save
|
||||
redirect_to admins_topic_cards_path
|
||||
flash[:success] = "新增合作单位成功"
|
||||
else
|
||||
redirect_to admins_topic_cards_path
|
||||
flash[:danger] = "新增合作单位失败"
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def update
|
||||
@card.attributes = card_params
|
||||
if @card.save
|
||||
redirect_to admins_topic_cards_path
|
||||
flash[:success] = "更新合作单位成功"
|
||||
else
|
||||
redirect_to admins_topic_cards_path
|
||||
flash[:danger] = "更新合作单位失败"
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
if @card.destroy
|
||||
redirect_to admins_topic_cards_path
|
||||
flash[:success] = "删除合作单位成功"
|
||||
else
|
||||
redirect_to admins_topic_cards_path
|
||||
flash[:danger] = "删除合作单位失败"
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def find_card
|
||||
@card = ::Topic::Card.find_by_id(params[:id])
|
||||
end
|
||||
|
||||
def card_params
|
||||
params.require(:topic_card).permit(:title, :url, :order_index)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,57 @@
|
|||
class Admins::Topic::CooperatorsController < Admins::Topic::BaseController
|
||||
before_action :find_cooperator, only: [:edit, :update, :destroy]
|
||||
|
||||
def index
|
||||
@cooperators = paginate(::Topic::Cooperator)
|
||||
end
|
||||
|
||||
def new
|
||||
@cooperator = ::Topic::Cooperator.new
|
||||
end
|
||||
|
||||
def create
|
||||
@cooperator = ::Topic::Cooperator.new(cooperator_params)
|
||||
if @cooperator.save
|
||||
save_image_file(params[:image], @cooperator)
|
||||
redirect_to admins_topic_cooperators_path
|
||||
flash[:success] = "新增合作单位成功"
|
||||
else
|
||||
redirect_to admins_topic_cooperators_path
|
||||
flash[:danger] = "新增合作单位失败"
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def update
|
||||
@cooperator.attributes = cooperator_params
|
||||
if @cooperator.save
|
||||
save_image_file(params[:image], @cooperator)
|
||||
redirect_to admins_topic_cooperators_path
|
||||
flash[:success] = "更新合作单位成功"
|
||||
else
|
||||
redirect_to admins_topic_cooperators_path
|
||||
flash[:danger] = "更新合作单位失败"
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
if @cooperator.destroy
|
||||
redirect_to admins_topic_cooperators_path
|
||||
flash[:success] = "删除合作单位成功"
|
||||
else
|
||||
redirect_to admins_topic_cooperators_path
|
||||
flash[:danger] = "删除合作单位失败"
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def find_cooperator
|
||||
@cooperator = ::Topic::Cooperator.find_by_id(params[:id])
|
||||
end
|
||||
|
||||
def cooperator_params
|
||||
params.require(:topic_cooperator).permit(:title, :url, :order_index)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,57 @@
|
|||
class Admins::Topic::ExcellentProjectsController < Admins::Topic::BaseController
|
||||
before_action :find_excellent_project, only: [:edit, :update, :destroy]
|
||||
|
||||
def index
|
||||
q = ::Topic::ExcellentProject.ransack(title_cont: params[:search])
|
||||
excellent_projects = q.result(distinct: true)
|
||||
@excellent_projects = paginate(excellent_projects)
|
||||
end
|
||||
|
||||
def new
|
||||
@excellent_project = ::Topic::ExcellentProject.new
|
||||
end
|
||||
|
||||
def create
|
||||
@excellent_project = ::Topic::ExcellentProject.new(excellent_project_params)
|
||||
if @excellent_project.save
|
||||
redirect_to admins_topic_excellent_projects_path
|
||||
flash[:success] = "新增优秀仓库成功"
|
||||
else
|
||||
redirect_to admins_topic_excellent_projects_path
|
||||
flash[:danger] = "新增优秀仓库失败"
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def update
|
||||
@excellent_project.attributes = excellent_project_params
|
||||
if @excellent_project.save
|
||||
redirect_to admins_topic_excellent_projects_path
|
||||
flash[:success] = "更新优秀仓库成功"
|
||||
else
|
||||
redirect_to admins_topic_excellent_projects_path
|
||||
flash[:danger] = "更新优秀仓库失败"
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
if @excellent_project.destroy
|
||||
redirect_to admins_topic_excellent_projects_path
|
||||
flash[:success] = "删除优秀仓库成功"
|
||||
else
|
||||
redirect_to admins_topic_excellent_projects_path
|
||||
flash[:danger] = "删除优秀仓库失败"
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def find_excellent_project
|
||||
@excellent_project = ::Topic::ExcellentProject.find_by_id(params[:id])
|
||||
end
|
||||
|
||||
def excellent_project_params
|
||||
params.require(:topic_excellent_project).permit(:title, :uuid, :url, :order_index)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,57 @@
|
|||
class Admins::Topic::ExperienceForumsController < Admins::Topic::BaseController
|
||||
before_action :find_experience_forum, only: [:edit, :update, :destroy]
|
||||
|
||||
def index
|
||||
q = ::Topic::ExperienceForum.ransack(title_cont: params[:search])
|
||||
experience_forums = q.result(distinct: true)
|
||||
@experience_forums = paginate(experience_forums)
|
||||
end
|
||||
|
||||
def new
|
||||
@experience_forum = ::Topic::ExperienceForum.new
|
||||
end
|
||||
|
||||
def create
|
||||
@experience_forum = ::Topic::ExperienceForum.new(experience_forum_params)
|
||||
if @experience_forum.save
|
||||
redirect_to admins_topic_experience_forums_path
|
||||
flash[:success] = "新增经验分享成功"
|
||||
else
|
||||
redirect_to admins_topic_experience_forums_path
|
||||
flash[:danger] = "新增经验分享失败"
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def update
|
||||
@experience_forum.attributes = experience_forum_params
|
||||
if @experience_forum.save
|
||||
redirect_to admins_topic_experience_forums_path
|
||||
flash[:success] = "更新经验分享成功"
|
||||
else
|
||||
redirect_to admins_topic_experience_forums_path
|
||||
flash[:danger] = "更新经验分享失败"
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
if @experience_forum.destroy
|
||||
redirect_to admins_topic_experience_forums_path
|
||||
flash[:success] = "删除经验分享成功"
|
||||
else
|
||||
redirect_to admins_topic_experience_forums_path
|
||||
flash[:danger] = "删除经验分享失败"
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def find_experience_forum
|
||||
@experience_forum = ::Topic::ExperienceForum.find_by_id(params[:id])
|
||||
end
|
||||
|
||||
def experience_forum_params
|
||||
params.require(:topic_experience_forum).permit(:title, :uuid, :url, :order_index)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,57 @@
|
|||
class Admins::Topic::GlccNewsController < Admins::Topic::BaseController
|
||||
before_action :find_glcc, only: [:edit, :update, :destroy]
|
||||
|
||||
def index
|
||||
q = ::Topic::GlccNews.ransack(title_cont: params[:search])
|
||||
glcc_news = q.result(distinct: true)
|
||||
@glcc_news = paginate(glcc_news)
|
||||
end
|
||||
|
||||
def new
|
||||
@glcc = ::Topic::GlccNews.new
|
||||
end
|
||||
|
||||
def create
|
||||
@glcc = ::Topic::GlccNews.new(glcc_params)
|
||||
if @glcc.save
|
||||
redirect_to admins_topic_glcc_news_index_path
|
||||
flash[:success] = "新增新闻稿成功"
|
||||
else
|
||||
redirect_to admins_topic_glcc_news_index_path
|
||||
flash[:danger] = "新增新闻稿失败"
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def update
|
||||
@glcc.attributes = glcc_params
|
||||
if @glcc.save
|
||||
redirect_to admins_topic_glcc_news_index_path
|
||||
flash[:success] = "更新新闻稿成功"
|
||||
else
|
||||
redirect_to admins_topic_glcc_news_index_path
|
||||
flash[:danger] = "更新新闻稿失败"
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
if @glcc.destroy
|
||||
redirect_to admins_topic_glcc_news_index_path
|
||||
flash[:success] = "删除新闻稿成功"
|
||||
else
|
||||
redirect_to admins_topic_glcc_news_index_path
|
||||
flash[:danger] = "删除新闻稿失败"
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def find_glcc
|
||||
@glcc = ::Topic::GlccNews.find_by_id(params[:id])
|
||||
end
|
||||
|
||||
def glcc_params
|
||||
params.require(:topic_glcc_news).permit(:title, :uuid, :url, :order_index)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,57 @@
|
|||
class Admins::Topic::PinnedForumsController < Admins::Topic::BaseController
|
||||
before_action :find_pinned_forum, only: [:edit, :update, :destroy]
|
||||
|
||||
def index
|
||||
q = ::Topic::PinnedForum.ransack(title_cont: params[:search])
|
||||
pinned_forums = q.result(distinct: true)
|
||||
@pinned_forums = paginate(pinned_forums)
|
||||
end
|
||||
|
||||
def new
|
||||
@pinned_forum = ::Topic::PinnedForum.new
|
||||
end
|
||||
|
||||
def create
|
||||
@pinned_forum = ::Topic::PinnedForum.new(pinned_forum_params)
|
||||
if @pinned_forum.save
|
||||
redirect_to admins_topic_pinned_forums_path
|
||||
flash[:success] = "新增精选文章成功"
|
||||
else
|
||||
redirect_to admins_topic_pinned_forums_path
|
||||
flash[:danger] = "新增精选文章失败"
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def update
|
||||
@pinned_forum.attributes = pinned_forum_params
|
||||
if @pinned_forum.save
|
||||
redirect_to admins_topic_pinned_forums_path
|
||||
flash[:success] = "更新精选文章成功"
|
||||
else
|
||||
redirect_to admins_topic_pinned_forums_path
|
||||
flash[:danger] = "更新精选文章失败"
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
if @pinned_forum.destroy
|
||||
redirect_to admins_topic_pinned_forums_path
|
||||
flash[:success] = "删除精选文章成功"
|
||||
else
|
||||
redirect_to admins_topic_pinned_forums_path
|
||||
flash[:danger] = "删除精选文章失败"
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def find_pinned_forum
|
||||
@pinned_forum = ::Topic::PinnedForum.find_by_id(params[:id])
|
||||
end
|
||||
|
||||
def pinned_forum_params
|
||||
params.require(:topic_pinned_forum).permit(:title, :uuid, :url, :order_index)
|
||||
end
|
||||
end
|
|
@ -57,6 +57,12 @@ class Admins::UsersController < Admins::BaseController
|
|||
render_ok
|
||||
end
|
||||
|
||||
|
||||
def fresh_gitea_token
|
||||
@user.fresh_gitea_token
|
||||
render_ok
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def finder_user
|
||||
|
@ -64,8 +70,8 @@ class Admins::UsersController < Admins::BaseController
|
|||
end
|
||||
|
||||
def update_params
|
||||
params.require(:user).permit(%i[lastname nickname gender identity technical_title student_id is_shixun_marker
|
||||
mail phone location location_city school_id department_id admin business is_test
|
||||
password professional_certification authentication login])
|
||||
params.require(:user).permit(%i[lastname nickname gender technical_title is_shixun_marker
|
||||
mail phone location location_city school_id department_id admin
|
||||
password login])
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
class Admins::UsersRankController < Admins::BaseController
|
||||
|
||||
def index
|
||||
@rank_date = rank_date
|
||||
@date_rank = $redis_cache.zrevrange("v2-user-rank-#{rank_date}", 0, -1, withscores: true)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def rank_date
|
||||
params.fetch(:date, Date.today.to_s)
|
||||
end
|
||||
|
||||
|
||||
end
|
|
@ -0,0 +1,63 @@
|
|||
class Api::V1::BaseController < ApplicationController
|
||||
|
||||
include Api::ProjectHelper
|
||||
include Api::UserHelper
|
||||
include Api::PullHelper
|
||||
|
||||
# before_action :doorkeeper_authorize!
|
||||
# skip_before_action :user_setup
|
||||
|
||||
protected
|
||||
# def current_user
|
||||
# #client方法对接,需要一直带着用户标识uid
|
||||
# Rails.logger.info doorkeeper_token
|
||||
# if doorkeeper_token && doorkeeper_token.resource_owner_id.blank?
|
||||
# # return User.anonymous if params[:uid].nil?
|
||||
# # tip_exception("2222")
|
||||
# # return render_error('缺少用户标识!') if params[:uid].nil?
|
||||
# User.current = User.find(params[:uid])
|
||||
# else
|
||||
# User.find(doorkeeper_token.resource_owner_id) if doorkeeper_token
|
||||
# end
|
||||
# end
|
||||
|
||||
def kaminary_select_paginate(relation)
|
||||
limit = params[:limit] || params[:per_page]
|
||||
limit = (limit.to_i.zero? || limit.to_i > 200) ? 200 : limit.to_i
|
||||
page = params[:page].to_i.zero? ? 1 : params[:page].to_i
|
||||
|
||||
relation.page(page).per(limit)
|
||||
end
|
||||
|
||||
def limit
|
||||
params.fetch(:limit, 15)
|
||||
end
|
||||
|
||||
def page
|
||||
params.fetch(:page, 1)
|
||||
end
|
||||
|
||||
# 具有对仓库的管理权限
|
||||
def require_manager_above
|
||||
@project = load_project
|
||||
return render_forbidden if !current_user.admin? && !@project.manager?(current_user)
|
||||
end
|
||||
|
||||
# 具有对仓库的操作权限
|
||||
def require_operate_above
|
||||
@project = load_project
|
||||
return render_forbidden if !current_user.admin? && !@project.operator?(current_user)
|
||||
end
|
||||
|
||||
# 具有仓库的操作权限或者fork仓库的操作权限
|
||||
def require_operate_above_or_fork_project
|
||||
@project = load_project
|
||||
return render_forbidden if !current_user.admin? && !@project.operator?(current_user) && !(@project.fork_project.present? && @project.fork_project.operator?(current_user))
|
||||
end
|
||||
|
||||
# 具有对仓库的访问权限
|
||||
def require_public_and_member_above
|
||||
@project = load_project
|
||||
return render_forbidden if !@project.is_public && !current_user.admin? && !@project.member?(current_user)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,12 @@
|
|||
class Api::V1::Issues::AssignersController < Api::V1::BaseController
|
||||
|
||||
before_action :require_public_and_member_above, only: [:index]
|
||||
|
||||
# 负责人列表
|
||||
def index
|
||||
@assigners = User.joins(assigned_issues: :project).where(projects: {id: @project&.id})
|
||||
@assigners = @assigners.order("users.id=#{current_user.id} desc").distinct
|
||||
@assigners = @assigners.ransack(login_or_nickname_cont: params[:keyword]).result if params[:keyword].present?
|
||||
@assigners = kaminary_select_paginate(@assigners)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,11 @@
|
|||
class Api::V1::Issues::AuthorsController < Api::V1::BaseController
|
||||
before_action :require_public_and_member_above, only: [:index]
|
||||
|
||||
# 发布人列表
|
||||
def index
|
||||
@authors = User.joins(issues: :project).where(projects: {id: @project&.id})
|
||||
@authors = @authors.order("users.id=#{current_user.id} desc").distinct
|
||||
@authors = @authors.ransack(login_or_nickname_cont: params[:keyword]).result if params[:keyword].present?
|
||||
@authors = kaminary_select_paginate(@authors)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,10 @@
|
|||
class Api::V1::Issues::IssuePrioritiesController < Api::V1::BaseController
|
||||
|
||||
before_action :require_public_and_member_above, only: [:index]
|
||||
|
||||
def index
|
||||
@priorities = IssuePriority.order(position: :asc)
|
||||
@priorities = @priorities.ransack(name_cont: params[:keyword]).result if params[:keyword]
|
||||
@priorities = kaminary_select_paginate(@priorities)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,65 @@
|
|||
class Api::V1::Issues::IssueTagsController < Api::V1::BaseController
|
||||
before_action :require_login, except: [:index]
|
||||
before_action :require_public_and_member_above, only: [:index]
|
||||
before_action :require_operate_above, only: [:create, :update, :destroy]
|
||||
|
||||
def index
|
||||
@issue_tags = @project.issue_tags.reorder("#{sort_by} #{sort_direction}")
|
||||
@issue_tags = @issue_tags.ransack(name_cont: params[:keyword]).result if params[:keyword].present?
|
||||
if params[:only_name]
|
||||
@issue_tags = kaminary_select_paginate(@issue_tags.select(:id, :name, :color))
|
||||
else
|
||||
@issue_tags = kaminari_paginate(@issue_tags.includes(:project, :user, :issue_issues, :pull_request_issues))
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
@issue_tag = @project.issue_tags.new(issue_tag_params)
|
||||
if @issue_tag.save!
|
||||
render_ok
|
||||
else
|
||||
render_error("创建标记失败!")
|
||||
end
|
||||
end
|
||||
|
||||
before_action :load_issue_tag, only: [:update, :destroy]
|
||||
|
||||
def update
|
||||
@issue_tag.attributes = issue_tag_params
|
||||
if @issue_tag.save!
|
||||
render_ok
|
||||
else
|
||||
render_error("更新标记失败!")
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
if @issue_tag.destroy!
|
||||
render_ok
|
||||
else
|
||||
render_error("删除标记失败!")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
def sort_by
|
||||
sort_by = params.fetch(:sort_by, "created_at")
|
||||
sort_by = IssueTag.column_names.include?(sort_by) ? sort_by : "created_at"
|
||||
sort_by
|
||||
end
|
||||
|
||||
def sort_direction
|
||||
sort_direction = params.fetch(:sort_direction, "desc").downcase
|
||||
sort_direction = %w(desc asc).include?(sort_direction) ? sort_direction : "desc"
|
||||
sort_direction
|
||||
end
|
||||
|
||||
def issue_tag_params
|
||||
params.permit(:name, :description, :color)
|
||||
end
|
||||
|
||||
def load_issue_tag
|
||||
@issue_tag = @project.issue_tags.find_by_id(params[:id])
|
||||
end
|
||||
end
|
|
@ -0,0 +1,64 @@
|
|||
class Api::V1::Issues::JournalsController < Api::V1::BaseController
|
||||
before_action :require_login, except: [:index, :children_journals]
|
||||
before_action :require_public_and_member_above
|
||||
before_action :load_issue
|
||||
before_action :load_journal, only: [:children_journals, :update, :destroy]
|
||||
before_action :check_journal_operate_permission, only: [:update, :destroy]
|
||||
|
||||
def index
|
||||
@object_result = Api::V1::Issues::Journals::ListService.call(@issue, query_params, current_user)
|
||||
@total_journals_count = @object_result[:total_journals_count]
|
||||
@total_operate_journals_count = @object_result[:total_operate_journals_count]
|
||||
@total_comment_journals_count = @object_result[:total_comment_journals_count]
|
||||
@journals = kaminary_select_paginate(@object_result[:data])
|
||||
end
|
||||
|
||||
def create
|
||||
@object_result = Api::V1::Issues::Journals::CreateService.call(@issue, journal_params, current_user)
|
||||
end
|
||||
|
||||
def children_journals
|
||||
@object_results = Api::V1::Issues::Journals::ChildrenListService.call(@issue, @journal, query_params, current_user)
|
||||
@journals = kaminari_paginate(@object_results)
|
||||
end
|
||||
|
||||
def update
|
||||
@object_result = Api::V1::Issues::Journals::UpdateService.call(@issue, @journal, journal_params, current_user)
|
||||
end
|
||||
|
||||
def destroy
|
||||
TouchWebhookJob.set(wait: 5.seconds).perform_later('IssueComment', @issue&.id, current_user.id, @journal.id, 'deleted', JSON.parse(@journal.to_builder.target!))
|
||||
if @journal.destroy!
|
||||
render_ok
|
||||
else
|
||||
render_error("删除评论失败!")
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def query_params
|
||||
params.permit(:category, :keyword, :sort_by, :sort_direction)
|
||||
end
|
||||
|
||||
def journal_params
|
||||
params.permit(:notes, :parent_id, :reply_id, :attachment_ids => [], :receivers_login => [])
|
||||
end
|
||||
|
||||
def load_issue
|
||||
@issue = @project.issues.issue_issue.where(project_issues_index: params[:index]).where.not(id: params[:index]).take || Issue.find_by_id(params[:index])
|
||||
if @issue.blank?
|
||||
render_not_found("疑修不存在!")
|
||||
end
|
||||
end
|
||||
|
||||
def load_journal
|
||||
@journal = Journal.find_by_id(params[:id])
|
||||
return render_not_found("评论不存在!") unless @journal.present?
|
||||
end
|
||||
|
||||
def check_journal_operate_permission
|
||||
return render_forbidden("您没有操作权限!") unless @project.member?(current_user) || current_user.admin? || @issue.user == current_user || @journal.user == current_user || @journal.parent_journal&.user == current_user
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,87 @@
|
|||
class Api::V1::Issues::MilestonesController < Api::V1::BaseController
|
||||
before_action :require_login, except: [:index, :show]
|
||||
before_action :require_public_and_member_above, only: [:index, :show]
|
||||
before_action :require_operate_above, only: [:create, :update, :destroy]
|
||||
before_action :load_milestone, only: [:show, :update, :destroy]
|
||||
|
||||
# 里程碑列表
|
||||
def index
|
||||
@milestones = @project.versions
|
||||
@milestones = @milestones.ransack(id_eq: params[:keyword]).result.or(@milestones.ransack(name_or_description_cont: params[:keyword]).result) if params[:keyword].present?
|
||||
@closed_milestone_count = @milestones.closed.size
|
||||
@opening_milestone_count = @milestones.opening.size
|
||||
@milestones = params[:category] == "closed" ? @milestones.closed : @milestones.opening
|
||||
@milestones = @milestones.reorder("versions.#{sort_by} #{sort_direction}")
|
||||
if params[:only_name]
|
||||
@milestones = @milestones.select(:id, :name)
|
||||
@milestones = kaminary_select_paginate(@milestones)
|
||||
else
|
||||
@milestones = @milestones.includes(:issues, :closed_issues, :opened_issues)
|
||||
@milestones = kaminari_paginate(@milestones)
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
@milestone = @project.versions.new(milestone_params)
|
||||
if @milestone.save!
|
||||
render_ok
|
||||
else
|
||||
render_error(@milestone.errors.full_messages.join(","))
|
||||
end
|
||||
end
|
||||
|
||||
# 里程碑详情
|
||||
def show
|
||||
@object_result = Api::V1::Issues::Milestones::DetailIssuesService.call(@project, @milestone, query_params, current_user)
|
||||
@total_issues_count = @object_result[:total_issues_count]
|
||||
@opened_issues_count = @object_result[:opened_issues_count]
|
||||
@closed_issues_count = @object_result[:closed_issues_count]
|
||||
|
||||
@issues = kaminari_paginate(@object_result[:data])
|
||||
end
|
||||
|
||||
def update
|
||||
@milestone.attributes = milestone_params
|
||||
if @milestone.save!
|
||||
render_ok
|
||||
else
|
||||
render_error(@milestone.errors.full_messages.join(","))
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
if @milestone.destroy!
|
||||
render_ok
|
||||
else
|
||||
render_error("删除里程碑失败!")
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def milestone_params
|
||||
params.permit(:name, :description, :effective_date)
|
||||
end
|
||||
|
||||
def query_params
|
||||
params.permit(:category, :author_id, :assigner_id, :sort_by, :sort_direction, :issue_tag_ids)
|
||||
end
|
||||
|
||||
def load_milestone
|
||||
@milestone = @project.versions.find_by_id(params[:id])
|
||||
return render_not_found('里程碑不存在!') unless @milestone.present?
|
||||
end
|
||||
|
||||
def sort_by
|
||||
sort_by = params.fetch(:sort_by, "created_on")
|
||||
sort_by = Version.column_names.include?(sort_by) ? sort_by : "created_on"
|
||||
|
||||
sort_by
|
||||
end
|
||||
|
||||
def sort_direction
|
||||
sort_direction = params.fetch(:sort_direction, "desc").downcase
|
||||
sort_direction = %w(desc asc).include?(sort_direction) ? sort_direction : "desc"
|
||||
sort_direction
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,11 @@
|
|||
class Api::V1::Issues::StatuesController < Api::V1::BaseController
|
||||
|
||||
before_action :require_public_and_member_above, only: [:index]
|
||||
|
||||
# 状态列表
|
||||
def index
|
||||
@statues = IssueStatus.order("position asc")
|
||||
@statues = @statues.ransack(name_cont: params[:keyword]).result if params[:keyword].present?
|
||||
@statues = kaminary_select_paginate(@statues)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,116 @@
|
|||
class Api::V1::IssuesController < Api::V1::BaseController
|
||||
before_action :require_login, except: [:index, :show]
|
||||
before_action :require_public_and_member_above, only: [:index, :show, :create, :update, :destroy]
|
||||
before_action :require_operate_above, only: [:batch_update, :batch_destroy]
|
||||
|
||||
def index
|
||||
IssueTag.init_data(@project.id) unless $redis_cache.hget("project_init_issue_tags", @project.id)
|
||||
@object_result = Api::V1::Issues::ListService.call(@project, query_params, current_user)
|
||||
@total_issues_count = @object_result[:total_issues_count]
|
||||
@opened_issues_count = @object_result[:opened_issues_count]
|
||||
@closed_issues_count = @object_result[:closed_issues_count]
|
||||
if params[:only_name].present?
|
||||
@issues = kaminary_select_paginate(@object_result[:data].select(:id, :subject, :project_issues_index, :updated_on, :created_on))
|
||||
else
|
||||
@issues = kaminari_paginate(@object_result[:data])
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
@object_result = Api::V1::Issues::CreateService.call(@project, issue_params, current_user)
|
||||
end
|
||||
|
||||
before_action :load_issue, only: [:show, :update, :destroy]
|
||||
before_action :check_issue_operate_permission, only: [:update, :destroy]
|
||||
|
||||
def show
|
||||
@user_permission = current_user.present? && current_user.logged? && (@project.member?(current_user) || current_user.admin? || @issue.user == current_user)
|
||||
end
|
||||
|
||||
def update
|
||||
@object_result = Api::V1::Issues::UpdateService.call(@project, @issue, issue_params, current_user)
|
||||
end
|
||||
|
||||
def destroy
|
||||
@object_result = Api::V1::Issues::DeleteService.call(@project, @issue, current_user)
|
||||
if @object_result
|
||||
render_ok
|
||||
else
|
||||
render_error("删除疑修失败!")
|
||||
end
|
||||
end
|
||||
|
||||
before_action :load_issues, only: [:batch_update, :batch_destroy]
|
||||
|
||||
def batch_update
|
||||
@object_result = Api::V1::Issues::BatchUpdateService.call(@project, @issues, batch_issue_params, current_user)
|
||||
if @object_result
|
||||
render_ok
|
||||
else
|
||||
render_error("批量更新疑修失败!")
|
||||
end
|
||||
end
|
||||
|
||||
def batch_destroy
|
||||
@object_result = Api::V1::Issues::BatchDeleteService.call(@project, @issues, current_user)
|
||||
if @object_result
|
||||
render_ok
|
||||
else
|
||||
render_error("批量删除疑修失败!")
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_issue
|
||||
@issue = @project.issues.issue_issue.where(project_issues_index: params[:index]).where.not(id: params[:index]).take || Issue.find_by_id(params[:index])
|
||||
if @issue.blank?
|
||||
render_not_found("疑修不存在!")
|
||||
end
|
||||
end
|
||||
|
||||
def load_issues
|
||||
return render_error("请输入正确的ID数组!") unless params[:ids].is_a?(Array)
|
||||
params[:ids].each do |id|
|
||||
@issue = Issue.find_by_id(id)
|
||||
if @issue.blank?
|
||||
return render_not_found("ID为#{id}的疑修不存在!")
|
||||
end
|
||||
end
|
||||
@issues = Issue.where(id: params[:ids])
|
||||
end
|
||||
|
||||
def check_issue_operate_permission
|
||||
return render_forbidden("您没有操作权限!") unless @project.member?(current_user) || current_user.admin? || @issue.user == current_user
|
||||
end
|
||||
|
||||
def query_params
|
||||
params.permit(
|
||||
:category,
|
||||
:participant_category,
|
||||
:keyword, :author_id,
|
||||
:milestone_id, :assigner_id,
|
||||
:status_id,
|
||||
:begin_date, :end_date,
|
||||
:sort_by, :sort_direction,
|
||||
:issue_tag_ids)
|
||||
end
|
||||
|
||||
def issue_params
|
||||
params.permit(
|
||||
:status_id, :priority_id, :milestone_id,
|
||||
:branch_name, :start_date, :due_date,
|
||||
:subject, :description,
|
||||
:issue_tag_ids => [],
|
||||
:assigner_ids => [],
|
||||
:attachment_ids => [],
|
||||
:receivers_login => [])
|
||||
end
|
||||
|
||||
def batch_issue_params
|
||||
params.permit(
|
||||
:status_id, :priority_id, :milestone_id,
|
||||
:issue_tag_ids => [],
|
||||
:assigner_ids => [])
|
||||
end
|
||||
end
|
|
@ -0,0 +1,46 @@
|
|||
class Api::V1::ProjectTopicsController < Api::V1::BaseController
|
||||
|
||||
def index
|
||||
@project_topics = ProjectTopic
|
||||
@project_topics = @project_topics.ransack(name_cont: params[:keyword]) if params[:keyword].present?
|
||||
# @project_topics = @project_topics.includes(:projects)
|
||||
@project_topics = kaminary_select_paginate(@project_topics)
|
||||
end
|
||||
|
||||
def create
|
||||
ActiveRecord::Base.transaction do
|
||||
@project = Project.find_by_id(create_params[:project_id])
|
||||
return render_not_found unless @project.present?
|
||||
return render_error("请输入项目搜索标签名称.") unless create_params[:name].present?
|
||||
|
||||
@project_topic = ProjectTopic.find_or_create_by!(name: create_params[:name].downcase)
|
||||
@project_topic_ralate = @project_topic.project_topic_ralates.find_or_create_by!(project_id: create_params[:project_id])
|
||||
|
||||
if @project_topic.present? && @project_topic_ralate.present?
|
||||
render_ok
|
||||
else
|
||||
render_error("项目关联搜索标签失败.")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
ActiveRecord::Base.transaction do
|
||||
@project = Project.find_by_id(create_params[:project_id])
|
||||
return render_not_found unless @project.present?
|
||||
|
||||
@project_topic = ProjectTopic.find_by_id(params[:id])
|
||||
@project_topic_ralate = @project_topic.project_topic_ralates.find_by(project_id: @project.id)
|
||||
if @project_topic_ralate.destroy!
|
||||
render_ok
|
||||
else
|
||||
render_error("项目取消关联搜索标签失败.")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def create_params
|
||||
params.permit(:project_id, :name)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,42 @@
|
|||
class Api::V1::Projects::BranchesController < Api::V1::BaseController
|
||||
before_action :require_public_and_member_above, only: [:index, :all]
|
||||
|
||||
def index
|
||||
@result_object = Api::V1::Projects::Branches::ListService.call(@project, {name: params[:keyword], page: page, limit: limit}, current_user&.gitea_token)
|
||||
end
|
||||
|
||||
def all
|
||||
@result_object = Api::V1::Projects::Branches::AllListService.call(@project, current_user&.gitea_token)
|
||||
end
|
||||
|
||||
before_action :require_operate_above, only: [:create, :destroy]
|
||||
|
||||
def create
|
||||
@result_object = Api::V1::Projects::Branches::CreateService.call(@project, branch_params, current_user&.gitea_token)
|
||||
end
|
||||
|
||||
def destroy
|
||||
@result_object = Api::V1::Projects::Branches::DeleteService.call(@project, params[:name], current_user&.gitea_token)
|
||||
if @result_object
|
||||
return render_ok
|
||||
else
|
||||
return render_error('删除分支失败!')
|
||||
end
|
||||
end
|
||||
|
||||
before_action :require_manager_above, only: [:update_default_branch]
|
||||
|
||||
def update_default_branch
|
||||
@result_object = Api::V1::Projects::Branches::UpdateDefaultBranchService.call(@project, params[:name], current_user&.gitea_token)
|
||||
if @result_object
|
||||
return render_ok
|
||||
else
|
||||
return render_error('更新默认分支失败!')
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def branch_params
|
||||
params.require(:branch).permit(:new_branch_name, :old_branch_name)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,8 @@
|
|||
class Api::V1::Projects::CodeStatsController < Api::V1::BaseController
|
||||
before_action :require_public_and_member_above, only: [:index]
|
||||
|
||||
def index
|
||||
@result_object = Api::V1::Projects::CodeStats::ListService.call(@project, {ref: params[:ref]}, current_user&.gitea_token)
|
||||
# puts @result_object
|
||||
end
|
||||
end
|
|
@ -0,0 +1,10 @@
|
|||
class Api::V1::Projects::CollaboratorsController < Api::V1::BaseController
|
||||
|
||||
before_action :require_public_and_member_above, only: [:index]
|
||||
|
||||
def index
|
||||
@collaborators = @project.all_collaborators.like(params[:keyword])
|
||||
@collaborators = kaminary_select_paginate(@collaborators)
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,12 @@
|
|||
class Api::V1::Projects::CommitsController < Api::V1::BaseController
|
||||
before_action :require_public_and_member_above, only: [:index, :diff]
|
||||
|
||||
def index
|
||||
@result_object = Api::V1::Projects::Commits::ListService.call(@project, {page: page, limit: limit, sha: params[:sha]}, current_user&.gitea_token)
|
||||
puts @result_object
|
||||
end
|
||||
|
||||
def diff
|
||||
@result_object = Api::V1::Projects::Commits::DiffService.call(@project, params[:sha], current_user&.gitea_token)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,17 @@
|
|||
class Api::V1::Projects::ContentsController < Api::V1::BaseController
|
||||
before_action :require_operate_above_or_fork_project, only: [:batch]
|
||||
|
||||
def batch
|
||||
@batch_content_params = batch_content_params
|
||||
# 处理下author和committer信息,如果没传则默认为当前用户信息
|
||||
@batch_content_params.merge!(author_email: current_user.mail, author_name: current_user.login) if batch_content_params[:author_email].blank? && batch_content_params[:author_name].blank?
|
||||
@batch_content_params.merge!(committer_email: current_user.mail, committer_name: current_user.login) if batch_content_params[:committer_email].blank? && batch_content_params[:committer_name].blank?
|
||||
|
||||
@result_object = Api::V1::Projects::Contents::BatchCreateService.call(@project, @batch_content_params, @project.owner.gitea_token)
|
||||
end
|
||||
|
||||
private
|
||||
def batch_content_params
|
||||
params.require(:content).permit(:author_email, :author_name, :author_timeunix, :branch, :committer_email, :committer_name, :committer_timeunix, :message, :new_branch, files: [ :action_type, :content, :encoding, :file_path])
|
||||
end
|
||||
end
|
|
@ -0,0 +1,11 @@
|
|||
class Api::V1::Projects::ContributorsController < Api::V1::BaseController
|
||||
before_action :require_public_and_member_above, only: [:index, :stat]
|
||||
|
||||
# todo
|
||||
def index
|
||||
end
|
||||
|
||||
def stat
|
||||
@result_object = Api::V1::Projects::Contributors::StatService.call(@project, {branch: params[:branch], pass_year: params[:pass_year], page: page, limit: limit}, current_user&.gitea_token)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,12 @@
|
|||
class Api::V1::Projects::GitController < Api::V1::BaseController
|
||||
before_action :require_public_and_member_above, only: [:trees, :blobs]
|
||||
|
||||
def trees
|
||||
@result_object = Api::V1::Projects::Git::TreesService.call(@project, params[:sha], {recursive: params[:recursive], page: page, limit: limit}, current_user&.gitea_token)
|
||||
end
|
||||
|
||||
def blobs
|
||||
@result_object = Api::V1::Projects::Git::BlobsService.call(@project, params[:sha], current_user&.gitea_token)
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
class Api::V1::Projects::Pulls::BaseController < Api::V1::BaseController
|
||||
before_action :require_public_and_member_above
|
||||
before_action :load_pull_request
|
||||
|
||||
end
|
|
@ -0,0 +1,40 @@
|
|||
class Api::V1::Projects::Pulls::JournalsController < Api::V1::Projects::Pulls::BaseController
|
||||
|
||||
def index
|
||||
@journals = Api::V1::Projects::Pulls::Journals::ListService.call(@project, @pull_request, params, current_user)
|
||||
@journals = @journals.limit(200)
|
||||
end
|
||||
|
||||
def create
|
||||
@journal = Api::V1::Projects::Pulls::Journals::CreateService.call(@project, @pull_request, create_params, current_user)
|
||||
end
|
||||
|
||||
before_action :find_journal, only: [:update, :destroy]
|
||||
|
||||
def update
|
||||
@journal = Api::V1::Projects::Pulls::Journals::UpdateService.call(@project, @pull_request, @journal, update_params, current_user)
|
||||
end
|
||||
|
||||
def destroy
|
||||
if @journal.destroy
|
||||
render_ok
|
||||
else
|
||||
render_error("删除评论失败!")
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def create_params
|
||||
params.permit(:parent_id, :line_code, :note, :commit_id, :path, :type, :review_id, :diff => {})
|
||||
end
|
||||
|
||||
def update_params
|
||||
params.permit(:note, :commit_id, :state)
|
||||
end
|
||||
|
||||
def find_journal
|
||||
@journal = @pull_request.journals.find_by_id(params[:id])
|
||||
return render_not_found unless @journal.present?
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,20 @@
|
|||
class Api::V1::Projects::Pulls::PullsController < Api::V1::BaseController
|
||||
before_action :require_public_and_member_above
|
||||
|
||||
def index
|
||||
@pulls = Api::V1::Projects::Pulls::ListService.call(@project, query_params)
|
||||
@pulls = kaminari_paginate(@pulls)
|
||||
end
|
||||
|
||||
before_action :load_pull_request, only: [:show]
|
||||
|
||||
def show
|
||||
@result_object = Api::V1::Projects::Pulls::GetService.call(@project, @pull_request, current_user&.gitea_token)
|
||||
@last_review = @pull_request.reviews.order(created_at: :desc).take
|
||||
end
|
||||
|
||||
private
|
||||
def query_params
|
||||
params.permit(:status, :keyword, :priority_id, :issue_tag_id, :version_id, :reviewer_id, :sort_by, :sort_direction)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,23 @@
|
|||
class Api::V1::Projects::Pulls::ReviewsController < Api::V1::Projects::Pulls::BaseController
|
||||
|
||||
def index
|
||||
@reviews = @pull_request.reviews
|
||||
@reviews = @reviews.where(status: params[:status]) if params[:status].present?
|
||||
# @reviews = kaminari_paginate(@reviews)
|
||||
end
|
||||
|
||||
before_action :require_reviewer, only: [:create]
|
||||
|
||||
def create
|
||||
@review = Api::V1::Projects::Pulls::Reviews::CreateService.call(@project, @pull_request, review_params, current_user)
|
||||
end
|
||||
|
||||
private
|
||||
def require_reviewer
|
||||
return render_forbidden('您没有审查权限,请联系项目管理员') if !current_user.admin? && !@pull_request.reviewers.exists?(current_user.id) && !@project.manager?(current_user)
|
||||
end
|
||||
|
||||
def review_params
|
||||
params.require(:review).permit(:content, :commit_id, :status)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,10 @@
|
|||
class Api::V1::Projects::Pulls::VersionsController < Api::V1::Projects::Pulls::BaseController
|
||||
|
||||
def index
|
||||
@result_object = Api::V1::Projects::Pulls::Versions::ListService.call(@project, @pull_request, {page: page, limit: limit}, current_user&.gitea_token)
|
||||
end
|
||||
|
||||
def diff
|
||||
@result_object = Api::V1::Projects::Pulls::Versions::GetDiffService.call(@project, @pull_request, params[:id], {filepath: params[:filepath]}, current_user&.gitea_token)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,20 @@
|
|||
class Api::V1::Projects::TagsController < Api::V1::BaseController
|
||||
before_action :require_public_and_member_above, only: [:index]
|
||||
|
||||
def index
|
||||
@release_tags = @repository.version_releases.pluck(:tag_name)
|
||||
@result_object = Api::V1::Projects::Tags::ListService.call(@project, {page: page, limit: limit}, current_user&.gitea_token)
|
||||
puts @result_object
|
||||
end
|
||||
|
||||
before_action :require_operate_above, only: [:destroy]
|
||||
|
||||
def destroy
|
||||
@result_object = Api::V1::Projects::Tags::DeleteService.call(@project, params[:name], current_user&.gitea_token)
|
||||
if @result_object
|
||||
return render_ok
|
||||
else
|
||||
return render_error('删除标签失败!')
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,61 @@
|
|||
class Api::V1::Projects::WebhooksController < Api::V1::BaseController
|
||||
before_action :require_manager_above
|
||||
before_action :find_webhook, only: [:show, :update, :destroy, :tests, :hooktasks]
|
||||
|
||||
def index
|
||||
# @result_object = Api::V1::Projects::Webhooks::ListService.call(@project, current_user&.gitea_token)
|
||||
@webhooks = @project.webhooks
|
||||
@webhooks = @webhooks.where(type: params[:type]) if params[:type].present?
|
||||
@webhooks = kaminari_paginate(@webhooks)
|
||||
end
|
||||
|
||||
def create
|
||||
return render_error("webhooks数量已到上限!请删除暂不使用的webhooks以进行添加操作") if @project.webhooks.size > 49
|
||||
@result_object = Api::V1::Projects::Webhooks::CreateService.call(@project, create_webhook_params, current_user&.gitea_token)
|
||||
end
|
||||
|
||||
def show
|
||||
@result_object = Api::V1::Projects::Webhooks::GetService.call(@project, params[:id], current_user&.gitea_token)
|
||||
end
|
||||
|
||||
def update
|
||||
@result_object = Api::V1::Projects::Webhooks::UpdateService.call(@project, params[:id], webhook_params, current_user&.gitea_token)
|
||||
end
|
||||
|
||||
def destroy
|
||||
@result_object = Api::V1::Projects::Webhooks::DeleteService.call(@project, params[:id], current_user&.gitea_token)
|
||||
if @result_object
|
||||
return render_ok
|
||||
else
|
||||
return render_error('删除失败!')
|
||||
end
|
||||
end
|
||||
|
||||
def tests
|
||||
@result_object = Api::V1::Projects::Webhooks::TestsService.call(@project, params[:id], current_user&.gitea_token)
|
||||
if @result_object
|
||||
return render_ok
|
||||
else
|
||||
return render_error('推送失败!')
|
||||
end
|
||||
end
|
||||
|
||||
def hooktasks
|
||||
@hooktasks = @webhook.tasks.where(is_delivered: true).order("delivered desc")
|
||||
@hooktasks = kaminari_paginate(@hooktasks)
|
||||
end
|
||||
|
||||
private
|
||||
def create_webhook_params
|
||||
params.require(:webhook).permit(:active, :branch_filter, :http_method, :url, :content_type, :secret, :type, events: [])
|
||||
end
|
||||
|
||||
def webhook_params
|
||||
params.require(:webhook).permit(:active, :branch_filter, :http_method, :url, :content_type, :secret, events: [])
|
||||
end
|
||||
|
||||
def find_webhook
|
||||
@webhook = Gitea::Webhook.find_by_id(params[:id])
|
||||
return render_not_found unless @webhook.present?
|
||||
end
|
||||
end
|
|
@ -0,0 +1,19 @@
|
|||
class Api::V1::ProjectsController < Api::V1::BaseController
|
||||
before_action :require_public_and_member_above, only: [:show, :compare, :blame]
|
||||
|
||||
def index
|
||||
render_ok
|
||||
end
|
||||
|
||||
def show
|
||||
@result_object = Api::V1::Projects::GetService.call(@project, current_user.gitea_token)
|
||||
end
|
||||
|
||||
def compare
|
||||
@result_object = Api::V1::Projects::CompareService.call(@project, params[:from], params[:to], current_user&.gitea_token)
|
||||
end
|
||||
|
||||
def blame
|
||||
@result_object = Api::V1::Projects::BlameService.call(@project, params[:sha], params[:filepath], current_user&.gitea_token)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,16 @@
|
|||
class Api::V1::Users::FeedbacksController < Api::V1::BaseController
|
||||
|
||||
before_action :load_observe_user
|
||||
before_action :check_auth_for_observe_user
|
||||
|
||||
def create
|
||||
@result = Api::V1::Users::Feedbacks::CreateService.call(@observe_user, feedback_params)
|
||||
return render_error("反馈意见创建失败.") if @result.nil?
|
||||
return render_ok
|
||||
end
|
||||
|
||||
private
|
||||
def feedback_params
|
||||
params.permit(:content)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,13 @@
|
|||
class Api::V1::Users::ProjectsController < Api::V1::BaseController
|
||||
before_action :load_observe_user
|
||||
|
||||
def index
|
||||
@object_results = Api::V1::Users::Projects::ListService.call(@observe_user, query_params, current_user)
|
||||
@projects = kaminari_paginate(@object_results)
|
||||
end
|
||||
|
||||
private
|
||||
def query_params
|
||||
params.permit(:category, :is_public, :project_type, :sort_by, :sort_direction, :search)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,118 @@
|
|||
class Api::V1::UsersController < Api::V1::BaseController
|
||||
|
||||
before_action :load_observe_user, except: [:check_user_id]
|
||||
before_action :check_auth_for_observe_user, except: [:check_user_id]
|
||||
|
||||
def check_user_id
|
||||
return tip_exception(-1, "用户ID不存在") unless params[:user_id].present? && User.exists?(id: params[:user_id])
|
||||
render_ok
|
||||
end
|
||||
|
||||
def check_user_login
|
||||
return tip_exception(-1, "用户标识不存在") unless params[:login].present? && User.exists?(login: params[:login])
|
||||
render_ok
|
||||
end
|
||||
|
||||
def send_email_vefify_code
|
||||
code = %W(0 1 2 3 4 5 6 7 8 9)
|
||||
verification_code = code.sample(6).join
|
||||
mail = params[:email]
|
||||
code_type = params[:code_type]
|
||||
|
||||
status, message = InfoRiskControlService.call(mail, request.remote_ip)
|
||||
tip_exception(420, message) if status == 0
|
||||
|
||||
sign = Digest::MD5.hexdigest("#{OPENKEY}#{mail}")
|
||||
Rails.logger.info sign
|
||||
|
||||
tip_exception(501, "请求不合理") if sign != params[:smscode]
|
||||
|
||||
# 60s内不能重复发送
|
||||
# send_email_limit_cache_key = "send_email_60_second_limit:#{mail}"
|
||||
# tip_exception(-2, '请勿频繁操作') if Rails.cache.exist?(send_email_limit_cache_key)
|
||||
# send_email_control = LimitForbidControl::SendEmailCode.new(mail)
|
||||
# tip_exception(-2, '邮件发送太频繁,请稍后再试') if send_email_control.forbid?
|
||||
begin
|
||||
UserMailer.update_email(mail, verification_code).deliver_now
|
||||
|
||||
# Rails.cache.write(send_email_limit_cache_key, 1, expires_in: 1.minute)
|
||||
# send_email_control.increment!
|
||||
rescue Exception => e
|
||||
logger_error(e)
|
||||
tip_exception(-2,"邮件发送失败,请稍后重试")
|
||||
end
|
||||
ver_params = {code_type: code_type, code: verification_code, email: mail}
|
||||
last_code = VerificationCode.where(code_type: code_type, email: mail).last
|
||||
last_code.update_attributes!({created_at: Time.current - 10.minute}) if last_code.present?
|
||||
data = VerificationCode.new(ver_params)
|
||||
if data.save!
|
||||
render_ok
|
||||
else
|
||||
tip_exception(-1, "创建数据失败")
|
||||
end
|
||||
end
|
||||
|
||||
def check_password
|
||||
password = params[:password]
|
||||
return tip_exception(-5, "8~16位密码,支持字母数字和符号") unless password =~ CustomRegexp::PASSWORD
|
||||
return tip_exception(-5, "密码错误") unless @observe_user.check_password?(password)
|
||||
render_ok
|
||||
end
|
||||
|
||||
def check_email
|
||||
mail = strip(params[:email])
|
||||
return tip_exception(-2, "邮件格式有误") unless mail =~ CustomRegexp::EMAIL
|
||||
|
||||
exist_owner = Owner.find_by(mail: mail)
|
||||
return tip_exception(-2, '邮箱已被使用') if exist_owner
|
||||
render_ok
|
||||
end
|
||||
|
||||
def check_email_verify_code
|
||||
code = strip(params[:code])
|
||||
mail = strip(params[:email])
|
||||
code_type = params[:code_type]
|
||||
|
||||
return tip_exception(-2, "邮件格式有误") unless mail =~ CustomRegexp::EMAIL
|
||||
|
||||
verifi_code = VerificationCode.where(email: mail, code: code, code_type: code_type).last
|
||||
return render_ok if code == "123123" && EduSetting.get("code_debug") # 万能验证码,用于测试 # TODO 万能验证码,用于测试
|
||||
|
||||
return tip_exception(-6, "验证码不正确") if verifi_code&.code != code
|
||||
return tip_exception(-6, "验证码已失效") if !verifi_code&.effective?
|
||||
render_ok
|
||||
end
|
||||
|
||||
def check_phone_verify_code
|
||||
code = strip(params[:code])
|
||||
phone = strip(params[:phone])
|
||||
code_type = params[:code_type]
|
||||
|
||||
return tip_exception(-2, "手机号格式有误") unless phone =~ CustomRegexp::PHONE
|
||||
|
||||
verifi_code = VerificationCode.where(phone: phone, code: code, code_type: code_type).last
|
||||
return render_ok if code == "123123" && EduSetting.get("code_debug") # 万能验证码,用于测试 # TODO 万能验证码,用于测试
|
||||
|
||||
return tip_exception(-6, "验证码不正确") if verifi_code&.code != code
|
||||
return tip_exception(-6, "验证码已失效") if !verifi_code&.effective?
|
||||
render_ok
|
||||
end
|
||||
|
||||
def update_email
|
||||
@result_object = Api::V1::Users::UpdateEmailService.call(@observe_user, params, current_user.gitea_token)
|
||||
if @result_object
|
||||
return render_ok
|
||||
else
|
||||
return render_error('更改邮箱失败!')
|
||||
end
|
||||
end
|
||||
|
||||
def update_phone
|
||||
@result_object = Api::V1::Users::UpdatePhoneService.call(@observe_user, params)
|
||||
if @result_object
|
||||
return render_ok
|
||||
else
|
||||
return render_error('更改手机号失败!')
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,4 +1,6 @@
|
|||
require 'oauth2'
|
||||
# require 'openssl'
|
||||
# require 'jwt'
|
||||
|
||||
class ApplicationController < ActionController::Base
|
||||
include CodeExample
|
||||
|
@ -20,13 +22,14 @@ class ApplicationController < ActionController::Base
|
|||
# TODO
|
||||
# check sql query time
|
||||
before_action do
|
||||
if request.subdomain === 'testforgeplus' || request.subdomain === "profiler"
|
||||
Rack::MiniProfiler.authorize_request
|
||||
end
|
||||
# if request.subdomain === 'testforgeplus' || request.subdomain === "profiler"
|
||||
# Rack::MiniProfiler.authorize_request
|
||||
# end
|
||||
end
|
||||
|
||||
DCODES = %W(2 3 4 5 6 7 8 9 a b c f e f g h i j k l m n o p q r s t u v w x y z)
|
||||
OPENKEY = "79e33abd4b6588941ab7622aed1e67e8"
|
||||
OPENKEY = Rails.application.config_for(:configuration)['sign_key'] || "79e33abd4b6588941ab7622aed1e67e8"
|
||||
|
||||
|
||||
helper_method :current_user, :base_url
|
||||
|
||||
|
@ -78,8 +81,7 @@ class ApplicationController < ActionController::Base
|
|||
# 判断用户的邮箱或者手机是否可用
|
||||
# params[:type] 1: 注册;2:忘记密码;3:绑定
|
||||
def check_mail_and_phone_valid login, type
|
||||
unless login =~ /^[a-zA-Z0-9]+([._\\]*[a-zA-Z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/ || login =~ /^1\d{10}$/ ||
|
||||
login =~ /^[a-zA-Z0-9]+([._\\]*[a-zA-Z0-9])$/
|
||||
unless login =~ /^[a-zA-Z0-9]+([._\\]*[a-zA-Z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/ || login =~ /^1\d{10}$/
|
||||
tip_exception(-2, "请输入正确的手机号或邮箱")
|
||||
end
|
||||
|
||||
|
@ -102,23 +104,30 @@ class ApplicationController < ActionController::Base
|
|||
when 1, 2, 4, 9
|
||||
# 手机类型的发送
|
||||
sigle_para = {phone: value}
|
||||
status = Gitlink::Sms.send(mobile: value, code: code)
|
||||
tip_exception(-2, code_msg(status)) if status != 0
|
||||
# status = Gitlink::Sms.send(mobile: value, code: code)
|
||||
# tip_exception(-2, code_msg(status)) if status != 0
|
||||
status = Sms::UcloudService.call(value, code, send_type)
|
||||
tip_exception(-2, ucloud_code_msg(status)) if status != 0
|
||||
when 8, 3, 5
|
||||
# 邮箱类型的发送
|
||||
sigle_para = {email: value}
|
||||
# 60s内不能重复发送
|
||||
send_email_limit_cache_key = "send_email_60_second_limit:#{value}"
|
||||
tip_exception(-1, '请勿频繁操作') if Rails.cache.exist?(send_email_limit_cache_key)
|
||||
# send_email_limit_cache_key = "send_email_60_second_limit:#{value}"
|
||||
# tip_exception(-1, '请勿频繁操作') if Rails.cache.exist?(send_email_limit_cache_key)
|
||||
|
||||
# 短时间内不能大量发送
|
||||
send_email_control = LimitForbidControl::SendEmailCode.new(value)
|
||||
tip_exception(-1, '邮件发送太频繁,请稍后再试') if send_email_control.forbid?
|
||||
# # 短时间内不能大量发送
|
||||
# send_email_control = LimitForbidControl::SendEmailCode.new(value)
|
||||
# tip_exception(-1, '邮件发送太频繁,请稍后再试') if send_email_control.forbid?
|
||||
begin
|
||||
if send_type == 3
|
||||
UserMailer.find_password(value, code).deliver_now
|
||||
elsif send_type == 5
|
||||
UserMailer.bind_email(value, code).deliver_now
|
||||
else
|
||||
UserMailer.register_email(value, code).deliver_now
|
||||
|
||||
Rails.cache.write(send_email_limit_cache_key, 1, expires_in: 1.minute)
|
||||
send_email_control.increment!
|
||||
end
|
||||
# Rails.cache.write(send_email_limit_cache_key, 1, expires_in: 1.minute)
|
||||
# send_email_control.increment!
|
||||
# Mailer.run.email_register(code, value)
|
||||
rescue Exception => e
|
||||
logger_error(e)
|
||||
|
@ -148,6 +157,27 @@ class ApplicationController < ActionController::Base
|
|||
end
|
||||
end
|
||||
|
||||
def ucloud_code_msg status
|
||||
case status
|
||||
when 0
|
||||
"验证码已经发送到您的手机,请注意查收"
|
||||
when 171
|
||||
"API签名错误"
|
||||
when 18014
|
||||
"无效手机号码"
|
||||
when 18017
|
||||
"无效模板"
|
||||
when 18018
|
||||
"短信模板参数与短信模板不匹配"
|
||||
when 18023
|
||||
"短信内容中含有运营商拦截的关键词"
|
||||
when 18033
|
||||
"变量内容不符合规范"
|
||||
else
|
||||
"错误码#{status}"
|
||||
end
|
||||
end
|
||||
|
||||
def validate_type(object_type)
|
||||
normal_status(2, "参数") if params.has_key?(:sort_type) && !SORT_TYPE.include?(params[:sort_type].strip)
|
||||
end
|
||||
|
@ -169,7 +199,25 @@ class ApplicationController < ActionController::Base
|
|||
# 未授权的捕捉407,弹试用申请弹框
|
||||
def require_login
|
||||
#6.13 -hs
|
||||
tip_exception(401, "请登录后再操作") unless User.current.logged?
|
||||
end
|
||||
|
||||
def require_login_or_token
|
||||
if params[:token].present?
|
||||
user = User.try_to_autologin(params[:token])
|
||||
User.current = user
|
||||
end
|
||||
tip_exception(401, "请登录后再操作") unless User.current.logged?
|
||||
end
|
||||
|
||||
def require_login_cloud_ide_saas
|
||||
if params[:sign].present? && params[:email].present?
|
||||
sign = Digest::MD5.hexdigest("#{OPENKEY}#{params[:email]}")
|
||||
if params[:sign].to_s == sign
|
||||
user = User.find_by(mail: params[:email])
|
||||
User.current = user
|
||||
end
|
||||
end
|
||||
tip_exception(401, "请登录后再操作") unless User.current.logged?
|
||||
end
|
||||
|
||||
|
@ -248,6 +296,25 @@ class ApplicationController < ActionController::Base
|
|||
#return if params[:controller] == "main"
|
||||
# Find the current user
|
||||
#Rails.logger.info("current_laboratory is #{current_laboratory} domain is #{request.subdomain}")
|
||||
if request.headers["Authorization"].present? && request.headers["Authorization"].start_with?('Bearer')
|
||||
if !valid_doorkeeper_token?
|
||||
header = request.authorization
|
||||
pattern = /^Bearer /i
|
||||
token = header.gsub(pattern, "")
|
||||
User.current, message = Bot.decode_jwt_token(token)
|
||||
tip_exception(401, message) if message.present?
|
||||
else
|
||||
if @doorkeeper_token.present?
|
||||
# client方法对接,需要一直带着用户标识uid
|
||||
if @doorkeeper_token.resource_owner_id.blank?
|
||||
tip_exception(-1, "缺少用户标识!") if params[:uid].nil?
|
||||
User.current = User.find(params[:uid])
|
||||
else
|
||||
User.current = User.find_by(id: @doorkeeper_token.resource_owner_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
User.current = find_current_user
|
||||
uid_logger("user_setup: " + (User.current.logged? ? "#{User.current.try(:login)} (id=#{User.current.try(:id)})" : "anonymous"))
|
||||
|
||||
|
@ -265,25 +332,28 @@ class ApplicationController < ActionController::Base
|
|||
end
|
||||
end
|
||||
|
||||
# if !User.current.logged? && Rails.env.development?
|
||||
# User.current = User.find 1
|
||||
# end
|
||||
if !User.current.logged? && Rails.env.development?
|
||||
user = User.find 1
|
||||
User.current = user
|
||||
start_user_session(user)
|
||||
end
|
||||
|
||||
|
||||
# 测试版前端需求
|
||||
logger.info("subdomain:#{request.subdomain}")
|
||||
# if request.subdomain != "www"
|
||||
# if params[:debug] == 'teacher' #todo 为了测试,记得讲debug删除
|
||||
# User.current = User.find 81403
|
||||
# elsif params[:debug] == 'student'
|
||||
# User.current = User.find 8686
|
||||
# elsif params[:debug] == 'admin'
|
||||
# logger.info "@@@@@@@@@@@@@@@@@@@@@@ debug mode....."
|
||||
# user = User.find 36480
|
||||
# User.current = user
|
||||
# cookies.signed[:user_id] = user.id
|
||||
# end
|
||||
# end
|
||||
if request.subdomain != "www"
|
||||
if params[:debug] == 'teacher' #todo 为了测试,记得讲debug删除
|
||||
User.current = User.find 81403
|
||||
elsif params[:debug] == 'student'
|
||||
User.current = User.find 8686
|
||||
elsif params[:debug] == 'admin'
|
||||
logger.info "@@@@@@@@@@@@@@@@@@@@@@ debug mode....."
|
||||
user = User.find 36480
|
||||
User.current = user
|
||||
cookies.signed[:user_id] = user.id
|
||||
end
|
||||
end
|
||||
end
|
||||
# User.current = User.find 81403
|
||||
end
|
||||
|
||||
|
@ -336,11 +406,6 @@ class ApplicationController < ActionController::Base
|
|||
@message = message
|
||||
end
|
||||
|
||||
# 实训等对应的仓库地址
|
||||
def repo_ip_url(repo_path)
|
||||
"#{edu_setting('git_address_ip')}/#{repo_path}"
|
||||
end
|
||||
|
||||
def repo_url(repo_path)
|
||||
"#{edu_setting('git_address_domain')}/#{repo_path}"
|
||||
end
|
||||
|
@ -609,7 +674,15 @@ class ApplicationController < ActionController::Base
|
|||
|
||||
def kaminari_paginate(relation)
|
||||
limit = params[:limit] || params[:per_page]
|
||||
limit = (limit.to_i.zero? || limit.to_i > 15) ? 15 : limit.to_i
|
||||
limit = (limit.to_i.zero? || limit.to_i > 50) ? 50 : limit.to_i
|
||||
page = params[:page].to_i.zero? ? 1 : params[:page].to_i
|
||||
|
||||
relation.page(page).per(limit)
|
||||
end
|
||||
|
||||
def kaminari_unlimit_paginate(relation)
|
||||
limit = params[:limit] || params[:per_page]
|
||||
limit = (limit.to_i.zero? || limit.to_i > 9999) ? 9999 : limit.to_i
|
||||
page = params[:page].to_i.zero? ? 1 : params[:page].to_i
|
||||
|
||||
relation.page(page).per(limit)
|
||||
|
@ -617,7 +690,7 @@ class ApplicationController < ActionController::Base
|
|||
|
||||
def kaminari_array_paginate(relation)
|
||||
limit = params[:limit] || params[:per_page]
|
||||
limit = (limit.to_i.zero? || limit.to_i > 15) ? 15 : limit.to_i
|
||||
limit = (limit.to_i.zero? || limit.to_i > 20) ? 20 : limit.to_i
|
||||
page = params[:page].to_i.zero? ? 1 : params[:page].to_i
|
||||
|
||||
Kaminari.paginate_array(relation).page(page).per(limit)
|
||||
|
@ -686,18 +759,24 @@ class ApplicationController < ActionController::Base
|
|||
|
||||
@project, @owner = Project.find_with_namespace(namespace, id)
|
||||
|
||||
if @project and current_user.can_read_project?(@project)
|
||||
if @project and (current_user.can_read_project?(@project) || controller_path == "projects/project_invite_links")
|
||||
logger.info "###########: has project and can read project"
|
||||
@project
|
||||
# elsif @project && current_user.is_a?(AnonymousUser)
|
||||
# logger.info "###########:This is AnonymousUser"
|
||||
# @project = nil if !@project.is_public?
|
||||
# render_forbidden and return
|
||||
else
|
||||
if @project.present?
|
||||
logger.info "###########: has project and but can't read project"
|
||||
@project = nil
|
||||
render_forbidden and return
|
||||
else
|
||||
logger.info "###########:project not found"
|
||||
@project = nil
|
||||
render_not_found and return
|
||||
end
|
||||
end
|
||||
@project
|
||||
end
|
||||
|
||||
|
@ -709,14 +788,20 @@ class ApplicationController < ActionController::Base
|
|||
Rails.application.config_for(:configuration)['platform_url'] || request.base_url
|
||||
end
|
||||
|
||||
def image_type?(str)
|
||||
default_type = %w(png jpg gif tif psd svg bmp webp jpeg ico psd)
|
||||
default_type.include?(str&.downcase)
|
||||
end
|
||||
|
||||
def convert_image!
|
||||
@image = params[:image]
|
||||
@image = @image.nil? && params[:user].present? ? params[:user][:image] : @image
|
||||
return unless @image.present?
|
||||
max_size = EduSetting.get('upload_avatar_max_size') || 2 * 1024 * 1024 # 2M
|
||||
if @image.class == ActionDispatch::Http::UploadedFile
|
||||
render_error('请上传文件') if @image.size.zero?
|
||||
render_error('文件大小超过限制') if @image.size > max_size.to_i
|
||||
return render_error('请上传文件') if @image.size.zero?
|
||||
return render_error('文件大小超过限制') if @image.size > max_size.to_i
|
||||
return render_error('头像格式不正确!') unless image_type?(File.extname(@image.original_filename.to_s)[1..-1])
|
||||
else
|
||||
image = @image.to_s.strip
|
||||
return render_error('请上传正确的图片') if image.blank?
|
||||
|
@ -742,37 +827,10 @@ class ApplicationController < ActionController::Base
|
|||
render json: exception.tip_json
|
||||
end
|
||||
|
||||
def render_parameter_missing
|
||||
render json: { status: -1, message: '参数缺失' }
|
||||
end
|
||||
|
||||
def set_export_cookies
|
||||
cookies[:fileDownload] = true
|
||||
end
|
||||
|
||||
# 149课程的评审用户数据创建(包含创建课堂学生)
|
||||
def open_class_user
|
||||
user = User.find_by(login: "OpenClassUser")
|
||||
unless user
|
||||
ActiveRecord::Base.transaction do
|
||||
user_params = {status: 1, login: "OpenClassUser", lastname: "开放课程",
|
||||
nickname: "开放课程", professional_certification: 1, certification: 1, grade: 0,
|
||||
password: "12345678", phone: "11122223333", profile_completed: 1}
|
||||
user = User.create!(user_params)
|
||||
|
||||
UserExtension.create!(user_id: user.id, gender: 0, school_id: 3396, :identity => 1, :student_id => "openclassuser") # 3396
|
||||
|
||||
subject = Subject.find_by(id: 149)
|
||||
if subject
|
||||
subject.courses.each do |course|
|
||||
CourseMember.create!(course_id: course.id, role: 3, user_id: user.id) if !course.course_members.exists?(user_id: user.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
user
|
||||
end
|
||||
|
||||
# 记录热门搜索关键字
|
||||
def record_search_keyword
|
||||
keyword = params[:keyword].to_s.strip
|
||||
|
|
|
@ -31,14 +31,17 @@ class AttachmentsController < ApplicationController
|
|||
|
||||
def get_file
|
||||
normal_status(-1, "参数缺失") if params[:download_url].blank?
|
||||
url = URI.encode(params[:download_url].to_s.gsub("http:", "https:"))
|
||||
if url.starts_with?(base_url)
|
||||
domain = Gitea.gitea_config[:domain]
|
||||
api_url = Gitea.gitea_config[:base_url]
|
||||
url = url.split(base_url)[1].gsub("api", "repos").gsub('?filepath=', '/').gsub('&', '?')
|
||||
request_url = [domain, api_url, url, "?ref=#{params[:ref]}&access_token=#{current_user&.gitea_token}"].join
|
||||
url = base_url.starts_with?("https:") ? params[:download_url].to_s.gsub("http:", "https:") : params[:download_url].to_s
|
||||
if url.starts_with?(base_url) && !url.starts_with?("#{base_url}/repo")
|
||||
domain = GiteaService.gitea_config[:domain]
|
||||
api_url = GiteaService.gitea_config[:base_url]
|
||||
url = ("/repos"+url.split(base_url + "/api")[1])
|
||||
filepath, ref = url.split("/")[-1].split("?")
|
||||
url.gsub!(url.split("/")[-1], '')
|
||||
puts filepath
|
||||
request_url = [domain, api_url, url, CGI.escape(filepath), "?ref=#{CGI.escape(ref.split('ref=')[1])}&access_token=#{User.where(admin: true).take&.gitea_token}"].join
|
||||
response = Faraday.get(request_url)
|
||||
filename = url.to_s.split("/").pop()
|
||||
filename = filepath
|
||||
else
|
||||
response = Faraday.get(url)
|
||||
filename = params[:download_url].to_s.split("/").pop()
|
||||
|
@ -213,20 +216,17 @@ class AttachmentsController < ApplicationController
|
|||
def attachment_candown
|
||||
unless current_user.admin? || current_user.business?
|
||||
candown = true
|
||||
unless params[:type] == 'history'
|
||||
if @file.container && current_user.logged?
|
||||
if @file.container
|
||||
if @file.container.is_a?(Issue)
|
||||
course = @file.container.project
|
||||
candown = course.member?(current_user)
|
||||
project = @file.container.project
|
||||
candown = project.is_public || (current_user.logged? && project.member?(current_user))
|
||||
elsif @file.container.is_a?(Journal)
|
||||
course = @file.container.issue.project
|
||||
candown = course.member?(current_user)
|
||||
project = @file.container.issue.project
|
||||
candown = project.is_public || (current_user.logged? && project.member?(current_user))
|
||||
else
|
||||
course = nil
|
||||
end
|
||||
tip_exception(403, "您没有权限进入") if course.present? && !candown
|
||||
tip_exception(403, "您没有权限进入") if @file.container.is_a?(ApplyUserAuthentication)
|
||||
project = nil
|
||||
end
|
||||
tip_exception(403, "您没有权限进入") if project.present? && !candown
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,35 +1,19 @@
|
|||
class BindUsersController < ApplicationController
|
||||
# before_action :require_login
|
||||
|
||||
def create
|
||||
# user = CreateBindUserService.call(create_params)
|
||||
#
|
||||
if params[:type] == "qq"
|
||||
begin
|
||||
user = CreateBindUserService.call(current_user, create_params)
|
||||
successful_authentication(user) if user.id != current_user.id
|
||||
|
||||
render_ok
|
||||
rescue ApplicationService::Error => ex
|
||||
render_error(ex.message)
|
||||
end
|
||||
else
|
||||
begin
|
||||
Rails.logger.debug "--------------开始绑定用户------------"
|
||||
Rails.logger.debug "--------------params: #{params.to_unsafe_h}"
|
||||
tip_exception '系统错误' if session[:unionid].blank?
|
||||
|
||||
bind_user = User.try_to_login(params[:username], params[:password])
|
||||
tip_exception '用户名或者密码错误' if bind_user.blank?
|
||||
tip_exception '用户名或者密码错误' unless bind_user.check_password?(params[:password].to_s)
|
||||
tip_exception '参数错误' unless ["qq", "wechat", "gitee", "github", "educoder"].include?(params[:type].to_s)
|
||||
tip_exception '该账号已被绑定,请更换其他账号进行绑定' if bind_user.bind_open_user?(params[:type].to_s)
|
||||
|
||||
OpenUsers::Wechat.create!(user: bind_user, uid: session[:unionid])
|
||||
"OpenUsers::#{params[:type].to_s.capitalize}".constantize.create!(user: bind_user, uid: session[:unionid])
|
||||
successful_authentication(bind_user)
|
||||
|
||||
render_ok
|
||||
rescue Exception => e
|
||||
render_error(e.message)
|
||||
end
|
||||
end
|
||||
@user = bind_user
|
||||
end
|
||||
|
||||
def new_user
|
||||
|
|
|
@ -8,7 +8,7 @@ class Ci::BaseController < ApplicationController
|
|||
namespace = params[:owner]
|
||||
id = params[:repo] || params[:id]
|
||||
|
||||
@ci_user, @repo = Ci::Repo.find_with_namespace(namespace, id)
|
||||
@ci_user, @repo = Ci::Repo.find_with_namespace(namespace, id, current_user.login)
|
||||
end
|
||||
|
||||
def load_all_repo
|
||||
|
|
|
@ -14,12 +14,12 @@ class Ci::CloudAccountsController < Ci::BaseController
|
|||
|
||||
def create
|
||||
flag, msg = check_bind_cloud_account!
|
||||
return render_error(msg) if flag === true
|
||||
return tip_exception(msg) if flag === true
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
@cloud_account = bind_account!
|
||||
if @cloud_account.blank?
|
||||
render_error('激活失败, 请检查你的云服务器信息是否正确.')
|
||||
tip_exception('激活失败, 请检查你的云服务器信息是否正确.')
|
||||
raise ActiveRecord::Rollback
|
||||
else
|
||||
current_user.set_drone_step!(User::DEVOPS_UNVERIFIED)
|
||||
|
@ -27,17 +27,17 @@ class Ci::CloudAccountsController < Ci::BaseController
|
|||
end
|
||||
end
|
||||
rescue Exception => ex
|
||||
render_error(ex.message)
|
||||
tip_exception(ex.message)
|
||||
end
|
||||
|
||||
def activate
|
||||
return render_error('请先认证') unless current_user.ci_certification?
|
||||
return tip_exception('请先认证') unless current_user.ci_certification?
|
||||
|
||||
begin
|
||||
@cloud_account = Ci::CloudAccount.find params[:id]
|
||||
ActiveRecord::Base.transaction do
|
||||
if @repo
|
||||
return render_error('该项目已经激活') if @repo.repo_active?
|
||||
return tip_exception('该项目已经激活') if @repo.repo_active?
|
||||
@repo.activate!(@project)
|
||||
else
|
||||
@repo = Ci::Repo.auto_create!(@ci_user, @project)
|
||||
|
@ -50,7 +50,7 @@ class Ci::CloudAccountsController < Ci::BaseController
|
|||
end
|
||||
render_ok
|
||||
rescue Exception => ex
|
||||
render_error(ex.message)
|
||||
tip_exception(ex.message)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -59,39 +59,39 @@ class Ci::CloudAccountsController < Ci::BaseController
|
|||
|
||||
def bind
|
||||
flag, msg = check_bind_cloud_account!
|
||||
return render_error(msg) if flag === true
|
||||
return tip_exception(msg) if flag === true
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
@cloud_account = bind_account!
|
||||
if @cloud_account.blank?
|
||||
render_error('激活失败, 请检查你的云服务器信息是否正确.')
|
||||
tip_exception('激活失败, 请检查你的云服务器信息是否正确.')
|
||||
raise ActiveRecord::Rollback
|
||||
else
|
||||
current_user.set_drone_step!(User::DEVOPS_UNVERIFIED)
|
||||
end
|
||||
end
|
||||
rescue Exception => ex
|
||||
render_error(ex.message)
|
||||
tip_exception(ex.message)
|
||||
end
|
||||
|
||||
def trustie_bind
|
||||
account = params[:account].to_s
|
||||
return render_error("account不能为空.") if account.blank?
|
||||
return tip_exception("account不能为空.") if account.blank?
|
||||
|
||||
flag, msg = check_trustie_bind_cloud_account!
|
||||
return render_error(msg) if flag === true
|
||||
return tip_exception(msg) if flag === true
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
@cloud_account = trustie_bind_account!
|
||||
if @cloud_account.blank?
|
||||
render_error('激活失败, 请检查你的云服务器信息是否正确.')
|
||||
tip_exception('激活失败, 请检查你的云服务器信息是否正确.')
|
||||
raise ActiveRecord::Rollback
|
||||
else
|
||||
current_user.set_drone_step!(User::DEVOPS_UNVERIFIED)
|
||||
end
|
||||
end
|
||||
rescue Exception => ex
|
||||
render_error(ex.message)
|
||||
tip_exception(ex.message)
|
||||
end
|
||||
|
||||
def unbind
|
||||
|
@ -107,18 +107,18 @@ class Ci::CloudAccountsController < Ci::BaseController
|
|||
render_ok
|
||||
end
|
||||
rescue Exception => ex
|
||||
render_error(ex.message)
|
||||
tip_exception(ex.message)
|
||||
end
|
||||
|
||||
def oauth_grant
|
||||
password = params[:password].to_s
|
||||
return render_error('你输入的密码不正确.') unless current_user.check_password?(password)
|
||||
return tip_exception('你输入的密码不正确.') unless current_user.check_password?(password)
|
||||
|
||||
oauth = current_user.oauths.last
|
||||
return render_error("服务器出小差了.") if oauth.blank?
|
||||
return tip_exception("服务器出小差了.") if oauth.blank?
|
||||
|
||||
result = gitea_oauth_grant!(password, oauth)
|
||||
return render_error('授权失败.') unless result === true
|
||||
return tip_exception('授权失败.') unless result === true
|
||||
current_user.set_drone_step!(User::DEVOPS_CERTIFICATION)
|
||||
end
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ class Ci::PipelinesController < Ci::BaseController
|
|||
ActiveRecord::Base.transaction do
|
||||
size = Ci::Pipeline.where('branch=? and identifier=? and owner=?', params[:branch], params[:repo], params[:owner]).size
|
||||
if size > 0
|
||||
render_error("#{params[:branch]}分支已经存在流水线!")
|
||||
tip_exception("#{params[:branch]}分支已经存在流水线!")
|
||||
return
|
||||
end
|
||||
pipeline = Ci::Pipeline.new(pipeline_name: params[:pipeline_name], file_name: params[:file_name],owner: params[:owner],
|
||||
|
@ -53,7 +53,7 @@ class Ci::PipelinesController < Ci::BaseController
|
|||
render_ok({id: pipeline.id})
|
||||
end
|
||||
rescue Exception => ex
|
||||
render_error(ex.message)
|
||||
tip_exception(ex.message)
|
||||
end
|
||||
|
||||
# 在代码库创建文件
|
||||
|
@ -81,6 +81,7 @@ class Ci::PipelinesController < Ci::BaseController
|
|||
repo_branch: pipeline.branch,
|
||||
repo_config: pipeline.file_name
|
||||
}
|
||||
Rails.logger.info("########create_params===#{create_params.to_json}")
|
||||
repo = Ci::Repo.create_repo(create_params)
|
||||
repo
|
||||
end
|
||||
|
@ -118,7 +119,7 @@ class Ci::PipelinesController < Ci::BaseController
|
|||
end
|
||||
render_ok
|
||||
rescue Exception => ex
|
||||
render_error(ex.message)
|
||||
tip_exception(ex.message)
|
||||
end
|
||||
|
||||
def destroy
|
||||
|
@ -132,7 +133,7 @@ class Ci::PipelinesController < Ci::BaseController
|
|||
end
|
||||
render_ok
|
||||
rescue Exception => ex
|
||||
render_error(ex.message)
|
||||
tip_exception(ex.message)
|
||||
end
|
||||
|
||||
def content
|
||||
|
@ -182,7 +183,7 @@ class Ci::PipelinesController < Ci::BaseController
|
|||
render_ok
|
||||
end
|
||||
rescue Exception => ex
|
||||
render_error(ex.message)
|
||||
tip_exception(ex.message)
|
||||
end
|
||||
|
||||
def update_stage
|
||||
|
@ -192,7 +193,7 @@ class Ci::PipelinesController < Ci::BaseController
|
|||
end
|
||||
render_ok
|
||||
rescue Exception => ex
|
||||
render_error(ex.message)
|
||||
tip_exception(ex.message)
|
||||
end
|
||||
|
||||
def delete_stage
|
||||
|
@ -205,7 +206,7 @@ class Ci::PipelinesController < Ci::BaseController
|
|||
render_ok
|
||||
end
|
||||
rescue Exception => ex
|
||||
render_error(ex.message)
|
||||
tip_exception(ex.message)
|
||||
end
|
||||
|
||||
def update_stage_index(pipeline_id, show_index, diff)
|
||||
|
@ -229,7 +230,7 @@ class Ci::PipelinesController < Ci::BaseController
|
|||
unless steps.empty?
|
||||
steps.each do |step|
|
||||
unless step[:template_id]
|
||||
render_error('请选择模板!')
|
||||
tip_exception('请选择模板!')
|
||||
return
|
||||
end
|
||||
if !step[:id]
|
||||
|
@ -246,7 +247,7 @@ class Ci::PipelinesController < Ci::BaseController
|
|||
render_ok
|
||||
end
|
||||
rescue Exception => ex
|
||||
render_error(ex.message)
|
||||
tip_exception(ex.message)
|
||||
end
|
||||
|
||||
def create_stage_step
|
||||
|
@ -262,7 +263,7 @@ class Ci::PipelinesController < Ci::BaseController
|
|||
render_ok
|
||||
end
|
||||
rescue Exception => ex
|
||||
render_error(ex.message)
|
||||
tip_exception(ex.message)
|
||||
end
|
||||
|
||||
def update_stage_step
|
||||
|
@ -279,7 +280,7 @@ class Ci::PipelinesController < Ci::BaseController
|
|||
render_ok
|
||||
end
|
||||
rescue Exception => ex
|
||||
render_error(ex.message)
|
||||
tip_exception(ex.message)
|
||||
end
|
||||
|
||||
def delete_stage_step
|
||||
|
@ -289,6 +290,6 @@ class Ci::PipelinesController < Ci::BaseController
|
|||
end
|
||||
render_ok
|
||||
rescue Exception => ex
|
||||
render_error(ex.message)
|
||||
tip_exception(ex.message)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -30,19 +30,19 @@ class Ci::ProjectsController < Ci::BaseController
|
|||
@file = interactor.result
|
||||
render_result(1, "更新成功")
|
||||
else
|
||||
render_error(interactor.error)
|
||||
tip_exception(interactor.error)
|
||||
end
|
||||
end
|
||||
|
||||
def activate
|
||||
return render_error('你还未认证') unless current_user.ci_certification?
|
||||
return tip_exception('你还未认证') unless current_user.ci_certification?
|
||||
|
||||
begin
|
||||
ActiveRecord::Base.transaction do
|
||||
if @repo
|
||||
return render_error('该项目已经激活') if @repo.repo_active?
|
||||
@repo.destroy! if @repo&.repo_user_id == 0
|
||||
return tip_exception('该项目已经激活') if @repo.repo_active?
|
||||
@repo.activate!(@project)
|
||||
return render_ok
|
||||
else
|
||||
@repo = Ci::Repo.auto_create!(@ci_user, @project)
|
||||
@ci_user.update_column(:user_syncing, false)
|
||||
|
@ -55,12 +55,12 @@ class Ci::ProjectsController < Ci::BaseController
|
|||
end
|
||||
render_ok
|
||||
rescue Exception => ex
|
||||
render_error(ex.message)
|
||||
tip_exception(ex.message)
|
||||
end
|
||||
end
|
||||
|
||||
def deactivate
|
||||
return render_error('该项目已经取消激活') if !@repo.repo_active?
|
||||
return tip_exception('该项目已经取消激活') if !@repo.repo_active?
|
||||
|
||||
@project.update_column(:open_devops, false)
|
||||
@repo.deactivate_repos!
|
||||
|
|
|
@ -20,14 +20,14 @@ class Ci::SecretsController < Ci::BaseController
|
|||
if result["id"]
|
||||
render_ok
|
||||
else
|
||||
render_error(result["message"])
|
||||
tip_exception(result["message"])
|
||||
end
|
||||
else
|
||||
result = Ci::Drone::API.new(@ci_user.user_hash, ci_drone_url, params[:owner], params[:repo], options).create_secret
|
||||
if result["id"]
|
||||
render_ok
|
||||
else
|
||||
render_error(result["message"])
|
||||
tip_exception(result["message"])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -39,14 +39,14 @@ class Ci::SecretsController < Ci::BaseController
|
|||
Ci::Drone::API.new(@ci_user.user_hash, ci_drone_url, params[:owner], params[:repo], {name: name}).delete_secret
|
||||
render_ok
|
||||
else
|
||||
render_error("参数名不能为空")
|
||||
tip_exception("参数名不能为空")
|
||||
end
|
||||
rescue Exception => ex
|
||||
render_ok
|
||||
end
|
||||
|
||||
def ci_drone_url
|
||||
user = User.find_by(login: params[:owner])
|
||||
user = User.find_by(login: params[:owner]) || User.find_by(login: current_user.login)
|
||||
user&.ci_cloud_account.drone_url
|
||||
end
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ class Ci::TemplatesController < Ci::BaseController
|
|||
end
|
||||
render_ok
|
||||
rescue Exception => ex
|
||||
render_error(ex.message)
|
||||
tip_exception(ex.message)
|
||||
end
|
||||
|
||||
def update
|
||||
|
@ -63,7 +63,7 @@ class Ci::TemplatesController < Ci::BaseController
|
|||
)
|
||||
render_ok
|
||||
rescue Exception => ex
|
||||
render_error(ex.message)
|
||||
tip_exception(ex.message)
|
||||
end
|
||||
|
||||
def destroy
|
||||
|
@ -73,7 +73,7 @@ class Ci::TemplatesController < Ci::BaseController
|
|||
end
|
||||
render_ok
|
||||
rescue Exception => ex
|
||||
render_error(ex.message)
|
||||
tip_exception(ex.message)
|
||||
end
|
||||
|
||||
#======流水线模板查询=====#
|
||||
|
|
|
@ -0,0 +1,139 @@
|
|||
#coding=utf-8
|
||||
class ClaimsController < ApplicationController
|
||||
# skip_before_action :verify_authenticity_token
|
||||
protect_from_forgery with: :null_session
|
||||
before_action :require_login, except: [:index]
|
||||
before_action :set_issue
|
||||
|
||||
def index
|
||||
@user_claimed = 0
|
||||
@claims = @issue.claims.claim_includes.order("created_at desc")
|
||||
|
||||
@claims.each do |claim|
|
||||
if claim.user_id == current_user.id
|
||||
@user_claimed = 1
|
||||
break
|
||||
end
|
||||
end
|
||||
render file: 'app/views/claims/list.json.jbuilder'
|
||||
end
|
||||
|
||||
def create
|
||||
@claim = Claim.find_by_sql(["select id from claims where issue_id=? and user_id=?",params[:issue_id], current_user.id])
|
||||
if @claim.present?
|
||||
return normal_status(-1,"您已经声明过该易修")
|
||||
end
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
@claim = Claim.new(parse_issue_params(params))
|
||||
if @claim.save
|
||||
@claims = @issue.claims.claim_includes.order("created_at desc")
|
||||
@user_claimed = 1
|
||||
|
||||
journal_params = {
|
||||
journalized_id: params[:issue_id],
|
||||
journalized_type: "Issue",
|
||||
user_id: current_user.id ,
|
||||
notes: "新建声明: #{params[:claim_note]}",
|
||||
}
|
||||
|
||||
journal = Journal.new(journal_params)
|
||||
if journal.save
|
||||
SendTemplateMessageJob.perform_later('IssueClaim', current_user.id, @issue&.id)
|
||||
render file: 'app/views/claims/list.json.jbuilder'
|
||||
else
|
||||
normal_status(-1,"新建声明关联评论操作失败")
|
||||
end
|
||||
|
||||
else
|
||||
normal_status(-1,"新建声明操作失败")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
@claim = Claim.find_by_id(params[:claim_id])
|
||||
if @claim.blank?
|
||||
return normal_status(-1,"易修不存在")
|
||||
end
|
||||
|
||||
if @claim.user_id != current_user.id
|
||||
return normal_status(-1,"你不能更新别人的声明")
|
||||
end
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
if @claim.update_attribute(:note,params[:claim_note])
|
||||
@claims = @issue.claims.claim_includes.order("created_at desc")
|
||||
@user_claimed = 1
|
||||
|
||||
journal_params = {
|
||||
journalized_id: params[:issue_id],
|
||||
journalized_type: "Issue",
|
||||
user_id: current_user.id ,
|
||||
notes: "更新声明: #{params[:claim_note]}",
|
||||
}
|
||||
|
||||
journal = Journal.new(journal_params)
|
||||
if journal.save
|
||||
render file: 'app/views/claims/list.json.jbuilder'
|
||||
else
|
||||
normal_status(-1,"新建声明关联评论操作失败")
|
||||
end
|
||||
|
||||
else
|
||||
normal_status(-1,"声明更新操作失败")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@claim = Claim.find_by_sql(["select id from claims where issue_id=? and user_id=?",params[:issue_id], current_user.id])
|
||||
if @claim.blank?
|
||||
normal_status(-1,"您未曾声明过该易修")
|
||||
else
|
||||
@claim = @claim[0]
|
||||
# 判断current user是否是claimer
|
||||
ActiveRecord::Base.transaction do
|
||||
if @claim.destroy
|
||||
|
||||
@claims = @issue.claims.claim_includes.order("created_at desc")
|
||||
@user_claimed = 0
|
||||
|
||||
journal_params = {
|
||||
journalized_id: params[:issue_id],
|
||||
journalized_type: "Issue",
|
||||
user_id: current_user.id ,
|
||||
notes: "取消声明",
|
||||
}
|
||||
|
||||
journal = Journal.new(journal_params)
|
||||
if journal.save
|
||||
render file: 'app/views/claims/list.json.jbuilder'
|
||||
else
|
||||
normal_status(-1,"新建声明关联评论操作失败")
|
||||
end
|
||||
|
||||
else
|
||||
normal_status(-1,"取消声明操作失败")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def parse_issue_params(params)
|
||||
{
|
||||
issue_id: params[:issue_id],
|
||||
user_id: current_user.id,
|
||||
note: params[:claim_note],
|
||||
}
|
||||
end
|
||||
|
||||
def set_issue
|
||||
@issue = Issue.find_by_id(params[:issue_id])
|
||||
unless @issue.present?
|
||||
normal_status(-1, "易修不存在")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,30 @@
|
|||
class CommitLogsController < ApplicationController
|
||||
|
||||
def create
|
||||
tip_exception "未认证" unless params[:token].to_s == "7917908927b6f1b792f2027a08a8b24a2de42c1692c2fd45da0dee5cf90a5af5"
|
||||
ref = params[:ref]
|
||||
user_name = params[:pusher][:login]
|
||||
user_mail = params[:pusher][:email]
|
||||
user = User.find_by(mail: user_mail)
|
||||
user = User.find_by(login: user_name) if user.blank?
|
||||
|
||||
repository_id = params[:repository][:id]
|
||||
repository_name = params[:repository][:name]
|
||||
repository_full_name = params[:repository][:full_name]
|
||||
owner_name = repository_full_name.split("/")[0]
|
||||
owner = User.find_by(login: owner_name)
|
||||
project = Project.where(identifier: repository_name).where(user_id: owner&.id)&.first
|
||||
project = Project.where(identifier: repository_name).where(gpid: repository_id)&.first if project.blank?
|
||||
project.update_column(:updated_on, Time.now) if project.present?
|
||||
params[:commits].each do |commit|
|
||||
commit_id = commit[:id]
|
||||
message = commit[:message]
|
||||
CommitLog.create(user: user, project: project, repository_id: repository_id,
|
||||
name: repository_name, full_name: repository_full_name,
|
||||
ref: ref, commit_id: commit_id, message: message)
|
||||
# 统计数据新增
|
||||
CacheAsyncSetJob.perform_later("project_common_service", {commits: 1}, project.id)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
|
@ -6,16 +6,26 @@ class CompareController < ApplicationController
|
|||
end
|
||||
|
||||
def show
|
||||
if params[:type] == "sha"
|
||||
load_compare_params
|
||||
@compare_result ||= gitea_compare(@base, @head)
|
||||
else
|
||||
load_compare_params
|
||||
compare
|
||||
@merge_status, @merge_message = get_merge_message
|
||||
end
|
||||
@page_size = page_size <= 0 ? 1 : page_size
|
||||
@page_limit = page_limit <=0 ? 15 : page_limit
|
||||
@page_offset = (@page_size -1) * @page_limit
|
||||
Rails.logger.info("+========#{@page_size}-#{@page_limit}-#{@page_offset}")
|
||||
end
|
||||
|
||||
private
|
||||
def get_merge_message
|
||||
if @base.blank? || @head.blank?
|
||||
return -2, "请选择分支"
|
||||
else
|
||||
return -2, "目标仓库未开启合并请求(PR)功能" unless @project.has_menu_permission("pulls")
|
||||
if @head.include?(":")
|
||||
fork_project = @project.forked_projects.joins(:owner).where(users: {login: @head.to_s.split("/")[0]}).take
|
||||
return -2, "请选择正确的仓库" unless fork_project.present?
|
||||
|
@ -42,12 +52,22 @@ class CompareController < ApplicationController
|
|||
end
|
||||
|
||||
def load_compare_params
|
||||
@base = Addressable::URI.unescape(params[:base])
|
||||
@head = params[:head].include?('json') ? params[:head]&.split('.json')[0] : params[:head]
|
||||
|
||||
# @base = Addressable::URI.unescape(params[:base])
|
||||
@base = params[:base].include?(":") ? Addressable::URI.unescape(params[:base].split(":")[0]) + ':' + Base64.decode64(params[:base].split(":")[1]) : Base64.decode64(params[:base])
|
||||
@head = params[:head].include?('.json') ? params[:head][0..-6] : params[:head]
|
||||
# @head = Addressable::URI.unescape(@head)
|
||||
@head = @head.include?(":") ? Addressable::URI.unescape(@head.split(":")[0]) + ':' + Base64.decode64(@head.split(":")[1]) : Base64.decode64(@head)
|
||||
end
|
||||
|
||||
def gitea_compare(base, head)
|
||||
Gitea::Repository::Commits::CompareService.call(@owner.login, @project.identifier, base, head, current_user.gitea_token)
|
||||
Gitea::Repository::Commits::CompareService.call(@owner.login, @project.identifier, Addressable::URI.escape(base), Addressable::URI.escape(head), current_user.gitea_token)
|
||||
end
|
||||
|
||||
def page_size
|
||||
params.fetch(:page, 1).to_i
|
||||
end
|
||||
|
||||
def page_limit
|
||||
params.fetch(:limit, 15).to_i
|
||||
end
|
||||
end
|
||||
|
|
|
@ -18,15 +18,15 @@ module Acceleratorable
|
|||
end
|
||||
|
||||
def accelerator_domain
|
||||
Gitea.gitea_config[:accelerator]["domain"]
|
||||
GiteaService.gitea_config[:accelerator]["domain"]
|
||||
end
|
||||
|
||||
def accelerator_username
|
||||
Gitea.gitea_config[:accelerator]["access_key_id"]
|
||||
GiteaService.gitea_config[:accelerator]["access_key_id"]
|
||||
end
|
||||
|
||||
def config_accelerator?
|
||||
Gitea.gitea_config[:accelerator].present?
|
||||
GiteaService.gitea_config[:accelerator].present?
|
||||
end
|
||||
|
||||
def is_foreign_url?(clone_addr)
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
module Api::ProjectHelper
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
def load_project
|
||||
namespace = params[:owner]
|
||||
repo = params[:repo]
|
||||
|
||||
@project, @owner = Project.find_with_namespace(namespace, repo)
|
||||
@repository = @project&.repository
|
||||
|
||||
if @project
|
||||
logger.info "###########:project founded"
|
||||
@project
|
||||
else
|
||||
logger.info "###########:project not found"
|
||||
@project = nil
|
||||
tip_exception(404, '您访问的页面不存在或已被删除')
|
||||
end
|
||||
@project
|
||||
end
|
||||
end
|
|
@ -0,0 +1,19 @@
|
|||
module Api::PullHelper
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
def load_pull_request
|
||||
pull_request_id = params[:pull_id] || params[:id]
|
||||
@pull_request = @project.pull_requests.where(gitea_number: pull_request_id).where.not(id: pull_request_id).take || PullRequest.find_by_id(pull_request_id)
|
||||
@issue = @pull_request&.issue
|
||||
if @pull_request
|
||||
logger.info "###########pull_request founded"
|
||||
@pull_request
|
||||
else
|
||||
logger.info "###########pull_request not found"
|
||||
@pull_request = nil
|
||||
render_not_found and return
|
||||
end
|
||||
|
||||
@pull_request
|
||||
end
|
||||
end
|
|
@ -0,0 +1,28 @@
|
|||
module Api::UserHelper
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
def load_observe_user
|
||||
username = params[:owner]
|
||||
|
||||
@observe_user = User.find_by(login: username)
|
||||
|
||||
if @observe_user
|
||||
logger.info "###########observe_user not founded"
|
||||
@observe_user
|
||||
else
|
||||
logger.info "###########observe_user not found"
|
||||
@observe_user = nil
|
||||
render_not_found and return
|
||||
end
|
||||
@observe_user
|
||||
end
|
||||
|
||||
# 是否具有查看用户或编辑用户的权限
|
||||
def check_auth_for_observe_user
|
||||
return render_forbidden unless current_user.admin? || @observe_user.id == current_user.id
|
||||
end
|
||||
|
||||
def strip(str)
|
||||
str.to_s.strip.presence
|
||||
end
|
||||
end
|
|
@ -160,9 +160,9 @@ module Ci::CloudAccountManageable
|
|||
state = SecureRandom.hex(8)
|
||||
# redirect_uri eg:
|
||||
# https://localhost:3000/login/oauth/authorize?client_id=94976481-ad0e-4ed4-9247-7eef106007a2&redirect_uri=http%3A%2F%2F121.69.81.11%3A80%2Flogin&response_type=code&state=9cab990b9cfb1805
|
||||
redirect_uri = CGI.escape("#{@cloud_account.drone_url}/login")
|
||||
clientId = client_id(oauth)
|
||||
grant_url = "#{Gitea.gitea_config[:domain]}/login/oauth/authorize?client_id=#{clientId}&redirect_uri=#{redirect_uri}&response_type=code&state=#{state}"
|
||||
# redirect_uri = CGI.escape("#{@cloud_account.drone_url}/login")
|
||||
# clientId = client_id(oauth)
|
||||
grant_url = "#{@cloud_account.drone_url}/login"
|
||||
logger.info "[gitea] grant_url: #{grant_url}"
|
||||
|
||||
conn = Faraday.new(url: grant_url) do |req|
|
||||
|
@ -188,6 +188,7 @@ module Ci::CloudAccountManageable
|
|||
response = conn.get
|
||||
logger.info "[drone] response headers: #{response.headers}"
|
||||
|
||||
# true
|
||||
response.headers['location'].include?('error') ? false : true
|
||||
end
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ module LoginHelper
|
|||
|
||||
def set_autologin_cookie(user)
|
||||
token = Token.get_or_create_permanent_login_token(user, "autologin")
|
||||
sync_user_token_to_trustie(user.login, token.value)
|
||||
# sync_user_token_to_trustie(user.login, token.value)
|
||||
|
||||
Rails.logger.info "###### def set_autologin_cookie and get_or_create_permanent_login_token result: #{token&.value}"
|
||||
cookie_options = {
|
||||
|
@ -108,10 +108,15 @@ module LoginHelper
|
|||
def sync_pwd_to_gitea!(user, hash={})
|
||||
return true if user.is_sync_pwd?
|
||||
|
||||
sync_params = { email: user.mail }
|
||||
sync_params = {
|
||||
login_name: user.name,
|
||||
source_id: 0,
|
||||
email: user.mail
|
||||
}
|
||||
interactor = Gitea::User::UpdateInteractor.call(user.login, sync_params.merge(hash))
|
||||
if interactor.success?
|
||||
Rails.logger.info "########_ login is #{user.login} sync_pwd_to_gitea success _########"
|
||||
user.update_column(:is_sync_pwd, true)
|
||||
true
|
||||
else
|
||||
Rails.logger.info "########_ login is #{user.login} sync_pwd_to_gitea fail!: #{interactor.error}"
|
||||
|
|
|
@ -1,17 +1,25 @@
|
|||
module RegisterHelper
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
def autologin_register(username, email, password, platform= 'forge')
|
||||
def autologin_register(username, email, password, platform = 'forge', phone = nil, nickname =nil, need_edit_info = false)
|
||||
result = {message: nil, user: nil}
|
||||
email = email.blank? ? "#{username}@example.org" : email
|
||||
|
||||
user = User.new(admin: false, login: username, mail: email, type: "User")
|
||||
user.password = password
|
||||
user.platform = platform
|
||||
user.phone = phone if phone.present?
|
||||
user.nickname = nickname if nickname.present?
|
||||
if need_edit_info
|
||||
user.need_edit_info
|
||||
else
|
||||
user.activate
|
||||
end
|
||||
|
||||
return unless user.valid?
|
||||
|
||||
interactor = Gitea::RegisterInteractor.call({username: username, email: email, password: password})
|
||||
result ={}
|
||||
if interactor.success?
|
||||
gitea_user = interactor.result
|
||||
result = Gitea::User::GenerateTokenService.call(username, password)
|
||||
|
@ -22,9 +30,64 @@ module RegisterHelper
|
|||
result[:user] = {id: user.id, token: user.gitea_token}
|
||||
end
|
||||
else
|
||||
result[:message] = interactor.error
|
||||
result[:message] = interactor.result[:message]
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
def autosync_register_trustie(username, password, email, lastname="")
|
||||
config = Rails.application.config_for(:configuration).symbolize_keys!
|
||||
|
||||
api_host = config[:sync_url]
|
||||
|
||||
return if api_host.blank?
|
||||
|
||||
url = "#{api_host}/api/v1/users/common"
|
||||
sync_json = {
|
||||
"mail": email,
|
||||
"password": password,
|
||||
"login": username,
|
||||
"lastname": lastname
|
||||
}.compact
|
||||
uri = URI.parse(url)
|
||||
|
||||
if api_host
|
||||
http = Net::HTTP.new(uri.hostname, uri.port)
|
||||
|
||||
if api_host.include?("https://")
|
||||
http.use_ssl = true
|
||||
end
|
||||
|
||||
http.send_request('POST', uri.path, sync_json.to_json, {'Content-Type' => 'application/json'})
|
||||
end
|
||||
end
|
||||
|
||||
def auto_update(user, params={})
|
||||
return if params.blank?
|
||||
result = {message: nil, user: nil}
|
||||
before_login = user.login
|
||||
user.login = params[:username]
|
||||
user.password = params[:password]
|
||||
user.mail = params[:email]
|
||||
|
||||
if user.save!
|
||||
sync_params = {
|
||||
password: params[:password].to_s,
|
||||
email: params[:email],
|
||||
login_name: params[:username],
|
||||
new_name: params[:username],
|
||||
source_id: 0
|
||||
}
|
||||
|
||||
interactor = Gitea::User::UpdateInteractor.call(before_login, sync_params)
|
||||
if interactor.success?
|
||||
result[:user] = user
|
||||
else
|
||||
result[:message] = '用户同步Gitea失败!'
|
||||
end
|
||||
else
|
||||
result[:message] = user.errors.full_messages.join(",")
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,7 +3,7 @@ module RenderHelper
|
|||
render json: { status: 0, message: 'success' }.merge(data)
|
||||
end
|
||||
|
||||
def render_error(status = -1, message = '')
|
||||
def render_error(message = '', status = -1)
|
||||
render json: { status: status, message: message }
|
||||
end
|
||||
|
||||
|
@ -28,4 +28,8 @@ module RenderHelper
|
|||
def render_result(status=1, message='success')
|
||||
render json: { status: status, message: message }
|
||||
end
|
||||
|
||||
def render_parameter_missing
|
||||
render json: { status: -1, message: '参数缺失' }
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,7 +5,17 @@ module Repository::LanguagesPercentagable
|
|||
result = Gitea::Repository::Languages::ListService.call(@owner.login,
|
||||
@repository.identifier, current_user&.gitea_token)
|
||||
|
||||
result[:status] === :success ? hash_transform_precentagable(result[:body]) : nil
|
||||
@transform_language = result[:status] === :success ? hash_transform_precentagable(result[:body]) : nil
|
||||
update_project_language(@transform_language) unless @transform_language.nil?
|
||||
@transform_language
|
||||
end
|
||||
|
||||
def update_project_language(language)
|
||||
return if @project.project_language.present?
|
||||
db_language = ProjectLanguage.find_or_create_by!(name: language.keys.first.downcase.upcase_first)
|
||||
@project.update_attribute(:project_language_id, db_language.id)
|
||||
rescue
|
||||
return
|
||||
end
|
||||
|
||||
# hash eq:{"JavaScript": 301681522,"Ruby": 1444004,"Roff": 578781}
|
||||
|
|
|
@ -13,7 +13,7 @@ class ForksController < ApplicationController
|
|||
if current_user&.id == @project.user_id
|
||||
render_result(-1, "自己不能fork自己的项目")
|
||||
elsif Project.exists?(user_id: current_user.id, identifier: @project.identifier)
|
||||
render_result(-1, "fork失败,你已拥有了这个项目")
|
||||
render_result(0, "fork失败,你已拥有了这个项目")
|
||||
end
|
||||
# return if current_user != @project.owner
|
||||
# render_result(-1, "自己不能fork自己的项目")
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
class InstallationsController < ApplicationController
|
||||
include RegisterHelper
|
||||
before_action :require_login
|
||||
|
||||
def index
|
||||
@install_bots = BotInstall.where(:installer_id => current_user.id)
|
||||
end
|
||||
|
||||
def update_secret
|
||||
ActiveRecord::Base.transaction do
|
||||
bot = Bot.find params[:id]
|
||||
application = Doorkeeper::Application.find_by(uid: bot.client_id, secret: bot.client_secret)
|
||||
bot.client_secret = Doorkeeper::OAuth::Helpers::UniqueToken.generate
|
||||
bot.save!
|
||||
application.secret = bot.client_secret
|
||||
application.save!
|
||||
render_ok
|
||||
end
|
||||
end
|
||||
|
||||
def update_private_key
|
||||
bot = Bot.find params[:id]
|
||||
bot.private_key = OpenSSL::PKey::RSA::generate(2048).to_s
|
||||
bot.save!
|
||||
render_ok
|
||||
end
|
||||
|
||||
def auth_active
|
||||
begin
|
||||
@bot = Bot.find params[:id]
|
||||
tip_exception("该Bot已激活") if Doorkeeper::Application.find_by(uid: @bot.client_id, secret: @bot.client_secret).present?
|
||||
@bot.client_id = Doorkeeper::OAuth::Helpers::UniqueToken.generate if params[:client_id].blank?
|
||||
@bot.client_secret = Doorkeeper::OAuth::Helpers::UniqueToken.generate if params[:client_secret].blank?
|
||||
@bot.private_key = OpenSSL::PKey::RSA::generate(2048).to_s
|
||||
@bot.owner_id = current_user.id
|
||||
ActiveRecord::Base.transaction do
|
||||
# 注册bot对应oauth应用
|
||||
Doorkeeper::Application.create!(name: @bot.name, uid: @bot.client_id, secret: @bot.client_secret, redirect_uri: "https://gitlink.org.cn")
|
||||
# 注册bot对应用户
|
||||
result = autologin_register(User.generate_user_login('b'), nil, "#{SecureRandom.hex(6)}", 'bot', nil, nickname: @bot.name)
|
||||
tip_exception(-1, result[:message]) if result[:message].present?
|
||||
@bot.uid = result[:user][:id]
|
||||
@bot.save
|
||||
render_ok
|
||||
end
|
||||
rescue Exception => e
|
||||
tip_exception(-1, e.message)
|
||||
end
|
||||
end
|
||||
|
||||
def access_tokens
|
||||
@install_bot = BotInstall.find params[:id]
|
||||
@bot = @install_bot.bot
|
||||
@application = Doorkeeper::Application.find_by(uid: @bot.client_id, secret: @bot.client_secret)
|
||||
tip_exception("该Bot未激活") if @application.blank?
|
||||
# 给bot生成token,因为bot是机器人操作
|
||||
@access_token = Doorkeeper::AccessToken.create!({ :application_id => @application.id,
|
||||
:resource_owner_id => @bot.uid,
|
||||
:scopes => "public write",
|
||||
:expires_in => "604800",
|
||||
:use_refresh_token => true
|
||||
})
|
||||
render_ok(token: @access_token.token)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -2,12 +2,12 @@ class IssueTagsController < ApplicationController
|
|||
before_action :require_login, except: [:index]
|
||||
before_action :load_repository
|
||||
before_action :set_user
|
||||
before_action :check_issue_permission, except: :index
|
||||
before_action :check_issue_tags_permission
|
||||
before_action :set_issue_tag, only: [:edit, :update, :destroy]
|
||||
|
||||
|
||||
def index
|
||||
issue_tags = @project.issue_tags.reorder("#{order_name} #{order_type}")
|
||||
issue_tags = @project.issue_tags.includes(:issues).reorder("issue_tags.#{order_name} #{order_type}")
|
||||
@user_admin_or_member = current_user.present? && (current_user.admin || @project.member?(current_user))
|
||||
@page = params[:page] || 1
|
||||
@limit = params[:limit] || 15
|
||||
|
@ -17,7 +17,7 @@ class IssueTagsController < ApplicationController
|
|||
|
||||
|
||||
def create
|
||||
title = params[:name].to_s.strip.first(10)
|
||||
title = params[:name].to_s.strip.first(15)
|
||||
desc = params[:description].to_s.first(30)
|
||||
color = params[:color] || "#ccc"
|
||||
|
||||
|
@ -29,7 +29,7 @@ class IssueTagsController < ApplicationController
|
|||
|
||||
if title.present?
|
||||
if IssueTag.exists?(name: title, project_id: @project.id)
|
||||
normal_status(-1, "标签已存在")
|
||||
normal_status(-1, "项目标记已存在")
|
||||
else
|
||||
ActiveRecord::Base.transaction do
|
||||
begin
|
||||
|
@ -37,12 +37,12 @@ class IssueTagsController < ApplicationController
|
|||
if issue_tag.save
|
||||
# gitea_tag = Gitea::Labels::CreateService.new(current_user, @repository.try(:identifier), tag_params).call
|
||||
# if gitea_tag && issue_tag.update_attributes(gid: gitea_tag["id"], gitea_url: gitea_tag["url"])
|
||||
# normal_status(0, "标签创建成功")
|
||||
normal_status(0, "项目标记创建成功!")
|
||||
# else
|
||||
# normal_status(-1, "标签创建失败")
|
||||
# normal_status(-1, "项目标记创建失败")
|
||||
# end
|
||||
else
|
||||
normal_status(-1, "标签创建失败")
|
||||
normal_status(-1, "项目标记创建失败")
|
||||
end
|
||||
rescue => e
|
||||
puts "create version release error: #{e.message}"
|
||||
|
@ -51,7 +51,7 @@ class IssueTagsController < ApplicationController
|
|||
end
|
||||
end
|
||||
else
|
||||
normal_status(-1, "标签名称不能为空")
|
||||
normal_status(-1, "项目标记名称不能为空")
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -60,8 +60,8 @@ class IssueTagsController < ApplicationController
|
|||
end
|
||||
|
||||
def update
|
||||
title = params[:name]
|
||||
desc = params[:description]
|
||||
title = params[:name].to_s.strip.first(15)
|
||||
desc = params[:description].to_s.first(30)
|
||||
color = params[:color] || "#ccc"
|
||||
|
||||
tag_params = {
|
||||
|
@ -71,19 +71,19 @@ class IssueTagsController < ApplicationController
|
|||
}
|
||||
if title.present?
|
||||
if IssueTag.exists?(name: title, project_id: @project.id) && (@issue_tag.name != title)
|
||||
normal_status(-1, "标签已存在")
|
||||
normal_status(-1, "项目标记已存在")
|
||||
else
|
||||
ActiveRecord::Base.transaction do
|
||||
begin
|
||||
if @issue_tag.update_attributes(tag_params)
|
||||
# gitea_tag = Gitea::Labels::UpdateService.new(current_user, @repository.try(:identifier),@issue_tag.try(:gid), tag_params).call
|
||||
# if gitea_tag
|
||||
# normal_status(0, "标签更新成功")
|
||||
# normal_status(0, "项目标记更新成功")
|
||||
# else
|
||||
# normal_status(-1, "标签更新失败")
|
||||
# normal_status(-1, "项目标记更新失败")
|
||||
# end
|
||||
else
|
||||
normal_status(-1, "标签更新失败")
|
||||
normal_status(-1, "项目标记更新失败")
|
||||
end
|
||||
rescue => e
|
||||
puts "create version release error: #{e.message}"
|
||||
|
@ -92,7 +92,7 @@ class IssueTagsController < ApplicationController
|
|||
end
|
||||
end
|
||||
else
|
||||
normal_status(-1, "标签名称不能为空")
|
||||
normal_status(-1, "项目标记名称不能为空")
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -102,12 +102,12 @@ class IssueTagsController < ApplicationController
|
|||
if @issue_tag.destroy
|
||||
# issue_tag = Gitea::Labels::DeleteService.new(@user, @repository.try(:identifier), @issue_tag.try(:gid)).call
|
||||
# if issue_tag
|
||||
# normal_status(0, "标签删除成功")
|
||||
# normal_status(0, "项目标记删除成功")
|
||||
# else
|
||||
# normal_status(-1, "标签删除失败")
|
||||
# normal_status(-1, "项目标记删除失败")
|
||||
# end
|
||||
else
|
||||
normal_status(-1, "标签删除失败")
|
||||
normal_status(-1, "项目标记删除失败")
|
||||
end
|
||||
rescue => e
|
||||
puts "create version release error: #{e.message}"
|
||||
|
@ -122,16 +122,16 @@ class IssueTagsController < ApplicationController
|
|||
@user = @project.owner
|
||||
end
|
||||
|
||||
def check_issue_permission
|
||||
unless @project.member?(current_user) || current_user.admin?
|
||||
normal_status(-1, "您没有权限")
|
||||
def check_issue_tags_permission
|
||||
unless @project.manager?(current_user) || current_user.admin?
|
||||
return render_forbidden('你不是管理员,没有权限操作')
|
||||
end
|
||||
end
|
||||
|
||||
def set_issue_tag
|
||||
@issue_tag = IssueTag.find_by_id(params[:id])
|
||||
unless @issue_tag.present?
|
||||
normal_status(-1, "标签不存在")
|
||||
normal_status(-1, "项目标记不存在")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ class IssuesController < ApplicationController
|
|||
include TagChosenHelper
|
||||
|
||||
def index
|
||||
@user_operate_issue = current_user.present? && current_user.logged? && (current_user.admin || @project.member?(current_user))
|
||||
@user_admin_or_member = current_user.present? && current_user.logged? && (current_user.admin || @project.member?(current_user) || @project.is_public?)
|
||||
issues = @project.issues.issue_issue.issue_index_includes
|
||||
issues = issues.where(is_private: false) unless @user_admin_or_member
|
||||
|
@ -23,13 +24,13 @@ class IssuesController < ApplicationController
|
|||
@filter_issues = @all_issues
|
||||
@filter_issues = @filter_issues.where.not(status_id: IssueStatus::CLOSED) if params[:status_type].to_i == IssueStatus::ADD
|
||||
@filter_issues = @filter_issues.where(status_id: IssueStatus::CLOSED) if params[:status_type].to_i == IssueStatus::SOLVING
|
||||
@filter_issues = @filter_issues.where("subject LIKE ? OR description LIKE ? ", "%#{params[:search]}%", "%#{params[:search]}%") if params[:search].present?
|
||||
@filter_issues = @filter_issues.where("issues.subject LIKE ? OR issues.description LIKE ? ", "%#{params[:search]}%", "%#{params[:search]}%") if params[:search].present?
|
||||
@open_issues = @all_issues.where.not(status_id: IssueStatus::CLOSED)
|
||||
@close_issues = @all_issues.where(status_id: IssueStatus::CLOSED)
|
||||
@assign_to_me = @filter_issues.where(assigned_to_id: current_user&.id)
|
||||
@my_published = @filter_issues.where(author_id: current_user&.id)
|
||||
scopes = Issues::ListQueryService.call(issues,params.delete_if{|k,v| v.blank?}, "Issue")
|
||||
@issues_size = scopes.size
|
||||
@assign_to_me = scopes.where(assigned_to_id: current_user&.id)
|
||||
@my_published = scopes.where(author_id: current_user&.id)
|
||||
@issues = paginate(scopes)
|
||||
|
||||
respond_to do |format|
|
||||
|
@ -108,9 +109,11 @@ class IssuesController < ApplicationController
|
|||
|
||||
def create
|
||||
issue_params = issue_send_params(params)
|
||||
Issues::CreateForm.new({subject:issue_params[:subject]}).validate!
|
||||
Issues::CreateForm.new({subject: issue_params[:subject], description: issue_params[:description].blank? ? issue_params[:description] : issue_params[:description].b}).validate!
|
||||
@issue = Issue.new(issue_params)
|
||||
@issue.project_issues_index = @project.get_last_project_issues_index + 1
|
||||
if @issue.save!
|
||||
@project.del_project_issue_cache_delete_count
|
||||
SendTemplateMessageJob.perform_later('IssueAssigned', current_user.id, @issue&.id) if Site.has_notice_menu?
|
||||
SendTemplateMessageJob.perform_later('ProjectIssue', current_user.id, @issue&.id) if Site.has_notice_menu?
|
||||
if params[:attachment_ids].present?
|
||||
|
@ -125,9 +128,15 @@ class IssuesController < ApplicationController
|
|||
end
|
||||
end
|
||||
if params[:issue_tag_ids].present?
|
||||
if params[:issue_tag_ids].is_a?(Array) && params[:issue_tag_ids].size > 1
|
||||
return normal_status(-1, "最多只能创建一个标记。")
|
||||
elsif params[:issue_tag_ids].is_a?(Array) && params[:issue_tag_ids].size == 1
|
||||
params[:issue_tag_ids].each do |tag|
|
||||
IssueTagsRelate.create!(issue_id: @issue.id, issue_tag_id: tag)
|
||||
end
|
||||
else
|
||||
return normal_status(-1, "请输入正确的标记。")
|
||||
end
|
||||
end
|
||||
if params[:assigned_to_id].present?
|
||||
Tiding.create!(user_id: params[:assigned_to_id], trigger_user_id: current_user.id,
|
||||
|
@ -142,11 +151,15 @@ class IssuesController < ApplicationController
|
|||
end
|
||||
|
||||
@issue.project_trends.create(user_id: current_user.id, project_id: @project.id, action_type: "create")
|
||||
@issue.project_trends.create(user_id: current_user.id, project_id: @project.id, action_type: ProjectTrend::CLOSE) if params[:status_id].to_i == 5
|
||||
|
||||
|
||||
Rails.logger.info "[ATME] maybe to at such users: #{@atme_receivers.pluck(:login)}"
|
||||
AtmeService.call(current_user, @atme_receivers, @issue) if @atme_receivers.size > 0
|
||||
# 新增时向grimoirelab推送事件
|
||||
IssueWebhookJob.set(wait: 5.seconds).perform_later(@issue.id)
|
||||
|
||||
render json: {status: 0, message: "创建成", id: @issue.id}
|
||||
render json: {status: 0, message: "创建成功", id: @issue.id}
|
||||
else
|
||||
normal_status(-1, "创建失败")
|
||||
end
|
||||
|
@ -165,10 +178,17 @@ class IssuesController < ApplicationController
|
|||
last_token = @issue.token
|
||||
last_status_id = @issue.status_id
|
||||
@issue&.issue_tags_relates&.destroy_all if params[:issue_tag_ids].blank?
|
||||
if params[:issue_tag_ids].present? && !@issue&.issue_tags_relates.where(issue_tag_id: params[:issue_tag_ids]).exists?
|
||||
if params[:issue_tag_ids].present?
|
||||
if params[:issue_tag_ids].is_a?(Array) && params[:issue_tag_ids].size > 1
|
||||
return normal_status(-1, "最多只能创建一个标记。")
|
||||
elsif params[:issue_tag_ids].is_a?(Array) && params[:issue_tag_ids].size == 1
|
||||
@issue&.issue_tags_relates&.destroy_all
|
||||
params[:issue_tag_ids].each do |tag|
|
||||
IssueTagsRelate.create(issue_id: @issue.id, issue_tag_id: tag)
|
||||
next if tag == [""]
|
||||
IssueTagsRelate.create!(issue_id: @issue.id, issue_tag_id: tag)
|
||||
end
|
||||
else
|
||||
return normal_status(-1, "请输入正确的标记。")
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -207,7 +227,7 @@ class IssuesController < ApplicationController
|
|||
normal_status(-1, "不允许修改为关闭状态")
|
||||
else
|
||||
issue_params = issue_send_params(params).except(:issue_classify, :author_id, :project_id)
|
||||
Issues::UpdateForm.new({subject:issue_params[:subject]}).validate!
|
||||
Issues::UpdateForm.new({subject: issue_params[:subject], description: issue_params[:description].blank? ? issue_params[:description] : issue_params[:description].b}).validate!
|
||||
if @issue.update_attributes(issue_params)
|
||||
if @issue&.pull_request.present?
|
||||
SendTemplateMessageJob.perform_later('PullRequestChanged', current_user.id, @issue&.pull_request&.id, @issue.previous_changes.slice(:assigned_to_id, :priority_id, :fixed_version_id, :issue_tags_value)) if Site.has_notice_menu?
|
||||
|
@ -231,7 +251,7 @@ class IssuesController < ApplicationController
|
|||
end
|
||||
if params[:status_id].to_i == 5 #任务由非关闭状态到关闭状态时
|
||||
@issue.issue_times.update_all(end_time: Time.now)
|
||||
@issue.update_closed_issues_count_in_project!
|
||||
# @issue.update_closed_issues_count_in_project!
|
||||
if @issue.issue_type.to_s == "2" && last_status_id != 5
|
||||
if @issue.assigned_to_id.present? && last_status_id == 3 #只有当用户完成100%时,才给token
|
||||
post_to_chain("add", @issue.token, @issue.get_assign_user.try(:login))
|
||||
|
@ -286,6 +306,7 @@ class IssuesController < ApplicationController
|
|||
login = @issue.user.try(:login)
|
||||
SendTemplateMessageJob.perform_later('IssueDeleted', current_user.id, @issue&.subject, @issue.assigned_to_id, @issue.author_id) if Site.has_notice_menu?
|
||||
if @issue.destroy
|
||||
@project.incre_project_issue_cache_delete_count
|
||||
if issue_type == "2" && status_id != 5
|
||||
post_to_chain("add", token, login)
|
||||
end
|
||||
|
@ -473,7 +494,8 @@ class IssuesController < ApplicationController
|
|||
end
|
||||
|
||||
def operate_issue_permission
|
||||
return render_forbidden("您没有权限进行此操作.") unless current_user.present? && current_user.logged? && (current_user.admin? || @project.member?(current_user) || @project.is_public?)
|
||||
@issue = Issue.find_by_id(params[:id]) unless @issue.present?
|
||||
return render_forbidden("您没有权限进行此操作.") unless current_user.present? && current_user.logged? && (current_user.admin? || @project.member?(current_user) || (@project.is_public && @issue.nil?) || (@project.is_public && @issue.present? && @issue.author_id == current_user.id))
|
||||
end
|
||||
|
||||
def export_issues(issues)
|
||||
|
|
|
@ -23,6 +23,7 @@ class JournalsController < ApplicationController
|
|||
normal_status(-1, "评论内容不能为空")
|
||||
else
|
||||
ActiveRecord::Base.transaction do
|
||||
Journals::CreateForm.new({notes: notes.to_s.strip.blank? ? notes.to_s.strip : notes.to_s.strip.b}).validate!
|
||||
journal_params = {
|
||||
journalized_id: @issue.id ,
|
||||
journalized_type: "Issue",
|
||||
|
@ -45,6 +46,7 @@ class JournalsController < ApplicationController
|
|||
end
|
||||
Rails.logger.info "[ATME] maybe to at such users: #{@atme_receivers.pluck(:login)}"
|
||||
AtmeService.call(current_user, @atme_receivers, journal) if @atme_receivers.size > 0
|
||||
TouchWebhookJob.set(wait: 5.seconds).perform_later('PullRequestComment', @issue&.id, current_user.id, journal.id, 'created', {})
|
||||
# @issue.project_trends.create(user_id: current_user.id, project_id: @project.id, action_type: "journal")
|
||||
render :json => { status: 0, message: "评论成功", id: journal.id}
|
||||
# normal_status(0, "评论成功")
|
||||
|
@ -53,10 +55,14 @@ class JournalsController < ApplicationController
|
|||
end
|
||||
end
|
||||
end
|
||||
rescue Exception => exception
|
||||
puts exception.message
|
||||
normal_status(-1, exception.message)
|
||||
end
|
||||
|
||||
def destroy
|
||||
if @journal.destroy #如果有子评论,子评论删除吗?
|
||||
TouchWebhookJob.set(wait: 5.seconds).perform_later('PullRequestComment', @issue&.id, current_user.id, @journal.id, 'deleted', JSON.parse(@journal.to_builder.target!))
|
||||
Journal.children_journals(@journal.id).destroy_all
|
||||
normal_status(0, "评论删除成功")
|
||||
else
|
||||
|
@ -71,6 +77,7 @@ class JournalsController < ApplicationController
|
|||
def update
|
||||
content = params[:content]
|
||||
if content.present?
|
||||
Journals::UpdateForm.new({notes: notes.to_s.strip.blank? ? notes.to_s.strip : notes.to_s.strip.b}).validate!
|
||||
if @journal.update_attribute(:notes, content)
|
||||
normal_status(0, "更新成功")
|
||||
else
|
||||
|
@ -79,7 +86,9 @@ class JournalsController < ApplicationController
|
|||
else
|
||||
normal_status(-1, "评论的内容不能为空")
|
||||
end
|
||||
|
||||
rescue Exception => exception
|
||||
puts exception.message
|
||||
normal_status(-1, exception.message)
|
||||
end
|
||||
|
||||
def get_children_journals
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
class MarkFilesController < ApplicationController
|
||||
before_action :require_login
|
||||
before_action :load_project
|
||||
before_action :load_pull_request
|
||||
|
||||
def index
|
||||
@files_result = Gitea::PullRequest::FilesService.call(@owner.login, @project.identifier, @pull_request.gitea_number, current_user&.gitea_token, { "only-file-name": true })
|
||||
@mark_files = MarkFile.where(pull_request_id: @pull_request.id)
|
||||
end
|
||||
|
||||
def create
|
||||
# unless @pull_request.mark_files.present?
|
||||
# MarkFile.bulk_insert(*%i[pull_request_id, file_path_sha file_path created_at updated_at]) do |worker|
|
||||
# @files_result['Files'].each do |file|
|
||||
# worker.add(pull_request_id: @pull_request.id, file_path_sha: SecureRandom.uuid.gsub("-", ""), file_path: file['Name'])
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
end
|
||||
|
||||
def mark_file_as_unread
|
||||
tip_exception "参数错误" if params[:file_path_sha].blank?
|
||||
file_path = Base64.strict_decode64(params[:file_path_sha].to_s)
|
||||
mark_file = @pull_request.mark_files.find_or_initialize_by(file_path_sha: params[:file_path_sha])
|
||||
mark_file.file_path = file_path
|
||||
mark_file.user_id = current_user.id
|
||||
mark_file.mark_as_read = false
|
||||
mark_file.save
|
||||
render_ok
|
||||
rescue Exception => e
|
||||
tip_exception "参数解析错误"
|
||||
end
|
||||
|
||||
def mark_file_as_read
|
||||
tip_exception "参数错误" if params[:file_path_sha].blank?
|
||||
file_path = Base64.strict_decode64(params[:file_path_sha].to_s)
|
||||
mark_file = @pull_request.mark_files.find_or_initialize_by(file_path_sha: params[:file_path_sha])
|
||||
mark_file.file_path = file_path
|
||||
mark_file.user_id = current_user.id
|
||||
mark_file.mark_as_read = true
|
||||
mark_file.save
|
||||
render_ok
|
||||
rescue Exception => e
|
||||
tip_exception "参数解析错误"
|
||||
end
|
||||
|
||||
private
|
||||
def review_params
|
||||
params.require(:review).permit(:content, :commit_id, :status)
|
||||
end
|
||||
|
||||
def load_pull_request
|
||||
@pull_request = @project.pull_requests.where(gitea_number: params[:id]).where.not(id: params[:id]).take || PullRequest.find_by_id(params[:id])
|
||||
end
|
||||
|
||||
end
|
|
@ -3,7 +3,7 @@ class MembersController < ApplicationController
|
|||
before_action :load_project
|
||||
before_action :find_user_with_id, only: %i[create remove change_role]
|
||||
before_action :check_user_profile_completed, only: [:create]
|
||||
before_action :operate!, except: %i[index]
|
||||
before_action :operate!
|
||||
before_action :check_member_exists!, only: %i[create]
|
||||
before_action :check_member_not_exists!, only: %i[remove change_role]
|
||||
|
||||
|
@ -26,6 +26,9 @@ class MembersController < ApplicationController
|
|||
|
||||
@total_count = scope.size
|
||||
@members = paginate(scope)
|
||||
if @project.owner.is_a?(Organization) && (params[:page].to_i == 1 || params[:page].blank?) && !@project.members.exists?(user_id: current_user.id)
|
||||
@current_user_header_team = Team.joins(:team_users, :team_projects).where(team_projects: {project_id: @project.id}, team_users: {user_id: current_user.id}).order(authorize: :desc).take
|
||||
end
|
||||
end
|
||||
|
||||
def remove
|
||||
|
@ -61,11 +64,14 @@ class MembersController < ApplicationController
|
|||
end
|
||||
|
||||
def check_member_exists!
|
||||
return render_error("user_id为#{params[:user_id]}的用户已经是项目成员") if member_exists?
|
||||
@current_user_header_team = Team.joins(:team_users, :team_projects).where(team_projects: {project_id: @project.id}, team_users: {user_id: current_user.id}).order(authorize: :desc).take
|
||||
return render_error("#{@user&.nickname}已经是项目成员") if member_exists? || (params[:user_id].to_i == current_user.id && @current_user_header_team.present?)
|
||||
end
|
||||
|
||||
def check_member_not_exists!
|
||||
return render_error("user_id为#{params[:user_id]}的用户还不是项目成员") unless member_exists?
|
||||
@current_user_header_team = Team.joins(:team_users, :team_projects).where(team_projects: {project_id: @project.id}, team_users: {user_id: current_user.id}).order(authorize: :desc).take
|
||||
return render_error("用户为组织成员,请到组织下操作!") if (params[:user_id].to_i == current_user.id && @current_user_header_team.present?) && !member_exists?
|
||||
return render_error("#{@user&.nickname}还不是项目成员") unless member_exists?
|
||||
end
|
||||
|
||||
def check_user_profile_completed
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
class NoticesController < ApplicationController
|
||||
|
||||
def create
|
||||
return tip_exception("参数有误") if params["source"].blank?
|
||||
user_id = params[:user_id]
|
||||
|
||||
if params["source"] == "CompetitionBegin"
|
||||
competition_id = params[:competition_id]
|
||||
SendTemplateMessageJob.perform_later('CompetitionBegin', user_id, competition_id)
|
||||
elsif params["source"] == "CompetitionResult"
|
||||
competition_id = params[:competition_id]
|
||||
SendTemplateMessageJob.perform_later('CompetitionResult', user_id, competition_id)
|
||||
elsif params["source"] == "CompetitionReview"
|
||||
competition_id = params[:competition_id]
|
||||
SendTemplateMessageJob.perform_later('CompetitionReview', user_id, competition_id)
|
||||
elsif params["source"] == "CustomTip"
|
||||
users_id = params[:users_id]
|
||||
props = params[:props].to_unsafe_hash
|
||||
return tip_exception("参数有误") unless props.is_a?(Hash) && users_id.is_a?(Array)
|
||||
template_id = params[:template_id]
|
||||
SendTemplateMessageJob.perform_later('CustomTip', users_id, template_id, props)
|
||||
else
|
||||
tip_exception("#{params["source"]}未配置")
|
||||
end
|
||||
render_ok
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
def params_props
|
||||
params.require(:notice).permit(:props)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,17 @@
|
|||
class NpsController < ApplicationController
|
||||
|
||||
before_action :require_login
|
||||
|
||||
# close,关闭
|
||||
# createIssue,创建issue
|
||||
# createPullRequest,创建PR
|
||||
# auditPullRequest,审核PR
|
||||
# indexProject,项目主页
|
||||
# createProject,创建项目
|
||||
# createOrganization,创建组织
|
||||
def create
|
||||
tip_exception "缺少参数" if params[:action_id].blank? || params[:action_type].blank?
|
||||
UserNp.create(:action_id => params[:action_id].to_i, :action_type => params[:action_type], :user_id => User.current.id, :score => params[:score].to_f, memo: params[:memo])
|
||||
render_ok
|
||||
end
|
||||
end
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue