Compare commits

...

147 Commits

Author SHA1 Message Date
jasder 574f6561d1 ADD 后台管理特殊协议列表添加项目名称区分信息 2021-07-26 11:20:21 +08:00
jasder eaddf52cbd FIX 解决标签列表和发行版列表中下周zip包、tar包导致的404问题 2021-06-30 14:30:48 +08:00
jasder ef0a0e5ddd FIX [bug]cherry pick ce85273^..0bfed83 2021-06-23 17:56:04 +08:00
jasder ef81d61a0d FIX cherry pick ce85273^..0bfed83 2021-06-23 17:48:14 +08:00
jasder 071f913123 FIX code bug 2021-06-23 17:32:48 +08:00
jasder 6096fdd7bf FIX 解决在线创建文件错误提示信息不准确的问题 2021-06-23 17:31:45 +08:00
jasder 9ba297ccf6 FIX 后台管理系统添加用户时,自动为用户生成邮箱 2021-06-08 09:27:41 +08:00
jasder 66fd6a71e5 FIX 后台管理系统添加用户时,自动为用户生产登录名 2021-06-07 17:09:23 +08:00
jasder 89bc20e540 FIX 去掉User模型中的open_users关联 2021-06-07 16:44:17 +08:00
jasder 184a6bf1bf FIX 去掉User模型中的compose关联 2021-06-07 16:42:40 +08:00
jasder 8ee089b82d ADD 后台管理系统 添加新增用户功能 2021-06-04 18:01:03 +08:00
jasder abc21413ac Merge branch 'dev_military' of https://git.trustie.net/jasder/forgeplus into dev_military 2021-06-04 11:35:18 +08:00
vilet.yy ce89ce5169 fix:use concat_ws 2021-04-02 11:39:55 +08:00
vilet.yy b8a4c467fe fix 2021-04-02 11:29:30 +08:00
vilet.yy 300658f8dd fix: apply_signature filter 2021-04-02 11:18:28 +08:00
vilet.yy 9553740960 add: project order index 2021-03-17 15:47:01 +08:00
vilet.yy 1a8d9bb0ce [ADD]add police picture 2021-03-11 10:54:01 +08:00
vilet.yy 8c43f74b69 [ADD]job use model data 2021-03-10 14:11:56 +08:00
vilet.yy 3e7ae82258 [ADD]phenglei user list and cron job 2021-03-10 14:02:41 +08:00
vilet.yy 0aa75e077e [ADD]sync phenglei user job 2021-03-05 17:04:06 +08:00
vilet.yy 8aefcad510 [ADD]create project member rake 2021-03-05 17:04:06 +08:00
vilet.yy 622dcbaf4f Merge branch 'dev_military' of https://git.trustie.net/jasder/forgeplus into dev_military 2021-03-05 17:03:01 +08:00
jasder 6570125a36 Merge branch 'develop' of https://git.trustie.net/jasder/forgeplus into dev_military 2021-03-05 15:50:40 +08:00
jasder d91e8dcbfe Merge branch 'dev_military' of https://git.trustie.net/jasder/forgeplus into dev_military 2021-03-05 15:38:06 +08:00
jasder 0c2507b1e9 FIX valid user before register action 2021-03-05 15:37:41 +08:00
vilet.yy 8d29c2bd50 [FIX]org visit phenglei project 2021-03-05 09:50:03 +08:00
vilet.yy 774f632d9a Merge branch 'develop' into dev_military 2021-03-04 13:42:45 +08:00
vilet.yy 2969afd333 [FIX]project category correct projects_count 2021-03-01 16:23:29 +08:00
vilet.yy cc978c8dea [FIX]merge from develop 2021-03-01 13:59:30 +08:00
vilet.yy ce105b4c07 [FIX]project category not include private repo 2021-02-26 16:20:26 +08:00
vilet.yy b5870b1020 [FIX]lose role_name 2021-02-26 15:00:40 +08:00
vilet.yy 1edb3ce7ad [FIX]search projects error 2021-02-25 12:11:32 +08:00
jasder 59257b1caa FIX repo setting api for forbidden 2021-02-09 11:50:12 +08:00
Jasder b552e29aa3 ADD forge host and main web host for setting api 2021-02-04 11:43:11 +08:00
Jasder 21424a23f2 FIX change host 2021-02-04 11:12:51 +08:00
Jasder a82af669bd Merge branch 'dev_military' of http://git.trustie.net/jasder/forgeplus into dev_military 2021-01-28 15:22:53 +08:00
Jasder 0f01abd45f Merge branch 'develop' into dev_military 2021-01-28 15:21:43 +08:00
viletyy 80002be670 [FIX]项目列表total_count 2021-01-28 14:45:33 +08:00
Jasder f7e19cb3a4 Merge branch 'develop' into dev_military 2021-01-14 18:39:31 +08:00
Jasder 5cd6620413 Merge branch 'develop' into dev_military 2021-01-14 18:26:04 +08:00
Jasder f3a9124bdd Merge branch 'develop' into dev_military 2021-01-14 18:23:26 +08:00
Jasder d97a39a3a2 Merge branch 'develop' into dev_military 2021-01-14 17:05:50 +08:00
Jasder 987ff74690 FIX merge 2021-01-13 14:42:26 +08:00
Jasder 37be604e82 FIX [api] get pull files and commits bug 2021-01-13 14:40:23 +08:00
viletyy 83e2c1f889 [FIX]merge 2021-01-13 14:38:02 +08:00
viletyy 46a1c8877b [FIX]pull_request bug 2021-01-13 11:26:21 +08:00
Jasder 0aa39efe9b FIX code bug 2021-01-12 18:25:50 +08:00
Jasder 15d562d7b1 FIX delete batch import users with admin managerment 2021-01-12 18:15:01 +08:00
Jasder 5b261d6e81 FIX merge develop branch 2021-01-12 17:42:44 +08:00
viletyy 4693e77e02 [FIX] 2021-01-11 18:43:22 +08:00
viletyy fbf22ff0df [FIX]增加是否为成员参数 2021-01-11 17:52:58 +08:00
Jasder 0794f77a87 Merge branch 'develop' into dev_military 2021-01-06 14:00:51 +08:00
Jasder e5a46a242f FIX register with validate email 2021-01-06 11:03:00 +08:00
Jasder 4902237bd7 Merge branch 'dev_military_license' of http://git.trustie.net/jasder/forgeplus into dev_military_license 2021-01-06 10:44:37 +08:00
Jasder 4ddc60a1c3 FIX user register bug 2021-01-06 10:44:20 +08:00
viletyy cfa14fff9d [FIX] 2021-01-04 17:52:05 +08:00
viletyy ef327f2994 [FIX] 2021-01-04 16:19:11 +08:00
viletyy bf91c5e382 [FIX] 2021-01-04 15:32:44 +08:00
viletyy 9b687f7885 [FIX] 2021-01-04 15:22:03 +08:00
viletyy a072162324 [ADD]项目创建者审核申请 2021-01-04 12:27:12 +08:00
viletyy 8f1e0f39ea Merge branch 'dev_military_license' of https://git.trustie.net/jasder/forgeplus into dev_military_license 2020-12-31 14:03:06 +08:00
viletyy aaa6483958 [FIX]几处bug修复 2020-12-31 14:02:37 +08:00
Jasder bf730ca18f Merge branch 'dev_military_license' of http://git.trustie.net/jasder/forgeplus into dev_military_license 2020-12-29 18:20:46 +08:00
Jasder 132af875bc Merge branch 'master' into dev_military_license 2020-12-29 18:19:07 +08:00
viletyy a862d994ab [FIX]只有审核成功才添加成员 2020-12-29 18:08:10 +08:00
Jasder 604da93c5c FIX when add members to project, permission set to readable 2020-12-29 17:17:36 +08:00
Jasder 3f525f5779 FIX update model schema 2020-12-29 14:25:40 +08:00
viletyy 05d1e66ea9 [FIX] 2020-12-28 20:29:56 +08:00
viletyy 10c1cccf2c [FIX] 2020-12-28 19:42:59 +08:00
viletyy 27ec7ec7dd [ADD]simple去除访问限制,并加入字段 2020-12-28 18:41:28 +08:00
Jasder 43b4907565 Merge branch 'dev_military_license' of http://git.trustie.net/jasder/forgeplus into dev_military_license 2020-12-28 14:53:52 +08:00
Jasder cb90e1a13f FIX get branches bug 2020-12-28 14:53:30 +08:00
viletyy 749cd058c4 [FIX] 2020-12-28 12:57:58 +08:00
viletyy 47cc70f2c5 [ADD]增加下载文件接口 2020-12-28 12:31:05 +08:00
viletyy 5447d54d30 [FIX] 2020-12-28 10:26:50 +08:00
viletyy 6c436dd631 [ADD]后台审核特殊许可申请 2020-12-27 18:44:03 +08:00
viletyy 9eb7219b9a [FIX] 2020-12-25 18:58:03 +08:00
viletyy ad5fcb25c4 [ADD]接口文档 2020-12-25 17:51:42 +08:00
viletyy d42053ce0c [FIX]merge 2020-12-25 16:33:16 +08:00
viletyy 36bae71947 [ADD]增加特殊许可的验证 2020-12-25 16:17:46 +08:00
Jasder 837aa1ea9e FIX Merge master branch 2020-12-25 15:10:50 +08:00
Sylor-huang c283c7ed58 add: dun_check text and image 2020-11-30 19:36:30 +08:00
sylor_huang@126.com 4cf8588343 Reset Issue Closed_count 2020-09-27 11:17:22 +08:00
sylor_huang@126.com e75fad98f8 change admin projects 2020-09-18 13:41:44 +08:00
sylor_huang@126.com bc37c59f00 Change Header4 2020-09-16 15:08:35 +08:00
sylor_huang@126.com a6a745da93 Change Header1 2020-09-16 14:58:12 +08:00
sylor_huang@126.com 5bef80ee58 Change Index Category 2020-09-11 18:32:42 +08:00
sylor_huang@126.com f9bcc7e02b Close DunCheck 2020-09-07 16:33:26 +08:00
sylor_huang@126.com d35faf3935 Fix:Issues 2020-08-21 11:30:47 +08:00
sylor_huang@126.com 8d7dc9cb60 Test Push 2020-08-21 09:52:31 +08:00
sylor_huang@126.com 248d78d8c1 Merge branch 'dev_trustie' into dev_military 2020-08-20 18:10:07 +08:00
sylor_huang@126.com f632424f13 Change Like 2020-08-20 11:00:19 +08:00
sylor_huang@126.com 95ede63220 Change 2020-08-19 17:58:04 +08:00
sylor_huang@126.com 8fac294d04 Add UserAction Ip 2020-08-18 18:16:58 +08:00
sylor_huang@126.com d67c12beba Ignore migrate files 2020-08-18 18:10:05 +08:00
sylor_huang@126.com a7e4b85352 Change Confilct 2020-08-18 17:54:35 +08:00
Jasder 2ac2920399 FIX merge dev_trustie branch 2020-08-18 17:39:37 +08:00
Jasder 230b934de4 Update remote register forr military platform 2020-08-18 17:33:12 +08:00
sylor_huang@126.com e0bedf175f Change Dun Check 2020-08-18 11:02:09 +08:00
sylor_huang@126.com c9a263e03c Add Dun Check For Project 2020-08-18 10:36:13 +08:00
Jasder 2bd15d9746 Merge branch 'dev_trustie' into dev_military 2020-08-17 18:52:00 +08:00
sylor_huang@126.com fc9588fb63 Add Dun Check 2020-08-17 18:49:18 +08:00
sylor_huang@126.com e611b519ab Fix: Admins page remove .educoer.net words 2020-08-13 14:21:13 +08:00
sylor_huang@126.com 3dd3944ebd Fix: Unknow attribute private for project 2020-08-13 13:50:07 +08:00
sylor_huang@126.com f417bf3308 Change User Defautl Picture 2020-08-13 10:01:13 +08:00
sylor_huang@126.com 9c7c914d12 Change 2020-08-12 18:07:43 +08:00
sylor_huang@126.com b088befae7 Change 2020-08-12 16:39:10 +08:00
sylor_huang@126.com d3636e686b CHange 2020-08-12 16:27:42 +08:00
sylor_huang@126.com 88d98f0ac4 Change 2020-08-12 16:24:30 +08:00
sylor_huang@126.com db6aa954b1 Change 2020-08-12 16:18:16 +08:00
sylor_huang@126.com 04a611a4aa Change 2020-08-12 16:01:42 +08:00
sylor_huang@126.com 9ecea83506 Change 2020-08-12 15:43:55 +08:00
sylor_huang@126.com 82a9907fdc change 2020-08-12 15:31:56 +08:00
sylor_huang@126.com c56c98fd6e Change 2020-08-12 15:30:39 +08:00
sylor_huang@126.com 2948ad2033 Change 2020-08-12 15:28:09 +08:00
sylor_huang@126.com fc611140cf change 2020-08-12 15:25:16 +08:00
sylor_huang@126.com fcb5f58b69 change 2020-08-12 15:15:44 +08:00
sylor_huang@126.com 0f38a130f3 Change 2020-08-12 15:12:26 +08:00
sylor_huang@126.com fc54632a08 Change 2020-08-12 14:45:45 +08:00
sylor_huang@126.com 5963af5c7b Change Sidekiq 2020-08-12 14:41:53 +08:00
sylor_huang@126.com c1f2f7f6e2 Build 2020-08-12 14:06:32 +08:00
sylor_huang@126.com 271699daf1 Change 2020-08-12 11:54:20 +08:00
sylor_huang@126.com 98da7ea34d Change 2020-08-12 11:49:55 +08:00
sylor_huang@126.com 645e4a3586 Change 2020-08-12 11:45:57 +08:00
sylor_huang@126.com 7beca24a05 Change 2020-08-12 11:42:22 +08:00
sylor_huang@126.com d1368c7612 Change 2020-08-12 11:14:37 +08:00
sylor_huang@126.com 28e762810e Set 2020-08-12 10:45:54 +08:00
sylor_huang@126.com 0f60d0adc9 Change 2020-08-11 17:13:42 +08:00
sylor_huang@126.com e634317675 CHnage 2020-08-11 17:11:56 +08:00
sylor_huang@126.com 6b1a0a96c6 CHange 2020-08-11 17:09:48 +08:00
sylor_huang@126.com 298859bd10 Change 2020-08-11 17:07:15 +08:00
sylor_huang@126.com d4d412ab40 Change 2020-08-11 17:00:56 +08:00
sylor_huang@126.com 57d1a1474e Change 2020-08-11 16:21:43 +08:00
sylor_huang@126.com 055b7dbac5 Change 2020-08-11 15:56:37 +08:00
sylor_huang@126.com 30aad87e5a Change 2020-08-11 15:49:03 +08:00
sylor_huang@126.com aecd68fe9a Chnage 2020-08-11 15:44:10 +08:00
sylor_huang@126.com 998a6828d9 change 2020-08-11 15:34:50 +08:00
sylor_huang@126.com 12c04d02e5 Change 2020-08-11 15:30:12 +08:00
sylor_huang@126.com d6ef3d8aa3 Change 2020-08-11 15:23:49 +08:00
sylor_huang@126.com c7a89d1660 Change 2020-08-11 14:49:53 +08:00
sylor_huang@126.com 1939c0d33f Set Auto Login 2020-08-11 11:28:49 +08:00
Jasder 561b9efd92 FIX change manager main site url 2020-08-10 12:08:00 +08:00
Jasder 6c0b87fdd1 FIX bug 2020-08-10 11:26:15 +08:00
Jasder 5d309d1dc4 FIX bug 2020-08-10 11:24:59 +08:00
Jasder 89c230c362 FIX 处理顶部导航错误的问题 2020-08-10 11:23:01 +08:00
Jasder d4156a5582 Delete some url with setting api 2020-08-09 22:07:16 +08:00
Jasder ee8cbb8553 FIX 调整云上实验配置 2020-08-07 14:34:26 +08:00
151 changed files with 20189 additions and 1108 deletions

View File

@ -284,6 +284,7 @@ http://localhost:3000/api/licenses/ | jq
|licenses|array |返回数据| |licenses|array |返回数据|
|-- id |int |id | |-- id |int |id |
|-- name |string|开源许可证名称| |-- name |string|开源许可证名称|
|-- is_secret |string|是否为特殊许可证|
返回值 返回值
@ -292,23 +293,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
} }
] ]
} }
@ -554,6 +565,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|项目是否为特殊协议项目, truefalse: 否 |
返回值 返回值
@ -566,7 +579,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
} }
``` ```
--- ---
@ -1146,6 +1160,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|项目创建者|
@ -1156,6 +1171,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':审核通过|
返回值 返回值
@ -1171,6 +1190,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": {
@ -1184,7 +1204,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,
@ -1194,6 +1220,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": {
@ -1207,7 +1234,8 @@ http://localhost:3000/api/projects | jq
"language": { "language": {
"id": 2, "id": 2,
"name": "C" "name": "C"
} },
"user_apply_signatures":[]
}, },
{ {
"id": 3, "id": 3,
@ -1217,6 +1245,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": {
@ -1230,7 +1259,8 @@ http://localhost:3000/api/projects | jq
"language": { "language": {
"id": 2, "id": 2,
"name": "C" "name": "C"
} },
"user_apply_signatures":[]
}, },
{ {
"id": 5, "id": 5,
@ -1240,6 +1270,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": {
@ -1253,7 +1284,8 @@ http://localhost:3000/api/projects | jq
"language": { "language": {
"id": 2, "id": 2,
"name": "C" "name": "C"
} },
"user_apply_signatures":[]
}, },
{ {
"id": 7, "id": 7,
@ -1263,6 +1295,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": {
@ -1276,7 +1309,8 @@ http://localhost:3000/api/projects | jq
"language": { "language": {
"id": 2, "id": 2,
"name": "C" "name": "C"
} },
"user_apply_signatures":[]
} }
] ]
} }
@ -5016,6 +5050,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|项目创建者|
@ -5026,7 +5061,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
@ -5041,6 +5078,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": {
@ -5054,9 +5092,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"
}
```
---

View File

@ -242,9 +242,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_cookie_name)
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,

View File

@ -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

View File

@ -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

View File

@ -1,4 +1,5 @@
class Admins::ProjectsController < Admins::BaseController class Admins::ProjectsController < Admins::BaseController
before_action :load_project, only: [:sync_phenglei_user]
def index def index
sort_by = params[:sort_by] ||= 'created_on' sort_by = params[:sort_by] ||= 'created_on'
@ -6,7 +7,7 @@ class Admins::ProjectsController < Admins::BaseController
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 destroy def destroy
@ -22,4 +23,20 @@ class Admins::ProjectsController < Admins::BaseController
redirect_to admins_projects_path redirect_to admins_projects_path
flash[:danger] = "删除失败" flash[:danger] = "删除失败"
end 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
def load_project
@project = Project.find_by!(id: params[:id])
end
end end

View File

@ -58,11 +58,58 @@ class Admins::UsersController < Admins::BaseController
render_ok render_ok
end end
private 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
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]) password professional_certification authentication])
end 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

View File

@ -28,7 +28,7 @@ class ApplicationController < ActionController::Base
DCODES = %W(2 3 4 5 6 7 8 9 a b c f e f g h i j k l m n o p q r s t u v w x y z) DCODES = %W(2 3 4 5 6 7 8 9 a b c f e f g h i j k l m n o p q r s t u v w x y z)
OPENKEY = "79e33abd4b6588941ab7622aed1e67e8" OPENKEY = "79e33abd4b6588941ab7622aed1e67e8"
helper_method :current_user helper_method :current_user, :base_url
# 所有请求必须合法签名 # 所有请求必须合法签名
def check_sign def check_sign
@ -374,7 +374,7 @@ 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_cookie_name)
# start_user_session(user) if user # TODO 解决sso退出不同步的问题 # start_user_session(user) if user # TODO 解决sso退出不同步的问题
user user
end end
@ -770,6 +770,10 @@ class ApplicationController < ActionController::Base
@repository ||= load_project&.repository @repository ||= load_project&.repository
end end
def base_url
Rails.application.config_for(:configuration)['platform_url'] || request.base_url
end
private private
def object_not_found def object_not_found
uid_logger("Missing template or cant't find record, responding with 404") uid_logger("Missing template or cant't find record, responding with 404")

View File

@ -0,0 +1,75 @@
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
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)
end
end

View File

@ -42,6 +42,7 @@ class AttachmentsController < ApplicationController
# 2. 上传到云 # 2. 上传到云
begin begin
upload_file = params["file"] || params["#{params[:file_param_name]}"]# 这里的file_param_name是为了方便其他插件名称 upload_file = params["file"] || params["#{params[:file_param_name]}"]# 这里的file_param_name是为了方便其他插件名称
dun_check_file = upload_file.dup
uid_logger("#########################file_params####{params["#{params[:file_param_name]}"]}") uid_logger("#########################file_params####{params["#{params[:file_param_name]}"]}")
raise "未上传文件" unless upload_file raise "未上传文件" unless upload_file
@ -79,8 +80,16 @@ class AttachmentsController < ApplicationController
@attachment.digest = digest @attachment.digest = digest
@attachment.author_id = current_user.id @attachment.author_id = current_user.id
@attachment.disk_directory = month_folder @attachment.disk_directory = month_folder
@attachment.cloud_url = remote_path # @attachment.cloud_url = remote_path
@attachment.save! # @attachment.save!
if @attachment.save!
check_result = Attachment.check_image_able(dun_check_file)
if check_result[:status].to_i == -1
@attachment.destroy
raise "上传失败,#{check_result[:message]}"
# return render json: {status: -1, message: "上传失败,#{check_result[:message]}" }
end
end
else else
logger.info "文件已存在id = #{@attachment.id}, filename = #{@attachment.filename}" logger.info "文件已存在id = #{@attachment.id}, filename = #{@attachment.filename}"
end end

View File

@ -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,29 @@ 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: "https://www.trustie.net/", # 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: "#{main_web_site_url}/user_join"
} }
end end
def manager_main_site_url
{name: '管理', link: "#{main_web_site_url}/managements"}
end
def main_web_site_url
EduSetting.get('host_main_site')
end
def current_main_site_url
EduSetting.get('host_name')
end
end end

View File

@ -6,14 +6,12 @@ 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 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_cookie_name)
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,

View File

@ -3,8 +3,11 @@ module RegisterHelper
def autologin_register(username, email, password, platform= 'forge') def autologin_register(username, email, password, platform= 'forge')
result = {message: nil, user: nil} result = {message: nil, user: nil}
email = email.blank? ? "#{username}@example.org" : email
user = User.find_by(login: username)
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.activate user.activate
@ -18,7 +21,7 @@ module RegisterHelper
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 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

View File

@ -6,7 +6,6 @@ class IssuesController < ApplicationController
before_action :check_project_public, only: [:index ,:show, :copy, :index_chosen, :close_issue] before_action :check_project_public, only: [:index ,:show, :copy, :index_chosen, :close_issue]
before_action :set_issue, only: [:edit, :update, :destroy, :show, :copy, :close_issue, :lock_issue] before_action :set_issue, only: [:edit, :update, :destroy, :show, :copy, :close_issue, :lock_issue]
before_action :check_token_enough, only: [:create, :update]
include ApplicationHelper include ApplicationHelper
include TagChosenHelper include TagChosenHelper
@ -96,7 +95,8 @@ class IssuesController < ApplicationController
end end
def new def new
@issue_chosen = get_associated_data(@project) # @all_branches = get_branches
@issue_chosen = issue_left_chosen(@project, nil)
end end
def create def create
@ -132,15 +132,10 @@ class IssuesController < ApplicationController
tiding_type: 'issue', status: 0) tiding_type: 'issue', status: 0)
end end
#为悬赏任务时, 扣除当前用户的积分
if params[:issue_type].to_s == "2"
post_to_chain("minus", params[:token].to_i, current_user.try(:login))
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")
render json: {status: 0, message: "创建成", id: @issue.id} render json: {status: 0, message: "创建成", id: @issue.id}
else else
normal_status(-1, "创建失败") normal_status(-1, @issue.errors.messages.values[0][0])
end end
end end
@ -149,13 +144,12 @@ 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
last_token = @issue.token issue_params = issue_send_params(params).except(:issue_classify, :author_id, :project_id)
last_status_id = @issue.status_id return normal_status(-1, "您没有权限修改token") if @issue.will_save_change_to_token? && @issue.user_id != current_user&.id
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? && !@issue&.issue_tags_relates.where(issue_tag_id: params[:issue_tag_ids]).exists?
@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|
@ -163,22 +157,23 @@ class IssuesController < ApplicationController
end end
end end
issue_files = params[:attachment_ids] if @issue.update_attributes(issue_params)
change_files = false issue_files = params[:attachment_ids]
issue_file_ids = [] change_files = false
issue_file_ids = []
if issue_files.present? if issue_files.present?
change_files = true change_files = true
issue_files.each do |id| issue_files.each do |id|
attachment = Attachment.select(:id, :container_id, :container_type)&.find_by_id(id) attachment = Attachment.select(:id, :container_id, :container_type)&.find_by_id(id)
unless attachment.blank? unless attachment.blank?
attachment.container = @issue attachment.container = @issue
attachment.author_id = current_user.id attachment.author_id = current_user.id
attachment.description = "" attachment.description = ""
attachment.save attachment.save
end
end 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)
@ -194,35 +189,15 @@ class IssuesController < ApplicationController
# end # end
# end # end
if @issue.issue_type.to_s == "2" && params[:status_id].to_i == 5 && @issue.author_id != current_user.try(:id) if params[:status_id].to_i == 5
normal_status(-1, "不允许修改为关闭状态") @issue.issue_times.update_all(end_time: Time.now)
else #@issue.update_closed_issues_count_in_project!
issue_params = issue_send_params(params).except(:issue_classify, :author_id, :project_id)
if @issue.update_attributes(issue_params)
if params[:status_id].to_i == 5 #任务由非关闭状态到关闭状态时
@issue.issue_times.update_all(end_time: Time.now)
@issue.update_closed_issues_count_in_project!
if @issue.issue_type.to_s == "2" && last_status_id != 5
if @issue.assigned_to_id.present? && last_status_id == 3 #只有当用户完成100%时才给token
post_to_chain("add", @issue.token, @issue.get_assign_user.try(:login))
else
post_to_chain("add", @issue.token, @issue.user.try(:login))
end
end
end
if @issue.issue_type.to_s == "2" && @issue.status_id != 5 && @issue.saved_change_to_attribute("token")
#表示修改token值
change_token = last_token - @issue.token
change_type = change_token > 0 ? "add" : "minus"
post_to_chain(change_type, change_token.abs, current_user.try(:login))
end
@issue.create_journal_detail(change_files, issue_files, issue_file_ids, current_user&.id)
normal_status(0, "更新成功")
else
normal_status(-1, "更新失败")
end end
@issue.create_journal_detail(change_files, issue_files, issue_file_ids, current_user&.id)
normal_status(0, "更新成功")
else
normal_status(-1, @issue.errors.messages.values[0][0])
end end
end end
@ -243,32 +218,17 @@ class IssuesController < ApplicationController
end end
def destroy def destroy
begin if @issue.destroy
issue_type = @issue.issue_type normal_status(0, "删除成功")
status_id = @issue.status_id
token = @issue.token
login = @issue.user.try(:login)
if @issue.destroy
if issue_type == "2" && status_id != 5
post_to_chain("add", token, login)
end
normal_status(0, "删除成功")
else
normal_status(-1, "删除失败")
end
rescue => exception
Rails.logger.info("#########_______exception.message_________##########{exception.message}")
normal_status(-1, "删除失败")
else else
normal_status(-1, "删除失败")
end end
end end
def clean def clean
#批量删除,暂时只能删除未悬赏的
issue_ids = params[:ids] issue_ids = params[:ids]
if issue_ids.present? if issue_ids.present?
if Issue.where(id: issue_ids, issue_type: "1").destroy_all if Issue.where(id: issue_ids).destroy_all
normal_status(0, "删除成功") normal_status(0, "删除成功")
else else
normal_status(-1, "删除失败") normal_status(-1, "删除失败")
@ -460,32 +420,4 @@ class IssuesController < ApplicationController
project_id: @project.id project_id: @project.id
} }
end end
def post_to_chain(type, amount,login)
change_params = {
type: type,
chain_params: {
amount: amount,
reponame: @project.try(:identifier),
username: login
}
}
PostChainJob.perform_later(change_params)
end
def check_token_enough
if params[:issue_type].to_s == "2" && (@issue.blank? || (@issue.present? && @issue.author_id == current_user.try(:id)))
return normal_status(-1, "悬赏的奖金必须大于0") if params[:token].to_i == 0
query_params = {
type: "query",
chain_params: {
reponame: @project.try(:identifier),
username: current_user.try(:login)
}
}
response = Gitea::Chain::ChainGetService.new(query_params).call
return normal_status(-1, "获取token失败请稍后重试") if response.status != 200
return normal_status(-1, "您的token值不足") if JSON.parse(response.body)["balance"].to_i < params[:token].to_i
end
end
end end

View File

@ -46,7 +46,7 @@ class JournalsController < ApplicationController
render :json => { status: 0, message: "评论成功", id: journal.id} render :json => { status: 0, message: "评论成功", id: journal.id}
# normal_status(0, "评论成功") # normal_status(0, "评论成功")
else else
normal_status(-1, "评论失败") normal_status(-1, journal.errors.messages.values[0][0])
end end
end end
end end
@ -70,7 +70,7 @@ class JournalsController < ApplicationController
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, "评论的内容不能为空")

View File

@ -18,7 +18,7 @@ class MembersController < ApplicationController
scope = @project.members.includes(:roles, user: :user_extension) scope = @project.members.includes(:roles, user: :user_extension)
search = params[:search].to_s.downcase search = params[:search].to_s.downcase
role = params[:role].to_s role = params[:role].to_s
scope = scope.joins(:user).where("LOWER(concat(users.lastname, users.firstname, users.login, users.mail)) LIKE ?", "%#{search.split(" ").join('|')}%") if search.present? scope = scope.joins(:user).where("LOWER(CONCAT_WS(users.lastname, users.firstname, users.login, users.mail, users.nickname)) LIKE ?", "%#{search.split(" ").join('|')}%") if search.present?
scope = scope.joins(:roles).where("roles.name LIKE ?", "%#{role}%") if role.present? scope = scope.joins(:roles).where("roles.name LIKE ?", "%#{role}%") if role.present?
@total_count = scope.size @total_count = scope.size

View File

@ -8,7 +8,7 @@ class Oauth::EducoderController < Oauth::BaseController
::OauthEducoderForm.new({login: login, token: token, callback_url: callback_url}).validate! ::OauthEducoderForm.new({login: login, token: token, callback_url: callback_url}).validate!
open_user= OpenUsers::Educoder.find_by(uid: login) || OpenUsers::Educoder.find_by(uid: mail) open_user= OpenUsers::Educoder.find_by(uid: login)
if open_user.present? && open_user.user.present? && open_user.user.email_binded? 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" Rails.logger.info "######## open_user exist and open_user.user exsit and email is binded ok"

View File

@ -7,7 +7,5 @@ class ProjectCategoriesController < ApplicationController
def group_list def group_list
@project_categories = ProjectCategory.where('projects_count > 0').order(projects_count: :desc) @project_categories = ProjectCategory.where('projects_count > 0').order(projects_count: :desc)
# projects = Project.no_anomory_projects.visible
# @category_group_list = projects.joins(:project_category).group("project_categories.id", "project_categories.name").size
end end
end end

View File

@ -3,7 +3,7 @@ class ProjectsController < ApplicationController
include OperateProjectAbilityAble include OperateProjectAbilityAble
include ProjectsHelper include ProjectsHelper
before_action :require_login, except: %i[index branches group_type_list simple show fork_users praise_users watch_users recommend about] before_action :require_login, except: %i[index branches group_type_list simple show fork_users praise_users watch_users recommend about]
before_action :load_project, except: %i[index group_type_list migrate create recommend] before_action :load_repository, except: %i[index group_type_list migrate create recommend]
before_action :authorizate_user_can_edit_project!, only: %i[update] before_action :authorizate_user_can_edit_project!, only: %i[update]
before_action :project_public?, only: %i[fork_users praise_users watch_users] before_action :project_public?, only: %i[fork_users praise_users watch_users]
@ -11,10 +11,10 @@ class ProjectsController < ApplicationController
scope = Projects::ListQuery.call(params) scope = Projects::ListQuery.call(params)
# @projects = kaminari_paginate(scope) # @projects = kaminari_paginate(scope)
@projects = paginate scope.includes(:project_category, :project_language, :repository, :project_educoder, :owner) @projects = kaminari_paginate scope.includes(:project_category, :project_language, :repository, :project_educoder, :apply_signatures, :members, :owner)
category_id = params[:category_id] category_id = params[:category_id]
@total_count = @total_count = @projects.total_count
if category_id.blank? if category_id.blank?
ps = ProjectStatistic.first ps = ProjectStatistic.first
ps.common_projects_count + ps.mirror_projects_count unless ps.blank? ps.common_projects_count + ps.mirror_projects_count unless ps.blank?
@ -48,23 +48,14 @@ class ProjectsController < ApplicationController
end end
def group_type_list def group_type_list
project_statics = ProjectStatistic.first # if current_user&.logged?
# projects = Project.list_user_projects(current_user.id)
@project_statics_list = [ # else
{ # projects = Project.visible
project_type: 'common', # end
name: '开源托管项目', projects = Project.no_anomory_projects.secret_and_visible
projects_count: project_statics&.common_projects_count || 0 language_lists = projects.joins(:project_language).group("project_languages.name", "project_languages.id").size.keys.sort.to_h
}, @project_group_list = language_lists.delete_if { |k, v| k.blank? }
{
project_type: 'mirror',
name: '开源镜像项目',
projects_count: project_statics&.mirror_projects_count || 0
}
]
# projects = Project.no_anomory_projects.visible
# @project_group_list = projects.group(:project_type).size
end end
def update def update
@ -147,7 +138,6 @@ class ProjectsController < ApplicationController
end end
if @project_detail.save! if @project_detail.save!
attachment_ids = Array(params[:attachment_ids]) attachment_ids = Array(params[:attachment_ids])
logger.info "=============> #{Array(params[:attachment_ids])}"
@attachments = Attachment.where(id: attachment_ids) @attachments = Attachment.where(id: attachment_ids)
@attachments.update_all( @attachments.update_all(
container_id: @project_detail.id, container_id: @project_detail.id,

View File

@ -104,8 +104,10 @@ class PullRequestsController < ApplicationController
normal_status(-1, "PullRequest更新失败") normal_status(-1, "PullRequest更新失败")
end end
else else
normal_status(-1, "PullRequest更新失败") normal_status(-1, @pull_request.errors.messages.values[0][0])
end end
else
normal_status(-1, @issue.errors.messages.values[0][0])
end end
rescue => e rescue => e
normal_status(-1, e.message) normal_status(-1, e.message)

View File

@ -5,9 +5,9 @@ class RepositoriesController < ApplicationController
before_action :require_login, only: %i[edit update create_file update_file delete_file sync_mirror] before_action :require_login, only: %i[edit update create_file update_file delete_file sync_mirror]
before_action :load_repository before_action :load_repository
before_action :authorizate!, except: [:sync_mirror, :tags, :commit] before_action :authorizate!, except: [:sync_mirror, :tags, :commit, :archive]
before_action :authorizate_user_can_edit_repo!, only: %i[sync_mirror] before_action :authorizate_user_can_edit_repo!, only: %i[sync_mirror]
before_action :get_ref, only: %i[entries sub_entries top_counts] before_action :get_ref, only: %i[entries sub_entries top_counts file archive]
before_action :get_latest_commit, only: %i[entries sub_entries top_counts] before_action :get_latest_commit, only: %i[entries sub_entries top_counts]
before_action :get_statistics, only: %i[top_counts] before_action :get_statistics, only: %i[top_counts]
@ -157,6 +157,19 @@ class RepositoriesController < ApplicationController
render json: languages_precentagable render json: languages_precentagable
end end
def archive
domain = Gitea.gitea_config[:domain]
api_url = Gitea.gitea_config[:base_url]
archive_url = "/repos/#{@owner.login}/#{@repository.identifier}/archive/#{params[:archive]}"
file_path = [domain, api_url, archive_url].join
file_path = [file_path, "access_token=#{current_user&.gitea_token}"].join("?") if @repository.hidden?
return render_not_found if !request.format.zip? && !request.format.gzip?
redirect_to file_path
end
private private
def find_project def find_project
@ -231,7 +244,7 @@ class RepositoriesController < ApplicationController
# uploadPushInfo # uploadPushInfo
end end
def create_new_pr(params) def create_new_pr(params)
if params[:new_branch].present? && params[:new_branch] != params[:branch] if params[:new_branch].present? && params[:new_branch] != params[:branch]
local_params = { local_params = {

View File

@ -1,6 +1,4 @@
class SettingsController < ApplicationController class SettingsController < ApplicationController
def show def show
@old_projects_url = nil
@old_projects_url = "https://www.trustie.net/users/#{current_user.try(:login)}/projects" if User.current.logged?
end end
end end

View File

@ -309,12 +309,12 @@ class SyncForgeController < ApplicationController
# end # end
# end # end
# def check_token # # def check_token
# sync_params = params[:sync_params] # # sync_params = params[:sync_params]
# unless sync_params[:token] && sync_params[:token] == get_token # # unless sync_params[:token] && sync_params[:token] == get_token
# render json: {message: "token_errors"} # # render json: {message: "token_errors"}
# end # # end
# end # # end
# def get_token # def get_token
# "34c82f51e0b699d9d16d70fd6497c9b1e4821d6ea3e872558a6537a091076b8e" # "34c82f51e0b699d9d16d70fd6497c9b1e4821d6ea3e872558a6537a091076b8e"

View File

@ -155,8 +155,7 @@ class UsersController < ApplicationController
# 其他平台登录后必须将token同步到forge平台实现sso登录功能 # 其他平台登录后必须将token同步到forge平台实现sso登录功能
def sync_token def sync_token
return render_error('未找相关用户!') unless @user return render_error('未找相关用户!') unless @user
token = Token.get_or_create_permanent_login_token(@user, autologin_cookie_name)
token = Token.get_or_create_permanent_login_token(@user, 'autologin')
token.update_column(:value, params[:token]) token.update_column(:value, params[:token])
render_ok render_ok
end end

View File

@ -83,7 +83,7 @@ class VersionsController < ApplicationController
if version.save if version.save
normal_status(0, "里程碑创建成功") normal_status(0, "里程碑创建成功")
else else
normal_status(-1, "里程碑创建失败") normal_status(-1, version.errors.messages.values[0][0])
end end
end end
@ -121,7 +121,7 @@ class VersionsController < ApplicationController
if @version.update_attributes(tag_params) if @version.update_attributes(tag_params)
normal_status(0, "里程碑更新成功") normal_status(0, "里程碑更新成功")
else else
normal_status(-1, "里程碑更新失败") normal_status(-1, version.errors.messages.values[0][0])
end end
end end
else else

View File

@ -1,13 +1,24 @@
class Contents::CreateForm < BaseForm class Contents::CreateForm < BaseForm
attr_accessor :filepath, :branch, :new_branch attr_accessor :filepath, :branch, :new_branch, :content
validates :filepath, presence: true validates :filepath, presence: true
validate :check_branch validate :check_branch
validate :dun_content_check
def check_branch def check_branch
raise "branch和new_branch必须存在一个 " if branch.blank? && new_branch.blank? raise "branch和new_branch必须存在一个 " if branch.blank? && new_branch.blank?
# raise "branch和new_branch只能存在一个" if !branch.blank? && !new_branch.blank? # raise "branch和new_branch只能存在一个" if !branch.blank? && !new_branch.blank?
end end
def dun_content_check
if content.present?
check_result = DunCheck::TextCheck.new({title: "", content: content}).call
if check_result[:status].to_i == -1
raise "内容含有:#{check_result[:extra_params][:infos]},请修改"
end
end
end
end end

View File

@ -0,0 +1,11 @@
class Users::AdminCreateUserForm
include ActiveModel::Model
attr_accessor :phone, :password
validates :phone, presence: true, format: { with: CustomRegexp::PHONE, message: "手机号格式错误" }
validates :password, presence: true, length: { minimum: 8, maximum: 16 }, format: { with: CustomRegexp::PASSWORD, message: "8~16位密码支持字母数字和符号" }
end

View File

@ -149,7 +149,7 @@ module ApplicationHelper
File.join("images/avatars", ["#{source.class}", "#{source.id}"]) + "?t=#{ctime}" File.join("images/avatars", ["#{source.class}", "#{source.id}"]) + "?t=#{ctime}"
end end
elsif source.class.to_s == 'User' elsif source.class.to_s == 'User'
str = source.user_extension.try(:gender).to_i == 0 ? "b" : "g" str = source.user_extension.try(:gender).to_i == 0 ? "boy.jpg" : "girl.jpg"
File.join(relative_path, "#{source.class}", str) File.join(relative_path, "#{source.class}", str)
elsif source.class.to_s == 'Subject' elsif source.class.to_s == 'Subject'
File.join("images","educoder", "index", "subject", "subject#{rand(17)}.jpg") File.join("images","educoder", "index", "subject", "subject#{rand(17)}.jpg")

View File

@ -8,12 +8,12 @@ module ProjectsHelper
end end
end end
def render_zip_url(project, archive_name) def render_zip_url(owner, repository, archive)
[gitea_domain, project.owner.login, project.identifier, "archive", "#{archive_name}.zip"].join('/') [base_url, archive_repositories_path(owner&.login, repository, "#{archive}.zip")].join
end end
def render_tar_url(project, archive_name) def render_tar_url(owner, repository, archive)
[gitea_domain, project.owner.login, project.identifier, "archive", "#{archive_name}.tar.gz"].join('/') [base_url, archive_repositories_path(owner&.login, repository, "#{archive}.tar.gz")].join
end end
def render_http_url(project) def render_http_url(project)
@ -50,7 +50,10 @@ module ProjectsHelper
repo_id: repo.id, repo_id: repo.id,
open_devops: (user.blank? || user.is_a?(AnonymousUser)) ? false : project.open_devops?, open_devops: (user.blank? || user.is_a?(AnonymousUser)) ? false : project.open_devops?,
type: project.numerical_for_project_type, type: project.numerical_for_project_type,
author: render_owner(project) author: render_owner(project),
is_secret: project.is_secret,
is_member: project.member?(user.id),
user_apply_signatures: project.apply_signatures.with_user_id(user.id).collect{|s| {id: s.id, status: s.status}}
}).compact }).compact
render json: tmp_json render json: tmp_json

View File

@ -24,8 +24,14 @@ module Gitea
def run def run
Contents::CreateForm.new(valid_params).validate! Contents::CreateForm.new(valid_params).validate!
response = Gitea::Repository::Entries::CreateService.new(token, owner, @params[:identifier], @params[:filepath], file_params).call result = Gitea::Repository::Entries::CreateService.call(token,
render_result(response) owner, @params[:identifier], @params[:filepath], file_params)
if result[:status] == :success
@result = result[:body]
else
fail!(result[:message])
end
rescue Exception => exception rescue Exception => exception
Rails.logger.info "Exception ===========> #{exception.message}" Rails.logger.info "Exception ===========> #{exception.message}"
fail!(exception.message) fail!(exception.message)
@ -48,7 +54,8 @@ module Gitea
{ {
filepath: @params[:filepath], filepath: @params[:filepath],
branch: @params[:branch], branch: @params[:branch],
new_branch: @params[:new_branch] new_branch: @params[:new_branch],
content: @params[:content]
} }
end end
@ -56,7 +63,7 @@ module Gitea
file_params = {} file_params = {}
file_params = file_params.merge(branch: @params[:branch]) unless @params[:branch].blank? file_params = file_params.merge(branch: @params[:branch]) unless @params[:branch].blank?
file_params = file_params.merge(new_branch: @params[:new_branch]) unless @params[:new_branch].blank? file_params = file_params.merge(new_branch: @params[:new_branch]) unless @params[:new_branch].blank?
file_params = file_params.merge(content: Base64.encode64(@params[:content])) file_params = file_params.merge(content: Base64.encode64(@params[:content] || ""))
file_params = file_params.merge(message: @params[:message]) unless @params[:message].blank? file_params = file_params.merge(message: @params[:message]) unless @params[:message].blank?
file_params = file_params.merge(committer: @params[:committer]) file_params = file_params.merge(committer: @params[:committer])
file_params file_params

View File

@ -1,18 +1,19 @@
module Projects module Projects
class AddMemberInteractor class AddMemberInteractor
def self.call(owner, project, collaborator, permission="write") def self.call(owner, project, collaborator, permission="write", is_apply_signature=false)
interactor = new(owner, project, collaborator, permission) interactor = new(owner, project, collaborator, permission, is_apply_signature)
interactor.run interactor.run
interactor interactor
end end
attr_reader :error, :result attr_reader :error, :result
def initialize(owner, project, collaborator, permission) def initialize(owner, project, collaborator, permission, is_apply_signature)
@owner = owner @owner = owner
@project = project @project = project
@collaborator = collaborator @collaborator = collaborator
@permission = permission @permission = permission
@is_apply_signature = is_apply_signature
end end
def success? def success?
@ -23,7 +24,7 @@ module Projects
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
gitea_result = Gitea::Repository::Members::AddService.new(owner, project.identifier, collaborator.login, permission).call gitea_result = Gitea::Repository::Members::AddService.new(owner, project.identifier, collaborator.login, permission).call
if gitea_result.status == 204 if gitea_result.status == 204
project.add_member!(collaborator.id) project.add_member!(collaborator.id, set_member_role, is_apply_signature)
end end
fail!(nil) fail!(nil)
end end
@ -32,11 +33,20 @@ module Projects
end end
private private
attr_reader :owner, :project, :collaborator, :permission attr_reader :owner, :project, :collaborator, :permission, :is_apply_signature
def fail!(error) def fail!(error)
@error = error @error = error
end end
def set_member_role
@role ||=
case @permission
when "write" then "Developer"
when "read" then "Reporter"
else "Developer"
end
end
end end
end end

View File

@ -0,0 +1,48 @@
class SyncForgeProjectJob < ApplicationJob
queue_as :default
def perform(sync_parmas)
# sync_parmas.permit!
Rails.logger.info("=======begin to sync forge projects, and sync_parmas: #{sync_parmas}")
get_rand_user = rand_user
project_params = sync_parmas[:project]
repository_params = sync_parmas[:repository]
project_socre_params = sync_parmas[:project_socre]
begin
unless Project.select(:identifier).exists?(identifier: project_params[:identifier])
project_params = project_params.merge({user_id: get_rand_user.id })
project = Project.new(project_params)
if project.save
repository_params = {
hidden: false,
identifier: repository_params[:identifier],
mirror_url: repository_params[:url].to_s.gsub("https://gitea.", "https://git."),
user_id: get_rand_user.id,
login: get_rand_user.login,
password: "",
is_mirror: false
}
Repositories::MigrateService.new(get_rand_user, project, repository_params).call
project_score = ProjectScore.new(project_socre_params.merge({project_id: project.id}))
project_score.save
end
end
Rails.logger.info("=======end to sync forge projects")
rescue => e
Rails.logger.info("=======sync forge projects has errors: #{e}")
raise ActiveRecord::Rollback
end
end
private
def rand_user
user_ids = User.select(:id, :type, :gitea_token, :gitea_uid).where("gitea_token is not null and gitea_uid is not null and type = ?", "User").pluck(:id)
range_user_id = user_ids[rand(user_ids.length-1)]
rand_sync_user = User.find_by_id(range_user_id) #生成随机用户
unless rand_sync_user.present?
rand_user
end
rand_sync_user
end
end

View File

@ -5,7 +5,7 @@ class SyncMirroredRepositoryJob < ApplicationJob
repo = Repository.find_by(id: repo_id) repo = Repository.find_by(id: repo_id)
current_user = User.find_by(id: user_id) current_user = User.find_by(id: user_id)
return if repo.blank? || current_user.blank? return if repo.blank? || current_user.blank?
result = Gitea::Repository::SyncMirroredService.new(repo.owner.login, repo.identifier, token: current_user.gitea_token).call result = Gitea::Repository::SyncMirroredService.new(repo.user.login, repo.identifier, token: current_user.gitea_token).call
repo&.mirror.set_status! if result[:status] === 200 repo&.mirror&.set_status! if result[:status] == 200 && repo.mirror.present?
end end
end end

View File

@ -0,0 +1,36 @@
class SyncPhengleiUserJob < ApplicationJob
queue_as :default
def perform(project_id=nil)
project_id ||= EduSetting.get("sync_phenglei_user_project")
project = Project.find_by_id(project_id)
return if project.nil?
member_count, success_count, error_count, not_exsit_count = 0, 0, 0, 0
Rails.logger.info("======begin to sync phenglei user to project#{project.owner.login + "/" + project.identifier}")
PhengleiUser.find_each do |i|
puts "======开始处理#{i.phone}"
user = User.find_by(phone: i.phone)
if user.present?
if project.member?(user.id)
puts "======#{i.phone}用户已经是外围贡献者了"
member_count += 1
else
interactor = Projects::AddMemberInteractor.call(project.owner, project, user, "read", true)
if interactor.error.nil?
puts "========用户#{i.phone}成功添加为项目的外围贡献者======="
success_count += 1
else
puts "========用户#{i.phone}添加失败"
error_count += 1
end
end
else
puts "=====#{i.phone}用户不存在"
not_exsit_count += 1
next
end
end
Rails.logger.info("======已存在外围贡献者数量#{member_count}, 成功添加用户数量#{success_count}, 添加失败用户数量#{error_count}, 找不到用户数量#{not_exsit_count}")
Rails.logger.info("======end to sync phenglei user to project#{project.owner.login + "/" + project.identifier}")
end
end

View File

@ -0,0 +1,167 @@
class DunCheck::ImageCheck
#检测结果0通过1嫌疑2不通过
# include ActionView::Helpers::LoopTextsHelper
require 'uri'
require 'net/http'
def initialize(image_params)
@image_params = image_params
end
def call
begin
Rails.logger.info("==========@image_params===========#{@image_params}")
dun_params = check_dun_params(@image_params)
api_url = EduSetting.get("dun_image_api")
uri = URI.parse(api_url)
http = Net::HTTP.new(uri.hostname, uri.port)
if api_url.include?("https://")
http.use_ssl = true
end
dun_params_str = URI.encode_www_form(dun_params)
header = {'content-type':'application/x-www-form-urlencoded'}
response = http.post(uri.path, dun_params_str, header)
response_body = JSON.parse(response.body)
if response_body["code"].to_i == 200
response_body_result = response_body["antispam"]
response_lables = response_body_result[0]["labels"]
return_sub_lable = ""
if response_lables.present?
return_sub_lable = get_sub_labels(response_lables)
end
render_status = response_body_result[0]["action"].to_i == 0 ? 1 : -1
tip_status(render_status, return_sub_lable.present? ? "图片含有: #{return_sub_lable}" : response_body["msg"] )
else
tip_status(-1, response_body["msg"])
end
rescue Exception => ex
Rails.logger.info "*** transaction abored!"
Rails.logger.info "*** errors: #{ex.message}"
tip_status(-1, "检测失败")
end
end
private
def check_dun_params(image_params)
dun_public_params = DunCheck::PublicParams.new("image")
check_params = {
version: "v4",
images: image_params.to_json
}
check_params.merge!(dun_public_params.call)
dun_params = dun_public_params.generate_sign(check_params)
return dun_params
end
def tip_status(status, message, msg_params={})
return {status: status, message: message, extra_params: msg_params}
end
def get_sub_labels(labels)
_sub_labels = []
labels.each do |label|
error_label = label["subLabels"].present? ? label["subLabels"][0]["subLabel"] : ""
if error_label.present?
_sub_labels.push(sub_lables[:"#{error_label.to_s}"])
end
end
return _sub_labels.present? ? _sub_labels.join(",") : ""
end
def sub_lables
{
"10000": "色情",
"10001": "女下体",
"10002": "女胸",
"10003": "男下体",
"10004": "性行为",
"10005": "臀部",
"10006": "口交",
"10007": "卡通色情",
"10008": "色情人物",
"10009": "儿童色情",
"11000": "性感低俗",
"11001": "亲吻",
"11002": "腿部特写",
"11003": "非漏点赤膊",
"11004": "胸部",
"100001": "色情文字-色情其他",
"100002": "色情文字-色情传播",
"100003": "色情文字-色情性器官",
"100004": "色情文字-色情挑逗",
"100005": "色情文字-色情低俗段子",
"100006": "色情文字-色情性行为",
"100007": "色情文字-色情舆情事件",
"100008": "色情文字-色情交友类",
"20000": "广告",
"20001": "广告带文字",
"200009": "广告文字-商业推广",
"200010": "广告文字-广告法",
"200011": "刷量行为",
"200012": "广告其他",
"260052": "广告文字-广告法-涉医疗用语",
"260053": "广告文字-广告法-迷信用语",
"260054": "广告文字-广告法-需要凭证",
"260055": "广告文字-广告法-限时性用语",
"260056": "广告文字-广告法-涉嫌诱导消费者",
"260057": "广告文字-广告法-涉嫌欺诈消费者",
"260058": "广告文字-广告法-法律风险较高",
"260059": "广告文字-广告法-极限词",
"21000": "二维码",
"30000": "暴恐",
"30001": "暴恐图集",
"30002": "暴恐旗帜",
"30003": "暴恐人物",
"30004": "暴恐标识",
"30005": "暴恐场景",
"300016": "暴恐文字-暴恐其他",
"40000": "违禁",
"40001": "违禁图集",
"40002": "违禁品",
"40003": "特殊标识",
"40004": "血腥模型",
"40005": "公职服饰",
"40006": "不文明",
"40007": "违禁人物",
"40008": "违禁场景",
"40009": "火焰",
"40010": "骷髅",
"40011": "货币",
"40012": "毒品",
"400017": "违禁文字-违禁其他",
"600018": "违禁文字-谩骂其他",
"50000": "涉政",
"50001": "涉政图集",
"50002": "中国地图",
"50003": "涉政人物",
"50004": "涉政旗帜",
"50005": "涉政标识",
"50006": "涉政场景",
"500013": "涉政文字-涉政其他",
"500014": "涉政文字-敏感专项",
"500015": "涉政文字-严格涉政",
"500039": "涉政文字-时事报道",
"500040": "涉政文字-领导人相关",
"500041": "涉政文字-英雄烈士相关",
"500042": "涉政文字-邪教迷信",
"500043": "涉政文字-落马官员相关",
"500044": "涉政文字-热点舆情",
"500045": "涉政文字-涉政综合",
"90000": "其他",
"90002": "自定义用户名单",
"90003": "自定义IP名单",
"900020": "文字违规-其他"
}
end
end

View File

@ -0,0 +1,31 @@
class DunCheck::PublicParams
def initialize(type)
@type = type
end
def call
public_params = {
secretId: EduSetting.get("dun_secret_id"),
businessId: EduSetting.get("dun_#{@type}_businessId"),
timestamp: DateTime.current.strftime('%Q').to_i,
nonce: rand(10 ** 11).to_i
}
return public_params
end
def generate_sign(params)
secretkey = EduSetting.get("dun_secrect_key")
sort_params = params.sort.to_h
sign_str = ""
sort_params.each do |k,v|
sign_str += "#{k.to_s}#{v.to_s}"
end
sign_str += secretkey
md5_sign = Digest::MD5.hexdigest(sign_str.to_s.force_encoding("UTF-8"))
return sort_params.merge!(signature: md5_sign)
end
end

View File

@ -0,0 +1,164 @@
class DunCheck::TextCheck
# include DunCheck::PublicParams
#text_params = {
# content: "ccc", #内容
# ip: "xxx", #用户ip
# account: "xxx", #登录login
# nickname: "xxx", #用户姓名
# title: "xxx", #帖子的标题
# }
#检测结果0通过1嫌疑2不通过
# include ActionView::Helpers::LoopTextsHelper
require 'uri'
require 'net/http'
def initialize(text_params)
@text_params = text_params
end
def call
new_text_params = @text_params
text_long_array = []
check_content = new_text_params[:content]
format_text(check_content,text_long_array)
(1..text_long_array.size).each do |i|
new_text_params.merge!(content: text_long_array[i-1])
check_result = check_text(new_text_params)
if check_result[:status].to_i == -1
return check_result
break
else
if i == text_long_array.size
return check_result
else
next
end
end
end
end
def check_text(text_params)
begin
dun_params = check_dun_params(text_params)
# api_url = Redmine::Configuration['dun']['text_api']
api_url = EduSetting.get("dun_text_api")
uri = URI.parse(api_url)
http = Net::HTTP.new(uri.hostname, uri.port)
if api_url.include?("https://")
http.use_ssl = true
end
dun_params_str = URI.encode_www_form(dun_params)
header = {'content-type':'application/x-www-form-urlencoded'}
response = http.post(uri.path, dun_params_str, header)
response_body = eval(response.body)
Rails.logger.info("======response========#{response_body}")
if response_body[:code].to_i == 200
response_body_result = response_body[:result]
response_body_labels = response_body_result[:labels].present? ? response_body_result[:labels][0] : []
extra_params = {
action: response_body_result[:action],
taskId: response_body_result[:taskId],
infos: response_body_labels.present? ? sub_lables[:"#{response_body_labels[:subLabels][0][:subLabel]}"] : ""
}
render_status = response_body_result[:action].to_i == 0 ? 1 : -1
tip_status(render_status, response_body[:msg], extra_params)
else
tip_status(-1, response_body[:msg])
end
rescue Exception => ex
Rails.logger.info "*** transaction abored!"
Rails.logger.info "*** errors: #{ex.message}"
tip_status(-1, "检测失败")
end
end
private
def check_dun_params(text_params)
dun_public_params = DunCheck::PublicParams.new("text")
rand_data_id = random_dataId
check_params = {
dataId: rand_data_id,
version: "v3.1",
callback: rand_data_id
}.merge(text_params)
check_params.merge!(dun_public_params.call)
dun_params = dun_public_params.generate_sign(check_params)
return dun_params
end
def format_text(text_long, text_long_array)
slice_content = text_long.slice(0..4998)
last_slice_content = text_long.slice(4999..-1)
text_long_array.push(slice_content)
if last_slice_content.present?
if last_slice_content.length > 4999
format_text(last_slice_content, text_long_array)
else
text_long_array.push(last_slice_content)
end
end
end
def random_dataId
Digest::MD5.hexdigest(rand(100000000).to_s)
end
def check_labels
# 100色情200广告260广告法300暴恐400违禁500涉政600谩骂700灌水
%w(100 200 260 300 400 500 600 700).join(",")
end
def tip_status(status, message, msg_params={})
return {status: status, message: message, extra_params: msg_params}
end
def sub_lables
{
"100001": "色情其他",
"100002": "色情传播",
"100003": "色情性器官",
"100004": "色情挑逗",
"100005": "色情低俗段子",
"100006": "色情性行为",
"100007": "色情舆情事件",
"100008": "色情交友类",
"200009": "商业推广",
"200010": "广告法",
"200011": "刷量行为",
"200012": "广告其他",
"260052": "广告法-涉医疗用语(非药品禁止宣传药效)",
"260053": "广告法-迷信用语",
"260054": "广告法-需要凭证(可以写但需要凭证证明)",
"260055": "广告法-限时性用语(可以写但必须有具体时间)",
"260056": "广告法-涉嫌诱导消费者",
"260057": "广告法-涉嫌欺诈消费者",
"260058": "广告法-法律风险较高",
"260059": "广告法-极限词(用语绝对化)",
"300016": "暴恐其他",
"400017": "违禁其他",
"400021": "违禁网监要求",
"500013": "涉政其他",
"500014": "敏感专项",
"500015": "严格涉政",
"500039": "时事报道",
"500040": "领导人相关",
"500041": "英雄烈士相关",
"500042": "邪教迷信",
"500043": "落马官员相关",
"500044": "热点舆情",
"500045": "涉政综合",
"600018": "谩骂其他",
"700019": "灌水其他",
"900020": "其他",
}
end
end

View File

@ -0,0 +1,30 @@
# == Schema Information
#
# Table name: apply_signatures
#
# id :integer not null, primary key
# user_id :integer
# project_id :integer
# status :integer default("0")
# created_at :datetime not null
# updated_at :datetime not null
#
# Indexes
#
# index_apply_signatures_on_project_id (project_id)
# index_apply_signatures_on_user_id (user_id)
#
class ApplySignature < ApplicationRecord
belongs_to :user
belongs_to :project
has_many :attachments, as: :container, dependent: :destroy
scope :with_user_id, -> (user_id) {where(user_id: user_id)}
scope :with_status, -> (status) {where(status: status) if status.present? && status != "all"}
validates :project_id, uniqueness: {scope: :user_id}
enum status: {unpassed: -1, waiting: 0, passed: 1}
end

View File

@ -42,7 +42,7 @@ class Attachment < ApplicationRecord
include Publicable include Publicable
include Publishable include Publishable
include Lockable include Lockable
include DunCheckImageAble
belongs_to :container, polymorphic: true, optional: true belongs_to :container, polymorphic: true, optional: true
belongs_to :author, class_name: "User", foreign_key: :author_id belongs_to :author, class_name: "User", foreign_key: :author_id
# belongs_to :course, foreign_key: :container_id, optional: true # belongs_to :course, foreign_key: :container_id, optional: true

View File

@ -20,7 +20,6 @@
class Compose < ApplicationRecord class Compose < ApplicationRecord
#组织 #组织
belongs_to :user
has_many :compose_projects has_many :compose_projects
has_many :compose_users has_many :compose_users

View File

@ -0,0 +1,50 @@
module DunCheckAble
extend ActiveSupport::Concern
included do
validate :check_text_able
end
def check_text_able
dun_check_params = get_model
if dun_check_params[:is_change]
dun_check_params.delete(:is_change)
check_result = DunCheck::TextCheck.new(dun_check_params).call
if check_result[:status].to_i == -1
errors.add(:base, "内容含有:#{check_result[:extra_params][:infos]},请修改")
# raise ActiveRecord::RecordInvalid.new(self)
end
end
end
def get_model
dun_model = self.class.name
case dun_model
when "Issue"
check_params = {
title: self.subject,
content: self.description,
is_change: (self.subject_changed? || self.description_changed?) && self.subject.present? && self.description.present?
}
when "PullRequest"
check_params = {
title: "",
content: self.body,
is_change: self.body_changed? && self.body.present?
}
when "Journal"
check_params = {
title: "",
content: self.notes,
is_change: self.notes_changed? && self.notes.present?
}
when "Version"
check_params = {
title: self.name,
content: self.description,
is_change: (self.name_changed? || self.description_changed?) && self.name.present? && self.description.present?
}
end
return check_params
end
end

View File

@ -0,0 +1,33 @@
module DunCheckImageAble
extend ActiveSupport::Concern
included do
def self.check_image_able(file)
original_filename = file.original_filename
file_extention = original_filename.split(".").last
check_include = %w(jpg png bmp gif webp tiff jpeg)
if file_extention && check_include.include?(file_extention)
base64_file = Base64.encode64(file.open.read.force_encoding(Encoding::UTF_8))
check_params = [
{
name: original_filename,
type: 2,
data: base64_file,
}
]
check_result = DunCheck::ImageCheck.new(check_params).call
if check_result[:status].to_i == -1
return {status: -1, message: check_result[:message]}
else
return {status: 1}
end
else
return {status: 1}
end
end
end
end

View File

@ -5,7 +5,7 @@ module Matchable
scope :with_project_category, ->(category_id) { where(project_category_id: category_id) unless category_id.blank? } scope :with_project_category, ->(category_id) { where(project_category_id: category_id) unless category_id.blank? }
scope :with_project_language, ->(language_id) { where(project_language_id: language_id) unless language_id.blank? } scope :with_project_language, ->(language_id) { where(project_language_id: language_id) unless language_id.blank? }
scope :with_project_type, ->(project_type) { where(project_type: project_type) if Project.project_types.include?(project_type) } scope :with_project_type, ->(project_type) { where(project_type: project_type) if Project.project_types.include?(project_type) }
scope :by_name_or_identifier, ->(search) { where("name like :search or identifier LIKE :search", :search => "#{search.split(" ").join('|')}%") unless search.blank? } scope :by_name_or_identifier, ->(search) { where("projects.name like :search or projects.identifier LIKE :search", :search => "#{search.split(" ").join('|')}%") unless search.blank? }
end end
end end

View File

@ -7,6 +7,7 @@ module ProjectAbility
def can_read_project?(project) def can_read_project?(project)
return true if self.admin? return true if self.admin?
return true if project.is_secret
return false if !project.is_public? && !project.member?(self.id) return false if !project.is_public? && !project.member?(self.id)
true true
end end

View File

@ -11,8 +11,8 @@ module ProjectOperable
has_many :team_projects, dependent: :destroy has_many :team_projects, dependent: :destroy
end end
def add_member!(user_id, role_name='Developer') def add_member!(user_id, role_name='Developer', is_apply_signature=false)
member = members.create!(user_id: user_id) member = members.create!(user_id: user_id, is_apply_signature: is_apply_signature)
set_developer_role(member, role_name) set_developer_role(member, role_name)
end end

View File

@ -50,6 +50,7 @@
class Issue < ApplicationRecord class Issue < ApplicationRecord
#issue_type 1为普通2为悬赏 #issue_type 1为普通2为悬赏
include DunCheckAble
belongs_to :project, :counter_cache => true belongs_to :project, :counter_cache => true
belongs_to :tracker,optional: true belongs_to :tracker,optional: true
has_many :project_trends, as: :trend, dependent: :destroy has_many :project_trends, as: :trend, dependent: :destroy

View File

@ -22,6 +22,7 @@
# #
class Journal < ApplicationRecord class Journal < ApplicationRecord
include DunCheckAble
belongs_to :user belongs_to :user
belongs_to :issue, foreign_key: :journalized_id, :touch => true belongs_to :issue, foreign_key: :journalized_id, :touch => true
has_many :journal_details, :dependent => :delete_all has_many :journal_details, :dependent => :delete_all

View File

@ -36,9 +36,10 @@ class Laboratory < ApplicationRecord
delegate :name, :navbar, :footer, :login_logo_url, :nav_logo_url, :tab_logo_url, :default_navbar, to: :laboratory_setting delegate :name, :navbar, :footer, :login_logo_url, :nav_logo_url, :tab_logo_url, :default_navbar, to: :laboratory_setting
# TODO 域名申请后更改
def site def site
rails_env = EduSetting.get('rails_env') rails_env = EduSetting.get('rails_env')
suffix = rails_env && rails_env != 'production' ? ".#{rails_env}.trustie.net" : '.trustie.net' suffix = rails_env && rails_env != 'production' ? "39.105.176.215" : '39.105.176.215'
identifier ? "#{identifier}#{suffix}" : '' identifier ? "#{identifier}#{suffix}" : ''
end end

View File

@ -12,4 +12,6 @@
class License < ApplicationRecord class License < ApplicationRecord
include Projectable include Projectable
has_many :attachments, as: :container, dependent: :destroy
end end

View File

@ -0,0 +1,18 @@
# == Schema Information
#
# Table name: phenglei_users
#
# id :integer not null, primary key
# phone :string(255)
# created_at :datetime not null
# updated_at :datetime not null
#
class PhengleiUser < ApplicationRecord
validates :phone, uniqueness: true
def register
User.find_by(phone: self.phone)
end
end

View File

@ -109,6 +109,7 @@ class Project < ApplicationRecord
has_many :praise_treads, as: :praise_tread_object, dependent: :destroy has_many :praise_treads, as: :praise_tread_object, dependent: :destroy
has_and_belongs_to_many :trackers, :order => "#{Tracker.table_name}.position" has_and_belongs_to_many :trackers, :order => "#{Tracker.table_name}.position"
has_one :project_detail, dependent: :destroy has_one :project_detail, dependent: :destroy
has_many :apply_signatures, dependent: :destroy
has_many :team_projects, dependent: :destroy has_many :team_projects, dependent: :destroy
after_save :check_project_members after_save :check_project_members
@ -116,6 +117,9 @@ class Project < ApplicationRecord
scope :no_anomory_projects, -> {where("projects.user_id is not null and projects.user_id != ?", 2)} scope :no_anomory_projects, -> {where("projects.user_id is not null and projects.user_id != ?", 2)}
scope :recommend, -> { visible.project_statics_select.where(recommend: true) } scope :recommend, -> { visible.project_statics_select.where(recommend: true) }
scope :secret_and_visible, -> {left_outer_joins(:license).where("licenses.is_secret = TRUE OR projects.is_public = TRUE")}
delegate :is_secret, to: :license, allow_nil: true
def self.search_project(search) def self.search_project(search)

View File

@ -19,4 +19,12 @@ class ProjectCategory < ApplicationRecord
include Projectable include Projectable
has_ancestry has_ancestry
def self.descendants
where.not(ancestry: [nil, ""])
end
def self.get_children(target_id)
where(ancestry: target_id).pluck(:id,:name)
end
end end

View File

@ -24,6 +24,7 @@
# #
class PullRequest < ApplicationRecord class PullRequest < ApplicationRecord
include DunCheckAble
#status 0 默认未合并, 1表示合并, 2表示请求拒绝(或已关闭) #status 0 默认未合并, 1表示合并, 2表示请求拒绝(或已关闭)
OPEN = 0 OPEN = 0
MERGED = 1 MERGED = 1

View File

@ -70,7 +70,7 @@ class Token < ActiveRecord::Base
# Delete all expired tokens # Delete all expired tokens
def self.destroy_expired def self.destroy_expired
Token.delete_all ["action NOT IN (?) AND created_on < ?", ['feeds', 'api', 'autologin'], Time.now - @@validity_time] Token.delete_all ["action NOT IN (?) AND created_on < ?", ['feeds', 'api', 'autologin', 'autologin_forge_military'], Time.now - @@validity_time]
end end
# Returns the active user who owns the key for the given action # Returns the active user who owns the key for the given action

View File

@ -112,10 +112,8 @@ class User < Owner
enumerize :platform, in: [:forge, :educoder, :trustie, :military], default: :forge, scope: :shallow enumerize :platform, in: [:forge, :educoder, :trustie, :military], default: :forge, scope: :shallow
belongs_to :laboratory, optional: true belongs_to :laboratory, optional: true
has_many :composes, dependent: :destroy
has_many :compose_users, dependent: :destroy
has_one :user_extension, dependent: :destroy has_one :user_extension, dependent: :destroy
has_many :open_users, dependent: :destroy # has_many :open_users, dependent: :destroy
has_one :wechat_open_user, class_name: 'OpenUsers::Wechat' has_one :wechat_open_user, class_name: 'OpenUsers::Wechat'
has_one :qq_open_user, class_name: 'OpenUsers::QQ' has_one :qq_open_user, class_name: 'OpenUsers::QQ'
accepts_nested_attributes_for :user_extension, update_only: true accepts_nested_attributes_for :user_extension, update_only: true
@ -156,6 +154,7 @@ class User < Owner
# has_many :libraries, dependent: :destroy # has_many :libraries, dependent: :destroy
has_many :project_trends, dependent: :destroy has_many :project_trends, dependent: :destroy
has_many :oauths , dependent: :destroy has_many :oauths , dependent: :destroy
has_many :apply_signatures, dependent: :destroy
has_many :organization_users, dependent: :destroy has_many :organization_users, dependent: :destroy
has_many :organizations, through: :organization_users has_many :organizations, through: :organization_users
@ -163,7 +162,7 @@ class User < Owner
# Groups and active users # Groups and active users
scope :active, lambda { where(status: STATUS_ACTIVE) } scope :active, lambda { where(status: STATUS_ACTIVE) }
scope :like, lambda { |keywords| scope :like, lambda { |keywords|
where("LOWER(concat(lastname, firstname, login, mail)) LIKE ?", "%#{keywords.split(" ").join('|')}%") unless keywords.blank? where("LOWER(concat(nickname, lastname, firstname, login, mail)) LIKE ?", "%#{keywords.split(" ").join('|')}%") unless keywords.blank?
} }
scope :simple_select, -> {select(:id, :login, :lastname,:firstname, :nickname, :gitea_uid, :type)} scope :simple_select, -> {select(:id, :login, :lastname,:firstname, :nickname, :gitea_uid, :type)}
@ -191,7 +190,7 @@ class User < Owner
# 删除自动登录的token一旦退出下次会提示需要登录 # 删除自动登录的token一旦退出下次会提示需要登录
def delete_autologin_token(value) def delete_autologin_token(value)
Token.where(:user_id => id, :action => 'autologin', :value => value).delete_all Token.where(:user_id => id, :action => autologin_name, :value => value).delete_all
end end
def delete_session_token(value) def delete_session_token(value)
@ -577,8 +576,8 @@ class User < Owner
end end
# Returns the user who matches the given autologin +key+ or nil # Returns the user who matches the given autologin +key+ or nil
def self.try_to_autologin(key) def self.try_to_autologin(key,type)
user = Token.find_active_user('autologin', key) user = Token.find_active_user(type, key)
user.update(last_login_on: Time.now) if user user.update(last_login_on: Time.now) if user
user user
end end
@ -742,6 +741,10 @@ class User < Owner
raise("昵称包含敏感词汇,请重新输入") if nickname && !HarmoniousDictionary.clean?(nickname) raise("昵称包含敏感词汇,请重新输入") if nickname && !HarmoniousDictionary.clean?(nickname)
end end
def autologin_name
EduSetting.get('autologin_cookie_name') || "autologin_forge_military"
end
def set_laboratory def set_laboratory
return unless new_record? return unless new_record?

View File

@ -24,6 +24,7 @@
# #
class Version < ApplicationRecord class Version < ApplicationRecord
include DunCheckAble
belongs_to :project, counter_cache: true belongs_to :project, counter_cache: true
has_many :issues, class_name: "Issue", foreign_key: "fixed_version_id" has_many :issues, class_name: "Issue", foreign_key: "fixed_version_id"
belongs_to :user, optional: true belongs_to :user, optional: true

View File

@ -51,7 +51,7 @@ class Projects::ListMyQuery < ApplicationQuery
q = projects.ransack(name_or_identifier_cont: params[:search]) q = projects.ransack(name_or_identifier_cont: params[:search])
scope = q.result.includes(:project_category, :project_language,:owner, :repository) scope = q.result.includes(:project_category, :project_language,:owner, :repository, :members)
sort = params[:sort_by] || "updated_on" sort = params[:sort_by] || "updated_on"
sort_direction = params[:sort_direction] || "desc" sort_direction = params[:sort_direction] || "desc"

View File

@ -10,12 +10,12 @@ class Projects::ListQuery < ApplicationQuery
end end
def call def call
q = Project.visible.by_name_or_identifier(params[:search]) q = Project.secret_and_visible.by_name_or_identifier(params[:search])
scope = q scope = q
.with_project_type(params[:project_type]) .with_project_type(params[:project_type])
.with_project_category(params[:category_id]) .with_project_category(params[:category_id])
.with_project_language(params[:language_id]) .with_project_language(params[:language_id]).order(order_index: :desc)
sort = params[:sort_by] || "updated_on" sort = params[:sort_by] || "updated_on"
sort_direction = params[:sort_direction] || "desc" sort_direction = params[:sort_direction] || "desc"

View File

@ -195,6 +195,14 @@ class Gitea::ClientService < ApplicationService
[body, message] [body, message]
end end
def json_parse!(body)
return nil unless body.present?
body = JSON.parse(body)
body, message = fix_body(body)
body
end
def log_error(status, body) def log_error(status, body)
puts "[gitea] status: #{status}" puts "[gitea] status: #{status}"
puts "[gitea] body: #{body&.force_encoding('UTF-8')}" puts "[gitea] body: #{body&.force_encoding('UTF-8')}"

View File

@ -0,0 +1,40 @@
class Gitea::Repository::ArchiveService < Gitea::ClientService
attr_reader :owner, :repo, :archive, :token
def initialize(owner, repo, archive, token=nil)
@owner = owner
@repo = repo
@archive = archive
@token = token
end
def call
response = get(url, params)
response_payload(response)
end
private
def params
Hash.new.merge(token: token)
end
def url
"/repos/#{owner}/#{repo}/archive/#{archive}".freeze
end
def response_payload(response)
status = response.status
body = response&.body
log_error(status, body)
status_payload(status, body)
end
def status_payload(status, body)
case status
when 200 then success
when 404 then error("你操作的链接不存在!")
else error("系统错误!")
end
end
end

View File

@ -30,8 +30,7 @@ class Gitea::Repository::Entries::CreateService < Gitea::ClientService
def call def call
response = post(url, params) response = post(url, params)
response_payload(response)
render_201_response(response)
end end
private private
@ -43,4 +42,21 @@ class Gitea::Repository::Entries::CreateService < Gitea::ClientService
"/repos/#{owner}/#{repo_name}/contents/#{filepath}".freeze "/repos/#{owner}/#{repo_name}/contents/#{filepath}".freeze
end end
def response_payload(response)
status = response.status
body = response&.body
log_error(status, body)
status_payload(status, body)
end
def status_payload(status, body)
case status
when 201 then success(json_parse!(body))
when 403 then error("你没有权限操作!")
when 404 then error("你操作的链接不存在!")
when 422 then error("#{filepath}文件已存在,不能重复创建!")
else error("系统错误!")
end
end
end end

View File

@ -53,6 +53,11 @@ class Projects::CreateService < ApplicationService
# end # end
def repo_is_public def repo_is_public
params[:private].blank? ? true : !params[:private] license = License.find_by_id(params[:license_id])
if license.is_secret
false
else
params[:private].blank? ? true : !params[:private]
end
end end
end end

View File

@ -0,0 +1,20 @@
require 'uri'
require 'net/http'
class SyncForgeProjectsRake
# 运行示例: 检查哪些项目的repo不存在bundle exec rails runner "SyncForgeProjectsRake.new.call(5)" -e production
def call(count)
url = "https://forgeplus.trustie.net/api/sync_forge/sync_range_projects" #trustie上的相关路由
count_params = {
sync_count: count || 10
}
Rails.logger.info("============begin to sync project,count: #{count_params} ===========")
uri = URI.parse(url)
http = Net::HTTP.new(uri.hostname, uri.port)
http.use_ssl = true
response = http.send_request('POST', uri.path, count_params.to_json, {'Content-Type' => 'application/json'})
Rails.logger.info("============end to sync project, status: #{response.code} ===========")
end
end

View File

@ -0,0 +1,7 @@
<% define_admin_breadcrumbs do %>
<% add_admin_breadcrumb('特殊许可申请列表') %>
<% end %>
<div class="box admin-list-container apply_signatures-list-container">
<%= render partial: 'admins/apply_signatures/shared/list', locals: { apply_signatures: @apply_signatures } %>
</div>

View File

@ -0,0 +1 @@
$('.apply_signatures-list-container').html("<%= j( render partial: 'admins/apply_signatures/shared/list', locals: { apply_signatures: @apply_signatures } ) %>");

View File

@ -0,0 +1,42 @@
<table class="table table-hover text-center subject-list-table">
<thead class="thead-light">
<tr>
<th width="10%">序号</th>
<th width="20%" class="text-left">项目名称</th>
<th width="20%">申请人</th>
<th width="25%">申请材料</th>
<th width="25%">操作</th>
</tr>
</thead>
<tbody>
<% if apply_signatures.present? %>
<% apply_signatures.each_with_index do |signature, index| %>
<tr class="sinature-item-<%= signature.id %>">
<td><%= list_index_no((params[:page] || 1).to_i, index) %></td>
<td class="text-left">
<%= link_to("#{signature&.project&.owner&.real_name}/#{signature&.project&.name}", "/projects/#{signature&.project&.owner&.login}/#{signature&.project&.identifier}", target: '_blank') %>
</td>
<td>
<%= link_to(signature&.user&.real_name, "/users/#{signature&.user&.login}", target: '_blank') %>
</td>
<td>
<% if signature.attachments.present? %>
<% signature.attachments.each do |attachment|%>
<%= link_to "#{attachment.try(:filename)}",attachment_path(attachment), target: "_blank" %>
<% end %>
<% end %>
</td>
<td class="action-container">
<%= link_to "同意", admins_apply_signature_path(signature.id, status: "passed"), method: :patch, class: "delete-project-action" %>
<%= link_to "拒绝", admins_apply_signature_path(signature.id, status: "unpassed"), method: :patch, class: "delete-project-action" %>
</td>
</tr>
<% end %>
<% else %>
<%= render 'admins/shared/no_data_for_table' %>
<% end %>
</tbody>
</table>
<%= render partial: 'admins/shared/paginate', locals: { objects: apply_signatures } %>

View File

@ -4,7 +4,7 @@
<div class="box search-form-container laboratory-list-form"> <div class="box search-form-container laboratory-list-form">
<%= form_tag(admins_laboratories_path(unsafe_params), method: :get, class: 'form-inline search-form flex-1', remote: true) do %> <%= form_tag(admins_laboratories_path(unsafe_params), method: :get, class: 'form-inline search-form flex-1', remote: true) do %>
<%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-6 col-md-4 ml-3', placeholder: '学校名称/二级域名前缀检索') %> <%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-6 col-md-4 ml-3', placeholder: '二级域名前缀检索') %>
<%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %> <%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %>
<% end %> <% end %>
@ -16,4 +16,4 @@
</div> </div>
<%= render 'admins/laboratories/shared/create_laboratory_modal' %> <%= render 'admins/laboratories/shared/create_laboratory_modal' %>
<%= render 'admins/laboratories/shared/add_laboratory_user_modal' %> <%= render 'admins/laboratories/shared/add_laboratory_user_modal' %>

View File

@ -1,9 +1,9 @@
<% school = laboratory&.school %> <% school = laboratory&.school %>
<td><%= list_index_no((params[:page] || 1).to_i, index) %></td> <td><%= list_index_no((params[:page] || 1).to_i, index) %></td>
<td class="text-left"><%= school&.name || 'Trustie主站' %></td> <td class="text-left"><%= school&.name || '可控开源社区' %></td>
<td class="text-left"> <td class="text-left">
<% if laboratory.identifier %> <% if laboratory.identifier %>
<%= link_to laboratory.site, "https://#{laboratory.site}", target: '_blank' %> <%= link_to laboratory.site, "http://#{laboratory.site}", target: '_blank' %>
<% else %> <% else %>
-- --
<% end %> <% end %>
@ -51,19 +51,5 @@
<% if school.present? && laboratory.id != 1 %> <% if school.present? && laboratory.id != 1 %>
<%= javascript_void_link '添加管理员', class: 'action', data: { laboratory_id: laboratory.id, toggle: 'modal', target: '.admin-add-laboratory-user-modal' } %> <%= javascript_void_link '添加管理员', class: 'action', data: { laboratory_id: laboratory.id, toggle: 'modal', target: '.admin-add-laboratory-user-modal' } %>
<%= link_to '同步用户', synchronize_user_admins_laboratory_path(laboratory), remote: true, data: { confirm: '确认同步该单位下的所有用户到云上实验室吗?' }, class: 'action' %> <%= link_to '同步用户', synchronize_user_admins_laboratory_path(laboratory), remote: true, data: { confirm: '确认同步该单位下的所有用户到云上实验室吗?' }, class: 'action' %>
<% end %> <% end %>
<div class="d-inline">
<%= javascript_void_link('更多', class: 'action dropdown-toggle', 'data-toggle': 'dropdown', 'aria-haspopup': true, 'aria-expanded': false) %>
<div class="dropdown-menu more-action-dropdown">
<%= link_to '轮播图', admins_laboratory_carousels_path(laboratory), class: 'dropdown-item' %>
<%= link_to '查看实训项目', admins_laboratory_laboratory_shixuns_path(laboratory), class: 'dropdown-item' %>
<%= link_to '查看实践课程', admins_laboratory_laboratory_subjects_path(laboratory), class: 'dropdown-item' %>
<% if school.present? && laboratory.id != 1 %>
<%= delete_link '删除', admins_laboratory_path(laboratory, element: ".laboratory-item-#{laboratory.id}"), class: 'dropdown-item delete-laboratory-action' %>
<% end %>
</div>
</div>
</td> </td>

View File

@ -19,10 +19,14 @@
maxlength: 15, class: 'form-control font-16', maxlength: 15, class: 'form-control font-16',
'onKeyUp': 'value=value.replace(/[^\w\-\/]/ig,"").toLowerCase()', 'onKeyUp': 'value=value.replace(/[^\w\-\/]/ig,"").toLowerCase()',
style: 'text-transform:lowercase'%> style: 'text-transform:lowercase'%>
<div class="input-group-append"> <%
=begin%>
<div class="input-group-append">
<% rails_env = EduSetting.get('rails_env') %> <% rails_env = EduSetting.get('rails_env') %>
<span class="input-group-text font-14" id="site-prefix"><%= rails_env && rails_env != 'production' ? ".#{rails_env}.educoder.net" : '.educoder.net' %></span> <span class="input-group-text font-14" id="site-prefix"><%= rails_env && rails_env != 'production' ? ".#{rails_env}.educoder.net" : '.educoder.net' %></span>
</div> </div>
<%
=end%>
</div> </div>
<%# if @laboratory.errors && @laboratory.errors.key?(:identifier) %> <%# if @laboratory.errors && @laboratory.errors.key?(:identifier) %>
<!-- <span id="identifier-error" class="danger text-danger">二级域名已被使用</span>--> <!-- <span id="identifier-error" class="danger text-danger">二级域名已被使用</span>-->
@ -144,7 +148,7 @@
<div class="form-group px-2 setting-item"> <div class="form-group px-2 setting-item">
<div class="setting-item-head"> <div class="setting-item-head">
<h6>导航设置 <h6>导航设置
<%= link_to "<i class='fa fa-plus-circle'></i>".html_safe,new_admins_laboratory_laboratory_setting_path, remote: true, class: "btn btn-primary btn-sm"%> <%= link_to "<i class='fa fa-plus-circle'></i>".html_safe,new_admins_laboratory_laboratory_setting_path, remote: true, class: "btn btn-primary btn-sm"%>
</h6> </h6>
</div> </div>
@ -195,8 +199,3 @@
</div> </div>
<% end %> <% end %>
</div> </div>
<script>
function destroy_tr(that) {
$(that).parent().parent("tr").remove()
}
</script>

View File

@ -0,0 +1,19 @@
<% define_admin_breadcrumbs do %>
<% add_admin_breadcrumb('风雷意向用户管理', admins_phenglei_users_path) %>
<% end %>
<div class="box search-form-container user-list-form">
<%= form_tag(admins_phenglei_users_path, method: :get, class: 'form-inline search-form flex-1', remote: true) do %>
<%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-sm-2 ml-3', placeholder: '手机号检索') %>
<%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %>
<%= link_to "同步", sync_phenglei_user_admins_project_path(@phenglei_project.id), method: :get, data: {confirm: "确认同步吗?"}, class: "btn btn-primary pull-right ml-3", "data-disabled-with":"...同步" %>
<% end %>
<%= link_to "新增", new_admins_phenglei_user_path, remote: true, class: "btn btn-primary ml-3", "data-disabled-with":"...新增" %>
</div>
<div class="box admin-list-container phenglei-users-list-container">
<%= render partial: 'admins/phenglei_users/shared/list', locals: { phenglei_users: @phenglei_users } %>
</div>
<div id="phenglei-users-modals">
</div>

View File

@ -0,0 +1 @@
$('.phenglei-users-list-container').html("<%= j( render partial: 'admins/phenglei_users/shared/list', locals: { phenglei_users: @phenglei_users } ) %>");

View File

@ -0,0 +1,2 @@
$("#phenglei-users-modals").html("<%= j render(partial: 'admins/phenglei_users/shared/create_form_modal') %>")
$(".phenglei-user-create-modal").modal('show');

View File

@ -0,0 +1,21 @@
<div class="modal fade phenglei-user-create-modal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">新增</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<%= form_for @phenglei_user, url: {controller: "phenglei_users", action: 'create'} do |p| %>
<div class="modal-body">
<%= p.text_field :phone, class: "form-control input-lg",placeholder: "手机号",required: true, maxlength: 64%>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
<%= p.submit "确认", class: "btn btn-primary submit-btn" %>
</div>
<% end %>
</div>
</div>
</div>

View File

@ -0,0 +1,30 @@
<table class="table table-hover users-list-table">
<thead class="thead-light">
<tr>
<th width="4%">序号</th>
<th width="10%">手机号码</th>
<th width="12%">状态</th>
</tr>
</thead>
<tbody>
<% if phenglei_users.present? %>
<% phenglei_users.each_with_index do |user, index| %>
<tr class="user-item-<%= user.id %>">
<td><%= list_index_no((params[:page] || 1).to_i, index) %></td>
<td><%= overflow_hidden_span display_text(user.phone), width: 100 %></td>
<td>
<% if user.register.present? %>
<%= @phenglei_project.member?(user.register.id) ? "已同步" : "未同步" %>
<% else %>
未注册
<% end %>
</td>
</tr>
<% end %>
<% else %>
<%= render 'admins/shared/no_data_for_table' %>
<% end %>
</tbody>
</table>
<%= render partial: 'admins/shared/paginate', locals: { objects: phenglei_users } %>

View File

@ -5,6 +5,7 @@
<th width="4%">ID</th> <th width="4%">ID</th>
<th width="15%" class="text-left">项目名称</th> <th width="15%" class="text-left">项目名称</th>
<th width="6%">公开</th> <th width="6%">公开</th>
<th width="6%">特殊协议</th>
<th width="5%">issue</th> <th width="5%">issue</th>
<th width="5%">资源</th> <th width="5%">资源</th>
<th width="6%">版本库</th> <th width="6%">版本库</th>
@ -23,9 +24,10 @@
<td><%= list_index_no((params[:page] || 1).to_i, index) %></td> <td><%= list_index_no((params[:page] || 1).to_i, index) %></td>
<td><%= project.id %></td> <td><%= project.id %></td>
<td class="text-left"> <td class="text-left">
<%= link_to(project.name, "/projects/#{project.id}", target: '_blank') %> <%= link_to(project.name, "/projects/#{project.owner&.login}/#{project.identifier}", target: '_blank') %>
</td> </td>
<td><%= project.is_public ? '√' : '' %></td> <td><%= project.is_public ? '√' : '' %></td>
<td><%= project.is_secret ? '√' : '' %></td>
<td><%= project.issues.size %></td> <td><%= project.issues.size %></td>
<td><%= project.attachments.size %></td> <td><%= project.attachments.size %></td>
<td><%= project&.project_score.try(:changeset_num).to_i %></td> <td><%= project&.project_score.try(:changeset_num).to_i %></td>

View File

@ -17,6 +17,7 @@
<li> <li>
<%= sidebar_item_group('#user-submenu', '用户', icon: 'user') do %> <%= sidebar_item_group('#user-submenu', '用户', icon: 'user') do %>
<li><%= sidebar_item(admins_users_path, '用户列表', icon: 'user', controller: 'admins-users') %></li> <li><%= sidebar_item(admins_users_path, '用户列表', icon: 'user', controller: 'admins-users') %></li>
<li><%= sidebar_item(admins_phenglei_users_path, '风雷意向用户列表', icon: 'user', controller: 'admins-phenglei_users') %></li>
<% end %> <% end %>
</li> </li>
<li> <li>
@ -26,6 +27,8 @@
<li><%= sidebar_item(admins_project_categories_path, '分类列表', icon: 'sitemap', controller: 'admins-project_categories') %></li> <li><%= sidebar_item(admins_project_categories_path, '分类列表', icon: 'sitemap', controller: 'admins-project_categories') %></li>
<li><%= sidebar_item(admins_project_licenses_path, '开源许可证', icon: 'file-text-o', controller: 'admins-project_licenses') %></li> <li><%= sidebar_item(admins_project_licenses_path, '开源许可证', icon: 'file-text-o', controller: 'admins-project_licenses') %></li>
<li><%= sidebar_item(admins_project_ignores_path, '忽略文件', icon: 'git', controller: 'admins-project_ignores') %></li> <li><%= sidebar_item(admins_project_ignores_path, '忽略文件', icon: 'git', controller: 'admins-project_ignores') %></li>
<li><%= sidebar_item(admins_apply_signatures_path, '特殊许可申请列表', icon: 'git', controller: 'admins-apply_signatures') %></li>
<% end %> <% end %>
</li> </li>

View File

@ -64,12 +64,12 @@
<%= f.label :identity, label: '职业' %> <%= f.label :identity, label: '职业' %>
<%= select_tag('user[identity]', [], class: 'form-control identity-select optional', 'data-value': @user.user_extension&.identity, 'data-first-title': '请选择') %> <%= select_tag('user[identity]', [], class: 'form-control identity-select optional', 'data-value': @user.user_extension&.identity, 'data-first-title': '请选择') %>
</div> </div>
<div class="form-group technical-title-select-wrapper optional col-md-1" style="<%= @user.user_extension.student? ? 'display:none;' : '' %>"> <div class="form-group technical-title-select-wrapper optional col-md-1" style="<%= @user.user_extension&.student? ? 'display:none;' : '' %>">
<%= f.label :technical_title, label: '职称' %> <%= f.label :technical_title, label: '职称' %>
<%= select_tag('user[technical_title]', [], class: 'form-control technical-title-select optional', 'data-value': @user.technical_title) %> <%= select_tag('user[technical_title]', [], class: 'form-control technical-title-select optional', 'data-value': @user.technical_title) %>
</div> </div>
<%= f.input :student_id, as: :tel, label: '学号', wrapper_html: { class: 'col-md-2', style: @user.user_extension.student? ? '' : 'display:none;' }, input_html: { class: 'student-id-input' } %> <%= f.input :student_id, as: :tel, label: '学号', wrapper_html: { class: 'col-md-2', style: @user.user_extension&.student? ? '' : 'display:none;' }, input_html: { class: 'student-id-input' } %>
</div> </div>
<div class="form-row"> <div class="form-row">

View File

@ -25,16 +25,17 @@
<%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-sm-2 ml-3', placeholder: 'ID/姓名/邮箱/手机号检索') %> <%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-sm-2 ml-3', placeholder: 'ID/姓名/邮箱/手机号检索') %>
<% <%
=begin%> =begin%>
<%= text_field_tag(:school_name, params[:school_name], class: 'form-control col-sm-2', placeholder: '学校/单位检索') %> <%= text_field_tag(:school_name, params[:school_name], class: 'form-control col-sm-2', placeholder: '学校/单位检索') %>
<% <%
=end%> =end%>
<%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %> <%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %>
<% end %> <% end %>
<%= javascript_void_link '导入用户', class: 'btn btn-secondary btn-sm', data: { toggle: 'modal', target: '.admin-import-user-modal'} %> <%= link_to '新增', new_admins_user_path, class: 'btn btn-primary ml-3' %>
<%#= javascript_void_link '导入用户', class: 'btn btn-secondary btn-sm', data: { toggle: 'modal', target: '.admin-import-user-modal'} %>
<% <%
=begin%> =begin%>
<%= javascript_void_link '导入课堂成员', class: 'btn btn-secondary btn-sm ml-2', data: { toggle: 'modal', target: '.admin-import-course-member-modal'} %> <%= javascript_void_link '导入课堂成员', class: 'btn btn-secondary btn-sm ml-2', data: { toggle: 'modal', target: '.admin-import-course-member-modal'} %>
<% <%
=end%> =end%>
</div> </div>
@ -47,4 +48,4 @@
<%= render partial: 'admins/users/shared/import_user_modal' %> <%= render partial: 'admins/users/shared/import_user_modal' %>
<!-- TODO: move to course list page --> <!-- TODO: move to course list page -->
<%= render partial: 'admins/courses/shared/import_course_member_modal' %> <%= render partial: 'admins/courses/shared/import_course_member_modal' %>

View File

@ -0,0 +1,27 @@
<%
define_admin_breadcrumbs do
add_admin_breadcrumb('用户管理', admins_users_path)
add_admin_breadcrumb('新增用户')
end
%>
<div class="box user-edit-container">
<%= simple_form_for([:admins, User.new], url: admins_users_path ) do |f| %>
<%= f.error_notification %>
<div class="form-group px-2">
<div class="form-row">
<%= f.input :phone, as: :tel, label: '手机号', required: true, wrapper_html: { class: 'col-md-3' }, input_html: { class: 'col-sm-11', autocomplete: 'off' } %>
</div>
</div>
<div class="form-row">
<%= f.input :password, as: :password, required: true, label: '密码', wrapper_html: { class: 'col-md-3' }, input_html: { class: 'col-sm-11', autocomplete: 'new-password' } %>
<%= f.input :password_confirmation, as: :password, required: true, label: '确认密码', wrapper_html: { class: 'col-md-3' }, input_html: { class: 'col-sm-11', autocomplete: 'new-password' } %>
</div>
<div class="form-row mt-4">
<%= f.button :submit, value: '保存', class: 'btn-primary mr-3 px-4' %>
<%= link_to '取消', admins_users_path, class: 'btn btn-secondary px-4' %>
</div>
<% end %>
</div>

View File

@ -0,0 +1,4 @@
json.id @signature.id
json.attachment do
json.filename @attachment.filename
end

View File

@ -0,0 +1,19 @@
json.total_count @apply_signatures.total_count
json.apply_signatures @apply_signatures do |signature|
json.id signature.id
json.status signature.status
if signature.user.present?
json.user do
json.partial! 'members/member', user: signature.user
json.is_owner @project.owner?(signature.user)
end
end
if signature.attachments.present?
attachment = signature.attachments.take
json.attachment do
json.filename attachment.filename
json.path attachment_path(attachment)
end
end
end

View File

@ -1,2 +1,3 @@
json.status 0
json.id @attachment.id json.id @attachment.id
json.filesize @attachment.filesize json.filesize @attachment.filesize

View File

@ -1 +1 @@
json.licenses @licenses, :id, :name json.licenses @licenses, :id, :name, :is_secret

View File

@ -5,5 +5,6 @@ json.members @members do |member|
json.is_owner @project.owner?(member.user) json.is_owner @project.owner?(member.user)
json.role member.roles.last.name json.role member.roles.last.name
json.role_name t("roles.#{member.roles.last.name}") json.role_name t("roles.#{member.roles.last.name}")
json.is_apply_signature member.is_apply_signature
end end
end end

View File

@ -1,5 +1,6 @@
json.array! @project_categories do |category| json.array! @project_categories do |category|
hidden_projects = category.projects.joins(:license).where(is_public: false, licenses: {is_secret: false})
json.id category.id json.id category.id
json.name category.name json.name category.name
json.projects_count category.projects_count json.projects_count category.projects_count - hidden_projects.size
end end

View File

@ -7,6 +7,7 @@ json.visits project.visits
json.praises_count project.praises_count.to_i json.praises_count project.praises_count.to_i
json.forked_count project.forked_count.to_i json.forked_count project.forked_count.to_i
json.is_public project.is_public json.is_public project.is_public
json.is_secret project.is_secret
json.mirror_url project.repository&.mirror_url json.mirror_url project.repository&.mirror_url
json.type project&.numerical_for_project_type json.type project&.numerical_for_project_type
json.last_update_time render_unix_time(project.updated_on) json.last_update_time render_unix_time(project.updated_on)
@ -46,3 +47,9 @@ json.language do
json.name project.project_language.name json.name project.project_language.name
end end
end end
json.is_member !project.members.where(user_id: current_user.id).blank?
user_apply_signatures = project.apply_signatures.with_user_id(current_user.id)
json.user_apply_signatures user_apply_signatures do |signature|
json.id signature.id
json.status signature.status
end

View File

@ -4,8 +4,8 @@ json.array! @branches do |branch|
json.user_can_merge branch['user_can_merge'] json.user_can_merge branch['user_can_merge']
json.protected branch['protected'] json.protected branch['protected']
json.http_url render_http_url(@project) json.http_url render_http_url(@project)
json.zip_url render_zip_url(@project, branch['name']) json.zip_url render_zip_url(@owner, @repository, branch['name'])
json.tar_url render_tar_url(@project, branch['name']) json.tar_url render_tar_url(@owner, @repository, branch['name'])
json.last_commit do json.last_commit do
json.sha branch['commit']['id'] json.sha branch['commit']['id']
json.message branch['commit']['message'] json.message branch['commit']['message']

View File

@ -1,5 +1,10 @@
json.array! @project_statics_list do |static| # json.array! @project_group_list do |type,v|
json.project_type static[:project_type] # json.project_type type
json.name static[:name] # json.name render_zh_project_type(type)
json.projects_count static[:projects_count] # json.projects_count v
# end
json.array! @project_group_list do |k,v|
json.name k
json.id v
end end

View File

@ -10,6 +10,7 @@ json.projects @projects do |project|
json.praises_count project.praises_count.to_i json.praises_count project.praises_count.to_i
json.forked_count project.forked_count.to_i json.forked_count project.forked_count.to_i
json.is_public project.is_public json.is_public project.is_public
json.is_secret project.is_secret
json.mirror_url project.repository&.mirror_url json.mirror_url project.repository&.mirror_url
json.type project&.numerical_for_project_type json.type project&.numerical_for_project_type
json.last_update_time render_unix_time(project.updated_on) json.last_update_time render_unix_time(project.updated_on)
@ -47,4 +48,10 @@ json.projects @projects do |project|
json.name project.project_language.name json.name project.project_language.name
end end
end end
json.is_member project.member?(current_user.id)
user_apply_signatures = project.apply_signatures.with_user_id(current_user.id)
json.user_apply_signatures user_apply_signatures do |signature|
json.id signature.id
json.status signature.status
end
end end

View File

@ -1,6 +1,12 @@
json.name @project.name json.name @project.name
json.identifier @project.identifier json.identifier @project.identifier
json.is_public @project.is_public json.is_public @project.is_public
json.is_secret @project.is_secret
json.description @project.description json.description @project.description
json.repo_id @project.repository.id json.repo_id @project.repository.id
json.repo_identifier @project.repository.identifier json.repo_identifier @project.repository.identifier
user_apply_signatures = @project.apply_signatures.with_user_id(current_user.id)
json.user_apply_signatures user_apply_signatures do |signature|
json.id signature.id
json.status signature.status
end

View File

@ -21,8 +21,6 @@ json.issues do
json.fork_project_id pr&.fork_project_id json.fork_project_id pr&.fork_project_id
json.fork_project_identifier pr&.fork_project&.identifier json.fork_project_identifier pr&.fork_project&.identifier
json.fork_project_user pr&.fork_project&.owner.try(:login) json.fork_project_user pr&.fork_project&.owner.try(:login)
json.id issue.id json.id issue.id
json.name issue.subject json.name issue.subject
json.pr_time time_from_now(pr.status == 1 ? pr.updated_at : issue.updated_on) json.pr_time time_from_now(pr.status == 1 ? pr.updated_at : issue.updated_on)

View File

@ -5,3 +5,4 @@ json.project_description @project.description
json.project_category_id @project.project_category_id json.project_category_id @project.project_category_id
json.project_language_id @project.project_language_id json.project_language_id @project.project_language_id
json.private !@project.is_public json.private !@project.is_public
json.is_secret @project.is_secret

View File

@ -42,8 +42,8 @@ if @project.forge?
#json.tags_count @tags_count #json.tags_count @tags_count
#json.branches_count @branches_count #json.branches_count @branches_count
#json.commits_count @commits_count #json.commits_count @commits_count
json.zip_url render_zip_url(@project, @ref) json.zip_url render_zip_url(@owner, @repository, @ref)
json.tar_url render_tar_url(@project, @ref) json.tar_url render_tar_url(@owner, @repository, @ref)
json.entries do json.entries do
json.array! @entries do |entry| json.array! @entries do |entry|
json.name entry['name'] json.name entry['name']

View File

@ -17,6 +17,12 @@ json.mirror_url @project&.repository.mirror_url
json.mirror @project&.repository.mirror_url.present? json.mirror @project&.repository.mirror_url.present?
json.type @project.numerical_for_project_type json.type @project.numerical_for_project_type
json.open_devops @project.open_devops? json.open_devops @project.open_devops?
json.is_secret @project.is_secret
user_apply_signatures = @project.apply_signatures.with_user_id(current_user.id)
json.user_apply_signatures user_apply_signatures do |signature|
json.id signature.id
json.status signature.status
end
unless @project.common? unless @project.common?
json.mirror_status @repo.mirror_status json.mirror_status @repo.mirror_status

View File

@ -2,8 +2,8 @@ json.array! @tags do |tag|
if tag.present? if tag.present?
json.name tag['name'] json.name tag['name']
json.id tag['id'] json.id tag['id']
json.zipball_url tag['zipball_url'] json.zipball_url render_zip_url(@owner, @repository, tag['name'])
json.tarball_url tag['tarball_url'] json.tarball_url render_tar_url(@owner, @repository, tag['name'])
json.commit do json.commit do
json.sha tag['commit']['sha'] json.sha tag['commit']['sha']
end end

View File

@ -19,15 +19,16 @@ json.setting do
# end # end
nav_bar = default_setting.navbar nav_bar = default_setting.navbar
# if User.current.logged? # if User.current.logged?
# nav_bar[2]["link"] = "https://forgeplus.trustie.net/users/#{current_user.login}/projects" # nav_bar[2]["link"] = "/users/#{current_user.login}/projects"
# nav_bar[2]["hidden"] = false # nav_bar[2]["hidden"] = false
# else # else
# nav_bar[2]["link"] = "" # nav_bar[2]["link"] = ""
# nav_bar[2]["hidden"] = true # nav_bar[2]["hidden"] = true
# end # end
if current_user && current_user.admin?
nav_bar << manager_main_site_url
end
json.name default_setting.name json.name default_setting.name
json.nav_logo_url default_setting.nav_logo_url&.[](1..-1) json.nav_logo_url default_setting.nav_logo_url&.[](1..-1)
json.login_logo_url default_setting.login_logo_url&.[](1..-1) json.login_logo_url default_setting.login_logo_url&.[](1..-1)
@ -42,10 +43,8 @@ json.setting do
json.navbar nav_bar json.navbar nav_bar
json.footer default_setting.footer json.footer default_setting.footer
json.main_site current_laboratory.main_site?
json.new_course default_course_links json.new_course default_course_links
json.old_projects_url @old_projects_url json.main_site current_laboratory.main_site?
json.main_web_site_url main_web_site_url
json.current_main_site_url current_main_site_url
end end

View File

@ -14,8 +14,8 @@ json.releases do
json.name re["name"] json.name re["name"]
json.body re["body"] json.body re["body"]
json.url re["url"] json.url re["url"]
json.tarball_url re["tarball_url"] json.tarball_url render_tar_url(@owner, @repository, re["tag_name"])
json.zipball_url re["zipball_url"] json.zipball_url render_zip_url(@owner, @repository, re["tag_name"])
json.draft re["draft"] ? "草稿" : (re["prerelease"] ? "预发行" : "稳定") json.draft re["draft"] ? "草稿" : (re["prerelease"] ? "预发行" : "稳定")
json.created_at format_time(re["created_at"].to_s.to_time) json.created_at format_time(re["created_at"].to_s.to_time)
json.published_at format_time(re["published_at"].to_s.to_time) json.published_at format_time(re["published_at"].to_s.to_time)
@ -30,8 +30,8 @@ json.releases do
json.name re["name"] json.name re["name"]
json.body re["body"] json.body re["body"]
json.url re["url"] json.url re["url"]
json.tarball_url re["tarball_url"] json.tarball_url render_tar_url(@owner, @repository, re["tag_name"])
json.zipball_url re["zipball_url"] json.zipball_url render_zip_url(@owner, @repository, re["tag_name"])
json.draft re["draft"] ? "草稿" : (re["prerelease"] ? "预发行" : "稳定") json.draft re["draft"] ? "草稿" : (re["prerelease"] ? "预发行" : "稳定")
json.created_at format_time(re["created_at"].to_s.to_time) json.created_at format_time(re["created_at"].to_s.to_time)
json.published_at format_time(re["published_at"].to_s.to_time) json.published_at format_time(re["published_at"].to_s.to_time)

View File

@ -0,0 +1,14 @@
'zh-CN':
activemodel:
attributes:
users/admin_create_user_form:
login: '登录名'
password: '密码'
mail: '邮箱'
phone: '手机号'
errors:
models:
users/admin_create_user_form:
attributes:

View File

@ -97,6 +97,11 @@ Rails.application.routes.draw do
delete :destroy_files delete :destroy_files
end end
end end
resources :apply_signatures, only: [:index, :create, :update] do
collection do
get :template_file
end
end
get 'home/index' get 'home/index'
get 'home/search' get 'home/search'
get 'main/first_stamp' get 'main/first_stamp'
@ -380,7 +385,6 @@ Rails.application.routes.draw do
resource :repositories, path: '/', only: [:show, :create, :edit] do resource :repositories, path: '/', only: [:show, :create, :edit] do
member do member do
get :archive
get :top_counts get :top_counts
get :entries get :entries
match :sub_entries, :via => [:get, :put] match :sub_entries, :via => [:get, :put]
@ -395,6 +399,7 @@ Rails.application.routes.draw do
get 'commits/:sha', to: 'repositories#commit', as: 'commit' get 'commits/:sha', to: 'repositories#commit', as: 'commit'
get 'readme' get 'readme'
get 'languages' get 'languages'
get 'archive/:archive', to: 'repositories#archive', as: "archive", constraints: { archive: /.+/, format: /(zip|gzip)/ }
end end
end end
@ -636,7 +641,7 @@ Rails.application.routes.draw do
get :contrast, on: :collection get :contrast, on: :collection
end end
resources :users, only: [:index, :edit, :update, :destroy] do resources :users do
member do member do
post :reward_grade post :reward_grade
post :lock post :lock
@ -645,6 +650,7 @@ Rails.application.routes.draw do
post :reset_login_times post :reset_login_times
end end
end end
resources :phenglei_users, only: [:index, :new, :create]
resource :import_disciplines, only: [:create] resource :import_disciplines, only: [:create]
resource :import_users, only: [:create] resource :import_users, only: [:create]
resource :import_course_members, only: [:create] resource :import_course_members, only: [:create]
@ -822,7 +828,11 @@ Rails.application.routes.draw do
resources :courses, only: [:index, :destroy, :update] resources :courses, only: [:index, :destroy, :update]
resources :projects, only: [:index, :destroy] resources :projects, only: [:index, :destroy] do
member do
get :sync_phenglei_user
end
end
resources :disciplines, only: [:index, :create, :edit, :update, :destroy] do resources :disciplines, only: [:index, :create, :edit, :update, :destroy] do
post :adjust_position, on: :member post :adjust_position, on: :member
@ -847,6 +857,7 @@ Rails.application.routes.draw do
resources :salesman_customers, only: [:index, :create, :edit, :update, :destroy] do resources :salesman_customers, only: [:index, :create, :edit, :update, :destroy] do
post :batch_add, on: :collection post :batch_add, on: :collection
end end
resources :apply_signatures, only: [:index, :update]
end end

View File

@ -2,3 +2,7 @@ sync_gitea_repo_update_time:
cron: "0 0 * * *" cron: "0 0 * * *"
class: "SyncRepoUpdateTimeJob" class: "SyncRepoUpdateTimeJob"
queue: default queue: default
sync_phenglei_user:
cron: "0 23 * * *"
class: "SyncPhengleiUserJob"
queue: default

View File

@ -1,17 +1,17 @@
class CreateProjectCategories < ActiveRecord::Migration[5.2] class CreateProjectCategories < ActiveRecord::Migration[5.2]
def change # def change
# create_table :project_categories do |t| # # create_table :project_categories do |t|
# t.string :name # # t.string :name
# t.integer :position # # t.integer :position
# t.integer :projects_count, :default => 0 # # t.integer :projects_count, :default => 0
# # #
# t.timestamps # # t.timestamps
# end # # end
names = %w(大数据 机器学习 深度学习 人工智能 量子计算 智慧医疗 自动驾驶 其他) # names = %w(大数据 机器学习 深度学习 人工智能 量子计算 智慧医疗 自动驾驶 其他)
names.each do |name| # names.each do |name|
ProjectCategory.find_or_create_by!(name: name) # ProjectCategory.find_or_create_by!(name: name)
end # end
end end
end end

Some files were not shown because too many files have changed in this diff Show More