forked from Trustie/forgeplus
Compare commits
1226 Commits
master
...
dev_jk_ser
Author | SHA1 | Date |
---|---|---|
|
edf0655fb2 | |
|
4121a90a16 | |
|
023c23991b | |
|
9d54310f1f | |
|
9fc47bc675 | |
|
6132641ef5 | |
|
50adbd74df | |
|
449762b3ea | |
|
f307158909 | |
|
1b1bb860f7 | |
|
e375851a37 | |
|
de4376f91f | |
|
c1ee08ffa4 | |
|
c795a2a36d | |
|
5372183776 | |
|
c42e8c4b80 | |
|
448a6c17da | |
|
e60445057a | |
|
b32cbccb80 | |
|
25d1c5f13d | |
|
238e5fc65c | |
|
7eca07fc06 | |
|
fdd62a602e | |
|
b86eba4725 | |
|
49c96df25d | |
|
0266968d2c | |
|
f6ef2f5648 | |
|
b468740b15 | |
|
fce38e3fb7 | |
|
019e0a540b | |
|
517678f5ae | |
|
7632fa3988 | |
|
bd45e7167e | |
|
66927793fa | |
|
2b613ecc7b | |
|
ccfb367a88 | |
|
75faa6bf76 | |
|
e4e0b0ce57 | |
|
7fdf1af411 | |
|
2a956d02ed | |
|
7c249ea9fa | |
|
73d441397c | |
|
dc1d6ce219 | |
|
7e019e95ab | |
|
ec0846f223 | |
|
4ca3b66228 | |
|
1010b2a863 | |
|
1d832d1ba7 | |
|
3b3fad7e3c | |
|
16d8bf8f81 | |
|
5604ee036d | |
|
31797af44c | |
|
d369741900 | |
|
f69d423672 | |
|
28d45a48a1 | |
|
ccec8e9819 | |
|
bf5c226117 | |
|
0f8d2e6a5d | |
|
6cdaafe4e0 | |
|
0e49f81eaf | |
|
204554b34c | |
|
bc2992cc3d | |
|
a631d423c6 | |
|
edd1d27b0a | |
|
3edac3656a | |
|
d0b638cbc0 | |
|
1c16b74f1b | |
|
983f488177 | |
|
dfa0f1161d | |
|
bc6f5cec4d | |
|
ee27c90205 | |
|
aab1e42240 | |
|
0ec06bf54d | |
|
5d9f9cdfb0 | |
|
534ee80523 | |
|
daf7514afe | |
|
4b1f1c697e | |
|
77c7acd582 | |
|
025a6a53e9 | |
|
6b846b10bb | |
|
763d7b499e | |
|
9b39446dfb | |
|
c6e77ac7ee | |
|
f5cdb6f02d | |
|
f7ca03db81 | |
|
8da8b021f6 | |
|
70ba78a9b5 | |
|
6191ddd233 | |
|
35cf298f5d | |
|
ee5d959404 | |
|
7f47cd8d46 | |
|
06c0ac65bf | |
|
8f8dab10c3 | |
|
a6923bf7ed | |
![]() |
667dca0553 | |
![]() |
f23f02cb80 | |
|
38a8191b74 | |
|
e183f48c02 | |
![]() |
a1731f91a9 | |
|
ea7cf1cd1f | |
|
255b615327 | |
|
64c6f69f56 | |
|
49abadfa3f | |
|
4cde7c374e | |
|
b56930b9ab | |
|
f98886b3a0 | |
|
30572aa41c | |
|
ef83697cb8 | |
|
570f664c27 | |
|
e24921bba3 | |
|
e4d62c5335 | |
|
6d9cf8aad2 | |
|
e3179dfd6e | |
|
7817487ab7 | |
|
83b46fcb50 | |
![]() |
7cc9d207b6 | |
![]() |
abfb62f342 | |
![]() |
ccbbab0741 | |
|
3e5c1da2c5 | |
![]() |
1731d5fc20 | |
![]() |
8cce97258c | |
![]() |
4ea60a5114 | |
![]() |
dd7be1c392 | |
![]() |
dbc1ea107c | |
![]() |
a4df928c5a | |
![]() |
ab842a6f1a | |
![]() |
4636a1b3b6 | |
![]() |
591119016e | |
![]() |
16fc6ebc4e | |
|
6a3cc56f85 | |
|
eac812a7bf | |
![]() |
4560b9231e | |
![]() |
f3d7938750 | |
![]() |
23dc04b560 | |
|
07aefa79eb | |
|
423d5a9316 | |
|
9664ca001e | |
![]() |
f0a67c2f98 | |
![]() |
b3c1845dbf | |
|
d613b1f3bb | |
|
c8e063343e | |
![]() |
75a78c839d | |
|
e15809c186 | |
|
7d4c0df691 | |
|
e72dfa4973 | |
|
84a8339a04 | |
|
3d5b2e76d7 | |
|
8b14ee3c72 | |
![]() |
10b3eb8a7b | |
![]() |
f39873efd8 | |
![]() |
f880b316b9 | |
![]() |
074b999b2b | |
![]() |
ee17acf7cf | |
![]() |
e7af767d02 | |
|
5b30943feb | |
|
722f355fe4 | |
|
f8f9f3fbb6 | |
![]() |
84186fe694 | |
![]() |
d080727633 | |
![]() |
96165a3eec | |
![]() |
14d8a248d7 | |
![]() |
eb7f4e6da3 | |
![]() |
ef867e1e83 | |
![]() |
4c4f4396fe | |
![]() |
e99333113f | |
![]() |
7b63fd6b9f | |
![]() |
20b97286e3 | |
![]() |
3a4f6888fb | |
![]() |
da48675900 | |
![]() |
74b84f9f86 | |
![]() |
dbafeb5cee | |
![]() |
5ce3b4cea4 | |
|
3f7366fbcd | |
|
cfdbc5a682 | |
|
9b880e3209 | |
|
c2ef23b746 | |
|
8a33ea6707 | |
|
9ee4c85b7c | |
![]() |
97da0f908f | |
![]() |
3ea9f0017d | |
|
8da237e5b9 | |
|
e9b23d6577 | |
|
64d9c334ce | |
|
d832939038 | |
|
c0e1ed9d12 | |
|
cad7e24299 | |
|
2a9448517c | |
|
5e5fb6e122 | |
|
3b15dd84fc | |
|
2bf84c0d5e | |
|
58a43a8b80 | |
|
e25231738a | |
|
35965f542a | |
|
fa48e3f5ca | |
|
e4e0564228 | |
|
13e2738fb5 | |
![]() |
e5f95fa9b5 | |
![]() |
4416e8bd4f | |
![]() |
5391c97873 | |
|
b5df0bb93b | |
|
30437d828c | |
|
dcc7ab6738 | |
|
57a7a17f73 | |
|
5196f33f24 | |
![]() |
480f2b6516 | |
![]() |
ee3cacb6c8 | |
![]() |
b3cbed2963 | |
![]() |
dd1af6712c | |
![]() |
fc37f18022 | |
![]() |
bab6efb23d | |
![]() |
c20599d742 | |
![]() |
817b8d3650 | |
|
8807be6e4d | |
|
8d41c27044 | |
|
53fe554d1e | |
![]() |
4e02dbe06b | |
![]() |
620ddff9bb | |
![]() |
54bd088ae5 | |
![]() |
2af3671811 | |
|
630a7aadeb | |
|
6383384287 | |
|
83f1263f85 | |
|
e4158d7d3a | |
|
d328108d9e | |
|
304fd72f27 | |
![]() |
9e62d959fc | |
![]() |
63b349c9f3 | |
![]() |
538d0f7d0f | |
![]() |
edc0d16c52 | |
![]() |
548a983a7a | |
![]() |
1852070f5b | |
![]() |
433e94de3c | |
![]() |
9362201452 | |
![]() |
b416b12914 | |
|
89f57fa4fc | |
|
9c11cd79e8 | |
![]() |
86b5d9cb20 | |
![]() |
ca33c77ff1 | |
![]() |
9464aadd95 | |
![]() |
803c468a80 | |
![]() |
46c57186b4 | |
![]() |
2e116548db | |
![]() |
3777fa26a0 | |
![]() |
65b12bb93a | |
![]() |
4e4f68bd2c | |
![]() |
22983c518e | |
![]() |
b075fdc3c1 | |
![]() |
4c450a6bbc | |
![]() |
16205927d8 | |
![]() |
d446fecbef | |
![]() |
1c1450a9a4 | |
![]() |
56921a1801 | |
![]() |
f0be159722 | |
|
a7384bc1c3 | |
![]() |
4b4dfc17e1 | |
![]() |
997ab5a8f8 | |
|
e11a5c0848 | |
|
f1df84d725 | |
|
26bac63c8e | |
|
9263676f01 | |
![]() |
4ab868acc5 | |
![]() |
127a4c6998 | |
![]() |
026916abb1 | |
![]() |
dc0c493970 | |
![]() |
a77f070f69 | |
![]() |
6cf7b86cc4 | |
![]() |
328e6d1192 | |
![]() |
3fb184e3cc | |
|
55170c7693 | |
![]() |
6b5d19916b | |
![]() |
c086eb5f83 | |
|
2cde13eabb | |
|
d68e7f38a3 | |
|
2fd6d3619c | |
![]() |
1fb0b27630 | |
![]() |
3abd2c13e9 | |
|
649d9c4ea6 | |
![]() |
ca57477dcb | |
![]() |
043e1b5237 | |
![]() |
bcc2579910 | |
![]() |
3836270622 | |
![]() |
b7c3c7c5eb | |
![]() |
15d4336c00 | |
![]() |
c367eaca10 | |
![]() |
9fbbd9805f | |
![]() |
095e1c7b7b | |
![]() |
d401634af3 | |
![]() |
14022c0ccc | |
![]() |
95303c5394 | |
![]() |
1701890e1a | |
![]() |
63f8ca06df | |
![]() |
a74335fd12 | |
![]() |
497342bcff | |
![]() |
0f6ebbbf2f | |
![]() |
cb302b50dd | |
![]() |
a8cf9b21c8 | |
![]() |
60eebead05 | |
![]() |
fce8166ba7 | |
![]() |
81d29d3809 | |
![]() |
b0e6f2bcd3 | |
![]() |
c44755f8d7 | |
![]() |
f5f74f7333 | |
![]() |
ae0efc1115 | |
![]() |
dfc2edd62d | |
![]() |
84de681777 | |
![]() |
260737f417 | |
|
d7f3a21add | |
![]() |
fd07a8c6ae | |
|
ef9592ef30 | |
![]() |
f072a2a7f3 | |
|
cc42683316 | |
![]() |
8d28b41357 | |
![]() |
a247d5fc7a | |
![]() |
3d9aeef8b4 | |
![]() |
2790f91f1b | |
![]() |
dfe884ec47 | |
![]() |
da28624c0a | |
![]() |
05ca426004 | |
|
70f1e6827f | |
|
b5188e3272 | |
|
ff881732d2 | |
![]() |
0373d08fdc | |
![]() |
3ef6ed306f | |
![]() |
9ab130f81e | |
![]() |
20790f7548 | |
![]() |
2adf87a289 | |
![]() |
6954a860af | |
![]() |
bb8e6aeaf8 | |
![]() |
b38daf634f | |
![]() |
6d7b7dd058 | |
![]() |
ec0358d6b2 | |
![]() |
03075b8d48 | |
![]() |
6b67344493 | |
![]() |
ede998ebef | |
![]() |
fba7c7f8b9 | |
![]() |
4e29cabdef | |
![]() |
199240962a | |
![]() |
8608e2d67a | |
![]() |
acaea1901d | |
![]() |
28d2bbe9a1 | |
![]() |
a954081f74 | |
|
c12f49a987 | |
![]() |
180fd51395 | |
![]() |
4a566bb0f4 | |
![]() |
3f1803b2e5 | |
![]() |
ddeea66dc1 | |
![]() |
1f6fa921e8 | |
![]() |
f780d3a91e | |
![]() |
f2d652fafe | |
![]() |
369e87ab92 | |
![]() |
9850adfdb5 | |
|
007b90c284 | |
|
481d1b7db0 | |
|
733f64eaec | |
|
383660c778 | |
![]() |
5674800c97 | |
![]() |
2609908d6b | |
![]() |
2352e1a677 | |
![]() |
618d4ad995 | |
![]() |
32823ce9f9 | |
|
daa098abf2 | |
|
0cfe16a8d3 | |
![]() |
80ec837964 | |
![]() |
090d76ad69 | |
![]() |
517d84c3bd | |
![]() |
851577ea7c | |
![]() |
8fdb2df0ef | |
![]() |
12c91ca680 | |
![]() |
d3967f25ad | |
|
9509dc5af2 | |
|
cd39370fe5 | |
|
4ed846a68b | |
|
f22ffcb7c4 | |
|
bd5ffae6ad | |
|
708d66361c | |
|
f997a8a101 | |
|
17cf3b6c87 | |
|
1ae1188421 | |
|
ed84b387d5 | |
|
4bab6d1876 | |
![]() |
35b4fa0e94 | |
![]() |
3b4d84fef9 | |
|
8168329ba9 | |
|
89ab25974d | |
![]() |
e8ce1e46d4 | |
![]() |
2e046f313f | |
![]() |
63c40a2025 | |
|
4bd77a870b | |
|
4ca4bcac02 | |
|
3350b80e92 | |
|
b1f460d760 | |
![]() |
eaa0364e97 | |
![]() |
f2b7ae2f22 | |
![]() |
3ec44cbfa3 | |
|
1ca3db70b8 | |
![]() |
1193acc3a9 | |
![]() |
640094def7 | |
![]() |
6c0bd6a6fe | |
![]() |
f3b78cb40d | |
|
a438ab6f3e | |
![]() |
f5ebe5c5f1 | |
![]() |
ba97339821 | |
![]() |
240e2b22ab | |
![]() |
fef03e6d22 | |
![]() |
c42fa03b8b | |
![]() |
783474cbd9 | |
![]() |
ed909f620d | |
![]() |
3a34d8682c | |
![]() |
60894f00b1 | |
![]() |
925b05e004 | |
![]() |
9b465dd6cb | |
|
4878d66620 | |
|
632ade9d25 | |
|
5acd45bf85 | |
|
d03b45eecf | |
|
0193381d1f | |
![]() |
32a9d762d8 | |
![]() |
0a79950046 | |
![]() |
4b7c58b13f | |
![]() |
7148957368 | |
|
aa50c50254 | |
|
60b3c7925d | |
|
0f41cabe71 | |
![]() |
d04ed7e008 | |
![]() |
c6b35d83d3 | |
![]() |
8776f48f62 | |
![]() |
197c70927d | |
![]() |
8ac0c1fcd1 | |
![]() |
fc5aff287f | |
![]() |
82835969be | |
![]() |
b5409fa7e5 | |
![]() |
3303d801ea | |
|
6168256897 | |
|
62c5345889 | |
|
e8b8dc682a | |
|
73f41d555c | |
![]() |
6eadacb3f0 | |
|
4b167dacbb | |
|
911c47df8d | |
|
a37d7b9840 | |
![]() |
217ab920a9 | |
![]() |
98ae62d181 | |
![]() |
98f1723411 | |
|
68a38e75bc | |
|
ee29c6be5c | |
|
c0ee0a694c | |
![]() |
25fa6f427b | |
![]() |
467d722d25 | |
![]() |
f552fef4e2 | |
|
3e352d3c7c | |
![]() |
fbdb4cbf39 | |
|
13472b2311 | |
![]() |
bdddd655bf | |
![]() |
6ec7a13293 | |
![]() |
716b29c25f | |
![]() |
5c4930a362 | |
![]() |
ad8fed9440 | |
![]() |
964bef7896 | |
![]() |
7e48e5e8b8 | |
![]() |
48846a7e31 | |
|
32db15aad5 | |
![]() |
8ec3e4bbaa | |
|
4b05838498 | |
![]() |
2fe5fc369c | |
|
b8be0c23cb | |
|
d20a7b1318 | |
|
f8268accc0 | |
|
a9811768d4 | |
|
024bc289de | |
|
96d34d0237 | |
|
fea11bdc2e | |
![]() |
d0a164434c | |
|
ab5d273f98 | |
![]() |
8bf4e9b8d2 | |
|
096b0b954d | |
|
df57312056 | |
![]() |
59b256dd78 | |
![]() |
cfadde830f | |
![]() |
f12cfabee3 | |
![]() |
350783b833 | |
![]() |
b22909a654 | |
![]() |
579b45dfa4 | |
![]() |
fbc1f95cd1 | |
![]() |
4ccf8ea5ff | |
![]() |
45a2661f99 | |
![]() |
2d306e20fb | |
![]() |
f306a5008f | |
![]() |
fc064a53d1 | |
![]() |
dc6e62b784 | |
![]() |
20b8a6c005 | |
|
d5c141f892 | |
![]() |
e467794901 | |
![]() |
e098216af8 | |
![]() |
809cce9085 | |
|
35c6cb98db | |
|
f417e42864 | |
|
6e54203ebb | |
![]() |
79a6841bbc | |
![]() |
b3d78741a3 | |
![]() |
91884b9d2d | |
![]() |
6182405108 | |
![]() |
35336701fa | |
![]() |
ac82e14eba | |
|
935f3ddf7f | |
![]() |
5ca2cc69ac | |
|
a2549f7ff1 | |
![]() |
0a87973e71 | |
![]() |
a6099973d7 | |
![]() |
8b6ae143c0 | |
![]() |
862186a8f2 | |
![]() |
fcfd64f353 | |
![]() |
755c1f9492 | |
![]() |
f85e50a5f0 | |
![]() |
0f0d348d9f | |
|
d6b5dc326a | |
![]() |
53b6ffb15a | |
![]() |
380ef5e057 | |
![]() |
e69f9263b2 | |
![]() |
003bfe7884 | |
![]() |
df5efa0dc6 | |
|
a35db9fe80 | |
|
6183f1f76d | |
|
e72273f3b2 | |
|
cc09f724cc | |
|
7a54c5f536 | |
![]() |
bb3f5cec76 | |
![]() |
19ffd9fea1 | |
![]() |
5877474f59 | |
![]() |
1bbde165c2 | |
|
3f5754a3a5 | |
|
5463c22518 | |
|
5db43bf768 | |
|
1feb166fd5 | |
|
0df1e5fdd0 | |
|
8ba70a33be | |
![]() |
b21f44b59e | |
![]() |
92a310c916 | |
![]() |
42815c0812 | |
![]() |
231bf39283 | |
|
7793eacf75 | |
|
25afedcdfd | |
|
d95a689815 | |
|
b386dc51e4 | |
|
1882120df3 | |
|
274cd81655 | |
|
6273349334 | |
|
e8deb83004 | |
|
52701d1c2f | |
|
b248f770f1 | |
|
04b9e43382 | |
|
3580a8653d | |
|
d9653e461e | |
|
d9a1d32ec8 | |
|
b5dfd83527 | |
|
df7b91a8ba | |
|
8dae15225e | |
|
5fcf789e63 | |
|
ed0655452c | |
|
0dd062ce1c | |
|
bd3cbf33fd | |
|
b8d4b15b40 | |
|
24d83133e7 | |
|
4ed3a9d478 | |
|
0f5fd424fb | |
|
fbbacfa983 | |
|
169ec9e0b0 | |
|
a95ac23c49 | |
|
30acbec322 | |
|
08292d86ee | |
|
158ba9707d | |
|
d0988e42b4 | |
|
73b5c0f63f | |
|
d154f0aecc | |
|
29d9410e42 | |
|
dbae651abc | |
|
3b62f09669 | |
|
5864352049 | |
|
1d6d48fc94 | |
|
484c91a581 | |
|
aabb7518c0 | |
|
de2afba910 | |
|
a465e8de66 | |
|
e4a79a4049 | |
|
fa1e858a97 | |
|
2080d44bdb | |
|
97c1da579e | |
|
5ab66e0c40 | |
|
b1b7b6a1e0 | |
|
16f2aecb6d | |
|
a583d3156a | |
|
4ca5d4b234 | |
|
77a8e75e87 | |
|
7b91ad37e5 | |
|
9dbb9a42d6 | |
|
09f9f138f0 | |
|
f8aa5ddb00 | |
|
18d65c169c | |
|
3b3cd46b76 | |
|
a608803aa8 | |
|
76cc185a1d | |
|
10f8ff28e1 | |
|
25a686e4f3 | |
|
e76503ae26 | |
|
50991f503f | |
|
acd031ca7d | |
|
b59b76be4a | |
|
211581cef0 | |
|
7cad953413 | |
|
fe58175ee0 | |
|
5d0849a148 | |
|
d14bf35ca1 | |
|
9a5ce74d98 | |
|
d7dd3901b8 | |
|
aefd6c08dc | |
|
3c2c742121 | |
|
9221e55752 | |
|
44db7c48f9 | |
|
861a84d8ec | |
|
d496e1c01e | |
|
e4b2563780 | |
|
944fb3b89e | |
|
ba1fa8b685 | |
|
29e3a55a0c | |
|
c426467a68 | |
|
9fe8df3c1b | |
|
531495429c | |
|
bed2469014 | |
|
45b7f70d9f | |
|
1ebb6cb561 | |
|
21ccedab9c | |
|
8f45bcf959 | |
|
1f9caeece5 | |
|
5b4e6f4902 | |
|
3d0e323801 | |
|
f6fb50529c | |
|
c42f3d5928 | |
|
42d2b51f7f | |
|
66c40d4791 | |
|
ce467736a7 | |
|
3e4dd90e17 | |
|
8ae5587516 | |
|
0b543f7dda | |
|
a07204111a | |
|
d243fff299 | |
|
038df804c0 | |
|
877948b0cd | |
|
9a17c4865f | |
|
9427db3e5a | |
|
81da71d478 | |
|
169dc84e22 | |
|
d6fd85f536 | |
|
6448a30e03 | |
|
17fb43cea8 | |
|
a6e50d2a25 | |
|
bd16ca476d | |
|
7ddb59800d | |
|
2ea78b4f20 | |
|
e36c7a4b6a | |
|
8e8ec821f2 | |
|
cedaeda60c | |
|
5cf257c3cc | |
|
aa18fe0ad4 | |
|
1358c23ca6 | |
|
c27cc063e6 | |
|
b0092487e6 | |
|
555df176cc | |
|
fbebd0a623 | |
|
fe23c2afbf | |
|
779c86108a | |
|
83e43f0c97 | |
|
20f892a4f0 | |
|
f77dcd3b30 | |
|
701c05c39e | |
|
853c33cb24 | |
|
0bd8c19a87 | |
|
c2171eab9b | |
|
72fb2738db | |
|
1cb406e1e8 | |
|
5b33da0aa5 | |
|
ca78b04f6e | |
|
f93c1dff0b | |
|
e237fd46f7 | |
|
ca3c564529 | |
|
ef33193f01 | |
|
b648774b42 | |
|
9cd18397f7 | |
|
0ffb919242 | |
|
6d4fb8df34 | |
|
d9c1c3d3a2 | |
|
083a839bf5 | |
|
551edde13d | |
|
768f9a7847 | |
|
a8adf6f140 | |
|
77620f7735 | |
|
59cd230658 | |
|
79a6cea623 | |
|
45fdf9bb59 | |
|
50dc5cce5d | |
|
a6cee63d17 | |
|
000197b0d1 | |
|
6aa3321d17 | |
|
d44308fc82 | |
|
ae7d0d1329 | |
|
dc7c326ffe | |
|
f560723d5a | |
|
55c74de8e4 | |
|
7c88ea3d67 | |
|
f36dbf9c26 | |
|
29f6950e7c | |
|
cf164ff5f8 | |
|
d6f9530637 | |
|
f15cd44dff | |
|
babdec4788 | |
|
8731506992 | |
|
d90ab310cc | |
|
f0e2277f1c | |
|
88a9194aca | |
|
53dcd9de71 | |
|
6c68a51091 | |
|
3abd6037d9 | |
|
ec3a556a6f | |
|
793cbb372a | |
|
396ac55429 | |
|
97507c2203 | |
|
50db13a7ef | |
|
8115858c47 | |
|
357cd6d628 | |
|
20a69528fa | |
|
a5021df2ac | |
|
703c2c5bad | |
|
2d067f0a18 | |
|
0b34f49ea7 | |
|
088c617cc1 | |
|
2a2c8361b8 | |
|
8a3be40410 | |
|
8ce75ed2d3 | |
|
8052ae832d | |
|
adc9936566 | |
|
c00a8a67f9 | |
|
854ef5ca45 | |
|
dc43b3542c | |
|
fc3cf01d3f | |
|
8f5bb0e2d9 | |
|
1b8006f438 | |
|
5c123edfaa | |
|
3f94cf3637 | |
|
689a91ab49 | |
|
2dfd69ae21 | |
|
720c073f32 | |
|
0076468a15 | |
|
910ae48556 | |
|
eac7331070 | |
|
551f333261 | |
|
dec264d169 | |
|
7055974443 | |
|
a517d1df68 | |
|
547cf7ce86 | |
|
560adc458c | |
|
6dfffb8a6d | |
|
1c5b42e01b | |
|
85302102d6 | |
|
316fb0ff58 | |
|
d475413fd6 | |
|
cd40efc760 | |
|
76ed52b68a | |
|
3536918938 | |
|
56278b84f2 | |
|
882a50cf56 | |
|
db4031b8bf | |
|
ecfc39565c | |
|
9ced678f91 | |
|
7951ca28d5 | |
|
4bbb843edf | |
|
d1b5ead752 | |
|
972373a277 | |
|
66dead1e6a | |
|
f901ff8920 | |
|
00a4be2879 | |
|
90738a6117 | |
|
dea5a223d1 | |
|
bd88870405 | |
|
9b11bccd42 | |
|
fae11267f7 | |
|
747646cd9d | |
|
f0fc456a1c | |
|
2f06e89b54 | |
|
ae3057d150 | |
|
033865df66 | |
|
7ca13fb387 | |
|
2fb263d6c9 | |
|
fda21d782c | |
|
71836ca3ae | |
|
4dadce904d | |
|
e4ec205890 | |
|
aa9006bfe5 | |
|
00c1486e89 | |
|
f8ef2d48a0 | |
|
0f83639565 | |
|
0607a62b17 | |
|
3f0ded057b | |
|
1e1d07e697 | |
|
a72a0de2b9 | |
|
d0d906d04c | |
|
6079441f8a | |
|
f0bc08cd47 | |
|
39526b091b | |
|
bcd5c6bee0 | |
|
cf0565ddb6 | |
|
c4843da207 | |
|
cb184792cd | |
|
78cee5f7d1 | |
|
b852b8cf08 | |
|
cee09d9f8f | |
|
7ab87df7fc | |
|
78fd1d158f | |
|
9b91557bb6 | |
|
521a1a2c8a | |
|
bc639488aa | |
|
9ca85d8e8d | |
|
64ed6b93c9 | |
|
f9e613f856 | |
|
b508fd6cf4 | |
|
43334935d9 | |
|
958b1618b1 | |
|
99fbecc834 | |
|
e489c57fe8 | |
|
8d0a6d267a | |
|
cd85fea841 | |
|
b1c03ed5e8 | |
|
e9daacc1b2 | |
|
d48009fab6 | |
|
0b93a3a787 | |
|
d4c860bf29 | |
|
ce4aee366a | |
|
747bc4ab45 | |
|
fc3344c78a | |
|
ef12f85687 | |
|
e120c4dac2 | |
|
e1cf2fcdeb | |
|
c4f380873e | |
|
5cb2e55f74 | |
|
1dd3fbc69a | |
|
9b08a09a1b | |
|
01ccbe89cd | |
|
643dedc8cb | |
|
fbd1533a53 | |
|
49d1317d21 | |
|
31d7103da3 | |
|
0b0a57035a | |
|
7449d915ab | |
|
33c0e026fd | |
|
b97c42d0ae | |
|
60245b4558 | |
|
751187a3da | |
|
1bf858c10c | |
|
9e2db8a7f6 | |
|
c575376b44 | |
|
8564930dfc | |
|
8e362e902f | |
|
abf3541201 | |
|
a2612d8009 | |
|
2f2655525f | |
|
ec9f3a3058 | |
|
5d102f9ef4 | |
|
b7914e54f6 | |
|
1a93477635 | |
|
68cc2999ed | |
|
66ca7fd1f0 | |
|
b1c3d62e41 | |
|
a94493ce0d | |
|
c1ea0232bb | |
|
7c664addbd | |
|
c6b79f82bc | |
|
58ca8e2651 | |
|
692d51792a | |
|
fcc827522c | |
|
4e3f9cc019 | |
|
fe08cab2e5 | |
|
5ed7b3e4ad | |
|
2e511655f6 | |
|
4e2c46260c | |
|
9ba00b21c9 | |
|
b11f5fd228 | |
|
90dbe0730a | |
|
d6633cb73a | |
|
a7a6abd22a | |
|
c956667ce0 | |
|
5701c818ed | |
|
1ac2ddfaa5 | |
|
4aac05d4e1 | |
|
84b56bfcb8 | |
|
7485564bb9 | |
|
b5acf2308a | |
|
e3f4313c80 | |
|
b223abe229 | |
|
b3bede308c | |
|
2f170a54c6 | |
|
36c4b32acb | |
|
ada03e45ea | |
|
cad35e3757 | |
|
f38d6bc976 | |
|
22293572ac | |
|
8720cab1e9 | |
|
959c1e8d95 | |
|
3fc62ca1d5 | |
|
29dc3fff39 | |
|
298abdd1b1 | |
|
26f87fba16 | |
|
1e9a32a93e | |
|
2dc79052c2 | |
|
380ca3a066 | |
|
237b0afb08 | |
|
e14936e820 | |
|
655c85851f | |
|
1c7e414aa4 | |
|
099fc52e00 | |
|
490957ec3b | |
|
b1884d30d5 | |
|
87d2cc3e25 | |
|
98d8ee1fb6 | |
|
2ca77732c8 | |
|
c5063e513d | |
|
63e50e36ac | |
|
dca4ef6a34 | |
|
7a2270956c | |
|
b380afaf5c | |
|
e7af0e2e47 | |
|
04f2dbee9a | |
|
70d22f7c4f | |
|
25d0e784bb | |
|
5d45b24299 | |
|
b6b8befde7 | |
|
f33b9559cd | |
|
f9bc2258ec | |
|
2a09ced1ce | |
|
7a1e6cfbad | |
|
47d1f727ce | |
|
a7665df0ea | |
|
84f12adce8 | |
|
7fde1e0e12 | |
|
499734ebf9 | |
|
f339df699e | |
|
cfd94cb3b7 | |
|
43e0617429 | |
|
d6b66d5324 | |
|
0c1df3b2cb | |
|
fa86d3ea10 | |
|
8c99b754fb | |
|
f3cf2c87c9 | |
|
8e4e6fc0ac | |
|
75f3166ffa | |
|
04bf423fcb | |
|
51e8c9d908 | |
|
4304a35b80 | |
|
076375633a | |
|
dbf5e711a5 | |
|
4432e65683 | |
|
dcf44a78f0 | |
|
74cbca2421 | |
|
01bf13ddd9 | |
|
12edc620df | |
|
4ce03145df | |
|
3e04a37ece | |
|
78f464ccba | |
|
64423f1999 | |
|
05c3f60dab | |
|
0083ef33cb | |
|
36b68df273 | |
|
e1a5918c22 | |
|
26ae9b35df | |
|
8e79b43aaf | |
|
d28eba6423 | |
|
688be1bb7d | |
|
df69dee282 | |
|
45a77e5c07 | |
|
7849bd0ebf | |
|
ea2de5910a | |
|
a5d4799a21 | |
|
335d24bc8b | |
|
e97eacbbf6 | |
|
3649bf1fd0 | |
|
6ffc2938a1 | |
|
aa60de1dac | |
|
29f98513e2 | |
|
e35cdf39fb | |
|
2c17ae096e | |
|
e51b86538b | |
|
da4fd3a762 | |
|
399f6c2a17 | |
|
fb335162fc | |
|
c7b40c1230 | |
|
293121ab91 | |
|
efc82b9841 | |
|
e3df503dd2 | |
|
6a2ad67386 | |
|
3d12db3a07 | |
|
1faaf1d7d1 | |
|
f8a6f62342 | |
|
66d1246a6c | |
|
f79beef3f9 | |
|
43cccc5429 | |
|
81e6691632 | |
|
38d6519381 | |
|
16418675ac | |
|
102858bc8c | |
|
0d64768e4b | |
|
beccac652f | |
|
30eb1958c1 | |
|
33e17e8439 | |
|
e0c47c2abd | |
|
422549f9e7 | |
|
0358229b95 | |
|
c4586fbb36 | |
|
f94006abfd | |
|
4d61e7618a | |
|
36286d9003 | |
|
51356da7f3 | |
|
ebe893022f | |
|
c5f22e6c70 | |
|
fcc5429bbd | |
|
1f8f2abcf6 | |
|
a2140574cd | |
|
ab47dd0524 | |
|
4310cc9f26 | |
|
9648afb0bb | |
|
557b6ccc13 | |
|
d94b3ff2f4 | |
|
4a7878d16e | |
|
0a00a4bc0e | |
|
b81d92af46 | |
|
922561afb1 | |
|
6f7899d16f | |
|
4e3c8e414c | |
|
d588a78f62 | |
|
a7d681c4dd | |
|
7a93db9ed2 | |
|
74e5fa0e31 | |
|
de995c8714 | |
|
ea156cec7e | |
|
7499d8af89 | |
|
f8654edc3b | |
|
d16f290aa6 | |
|
9385d346f1 | |
|
22f3371090 | |
|
c0a4f8f4ec | |
|
7586a0fb21 | |
|
c0e3a91a46 | |
|
7ebd8681fa | |
|
72553dec57 | |
|
dee68808b1 | |
|
96d7917bbf | |
|
abca0fe432 | |
|
d7612a0921 | |
|
c54950a95f | |
|
be0f68cede | |
|
1b92b53099 | |
|
5634413cac | |
|
1a9ed1425e | |
|
f9d4316a8e | |
|
6f7f815fd4 | |
|
ddb826733b | |
|
1f989d0a37 | |
|
d63626424e | |
|
55ab694505 | |
|
0885575cc4 | |
|
a188648287 | |
|
8011dabaac | |
|
88a08e73c0 | |
|
6713f9b280 | |
![]() |
ef6f2c7b42 | |
![]() |
689b24da8f | |
![]() |
369877da5f | |
![]() |
96c67d359e | |
![]() |
3e633ea6cc | |
![]() |
4fe3f88de6 | |
![]() |
a5fd87a475 | |
![]() |
e8bbc7d856 | |
![]() |
9a0d7aa02a | |
![]() |
25e1bf1565 | |
![]() |
574f6561d1 | |
![]() |
eaddf52cbd | |
![]() |
ef0a0e5ddd | |
![]() |
ef81d61a0d | |
![]() |
071f913123 | |
![]() |
6096fdd7bf | |
![]() |
9ba297ccf6 | |
![]() |
66fd6a71e5 | |
![]() |
89bc20e540 | |
![]() |
184a6bf1bf | |
![]() |
8ee089b82d | |
![]() |
abc21413ac | |
|
ce89ce5169 | |
|
b8a4c467fe | |
|
300658f8dd | |
|
9553740960 | |
|
1a8d9bb0ce | |
|
8c43f74b69 | |
|
3e7ae82258 | |
|
0aa75e077e | |
|
8aefcad510 | |
|
622dcbaf4f | |
![]() |
6570125a36 | |
![]() |
d91e8dcbfe | |
![]() |
0c2507b1e9 | |
|
8d29c2bd50 | |
|
774f632d9a | |
|
2969afd333 | |
|
cc978c8dea | |
|
ce105b4c07 | |
|
b5870b1020 | |
|
1edb3ce7ad | |
![]() |
59257b1caa | |
![]() |
b552e29aa3 | |
![]() |
21424a23f2 | |
![]() |
a82af669bd | |
![]() |
0f01abd45f | |
|
80002be670 | |
![]() |
f7e19cb3a4 | |
![]() |
5cd6620413 | |
![]() |
f3a9124bdd | |
![]() |
d97a39a3a2 | |
![]() |
987ff74690 | |
![]() |
37be604e82 | |
|
83e2c1f889 | |
|
46a1c8877b | |
![]() |
0aa39efe9b | |
![]() |
15d562d7b1 | |
![]() |
5b261d6e81 | |
|
4693e77e02 | |
|
fbf22ff0df | |
![]() |
0794f77a87 | |
![]() |
e5a46a242f | |
![]() |
4902237bd7 | |
![]() |
4ddc60a1c3 | |
|
cfa14fff9d | |
|
ef327f2994 | |
|
bf91c5e382 | |
|
9b687f7885 | |
|
a072162324 | |
|
8f1e0f39ea | |
|
aaa6483958 | |
![]() |
bf730ca18f | |
![]() |
132af875bc | |
|
a862d994ab | |
![]() |
604da93c5c | |
![]() |
3f525f5779 | |
|
05d1e66ea9 | |
|
10c1cccf2c | |
|
27ec7ec7dd | |
![]() |
43b4907565 | |
![]() |
cb90e1a13f | |
|
749cd058c4 | |
|
47cc70f2c5 | |
|
5447d54d30 | |
|
6c436dd631 | |
|
9eb7219b9a | |
|
ad5fcb25c4 | |
|
d42053ce0c | |
|
36bae71947 | |
![]() |
837aa1ea9e | |
|
c283c7ed58 | |
|
4cf8588343 | |
|
e75fad98f8 | |
|
bc37c59f00 | |
|
a6a745da93 | |
|
5bef80ee58 | |
|
f9bcc7e02b | |
|
d35faf3935 | |
|
8d7dc9cb60 | |
|
248d78d8c1 | |
|
f632424f13 | |
|
95ede63220 | |
|
8fac294d04 | |
|
d67c12beba | |
|
a7e4b85352 | |
![]() |
2ac2920399 | |
![]() |
230b934de4 | |
|
e0bedf175f | |
|
c9a263e03c | |
![]() |
2bd15d9746 | |
|
fc9588fb63 | |
|
e611b519ab | |
|
3dd3944ebd | |
|
f417bf3308 | |
|
9c7c914d12 | |
|
b088befae7 | |
|
d3636e686b | |
|
88d98f0ac4 | |
|
db6aa954b1 | |
|
04a611a4aa | |
|
9ecea83506 | |
|
82a9907fdc | |
|
c56c98fd6e | |
|
2948ad2033 | |
|
fc611140cf | |
|
fcb5f58b69 | |
|
0f38a130f3 | |
|
fc54632a08 | |
|
5963af5c7b | |
|
c1f2f7f6e2 | |
|
271699daf1 | |
|
98da7ea34d | |
|
645e4a3586 | |
|
7beca24a05 | |
|
d1368c7612 | |
|
28e762810e | |
|
0f60d0adc9 | |
|
e634317675 | |
|
6b1a0a96c6 | |
|
298859bd10 | |
|
d4d412ab40 | |
|
57d1a1474e | |
|
055b7dbac5 | |
|
30aad87e5a | |
|
aecd68fe9a | |
|
998a6828d9 | |
|
12c04d02e5 | |
|
d6ef3d8aa3 | |
|
c7a89d1660 | |
|
1939c0d33f | |
![]() |
561b9efd92 | |
![]() |
6c0b87fdd1 | |
![]() |
5d309d1dc4 | |
![]() |
89c230c362 | |
![]() |
d4156a5582 | |
![]() |
ee8cbb8553 |
|
@ -23,7 +23,7 @@
|
||||||
* Fix 版本库中附件下载400(#51625)
|
* Fix 版本库中附件下载400(#51625)
|
||||||
* Fix loading页面优化(#51588)
|
* Fix loading页面优化(#51588)
|
||||||
* Fix 提交详情页面优化(#51577)
|
* Fix 提交详情页面优化(#51577)
|
||||||
* Fix 修复易修复制功能(#51569)
|
* Fix 修复疑修复制功能(#51569)
|
||||||
* Fix 修复新建发行版用户信息显示错误的问题(#51665)
|
* Fix 修复新建发行版用户信息显示错误的问题(#51665)
|
||||||
* Fix 修复查看文件详细信息报错的问题(#51561)
|
* Fix 修复查看文件详细信息报错的问题(#51561)
|
||||||
* Fix 修复提交记录中时间显示格式问题(#51526)
|
* Fix 修复提交记录中时间显示格式问题(#51526)
|
||||||
|
@ -62,7 +62,7 @@
|
||||||
## [v3.0.3](https://forgeplus.trustie.net/projects/jasder/forgeplus/releases) - 2021-05-08
|
## [v3.0.3](https://forgeplus.trustie.net/projects/jasder/forgeplus/releases) - 2021-05-08
|
||||||
|
|
||||||
* BUGFIXES
|
* BUGFIXES
|
||||||
* Fix 解决易修标题过长导致的排版问题(45469)
|
* Fix 解决疑修标题过长导致的排版问题(45469)
|
||||||
* Fix 解决合并请求详情页面排版错误的问题(45457)
|
* Fix 解决合并请求详情页面排版错误的问题(45457)
|
||||||
* FIX 解决转移仓库界面专有名词描述错误的问题(45455)
|
* FIX 解决转移仓库界面专有名词描述错误的问题(45455)
|
||||||
* Fix 解决markdown格式文件自动生成数字排序的问题(45454)
|
* Fix 解决markdown格式文件自动生成数字排序的问题(45454)
|
||||||
|
|
19
Gemfile
19
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" }
|
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
|
||||||
|
|
||||||
gem 'rails', '~> 5.2.0'
|
gem 'rails', '~> 5.2.0'
|
||||||
|
@ -22,7 +23,7 @@ gem 'chinese_pinyin'
|
||||||
gem 'rack-cors'
|
gem 'rack-cors'
|
||||||
gem 'redis-rails'
|
gem 'redis-rails'
|
||||||
gem 'roo-xls'
|
gem 'roo-xls'
|
||||||
gem 'simple_xlsx_reader'
|
gem 'simple_xlsx_reader', '~>1.0.4'
|
||||||
|
|
||||||
gem 'rubyzip'
|
gem 'rubyzip'
|
||||||
|
|
||||||
|
@ -52,7 +53,7 @@ gem 'acts_as_list'
|
||||||
gem 'omniauth-cas'
|
gem 'omniauth-cas'
|
||||||
|
|
||||||
# profiler Middleware
|
# profiler Middleware
|
||||||
gem 'rack-mini-profiler'
|
# gem 'rack-mini-profiler'
|
||||||
|
|
||||||
# object-based searching
|
# object-based searching
|
||||||
gem 'ransack'
|
gem 'ransack'
|
||||||
|
@ -118,6 +119,10 @@ gem 'deep_cloneable', '~> 3.0.0'
|
||||||
# oauth2
|
# oauth2
|
||||||
gem 'omniauth', '~> 1.9.0'
|
gem 'omniauth', '~> 1.9.0'
|
||||||
gem 'omniauth-oauth2', '~> 1.6.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
|
# global var
|
||||||
gem 'request_store'
|
gem 'request_store'
|
||||||
|
@ -128,3 +133,11 @@ gem 'harmonious_dictionary', '~> 0.0.1'
|
||||||
gem 'parallel', '~> 1.19', '>= 1.19.1'
|
gem 'parallel', '~> 1.19', '>= 1.19.1'
|
||||||
|
|
||||||
gem 'letter_avatar'
|
gem 'letter_avatar'
|
||||||
|
|
||||||
|
gem 'jwt'
|
||||||
|
|
||||||
|
gem 'doorkeeper'
|
||||||
|
|
||||||
|
gem 'doorkeeper-jwt'
|
||||||
|
|
||||||
|
gem 'gitea-client', '~> 0.11.1'
|
|
@ -106,6 +106,10 @@ GEM
|
||||||
activerecord (>= 3.1.0, < 7)
|
activerecord (>= 3.1.0, < 7)
|
||||||
diff-lcs (1.3)
|
diff-lcs (1.3)
|
||||||
diffy (3.3.0)
|
diffy (3.3.0)
|
||||||
|
doorkeeper (5.5.1)
|
||||||
|
railties (>= 5)
|
||||||
|
doorkeeper-jwt (0.4.1)
|
||||||
|
jwt (>= 2.1)
|
||||||
e2mmap (0.1.0)
|
e2mmap (0.1.0)
|
||||||
elasticsearch (7.5.0)
|
elasticsearch (7.5.0)
|
||||||
elasticsearch-api (= 7.5.0)
|
elasticsearch-api (= 7.5.0)
|
||||||
|
@ -450,6 +454,8 @@ DEPENDENCIES
|
||||||
chromedriver-helper
|
chromedriver-helper
|
||||||
deep_cloneable (~> 3.0.0)
|
deep_cloneable (~> 3.0.0)
|
||||||
diffy
|
diffy
|
||||||
|
doorkeeper
|
||||||
|
doorkeeper-jwt
|
||||||
enumerize
|
enumerize
|
||||||
faraday (~> 0.15.4)
|
faraday (~> 0.15.4)
|
||||||
font-awesome-sass (= 4.7.0)
|
font-awesome-sass (= 4.7.0)
|
||||||
|
@ -458,6 +464,7 @@ DEPENDENCIES
|
||||||
harmonious_dictionary (~> 0.0.1)
|
harmonious_dictionary (~> 0.0.1)
|
||||||
jbuilder (~> 2.5)
|
jbuilder (~> 2.5)
|
||||||
jquery-rails
|
jquery-rails
|
||||||
|
jwt
|
||||||
kaminari (~> 1.1, >= 1.1.1)
|
kaminari (~> 1.1, >= 1.1.1)
|
||||||
letter_avatar
|
letter_avatar
|
||||||
listen (>= 3.0.5, < 3.2)
|
listen (>= 3.0.5, < 3.2)
|
||||||
|
|
214
api_document.md
214
api_document.md
|
@ -329,6 +329,7 @@ http://localhost:3000/api/licenses/ | jq
|
||||||
|licenses|array |返回数据|
|
|licenses|array |返回数据|
|
||||||
|-- id |int |id |
|
|-- id |int |id |
|
||||||
|-- name |string|开源许可证名称|
|
|-- name |string|开源许可证名称|
|
||||||
|
|-- is_secret |string|是否为特殊许可证|
|
||||||
|
|
||||||
|
|
||||||
返回值
|
返回值
|
||||||
|
@ -337,23 +338,33 @@ http://localhost:3000/api/licenses/ | jq
|
||||||
"licenses": [
|
"licenses": [
|
||||||
{
|
{
|
||||||
"id": 57,
|
"id": 57,
|
||||||
"name": "AFL-1.2"
|
"name": "AFL-1.2",
|
||||||
|
"is_secret": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 76,
|
"id": 76,
|
||||||
"name": "AFL-3.0"
|
"name": "AFL-3.0",
|
||||||
|
"is_secret": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 214,
|
"id": 214,
|
||||||
"name": "AFL-1.1"
|
"name": "AFL-1.1",
|
||||||
|
"is_secret": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 326,
|
"id": 326,
|
||||||
"name": "AFL-2.1"
|
"name": "AFL-2.1",
|
||||||
|
"is_secret": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 350,
|
"id": 350,
|
||||||
"name": "AFL-2.0"
|
"name": "AFL-2.0",
|
||||||
|
"is_secret": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 359,
|
||||||
|
"name": "PHengLEI",
|
||||||
|
"is_secret": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -597,6 +608,8 @@ curl -X GET http://localhost:3000/api/repositories/:id/edit.json | jq
|
||||||
|project_category_id |int|项目类别id|
|
|project_category_id |int|项目类别id|
|
||||||
|project_language_id |int|项目语言id|
|
|project_language_id |int|项目语言id|
|
||||||
|private |boolean|项目是否私有, true:为私有,false: 公开 |
|
|private |boolean|项目是否私有, true:为私有,false: 公开 |
|
||||||
|
|is_secret |boolean|项目是否为特殊协议项目, true:是,false: 否 |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
返回值
|
返回值
|
||||||
|
@ -609,7 +622,8 @@ curl -X GET http://localhost:3000/api/repositories/:id/edit.json | jq
|
||||||
"project_description": "my first project mirror_demo",
|
"project_description": "my first project mirror_demo",
|
||||||
"project_category_id": 1,
|
"project_category_id": 1,
|
||||||
"project_language_id": 2,
|
"project_language_id": 2,
|
||||||
"private": false
|
"private": false,
|
||||||
|
"is_secret": true
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
---
|
---
|
||||||
|
@ -1189,6 +1203,7 @@ http://localhost:3000/api/projects | jq
|
||||||
|forked_count |int|被fork的数量|
|
|forked_count |int|被fork的数量|
|
||||||
|praises_count |int|star数量|
|
|praises_count |int|star数量|
|
||||||
|is_public |boolean|是否公开, true:公开,false:未公开|
|
|is_public |boolean|是否公开, true:公开,false:未公开|
|
||||||
|
|is_secret |boolean|是否为特殊许可证项目, true:是,false:否|
|
||||||
|mirror_url |string|镜像url|
|
|mirror_url |string|镜像url|
|
||||||
|last_update_time|int|最后更新时间,为UNIX格式的时间戳|
|
|last_update_time|int|最后更新时间,为UNIX格式的时间戳|
|
||||||
|author |object|项目创建者|
|
|author |object|项目创建者|
|
||||||
|
@ -1199,6 +1214,10 @@ http://localhost:3000/api/projects | jq
|
||||||
|language |object|项目语言|
|
|language |object|项目语言|
|
||||||
|-- id |int|项目语言id|
|
|-- id |int|项目语言id|
|
||||||
|-- name |string|项目语言名称|
|
|-- name |string|项目语言名称|
|
||||||
|
|user_apply_signatures |object|用户创建的特殊许可申请|
|
||||||
|
|-- id |int|用户创建的特殊许可申请id|
|
||||||
|
|-- status |int|用户创建的特殊许可申请审核状态, 'unpassed': 审核未通过,'waiting': 等待审核 'passed':审核通过|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
返回值
|
返回值
|
||||||
|
@ -1214,6 +1233,7 @@ http://localhost:3000/api/projects | jq
|
||||||
"praises_count": 0,
|
"praises_count": 0,
|
||||||
"forked_count": 0,
|
"forked_count": 0,
|
||||||
"is_public": true,
|
"is_public": true,
|
||||||
|
"is_secret": true,
|
||||||
"mirror_url": null,
|
"mirror_url": null,
|
||||||
"last_update_time": 1577697461,
|
"last_update_time": 1577697461,
|
||||||
"author": {
|
"author": {
|
||||||
|
@ -1227,7 +1247,13 @@ http://localhost:3000/api/projects | jq
|
||||||
"language": {
|
"language": {
|
||||||
"id": 2,
|
"id": 2,
|
||||||
"name": "C"
|
"name": "C"
|
||||||
|
},
|
||||||
|
"user_apply_signatures":[
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"status": "waiting"
|
||||||
}
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 2,
|
"id": 2,
|
||||||
|
@ -1237,6 +1263,7 @@ http://localhost:3000/api/projects | jq
|
||||||
"praises_count": 0,
|
"praises_count": 0,
|
||||||
"forked_count": 0,
|
"forked_count": 0,
|
||||||
"is_public": true,
|
"is_public": true,
|
||||||
|
"is_secret": false,
|
||||||
"mirror_url": null,
|
"mirror_url": null,
|
||||||
"last_update_time": 1577697403,
|
"last_update_time": 1577697403,
|
||||||
"author": {
|
"author": {
|
||||||
|
@ -1250,7 +1277,8 @@ http://localhost:3000/api/projects | jq
|
||||||
"language": {
|
"language": {
|
||||||
"id": 2,
|
"id": 2,
|
||||||
"name": "C"
|
"name": "C"
|
||||||
}
|
},
|
||||||
|
"user_apply_signatures":[]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 3,
|
"id": 3,
|
||||||
|
@ -1260,6 +1288,7 @@ http://localhost:3000/api/projects | jq
|
||||||
"praises_count": 0,
|
"praises_count": 0,
|
||||||
"forked_count": 0,
|
"forked_count": 0,
|
||||||
"is_public": true,
|
"is_public": true,
|
||||||
|
"is_secret": true,
|
||||||
"mirror_url": null,
|
"mirror_url": null,
|
||||||
"last_update_time": 1577415173,
|
"last_update_time": 1577415173,
|
||||||
"author": {
|
"author": {
|
||||||
|
@ -1273,7 +1302,8 @@ http://localhost:3000/api/projects | jq
|
||||||
"language": {
|
"language": {
|
||||||
"id": 2,
|
"id": 2,
|
||||||
"name": "C"
|
"name": "C"
|
||||||
}
|
},
|
||||||
|
"user_apply_signatures":[]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 5,
|
"id": 5,
|
||||||
|
@ -1283,6 +1313,7 @@ http://localhost:3000/api/projects | jq
|
||||||
"praises_count": 0,
|
"praises_count": 0,
|
||||||
"forked_count": 0,
|
"forked_count": 0,
|
||||||
"is_public": false,
|
"is_public": false,
|
||||||
|
"is_secret": true,
|
||||||
"mirror_url": "https://gitea.com/CasperVector/slew.git",
|
"mirror_url": "https://gitea.com/CasperVector/slew.git",
|
||||||
"last_update_time": 1577346228,
|
"last_update_time": 1577346228,
|
||||||
"author": {
|
"author": {
|
||||||
|
@ -1296,7 +1327,8 @@ http://localhost:3000/api/projects | jq
|
||||||
"language": {
|
"language": {
|
||||||
"id": 2,
|
"id": 2,
|
||||||
"name": "C"
|
"name": "C"
|
||||||
}
|
},
|
||||||
|
"user_apply_signatures":[]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 7,
|
"id": 7,
|
||||||
|
@ -1306,6 +1338,7 @@ http://localhost:3000/api/projects | jq
|
||||||
"praises_count": 0,
|
"praises_count": 0,
|
||||||
"forked_count": 0,
|
"forked_count": 0,
|
||||||
"is_public": true,
|
"is_public": true,
|
||||||
|
"is_secret": true,
|
||||||
"mirror_url": null,
|
"mirror_url": null,
|
||||||
"last_update_time": 1577341572,
|
"last_update_time": 1577341572,
|
||||||
"author": {
|
"author": {
|
||||||
|
@ -1319,7 +1352,8 @@ http://localhost:3000/api/projects | jq
|
||||||
"language": {
|
"language": {
|
||||||
"id": 2,
|
"id": 2,
|
||||||
"name": "C"
|
"name": "C"
|
||||||
}
|
},
|
||||||
|
"user_apply_signatures":[]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -5059,6 +5093,7 @@ http://localhost:3000/api/users/Jason/projects.json | jq
|
||||||
|forked_count |int|被fork的数量|
|
|forked_count |int|被fork的数量|
|
||||||
|praises_count |int|star数量|
|
|praises_count |int|star数量|
|
||||||
|is_public |boolean|是否公开, true:公开,false:未公开|
|
|is_public |boolean|是否公开, true:公开,false:未公开|
|
||||||
|
|is_secret |boolean|是否为特殊许可证项目, true:是,false:否|
|
||||||
|mirror_url |string|镜像url|
|
|mirror_url |string|镜像url|
|
||||||
|last_update_time|int|最后更新时间,为UNIX格式的时间戳|
|
|last_update_time|int|最后更新时间,为UNIX格式的时间戳|
|
||||||
|author |object|项目创建者|
|
|author |object|项目创建者|
|
||||||
|
@ -5069,7 +5104,9 @@ http://localhost:3000/api/users/Jason/projects.json | jq
|
||||||
|language |object|项目语言|
|
|language |object|项目语言|
|
||||||
|-- id |int|项目语言id|
|
|-- id |int|项目语言id|
|
||||||
|-- name |string|项目语言名称|
|
|-- name |string|项目语言名称|
|
||||||
|
|user_apply_signatures |object|用户创建的特殊许可申请|
|
||||||
|
|-- id |int|用户创建的特殊许可申请id|
|
||||||
|
|-- status |int|用户创建的特殊许可申请审核状态, 'unpassed': 审核未通过,'waiting': 等待审核 'passed':审核通过|
|
||||||
|
|
||||||
返回值
|
返回值
|
||||||
```json
|
```json
|
||||||
|
@ -5084,6 +5121,7 @@ http://localhost:3000/api/users/Jason/projects.json | jq
|
||||||
"praises_count": 0,
|
"praises_count": 0,
|
||||||
"forked_count": 0,
|
"forked_count": 0,
|
||||||
"is_public": true,
|
"is_public": true,
|
||||||
|
"is_secret": false,
|
||||||
"mirror_url": null,
|
"mirror_url": null,
|
||||||
"last_update_time": 1577697461,
|
"last_update_time": 1577697461,
|
||||||
"author": {
|
"author": {
|
||||||
|
@ -5097,9 +5135,163 @@ http://localhost:3000/api/users/Jason/projects.json | jq
|
||||||
"language": {
|
"language": {
|
||||||
"id": 2,
|
"id": 2,
|
||||||
"name": "C"
|
"name": "C"
|
||||||
|
},
|
||||||
|
"user_apply_signatures":[
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"status": "waiting"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
---
|
||||||
|
|
||||||
|
#### 特殊许可证项目申请列表
|
||||||
|
```
|
||||||
|
GET /api/apply_signatures
|
||||||
|
```
|
||||||
|
*示例*
|
||||||
|
```bash
|
||||||
|
curl -X GET \
|
||||||
|
-d "project_id=36" \
|
||||||
|
-d "page=1" \
|
||||||
|
-d "limit=5" \
|
||||||
|
-d "search=16895620" \
|
||||||
|
-d "status=waiting" \
|
||||||
|
http://localhost:3000/api/apply_signatures | jq
|
||||||
|
```
|
||||||
|
*请求参数说明:*
|
||||||
|
|
||||||
|
|参数名|必选|类型|说明|
|
||||||
|
|-|-|-|-|
|
||||||
|
|project_id |是|int |项目id |
|
||||||
|
|page |否|string |页数,第几页 |
|
||||||
|
|limit |否|string |每页多少条数据,默认15条 |
|
||||||
|
|search |否|string |用户名、登录名匹配搜索 |
|
||||||
|
|status |否|string |状态匹配搜索,'unpassed': 审核未通过,'waiting': 等待审核 'passed':审核通过 |
|
||||||
|
|
||||||
|
|
||||||
|
*返回参数说明:*
|
||||||
|
|
||||||
|
|参数名|类型|说明|
|
||||||
|
|-|-|-|
|
||||||
|
|total_count |int |返回记录总条数 |
|
||||||
|
|apply_signatures |array|特殊许可证项目申请信息|
|
||||||
|
|-- id |int|特殊许可证项目申请id|
|
||||||
|
|-- status |int|特殊许可证项目申请状态,'unpassed': 审核未通过,'waiting': 等待审核 'passed':审核通过|
|
||||||
|
|user |object|用户|
|
||||||
|
|-- id |int|用户id|
|
||||||
|
|-- name |string|用户名称|
|
||||||
|
|-- login |string|用户登录名/标识|
|
||||||
|
|-- image_url |string|用户头像|
|
||||||
|
|-- email |string|用户邮箱|
|
||||||
|
|-- is_owner |boolean|是否是项目的拥有者,true:是, false:不是|
|
||||||
|
|attachment |object|上传附件|
|
||||||
|
|--filename |string|附件名称|
|
||||||
|
|--path |string|附件地址|
|
||||||
|
|
||||||
|
|
||||||
|
返回值
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"total_count": 1,
|
||||||
|
"apply_signatures": [
|
||||||
|
{
|
||||||
|
"id": 18,
|
||||||
|
"status": "passed",
|
||||||
|
"user": {
|
||||||
|
"id": 3,
|
||||||
|
"name": "16895620",
|
||||||
|
"login": "16895620",
|
||||||
|
"image_url": "avatars/User/boy.jpg",
|
||||||
|
"email": "2456233122@qq.com",
|
||||||
|
"is_owner": false
|
||||||
|
},
|
||||||
|
"attachment": {
|
||||||
|
"filename": "PHengLEI软件开源协议.docx",
|
||||||
|
"path": "/api/attachments/23"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
---
|
---
|
||||||
|
#### 特殊许可证项目用户创建申请
|
||||||
|
```
|
||||||
|
POST /api/apply_signatures
|
||||||
|
```
|
||||||
|
|
||||||
|
*示例*
|
||||||
|
```bash
|
||||||
|
curl -X POST \
|
||||||
|
-d "project_id=8" \
|
||||||
|
-d "attachment_id=4" \
|
||||||
|
http://localhost:3000/api/apply_signatures.json | jq
|
||||||
|
```
|
||||||
|
|
||||||
|
*请求参数说明:*
|
||||||
|
|
||||||
|
|参数名|必选|类型|说明|
|
||||||
|
|-|-|-|-|
|
||||||
|
|project_id |是|int |项目id |
|
||||||
|
|attachment_id |是|int |上传的文件id |
|
||||||
|
|
||||||
|
*返回参数说明:*
|
||||||
|
|
||||||
|
|参数名|类型|说明|
|
||||||
|
|-|-|-|
|
||||||
|
|id |int|特殊许可证项目用户创建申请的id|
|
||||||
|
|attachment |object|上传的文件|
|
||||||
|
|--filename |string|上传的文件的文件名|
|
||||||
|
|
||||||
|
返回值
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": 5,
|
||||||
|
"attachment": {
|
||||||
|
"filename": "timg.jpeg"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
---
|
||||||
|
#### 特殊许可证项目申请修改
|
||||||
|
```
|
||||||
|
PATCH /api/apply_signatures/:id
|
||||||
|
```
|
||||||
|
|
||||||
|
*示例*
|
||||||
|
```bash
|
||||||
|
curl -X POST \
|
||||||
|
-d "id=18" \
|
||||||
|
-d "status=passed" \
|
||||||
|
-d "project_id=36" \
|
||||||
|
http://localhost:3000/api/apply_signatures/18 | jq
|
||||||
|
```
|
||||||
|
|
||||||
|
*请求参数说明:*
|
||||||
|
|
||||||
|
|参数名|必选|类型|说明|
|
||||||
|
|-|-|-|-|
|
||||||
|
|id |是|int |特殊许可证项目申请id |
|
||||||
|
|status |是|string |特殊许可证项目申请状态 ,'unpassed': 审核未通过,'waiting': 等待审核 'passed':审核通过|
|
||||||
|
|project_id |是|int |项目id|
|
||||||
|
|
||||||
|
|
||||||
|
*返回参数说明:*
|
||||||
|
|
||||||
|
|参数名|类型|说明|
|
||||||
|
|-|-|-|
|
||||||
|
|status |int |0:添加成功, -1: 更改失败, 1: 表示已经是该状态了 |
|
||||||
|
|message |string|返回信息说明|
|
||||||
|
|
||||||
|
|
||||||
|
返回值
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": 0,
|
||||||
|
"message": "success"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
---
|
|
@ -14,6 +14,7 @@
|
||||||
//= require bootstrap-datepicker
|
//= require bootstrap-datepicker
|
||||||
//= require bootstrap-datetimepicker
|
//= require bootstrap-datetimepicker
|
||||||
//= require bootstrap.viewer
|
//= require bootstrap.viewer
|
||||||
|
//= require bootstrap/bootstrap-toggle
|
||||||
//= require jquery.mloading
|
//= require jquery.mloading
|
||||||
//= require jquery-confirm.min
|
//= require jquery-confirm.min
|
||||||
//= require common
|
//= require common
|
||||||
|
@ -71,6 +72,23 @@ $(document).on('turbolinks:load', function(){
|
||||||
$('.admin-alert-container .alert.alert-danger').alert('close');
|
$('.admin-alert-container .alert.alert-danger').alert('close');
|
||||||
}, 5000);
|
}, 5000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$('.logo-item-left').on("change", 'input[type="file"]', function () {
|
||||||
|
var $fileInput = $(this);
|
||||||
|
var file = this.files[0];
|
||||||
|
var imageType = /image.*/;
|
||||||
|
if (file && file.type.match(imageType)) {
|
||||||
|
var reader = new FileReader();
|
||||||
|
reader.onload = function () {
|
||||||
|
var $box = $fileInput.parent();
|
||||||
|
$box.find('img').attr('src', reader.result).css('display', 'block');
|
||||||
|
$box.addClass('has-img');
|
||||||
|
};
|
||||||
|
reader.readAsDataURL(file);
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$(document).on("turbolinks:before-cache", function () {
|
$(document).on("turbolinks:before-cache", function () {
|
||||||
|
|
|
@ -6,7 +6,7 @@ $(document).on('turbolinks:load', function(){
|
||||||
});
|
});
|
||||||
|
|
||||||
var sidebarController = $('#sidebar').data('current-controller');
|
var sidebarController = $('#sidebar').data('current-controller');
|
||||||
if (sidebarController.length > 0) {
|
if (sidebarController && sidebarController.length > 0) {
|
||||||
$('#sidebar a.active').removeClass('active');
|
$('#sidebar a.active').removeClass('active');
|
||||||
$('#sidebar ul.collapse.show').removeClass('show');
|
$('#sidebar ul.collapse.show').removeClass('show');
|
||||||
var activeLi = $('#sidebar a[data-controller="' + sidebarController + '"]');
|
var activeLi = $('#sidebar a[data-controller="' + sidebarController + '"]');
|
||||||
|
|
|
@ -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.mloading";
|
||||||
@import "jquery-confirm.min";
|
@import "jquery-confirm.min";
|
||||||
@import "bootstrap-datetimepicker.min";
|
@import "bootstrap-datetimepicker.min";
|
||||||
|
@import "bootstrap/bootstrap-toggle.min";
|
||||||
|
|
||||||
@import "codemirror/lib/codemirror";
|
@import "codemirror/lib/codemirror";
|
||||||
@import "editormd/css/editormd.min";
|
@import "editormd/css/editormd.min";
|
||||||
|
@ -204,3 +205,13 @@ input.form-control {
|
||||||
font-size: 1rem;
|
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,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,7 +1,25 @@
|
||||||
class AccountsController < ApplicationController
|
class AccountsController < ApplicationController
|
||||||
|
before_action :require_login, only: [:login_check, :simple_update]
|
||||||
include ApplicationHelper
|
include ApplicationHelper
|
||||||
|
|
||||||
#skip_before_action :check_account, :only => [:logout]
|
#skip_before_action :check_account, :only => [:logout]
|
||||||
|
skip_before_action :verify_authenticity_token, :only => [:remote_password]
|
||||||
|
|
||||||
|
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?
|
||||||
|
render_ok
|
||||||
|
else
|
||||||
|
render_error(result[:message])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def index
|
def index
|
||||||
render json: session
|
render json: session
|
||||||
|
@ -9,15 +27,53 @@ class AccountsController < ApplicationController
|
||||||
|
|
||||||
# 其他平台同步注册的用户
|
# 其他平台同步注册的用户
|
||||||
def remote_register
|
def remote_register
|
||||||
|
# Register::RemoteForm.new(remote_register_params).validate!
|
||||||
username = params[:username]&.gsub(/\s+/, "")
|
username = params[:username]&.gsub(/\s+/, "")
|
||||||
tip_exception("无法使用以下关键词:#{username},请重新命名") if ReversedKeyword.check_exists?(username)
|
tip_exception("无法使用以下关键词:#{username},请重新命名") if ReversedKeyword.check_exists?(username)
|
||||||
email = params[:email]&.gsub(/\s+/, "")
|
email = params[:email]&.gsub(/\s+/, "")
|
||||||
|
phone = params[:phone]&.gsub(/\s+/, "")
|
||||||
password = params[:password]
|
password = params[:password]
|
||||||
platform = (params[:platform] || 'forge')&.gsub(/\s+/, "")
|
platform = (params[:platform] || 'forge')&.gsub(/\s+/, "")
|
||||||
|
need_send_pwd_sms = false
|
||||||
|
if params[:password].blank?
|
||||||
|
password = SecureRandom.hex(4)
|
||||||
|
need_send_pwd_sms = true
|
||||||
|
end
|
||||||
|
|
||||||
ActiveRecord::Base.transaction do
|
ActiveRecord::Base.transaction do
|
||||||
result = autologin_register(username, email, password, platform)
|
return render_error("该手机号已注册") if phone.present? && User.where(phone: phone).exists?
|
||||||
|
result = autologin_register(username, email, password, platform, phone)
|
||||||
if result[:message].blank?
|
if result[:message].blank?
|
||||||
|
PlatformStatistic.data.increment!(:users_count)
|
||||||
|
Gitlink::Sms.send(mobile: phone, send_type: 'init_password', code: password, user_name: username) if need_send_pwd_sms
|
||||||
|
render_ok({user: result[:user]})
|
||||||
|
else
|
||||||
|
render_error(result[:message])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
rescue Exception => e
|
||||||
|
uid_logger_error(e.message)
|
||||||
|
tip_exception(-1, e.message)
|
||||||
|
end
|
||||||
|
|
||||||
|
# 其他平台同步注册的用户
|
||||||
|
def wx_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+/, "")
|
||||||
|
phone = params[:phone]&.gsub(/\s+/, "")
|
||||||
|
code = params[:code]&.gsub(/\s+/, "")
|
||||||
|
password = SecureRandom.hex(4)
|
||||||
|
platform = (params[:platform] || 'forge')&.gsub(/\s+/, "")
|
||||||
|
check_phone_code(phone, code)
|
||||||
|
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
return render_error("该手机号已注册") if phone.present? && User.where(phone: phone).exists?
|
||||||
|
result = autologin_register(username, email, password, platform, phone)
|
||||||
|
if result[:message].blank?
|
||||||
|
Gitlink::Sms.send(mobile: phone, send_type: 'init_password', code: password, user_name: username)
|
||||||
|
PlatformStatistic.data.increment!(:users_count)
|
||||||
render_ok({user: result[:user]})
|
render_ok({user: result[:user]})
|
||||||
else
|
else
|
||||||
render_error(result[:message])
|
render_error(result[:message])
|
||||||
|
@ -93,7 +149,9 @@ class AccountsController < ApplicationController
|
||||||
|
|
||||||
sync_params = {
|
sync_params = {
|
||||||
password: params[:password].to_s,
|
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)
|
interactor = Gitea::User::UpdateInteractor.call(@user.login, sync_params)
|
||||||
|
@ -121,6 +179,10 @@ class AccountsController < ApplicationController
|
||||||
Register::Form.new(register_params).validate!
|
Register::Form.new(register_params).validate!
|
||||||
|
|
||||||
user = Users::RegisterService.call(register_params)
|
user = Users::RegisterService.call(register_params)
|
||||||
|
user.company_name = params[:company_name] if params[:company_name].present?
|
||||||
|
user.user_type = params[:user_type] if params[:user_type].present?
|
||||||
|
user.professional_field = params[:professional_field] if params[:professional_field].present?
|
||||||
|
user.mail = "#{user.login}@example.org"
|
||||||
password = register_params[:password].strip
|
password = register_params[:password].strip
|
||||||
|
|
||||||
# gitea用户注册, email, username, password
|
# gitea用户注册, email, username, password
|
||||||
|
@ -139,15 +201,17 @@ class AccountsController < ApplicationController
|
||||||
tip_exception(-1, interactor.error)
|
tip_exception(-1, interactor.error)
|
||||||
end
|
end
|
||||||
rescue Register::BaseForm::EmailError => e
|
rescue Register::BaseForm::EmailError => e
|
||||||
render_error(-2, e.message)
|
render_result(-2, e.message)
|
||||||
rescue Register::BaseForm::LoginError => e
|
rescue Register::BaseForm::LoginError => e
|
||||||
render_error(-3, e.message)
|
render_result(-3, e.message)
|
||||||
rescue Register::BaseForm::PhoneError => e
|
rescue Register::BaseForm::PhoneError => e
|
||||||
render_error(-4, e.message)
|
render_result(-4, e.message)
|
||||||
rescue Register::BaseForm::PasswordFormatError => e
|
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
|
rescue Register::BaseForm::VerifiCodeError => e
|
||||||
render_error(-6, e.message)
|
render_result(-6, e.message)
|
||||||
rescue Exception => e
|
rescue Exception => e
|
||||||
Gitea::User::DeleteService.call(user.login) unless user.nil?
|
Gitea::User::DeleteService.call(user.login) unless user.nil?
|
||||||
uid_logger_error(e.message)
|
uid_logger_error(e.message)
|
||||||
|
@ -157,7 +221,7 @@ class AccountsController < ApplicationController
|
||||||
|
|
||||||
# 用户登录
|
# 用户登录
|
||||||
def login
|
def login
|
||||||
Users::LoginForm.new(account_params).validate!
|
#Users::LoginForm.new(account_params).validate!
|
||||||
@user = User.try_to_login(params[:login], params[:password])
|
@user = User.try_to_login(params[:login], params[:password])
|
||||||
|
|
||||||
return normal_status(-2, "错误的账号或密码") if @user.blank?
|
return normal_status(-2, "错误的账号或密码") if @user.blank?
|
||||||
|
@ -179,7 +243,7 @@ class AccountsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
successful_authentication(@user)
|
successful_authentication(@user)
|
||||||
sync_pwd_to_gitea!(@user, {password: params[:password].to_s}) # TODO用户密码未同步
|
sync_pwd_to_gitea!(@user, { password: @user.get_source_password(params[:password].to_s) }) # TODO用户密码未同步
|
||||||
|
|
||||||
# session[:user_id] = @user.id
|
# session[:user_id] = @user.id
|
||||||
end
|
end
|
||||||
|
@ -191,7 +255,9 @@ class AccountsController < ApplicationController
|
||||||
|
|
||||||
sync_params = {
|
sync_params = {
|
||||||
password: params[:password].to_s,
|
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)
|
interactor = Gitea::User::UpdateInteractor.call(@user.login, sync_params)
|
||||||
|
@ -220,7 +286,7 @@ class AccountsController < ApplicationController
|
||||||
end
|
end
|
||||||
return normal_status(-2, "验证码不正确") if verifi_code.try(:code) != code.strip
|
return normal_status(-2, "验证码不正确") if verifi_code.try(:code) != code.strip
|
||||||
return normal_status(-2, "验证码已失效") if !verifi_code&.effective?
|
return normal_status(-2, "验证码已失效") if !verifi_code&.effective?
|
||||||
return normal_status(-1, "8~16位密码,支持字母数字和符号") unless params[:new_password] =~ CustomRegexp::PASSWORD
|
return normal_status(-1, "8~20位密码,支持字母数字和符号") unless params[:new_password] =~ CustomRegexp::PASSWORD
|
||||||
|
|
||||||
user.password, user.password_confirmation = params[:new_password], params[:new_password_confirmation]
|
user.password, user.password_confirmation = params[:new_password], params[:new_password_confirmation]
|
||||||
ActiveRecord::Base.transaction do
|
ActiveRecord::Base.transaction do
|
||||||
|
@ -250,9 +316,7 @@ class AccountsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_autologin_cookie(user)
|
def set_autologin_cookie(user)
|
||||||
token = Token.get_or_create_permanent_login_token(user, "autologin")
|
token = Token.get_or_create_permanent_login_token(user, autologin_action)
|
||||||
sync_user_token_to_trustie(user.login, token.value)
|
|
||||||
|
|
||||||
cookie_options = {
|
cookie_options = {
|
||||||
:value => token.value,
|
:value => token.value,
|
||||||
:expires => 1.month.from_now,
|
:expires => 1.month.from_now,
|
||||||
|
@ -314,8 +378,23 @@ class AccountsController < ApplicationController
|
||||||
render_ok
|
render_ok
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def login_check
|
||||||
|
Register::LoginCheckColumnsForm.new(check_params.merge(user: current_user)).validate!
|
||||||
|
render_ok
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def check_phone_code(phone, code)
|
||||||
|
verifi_code = VerificationCode.where(phone: phone, code: code, code_type: 1).last
|
||||||
|
code = strip(code)
|
||||||
|
return if code == "123123" && EduSetting.get("code_debug") # 万能验证码,用于测试
|
||||||
|
|
||||||
|
raise VerifiCodeError, "验证码不正确" if verifi_code&.code != code
|
||||||
|
raise VerifiCodeError, "验证码已失效" if !verifi_code&.effective?
|
||||||
|
end
|
||||||
|
|
||||||
# type 事件类型 1:用户注册 2:忘记密码 3: 绑定手机 4: 绑定邮箱, 5: 验证手机号是否有效 # 如果有新的继续后面加
|
# type 事件类型 1:用户注册 2:忘记密码 3: 绑定手机 4: 绑定邮箱, 5: 验证手机号是否有效 # 如果有新的继续后面加
|
||||||
# login_type 1:手机类型 2:邮箱类型
|
# login_type 1:手机类型 2:邮箱类型
|
||||||
def verify_type login_type, type
|
def verify_type login_type, type
|
||||||
|
@ -368,4 +447,11 @@ class AccountsController < ApplicationController
|
||||||
params.permit(:login, :namespace, :password, :code)
|
params.permit(:login, :namespace, :password, :code)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def remote_register_params
|
||||||
|
params.permit(:username, :email, :password, :platform)
|
||||||
|
end
|
||||||
|
|
||||||
|
def simple_update_params
|
||||||
|
params.permit(:username, :email, :password, :platform)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
class Admins::ApplySignaturesController < Admins::BaseController
|
||||||
|
|
||||||
|
def index
|
||||||
|
sort_by = params[:sort_by] ||= 'created_on'
|
||||||
|
sort_direction = params[:sort_direction] ||= 'desc'
|
||||||
|
|
||||||
|
@apply_signatures = paginate ApplySignature.waiting.includes(:attachments)
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
begin
|
||||||
|
apply_signature = ApplySignature.find_by!(id: params[:id])
|
||||||
|
apply_signature.update_attributes!(apply_signatures_params)
|
||||||
|
if apply_signature.status == "passed"
|
||||||
|
Projects::AddMemberInteractor.call(apply_signature.project.owner, apply_signature.project, apply_signature.user, "read", true)
|
||||||
|
end
|
||||||
|
redirect_to admins_apply_signatures_path
|
||||||
|
flash[:success] = "更新成功"
|
||||||
|
rescue => e
|
||||||
|
raise ActiveRecord::Rollback
|
||||||
|
redirect_to admins_apply_signatures_path
|
||||||
|
flash[:danger] = "更新失败"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def apply_signatures_params
|
||||||
|
params.permit(:status)
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,10 +1,33 @@
|
||||||
class Admins::DashboardsController < Admins::BaseController
|
class Admins::DashboardsController < Admins::BaseController
|
||||||
def index
|
def index
|
||||||
@active_user_count = User.where(last_login_on: today).count
|
# 用户活跃数
|
||||||
@weekly_active_user_count = User.where(last_login_on: current_week).count
|
day_user_ids = CommitLog.where(created_at: today).pluck(:user_id).uniq
|
||||||
@month_active_user_count = User.where(last_login_on: current_month).count
|
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
|
end
|
||||||
|
|
||||||
def month_active_user
|
def month_active_user
|
||||||
|
@ -42,10 +65,14 @@ class Admins::DashboardsController < Admins::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def current_week
|
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
|
end
|
||||||
|
|
||||||
def current_month
|
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
|
||||||
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
|
def create
|
||||||
return render_error('请上传正确的文件') if params[:file].blank? || !params[:file].is_a?(ActionDispatch::Http::UploadedFile)
|
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)
|
render_ok(result)
|
||||||
rescue Admins::ImportUserService::Error => ex
|
rescue Admins::ImportUserService::Error => ex
|
||||||
render_error(ex)
|
render_error(ex)
|
||||||
|
|
|
@ -2,8 +2,24 @@ class Admins::MessageTemplatesController < Admins::BaseController
|
||||||
before_action :get_template, only: [:edit, :update, :destroy]
|
before_action :get_template, only: [:edit, :update, :destroy]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
message_templates = MessageTemplate.group(:type).count.keys
|
message_templates = MessageTemplate.ransack(sys_notice_or_email_or_email_title_cont: params[:search]).result
|
||||||
@message_templates = kaminari_array_paginate(message_templates)
|
@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
|
end
|
||||||
|
|
||||||
def edit
|
def edit
|
||||||
|
@ -31,7 +47,9 @@ class Admins::MessageTemplatesController < Admins::BaseController
|
||||||
|
|
||||||
private
|
private
|
||||||
def message_template_params
|
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
|
end
|
||||||
|
|
||||||
def get_template
|
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,36 @@
|
||||||
|
class Admins::PhengleiUsersController < Admins::BaseController
|
||||||
|
before_action :phenglei_project, only: [:index]
|
||||||
|
|
||||||
|
def index
|
||||||
|
if params[:keyword].present?
|
||||||
|
@phenglei_users = PhengleiUser.ransack(phone_cont: params[:keyword]).result
|
||||||
|
else
|
||||||
|
@phenglei_users = PhengleiUser
|
||||||
|
end
|
||||||
|
@phenglei_users = @phenglei_users.page(page).per(per_page)
|
||||||
|
end
|
||||||
|
|
||||||
|
def new
|
||||||
|
@phenglei_user = PhengleiUser.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@phenglei_user = PhengleiUser.new(phenglei_user_params)
|
||||||
|
if @phenglei_user.save
|
||||||
|
redirect_to admins_phenglei_users_path
|
||||||
|
flash[:success] = "创建成功"
|
||||||
|
else
|
||||||
|
redirect_to admins_phenglei_users_path
|
||||||
|
flash[:error] = "创建失败"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def phenglei_project
|
||||||
|
@phenglei_project = Project.find_by_id(EduSetting.get("sync_phenglei_user_project"))
|
||||||
|
end
|
||||||
|
|
||||||
|
def phenglei_user_params
|
||||||
|
params.require(:phenglei_user).permit(:phone)
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,97 @@
|
||||||
|
class Admins::PlatformCommunicatesController < Admins::BaseController
|
||||||
|
before_action :get_communicate, only: [:edit, :update, :destroy, :show, :online_switch]
|
||||||
|
|
||||||
|
def index
|
||||||
|
params[:location] = "pc"
|
||||||
|
sort_by = PlatformCommunicate.column_names.include?(params[:sort_by]) ? params[:sort_by] : 'order_index'
|
||||||
|
sort_direction = %w(desc asc).include?(params[:sort_direction]) ? params[:sort_direction] : 'desc'
|
||||||
|
q = PlatformCommunicate.where(location: params[:location]).ransack(title_cont: params[:search])
|
||||||
|
communicates = q.result(distinct: true).order("#{sort_by} #{sort_direction}")
|
||||||
|
@communicates = kaminari_paginate(communicates)
|
||||||
|
end
|
||||||
|
|
||||||
|
def applet
|
||||||
|
params[:location] = "applet"
|
||||||
|
sort_by = PlatformCommunicate.column_names.include?(params[:sort_by]) ? params[:sort_by] : 'order_index'
|
||||||
|
sort_direction = %w(desc asc).include?(params[:sort_direction]) ? params[:sort_direction] : 'desc'
|
||||||
|
q = PlatformCommunicate.where(location: params[:location]).ransack(title_cont: params[:search])
|
||||||
|
communicates = q.result(distinct: true).order("#{sort_by} #{sort_direction}")
|
||||||
|
@communicates = kaminari_paginate(communicates)
|
||||||
|
end
|
||||||
|
|
||||||
|
def show
|
||||||
|
watchers = @communicate.watchers
|
||||||
|
if params[:search].present?
|
||||||
|
like_sql = 'users.lastname LIKE :keyword OR users.nickname LIKE :keyword OR users.mail LIKE :keyword OR users.phone LIKE :keyword OR users.login LIKE :keyword OR users.company_name LIKE :keyword'
|
||||||
|
watchers = watchers.left_joins(:user).where(like_sql, keyword: "%#{params[:search]}%")
|
||||||
|
end
|
||||||
|
if params[:user_type].present?
|
||||||
|
watchers = watchers.left_joins(:user).where("users.user_type = ?", params[:user_type])
|
||||||
|
end
|
||||||
|
if params[:professional_field].present?
|
||||||
|
watchers = watchers.left_joins(:user).where("users.professional_field = ?", params[:professional_field])
|
||||||
|
end
|
||||||
|
@watchers = kaminari_paginate watchers
|
||||||
|
end
|
||||||
|
|
||||||
|
def new
|
||||||
|
location = params[:location] || "pc"
|
||||||
|
@communicate = PlatformCommunicate.new(location: location)
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@communicate = PlatformCommunicate.new(communicate_params)
|
||||||
|
if @communicate.save
|
||||||
|
redirect_to @communicate.location == 'pc' ? "/admins/platform_communicates?location=pc" : "/admins/platform_communicates/applet?location=applet"
|
||||||
|
flash[:success] = '创建成功'
|
||||||
|
else
|
||||||
|
redirect_to @communicate.location == 'pc' ? "/admins/platform_communicates?location=pc" : "/admins/platform_communicates/applet?location=applet"
|
||||||
|
flash[:danger] = "创建失败"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
@communicate.attributes = communicate_params
|
||||||
|
if @communicate.save
|
||||||
|
redirect_to @communicate.location == 'pc' ? "/admins/platform_communicates?location=pc" : "/admins/platform_communicates/applet?location=applet"
|
||||||
|
flash[:success] = '更新成功'
|
||||||
|
else
|
||||||
|
redirect_to @communicate.location == 'pc' ? "/admins/platform_communicates?location=pc" : "/admins/platform_communicates/applet?location=applet"
|
||||||
|
flash[:danger] = '更新失败'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
location = @communicate.location
|
||||||
|
if @communicate.destroy
|
||||||
|
redirect_to location == 'pc' ? "/admins/platform_communicates?location=pc" : "/admins/platform_communicates/applet?location=applet"
|
||||||
|
flash[:success] = '删除成功'
|
||||||
|
else
|
||||||
|
redirect_to location == 'pc' ? "/admins/platform_communicates?location=pc" : "/admins/platform_communicates/applet?location=applet"
|
||||||
|
flash[:danger] = '删除失败'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def online_switch
|
||||||
|
if @communicate.status
|
||||||
|
@communicate.update_attributes!(status: false)
|
||||||
|
else
|
||||||
|
@communicate.update_attributes!(status: true)
|
||||||
|
end
|
||||||
|
# render_ok
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def get_communicate
|
||||||
|
@communicate = PlatformCommunicate.find_by_id(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def communicate_params
|
||||||
|
params.require(:platform_communicate).permit!
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,69 @@
|
||||||
|
class Admins::PlatformPeopleController < Admins::BaseController
|
||||||
|
before_action :get_person, only: [:edit, :update, :destroy]
|
||||||
|
def index
|
||||||
|
sort_by = PlatformPerson.column_names.include?(params[:sort_by]) ? params[:sort_by] : 'created_at'
|
||||||
|
sort_direction = %w(desc asc).include?(params[:sort_direction]) ? params[:sort_direction] : 'desc'
|
||||||
|
q = PlatformPerson.ransack(name_cont: params[:search])
|
||||||
|
people = q.result(distinct: true).order("#{sort_by} #{sort_direction}")
|
||||||
|
@people = kaminari_paginate(people)
|
||||||
|
end
|
||||||
|
|
||||||
|
def new
|
||||||
|
@person = PlatformPerson.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@person = PlatformPerson.new(person_params)
|
||||||
|
if @person.save
|
||||||
|
save_image_file(params[:image], @person)
|
||||||
|
redirect_to admins_platform_people_path
|
||||||
|
flash[:success] = '创建论坛交流人物成功'
|
||||||
|
else
|
||||||
|
redirect_to admins_platform_people_path
|
||||||
|
flash[:danger] = "创建论坛交流人物失败"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
@person.attributes = person_params
|
||||||
|
if @person.save
|
||||||
|
save_image_file(params[:image], @person)
|
||||||
|
redirect_to admins_platform_people_path
|
||||||
|
flash[:success] = '更新论坛交流人物成功'
|
||||||
|
else
|
||||||
|
redirect_to admins_platform_people_path
|
||||||
|
flash[:danger] = '更新论坛交流人物失败'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
if @person.destroy
|
||||||
|
redirect_to admins_platform_people_path
|
||||||
|
flash[:success] = '删除论坛交流人物成功'
|
||||||
|
else
|
||||||
|
redirect_to admins_platform_people_path
|
||||||
|
flash[:danger] = '删除论坛交流人物失败'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def get_person
|
||||||
|
@person = PlatformPerson.find_by_id(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def person_params
|
||||||
|
params.require(:platform_person).permit!
|
||||||
|
end
|
||||||
|
|
||||||
|
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
|
|
@ -5,7 +5,7 @@ class Admins::ProjectCategoriesController < Admins::BaseController
|
||||||
def index
|
def index
|
||||||
sort_by = ProjectCategory.column_names.include?(params[:sort_by]) ? params[:sort_by] : 'created_at'
|
sort_by = ProjectCategory.column_names.include?(params[:sort_by]) ? params[:sort_by] : 'created_at'
|
||||||
sort_direction = %w(desc asc).include?(params[:sort_direction]) ? params[:sort_direction] : 'desc'
|
sort_direction = %w(desc asc).include?(params[:sort_direction]) ? params[:sort_direction] : 'desc'
|
||||||
q = ProjectCategory.ransack(name_cont: params[:name])
|
q = ProjectCategory.ransack(name_cont: params[:search])
|
||||||
project_categories = q.result(distinct: true).order("#{sort_by} #{sort_direction}")
|
project_categories = q.result(distinct: true).order("#{sort_by} #{sort_direction}")
|
||||||
@project_categories = paginate(project_categories)
|
@project_categories = paginate(project_categories)
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
class Admins::ProjectIgnoresController < Admins::BaseController
|
class Admins::ProjectIgnoresController < Admins::BaseController
|
||||||
before_action :set_ignore, only: [:edit,:update, :destroy,:show]
|
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
|
def index
|
||||||
sort_by = Ignore.column_names.include?(params[:sort_by]) ? params[:sort_by] : 'created_at'
|
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)
|
@project_ignore = Ignore.new(ignore_params)
|
||||||
|
|
||||||
if @project_ignore.save!
|
if @project_ignore.save
|
||||||
redirect_to admins_project_ignores_path
|
redirect_to admins_project_ignores_path
|
||||||
flash[:success] = "创建成功"
|
flash[:success] = "创建成功"
|
||||||
else
|
else
|
||||||
render :new
|
redirect_to admins_project_ignores_path
|
||||||
flash[:danger] = "创建失败"
|
flash[:danger] = @project_ignore.errors.full_messages.join(",")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -58,8 +58,8 @@ class Admins::ProjectIgnoresController < Admins::BaseController
|
||||||
redirect_to admins_project_ignores_path
|
redirect_to admins_project_ignores_path
|
||||||
flash[:success] = "更新成功"
|
flash[:success] = "更新成功"
|
||||||
else
|
else
|
||||||
render :edit
|
redirect_to admins_project_ignores_path
|
||||||
flash[:danger] = "更新失败"
|
flash[:danger] = @project_ignore.errors.full_messages.join(",")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -98,23 +98,23 @@ class Admins::ProjectIgnoresController < Admins::BaseController
|
||||||
params.require(:ignore).permit(:name,:content)
|
params.require(:ignore).permit(:name,:content)
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_params
|
# def validate_params
|
||||||
name = params[:ignore][:name]
|
# name = params[:ignore][:name]
|
||||||
if name.blank?
|
# if name.blank?
|
||||||
flash[:danger] = "名称不允许为空"
|
# flash[:danger] = "名称不允许为空"
|
||||||
redirect_to admins_project_ignores_path
|
# redirect_to admins_project_ignores_path
|
||||||
elsif check_ignore_present?(name) && @project_ignore.blank?
|
# elsif check_ignore_present?(name) && @project_ignore.blank?
|
||||||
flash[:danger] = "创建失败:名称已存在"
|
# flash[:danger] = "创建失败:名称已存在"
|
||||||
redirect_to admins_project_ignores_path
|
# redirect_to admins_project_ignores_path
|
||||||
end
|
# end
|
||||||
end
|
# end
|
||||||
|
|
||||||
def check_ignore_present?(name)
|
# def check_ignore_present?(name)
|
||||||
return true if name.blank?
|
# return true if name.blank?
|
||||||
name_downcase = name.downcase
|
# name_downcase = name.downcase
|
||||||
name_upcase = name.upcase
|
# name_upcase = name.upcase
|
||||||
name_first_big = name.capitalize
|
# name_first_big = name.capitalize
|
||||||
Ignore.exists?(name: name_downcase) || Ignore.exists?(name: name_upcase) || Ignore.exists?(name: name_first_big)
|
# Ignore.exists?(name: name_downcase) || Ignore.exists?(name: name_upcase) || Ignore.exists?(name: name_first_big)
|
||||||
end
|
# end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -27,17 +27,18 @@ class Admins::ProjectLanguagesController < Admins::BaseController
|
||||||
flash[:success] = '创建成功'
|
flash[:success] = '创建成功'
|
||||||
else
|
else
|
||||||
redirect_to admins_project_languages_path
|
redirect_to admins_project_languages_path
|
||||||
flash[:danger] = '创建失败'
|
flash[:danger] = @project_language.errors.full_messages.join(",")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
if @project_language.update_attribute(:name, @name)
|
@project_language.attributes = {name: @name}
|
||||||
|
if @project_language.save
|
||||||
redirect_to admins_project_languages_path
|
redirect_to admins_project_languages_path
|
||||||
flash[:success] = '更新成功'
|
flash[:success] = '更新成功'
|
||||||
else
|
else
|
||||||
redirect_to admins_project_languages_path
|
redirect_to admins_project_languages_path
|
||||||
flash[:success] = '更新失败'
|
flash[:danger] = @project_language.errors.full_messages.join(",")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
class Admins::ProjectLicensesController < Admins::BaseController
|
class Admins::ProjectLicensesController < Admins::BaseController
|
||||||
before_action :set_license, only: [:edit,:update, :destroy,:show]
|
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
|
def index
|
||||||
sort_by = License.column_names.include?(params[:sort_by]) ? params[:sort_by] : 'created_at'
|
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
|
# position: max_position
|
||||||
# }
|
# }
|
||||||
@project_license = License.new(license_params)
|
@project_license = License.new(license_params)
|
||||||
|
if @project_license.save
|
||||||
if @project_license.save!
|
|
||||||
redirect_to admins_project_licenses_path
|
redirect_to admins_project_licenses_path
|
||||||
flash[:success] = "创建成功"
|
flash[:success] = "创建成功"
|
||||||
else
|
else
|
||||||
render :new
|
redirect_to admins_project_licenses_path
|
||||||
flash[:danger] = "创建失败"
|
flash[:danger] = @project_license.errors.full_messages.join(",")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -54,12 +53,13 @@ class Admins::ProjectLicensesController < Admins::BaseController
|
||||||
# permissions: permissions.to_s,
|
# permissions: permissions.to_s,
|
||||||
# limitations: limitations.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
|
redirect_to admins_project_licenses_path
|
||||||
flash[:success] = "更新成功"
|
flash[:success] = "更新成功"
|
||||||
else
|
else
|
||||||
render :edit
|
render admins_project_licenses_path
|
||||||
flash[:danger] = "更新失败"
|
flash[:danger] = @project_license.errors.full_messages.join(",")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -98,23 +98,23 @@ class Admins::ProjectLicensesController < Admins::BaseController
|
||||||
params.require(:license).permit(:name,:content)
|
params.require(:license).permit(:name,:content)
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_params
|
# def validate_params
|
||||||
name = params[:license][:name]
|
# name = params[:license][:name]
|
||||||
if name.blank?
|
# if name.blank?
|
||||||
flash[:danger] = "名称不允许为空"
|
# flash[:danger] = "名称不允许为空"
|
||||||
redirect_to admins_project_licenses_path
|
# redirect_to admins_project_licenses_path
|
||||||
elsif check_license_present?(name) && @project_license.blank?
|
# elsif check_license_present?(name) && @project_license.blank?
|
||||||
flash[:danger] = "创建失败:名称已存在"
|
# flash[:danger] = "创建失败:名称已存在"
|
||||||
redirect_to admins_project_licenses_path
|
# redirect_to admins_project_licenses_path
|
||||||
end
|
# end
|
||||||
end
|
# end
|
||||||
|
|
||||||
def check_license_present?(name)
|
# def check_license_present?(name)
|
||||||
return true if name.blank?
|
# return true if name.blank?
|
||||||
name_downcase = name.downcase
|
# name_downcase = name.downcase
|
||||||
name_upcase = name.upcase
|
# name_upcase = name.upcase
|
||||||
name_first_big = name.capitalize
|
# name_first_big = name.capitalize
|
||||||
License.exists?(name: name_downcase) || License.exists?(name: name_upcase) || License.exists?(name: name_first_big)
|
# License.exists?(name: name_downcase) || License.exists?(name: name_upcase) || License.exists?(name: name_first_big)
|
||||||
end
|
# end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
class Admins::ProjectsController < Admins::BaseController
|
class Admins::ProjectsController < Admins::BaseController
|
||||||
before_action :find_project, only: [:edit, :update]
|
before_action :find_project, only: [:edit, :update, :sync_phenglei_user]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
sort_by = Project.column_names.include?(params[:sort_by]) ? params[:sort_by] : 'created_on'
|
sort_by = Project.column_names.include?(params[:sort_by]) ? params[:sort_by] : 'created_on'
|
||||||
sort_direction = %w(desc asc).include?(params[:sort_direction]) ? params[:sort_direction] : 'desc'
|
sort_direction = %w(desc asc).include?(params[:sort_direction]) ? params[:sort_direction] : 'desc'
|
||||||
search = params[:search].to_s.strip
|
search = params[:search].to_s.strip
|
||||||
projects = Project.where("name like ?", "%#{search}%").order("#{sort_by} #{sort_direction}")
|
projects = Project.where("name like ?", "%#{search}%").order("#{sort_by} #{sort_direction}")
|
||||||
@projects = paginate projects.includes(:owner, :members, :issues, :versions, :attachments, :project_score)
|
@projects = paginate projects.includes(:owner, :members, :issues, :versions, :attachments, :project_score, :license)
|
||||||
end
|
end
|
||||||
|
|
||||||
def edit ;end
|
def edit ;end
|
||||||
|
@ -43,6 +43,28 @@ class Admins::ProjectsController < Admins::BaseController
|
||||||
flash[:danger] = "删除失败"
|
flash[:danger] = "删除失败"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def export
|
||||||
|
sort_by = Project.column_names.include?(params[:sort_by]) ? params[:sort_by] : 'created_on'
|
||||||
|
sort_direction = %w(desc asc).include?(params[:sort_direction]) ? params[:sort_direction] : 'desc'
|
||||||
|
search = params[:search].to_s.strip
|
||||||
|
projects = Project.where("name like ?", "%#{search}%").order("#{sort_by} #{sort_direction}")
|
||||||
|
@projects = projects.includes(:owner, :members, :issues, :versions, :attachments, :project_score, :license)
|
||||||
|
filename = ["项目列表", Time.zone.now.strftime('%Y%m%d%H%M%S')].join('-') << '.xlsx'
|
||||||
|
@domain_url = EduSetting.get('host_name')
|
||||||
|
render xlsx: 'export', filename: filename
|
||||||
|
end
|
||||||
|
|
||||||
|
def sync_phenglei_user
|
||||||
|
if @project.is_secret
|
||||||
|
SyncPhengleiUserJob.perform_later(@project.id)
|
||||||
|
redirect_to admins_phenglei_users_path
|
||||||
|
flash[:success] = "已开启后台同步任务"
|
||||||
|
else
|
||||||
|
redirect_to admins_phenglei_users_path
|
||||||
|
flash[:danger] = "非风雷协议项目"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
def find_project
|
def find_project
|
||||||
@project = Project.find_by_id(params[:id])
|
@project = Project.find_by_id(params[:id])
|
||||||
|
|
|
@ -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,60 @@
|
||||||
|
class Admins::Topic::AppletBannersController < Admins::Topic::BaseController
|
||||||
|
before_action :find_banner, only: [:edit, :update, :destroy]
|
||||||
|
|
||||||
|
def index
|
||||||
|
@banners = ::Topic::AppletBanner
|
||||||
|
@banners = @banners.where("title like ?", "%#{params[:search]}%") if params[:search].present?
|
||||||
|
@banners = @banners.where(location: params[:location]) if params[:location].present?
|
||||||
|
@banners = paginate(@banners)
|
||||||
|
end
|
||||||
|
|
||||||
|
def new
|
||||||
|
@banner = ::Topic::AppletBanner.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@banner = ::Topic::AppletBanner.new(banner_params)
|
||||||
|
if @banner.save
|
||||||
|
save_image_file(params[:image], @banner)
|
||||||
|
redirect_to admins_topic_applet_banners_path
|
||||||
|
flash[:success] = "新增banner成功"
|
||||||
|
else
|
||||||
|
redirect_to admins_topic_applet_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_applet_banners_path
|
||||||
|
flash[:success] = "更新banner成功"
|
||||||
|
else
|
||||||
|
redirect_to admins_topic_applet_banners_path
|
||||||
|
flash[:danger] = "更新banner失败"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
if @banner.destroy
|
||||||
|
redirect_to admins_topic_applet_banners_path
|
||||||
|
flash[:success] = "删除banner成功"
|
||||||
|
else
|
||||||
|
redirect_to admins_topic_applet_banners_path
|
||||||
|
flash[:danger] = "删除banner失败"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def find_banner
|
||||||
|
@banner = ::Topic::AppletBanner.find_by_id(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def banner_params
|
||||||
|
params.require(:topic_applet_banner).permit(:title, :order_index, :url, :location)
|
||||||
|
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
|
|
@ -1,5 +1,5 @@
|
||||||
class Admins::UsersController < Admins::BaseController
|
class Admins::UsersController < Admins::BaseController
|
||||||
before_action :finder_user, except: [:index]
|
before_action :finder_user, except: [:index, :export]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
params[:sort_by] = params[:sort_by].presence || 'created_on'
|
params[:sort_by] = params[:sort_by].presence || 'created_on'
|
||||||
|
@ -24,6 +24,16 @@ class Admins::UsersController < Admins::BaseController
|
||||||
render 'edit'
|
render 'edit'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def export
|
||||||
|
params[:sort_by] = params[:sort_by].presence || 'created_on'
|
||||||
|
params[:sort_direction] = params[:sort_direction].presence || 'desc'
|
||||||
|
|
||||||
|
users = Admins::UserQuery.call(params)
|
||||||
|
@users = users.includes(:user_extension, projects: :members)
|
||||||
|
filename = ["用户列表", Time.zone.now.strftime('%Y%m%d%H%M%S')].join('-') << '.xlsx'
|
||||||
|
render xlsx: 'export', filename: filename
|
||||||
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
@user.destroy!
|
@user.destroy!
|
||||||
Gitea::User::DeleteService.call(@user.login)
|
Gitea::User::DeleteService.call(@user.login)
|
||||||
|
@ -57,7 +67,50 @@ class Admins::UsersController < Admins::BaseController
|
||||||
render_ok
|
render_ok
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def new
|
||||||
|
@user = User.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
Users::AdminCreateUserForm.new(validate_create_params).validate!
|
||||||
|
|
||||||
|
user = User.new(create_params)
|
||||||
|
login = User.generate_login("p")
|
||||||
|
|
||||||
|
user.type = 'User'
|
||||||
|
user.login = login
|
||||||
|
user.mail = "#{login}@example.org"
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
if user.save!
|
||||||
|
UserExtension.create!(user_id: user.id)
|
||||||
|
interactor = Gitea::RegisterInteractor.call({username: user.login, email: user.mail, password: create_params[:password]})
|
||||||
|
if interactor.success?
|
||||||
|
gitea_user = interactor.result
|
||||||
|
result = Gitea::User::GenerateTokenService.call(user.login, create_params[:password])
|
||||||
|
user.gitea_token = result['sha1']
|
||||||
|
user.gitea_uid = gitea_user[:body]['id']
|
||||||
|
user.save!
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
flash[:success] = '保存成功'
|
||||||
|
redirect_to admins_users_path
|
||||||
|
rescue ActiveRecord::RecordInvalid => e
|
||||||
|
logger.info "------------ #{e.message}"
|
||||||
|
puts e.message
|
||||||
|
flash.now[:danger] = e.message
|
||||||
|
render 'new'
|
||||||
|
rescue Exception => ex
|
||||||
|
flash.now[:danger] = ex.message
|
||||||
|
render 'new'
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
def finder_user
|
||||||
|
@user = User.find(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
def finder_user
|
def finder_user
|
||||||
@user = User.find(params[:id])
|
@user = User.find(params[:id])
|
||||||
|
@ -66,6 +119,14 @@ class Admins::UsersController < Admins::BaseController
|
||||||
def update_params
|
def update_params
|
||||||
params.require(:user).permit(%i[lastname nickname gender identity technical_title student_id is_shixun_marker
|
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
|
mail phone location location_city school_id department_id admin business is_test
|
||||||
password professional_certification authentication login])
|
password professional_certification authentication login bank_certification enterprise_certification])
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_params
|
||||||
|
params.require(:user).permit(%i[nickname gender mail phone location location_city password professional_certification])
|
||||||
|
end
|
||||||
|
|
||||||
|
def validate_create_params
|
||||||
|
create_params.slice(:phone, :password)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
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 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
|
||||||
|
puts !current_user.admin? && !@project.operator?(current_user) && !(@project.fork_project.present? && @project.fork_project.operator?(current_user))
|
||||||
|
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,18 @@
|
||||||
|
class Api::V1::Projects::BranchesController < Api::V1::BaseController
|
||||||
|
before_action :require_public_and_member_above, only: [:all]
|
||||||
|
|
||||||
|
def all
|
||||||
|
@result_object = Api::V1::Projects::Branches::AllListService.call(@project, current_user&.gitea_token)
|
||||||
|
end
|
||||||
|
|
||||||
|
before_action :require_operate_above, only: [:create]
|
||||||
|
|
||||||
|
def create
|
||||||
|
@result_object = Api::V1::Projects::Branches::CreateService.call(@project, branch_params, current_user&.gitea_token)
|
||||||
|
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,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,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,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,81 @@
|
||||||
|
class Api::V1::UsersController < Api::V1::BaseController
|
||||||
|
|
||||||
|
before_action :load_observe_user
|
||||||
|
before_action :check_auth_for_observe_user
|
||||||
|
|
||||||
|
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]
|
||||||
|
|
||||||
|
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 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
|
||||||
|
end
|
|
@ -125,7 +125,7 @@ class ApplicationController < ActionController::Base
|
||||||
tip_exception(-2,"邮件发送失败,请稍后重试")
|
tip_exception(-2,"邮件发送失败,请稍后重试")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
ver_params = {code_type: send_type, code: code}.merge(sigle_para)
|
ver_params = { code_type: send_type, code: code, status: 1 }.merge(sigle_para)
|
||||||
VerificationCode.create!(ver_params)
|
VerificationCode.create!(ver_params)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -174,11 +174,11 @@ class ApplicationController < ActionController::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def require_profile_completed
|
def require_profile_completed
|
||||||
tip_exception(411, "请完善资料后再操作") unless User.current.profile_is_completed?
|
# tip_exception(411, "请完善资料后再操作") unless User.current.profile_is_completed?
|
||||||
end
|
end
|
||||||
|
|
||||||
def require_user_profile_completed(user)
|
def require_user_profile_completed(user)
|
||||||
tip_exception(412, "请用户完善资料后再操作") unless user.profile_is_completed?
|
# tip_exception(412, "请用户完善资料后再操作") unless user.profile_is_completed?
|
||||||
end
|
end
|
||||||
|
|
||||||
# 异常提醒
|
# 异常提醒
|
||||||
|
@ -248,6 +248,18 @@ class ApplicationController < ActionController::Base
|
||||||
#return if params[:controller] == "main"
|
#return if params[:controller] == "main"
|
||||||
# Find the current user
|
# Find the current user
|
||||||
#Rails.logger.info("current_laboratory is #{current_laboratory} domain is #{request.subdomain}")
|
#Rails.logger.info("current_laboratory is #{current_laboratory} domain is #{request.subdomain}")
|
||||||
|
if request.headers["Authorization"].present? && request.headers["Authorization"].start_with?('Bearer')
|
||||||
|
tip_exception(401, "请登录后再操作!") unless valid_doorkeeper_token?
|
||||||
|
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
|
||||||
|
else
|
||||||
User.current = find_current_user
|
User.current = find_current_user
|
||||||
uid_logger("user_setup: " + (User.current.logged? ? "#{User.current.try(:login)} (id=#{User.current.try(:id)})" : "anonymous"))
|
uid_logger("user_setup: " + (User.current.logged? ? "#{User.current.try(:login)} (id=#{User.current.try(:id)})" : "anonymous"))
|
||||||
|
|
||||||
|
@ -264,26 +276,27 @@ class ApplicationController < ActionController::Base
|
||||||
User.current = user
|
User.current = user
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# if !User.current.logged? && Rails.env.development?
|
if !User.current.logged? && Rails.env.development?
|
||||||
# User.current = User.find 1
|
User.current = User.find 1
|
||||||
# end
|
end
|
||||||
|
|
||||||
|
|
||||||
# 测试版前端需求
|
# 测试版前端需求
|
||||||
logger.info("subdomain:#{request.subdomain}")
|
logger.info("subdomain:#{request.subdomain}")
|
||||||
# if request.subdomain != "www"
|
if request.subdomain != "www"
|
||||||
# if params[:debug] == 'teacher' #todo 为了测试,记得讲debug删除
|
if params[:debug] == 'teacher' #todo 为了测试,记得讲debug删除
|
||||||
# User.current = User.find 81403
|
User.current = User.find 6
|
||||||
# elsif params[:debug] == 'student'
|
elsif params[:debug] == 'student'
|
||||||
# User.current = User.find 8686
|
User.current = User.find 7
|
||||||
# elsif params[:debug] == 'admin'
|
elsif params[:debug] == 'admin'
|
||||||
# logger.info "@@@@@@@@@@@@@@@@@@@@@@ debug mode....."
|
logger.info "@@@@@@@@@@@@@@@@@@@@@@ debug mode....."
|
||||||
# user = User.find 36480
|
user = User.find 1
|
||||||
# User.current = user
|
User.current = user
|
||||||
# cookies.signed[:user_id] = user.id
|
cookies.signed[:user_id] = user.id
|
||||||
# end
|
end
|
||||||
# end
|
end
|
||||||
# User.current = User.find 81403
|
# User.current = User.find 81403
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -309,9 +322,11 @@ class ApplicationController < ActionController::Base
|
||||||
# auto-login feature starts a new session
|
# auto-login feature starts a new session
|
||||||
user = nil
|
user = nil
|
||||||
Rails.logger.info("111111111111111111#{default_yun_session}, session is #{session[:"#{default_yun_session}"]} ")
|
Rails.logger.info("111111111111111111#{default_yun_session}, session is #{session[:"#{default_yun_session}"]} ")
|
||||||
user = User.try_to_autologin(cookies[autologin_cookie_name])
|
user = User.try_to_autologin(cookies[autologin_cookie_name], autologin_action)
|
||||||
# start_user_session(user) if user # TODO 解决sso退出不同步的问题
|
# start_user_session(user) if user # TODO 解决sso退出不同步的问题
|
||||||
user
|
user
|
||||||
|
elsif params[:token].present?
|
||||||
|
User.try_to_autologin(params[:token], autologin_action)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -686,18 +701,24 @@ class ApplicationController < ActionController::Base
|
||||||
|
|
||||||
@project, @owner = Project.find_with_namespace(namespace, id)
|
@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"
|
logger.info "###########: has project and can read project"
|
||||||
@project
|
@project
|
||||||
# elsif @project && current_user.is_a?(AnonymousUser)
|
# elsif @project && current_user.is_a?(AnonymousUser)
|
||||||
# logger.info "###########:This is AnonymousUser"
|
# logger.info "###########:This is AnonymousUser"
|
||||||
# @project = nil if !@project.is_public?
|
# @project = nil if !@project.is_public?
|
||||||
# render_forbidden and return
|
# 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
|
else
|
||||||
logger.info "###########:project not found"
|
logger.info "###########:project not found"
|
||||||
@project = nil
|
@project = nil
|
||||||
render_not_found and return
|
render_not_found and return
|
||||||
end
|
end
|
||||||
|
end
|
||||||
@project
|
@project
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -709,14 +730,20 @@ class ApplicationController < ActionController::Base
|
||||||
Rails.application.config_for(:configuration)['platform_url'] || request.base_url
|
Rails.application.config_for(:configuration)['platform_url'] || request.base_url
|
||||||
end
|
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!
|
def convert_image!
|
||||||
@image = params[:image]
|
@image = params[:image]
|
||||||
@image = @image.nil? && params[:user].present? ? params[:user][:image] : @image
|
@image = @image.nil? && params[:user].present? ? params[:user][:image] : @image
|
||||||
return unless @image.present?
|
return unless @image.present?
|
||||||
max_size = EduSetting.get('upload_avatar_max_size') || 2 * 1024 * 1024 # 2M
|
max_size = EduSetting.get('upload_avatar_max_size') || 2 * 1024 * 1024 # 2M
|
||||||
if @image.class == ActionDispatch::Http::UploadedFile
|
if @image.class == ActionDispatch::Http::UploadedFile
|
||||||
render_error('请上传文件') if @image.size.zero?
|
return render_error('请上传文件') if @image.size.zero?
|
||||||
render_error('文件大小超过限制') if @image.size > max_size.to_i
|
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
|
else
|
||||||
image = @image.to_s.strip
|
image = @image.to_s.strip
|
||||||
return render_error('请上传正确的图片') if image.blank?
|
return render_error('请上传正确的图片') if image.blank?
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
class ApplySignaturesController < ApplicationController
|
||||||
|
include ApplicationHelper
|
||||||
|
before_action :find_project, only: [:index, :create, :update]
|
||||||
|
before_action :require_owner, only: [:update]
|
||||||
|
before_action :find_apply_signature, only: [:update]
|
||||||
|
|
||||||
|
def index
|
||||||
|
search = params[:search].to_s.downcase
|
||||||
|
@apply_signatures = @project.apply_signatures.with_status(status).includes(user: :user_extension)
|
||||||
|
@apply_signatures = @apply_signatures.joins(:user).where("LOWER(CONCAT_WS(users.lastname, users.firstname, users.login, users.mail, users.nickname)) LIKE ?", "%#{search.split(" ").join('|')}%") if search.present?
|
||||||
|
@apply_signatures = kaminari_paginate(@apply_signatures)
|
||||||
|
end
|
||||||
|
|
||||||
|
def template_file
|
||||||
|
license = License.find_by_name("PHengLEI")
|
||||||
|
file = license.attachments.take
|
||||||
|
normal_status(-1, "文件不存在") if file.blank?
|
||||||
|
send_file(absolute_path(local_path(file)), filename: file.title,stream:false, type: file.content_type.presence || 'application/octet-stream')
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
tip_exception "您已上传开源许可协议" if current_user.apply_signatures.where(project_id: params[:project_id]).where(status: ['waiting', 'passed']).present?
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
begin
|
||||||
|
@signature = current_user.apply_signatures.find_or_create_by!(project_id: params[:project_id])
|
||||||
|
@signature.status = 0
|
||||||
|
@signature.attachments = Attachment.none
|
||||||
|
@attachment = Attachment.find_by_id(params[:attachment_id])
|
||||||
|
@attachment.container = @signature
|
||||||
|
@signature.save!
|
||||||
|
@attachment.save!
|
||||||
|
rescue Exception => e
|
||||||
|
tip_exception("#{e}")
|
||||||
|
raise ActiveRecord::Rollback
|
||||||
|
end
|
||||||
|
render_json
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
@apply_signature.update_attributes!(apply_signature_params)
|
||||||
|
if @apply_signature.status == "passed"
|
||||||
|
Projects::AddMemberInteractor.call(@apply_signature.project.owner, @apply_signature.project, @apply_signature.user, "read", true)
|
||||||
|
else
|
||||||
|
Projects::DeleteMemberInteractor.call(@apply_signature.project.owner, @apply_signature.project, @apply_signature.user)
|
||||||
|
end
|
||||||
|
render_ok
|
||||||
|
rescue Exception => e
|
||||||
|
uid_logger_error(e.message)
|
||||||
|
tip_exception(e.message)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def find_project
|
||||||
|
@project = Project.find_by_id(params[:project_id])
|
||||||
|
normal_status(-1, "项目不存在") unless @project.present?
|
||||||
|
end
|
||||||
|
|
||||||
|
def find_apply_signature
|
||||||
|
@apply_signature = ApplySignature.find_by_id(params[:id])
|
||||||
|
normal_status(-1, "特殊许可申请不存在") unless @apply_signature.present?
|
||||||
|
normal_status(1, "已经是该状态了") if @apply_signature.status == params[:status]
|
||||||
|
end
|
||||||
|
|
||||||
|
def apply_signature_params
|
||||||
|
params.permit(:status)
|
||||||
|
end
|
||||||
|
|
||||||
|
def status
|
||||||
|
params.fetch(:status, "all")
|
||||||
|
end
|
||||||
|
|
||||||
|
def require_owner
|
||||||
|
normal_status(403, "") unless @project.owner?(current_user) || current_user.admin?
|
||||||
|
end
|
||||||
|
end
|
|
@ -31,11 +31,11 @@ class AttachmentsController < ApplicationController
|
||||||
|
|
||||||
def get_file
|
def get_file
|
||||||
normal_status(-1, "参数缺失") if params[:download_url].blank?
|
normal_status(-1, "参数缺失") if params[:download_url].blank?
|
||||||
url = URI.encode(params[:download_url].to_s.gsub("http:", "https:"))
|
url = base_url.starts_with?("https:") ? URI.encode(params[:download_url].to_s.gsub("http:", "https:")) : URI.encode(params[:download_url].to_s)
|
||||||
if url.starts_with?(base_url)
|
if url.starts_with?(base_url) && !url.starts_with?("#{base_url}/repo")
|
||||||
domain = Gitea.gitea_config[:domain]
|
domain = GiteaService.gitea_config[:domain]
|
||||||
api_url = Gitea.gitea_config[:base_url]
|
api_url = GiteaService.gitea_config[:base_url]
|
||||||
url = url.split(base_url)[1].gsub("api", "repos").gsub('?filepath=', '/').gsub('&', '?')
|
url = ("/repos"+url.split(base_url + "/api")[1]).gsub('?filepath=', '/').gsub('&', '?')
|
||||||
request_url = [domain, api_url, url, "?ref=#{params[:ref]}&access_token=#{current_user&.gitea_token}"].join
|
request_url = [domain, api_url, url, "?ref=#{params[:ref]}&access_token=#{current_user&.gitea_token}"].join
|
||||||
response = Faraday.get(request_url)
|
response = Faraday.get(request_url)
|
||||||
filename = url.to_s.split("/").pop()
|
filename = url.to_s.split("/").pop()
|
||||||
|
@ -213,20 +213,17 @@ class AttachmentsController < ApplicationController
|
||||||
def attachment_candown
|
def attachment_candown
|
||||||
unless current_user.admin? || current_user.business?
|
unless current_user.admin? || current_user.business?
|
||||||
candown = true
|
candown = true
|
||||||
unless params[:type] == 'history'
|
if @file.container
|
||||||
if @file.container && current_user.logged?
|
|
||||||
if @file.container.is_a?(Issue)
|
if @file.container.is_a?(Issue)
|
||||||
course = @file.container.project
|
project = @file.container.project
|
||||||
candown = course.member?(current_user)
|
candown = project.is_public || (current_user.logged? && project.member?(current_user))
|
||||||
elsif @file.container.is_a?(Journal)
|
elsif @file.container.is_a?(Journal)
|
||||||
course = @file.container.issue.project
|
project = @file.container.issue.project
|
||||||
candown = course.member?(current_user)
|
candown = project.is_public || (current_user.logged? && project.member?(current_user))
|
||||||
else
|
else
|
||||||
course = nil
|
project = nil
|
||||||
end
|
|
||||||
tip_exception(403, "您没有权限进入") if course.present? && !candown
|
|
||||||
tip_exception(403, "您没有权限进入") if @file.container.is_a?(ApplyUserAuthentication)
|
|
||||||
end
|
end
|
||||||
|
tip_exception(403, "您没有权限进入") if project.present? && !candown
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -8,7 +8,7 @@ class Ci::BaseController < ApplicationController
|
||||||
namespace = params[:owner]
|
namespace = params[:owner]
|
||||||
id = params[:repo] || params[:id]
|
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
|
end
|
||||||
|
|
||||||
def load_all_repo
|
def load_all_repo
|
||||||
|
|
|
@ -14,12 +14,12 @@ class Ci::CloudAccountsController < Ci::BaseController
|
||||||
|
|
||||||
def create
|
def create
|
||||||
flag, msg = check_bind_cloud_account!
|
flag, msg = check_bind_cloud_account!
|
||||||
return render_error(msg) if flag === true
|
return tip_exception(msg) if flag === true
|
||||||
|
|
||||||
ActiveRecord::Base.transaction do
|
ActiveRecord::Base.transaction do
|
||||||
@cloud_account = bind_account!
|
@cloud_account = bind_account!
|
||||||
if @cloud_account.blank?
|
if @cloud_account.blank?
|
||||||
render_error('激活失败, 请检查你的云服务器信息是否正确.')
|
tip_exception('激活失败, 请检查你的云服务器信息是否正确.')
|
||||||
raise ActiveRecord::Rollback
|
raise ActiveRecord::Rollback
|
||||||
else
|
else
|
||||||
current_user.set_drone_step!(User::DEVOPS_UNVERIFIED)
|
current_user.set_drone_step!(User::DEVOPS_UNVERIFIED)
|
||||||
|
@ -27,17 +27,17 @@ class Ci::CloudAccountsController < Ci::BaseController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
rescue Exception => ex
|
rescue Exception => ex
|
||||||
render_error(ex.message)
|
tip_exception(ex.message)
|
||||||
end
|
end
|
||||||
|
|
||||||
def activate
|
def activate
|
||||||
return render_error('请先认证') unless current_user.ci_certification?
|
return tip_exception('请先认证') unless current_user.ci_certification?
|
||||||
|
|
||||||
begin
|
begin
|
||||||
@cloud_account = Ci::CloudAccount.find params[:id]
|
@cloud_account = Ci::CloudAccount.find params[:id]
|
||||||
ActiveRecord::Base.transaction do
|
ActiveRecord::Base.transaction do
|
||||||
if @repo
|
if @repo
|
||||||
return render_error('该项目已经激活') if @repo.repo_active?
|
return tip_exception('该项目已经激活') if @repo.repo_active?
|
||||||
@repo.activate!(@project)
|
@repo.activate!(@project)
|
||||||
else
|
else
|
||||||
@repo = Ci::Repo.auto_create!(@ci_user, @project)
|
@repo = Ci::Repo.auto_create!(@ci_user, @project)
|
||||||
|
@ -50,7 +50,7 @@ class Ci::CloudAccountsController < Ci::BaseController
|
||||||
end
|
end
|
||||||
render_ok
|
render_ok
|
||||||
rescue Exception => ex
|
rescue Exception => ex
|
||||||
render_error(ex.message)
|
tip_exception(ex.message)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -59,39 +59,39 @@ class Ci::CloudAccountsController < Ci::BaseController
|
||||||
|
|
||||||
def bind
|
def bind
|
||||||
flag, msg = check_bind_cloud_account!
|
flag, msg = check_bind_cloud_account!
|
||||||
return render_error(msg) if flag === true
|
return tip_exception(msg) if flag === true
|
||||||
|
|
||||||
ActiveRecord::Base.transaction do
|
ActiveRecord::Base.transaction do
|
||||||
@cloud_account = bind_account!
|
@cloud_account = bind_account!
|
||||||
if @cloud_account.blank?
|
if @cloud_account.blank?
|
||||||
render_error('激活失败, 请检查你的云服务器信息是否正确.')
|
tip_exception('激活失败, 请检查你的云服务器信息是否正确.')
|
||||||
raise ActiveRecord::Rollback
|
raise ActiveRecord::Rollback
|
||||||
else
|
else
|
||||||
current_user.set_drone_step!(User::DEVOPS_UNVERIFIED)
|
current_user.set_drone_step!(User::DEVOPS_UNVERIFIED)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
rescue Exception => ex
|
rescue Exception => ex
|
||||||
render_error(ex.message)
|
tip_exception(ex.message)
|
||||||
end
|
end
|
||||||
|
|
||||||
def trustie_bind
|
def trustie_bind
|
||||||
account = params[:account].to_s
|
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!
|
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
|
ActiveRecord::Base.transaction do
|
||||||
@cloud_account = trustie_bind_account!
|
@cloud_account = trustie_bind_account!
|
||||||
if @cloud_account.blank?
|
if @cloud_account.blank?
|
||||||
render_error('激活失败, 请检查你的云服务器信息是否正确.')
|
tip_exception('激活失败, 请检查你的云服务器信息是否正确.')
|
||||||
raise ActiveRecord::Rollback
|
raise ActiveRecord::Rollback
|
||||||
else
|
else
|
||||||
current_user.set_drone_step!(User::DEVOPS_UNVERIFIED)
|
current_user.set_drone_step!(User::DEVOPS_UNVERIFIED)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
rescue Exception => ex
|
rescue Exception => ex
|
||||||
render_error(ex.message)
|
tip_exception(ex.message)
|
||||||
end
|
end
|
||||||
|
|
||||||
def unbind
|
def unbind
|
||||||
|
@ -107,18 +107,18 @@ class Ci::CloudAccountsController < Ci::BaseController
|
||||||
render_ok
|
render_ok
|
||||||
end
|
end
|
||||||
rescue Exception => ex
|
rescue Exception => ex
|
||||||
render_error(ex.message)
|
tip_exception(ex.message)
|
||||||
end
|
end
|
||||||
|
|
||||||
def oauth_grant
|
def oauth_grant
|
||||||
password = params[:password].to_s
|
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
|
oauth = current_user.oauths.last
|
||||||
return render_error("服务器出小差了.") if oauth.blank?
|
return tip_exception("服务器出小差了.") if oauth.blank?
|
||||||
|
|
||||||
result = gitea_oauth_grant!(password, oauth)
|
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)
|
current_user.set_drone_step!(User::DEVOPS_CERTIFICATION)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ class Ci::PipelinesController < Ci::BaseController
|
||||||
ActiveRecord::Base.transaction do
|
ActiveRecord::Base.transaction do
|
||||||
size = Ci::Pipeline.where('branch=? and identifier=? and owner=?', params[:branch], params[:repo], params[:owner]).size
|
size = Ci::Pipeline.where('branch=? and identifier=? and owner=?', params[:branch], params[:repo], params[:owner]).size
|
||||||
if size > 0
|
if size > 0
|
||||||
render_error("#{params[:branch]}分支已经存在流水线!")
|
tip_exception("#{params[:branch]}分支已经存在流水线!")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
pipeline = Ci::Pipeline.new(pipeline_name: params[:pipeline_name], file_name: params[:file_name],owner: params[:owner],
|
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})
|
render_ok({id: pipeline.id})
|
||||||
end
|
end
|
||||||
rescue Exception => ex
|
rescue Exception => ex
|
||||||
render_error(ex.message)
|
tip_exception(ex.message)
|
||||||
end
|
end
|
||||||
|
|
||||||
# 在代码库创建文件
|
# 在代码库创建文件
|
||||||
|
@ -81,6 +81,7 @@ class Ci::PipelinesController < Ci::BaseController
|
||||||
repo_branch: pipeline.branch,
|
repo_branch: pipeline.branch,
|
||||||
repo_config: pipeline.file_name
|
repo_config: pipeline.file_name
|
||||||
}
|
}
|
||||||
|
Rails.logger.info("########create_params===#{create_params.to_json}")
|
||||||
repo = Ci::Repo.create_repo(create_params)
|
repo = Ci::Repo.create_repo(create_params)
|
||||||
repo
|
repo
|
||||||
end
|
end
|
||||||
|
@ -118,7 +119,7 @@ class Ci::PipelinesController < Ci::BaseController
|
||||||
end
|
end
|
||||||
render_ok
|
render_ok
|
||||||
rescue Exception => ex
|
rescue Exception => ex
|
||||||
render_error(ex.message)
|
tip_exception(ex.message)
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
|
@ -132,7 +133,7 @@ class Ci::PipelinesController < Ci::BaseController
|
||||||
end
|
end
|
||||||
render_ok
|
render_ok
|
||||||
rescue Exception => ex
|
rescue Exception => ex
|
||||||
render_error(ex.message)
|
tip_exception(ex.message)
|
||||||
end
|
end
|
||||||
|
|
||||||
def content
|
def content
|
||||||
|
@ -182,7 +183,7 @@ class Ci::PipelinesController < Ci::BaseController
|
||||||
render_ok
|
render_ok
|
||||||
end
|
end
|
||||||
rescue Exception => ex
|
rescue Exception => ex
|
||||||
render_error(ex.message)
|
tip_exception(ex.message)
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_stage
|
def update_stage
|
||||||
|
@ -192,7 +193,7 @@ class Ci::PipelinesController < Ci::BaseController
|
||||||
end
|
end
|
||||||
render_ok
|
render_ok
|
||||||
rescue Exception => ex
|
rescue Exception => ex
|
||||||
render_error(ex.message)
|
tip_exception(ex.message)
|
||||||
end
|
end
|
||||||
|
|
||||||
def delete_stage
|
def delete_stage
|
||||||
|
@ -205,7 +206,7 @@ class Ci::PipelinesController < Ci::BaseController
|
||||||
render_ok
|
render_ok
|
||||||
end
|
end
|
||||||
rescue Exception => ex
|
rescue Exception => ex
|
||||||
render_error(ex.message)
|
tip_exception(ex.message)
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_stage_index(pipeline_id, show_index, diff)
|
def update_stage_index(pipeline_id, show_index, diff)
|
||||||
|
@ -229,7 +230,7 @@ class Ci::PipelinesController < Ci::BaseController
|
||||||
unless steps.empty?
|
unless steps.empty?
|
||||||
steps.each do |step|
|
steps.each do |step|
|
||||||
unless step[:template_id]
|
unless step[:template_id]
|
||||||
render_error('请选择模板!')
|
tip_exception('请选择模板!')
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if !step[:id]
|
if !step[:id]
|
||||||
|
@ -246,7 +247,7 @@ class Ci::PipelinesController < Ci::BaseController
|
||||||
render_ok
|
render_ok
|
||||||
end
|
end
|
||||||
rescue Exception => ex
|
rescue Exception => ex
|
||||||
render_error(ex.message)
|
tip_exception(ex.message)
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_stage_step
|
def create_stage_step
|
||||||
|
@ -262,7 +263,7 @@ class Ci::PipelinesController < Ci::BaseController
|
||||||
render_ok
|
render_ok
|
||||||
end
|
end
|
||||||
rescue Exception => ex
|
rescue Exception => ex
|
||||||
render_error(ex.message)
|
tip_exception(ex.message)
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_stage_step
|
def update_stage_step
|
||||||
|
@ -279,7 +280,7 @@ class Ci::PipelinesController < Ci::BaseController
|
||||||
render_ok
|
render_ok
|
||||||
end
|
end
|
||||||
rescue Exception => ex
|
rescue Exception => ex
|
||||||
render_error(ex.message)
|
tip_exception(ex.message)
|
||||||
end
|
end
|
||||||
|
|
||||||
def delete_stage_step
|
def delete_stage_step
|
||||||
|
@ -289,6 +290,6 @@ class Ci::PipelinesController < Ci::BaseController
|
||||||
end
|
end
|
||||||
render_ok
|
render_ok
|
||||||
rescue Exception => ex
|
rescue Exception => ex
|
||||||
render_error(ex.message)
|
tip_exception(ex.message)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -30,19 +30,19 @@ class Ci::ProjectsController < Ci::BaseController
|
||||||
@file = interactor.result
|
@file = interactor.result
|
||||||
render_result(1, "更新成功")
|
render_result(1, "更新成功")
|
||||||
else
|
else
|
||||||
render_error(interactor.error)
|
tip_exception(interactor.error)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def activate
|
def activate
|
||||||
return render_error('你还未认证') unless current_user.ci_certification?
|
return tip_exception('你还未认证') unless current_user.ci_certification?
|
||||||
|
|
||||||
begin
|
begin
|
||||||
ActiveRecord::Base.transaction do
|
ActiveRecord::Base.transaction do
|
||||||
if @repo
|
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)
|
@repo.activate!(@project)
|
||||||
return render_ok
|
|
||||||
else
|
else
|
||||||
@repo = Ci::Repo.auto_create!(@ci_user, @project)
|
@repo = Ci::Repo.auto_create!(@ci_user, @project)
|
||||||
@ci_user.update_column(:user_syncing, false)
|
@ci_user.update_column(:user_syncing, false)
|
||||||
|
@ -55,12 +55,12 @@ class Ci::ProjectsController < Ci::BaseController
|
||||||
end
|
end
|
||||||
render_ok
|
render_ok
|
||||||
rescue Exception => ex
|
rescue Exception => ex
|
||||||
render_error(ex.message)
|
tip_exception(ex.message)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def deactivate
|
def deactivate
|
||||||
return render_error('该项目已经取消激活') if !@repo.repo_active?
|
return tip_exception('该项目已经取消激活') if !@repo.repo_active?
|
||||||
|
|
||||||
@project.update_column(:open_devops, false)
|
@project.update_column(:open_devops, false)
|
||||||
@repo.deactivate_repos!
|
@repo.deactivate_repos!
|
||||||
|
|
|
@ -20,14 +20,14 @@ class Ci::SecretsController < Ci::BaseController
|
||||||
if result["id"]
|
if result["id"]
|
||||||
render_ok
|
render_ok
|
||||||
else
|
else
|
||||||
render_error(result["message"])
|
tip_exception(result["message"])
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
result = Ci::Drone::API.new(@ci_user.user_hash, ci_drone_url, params[:owner], params[:repo], options).create_secret
|
result = Ci::Drone::API.new(@ci_user.user_hash, ci_drone_url, params[:owner], params[:repo], options).create_secret
|
||||||
if result["id"]
|
if result["id"]
|
||||||
render_ok
|
render_ok
|
||||||
else
|
else
|
||||||
render_error(result["message"])
|
tip_exception(result["message"])
|
||||||
end
|
end
|
||||||
end
|
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
|
Ci::Drone::API.new(@ci_user.user_hash, ci_drone_url, params[:owner], params[:repo], {name: name}).delete_secret
|
||||||
render_ok
|
render_ok
|
||||||
else
|
else
|
||||||
render_error("参数名不能为空")
|
tip_exception("参数名不能为空")
|
||||||
end
|
end
|
||||||
rescue Exception => ex
|
rescue Exception => ex
|
||||||
render_ok
|
render_ok
|
||||||
end
|
end
|
||||||
|
|
||||||
def ci_drone_url
|
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
|
user&.ci_cloud_account.drone_url
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ class Ci::TemplatesController < Ci::BaseController
|
||||||
end
|
end
|
||||||
render_ok
|
render_ok
|
||||||
rescue Exception => ex
|
rescue Exception => ex
|
||||||
render_error(ex.message)
|
tip_exception(ex.message)
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
|
@ -63,7 +63,7 @@ class Ci::TemplatesController < Ci::BaseController
|
||||||
)
|
)
|
||||||
render_ok
|
render_ok
|
||||||
rescue Exception => ex
|
rescue Exception => ex
|
||||||
render_error(ex.message)
|
tip_exception(ex.message)
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
|
@ -73,7 +73,7 @@ class Ci::TemplatesController < Ci::BaseController
|
||||||
end
|
end
|
||||||
render_ok
|
render_ok
|
||||||
rescue Exception => ex
|
rescue Exception => ex
|
||||||
render_error(ex.message)
|
tip_exception(ex.message)
|
||||||
end
|
end
|
||||||
|
|
||||||
#======流水线模板查询=====#
|
#======流水线模板查询=====#
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
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)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
|
@ -6,16 +6,26 @@ class CompareController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
|
if params[:type] == "sha"
|
||||||
|
load_compare_params
|
||||||
|
@compare_result ||= gitea_compare(@base, @head)
|
||||||
|
else
|
||||||
load_compare_params
|
load_compare_params
|
||||||
compare
|
compare
|
||||||
@merge_status, @merge_message = get_merge_message
|
@merge_status, @merge_message = get_merge_message
|
||||||
end
|
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
|
private
|
||||||
def get_merge_message
|
def get_merge_message
|
||||||
if @base.blank? || @head.blank?
|
if @base.blank? || @head.blank?
|
||||||
return -2, "请选择分支"
|
return -2, "请选择分支"
|
||||||
else
|
else
|
||||||
|
return -2, "目标仓库未开启合并请求(PR)功能" unless @project.has_menu_permission("pulls")
|
||||||
if @head.include?(":")
|
if @head.include?(":")
|
||||||
fork_project = @project.forked_projects.joins(:owner).where(users: {login: @head.to_s.split("/")[0]}).take
|
fork_project = @project.forked_projects.joins(:owner).where(users: {login: @head.to_s.split("/")[0]}).take
|
||||||
return -2, "请选择正确的仓库" unless fork_project.present?
|
return -2, "请选择正确的仓库" unless fork_project.present?
|
||||||
|
@ -42,12 +52,22 @@ class CompareController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def load_compare_params
|
def load_compare_params
|
||||||
@base = Addressable::URI.unescape(params[:base])
|
# @base = Addressable::URI.unescape(params[:base])
|
||||||
@head = params[:head].include?('json') ? params[:head]&.split('.json')[0] : params[:head]
|
@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
|
end
|
||||||
|
|
||||||
def gitea_compare(base, head)
|
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
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,368 @@
|
||||||
|
class CompetitionInfosController < ApplicationController
|
||||||
|
include ApplicationHelper
|
||||||
|
before_action :find_competition, only: [:show, :edit, :update, :update_zone_or_sub, :enroll, :upload, :enroll_status,
|
||||||
|
:statistics, :enroll_list, :ranking_list, :enroll_update, :enroll_status_update,
|
||||||
|
:upload_enroll_template, :enroll_template, :online_switch, :destroy]
|
||||||
|
before_action :require_admin, only: [:new, :edit, :create, :destroy]
|
||||||
|
before_action :check_competition_manager, only: [:update, :enroll_status_update]
|
||||||
|
|
||||||
|
def index
|
||||||
|
competition_infos = CompetitionInfo.order(sort_no: :desc)
|
||||||
|
competition_infos = competition_infos.where("competition_infos.title like ?", "%#{params[:name]}%") if params[:name].present?
|
||||||
|
competition_infos = competition_infos.joins(:watchers).where(watchers: { user_id: current_user.id }) if params[:category].to_s == "watched"
|
||||||
|
@competition_infos = paginate(competition_infos)
|
||||||
|
respond_to do |format|
|
||||||
|
format.html
|
||||||
|
format.json { render_ok(data: @competition_infos.as_json, count: competition_infos.count) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def recommend
|
||||||
|
sort_direction = ["asc", "desc"].include?(params[:sort_direction].to_s) ? params[:sort_direction] : "desc"
|
||||||
|
sort_by = params[:sort_by] || "created_at"
|
||||||
|
competition_infos = CompetitionInfo.where(status: true)
|
||||||
|
competition_infos = competition_infos.where("title like ?", "%#{params[:name]}%") if params[:name].present?
|
||||||
|
@total_count= competition_infos.count
|
||||||
|
if sort_by.to_s == "hot"
|
||||||
|
competition_infos = competition_infos.select("competition_infos.*, (SELECT count(1) from competition_users where competition_users.competition_info_id = competition_infos.id ) as count").order("count #{sort_direction}")
|
||||||
|
elsif sort_by.to_s == "new"
|
||||||
|
sort_by = "created_at"
|
||||||
|
competition_infos = competition_infos.order("#{sort_by} #{params[:sort_direction]}")
|
||||||
|
else
|
||||||
|
competition_infos = competition_infos.order("#{sort_by} #{params[:sort_direction]}")
|
||||||
|
end
|
||||||
|
@competition_infos = paginate(competition_infos)
|
||||||
|
render_ok(data: @competition_infos.as_json, count: @total_count)
|
||||||
|
end
|
||||||
|
|
||||||
|
# GET /competition_infos/new
|
||||||
|
def new
|
||||||
|
@competition_info = CompetitionInfo.new
|
||||||
|
end
|
||||||
|
|
||||||
|
# GET /competition_infos/1/edit
|
||||||
|
def edit
|
||||||
|
respond_to do |format|
|
||||||
|
format.html
|
||||||
|
format.json { render_ok(data: @competition_info.as_json) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# POST /competition_infos.json
|
||||||
|
def create
|
||||||
|
@competition_info = CompetitionInfo.new(competition_info_params)
|
||||||
|
@competition_info.admin_data = params[:admin_data]
|
||||||
|
|
||||||
|
respond_to do |format|
|
||||||
|
if @competition_info.save
|
||||||
|
format.html { redirect_to competition_infos_path, notice: '创建成功.' }
|
||||||
|
format.json { render_ok(data: @competition_info.as_json) }
|
||||||
|
else
|
||||||
|
format.html { render :new }
|
||||||
|
format.json { render json: @competition_info.errors, status: -1 }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# PATCH/PUT /competition_infos/1.json
|
||||||
|
def update
|
||||||
|
# @competition_info = CompetitionInfo.find params[:id]
|
||||||
|
respond_to do |format|
|
||||||
|
@competition_info.admin_data = params[:admin_data]
|
||||||
|
if @competition_info.update(competition_info_params)
|
||||||
|
format.html { redirect_to competition_infos_path, notice: '更新成功.' }
|
||||||
|
format.json { render_ok(data: @competition_info.as_json) }
|
||||||
|
else
|
||||||
|
format.html { render :edit }
|
||||||
|
format.json { render json: @competition_info.errors, status: -1 }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def online_switch
|
||||||
|
if @competition_info.status
|
||||||
|
@competition_info.update_attributes!(status: false)
|
||||||
|
else
|
||||||
|
@competition_info.update_attributes!(status: true)
|
||||||
|
end
|
||||||
|
render_ok
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_zone_or_sub
|
||||||
|
tip_exception "参数错误" if params[:new].blank? || params[:old].blank? || params[:type].blank?
|
||||||
|
if params[:type].to_s == "zone"
|
||||||
|
competition_users = CompetitionUser.where(competition_info: @competition_info.id).where(zone: params[:old].to_s)
|
||||||
|
competition_users.update_all(zone: params[:new].to_s)
|
||||||
|
elsif params[:type].to_s == "sub"
|
||||||
|
competition_users = CompetitionUser.where(competition_info: @competition_info.id).where(sub_competition: params[:old].to_s)
|
||||||
|
competition_users.update_all(sub_competition: params[:new].to_s)
|
||||||
|
end
|
||||||
|
render_ok
|
||||||
|
end
|
||||||
|
|
||||||
|
def enroll_list
|
||||||
|
competition_users = CompetitionUser.where(competition_info: @competition_info.id).order("updated_at desc")
|
||||||
|
zones = @competition_info.manager_zones(current_user)
|
||||||
|
if @competition_info.identifier == "qz2022"
|
||||||
|
if params[:zone].present?
|
||||||
|
competition_users = zones.include?(params[:zone].to_s) ? competition_users.where(zone: params[:zone].to_s) : competition_users.where(zone: [])
|
||||||
|
else
|
||||||
|
competition_users = current_user.admin? ? competition_users : competition_users.where(zone: zones)
|
||||||
|
end
|
||||||
|
if params[:sub_competition].present?
|
||||||
|
competition_users = competition_users.where(sub_competition: params[:sub_competition].to_s)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if params[:keyword].present?
|
||||||
|
competition_users = competition_users.where("competition_users.org_name LIKE :keyword OR competition_users.leader LIKE :keyword OR competition_users.phone LIKE :keyword", keyword: "%#{params[:keyword].to_s}%")
|
||||||
|
end
|
||||||
|
if params[:status].present?
|
||||||
|
competition_users = competition_users.where(status: params[:status])
|
||||||
|
end
|
||||||
|
if params[:upload].to_s == "true"
|
||||||
|
competition_users = competition_users.joins("join attachments on attachments.container_type='CompetitionUser' and attachments.container_id = competition_users.id")
|
||||||
|
end
|
||||||
|
@competition_users_count = competition_users.count
|
||||||
|
competition_users = competition_users.select("DISTINCT competition_users.*")
|
||||||
|
@competition_users = paginate(competition_users)
|
||||||
|
respond_to do |format|
|
||||||
|
format.json
|
||||||
|
#导出功能
|
||||||
|
format.xlsx {
|
||||||
|
set_export_cookies
|
||||||
|
competition_users = params[:upload].to_s == "true" ? competition_users.where(status: [2, 3]) : competition_users.where(status: [1, 2, 3])
|
||||||
|
@table_columns = @competition_info.enroll_fields.keys
|
||||||
|
@table_columns = @table_columns + %w(作品下载链接) if params[:upload].to_s == "true"
|
||||||
|
@export_infos = []
|
||||||
|
@export_infos_new = []
|
||||||
|
max_members = []
|
||||||
|
competition_users.each do |u|
|
||||||
|
info_array = []
|
||||||
|
@competition_info.enroll_fields.values.each do |val|
|
||||||
|
if "members_to_string" == val.to_s
|
||||||
|
members = u.send("#{val}")
|
||||||
|
max_members.push(members.size)
|
||||||
|
info_array = info_array + members
|
||||||
|
else
|
||||||
|
info_array.push("#{u.send("#{val}")}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if params[:upload].to_s == "true"
|
||||||
|
info_array = info_array + [u.attachments.blank? ? "" : "#{EduSetting.get('host_name')}/#{download_url(u.attachments.first)}"]
|
||||||
|
end
|
||||||
|
@export_infos.push(info_array)
|
||||||
|
end
|
||||||
|
if max_members.present? && max_members.max > 1
|
||||||
|
max_members.max.times do |n|
|
||||||
|
@table_columns = @table_columns - ["成员"]
|
||||||
|
@table_columns.push("成员#{n + 1}")
|
||||||
|
end
|
||||||
|
total_col = @competition_info.enroll_fields.values.size + max_members.max.to_i
|
||||||
|
@export_infos.each do |info|
|
||||||
|
blank_str = []
|
||||||
|
(total_col - 1 - info.size).times do
|
||||||
|
blank_str.push("")
|
||||||
|
end
|
||||||
|
@export_infos_new.push(info + blank_str)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
export_name = "竞赛报名列表_#{Time.now.strftime('%Y%m%d_%H%M%S')}"
|
||||||
|
export_name = "竞赛作品列表_#{Time.now.strftime('%Y%m%d_%H%M%S')}" if params[:upload].to_s == "true"
|
||||||
|
render xlsx: "#{export_name.strip}", template: "competition_infos/enroll_list.xlsx.axlsx", locals: { table_columns: @table_columns, export_infos: @export_infos_new }
|
||||||
|
}
|
||||||
|
format.zip {
|
||||||
|
competition_users = params[:upload].to_s == "true" ? competition_users.where(status: [2, 3]) : competition_users.where(status: [1, 2, 3])
|
||||||
|
Rails.logger.info("######_______________########competition_users.size: #{competition_users.size}")
|
||||||
|
service = Competition::ZipWorkFileService.new(competition_users, "files")
|
||||||
|
send_file service.zip, filename: service.filename, type: 'application/zip'
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def enroll_template
|
||||||
|
competition_users = CompetitionUser.where(competition_info: @competition_info.id).order("updated_at desc")
|
||||||
|
competition_users = competition_users.where(status: [1, 2, 3]).where("competition_users.enroll_template_id is not null")
|
||||||
|
zones = @competition_info.manager_zones(current_user)
|
||||||
|
if params[:zone].present?
|
||||||
|
competition_users = zones.include?(params[:zone].to_s) ? competition_users.where(zone: params[:zone].to_s) : competition_users.where(zone: [])
|
||||||
|
else
|
||||||
|
competition_users = current_user.admin? ? competition_users : competition_users.where(zone: zones)
|
||||||
|
end
|
||||||
|
if params[:sub_competition].present?
|
||||||
|
competition_users = competition_users.where(sub_competition: params[:sub_competition].to_s)
|
||||||
|
end
|
||||||
|
if params[:keyword].present?
|
||||||
|
competition_users = competition_users.where("competition_users.org_name LIKE :keyword OR competition_users.leader LIKE :keyword OR competition_users.phone LIKE :keyword", keyword: "%#{params[:keyword].to_s}%")
|
||||||
|
end
|
||||||
|
respond_to do |format|
|
||||||
|
format.json
|
||||||
|
format.zip {
|
||||||
|
Rails.logger.info("######_______________########competition_users.size: #{competition_users.size}")
|
||||||
|
service = Competition::ZipEnrollTemplateService.new(competition_users, "files")
|
||||||
|
send_file service.zip, filename: service.filename, type: 'application/zip'
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def show
|
||||||
|
@competition_info.increment!(:visits)
|
||||||
|
end
|
||||||
|
|
||||||
|
def enroll_status_update
|
||||||
|
competition_user = CompetitionUser.find_by(competition_info: @competition_info.id, user_id: params[:user_id])
|
||||||
|
tip_exception "未找到该报名用户" if competition_user.blank?
|
||||||
|
tip_exception "状态参数错误" unless ['0', '1', '2'].include?(params[:status].to_s)
|
||||||
|
competition_user.update_attributes!(status: params[:status].to_i)
|
||||||
|
render_ok
|
||||||
|
end
|
||||||
|
|
||||||
|
def enroll
|
||||||
|
competition_user = CompetitionUser.find_by(competition_info: @competition_info.id, user_id: current_user.id)
|
||||||
|
tip_exception "您已经报名!" if competition_user.present?
|
||||||
|
competition_user = CompetitionUser.new(enroll_params)
|
||||||
|
competition_user.competition_info = @competition_info
|
||||||
|
competition_user.user = current_user
|
||||||
|
competition_user.members = params[:members]
|
||||||
|
competition_user.status = 1
|
||||||
|
competition_user.save
|
||||||
|
render_ok
|
||||||
|
end
|
||||||
|
|
||||||
|
def enroll_update
|
||||||
|
competition_user = CompetitionUser.find_by(competition_info: @competition_info.id, user_id: current_user.id)
|
||||||
|
tip_exception "未报名,请先报名" if competition_user.blank?
|
||||||
|
competition_user.update_attributes!(enroll_params)
|
||||||
|
competition_user.members = params[:members]
|
||||||
|
competition_user.status = 1
|
||||||
|
competition_user.save
|
||||||
|
render_ok
|
||||||
|
end
|
||||||
|
|
||||||
|
def upload_enroll_template
|
||||||
|
competition_user = CompetitionUser.find_by(competition_info: @competition_info.id, user_id: current_user.id)
|
||||||
|
tip_exception "未报名,请先报名" if competition_user.blank?
|
||||||
|
tip_exception "附件参数enroll_template_id不能为空" if params[:enroll_template_id].blank?
|
||||||
|
competition_user.update_attributes!(enroll_template_id: params[:enroll_template_id])
|
||||||
|
render_ok
|
||||||
|
end
|
||||||
|
|
||||||
|
def enroll_status
|
||||||
|
@competition_user = CompetitionUser.find_by(competition_info: @competition_info.id, user_id: current_user.id)
|
||||||
|
# first_round_ids = CompetitionUser.where(competition_info_id: @competition_info.id).where("score > 26").pluck(:id)
|
||||||
|
# 第一轮赛合格人员
|
||||||
|
first_round_ids = [541, 543, 544, 545, 546, 548, 550, 551, 552, 554, 555, 556, 558, 560, 563, 565, 567, 576, 579, 581]
|
||||||
|
@second_round = first_round_ids.include?(@competition_user&.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def upload
|
||||||
|
competition_user = CompetitionUser.find_by(competition_info: @competition_info.id, user_id: current_user.id)
|
||||||
|
tip_exception "未报名,请先报名" if competition_user.blank?
|
||||||
|
tip_exception "附件参数attachment_ids不能为空" if params[:attachment_ids].blank?
|
||||||
|
# 第一轮赛合格人员
|
||||||
|
# first_round_ids = CompetitionUser.where(competition_info_id: @competition_info.id).where("score > 26").pluck(:id)
|
||||||
|
first_round_ids = [541, 543, 544, 545, 546, 548, 550, 551, 552, 554, 555, 556, 558, 560, 563, 565, 567, 576, 579, 581]
|
||||||
|
tip_exception "您不在复赛名单中,不能参加复赛!" if @competition_info.identifier == "zstp2022" && !first_round_ids.include?(competition_user&.id)
|
||||||
|
api_score_control = LimitForbidControl::CompetitionApiScore.new(competition_user.id)
|
||||||
|
return normal_status(-1, "今日打分已达上限,请明日再试") if api_score_control.forbid?
|
||||||
|
api_score_control.increment!
|
||||||
|
# tip_exception "您已经提交作品!" if competition_user.present? && competition_user.attachments.present?
|
||||||
|
competition_user.attachments.update_all(container_id: nil, container_type: nil)
|
||||||
|
params[:attachment_ids].each do |id|
|
||||||
|
attachment = Attachment.find_by_id(id)
|
||||||
|
unless attachment.blank?
|
||||||
|
attachment.container = competition_user
|
||||||
|
attachment.author_id = current_user.id
|
||||||
|
attachment.description = ""
|
||||||
|
attachment.save
|
||||||
|
end
|
||||||
|
forge_url = Rails.application.config_for(:configuration)['platform_url'] || EduSetting.get("main_site")
|
||||||
|
filePath = "#{forge_url}/api/attachments/#{attachment.id}"
|
||||||
|
if EduSetting.get("competition_ccks_ids").to_s.split(",").include?(@competition_info.identifier.to_s)
|
||||||
|
api_url = "/script/ccks"
|
||||||
|
CompetitionAutoScoreNewJob.perform_later(competition_user.id, api_url, filePath)
|
||||||
|
elsif EduSetting.get("competition_zstp2023_ids").to_s.split(",").include?(@competition_info.identifier.to_s)
|
||||||
|
api_url = "/script/ccks2023"
|
||||||
|
CompetitionAutoScoreNewJob.perform_later(competition_user.id, api_url, filePath)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
competition_user.update_attributes!(status: 3)
|
||||||
|
render_ok
|
||||||
|
end
|
||||||
|
|
||||||
|
# 自动打分接口
|
||||||
|
def auto_score
|
||||||
|
filePath = params[:filePath].to_s
|
||||||
|
team_id = params[:team_id].to_s
|
||||||
|
api_url = params[:api_url].to_s
|
||||||
|
tip_exception("参数错误") if filePath.blank? || team_id.blank? || api_url.blank?
|
||||||
|
competition_team = CompetitionTeam.find team_id
|
||||||
|
competition_team.update_attributes!(api_status: 1)
|
||||||
|
api_score_control = LimitForbidControl::CompetitionApiScore.new(team_id)
|
||||||
|
return normal_status(-1, "今日打分已达上限,请明日再试") if api_score_control.forbid?
|
||||||
|
api_score_control.increment!
|
||||||
|
CompetitionAutoScoreJob.perform_later(team_id, api_url, filePath)
|
||||||
|
render_ok
|
||||||
|
end
|
||||||
|
|
||||||
|
#赛事风采
|
||||||
|
def statistics
|
||||||
|
@competition_users = @competition_info.competition_users.where(status: [1, 2, 3])
|
||||||
|
@upload_count = @competition_users.joins("join attachments on attachments.container_type='CompetitionUser' and attachments.container_id = competition_users.id").count
|
||||||
|
end
|
||||||
|
|
||||||
|
# 排名
|
||||||
|
def ranking_list
|
||||||
|
competition_users = @competition_info.competition_users.where("score > 0").order("score desc, created_at asc")
|
||||||
|
@rank_num = competition_users.pluck(:id)
|
||||||
|
if params[:keyword].present?
|
||||||
|
competition_users = competition_users.where("competition_users.org_name LIKE :keyword OR competition_users.leader LIKE :keyword ", keyword: "%#{params[:keyword].to_s}%")
|
||||||
|
end
|
||||||
|
@competition_users_count = competition_users.count
|
||||||
|
@competition_users = paginate(competition_users)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
if @competition_info.destroy!
|
||||||
|
flash[:success] = '删除成功'
|
||||||
|
else
|
||||||
|
flash[:danger] = '删除失败'
|
||||||
|
end
|
||||||
|
redirect_to "api/competition_infos"
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def enroll_params
|
||||||
|
params.permit(:org_name, :org_job, :org_rank, :leader, :zone, :sub_competition, :phone,
|
||||||
|
:subject_source_type, :subject_source_name, :enroll_template_id, :mail, :ext1, :ext2, :ext3)
|
||||||
|
end
|
||||||
|
|
||||||
|
def competition_info_params
|
||||||
|
params.require(:competition_info).permit(:title, :zones, :zones_local, :sub_competitions, :identifier, :content,
|
||||||
|
:video_url, :is_local, :manager_ids, :upload_date, :enroll_date, :guide, :about_us,
|
||||||
|
:banner_url, :enroll_template, :enroll_columns, :applet_banner_url,:start_at, :sort_no)
|
||||||
|
end
|
||||||
|
|
||||||
|
def find_competition
|
||||||
|
if CompetitionInfo.where(:identifier => params[:id]).exists?
|
||||||
|
@competition_info = CompetitionInfo.where(:identifier => params[:id]).first
|
||||||
|
else
|
||||||
|
@competition_info = CompetitionInfo.find(params[:id])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def manager_competition_zones
|
||||||
|
if current_user.admin?
|
||||||
|
@competition_info.competition_zones
|
||||||
|
else
|
||||||
|
@competition_info.manager_zones(current_user)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def check_competition_manager
|
||||||
|
unless @competition_info.is_manager?(current_user)
|
||||||
|
tip_exception(403, "你没有权限操作!")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,90 @@
|
||||||
|
class CompetitionNoticesController < ApplicationController
|
||||||
|
include ApplicationHelper
|
||||||
|
before_action :find_competition, only: [:show, :index, :update, :destroy, :create]
|
||||||
|
# before_action :require_admin, only: [:show, :index, :update, :destroy, :create]
|
||||||
|
before_action :manager_competition_zones, only: [:enroll_list]
|
||||||
|
|
||||||
|
def index
|
||||||
|
competition_notices = CompetitionNotice.where(competition_info_id: @competition_info.id).order("created_at desc")
|
||||||
|
@competition_notices_count = competition_notices.size
|
||||||
|
@competition_notices = paginate(competition_notices)
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@competition_notice = CompetitionNotice.new(competition_notice_params)
|
||||||
|
@competition_notice.user = current_user
|
||||||
|
@competition_notice.competition_info = @competition_info
|
||||||
|
@competition_notice.save
|
||||||
|
if params[:attachment_ids].present?
|
||||||
|
params[:attachment_ids].each do |id|
|
||||||
|
attachment = Attachment.find_by_id(id)
|
||||||
|
unless attachment.blank?
|
||||||
|
attachment.container = @competition_notice
|
||||||
|
attachment.author_id = current_user.id
|
||||||
|
attachment.description = ""
|
||||||
|
attachment.save
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
render_ok
|
||||||
|
end
|
||||||
|
|
||||||
|
# PATCH/PUT /competition_infos/1.json
|
||||||
|
def update
|
||||||
|
@competition_notice = CompetitionNotice.find params[:id]
|
||||||
|
@competition_notice.update(competition_notice_params)
|
||||||
|
@competition_notice.attachments.update_all(container_id: nil, container_type: nil)
|
||||||
|
if params[:attachment_ids].present?
|
||||||
|
params[:attachment_ids].each do |id|
|
||||||
|
attachment = Attachment.find_by_id(id)
|
||||||
|
unless attachment.blank?
|
||||||
|
attachment.container = @competition_notice
|
||||||
|
attachment.author_id = current_user.id
|
||||||
|
attachment.description = ""
|
||||||
|
attachment.save
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
render_ok
|
||||||
|
end
|
||||||
|
|
||||||
|
def show
|
||||||
|
@competition_notice = CompetitionNotice.find params[:id]
|
||||||
|
end
|
||||||
|
|
||||||
|
def upload
|
||||||
|
competition_user = CompetitionUser.find_by(competition_info: @competition_notice.id, user_id: current_user.id)
|
||||||
|
tip_exception "未报名,请先报名" if competition_user.blank?
|
||||||
|
tip_exception "附件参数attachment_ids不能为空" if params[:attachment_ids].blank?
|
||||||
|
# tip_exception "您已经提交作品!" if competition_user.present? && competition_user.attachments.present?
|
||||||
|
competition_user.attachments.update_all(container_id: nil, container_type: nil)
|
||||||
|
|
||||||
|
render_ok
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
@competition_notice = CompetitionNotice.find params[:id]
|
||||||
|
@competition_notice.destroy
|
||||||
|
render_ok
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def competition_notice_params
|
||||||
|
params.permit(:title, :content)
|
||||||
|
end
|
||||||
|
|
||||||
|
def find_competition
|
||||||
|
if CompetitionInfo.where(:identifier => params[:competition_info_id]).exists?
|
||||||
|
@competition_info = CompetitionInfo.where(:identifier => params[:competition_info_id]).first
|
||||||
|
else
|
||||||
|
@competition_info = CompetitionInfo.find(params[:competition_info_id])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def manager_competition_zones
|
||||||
|
if current_user.admin?
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -18,15 +18,15 @@ module Acceleratorable
|
||||||
end
|
end
|
||||||
|
|
||||||
def accelerator_domain
|
def accelerator_domain
|
||||||
Gitea.gitea_config[:accelerator]["domain"]
|
GiteaService.gitea_config[:accelerator]["domain"]
|
||||||
end
|
end
|
||||||
|
|
||||||
def accelerator_username
|
def accelerator_username
|
||||||
Gitea.gitea_config[:accelerator]["access_key_id"]
|
GiteaService.gitea_config[:accelerator]["access_key_id"]
|
||||||
end
|
end
|
||||||
|
|
||||||
def config_accelerator?
|
def config_accelerator?
|
||||||
Gitea.gitea_config[:accelerator].present?
|
GiteaService.gitea_config[:accelerator].present?
|
||||||
end
|
end
|
||||||
|
|
||||||
def is_foreign_url?(clone_addr)
|
def is_foreign_url?(clone_addr)
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
module Api::ProjectHelper
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
def load_project
|
||||||
|
namespace = params[:owner]
|
||||||
|
repo = params[:repo]
|
||||||
|
|
||||||
|
@project, @owner = Project.find_with_namespace(namespace, repo)
|
||||||
|
|
||||||
|
if @project
|
||||||
|
logger.info "###########:project founded"
|
||||||
|
@project
|
||||||
|
else
|
||||||
|
logger.info "###########:project not found"
|
||||||
|
@project = nil
|
||||||
|
render_not_found and return
|
||||||
|
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
|
|
@ -15,7 +15,7 @@ module Base::PaginateHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def per_page
|
def per_page
|
||||||
params[:per_page].to_i <= 0 || params[:per_page].to_i > 100 ? 20 : params[:per_page].to_i
|
params[:per_page].to_i <= 0 || params[:per_page].to_i > 200 ? 10 : params[:per_page].to_i
|
||||||
end
|
end
|
||||||
alias_method :limit, :per_page
|
alias_method :limit, :per_page
|
||||||
|
|
||||||
|
|
|
@ -160,9 +160,9 @@ module Ci::CloudAccountManageable
|
||||||
state = SecureRandom.hex(8)
|
state = SecureRandom.hex(8)
|
||||||
# redirect_uri eg:
|
# 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
|
# 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")
|
# redirect_uri = CGI.escape("#{@cloud_account.drone_url}/login")
|
||||||
clientId = client_id(oauth)
|
# 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}"
|
grant_url = "#{@cloud_account.drone_url}/login"
|
||||||
logger.info "[gitea] grant_url: #{grant_url}"
|
logger.info "[gitea] grant_url: #{grant_url}"
|
||||||
|
|
||||||
conn = Faraday.new(url: grant_url) do |req|
|
conn = Faraday.new(url: grant_url) do |req|
|
||||||
|
@ -188,6 +188,7 @@ module Ci::CloudAccountManageable
|
||||||
response = conn.get
|
response = conn.get
|
||||||
logger.info "[drone] response headers: #{response.headers}"
|
logger.info "[drone] response headers: #{response.headers}"
|
||||||
|
|
||||||
|
# true
|
||||||
response.headers['location'].include?('error') ? false : true
|
response.headers['location'].include?('error') ? false : true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,9 @@ module LaboratoryHelper
|
||||||
helper_method :default_setting
|
helper_method :default_setting
|
||||||
helper_method :default_yun_session
|
helper_method :default_yun_session
|
||||||
helper_method :default_course_links
|
helper_method :default_course_links
|
||||||
|
helper_method :manager_main_site_url
|
||||||
|
helper_method :main_web_site_url
|
||||||
|
helper_method :current_main_site_url
|
||||||
end
|
end
|
||||||
|
|
||||||
def current_laboratory
|
def current_laboratory
|
||||||
|
@ -32,18 +35,30 @@ module LaboratoryHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def default_course_links
|
def default_course_links
|
||||||
# my_projects: "/users/#{current_user.try(:login)}/projects",
|
|
||||||
# my_projects: "https://www.trustie.net/users/#{current_user.try(:login)}/user_projectlist",
|
|
||||||
{
|
{
|
||||||
new_syllabuses: "https://www.trustie.net/syllabuses/new",
|
# new_syllabuses: "https://www.trustie.net/syllabuses/new",
|
||||||
new_course: "https://www.trustie.net/courses/new",
|
# new_course: "https://www.trustie.net/courses/new",
|
||||||
edit_account: "https://www.trustie.net/my/account",
|
# edit_account: "https://www.trustie.net/my/account",
|
||||||
my_courses: "https://www.trustie.net/users/#{current_user.try(:login)}/user_courselist",
|
# my_courses: "https://www.trustie.net/users/#{current_user.try(:login)}/user_courselist",
|
||||||
my_projects: "/users/#{current_user.try(:login)}/projects",
|
# my_projects: "/users/#{current_user.try(:login)}/projects",
|
||||||
my_organ: "https://www.trustie.net/users/#{current_user.try(:login)}/user_organizations",
|
# my_organ: "https://www.trustie.net/users/#{current_user.try(:login)}/user_organizations",
|
||||||
default_url: Rails.application.config_for(:configuration)['platform_url'],
|
# default_url: "https://www.trustie.net/",
|
||||||
tiding_url: "https://www.trustie.net/users/#{current_user.try(:login)}/user_messages",
|
tiding_url: "#{main_web_site_url}/users/#{current_user.try(:login)}/user_tidings",
|
||||||
register_url: "https://www.trustie.net/login?login=false"
|
register_url: "#{current_main_site_url}/register"
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def manager_main_site_url
|
||||||
|
url = EduSetting.get('managements_url') || "#{current_main_site_url}/managements"
|
||||||
|
{name: '管理', link: "#{url}"}
|
||||||
|
end
|
||||||
|
|
||||||
|
def main_web_site_url
|
||||||
|
EduSetting.get('host_main_site')
|
||||||
|
end
|
||||||
|
|
||||||
|
def current_main_site_url
|
||||||
|
EduSetting.get('host_name')
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,14 +6,16 @@ module LoginHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def autologin_cookie_name
|
def autologin_cookie_name
|
||||||
edu_setting('autologin_cookie_name').presence || 'autologin'
|
edu_setting('autologin_cookie_name').presence || 'autologin_forge_military'
|
||||||
|
end
|
||||||
|
|
||||||
|
def autologin_action
|
||||||
|
EduSetting.get('autologin_action').presence || 'autologin'
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_autologin_cookie(user)
|
def set_autologin_cookie(user)
|
||||||
token = Token.get_or_create_permanent_login_token(user, "autologin")
|
Rails.logger.info("set_cookie_user_id is=======> #{user.id}")
|
||||||
sync_user_token_to_trustie(user.login, token.value)
|
token = Token.get_or_create_permanent_login_token(user, autologin_action)
|
||||||
|
|
||||||
Rails.logger.info "###### def set_autologin_cookie and get_or_create_permanent_login_token result: #{token&.value}"
|
|
||||||
cookie_options = {
|
cookie_options = {
|
||||||
:value => token.value,
|
:value => token.value,
|
||||||
:expires => 1.month.from_now,
|
:expires => 1.month.from_now,
|
||||||
|
@ -108,10 +110,15 @@ module LoginHelper
|
||||||
def sync_pwd_to_gitea!(user, hash={})
|
def sync_pwd_to_gitea!(user, hash={})
|
||||||
return true if user.is_sync_pwd?
|
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))
|
interactor = Gitea::User::UpdateInteractor.call(user.login, sync_params.merge(hash))
|
||||||
if interactor.success?
|
if interactor.success?
|
||||||
Rails.logger.info "########_ login is #{user.login} sync_pwd_to_gitea success _########"
|
Rails.logger.info "########_ login is #{user.login} sync_pwd_to_gitea success _########"
|
||||||
|
user.update_column(:is_sync_pwd, true)
|
||||||
true
|
true
|
||||||
else
|
else
|
||||||
Rails.logger.info "########_ login is #{user.login} sync_pwd_to_gitea fail!: #{interactor.error}"
|
Rails.logger.info "########_ login is #{user.login} sync_pwd_to_gitea fail!: #{interactor.error}"
|
||||||
|
|
|
@ -1,30 +1,66 @@
|
||||||
module RegisterHelper
|
module RegisterHelper
|
||||||
extend ActiveSupport::Concern
|
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}
|
result = {message: nil, user: nil}
|
||||||
|
email = email.blank? ? "#{username}@example.org" : email
|
||||||
|
|
||||||
user = User.new(admin: false, login: username, mail: email, type: "User")
|
user = User.new(admin: false, login: username, mail: email, type: "User")
|
||||||
user.password = password
|
user.password = password
|
||||||
user.platform = platform
|
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
|
user.activate
|
||||||
|
end
|
||||||
|
|
||||||
return unless user.valid?
|
return unless user.valid?
|
||||||
|
|
||||||
interactor = Gitea::RegisterInteractor.call({username: username, email: email, password: password})
|
interactor = Gitea::RegisterInteractor.call({username: username, email: email, password: password})
|
||||||
|
result ={}
|
||||||
if interactor.success?
|
if interactor.success?
|
||||||
gitea_user = interactor.result
|
gitea_user = interactor.result
|
||||||
result = Gitea::User::GenerateTokenService.call(username, password)
|
result = Gitea::User::GenerateTokenService.call(username, password)
|
||||||
user.gitea_token = result['sha1']
|
user.gitea_token = result['sha1']
|
||||||
user.gitea_uid = gitea_user[:body]['id']
|
user.gitea_uid = gitea_user[:body]['id'] if gitea_user[:body].present?
|
||||||
if user.save!
|
if user.save!
|
||||||
UserExtension.create!(user_id: user.id)
|
UserExtension.create!(user_id: user.id) if user.user_extension.blank?
|
||||||
result[:user] = {id: user.id, token: user.gitea_token}
|
result[:user] = {id: user.id, token: user.gitea_token}
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
result[:message] = interactor.error
|
result[:message] = interactor.result[:message]
|
||||||
end
|
end
|
||||||
result
|
result
|
||||||
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
|
end
|
||||||
|
|
|
@ -3,7 +3,7 @@ module RenderHelper
|
||||||
render json: { status: 0, message: 'success' }.merge(data)
|
render json: { status: 0, message: 'success' }.merge(data)
|
||||||
end
|
end
|
||||||
|
|
||||||
def render_error(status = -1, message = '')
|
def render_error(message = '', status = -1)
|
||||||
render json: { status: status, message: message }
|
render json: { status: status, message: message }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,17 @@ module Repository::LanguagesPercentagable
|
||||||
result = Gitea::Repository::Languages::ListService.call(@owner.login,
|
result = Gitea::Repository::Languages::ListService.call(@owner.login,
|
||||||
@repository.identifier, current_user&.gitea_token)
|
@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_column(:project_language_id, db_language.id)
|
||||||
|
rescue
|
||||||
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
# hash eq:{"JavaScript": 301681522,"Ruby": 1444004,"Roff": 578781}
|
# hash eq:{"JavaScript": 301681522,"Ruby": 1444004,"Roff": 578781}
|
||||||
|
|
|
@ -13,7 +13,7 @@ class ForksController < ApplicationController
|
||||||
if current_user&.id == @project.user_id
|
if current_user&.id == @project.user_id
|
||||||
render_result(-1, "自己不能fork自己的项目")
|
render_result(-1, "自己不能fork自己的项目")
|
||||||
elsif Project.exists?(user_id: current_user.id, identifier: @project.identifier)
|
elsif Project.exists?(user_id: current_user.id, identifier: @project.identifier)
|
||||||
render_result(-1, "fork失败,你已拥有了这个项目")
|
render_result(0, "fork失败,你已拥有了这个项目")
|
||||||
end
|
end
|
||||||
# return if current_user != @project.owner
|
# return if current_user != @project.owner
|
||||||
# render_result(-1, "自己不能fork自己的项目")
|
# render_result(-1, "自己不能fork自己的项目")
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
class Home::CompetitionsController < ApplicationController
|
||||||
|
|
||||||
|
def index
|
||||||
|
@competitions = Competition.active.where(show_index: true).order(sort_no: :desc).limit(3)
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,8 @@
|
||||||
|
class Home::PlatformCommunicatesController < ApplicationController
|
||||||
|
|
||||||
|
def index
|
||||||
|
location = params[:location] || "pc"
|
||||||
|
scope = PlatformCommunicate.where(status:true).where(location: location).order(order_index: :desc)
|
||||||
|
@communicates = kaminari_paginate(scope)
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,7 @@
|
||||||
|
class Home::PlatformPeopleController < ApplicationController
|
||||||
|
|
||||||
|
def index
|
||||||
|
scope = PlatformPerson.order(created_at: :desc)
|
||||||
|
@people = kaminari_paginate(scope)
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,10 @@
|
||||||
|
class Home::PlatformStatisticsController < ApplicationController
|
||||||
|
|
||||||
|
def index
|
||||||
|
@platform_statistic = PlatformStatistic.data
|
||||||
|
@project_statistic = ProjectStatistic.data
|
||||||
|
@platform_statistic.increment!(:visits)
|
||||||
|
@tasks_count = ActiveRecord::Base.connection.exec_query("SELECT COUNT(1) FROM tasks b LEFT JOIN task_details a ON a.task_id = b.id WHERE b.is_delete = 0 AND b.published = 1 AND status IN (3, 4, 5, 6, 7, 8)").rows[0][0]
|
||||||
|
@memos_count = ActiveRecord::Base.connection.exec_query("SELECT COUNT(*) FROM memos").rows[0][0]
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,7 @@
|
||||||
|
class HomeController < ApplicationController
|
||||||
|
|
||||||
|
def to_competitions
|
||||||
|
competition_url = Rails.application.config_for(:configuration)['web_site'] || EduSetting.get('host_main_site')
|
||||||
|
redirect_to "#{competition_url}/competitions/#{params[:identifier].to_s}/home"
|
||||||
|
end
|
||||||
|
end
|
|
@ -2,12 +2,12 @@ class IssueTagsController < ApplicationController
|
||||||
before_action :require_login, except: [:index]
|
before_action :require_login, except: [:index]
|
||||||
before_action :load_repository
|
before_action :load_repository
|
||||||
before_action :set_user
|
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]
|
before_action :set_issue_tag, only: [:edit, :update, :destroy]
|
||||||
|
|
||||||
|
|
||||||
def index
|
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))
|
@user_admin_or_member = current_user.present? && (current_user.admin || @project.member?(current_user))
|
||||||
@page = params[:page] || 1
|
@page = params[:page] || 1
|
||||||
@limit = params[:limit] || 15
|
@limit = params[:limit] || 15
|
||||||
|
@ -17,7 +17,7 @@ class IssueTagsController < ApplicationController
|
||||||
|
|
||||||
|
|
||||||
def create
|
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)
|
desc = params[:description].to_s.first(30)
|
||||||
color = params[:color] || "#ccc"
|
color = params[:color] || "#ccc"
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ class IssueTagsController < ApplicationController
|
||||||
|
|
||||||
if title.present?
|
if title.present?
|
||||||
if IssueTag.exists?(name: title, project_id: @project.id)
|
if IssueTag.exists?(name: title, project_id: @project.id)
|
||||||
normal_status(-1, "标签已存在")
|
normal_status(-1, "项目标记已存在")
|
||||||
else
|
else
|
||||||
ActiveRecord::Base.transaction do
|
ActiveRecord::Base.transaction do
|
||||||
begin
|
begin
|
||||||
|
@ -37,12 +37,12 @@ class IssueTagsController < ApplicationController
|
||||||
if issue_tag.save
|
if issue_tag.save
|
||||||
# gitea_tag = Gitea::Labels::CreateService.new(current_user, @repository.try(:identifier), tag_params).call
|
# 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"])
|
# if gitea_tag && issue_tag.update_attributes(gid: gitea_tag["id"], gitea_url: gitea_tag["url"])
|
||||||
# normal_status(0, "标签创建成功")
|
normal_status(0, "项目标记创建成功!")
|
||||||
# else
|
# else
|
||||||
# normal_status(-1, "标签创建失败")
|
# normal_status(-1, "项目标记创建失败")
|
||||||
# end
|
# end
|
||||||
else
|
else
|
||||||
normal_status(-1, "标签创建失败")
|
normal_status(-1, "项目标记创建失败")
|
||||||
end
|
end
|
||||||
rescue => e
|
rescue => e
|
||||||
puts "create version release error: #{e.message}"
|
puts "create version release error: #{e.message}"
|
||||||
|
@ -51,7 +51,7 @@ class IssueTagsController < ApplicationController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
normal_status(-1, "标签名称不能为空")
|
normal_status(-1, "项目标记名称不能为空")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -60,8 +60,8 @@ class IssueTagsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
title = params[:name]
|
title = params[:name].to_s.strip.first(15)
|
||||||
desc = params[:description]
|
desc = params[:description].to_s.first(30)
|
||||||
color = params[:color] || "#ccc"
|
color = params[:color] || "#ccc"
|
||||||
|
|
||||||
tag_params = {
|
tag_params = {
|
||||||
|
@ -71,19 +71,19 @@ class IssueTagsController < ApplicationController
|
||||||
}
|
}
|
||||||
if title.present?
|
if title.present?
|
||||||
if IssueTag.exists?(name: title, project_id: @project.id) && (@issue_tag.name != title)
|
if IssueTag.exists?(name: title, project_id: @project.id) && (@issue_tag.name != title)
|
||||||
normal_status(-1, "标签已存在")
|
normal_status(-1, "项目标记已存在")
|
||||||
else
|
else
|
||||||
ActiveRecord::Base.transaction do
|
ActiveRecord::Base.transaction do
|
||||||
begin
|
begin
|
||||||
if @issue_tag.update_attributes(tag_params)
|
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
|
# gitea_tag = Gitea::Labels::UpdateService.new(current_user, @repository.try(:identifier),@issue_tag.try(:gid), tag_params).call
|
||||||
# if gitea_tag
|
# if gitea_tag
|
||||||
# normal_status(0, "标签更新成功")
|
# normal_status(0, "项目标记更新成功")
|
||||||
# else
|
# else
|
||||||
# normal_status(-1, "标签更新失败")
|
# normal_status(-1, "项目标记更新失败")
|
||||||
# end
|
# end
|
||||||
else
|
else
|
||||||
normal_status(-1, "标签更新失败")
|
normal_status(-1, "项目标记更新失败")
|
||||||
end
|
end
|
||||||
rescue => e
|
rescue => e
|
||||||
puts "create version release error: #{e.message}"
|
puts "create version release error: #{e.message}"
|
||||||
|
@ -92,7 +92,7 @@ class IssueTagsController < ApplicationController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
normal_status(-1, "标签名称不能为空")
|
normal_status(-1, "项目标记名称不能为空")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -102,12 +102,12 @@ class IssueTagsController < ApplicationController
|
||||||
if @issue_tag.destroy
|
if @issue_tag.destroy
|
||||||
# issue_tag = Gitea::Labels::DeleteService.new(@user, @repository.try(:identifier), @issue_tag.try(:gid)).call
|
# issue_tag = Gitea::Labels::DeleteService.new(@user, @repository.try(:identifier), @issue_tag.try(:gid)).call
|
||||||
# if issue_tag
|
# if issue_tag
|
||||||
# normal_status(0, "标签删除成功")
|
# normal_status(0, "项目标记删除成功")
|
||||||
# else
|
# else
|
||||||
# normal_status(-1, "标签删除失败")
|
# normal_status(-1, "项目标记删除失败")
|
||||||
# end
|
# end
|
||||||
else
|
else
|
||||||
normal_status(-1, "标签删除失败")
|
normal_status(-1, "项目标记删除失败")
|
||||||
end
|
end
|
||||||
rescue => e
|
rescue => e
|
||||||
puts "create version release error: #{e.message}"
|
puts "create version release error: #{e.message}"
|
||||||
|
@ -122,16 +122,16 @@ class IssueTagsController < ApplicationController
|
||||||
@user = @project.owner
|
@user = @project.owner
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_issue_permission
|
def check_issue_tags_permission
|
||||||
unless @project.member?(current_user) || current_user.admin?
|
unless @project.manager?(current_user) || current_user.admin?
|
||||||
normal_status(-1, "您没有权限")
|
return render_forbidden('你不是管理员,没有权限操作')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_issue_tag
|
def set_issue_tag
|
||||||
@issue_tag = IssueTag.find_by_id(params[:id])
|
@issue_tag = IssueTag.find_by_id(params[:id])
|
||||||
unless @issue_tag.present?
|
unless @issue_tag.present?
|
||||||
normal_status(-1, "标签不存在")
|
normal_status(-1, "项目标记不存在")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ class IssuesController < ApplicationController
|
||||||
include TagChosenHelper
|
include TagChosenHelper
|
||||||
|
|
||||||
def index
|
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?)
|
@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 = @project.issues.issue_issue.issue_index_includes
|
||||||
issues = issues.where(is_private: false) unless @user_admin_or_member
|
issues = issues.where(is_private: false) unless @user_admin_or_member
|
||||||
|
@ -23,13 +24,13 @@ class IssuesController < ApplicationController
|
||||||
@filter_issues = @all_issues
|
@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.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(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)
|
@open_issues = @all_issues.where.not(status_id: IssueStatus::CLOSED)
|
||||||
@close_issues = @all_issues.where(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")
|
scopes = Issues::ListQueryService.call(issues,params.delete_if{|k,v| v.blank?}, "Issue")
|
||||||
@issues_size = scopes.size
|
@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)
|
@issues = paginate(scopes)
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
|
@ -108,7 +109,7 @@ class IssuesController < ApplicationController
|
||||||
|
|
||||||
def create
|
def create
|
||||||
issue_params = issue_send_params(params)
|
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 = Issue.new(issue_params)
|
||||||
if @issue.save!
|
if @issue.save!
|
||||||
SendTemplateMessageJob.perform_later('IssueAssigned', current_user.id, @issue&.id) if Site.has_notice_menu?
|
SendTemplateMessageJob.perform_later('IssueAssigned', current_user.id, @issue&.id) if Site.has_notice_menu?
|
||||||
|
@ -125,10 +126,17 @@ class IssuesController < ApplicationController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if params[:issue_tag_ids].present?
|
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|
|
params[:issue_tag_ids].each do |tag|
|
||||||
IssueTagsRelate.create!(issue_id: @issue.id, issue_tag_id: tag)
|
IssueTagsRelate.create!(issue_id: @issue.id, issue_tag_id: tag)
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
return normal_status(-1, "请输入正确的标记。")
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if params[:assigned_to_id].present?
|
if params[:assigned_to_id].present?
|
||||||
Tiding.create!(user_id: params[:assigned_to_id], trigger_user_id: current_user.id,
|
Tiding.create!(user_id: params[:assigned_to_id], trigger_user_id: current_user.id,
|
||||||
container_id: @issue.id, container_type: 'Issue',
|
container_id: @issue.id, container_type: 'Issue',
|
||||||
|
@ -142,11 +150,13 @@ class IssuesController < ApplicationController
|
||||||
end
|
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: "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)}"
|
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
|
AtmeService.call(current_user, @atme_receivers, @issue) if @atme_receivers.size > 0
|
||||||
|
|
||||||
render json: {status: 0, message: "创建成", id: @issue.id}
|
render json: {status: 0, message: "创建成功", id: @issue.id}
|
||||||
else
|
else
|
||||||
normal_status(-1, "创建失败")
|
normal_status(-1, "创建失败")
|
||||||
end
|
end
|
||||||
|
@ -157,18 +167,26 @@ class IssuesController < ApplicationController
|
||||||
|
|
||||||
def edit
|
def edit
|
||||||
# @issue_chosen = issue_left_chosen(@project, @issue.id)
|
# @issue_chosen = issue_left_chosen(@project, @issue.id)
|
||||||
@cannot_edit_tags = @issue.issue_type=="2" && @issue.status_id == 5 #悬赏任务已解决且关闭的状态下,不能修改
|
|
||||||
@issue_attachments = @issue.attachments
|
@issue_attachments = @issue.attachments
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
|
issue_params = issue_send_params(params).except(:issue_classify, :author_id, :project_id)
|
||||||
|
return normal_status(-1, "您没有权限修改token") if @issue.will_save_change_to_token? && @issue.user_id != current_user&.id
|
||||||
last_token = @issue.token
|
last_token = @issue.token
|
||||||
last_status_id = @issue.status_id
|
last_status_id = @issue.status_id
|
||||||
@issue&.issue_tags_relates&.destroy_all if params[:issue_tag_ids].blank?
|
@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
|
@issue&.issue_tags_relates&.destroy_all
|
||||||
params[:issue_tag_ids].each do |tag|
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -189,6 +207,7 @@ class IssuesController < ApplicationController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# if params[:issue_tag_ids].present?
|
# if params[:issue_tag_ids].present?
|
||||||
# issue_current_tags = @issue&.issue_tags&.select(:id)&.pluck(:id)
|
# issue_current_tags = @issue&.issue_tags&.select(:id)&.pluck(:id)
|
||||||
# new_tag_ids = params[:issue_tag_ids] - issue_current_tags
|
# new_tag_ids = params[:issue_tag_ids] - issue_current_tags
|
||||||
|
@ -207,7 +226,7 @@ class IssuesController < ApplicationController
|
||||||
normal_status(-1, "不允许修改为关闭状态")
|
normal_status(-1, "不允许修改为关闭状态")
|
||||||
else
|
else
|
||||||
issue_params = issue_send_params(params).except(:issue_classify, :author_id, :project_id)
|
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.update_attributes(issue_params)
|
||||||
if @issue&.pull_request.present?
|
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?
|
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 +250,7 @@ class IssuesController < ApplicationController
|
||||||
end
|
end
|
||||||
if params[:status_id].to_i == 5 #任务由非关闭状态到关闭状态时
|
if params[:status_id].to_i == 5 #任务由非关闭状态到关闭状态时
|
||||||
@issue.issue_times.update_all(end_time: Time.now)
|
@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.issue_type.to_s == "2" && last_status_id != 5
|
||||||
if @issue.assigned_to_id.present? && last_status_id == 3 #只有当用户完成100%时,才给token
|
if @issue.assigned_to_id.present? && last_status_id == 3 #只有当用户完成100%时,才给token
|
||||||
post_to_chain("add", @issue.token, @issue.get_assign_user.try(:login))
|
post_to_chain("add", @issue.token, @issue.get_assign_user.try(:login))
|
||||||
|
@ -256,6 +275,8 @@ class IssuesController < ApplicationController
|
||||||
else
|
else
|
||||||
normal_status(-1, "更新失败")
|
normal_status(-1, "更新失败")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
rescue Exception => exception
|
rescue Exception => exception
|
||||||
puts exception.message
|
puts exception.message
|
||||||
|
@ -289,20 +310,17 @@ class IssuesController < ApplicationController
|
||||||
if issue_type == "2" && status_id != 5
|
if issue_type == "2" && status_id != 5
|
||||||
post_to_chain("add", token, login)
|
post_to_chain("add", token, login)
|
||||||
end
|
end
|
||||||
normal_status(0, "删除成功")
|
return normal_status(0, "删除成功")
|
||||||
else
|
else
|
||||||
normal_status(-1, "删除失败")
|
return normal_status(-1, "删除失败")
|
||||||
end
|
end
|
||||||
rescue => exception
|
rescue => exception
|
||||||
Rails.logger.info("#########_______exception.message_________##########{exception.message}")
|
Rails.logger.info("#########_______exception.message_________##########{exception.message}")
|
||||||
normal_status(-1, "删除失败")
|
normal_status(-1, "删除失败")
|
||||||
else
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def clean
|
def clean
|
||||||
#批量删除,暂时只能删除未悬赏的
|
|
||||||
issue_ids = params[:ids]
|
issue_ids = params[:ids]
|
||||||
issues = Issue.where(id: issue_ids, issue_type: "1")
|
issues = Issue.where(id: issue_ids, issue_type: "1")
|
||||||
if issues.present?
|
if issues.present?
|
||||||
|
@ -473,7 +491,8 @@ class IssuesController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def operate_issue_permission
|
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
|
end
|
||||||
|
|
||||||
def export_issues(issues)
|
def export_issues(issues)
|
||||||
|
|
|
@ -23,6 +23,7 @@ class JournalsController < ApplicationController
|
||||||
normal_status(-1, "评论内容不能为空")
|
normal_status(-1, "评论内容不能为空")
|
||||||
else
|
else
|
||||||
ActiveRecord::Base.transaction do
|
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 = {
|
journal_params = {
|
||||||
journalized_id: @issue.id ,
|
journalized_id: @issue.id ,
|
||||||
journalized_type: "Issue",
|
journalized_type: "Issue",
|
||||||
|
@ -53,6 +54,9 @@ class JournalsController < ApplicationController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
rescue Exception => exception
|
||||||
|
puts exception.message
|
||||||
|
normal_status(-1, exception.message)
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
|
@ -71,15 +75,18 @@ class JournalsController < ApplicationController
|
||||||
def update
|
def update
|
||||||
content = params[:content]
|
content = params[:content]
|
||||||
if content.present?
|
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)
|
if @journal.update_attribute(:notes, content)
|
||||||
normal_status(0, "更新成功")
|
normal_status(0, "更新成功")
|
||||||
else
|
else
|
||||||
normal_status(-1, "更新失败")
|
normal_status(-1, @journal.errors.messages.values[0][0])
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
normal_status(-1, "评论的内容不能为空")
|
normal_status(-1, "评论的内容不能为空")
|
||||||
end
|
end
|
||||||
|
rescue Exception => exception
|
||||||
|
puts exception.message
|
||||||
|
normal_status(-1, exception.message)
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_children_journals
|
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 :load_project
|
||||||
before_action :find_user_with_id, only: %i[create remove change_role]
|
before_action :find_user_with_id, only: %i[create remove change_role]
|
||||||
before_action :check_user_profile_completed, only: [:create]
|
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_exists!, only: %i[create]
|
||||||
before_action :check_member_not_exists!, only: %i[remove change_role]
|
before_action :check_member_not_exists!, only: %i[remove change_role]
|
||||||
|
|
||||||
|
@ -26,6 +26,9 @@ class MembersController < ApplicationController
|
||||||
|
|
||||||
@total_count = scope.size
|
@total_count = scope.size
|
||||||
@members = paginate(scope)
|
@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
|
end
|
||||||
|
|
||||||
def remove
|
def remove
|
||||||
|
@ -61,11 +64,14 @@ class MembersController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_member_exists!
|
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
|
end
|
||||||
|
|
||||||
def check_member_not_exists!
|
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
|
end
|
||||||
|
|
||||||
def check_user_profile_completed
|
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
|
|
@ -2,6 +2,8 @@ class Oauth::BaseController < ActionController::Base
|
||||||
include RenderHelper
|
include RenderHelper
|
||||||
include LoginHelper
|
include LoginHelper
|
||||||
include ControllerRescueHandler
|
include ControllerRescueHandler
|
||||||
|
include LoggerHelper
|
||||||
|
include RegisterHelper
|
||||||
# include LaboratoryHelper
|
# include LaboratoryHelper
|
||||||
|
|
||||||
skip_before_action :verify_authenticity_token
|
skip_before_action :verify_authenticity_token
|
||||||
|
@ -11,6 +13,18 @@ class Oauth::BaseController < ActionController::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
def tip_exception(status = -1, message)
|
||||||
|
raise Gitlink::TipException.new(status, message)
|
||||||
|
end
|
||||||
|
|
||||||
|
def tip_show_exception(status = -2, message)
|
||||||
|
raise Gitlink::TipException.new(status, message)
|
||||||
|
end
|
||||||
|
|
||||||
|
def tip_show(exception)
|
||||||
|
uid_logger("Tip show status is #{exception.status}, message is #{exception.message}")
|
||||||
|
render json: exception.tip_json
|
||||||
|
end
|
||||||
|
|
||||||
def session_user_id
|
def session_user_id
|
||||||
# session[:user_id]
|
# session[:user_id]
|
||||||
|
@ -22,7 +36,7 @@ class Oauth::BaseController < ActionController::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def auth_hash
|
def auth_hash
|
||||||
Rails.logger.info("[OAuth2] omniauth.auth -> #{request.env['omniauth.auth'].inspect}")
|
# Rails.logger.info("[OAuth2] omniauth.auth -> #{request.env['omniauth.auth'].inspect}")
|
||||||
request.env['omniauth.auth']
|
request.env['omniauth.auth']
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
class Oauth::CallbacksController < Oauth::BaseController
|
||||||
|
def create
|
||||||
|
process_callback
|
||||||
|
rescue Exception => e
|
||||||
|
Rails.logger.info "授权失败:#{e}"
|
||||||
|
tip_exception("授权失败")
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def config_providers
|
||||||
|
config = Rails.application.config_for(:configuration)
|
||||||
|
config.dig("oauth").keys
|
||||||
|
end
|
||||||
|
|
||||||
|
# QQ: {"ret":0,"msg":"","is_lost":0,"nickname":"颜值不算太高","gender":"男","gender_type":1,"province":"","city":"","year":"2013","constellation":"","figureurl":"http://qzapp.qlogo.cn/qzapp/101508858/0F860F4B329768F47B22341C5FD9089C/30","figureurl_1":"http://qzapp.qlogo.cn/qzapp/101508858/0F860F4B329768F47B22341C5FD9089C/50","figureurl_2":"http://qzapp.qlogo.cn/qzapp/101508858/0F860F4B329768F47B22341C5FD9089C/100","figureurl_qq_1":"http://thirdqq.qlogo.cn/g?b=oidb\u0026k=My3segFVHFqVmauibJQUltw\u0026s=40\u0026t=1568887757","figureurl_qq_2":"http://thirdqq.qlogo.cn/g?b=oidb\u0026k=My3segFVHFqVmauibJQUltw\u0026s=100\u0026t=1568887757","figureurl_qq":"http://thirdqq.qlogo.cn/g?b=oidb\u0026k=My3segFVHFqVmauibJQUltw\u0026s=140\u0026t=1568887757","figureurl_type":"1","is_yellow_vip":"0","vip":"0","yellow_vip_level":"0","level":"0","is_yellow_year_vip":"0"}
|
||||||
|
def process_callback
|
||||||
|
Rails.logger.info("[OAuth2] omniauth.auth -> #{request.env['omniauth.auth'].inspect}")
|
||||||
|
if auth_hash.blank?
|
||||||
|
redirect_to("/login") && return
|
||||||
|
end
|
||||||
|
|
||||||
|
new_user = false
|
||||||
|
platform = auth_hash[:provider]
|
||||||
|
uid = auth_hash[:uid]
|
||||||
|
mail = auth_hash.info.email || nil
|
||||||
|
nickname = ["gitee", "github"].include?(platform) ? auth_hash.info.name : auth_hash.info.nickname
|
||||||
|
|
||||||
|
open_user = "OpenUsers::#{platform.to_s.capitalize}".constantize.find_by(uid: uid)
|
||||||
|
if open_user.present? && open_user.user.present?
|
||||||
|
successful_authentication(open_user.user)
|
||||||
|
else
|
||||||
|
if current_user.blank? || !current_user.logged?
|
||||||
|
has_user = User.find_by(mail: mail)
|
||||||
|
if has_user.present?
|
||||||
|
"OpenUsers::#{platform.to_s.capitalize}".constantize.create!(user_id: has_user.id, uid: uid, extra: auth_hash.extra)
|
||||||
|
successful_authentication(has_user)
|
||||||
|
else
|
||||||
|
new_user = true
|
||||||
|
login = build_login_name(platform, auth_hash.info.nickname)
|
||||||
|
mail = "#{login}@example.org" if mail.blank?
|
||||||
|
code = %W(0 1 2 3 4 5 6 7 8 9)
|
||||||
|
rand_password = code.sample(10).join
|
||||||
|
reg_result = autologin_register(login, mail, rand_password, platform, nil, nickname)
|
||||||
|
Rails.logger.info("[OAuth2] omniauth.auth [reg_result] #{reg_result} ")
|
||||||
|
if reg_result[:message].blank?
|
||||||
|
open_user = "OpenUsers::#{platform.to_s.capitalize}".constantize.create!(user_id: reg_result[:user][:id], uid: uid, extra: auth_hash.extra)
|
||||||
|
successful_authentication(open_user.user)
|
||||||
|
else
|
||||||
|
tip_exception(reg_result.present? ? reg_result[:message] : "授权失败")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
"OpenUsers::#{platform.to_s.capitalize}".constantize.create!(user: current_user, uid: login, extra: auth_hash.extra)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
redirect_to root_path(new_user: new_user)
|
||||||
|
end
|
||||||
|
|
||||||
|
# gitee,github nickname=login,如果系统未占用保留原用户名
|
||||||
|
def build_login_name(provider, nickname)
|
||||||
|
if ["gitee", "github"].include?(provider) && User.find_by(login: nickname).blank?
|
||||||
|
nickname
|
||||||
|
else
|
||||||
|
User.generate_user_login('p')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -32,4 +32,41 @@ class Oauth::EducoderController < Oauth::BaseController
|
||||||
render_error(ex.message)
|
render_error(ex.message)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# 需要educoder那边设置回调地址
|
||||||
|
def create
|
||||||
|
begin
|
||||||
|
code = params['code'].to_s.strip
|
||||||
|
tip_exception("code不能为空") if code.blank?
|
||||||
|
|
||||||
|
new_user = false
|
||||||
|
result = EducoderOauth::Service.access_token(code)
|
||||||
|
result = EducoderOauth::Service.user_info(result[:access_token])
|
||||||
|
|
||||||
|
# 存在该用户
|
||||||
|
open_user = OpenUsers::Educoder.find_by(uid: result['login'])
|
||||||
|
if open_user.present? && open_user.user.present?
|
||||||
|
successful_authentication(open_user.user)
|
||||||
|
else
|
||||||
|
if current_user.blank? || !current_user.logged?
|
||||||
|
new_user = true
|
||||||
|
login = User.generate_login('E')
|
||||||
|
reg_result = autologin_register(login,"#{login}@forge.com", "Ec#{login}2021#", 'educoder', true)
|
||||||
|
if reg_result[:message].blank?
|
||||||
|
open_user = OpenUsers::Educoder.create!(user_id: reg_result[:user][:id], uid: result['login'], extra: result)
|
||||||
|
autosync_register_trustie(login, "Ec#{login}2021#", "#{login}@forge.com")
|
||||||
|
successful_authentication(open_user.user)
|
||||||
|
else
|
||||||
|
render_error(reg_result[:message])
|
||||||
|
end
|
||||||
|
else
|
||||||
|
OpenUsers::Educoder.create!(user: current_user, uid: result['login'], extra: result)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
redirect_to root_path(new_user: new_user)
|
||||||
|
rescue Exception => ex
|
||||||
|
render_error(ex.message)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
class Oauth::GitlinkController < Oauth::BaseController
|
||||||
|
def bind
|
||||||
|
begin
|
||||||
|
login = params[:login]
|
||||||
|
mail = params[:mail] || nil
|
||||||
|
callback_url = params[:callback_url]
|
||||||
|
token = params[:token]
|
||||||
|
|
||||||
|
::OauthEducoderForm.new({login: login, token: token, callback_url: callback_url}).validate!
|
||||||
|
|
||||||
|
open_user= OpenUsers::Gitlink.find_by(uid: login) || OpenUsers::Gitlink.find_by(uid: mail)
|
||||||
|
|
||||||
|
if open_user.present? && open_user.user.present? && open_user.user.email_binded?
|
||||||
|
Rails.logger.info "######## open_user exist and open_user.user exsit and email is binded ok"
|
||||||
|
successful_authentication(open_user.user)
|
||||||
|
|
||||||
|
redirect_to callback_url
|
||||||
|
else
|
||||||
|
Rails.logger.info "######## open user not exits"
|
||||||
|
user = User.find_by(login: login) || User.find_by(mail: mail)
|
||||||
|
|
||||||
|
if user.is_a?(User) && !user.is_a?(AnonymousUser)
|
||||||
|
OpenUsers::Gitlink.create!(user: user, uid: login)
|
||||||
|
successful_authentication(user)
|
||||||
|
|
||||||
|
redirect_to callback_url
|
||||||
|
else
|
||||||
|
redirect_to oauth_register_path(login: login, mail: mail, callback_url: callback_url)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
rescue WechatOauth::Error => ex
|
||||||
|
render_error(ex.message)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# 需要gitlink那边设置回调地址
|
||||||
|
def create
|
||||||
|
begin
|
||||||
|
code = params['code'].to_s.strip
|
||||||
|
tip_exception("code不能为空") if code.blank?
|
||||||
|
|
||||||
|
result = GitlinkOauth::Service.access_token(code)
|
||||||
|
result = GitlinkOauth::Service.user_info(result[:access_token])
|
||||||
|
login = result['login']
|
||||||
|
mail = result['email']
|
||||||
|
nickName = result['username']
|
||||||
|
new_user = false
|
||||||
|
# 存在该用户
|
||||||
|
open_user = OpenUsers::Gitlink.find_by(uid: login)
|
||||||
|
if open_user.present? && open_user.user.present?
|
||||||
|
successful_authentication(open_user.user)
|
||||||
|
else
|
||||||
|
if current_user.blank? || !current_user.logged?
|
||||||
|
has_user = User.find_by(mail: mail)
|
||||||
|
if has_user.present?
|
||||||
|
OpenUsers::Gitlink.create!(user_id: has_user.id, uid: login, extra: result)
|
||||||
|
successful_authentication(has_user)
|
||||||
|
else
|
||||||
|
new_user = true
|
||||||
|
login = User.generate_user_login('p')
|
||||||
|
mail = "#{login}@example.org" if mail.blank?
|
||||||
|
reg_result = autologin_register(login, mail, "Ec#{login}2021#", 'gitlink', nil, nickName)
|
||||||
|
Rails.logger.info("[Gitlink] [reg_result] #{reg_result} ")
|
||||||
|
if reg_result[:message].blank?
|
||||||
|
open_user = OpenUsers::Gitlink.create!(user_id: reg_result[:user][:id], uid: login, extra: result)
|
||||||
|
successful_authentication(open_user.user)
|
||||||
|
else
|
||||||
|
tip_exception(reg_result.present? ? reg_result[:message] : "授权失败")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
OpenUsers::Gitlink.create!(user: current_user, uid: login, extra: result)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
redirect_to root_path(new_user: new_user)
|
||||||
|
rescue Exception => ex
|
||||||
|
render_error(ex.message)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue