Compare commits

..

183 Commits

Author SHA1 Message Date
chenjing f8d9aebfcb change projedeID to sync 2022-07-13 11:10:27 +08:00
chenjing a82cf528a6 change synchronization_service 2022-07-13 10:50:06 +08:00
chenjing d957955789 fix service bug 2022-07-13 10:27:21 +08:00
chenjing db185ba647 fix target_type error 2022-07-13 09:54:16 +08:00
chenjing 25f7b340d2 add sync to smart.doaction when follow project 2022-07-13 09:41:57 +08:00
chenjing aaeec77d23 add login by giteatoken 2022-06-23 16:15:03 +08:00
chenjing 8670bcf95c add smartdoaction to user platform 2022-05-25 17:40:40 +08:00
xiaoxiaoqiong 6c70b680ea fixed 项目查询错误 2022-01-05 15:50:31 +08:00
xiaoxiaoqiong 67020b7e73 科技部项目同步木兰镜像用户 2022-01-05 15:32:46 +08:00
xiaoxiaoqiong 34af5a59eb 科技部项目同步木兰镜像用户 2022-01-05 15:13:02 +08:00
xiaoxiaoqiong 2b15792e49 科技部项目同步木兰镜像 2022-01-05 15:03:33 +08:00
xiaoxiaoqiong 03fcc435a6 科技部项目同步木兰镜像 2022-01-05 14:43:38 +08:00
yystopf 5d88b6cb90 fix: use kaminary 2021-11-22 14:50:01 +08:00
xxq250 9e2d8fba0e Merge pull request '木兰版本:项目首页分页功能' (#254) from yystopf/forgeplus:mulanoss_server into mulanoss_server 2021-11-22 14:41:19 +08:00
yystopf a28589cce5 fix: change index paginate 2021-11-22 14:32:44 +08:00
jasder c860e7bc43 Merge pull request '调整返回给前端的sonar_url' (#222) from gua2048/forgeplus:mulanoss_server into mulanoss_server 2021-10-23 21:55:14 +08:00
chenjing 2743da824e add sonar_url for details 2021-10-23 21:19:56 +08:00
jasder 1822ade2db Merge pull request 'project 新增sonar_url ,且新增回调接口,新增调试工具' (#220) from gua2048/forgeplus:mulanoss_server into mulanoss_server 2021-10-22 16:25:02 +08:00
chenjing 91fa87ada5 为项目新增sonar_url 且增加回调接口 2021-10-22 15:23:32 +08:00
jasder 38e55cea40 Merge pull request 'ADD 通知系统动态配置功能以及修复Issue、Pr标题限制问题' (#209) from jasder/forgeplus:mulanoss_server into mulanoss_server 2021-10-19 15:40:00 +08:00
jasder 2f038117f7 FIX 合并主干分支代码并解决代码冲突 2021-10-19 15:35:41 +08:00
jasder d0b3ea7a5a Merge pull request '更新木兰授权地址' (#186) from gua2048/forgeplus:mulanoss_server into mulanoss_server 2021-10-14 10:56:51 +08:00
chenjing 734ff6463a 更改木兰授权页面地址 2021-10-14 10:44:34 +08:00
jasder 3e399af371 Merge pull request 'FIX WIP' (#185) from jasder/forgeplus:mulanoss_server into mulanoss_server 2021-10-13 11:42:15 +08:00
jasder f7ca0c3a13 集成develop分支最新代码 2021-10-13 11:22:02 +08:00
jasder 8343c625c3 Merge pull request '更新木兰授权地址' (#183) from gua2048/forgeplus:mulanoss_server into mulanoss_server 2021-10-13 09:51:46 +08:00
chenjing eec57f26b9 更新授权地址 2021-10-13 09:46:27 +08:00
jasder 5930a93b8f Merge pull request '新增北航发送评论接口' (#182) from gua2048/forgeplus:mulanoss_server into mulanoss_server 2021-10-12 23:02:15 +08:00
chenjing b5dd2ade82 add Journals beihang 2021-10-12 22:56:50 +08:00
jasder 7812996894 Merge pull request '新增授权木兰邮箱地址判定' (#170) from gua2048/forgeplus:mulanoss_server into mulanoss_server 2021-09-30 10:13:05 +08:00
chenjing 8c2f0e9fdb 新增邮箱判定 2021-09-30 10:08:40 +08:00
jasder ab9bdfd109 Merge pull request '新增callback路由' (#168) from gua2048/forgeplus:mulanoss_server into mulanoss_server 2021-09-29 17:33:18 +08:00
chenjing 8d81672ac5 fix routes 2021-09-29 17:30:10 +08:00
jasder a721968938 Merge pull request '木兰第三方登录授权登录' (#167) from gua2048/forgeplus:mulanoss_server into mulanoss_server 2021-09-29 15:15:59 +08:00
chenjing 0bacc4c969 remove educoder third login 2021-09-29 15:11:32 +08:00
chenjing d63df944c8 木兰授权登录 2021-09-29 14:42:13 +08:00
jasder eb593c384b Merge pull request 'FIX 修复相关bug' (#156) from jasder/forgeplus:mulanoss_server into mulanoss_server 2021-09-26 17:48:33 +08:00
jasder 0cbfc895ca Merge pull request 'FIX 修复修改组织信息后导致不能创建项目的bug' (#152) from dev_trustie_server into trustie_server 2021-09-10 22:52:12 +08:00
jasder 2fab120118 Merge pull request 'FIX 修复修改组织信息后导致不能创建项目的bug' (#151) from develop into dev_trustie_server 2021-09-10 22:51:18 +08:00
jasder 629729436c Merge pull request 'FIX 优化创建项目流程' (#149) from dev_trustie_server into trustie_server 2021-09-10 19:03:26 +08:00
jasder 00ed177089 Merge pull request 'FIX bug' (#148) from develop into dev_trustie_server 2021-09-10 18:32:08 +08:00
jasder 26c0d36227 Merge pull request 'FIX 优化项目流程' (#146) from develop into dev_trustie_server 2021-09-10 18:28:36 +08:00
jasder 86c98a1716 Merge pull request '发布V3.1.0版本' (#139) from dev_trustie_server into trustie_server 2021-09-03 18:16:51 +08:00
jasder 143e88593f Merge pull request 'FIX 路由优化' (#138) from develop into dev_trustie_server 2021-09-03 17:55:43 +08:00
jasder 99e3aaf780 Merge pull request 'merge dev_trustie_server' (#134) from dev_trustie_server into trustie_server 2021-09-01 19:02:51 +08:00
jasder 7d12a25088 Merge pull request 'FIX commit user info' (#133) from develop into dev_trustie_server 2021-09-01 19:01:22 +08:00
jasder 85d1aa3a85 Merge pull request 'fix release v3.2.0' (#129) from dev_trustie_server into trustie_server 2021-08-27 15:28:22 +08:00
jasder 0f57844106 Merge pull request 'FIX some bug' (#128) from develop into dev_trustie_server 2021-08-27 15:12:27 +08:00
jasder c3b9d2e0b5 ADD wiki模块功能 2021-08-24 18:17:34 +08:00
jasder 299e8534d1 Merge branch 'develop' into dev_trustie_server 2021-08-19 17:48:31 +08:00
jasder d7362925f2 Merge branch 'dev_trustie_server' into trustie_server 2021-08-06 17:24:02 +08:00
jasder 43945b00b8 Merge branch 'dev_trustie_server' of https://git.trustie.net/jasder/forgeplus into dev_trustie_server 2021-08-06 17:20:44 +08:00
jasder b11d515ec6 Merge branch 'develop' into dev_trustie_server 2021-08-06 17:20:30 +08:00
yystopf 07a38ac3f7 Merge branch 'develop' into dev_trustie_server 2021-07-30 18:12:19 +08:00
yystopf 18227c232b Merge branch 'develop' into trustie_server 2021-07-30 18:10:31 +08:00
jasder f1d79e4d9f Merge branch 'trustie_server' of https://git.trustie.net/jasder/forgeplus into trustie_server 2021-07-30 17:08:42 +08:00
jasder 20e2e22be5 Merge branch 'dev_trustie_server' into trustie_server 2021-07-30 17:08:23 +08:00
jasder 27e5febef2 Merge branch 'develop' into dev_trustie_server 2021-07-30 17:04:21 +08:00
yystopf fb23e733d6 Merge branch 'develop' into dev_trustie_server 2021-07-23 17:23:45 +08:00
yystopf 512bff426d Merge branch 'develop' into trustie_server 2021-07-23 17:23:29 +08:00
yystopf 671c2c2257 Merge branch 'develop' into trustie_server 2021-07-23 14:53:18 +08:00
yystopf c6f2021017 Merge branch 'develop' into dev_trustie_server 2021-07-23 14:53:06 +08:00
jasder 581b147b3c Merge branch 'dev_trustie_server' of https://git.trustie.net/jasder/forgeplus into dev_trustie_server 2021-07-23 14:16:43 +08:00
jasder deebfc3292 fix merge develop branch 2021-07-23 14:16:29 +08:00
yystopf 6c4d17bed8 Merge branch 'develop' into trustie_server 2021-07-22 18:31:44 +08:00
yystopf e68c13f1a2 Merge branch 'develop' into dev_trustie_server 2021-07-22 18:30:59 +08:00
yystopf 15eb1f4a17 Merge branch 'develop' into dev_trustie_server 2021-07-21 21:32:38 +08:00
yystopf a1cb9a11d6 Merge branch 'develop' into trustie_server 2021-07-21 21:32:18 +08:00
yystopf 0884a0de1b Merge branch 'develop' into dev_trustie_server 2021-07-16 16:46:28 +08:00
yystopf 900fdd2691 Merge branch 'develop' into trustie_server 2021-07-16 16:46:08 +08:00
viletyy 4520055de2 Merge branch 'dev_trustie_server' into trustie_server 2021-07-12 18:38:03 +08:00
viletyy 193d1b21df Merge branch 'develop' into dev_trustie_server 2021-07-12 18:10:50 +08:00
viletyy ed8e079595 Merge branch 'develop' into dev_trustie_server 2021-07-12 17:57:51 +08:00
viletyy 55a0bcfb82 fix 2021-07-12 17:33:10 +08:00
viletyy 8f1aa3f4b1 fix: merge from develop 2021-07-12 17:28:47 +08:00
jasder b054094798 FIX conflicts 2021-07-12 16:20:14 +08:00
jasder 2d648e516e FIX merge develop branch 2021-07-12 16:19:03 +08:00
yystopf 7c23b40661 易修权限、用户更改昵称、fork项目修改项目私有性 2021-07-09 13:55:22 +08:00
viletyy ff21916f18 fix: merge from develop 2021-07-09 13:48:48 +08:00
viletyy d9162cb3bf fix: merge from develop 2021-07-09 13:47:21 +08:00
jasder ca1fd3cd4f FIX 解决标签列表和发行版列表中下周zip包、tar包导致的404问题 2021-07-01 16:57:52 +08:00
jasder 913bc45a9f Merge branch 'dev_trustie_server' of https://git.trustie.net/jasder/forgeplus into dev_trustie_server 2021-07-01 10:09:28 +08:00
jasder 8131d8cd48 Merge branch 'sync_develop' into dev_trustie_server 2021-07-01 10:08:58 +08:00
viletyy b45ab12279 Merge branch 'dev_trustie_server' into trustie_server 2021-06-28 21:11:13 +08:00
viletyy 259090b8e3 fix 2021-06-28 21:07:10 +08:00
jasder c3bc4166d9 FIX pr bug
ADD conflict files list
2021-06-28 10:09:40 +08:00
jasder 7e474cab70 Merge branch 'feature/pull_conflict_files' into dev_trustie_server 2021-06-28 10:06:54 +08:00
jasder 01341d4389 FIX pull、 gitea pull model relation bug 2021-06-28 10:04:48 +08:00
jasder 3a475a4674 FIX get conflict files bug with create pr api 2021-06-28 09:59:47 +08:00
jasder 83b7b8cd9c Merge branch 'develop' into dev_trustie_server 2021-06-25 18:03:28 +08:00
jasder c298ff02b8 ADD pr冲突文件展示 2021-06-25 18:03:07 +08:00
jasder 16ea03dcc8 fix 修复一些bug
* 解决获取平台base url导致的https的问题
* FIX 处理版本库zip、gzip包链接为无效的问题
2021-06-22 16:49:20 +08:00
jasder 7bb4cf7391 Merge branch 'develop' into dev_trustie_server 2021-06-22 15:15:51 +08:00
jasder 23f7439a8c Merge branch 'develop' into dev_trustie_server 2021-06-22 09:51:46 +08:00
jasder fa8f1155f5 V3.1.0
* FIX 修复pulls、issues 搜索数量统计问题
* FIX 解决在线创建文件错误提示信息不准确的问题
* FIX table name bug
* FIX 解决applied_projects相关表操作的问题
* FIX 解决排序参数的判断预防SQL注入
* FIX 项目导航栏数量改为开启中的数量
* FIX 解决项目邀请码的索引查询问题
* FIX FIX get readme file bug
* FIX sql attack
* FIX projects load by invite code slowly
2021-06-18 17:03:27 +08:00
jasder 484f8a854a Merge branch 'develop' into dev_trustie_server 2021-06-18 16:45:12 +08:00
jasder 7bedac263d Merge branch 'develop' into dev_trustie_server 2021-06-18 16:21:21 +08:00
jasder f0b1c9e80b Merge branch 'develop' into dev_trustie_server 2021-06-18 11:03:41 +08:00
jasder dc23be9001 Merge branch 'develop' into dev_trustie_server 2021-06-18 10:54:29 +08:00
jasder e24269c2a7 Merge branch 'develop' into dev_trustie_server 2021-06-17 18:14:19 +08:00
jasder e31176c696 ADD 项目邀请码功能 2021-06-11 18:13:33 +08:00
jasder bf390c8366 Merge branch 'develop' into dev_trustie_server 2021-06-11 18:03:35 +08:00
jasder 632a06e575 Merge branch 'develop' into dev_trustie_server 2021-06-08 18:13:16 +08:00
jasder 04c7887319 Merge branch 'sync_develop' into dev_trustie_server 2021-06-08 14:34:29 +08:00
jasder b012740195 ADD 升级改版个人中心模块功能 2021-06-04 19:10:07 +08:00
jasder d75b79670d Merge branch 'develop' into dev_trustie_server 2021-06-04 18:51:47 +08:00
jasder 0f79238f0e 解决镜像加速器失效问题 2021-06-03 17:29:37 +08:00
jasder 2c5fa8492f Merge branch 'develop' into dev_trustie_server 2021-06-03 17:26:35 +08:00
jasder fdfbf505ed ADD issue、pull、milestone钩子,自动触发项目的更新时间 2021-05-26 17:52:30 +08:00
jasder 6d845eeb3b Merge branch 'develop' into dev_trustie_server 2021-05-26 17:39:54 +08:00
jasder a7695b16a4 FIX query project members api bug 2021-05-24 17:08:03 +08:00
jasder 83e666a387 Merge branch 'develop' into dev_trustie_server 2021-05-24 17:06:54 +08:00
jasder 1a0fd38d15 发布v3.0.4版本 2021-05-24 10:18:57 +08:00
jasder 72b89d4b2b Merge branch 'develop' into dev_trustie_server 2021-05-21 19:26:47 +08:00
jasder b0b224fe76 Merge branch 'trustie_server' of https://git.trustie.net/jasder/forgeplus into trustie_server 2021-05-15 10:21:03 +08:00
jasder 38f6254edc Merge branch 'develop' into dev_trustie_server 2021-05-15 10:20:14 +08:00
jasder 57d9da002e ADD 页面置顶等功能 2021-05-14 17:57:48 +08:00
jasder 8a4b0ba966 Merge branch 'develop' into dev_trustie_server 2021-05-14 17:34:36 +08:00
jasder 84927c2361 FIX 解决大赛中点击项目跳转到forge平台,保持自动登陆的bug 2021-05-13 11:47:47 +08:00
jasder b568ac4e97 ADD title 2021-05-12 17:48:05 +08:00
jasder 91bbb58d4f FIX delete input readonly 2021-05-12 17:44:45 +08:00
jasder f278b38e6c Merge branch 'trustie_server' into dev_trustie_server 2021-05-12 17:01:59 +08:00
jasder 4023b8980e FIX 完善通过大赛点击项目链接自动注册关联Educoder平台账号的功能 2021-05-12 17:01:30 +08:00
jasder 1c1be18151 Merge branch 'dev_trustie_server' into trustie_server 2021-05-10 14:39:14 +08:00
jasder e5f591e509 Merge branch 'develop' into dev_trustie_server 2021-05-10 14:38:58 +08:00
yystopf 27ee32054b 发布v3.0.3版本 2021-05-08 17:45:23 +08:00
jasder 3e3fd46cad Merge branch 'develop' into dev_trustie_server 2021-05-08 17:02:56 +08:00
jasder 7a752b177d Merge branch 'develop' into dev_trustie_server 2021-05-08 14:23:34 +08:00
jasder abbabfdefd Merge branch 'dev_trustie_server' into trustie_server 2021-04-30 17:13:33 +08:00
jasder edd76b9286 Merge branch 'develop' into dev_trustie_server 2021-04-30 17:13:18 +08:00
jasder a3ca94d433 Merge branch 'dev_trustie_server' into trustie_server 2021-04-29 23:23:55 +08:00
jasder 91a804caf7 Merge branch 'develop' into dev_trustie_server 2021-04-29 23:23:42 +08:00
jasder 663deae21b Merge branch 'dev_trustie_server' into trustie_server 2021-04-29 23:19:34 +08:00
jasder dae5c9690f Merge branch 'develop' into dev_trustie_server 2021-04-29 23:19:17 +08:00
jasder e65df07d79 Merge branch 'dev_trustie_server' into trustie_server 2021-04-29 19:27:55 +08:00
jasder 246b6b52ec Merge branch 'develop' into dev_trustie_server 2021-04-29 19:27:36 +08:00
jasder b9789183e3 Merge branch 'dev_trustie_server' into trustie_server 2021-04-29 19:17:03 +08:00
jasder 7cf2c6021f Merge branch 'develop' into dev_trustie_server 2021-04-29 19:13:12 +08:00
jasder e0f9a3d43d Merge branch 'develop' into dev_trustie_server 2021-04-29 18:50:11 +08:00
jasder c1ef39b262 Merge branch 'develop' into dev_trustie_server 2021-04-29 18:37:35 +08:00
jasder 51643dc02c Merge branch 'dev_trustie_server' into trustie_server 2021-04-29 10:42:12 +08:00
jasder a078c07b59 Merge branch 'develop' into dev_trustie_server 2021-04-29 10:41:59 +08:00
jasder b984790d5c Merge branch 'develop' into trustie_server 2021-04-28 21:17:43 +08:00
jasder 876591100e Merge branch 'develop' into dev_trustie_server 2021-04-28 21:17:36 +08:00
jasder ba9848ebe7 Merge branch 'develop' into dev_trustie_server 2021-04-27 18:24:41 +08:00
jasder 41c621cf55 Merge branch 'develop' into dev_trustie_server 2021-04-26 16:53:05 +08:00
jasder 09ac49dda5 Merge branch 'develop' into dev_trustie_server 2021-04-26 16:46:24 +08:00
jasder 341a810afc Merge branch 'develop' into dev_trustie_server 2021-04-23 17:54:13 +08:00
jasder 2282c52efb FIX update README.md 2021-04-23 17:33:19 +08:00
jasder 34edd78ae7 Merge branch 'develop' into dev_trustie_server 2021-04-23 17:21:34 +08:00
jasder 36fb5a118c Merge branch 'develop' into dev_trustie_server 2021-04-23 14:40:41 +08:00
jasder b756be1d6a Merge branch 'develop' into dev_trustie_server 2021-04-22 18:10:32 +08:00
jasder 348c2244f7 Merge branch 'develop' into dev_trustie_server 2021-04-22 16:45:40 +08:00
jasder 31738fc227 Merge branch 'develop' into dev_trustie_server 2021-04-22 16:43:04 +08:00
jasder a93c98fb7c Merge branch 'trustie_server' into dev_trustie_server 2021-04-22 16:39:03 +08:00
jasder 39193324e9 Merge branch 'develop' into dev_trustie_server 2021-04-22 16:38:58 +08:00
jasder 81743ce3bc Merge branch 'develop' into trustie_server 2021-04-20 19:07:56 +08:00
jasder e9ae536f04 Merge branch 'develop' into trustie_server 2021-04-20 19:06:40 +08:00
jasder 186955fe4a Merge branch 'develop' into trustie_server 2021-04-20 18:58:24 +08:00
jasder 8ce7fd95cb Merge branch 'develop' into trustie_server 2021-04-20 18:37:55 +08:00
jasder 0867e5130f Merge branch 'dev_trustie_server' into trustie_server 2021-04-20 11:37:25 +08:00
jasder db476a1a9b Merge branch 'develop' into dev_trustie_server 2021-04-20 11:37:08 +08:00
jasder fa1fd8a4ba Merge branch 'develop' into trustie_server 2021-04-19 20:39:29 +08:00
jasder 0d7a11f3ab Merge branch 'develop' into dev_trustie_server 2021-04-19 18:41:18 +08:00
jasder 879e45e106 Merge branch 'develop' into trustie_server 2021-04-13 16:40:23 +08:00
jasder b3b0f75e9b Merge branch 'develop' into trustie_server 2021-04-13 10:18:52 +08:00
jasder 5c8e561bd8 Merge branch 'develop' into trustie_server 2021-04-08 18:36:27 +08:00
jasder 2b0c987558 Merge branch 'develop' into trustie_server 2021-04-07 11:35:09 +08:00
jasder 6796805b21 Merge branch 'develop' into trustie_server 2021-04-02 18:58:08 +08:00
jasder 5752f19b2f FIX gug 2021-04-02 18:56:44 +08:00
jasder eb52f05417 集成educoder登陆 2021-04-02 18:46:15 +08:00
vilet.yy 786629dbff fix 2021-04-02 18:41:48 +08:00
vilet.yy 7a00541375 Merge branch 'develop' into hh_develop 2021-04-02 18:41:37 +08:00
vilet.yy 1d832a1723 fix 2021-04-02 18:38:08 +08:00
vilet.yy 80ce40e492 fix 2021-04-02 18:33:31 +08:00
vilet.yy 91f6dae56a fix 2021-04-02 18:24:20 +08:00
vilet.yy 8c5a834b14 Merge branch 'develop' into hh_develop 2021-04-02 18:22:32 +08:00
vilet.yy 57f420848e Merge branch 'develop' into hh_develop 2021-04-02 18:20:41 +08:00
vilet.yy fba58800a7 fix 2021-04-02 18:08:36 +08:00
vilet.yy c4a43c4392 add: need edit user password 2021-04-02 16:44:36 +08:00
vilet.yy 1153bd5ab6 fix: set redirect_uri 2021-04-02 09:43:18 +08:00
vilet.yy f732b0374c fix: ceshi 2021-04-02 09:23:11 +08:00
vilet.yy 0d97d7d4f0 add: educoder third party 2021-04-01 18:01:51 +08:00
451 changed files with 7241 additions and 4932 deletions

View File

@ -63,6 +63,7 @@ end
group :development do
gem 'prettier'
gem 'pry-rails', '~> 0.3.9'
gem 'rubocop', '~> 0.52.0'
gem 'solargraph', '~> 0.38.0'
gem 'awesome_print'

View File

@ -99,6 +99,7 @@ GEM
archive-zip (~> 0.10)
nokogiri (~> 1.8)
chunky_png (1.3.11)
coderay (1.1.3)
concurrent-ruby (1.1.6)
connection_pool (2.2.2)
crass (1.0.6)
@ -217,6 +218,11 @@ GEM
popper_js (1.16.0)
powerpack (0.1.2)
prettier (0.18.2)
pry (0.12.2)
coderay (~> 1.1.0)
method_source (~> 0.9.0)
pry-rails (0.3.9)
pry (>= 0.10.4)
public_suffix (4.0.3)
puma (3.12.2)
raabro (1.4.0)
@ -469,6 +475,7 @@ DEPENDENCIES
parallel (~> 1.19, >= 1.19.1)
pdfkit
prettier
pry-rails (~> 0.3.9)
puma (~> 3.11)
rack-cors
rack-mini-profiler

View File

@ -51,51 +51,6 @@ http://localhost:3000/api/accounts/remote_register | jq
|-- token |string|用户token|
返回值
```json
{
"status": 0,
"message": "success",
"user": {
"id": 36400,
"token": "8c87a80d9cfacc92fcb2451845104f35119eda96"
}
}
```
---
#### 独立注册接口
```
POST accounts/register
```
*示例*
```bash
curl -X POST \
-d "login=2456233122@qq.com" \
-d "password=djs_D_00001" \
-d "namespace=16895620" \
-d "code=forge" \
http://localhost:3000/api/accounts/remote_register | jq
```
*请求参数说明:*
|参数名|必选|类型|说明|
|-|-|-|-|
|login |是|string |邮箱或者手机号 |
|namespace |是|string |登录名 |
|password |是|string |密码 |
|code |是|string |验证码 |
*返回参数说明:*
|参数名|类型|说明|
|-|-|-|
|user|json object |返回数据|
|-- id |int |用户id |
|-- token |string|用户token|
返回值
```json
{

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -99,38 +99,3 @@ $(document).on("turbolinks:before-cache", function () {
$(function () {
});
$(document).on('turbolinks:load', function() {
$('.logo-item-left').on("change", 'input[type="file"]', function () {
var $fileInput = $(this);
var file = this.files[0];
var imageType = /image.*/;
if (file && file.type.match(imageType)) {
var reader = new FileReader();
reader.onload = function () {
var $box = $fileInput.parent();
$box.find('img').attr('src', reader.result).css('display', 'block');
$box.addClass('has-img');
};
reader.readAsDataURL(file);
} else {
}
});
$('.attachment-item-left').on("change", 'input[type="file"]', function () {
var $fileInput = $(this);
var file = this.files[0];
var imageType = /image.*/;
if (file && file.type.match(imageType)) {
var reader = new FileReader();
reader.onload = function () {
var $box = $fileInput.parent();
$box.find('img').attr('src', reader.result).css('display', 'block');
$box.addClass('has-img');
};
reader.readAsDataURL(file);
} else {
}
});
})

View File

@ -1,141 +0,0 @@
/*
* @Description: Do not edit
* @Date: 2021-08-31 11:16:45
* @LastEditors: viletyy
* @Author: viletyy
* @LastEditTime: 2021-08-31 14:19:46
* @FilePath: /forgeplus/app/assets/javascripts/admins/system_notifications/index.js
*/
$(document).on('turbolinks:load', function(){
var showSuccessNotify = function() {
$.notify({
message: '操作成功'
},{
type: 'success'
});
}
// close user
$('.project-list-container').on('click', '.recommend-action', function(){
var $closeAction = $(this);
var $uncloseAction = $closeAction.siblings('.unrecommend-action');
var $editAction = $closeAction.siblings('.edit-recommend-action');
var keywordID = $closeAction.data('id');
customConfirm({
content: '确认将该项目设置为推荐项目吗?',
ok: function(){
$.ajax({
url: '/admins/projects/' + keywordID,
method: 'PUT',
dataType: 'json',
data: {
project: {
recommend: true,
recommend_index: 1
}
},
success: function() {
showSuccessNotify();
$closeAction.hide();
$uncloseAction.show();
$editAction.show();
$(".project-item-"+keywordID).children('td').eq(5).text("√")
}
});
}
});
});
// unclose user
$('.project-list-container').on('click', '.unrecommend-action', function(){
var $uncloseAction = $(this);
var $closeAction = $uncloseAction.siblings('.recommend-action');
var $editAction = $closeAction.siblings('.edit-recommend-action');
var keywordID = $uncloseAction.data('id');
customConfirm({
content: '确认取消该推荐项目吗?',
ok: function () {
$.ajax({
url: '/admins/projects/' + keywordID,
method: 'PUT',
dataType: 'json',
data: {
project: {
recommend: false,
recommend_index: 0
}
},
success: function() {
showSuccessNotify();
$closeAction.show();
$uncloseAction.hide();
$editAction.hide();
$(".project-item-"+keywordID).children('td').eq(5).text("")
}
});
}
})
});
// close user
$('.project-list-container').on('click', '.pinned-action', function(){
var $closeAction = $(this);
var $uncloseAction = $closeAction.siblings('.unpinned-action');
var keywordID = $closeAction.data('id');
customConfirm({
content: '确认将该项目设置为精选项目吗?',
ok: function(){
$.ajax({
url: '/admins/projects/' + keywordID,
method: 'PUT',
dataType: 'json',
data: {
project: {
is_pinned: true,
}
},
success: function() {
showSuccessNotify();
$closeAction.hide();
$uncloseAction.show();
$(".project-item-"+keywordID).children('td').eq(4).text("√")
}
});
}
});
});
// unclose user
$('.project-list-container').on('click', '.unpinned-action', function(){
var $uncloseAction = $(this);
var $closeAction = $uncloseAction.siblings('.pinned-action');
var keywordID = $uncloseAction.data('id');
customConfirm({
content: '确认取消该精选项目吗?',
ok: function () {
$.ajax({
url: '/admins/projects/' + keywordID,
method: 'PUT',
dataType: 'json',
data: {
project: {
is_pinned: false,
}
},
success: function() {
showSuccessNotify();
$closeAction.show();
$uncloseAction.hide();
$(".project-item-"+keywordID).children('td').eq(4).text("")
}
});
}
})
});
})

View File

@ -58,149 +58,3 @@ input.form-control {
position: absolute;
}
.logo-item {
display: flex;
&-img {
display: block;
width: 80px;
height: 80px;
background: #e9ecef;
}
&-upload {
cursor: pointer;
position: absolute;
top: 0;
width: 80px;
height: 80px;
background: #e9ecef;
border: 1px solid #ced4da;
&::before {
content: '';
position: absolute;
top: 27px;
left: 39px;
width: 2px;
height: 26px;
background: #495057;
}
&::after {
content: '';
position: absolute;
top: 39px;
left: 27px;
width: 26px;
height: 2px;
background: #495057;
}
}
&-left {
position: relative;
width: 80px;
height: 80px;
&.has-img {
.logo-item-upload {
display: none;
}
&:hover {
.logo-item-upload {
display: block;
background: rgba(145, 145, 145, 0.8);
}
}
}
}
&-right {
display: flex;
flex-direction: column;
justify-content: space-between;
color: #777777;
font-size: 0.8rem;
}
&-title {
color: #23272B;
font-size: 1rem;
}
}
.attachment-item {
display: flex;
&-img {
display: block;
width: 160px;
height: 160px;
background: #e9ecef;
}
&-upload {
cursor: pointer;
position: absolute;
top: 0;
width: 160px;
height: 160px;
background: #e9ecef;
border: 1px solid #ced4da;
&::before {
content: '';
position: absolute;
top: 54px;
left: 78px;
width: 2px;
height: 52px;
background: #495057;
}
&::after {
content: '';
position: absolute;
top: 78px;
left: 54px;
width: 52px;
height: 2px;
background: #495057;
}
}
&-left {
position: relative;
width: 160px;
height: 160px;
&.has-img {
.attachment-item-upload {
display: none;
}
&:hover {
.attachment-item-upload {
display: block;
background: rgba(145, 145, 145, 0.8);
}
}
}
}
&-right {
padding-top: 100px;
display: flex;
flex-direction: column;
justify-content: space-between;
color: #777777;
font-size: 0.8rem;
}
&-title {
color: #23272B;
font-size: 1rem;
}
}

View File

@ -1,5 +1,4 @@
class AccountsController < ApplicationController
include ApplicationHelper
#skip_before_action :check_account, :only => [:logout]
@ -10,7 +9,7 @@ class AccountsController < ApplicationController
# 其他平台同步注册的用户
def remote_register
username = params[:username]&.gsub(/\s+/, "")
tip_exception("无法使用以下关键词:#{username},请重新命名") if ReversedKeyword.check_exists?(username)
tip_exception("无法使用以下关键词:#{username},请重新命名") if ReversedKeyword.is_reversed(username).present?
email = params[:email]&.gsub(/\s+/, "")
password = params[:password]
platform = (params[:platform] || 'forge')&.gsub(/\s+/, "")
@ -110,46 +109,60 @@ class AccountsController < ApplicationController
# 用户注册
# 注意:用户注册需要兼顾本地版,本地版是不需要验证码及激活码以及使用授权的,注册完成即可使用
# params[:login] 邮箱或者手机号
# params[:namespace] 登录名
# params[:code] 验证码
# code_type 1注册手机验证码 8邮箱注册验证码
# 本地forge注册入口需要重新更改逻辑
# 本地forge注册入口
def register
# type只可能是1或者8
user = nil
begin
Register::Form.new(register_params).validate!
# 查询验证码是否正确;type只可能是1或者8
type = phone_mail_type(params[:login].strip)
# code = params[:code].strip
user = Users::RegisterService.call(register_params)
password = register_params[:password].strip
if type == 1
uid_logger("start register by phone: type is #{type}")
pre = 'p'
email = nil
phone = params[:login]
# verifi_code = VerificationCode.where(phone: phone, code: code, code_type: 1).last
# TODO: 暂时限定邮箱注册
return normal_status(-1, '只支持邮箱注册')
else
uid_logger("start register by email: type is #{type}")
pre = 'm'
email = params[:login]
phone = nil
return normal_status(-1, "该邮箱已注册") if User.exists?(mail: params[:login])
return normal_status(-1, "邮箱格式错误") unless params[:login] =~ CustomRegexp::EMAIL
# verifi_code = VerificationCode.where(email: email, code: code, code_type: 8).last
end
# uid_logger("start register: verifi_code is #{verifi_code}, code is #{code}, time is #{Time.now.to_i - verifi_code.try(:created_at).to_i}")
# check_code = (verifi_code.try(:code) == code.strip && (Time.now.to_i - verifi_code.created_at.to_i) <= 10*60)
# todo 上线前请删除万能验证码"513231"
return normal_status(-1, "8~16位密码支持字母数字和符号") unless params[:password] =~ CustomRegexp::PASSWORD
# gitea用户注册, email, username, password
interactor = Gitea::RegisterInteractor.call({username: user.login, email: user.mail, password: password})
code = generate_identifier User, 8, pre
login = pre + code
@user = User.new(admin: false, login: login, mail: email, phone: phone, type: "User")
@user.password = params[:password]
# 现在因为是验证码,所以在注册的时候就可以激活
@user.activate
# 必须要用save操作密码的保存是在users中
interactor = Gitea::RegisterInteractor.call({username: login, email: email, password: params[:password]})
if interactor.success?
gitea_user = interactor.result
result = Gitea::User::GenerateTokenService.call(user.login, password)
user.gitea_token = result['sha1']
user.gitea_uid = gitea_user[:body]['id']
if user.save!
UserExtension.create!(user_id: user.id)
successful_authentication(user)
render_ok
result = Gitea::User::GenerateTokenService.new(login, params[:password]).call
@user.gitea_token = result['sha1']
@user.gitea_uid = gitea_user[:body]['id']
if @user.save!
UserExtension.create!(user_id: @user.id)
successful_authentication(@user)
normal_status("注册成功")
end
else
tip_exception(-1, interactor.error)
end
rescue Register::BaseForm::EmailError => e
render_error(-2, e.message)
rescue Register::BaseForm::LoginError => e
render_error(-3, e.message)
rescue Register::BaseForm::PhoneError => e
render_error(-4, e.message)
rescue Register::BaseForm::PasswordFormatError => e
render_error(-5, e.message)
rescue Register::BaseForm::VerifiCodeError => e
render_error(-6, e.message)
rescue Exception => e
Gitea::User::DeleteService.call(user.login) unless user.nil?
uid_logger_error(e.message)
tip_exception(-1, e.message)
end
@ -284,7 +297,7 @@ class AccountsController < ApplicationController
# 发送验证码
# params[:login] 手机号或者邮箱号
# params[:type]为事件通知类型 1用户注册 2忘记密码 3: 绑定手机 4: 绑定邮箱, 5: 验收手机号有效 # 如果有新的继续后面加
# params[:type]为事件通知类型 1用户注册注册 2忘记密码 3: 绑定手机 4: 绑定邮箱, 5: 验收手机号有效 # 如果有新的继续后面加
# 发送验证码send_type 1注册手机验证码 2找回密码手机验证码 3找回密码邮箱验证码 4绑定手机 5绑定邮箱
# 6手机验证码登录 7邮箱验证码登录 8邮箱注册验证码 9: 验收手机号有效
def get_verification_code
@ -298,22 +311,19 @@ class AccountsController < ApplicationController
sign = Digest::MD5.hexdigest("#{OPENKEY}#{value}")
tip_exception(501, "请求不合理") if sign != params[:smscode]
logger.info "########### 验证码:#{verification_code}"
logger.info("########get_verification_code: login_type #{login_type} send_type#{send_type}, ")
# 记录验证码
check_verification_code(verification_code, send_type, value)
render_ok
sucess_status
end
# check user's login or email or phone is used
# params[:value] 手机号或者邮箱号或者登录名
# params[:type] 为事件类型 1登录名(login) 2email(邮箱) 3phone(手机号)
def check
Register::CheckColumnsForm.new(check_params).validate!
render_ok
# 1 手机类型0 邮箱类型
# 注意新版的login是自动名生成的
def phone_mail_type value
value =~ /^1\d{10}$/ ? 1 : 0
end
private
# type 事件类型 1用户注册 2忘记密码 3: 绑定手机 4: 绑定邮箱, 5: 验证手机号是否有效 # 如果有新的继续后面加
@ -359,13 +369,4 @@ class AccountsController < ApplicationController
def account_params
params.require(:account).permit(:login, :password)
end
def check_params
params.permit(:type, :value)
end
def register_params
params.permit(:login, :namespace, :password, :code)
end
end

View File

@ -22,7 +22,7 @@ class Admins::ProjectCategoriesController < Admins::BaseController
max_position_items = ProjectCategory.select(:id, :position).pluck(:position).reject!(&:blank?)
max_position = max_position_items.present? ? max_position_items.max.to_i : 0
@project_category = ProjectCategory.new(name: @name,position: max_position, pinned_index: params[:project_category][:pinned_index].to_i)
@project_category = ProjectCategory.new(name: @name,position: max_position)
if @project_category.save
redirect_to admins_project_categories_path
flash[:success] = '创建成功'
@ -33,18 +33,17 @@ class Admins::ProjectCategoriesController < Admins::BaseController
end
def update
if @project_category.update_attributes({name: @name, pinned_index: params[:project_category][:pinned_index].to_i})
save_image_file(params[:logo], 'logo')
if @project_category.update_attribute(:name, @name)
redirect_to admins_project_categories_path
flash[:success] = '更新成功'
else
redirect_to admins_project_categories_path
flash[:danger] = '更新失败'
flash[:success] = '更新失败'
end
end
def destroy
if @project_category.destroy
if @project_language.destroy
redirect_to admins_project_categories_path
flash[:success] = "删除成功"
else
@ -81,12 +80,4 @@ class Admins::ProjectCategoriesController < Admins::BaseController
flash[:danger] = '分类已存在'
end
end
def save_image_file(file, type)
return unless file.present? && file.is_a?(ActionDispatch::Http::UploadedFile)
file_path = Util::FileManage.source_disk_filename(@project_category, type)
File.delete(file_path) if File.exist?(file_path) # 删除之前的文件
Util.write_file(file, file_path)
end
end

View File

@ -1,5 +1,4 @@
class Admins::ProjectsController < Admins::BaseController
before_action :find_project, only: [:edit, :update]
def index
sort_by = Project.column_names.include?(params[:sort_by]) ? params[:sort_by] : 'created_on'
@ -9,26 +8,6 @@ class Admins::ProjectsController < Admins::BaseController
@projects = paginate projects.includes(:owner, :members, :issues, :versions, :attachments, :project_score)
end
def edit ;end
def update
respond_to do |format|
if @project.update_attributes(project_update_params)
format.html do
redirect_to admins_projects_path
flash[:sucess] = "更新成功"
end
format.js {render_ok}
else
format.html do
redirect_to admins_projects_path
flash[:danger] = "更新失败"
end
format.js {render_js_error}
end
end
end
def destroy
project = Project.find_by!(id: params[:id])
ActiveRecord::Base.transaction do
@ -42,13 +21,4 @@ class Admins::ProjectsController < Admins::BaseController
redirect_to admins_projects_path
flash[:danger] = "删除失败"
end
private
def find_project
@project = Project.find_by_id(params[:id])
end
def project_update_params
params.require(:project).permit(:is_pinned, :recommend, :recommend_index)
end
end

View File

@ -10,10 +10,6 @@ class Admins::SystemNotificationsController < Admins::BaseController
@notifications = paginate(notifications)
end
def history
@users = @notification.users
end
def new
@notification = SystemNotification.new
end

View File

@ -1,6 +1,4 @@
class Admins::UsersController < Admins::BaseController
before_action :finder_user, except: [:index]
def index
params[:sort_by] = params[:sort_by].presence || 'created_on'
params[:sort_direction] = params[:sort_direction].presence || 'desc'
@ -10,9 +8,12 @@ class Admins::UsersController < Admins::BaseController
end
def edit
@user = User.find(params[:id])
end
def update
@user = User.find(params[:id])
Admins::UpdateUserService.call(@user, update_params)
flash[:success] = '保存成功'
redirect_to edit_admins_user_path(@user)
@ -25,47 +26,43 @@ class Admins::UsersController < Admins::BaseController
end
def destroy
@user.destroy!
Gitea::User::DeleteService.call(@user.login)
User.find(params[:id]).destroy!
render_delete_success
end
def lock
@user.lock!
User.find(params[:id]).lock!
render_ok
end
def unlock
@user.activate!
User.find(params[:id]).activate!
render_ok
end
def reward_grade
user = User.find(params[:user_id])
return render_unprocessable_entity('金币数量必须大于0') if params[:grade].to_i <= 0
RewardGradeService.call(@user, container_id: @user.id, container_type: 'Feedback', score: params[:grade].to_i, not_unique: true)
RewardGradeService.call(user, container_id: user.id, container_type: 'Feedback', score: params[:grade].to_i, not_unique: true)
render_ok(grade: @user.grade)
render_ok(grade: user.grade)
end
def reset_login_times
@user.reset_login_times!
User.find(params[:id]).reset_login_times!
render_ok
end
private
def finder_user
@user = User.find(params[:id])
end
def update_params
params.require(:user).permit(%i[lastname nickname gender identity technical_title student_id is_shixun_marker
mail phone location location_city school_id department_id admin business is_test
password professional_certification authentication login])
password professional_certification authentication])
end
end

View File

@ -70,11 +70,49 @@ class ApplicationController < ActionController::Base
(current_user.professional_certification && (ue.teacher? || ue.professional?))
end
def shixun_marker
unless current_user.is_shixun_marker? || current_user.admin_or_business?
tip_exception(403, "..")
end
end
# 实训的访问权限
def shixun_access_allowed
if !current_user.shixun_permission(@shixun)
tip_exception(403, "..")
end
end
def admin_or_business?
User.current.admin? || User.current.business?
end
# 访问课堂时没权限直接弹加入课堂的弹框 409
def user_course_identity
@user_course_identity = current_user.course_identity(@course)
if @user_course_identity > Course::STUDENT && @course.is_public == 0
tip_exception(401, "..") unless User.current.logged?
check_account
tip_exception(@course.excellent ? 410 : 409, "您没有权限进入")
end
if @user_course_identity > Course::CREATOR && @user_course_identity <= Course::STUDENT && @course.tea_id != current_user.id
# 实名认证和职业认证的身份判断
tip_exception(411, "你的实名认证和职业认证审核未通过") if @course.authentication &&
@course.professional_certification && (!current_user.authentication && !current_user.professional_certification)
tip_exception(411, "你的实名认证审核未通过") if @course.authentication && !current_user.authentication
tip_exception(411, "你的职业认证审核未通过") if @course.professional_certification && !current_user.professional_certification
end
uid_logger("###############user_course_identity:#{@user_course_identity}")
end
# 题库的访问权限
def bank_visit_auth
tip_exception(-2,"未通过职业认证") if current_user.is_teacher? && !current_user.certification_teacher? && !current_user.admin_or_business? && @bank.user_id != current_user.id && @bank.is_public
tip_exception(403, "无权限") unless @bank.user_id == current_user.id || current_user.admin_or_business? ||
(current_user.certification_teacher? && @bank.is_public)
end
# 判断用户的邮箱或者手机是否可用
# params[:type] 1: 注册2忘记密码3绑定
def check_mail_and_phone_valid login, type
@ -82,16 +120,16 @@ class ApplicationController < ActionController::Base
login =~ /^[a-zA-Z0-9]+([._\\]*[a-zA-Z0-9])$/
tip_exception(-2, "请输入正确的手机号或邮箱")
end
user_exist = Owner.exists?(phone: login) || Owner.exists?(mail: login)
if user_exist && type.to_i == 1
# 考虑到安全参数问题多一次查询去掉Union
user = User.where(phone: login).first || User.where(mail: login).first
if type.to_i == 1 && !user.nil?
tip_exception(-2, "该手机号码或邮箱已被注册")
elsif type.to_i == 2 && !user_exist
elsif type.to_i == 2 && user.nil?
tip_exception(-2, "该手机号码或邮箱未注册")
elsif type.to_i == 3 && user_exist
elsif type.to_i == 3 && user.present?
tip_exception(-2, "该手机号码或邮箱已绑定")
end
render_ok
sucess_status
end
# 发送及记录激活码
@ -102,7 +140,7 @@ class ApplicationController < ActionController::Base
when 1, 2, 4, 9
# 手机类型的发送
sigle_para = {phone: value}
status = Gitlink::Sms.send(mobile: value, code: code)
status = Educoder::Sms.send(mobile: value, code: code)
tip_exception(-2, code_msg(status)) if status != 0
when 8, 3, 5
# 邮箱类型的发送
@ -148,6 +186,26 @@ class ApplicationController < ActionController::Base
end
end
def find_course
return normal_status(2, '缺少course_id参数') if params[:course_id].blank?
@course = Course.find(params[:course_id])
tip_exception(404, "") if @course.is_delete == 1 && !current_user.admin_or_business?
rescue Exception => e
tip_exception(e.message)
end
def course_manager
return normal_status(403, '只有课堂管理员才有权限') if @user_course_identity > Course::CREATOR
end
def find_board
return normal_status(2, "缺少board_id参数") if params[:board_id].blank?
@board = Board.find(params[:board_id])
rescue Exception => e
uid_logger_error(e.message)
tip_exception(e.message)
end
def validate_type(object_type)
normal_status(2, "参数") if params.has_key?(:sort_type) && !SORT_TYPE.include?(params[:sort_type].strip)
end
@ -157,6 +215,21 @@ class ApplicationController < ActionController::Base
@page_size = params[:page_size] || 15
end
# 课堂教师权限
def teacher_allowed
logger.info("#####identity: #{current_user.course_identity(@course)}")
unless current_user.course_identity(@course) < Course::STUDENT
normal_status(403, "")
end
end
# 课堂教师、课堂管理员、超级管理员的权限(不包含助教)
def teacher_or_admin_allowed
unless current_user.course_identity(@course) < Course::ASSISTANT_PROFESSOR
normal_status(403, "")
end
end
def require_admin
normal_status(403, "") unless User.current.admin?
end
@ -183,7 +256,7 @@ class ApplicationController < ActionController::Base
# 异常提醒
def tip_exception(status = -1, message)
raise Gitlink::TipException.new(status, message)
raise Educoder::TipException.new(status, message)
end
def missing_template
@ -192,7 +265,7 @@ class ApplicationController < ActionController::Base
# 弹框提醒
def tip_show_exception(status = -2, message)
raise Gitlink::TipException.new(status, message)
raise Educoder::TipException.new(status, message)
end
def normal_status(status = 0, message)
@ -264,7 +337,6 @@ class ApplicationController < ActionController::Base
User.current = user
end
end
# if !User.current.logged? && Rails.env.development?
# User.current = User.find 1
# end
@ -272,18 +344,18 @@ class ApplicationController < ActionController::Base
# 测试版前端需求
logger.info("subdomain:#{request.subdomain}")
# if request.subdomain != "www"
# if params[:debug] == 'teacher' #todo 为了测试,记得讲debug删除
# User.current = User.find 81403
# elsif params[:debug] == 'student'
# User.current = User.find 8686
# elsif params[:debug] == 'admin'
# logger.info "@@@@@@@@@@@@@@@@@@@@@@ debug mode....."
# user = User.find 36480
# User.current = user
# cookies.signed[:user_id] = user.id
# end
# end
if request.subdomain != "www"
if params[:debug] == 'teacher' #todo 为了测试,记得讲debug删除
User.current = User.find 81403
elsif params[:debug] == 'student'
User.current = User.find 8686
elsif params[:debug] == 'admin'
logger.info "@@@@@@@@@@@@@@@@@@@@@@ debug mode....."
user = User.find 36480
User.current = user
cookies.signed[:user_id] = user.id
end
end
# User.current = User.find 81403
end
@ -373,7 +445,7 @@ class ApplicationController < ActionController::Base
JSON.parse(res)
rescue Exception => e
uid_logger_error("--uri_exec: exception #{e.message}")
raise Gitlink::TipException.new("实训平台繁忙繁忙等级84")
raise Educoder::TipException.new("实训平台繁忙繁忙等级84")
end
end
@ -392,7 +464,7 @@ class ApplicationController < ActionController::Base
end
rescue Exception => e
uid_logger("--uri_exec: exception #{e.message}")
raise Gitlink::TipException.new(message)
raise Educoder::TipException.new(message)
end
end
@ -416,7 +488,7 @@ class ApplicationController < ActionController::Base
end
rescue Exception => e
uid_logger("--uri_exec: exception #{e.message}")
raise Gitlink::TipException.new("服务器繁忙")
raise Educoder::TipException.new("服务器繁忙")
end
end
@ -588,8 +660,8 @@ class ApplicationController < ActionController::Base
# 获取Oauth Client
def get_client(site)
client_id = Rails.configuration.Gitlink['client_id']
client_secret = Rails.configuration.Gitlink['client_secret']
client_id = Rails.configuration.educoder['client_id']
client_secret = Rails.configuration.educoder['client_secret']
OAuth2::Client.new(client_id, client_secret, site: site)
end
@ -782,8 +854,4 @@ class ApplicationController < ActionController::Base
HotSearchKeyword.add(keyword)
end
def find_atme_receivers
@atme_receivers = User.where(login: params[:receivers_login])
end
end

View File

@ -196,7 +196,7 @@ class AttachmentsController < ApplicationController
end
def file_save_to_ucloud(path, file, content_type)
ufile = Gitlink::Ufile.new(
ufile = Educoder::Ufile.new(
ucloud_public_key: edu_setting('public_key'),
ucloud_private_key: edu_setting('private_key'),
ucloud_public_read: true,

View File

@ -20,7 +20,7 @@ module ControllerRescueHandler
end
# rescue_from ActionView::MissingTemplate, with: :object_not_found
# rescue_from ActiveRecord::RecordNotFound, with: :object_not_found
rescue_from Gitlink::TipException, with: :tip_show
rescue_from Educoder::TipException, with: :tip_show
rescue_from ::ActionView::MissingTemplate, with: :missing_template
rescue_from ActiveRecord::RecordNotFound, with: :object_not_found
rescue_from ActionController::ParameterMissing, with: :render_parameter_missing

View File

@ -36,10 +36,10 @@ module GitCommon
begin
@commits = GitService.commits(repo_path: @repo_path)
logger.info("git first commit is #{@commits.try(:first)}")
raise Gitlink::TipException.new("请先创建版本库") if @commits.nil?
raise Educoder::TipException.new("请先创建版本库") if @commits.nil?
rescue Exception => e
uid_logger_error(e.message)
raise Gitlink::TipException.new("提交记录异常")
raise Educoder::TipException.new("提交记录异常")
end
end

View File

@ -34,7 +34,7 @@ module GitHelper
rescue Exception => e
Rails.logger.error(e.message)
raise Gitlink::TipException.new("文档内容获取异常")
raise Educoder::TipException.new("文档内容获取异常")
end
end
@ -64,7 +64,7 @@ module GitHelper
# 版本库Fork功能
def project_fork(container, original_rep_path, username)
raise Gitlink::TipException.new("fork源路径为空,fork失败!") if original_rep_path.blank?
raise Educoder::TipException.new("fork源路径为空,fork失败!") if original_rep_path.blank?
# 将要生成的仓库名字
new_repo_name = "#{username.try(:strip)}/#{container.try(:identifier)}#{ Time.now.strftime("%Y%m%d%H%M%S")}"
# uid_logger("start fork container: repo_name is #{new_repo_name}")

View File

@ -1,13 +1,17 @@
module RegisterHelper
extend ActiveSupport::Concern
def autologin_register(username, email, password, platform= 'forge')
def autologin_register(username, email, password, platform= 'forge', need_edit_info = false)
result = {message: nil, user: nil}
user = User.new(admin: false, login: username, mail: email, type: "User")
user.password = password
user.platform = platform
user.activate
if need_edit_info
user.need_edit_info
else
user.activate
end
return unless user.valid?
@ -27,4 +31,31 @@ module RegisterHelper
result
end
def autosync_register_trustie(username, password, email, lastname="")
config = Rails.application.config_for(:configuration).symbolize_keys!
api_host = config[:sync_url]
return if api_host.blank?
url = "#{api_host}/api/v1/users/common"
sync_json = {
"mail": email,
"password": password,
"login": username,
"lastname": lastname
}.compact
uri = URI.parse(url)
if api_host
http = Net::HTTP.new(uri.hostname, uri.port)
if api_host.include?("https://")
http.use_ssl = true
end
http.send_request('POST', uri.path, sync_json.to_json, {'Content-Type' => 'application/json'})
end
end
end

View File

@ -3,8 +3,8 @@ module RenderHelper
render json: { status: 0, message: 'success' }.merge(data)
end
def render_error(status = -1, message = '')
render json: { status: status, message: message }
def render_error(message = '')
render json: { status: -1, message: message }
end
def render_not_acceptable(message = '请求已拒绝')

View File

@ -9,7 +9,7 @@ class IssuesController < ApplicationController
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 :check_token_enough, :find_atme_receivers, only: [:create, :update]
before_action :check_token_enough, only: [:create, :update]
include ApplicationHelper
include TagChosenHelper
@ -142,10 +142,6 @@ class IssuesController < ApplicationController
end
@issue.project_trends.create(user_id: current_user.id, project_id: @project.id, action_type: "create")
Rails.logger.info "[ATME] maybe to at such users: #{@atme_receivers.pluck(:login)}"
AtmeService.call(current_user, @atme_receivers, @issue) if @atme_receivers.size > 0
render json: {status: 0, message: "创建成", id: @issue.id}
else
normal_status(-1, "创建失败")
@ -248,10 +244,6 @@ class IssuesController < ApplicationController
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) if @issue.previous_changes.present?
Rails.logger.info "[ATME] maybe to at such users: #{@atme_receivers.pluck(:login)}"
AtmeService.call(current_user, @atme_receivers, @issue) if @atme_receivers.size > 0
normal_status(0, "更新成功")
else
normal_status(-1, "更新失败")

View File

@ -1,6 +1,6 @@
class JournalsController < ApplicationController
before_action :require_login, except: [:index, :get_children_journals]
before_action :require_profile_completed, :find_atme_receivers, only: [:create]
before_action :require_login, except: [:index, :get_children_journals,:beihang]
before_action :require_profile_completed, only: [:create]
before_action :set_issue
before_action :check_issue_permission
before_action :set_journal, only: [:destroy, :edit, :update]
@ -13,8 +13,8 @@ class JournalsController < ApplicationController
parent_journals = total_journals.parent_journals.order("created_on desc")
@journals = parent_journals.order("created_on desc").page(@page).per(@limit)
@journals_size = parent_journals.size
end
def create
@ -22,39 +22,61 @@ class JournalsController < ApplicationController
if notes.blank?
normal_status(-1, "评论内容不能为空")
else
ActiveRecord::Base.transaction do
journal_params = {
journalized_id: @issue.id ,
journalized_type: "Issue",
user_id: current_user.id ,
notes: notes.to_s.strip,
parent_id: params[:parent_id]
}
journal = Journal.new journal_params
if journal.save
if params[:attachment_ids].present?
params[:attachment_ids].each do |id|
attachment = Attachment.select(:id, :container_id, :container_type)&.find_by_id(id)
unless attachment.blank?
attachment.container = journal
attachment.author_id = current_user.id
attachment.description = ""
attachment.save
end
journal_params = {
journalized_id: @issue.id ,
journalized_type: "Issue",
user_id: current_user.id ,
notes: notes.to_s.strip,
parent_id: params[:parent_id]
}
journal = Journal.new journal_params
if journal.save
if params[:attachment_ids].present?
params[:attachment_ids].each do |id|
attachment = Attachment.select(:id, :container_id, :container_type)&.find_by_id(id)
unless attachment.blank?
attachment.container = journal
attachment.author_id = current_user.id
attachment.description = ""
attachment.save
end
end
Rails.logger.info "[ATME] maybe to at such users: #{@atme_receivers.pluck(:login)}"
AtmeService.call(current_user, @atme_receivers, journal) if @atme_receivers.size > 0
# @issue.project_trends.create(user_id: current_user.id, project_id: @project.id, action_type: "journal")
render :json => { status: 0, message: "评论成功", id: journal.id}
# normal_status(0, "评论成功")
else
normal_status(-1, "评论失败")
end
# @issue.project_trends.create(user_id: current_user.id, project_id: @project.id, action_type: "journal")
render :json => { status: 0, message: "评论成功", id: journal.id}
# normal_status(0, "评论成功")
else
normal_status(-1, "评论失败")
end
end
end
def beihang
token = request.headers["HTTP_TOKEN"]
playod = JWT.decode(token,EducoderOauth.client_id)[0]
data = HashWithIndifferentAccess.new playod
notes = params[:content]
return normal_status(-1, "评论内容不能为空") if notes.blank?
return normal_status(-1, "验证失败") if data["user_id"].blank?
journal_params = {
journalized_id: @issue.id ,
journalized_type: "Issue",
user_id: data["user_id"] ,
notes: notes.to_s.strip,
parent_id: params[:parent_id]
}
journal = Journal.new journal_params
if journal.save
# @issue.project_trends.create(user_id: current_user.id, project_id: @project.id, action_type: "journal")
render :json => { status: 0, message: "评论成功", id: journal.id}
# normal_status(0, "评论成功")
else
normal_status(-1, "评论失败")
end
end
def destroy
if @journal.destroy #如果有子评论,子评论删除吗?
Journal.children_journals(@journal.id).destroy_all
@ -113,4 +135,4 @@ class JournalsController < ApplicationController
normal_status(-1, "评论不存在")
end
end
end
end

View File

@ -2,6 +2,7 @@ class Oauth::BaseController < ActionController::Base
include RenderHelper
include LoginHelper
include ControllerRescueHandler
include LoggerHelper
# include LaboratoryHelper
skip_before_action :verify_authenticity_token
@ -11,6 +12,18 @@ class Oauth::BaseController < ActionController::Base
end
private
def tip_exception(status = -1, message)
raise Educoder::TipException.new(status, message)
end
def tip_show_exception(status = -2, message)
raise Educoder::TipException.new(status, message)
end
def tip_show(exception)
uid_logger("Tip show status is #{exception.status}, message is #{exception.message}")
render json: exception.tip_json
end
def session_user_id
# session[:user_id]
@ -48,4 +61,13 @@ class Oauth::BaseController < ActionController::Base
Rails.logger.info("[wechat] set session unionid: #{unionid}")
session[:unionid] = unionid
end
def session_edulogin
session[:edulogin]
end
def set_session_edulogin(login)
Rails.logger.info("[educoder] set sesstion edulogin: #{login}")
session[:edulogin] = login
end
end

View File

@ -1,4 +1,6 @@
class Oauth::EducoderController < Oauth::BaseController
include RegisterHelper
def bind
begin
login = params[:login]
@ -32,4 +34,41 @@ class Oauth::EducoderController < Oauth::BaseController
render_error(ex.message)
end
end
# 需要educoder那边设置回调地址
def create
begin
code = params['code'].to_s.strip
tip_exception("code不能为空") if code.blank?
new_user = false
result = EducoderOauth::Service.access_token(code)
result = EducoderOauth::Service.user_info(result[:access_token])
# 存在该用户
open_user = OpenUsers::Educoder.find_by(uid: result['login'])
if open_user.present? && open_user.user.present?
successful_authentication(open_user.user)
else
if current_user.blank? || !current_user.logged?
new_user = true
login = User.generate_login('E')
reg_result = autologin_register(login,"#{login}@forge.com", "Ec#{login}2021#", 'educoder', true)
if reg_result[:message].blank?
open_user = OpenUsers::Educoder.create!(user_id: reg_result[:user][:id], uid: result['login'], extra: result)
autosync_register_trustie(login, "Ec#{login}2021#", "#{login}@forge.com")
successful_authentication(open_user.user)
else
render_error(reg_result[:message])
end
else
OpenUsers::Educoder.create!(user: current_user, uid: result['login'], extra: result)
end
end
redirect_to root_path(new_user: new_user)
rescue Exception => ex
render_error(ex.message)
end
end
end

View File

@ -0,0 +1,34 @@
class Oauth::MulanossController < Oauth::BaseController
include RegisterHelper
# 需要educoder那边设置回调地址
def create
# user, new_user = Oauth::CreateOrFindWechatAccountService.call(current_user ,params)
begin
code = params['code'].to_s.strip
tip_exception("code不能为空") if code.blank?
result = MulanossOauth::Service.access_token(code)
result = MulanossOauth::Service.user_info(result[:access_token])
# 存在该用户
open_user = OpenUsers::Mulan.find_by(uid: result['id'])
if open_user.present? && open_user.user.present?
successful_authentication(open_user.user)
else
if current_user.blank? || !current_user.logged?
login = User.generate_login('ML')
mail = result["email"].to_s.match(CustomRegexp::EMAIL).present? ? result["email"].to_s : "#{login}@mulan.com"
reg_result = autologin_register(login, mail , "M#{login}2021#", 'mulan', true)
open_user = OpenUsers::Mulan.create!(user_id: reg_result[:user][:id], uid: result['id'], extra: result)
successful_authentication(open_user.user)
else
OpenUsers::Mulan.create!(user: current_user, uid: result["id"])
end
end
redirect_to "/explore"
rescue Exception => ex
render_error(ex.message)
end
end
end

View File

@ -61,6 +61,7 @@ class OauthController < ApplicationController
login = params[:login]
email = params[:mail]
password = params[:password]
lastname = params[:lastname]
callback_url = params[:callback_url]
platform = params[:plathform] || 'educoder'
@ -72,8 +73,11 @@ class OauthController < ApplicationController
if result[:message].blank?
logger.info "[Oauth educoer] ====auto_register success"
user = User.find result[:user][:id]
successful_authentication(user)
user.update_column(:lastname, params[:lastname])
autosync_register_trustie(login, password, email, lastname)
OpenUsers::Educoder.create!(user: user, uid: user.login)
successful_authentication(user)
render json: { callback_url: callback_url }
# redirect_to callback_url
@ -84,4 +88,13 @@ class OauthController < ApplicationController
end
end
def token_login
@user = User.find_by_gitea_token(params[:token])
if @user.present?
successful_authentication(@user)
redirect_to root_url
else
render json: { error: "用户不存在" }
end
end
end

View File

@ -22,12 +22,11 @@ class Organizations::OrganizationsController < Organizations::BaseController
@can_create_project = @organization.can_create_project?(current_user.id)
@is_admin = can_edit_org?
@is_member = @organization.is_member?(current_user.id)
Cache::V2::OwnerCommonService.new(@organization.id).read
end
def create
ActiveRecord::Base.transaction do
tip_exception("无法使用以下关键词:#{organization_params[:name]},请重新命名") if ReversedKeyword.check_exists?(organization_params[:name])
tip_exception("无法使用以下关键词:#{organization_params[:name]},请重新命名") if ReversedKeyword.is_reversed(organization_params[:name]).present?
Organizations::CreateForm.new(organization_params).validate!
@organization = Organizations::CreateService.call(current_user, organization_params)
Util.write_file(@image, avatar_path(@organization)) if params[:image].present?
@ -69,7 +68,8 @@ class Organizations::OrganizationsController < Organizations::BaseController
def recommend
recommend = %W(xuos Huawei_Technology openatom_foundation pkecosystem TensorLayer)
@organizations = Organization.includes(:organization_extension).where(organization_extensions: {recommend: true}).to_a.each_slice(group_size).to_a
@organizations = Organization.with_visibility(%w(common))
.where(login: recommend).select(:id, :login, :firstname, :lastname, :nickname)
end
private
@ -80,10 +80,6 @@ class Organizations::OrganizationsController < Organizations::BaseController
:max_repo_creation, :nickname)
end
def group_size
params.fetch(:group_size, 4).to_i
end
def password
params.fetch(:password, "")
end

View File

@ -5,10 +5,6 @@ class ProjectCategoriesController < ApplicationController
@project_categories = q.result(distinct: true)
end
def pinned_index
@project_categories = ProjectCategory.where.not(pinned_index: 0).order(pinned_index: :desc)
end
def group_list
@project_categories = ProjectCategory.where('projects_count > 0').order(projects_count: :desc)
# projects = Project.no_anomory_projects.visible

View File

@ -1,26 +0,0 @@
class ProjectRankController < ApplicationController
# 根据时间获取热门项目
def index
$redis_cache.zunionstore("recent-days-project-rank", get_timeable_key_names)
deleted_data = $redis_cache.smembers("v2-project-rank-deleted")
$redis_cache.zrem("recent-days-project-rank", deleted_data) unless deleted_data.blank?
@project_rank = $redis_cache.zrevrange("recent-days-project-rank", 0, 4, withscores: true)
rescue Exception => e
@project_rank = []
end
private
# 默认显示7天的
def time
params.fetch(:time, 7).to_i
end
def get_timeable_key_names
names_array = []
(0...time).to_a.each do |i|
date_time_string = (Date.today - i.days).to_s
names_array << "v2-project-rank-#{date_time_string}"
end
names_array
end
end

View File

@ -1,6 +0,0 @@
class Projects::MembersController < Projects::BaseController
def index
users = @project.all_collaborators.like(params[:search]).includes(:user_extension)
@users = kaminari_paginate(users)
end
end

View File

@ -4,9 +4,9 @@ class ProjectsController < ApplicationController
include ProjectsHelper
include Acceleratorable
before_action :require_login, except: %i[index branches branches_slice group_type_list simple show fork_users praise_users watch_users recommend banner_recommend about menu_list]
before_action :require_login, except: %i[index branches branches_slice group_type_list simple show fork_users praise_users watch_users recommend about menu_list sonar_url]
before_action :require_profile_completed, only: [:create, :migrate]
before_action :load_repository, except: %i[index group_type_list migrate create recommend banner_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 :project_public?, only: %i[fork_users praise_users watch_users]
@ -31,7 +31,7 @@ class ProjectsController < ApplicationController
scope = current_user.logged? ? Projects::ListQuery.call(params, current_user.id) : Projects::ListQuery.call(params)
@projects = kaminari_paginate(scope.includes(:project_category, :project_language, :repository, :project_educoder, :owner, :project_units))
# @projects = paginate scope.includes(:project_category, :project_language, :repository, :project_educoder, :owner, :project_units)
#@projects = paginate scope.includes(:project_category, :project_language, :repository, :project_educoder, :owner, :project_units)
category_id = params[:category_id]
@total_count =
@ -58,14 +58,14 @@ class ProjectsController < ApplicationController
def migrate
Projects::MigrateForm.new(mirror_params).validate!
@project =
@project =
if enable_accelerator?(mirror_params[:clone_addr])
source_clone_url = mirror_params[:clone_addr]
uid_logger("########## 已动加速器 ##########")
result = Gitea::Accelerator::MigrateService.call(mirror_params)
if result[:status] == :success
Rails.logger.info "########## 加速镜像成功 ########## "
Projects::MigrateService.call(current_user,
Projects::MigrateService.call(current_user,
mirror_params.merge(source_clone_url: source_clone_url,
clone_addr: accelerator_url(mirror_params[:repository_name])))
else
@ -117,7 +117,7 @@ class ProjectsController < ApplicationController
ActiveRecord::Base.transaction do
# TODO:
# 临时特殊处理修改website、lesson_url操作方法
if project_params.has_key?("website")
if project_params.has_key?("website")
@project.update(project_params)
elsif project_params.has_key?("default_branch")
@project.update(project_params)
@ -126,11 +126,11 @@ class ProjectsController < ApplicationController
}
Gitea::Repository::UpdateService.call(@owner, @project.identifier, gitea_params)
else
validate_params = project_params.slice(:name, :description,
validate_params = project_params.slice(:name, :description,
:project_category_id, :project_language_id, :private, :identifier)
Projects::UpdateForm.new(validate_params.merge(user_id: @project.user_id, project_identifier: @project.identifier)).validate!
private = @project.forked_from_project.present? ? !@project.forked_from_project.is_public : params[:private] || false
new_project_params = project_params.except(:private).merge(is_public: !private)
@ -145,7 +145,7 @@ class ProjectsController < ApplicationController
gitea_repo = Gitea::Repository::UpdateService.call(@owner, @project&.repository&.identifier, gitea_params)
@project.repository.update_attributes({hidden: gitea_repo["private"], identifier: gitea_repo["name"]})
end
SendTemplateMessageJob.perform_later('ProjectSettingChanged', current_user.id, @project&.id, @project.previous_changes.slice(:name, :description, :project_category_id, :project_language_id, :is_public, :identifier)) if Site.has_notice_menu?
SendTemplateMessageJob.perform_later('ProjectSettingChanged', current_user.id, @project&.id, @project.previous_changes.slice(:name, :description, :project_category_id, :project_language_id, :is_public)) if Site.has_notice_menu?
end
rescue Exception => e
uid_logger_error(e.message)
@ -190,8 +190,6 @@ class ProjectsController < ApplicationController
end
def simple
# 为了缓存活跃项目的基本信息,后续删除
Cache::V2::ProjectCommonService.new(@project.id).read
json_response(@project, current_user)
end
@ -199,10 +197,6 @@ class ProjectsController < ApplicationController
@projects = Project.recommend.includes(:repository, :project_category, :owner).order(visits: :desc)
end
def banner_recommend
@projects = Project.recommend.where.not(recommend_index: 0).includes(:project_category, :owner, :project_language).order(recommend_index: :desc)
end
def about
@project_detail = @project.project_detail
@attachments = Array(@project_detail&.attachments) if request.get?
@ -231,6 +225,14 @@ class ProjectsController < ApplicationController
end
end
def sonar_url
token = request.headers["HTTP_SONAR_TOKEN"]
playod = JWT.decode(token,EducoderOauth.client_id)[0]
data = HashWithIndifferentAccess.new playod
return normal_status(-1, "sonar_url不能为空") if data["sonar_url"].blank?
@project.update(sonar_url:data["sonar_url"])
render :json => { status: 0, message: "更新成功"}
end
private
def project_params

View File

@ -5,7 +5,6 @@ class PullRequestsController < ApplicationController
before_action :check_menu_authorize
before_action :find_pull_request, except: [:index, :new, :create, :check_can_merge,:get_branches,:create_merge_infos, :files, :commits]
before_action :load_pull_request, only: [:files, :commits]
before_action :find_atme_receivers, only: [:create, :update]
include TagChosenHelper
include ApplicationHelper
@ -62,8 +61,6 @@ class PullRequestsController < ApplicationController
@pull_request.bind_gitea_pull_request!(@gitea_pull_request[:body]["number"], @gitea_pull_request[:body]["id"])
SendTemplateMessageJob.perform_later('PullRequestAssigned', current_user.id, @pull_request&.id) if Site.has_notice_menu?
SendTemplateMessageJob.perform_later('ProjectPullRequest', current_user.id, @pull_request&.id) if Site.has_notice_menu?
Rails.logger.info "[ATME] maybe to at such users: #{@atme_receivers.pluck(:login)}"
AtmeService.call(current_user, @atme_receivers, @pull_request) if @atme_receivers.size > 0
else
render_error("create pull request error: #{@gitea_pull_request[:status]}")
raise ActiveRecord::Rollback
@ -109,8 +106,6 @@ class PullRequestsController < ApplicationController
if params[:status_id].to_i == 5
@issue.issue_times.update_all(end_time: Time.now)
end
Rails.logger.info "[ATME] maybe to at such users: #{@atme_receivers.pluck(:login)}"
AtmeService.call(current_user, @atme_receivers, @pull_request) if @atme_receivers.size > 0
normal_status(0, "PullRequest更新成功")
else
normal_status(-1, "PullRequest更新失败")

View File

@ -48,7 +48,7 @@ class RepositoriesController < ApplicationController
def entries
@project.increment!(:visits)
CacheAsyncSetJob.perform_later("project_common_service", {visits: 1}, @project.id)
if @project.educoder?
@entries = Educoder::Repository::Entries::ListService.call(@project&.project_educoder.repo_name)
else
@ -347,7 +347,7 @@ class RepositoriesController < ApplicationController
local_requests = PullRequest.new(local_params.merge(user_id: current_user.try(:id), project_id: @project.id, issue_id: @pull_issue.id))
if local_requests.save
gitea_request = Gitea::PullRequest::CreateService.new(current_user.try(:gitea_token), @owner.login, @project.try(:identifier), requests_params).call
if gitea_request[:status] == :success && local_requests.update_attributes(gpid: gitea_request["body"]["number"])
if gitea_request[:status] == :success && local_requests.update_attributes(gitea_number: gitea_request["body"]["number"])
local_requests.project_trends.create(user_id: current_user.id, project_id: @project.id, action_type: "create")
end
end

View File

@ -4,6 +4,7 @@ class SettingsController < ApplicationController
get_add_menu
get_common_menu
get_personal_menu
get_third_party
get_top_system_notification
end
@ -40,6 +41,14 @@ class SettingsController < ApplicationController
end
end
def get_third_party
@third_party = []
@third_party << {
name: 'mulan',
url: MulanossOauth.oauth_url
}
end
def get_top_system_notification
@top_system_notification = SystemNotification.is_top.first
end

View File

@ -1,8 +0,0 @@
class TemplateMessageSettingsController < ApplicationController
before_action :require_login
def index
@group_settings = TemplateMessageSetting.group(:type).count
end
end

View File

@ -1,24 +0,0 @@
class UserRankController < ApplicationController
# 根据时间获取热门开发者
def index
$redis_cache.zunionstore("recent-days-user-rank", get_timeable_key_names)
@user_rank = $redis_cache.zrevrange("recent-days-user-rank", 0, 3, withscores: true)
rescue Exception => e
@user_rank = []
end
private
# 默认显示7天的
def time
params.fetch(:time, 7).to_i
end
def get_timeable_key_names
names_array = []
(0...time).to_a.each do |i|
date_time_string = (Date.today - i.days).to_s
names_array << "v2-user-rank-#{date_time_string}"
end
names_array
end
end

View File

@ -188,32 +188,30 @@ class Users::StatisticsController < Users::BaseController
@project_languages_count = time_filter(Project.where(user_id: observed_user.id), 'created_on').joins(:project_language).group("project_languages.name").count
@platform_project_languages_count = time_filter(Project, 'created_on').joins(:project_language).group("project_languages.name").count
else
@platform_result = Cache::V2::PlatformStatisticService.new.read
@user_result = Cache::V2::UserStatisticService.new(observed_user.id).read
# 用户被follow数量
@follow_count = @user_result["follow-count"].to_i
@platform_follow_count = @platform_result["follow-count"].to_i
@follow_count = Cache::UserFollowCountService.call(observed_user)
@platform_follow_count = Cache::PlatformFollowCountService.call
# 用户pr数量
@pullrequest_count = @user_result["pullrequest-count"].to_i
@platform_pullrequest_count = @platform_result["pullrequest-count"].to_i
@pullrequest_count = Cache::UserPullrequestCountService.call(observed_user)
@platform_pullrequest_count = Cache::PlatformPullrequestCountService.call
# 用户issue数量
@issues_count = @user_result["issue-count"].to_i
@platform_issues_count = @platform_result["issue-count"].to_i
@issues_count = Cache::UserIssueCountService.call(observed_user)
@platform_issues_count = Cache::PlatformIssueCountService.call
# 用户总项目数
@project_count = @user_result["project-count"].to_i
@platform_project_count = @platform_result["project-count"].to_i
@project_count = Cache::UserProjectCountService.call(observed_user)
@platform_project_count = Cache::PlatformProjectCountService.call
# 用户项目被fork数量
@fork_count = @user_result["fork-count"].to_i
@platform_fork_count = @platform_result["fork-count"].to_i
@fork_count = Cache::UserProjectForkCountService.call(observed_user)
@platform_fork_count = Cache::PlatformProjectForkCountService.call
# 用户项目关注数
@project_watchers_count = @user_result["project-watcher-count"].to_i
@platform_project_watchers_count = @platform_result["project-watcher-count"].to_i
@project_watchers_count = Cache::UserProjectWatchersCountService.call(observed_user)
@platform_project_watchers_count = Cache::PlatformProjectWatchersCountService.call
# 用户项目点赞数
@project_praises_count = @user_result["project-praise-count"].to_i
@platform_project_praises_count = @platform_result["project-praise-count"].to_i
@project_praises_count = Cache::UserProjectPraisesCountService.call(observed_user)
@platform_project_praises_count = Cache::PlatformProjectPraisesCountService.call
# 用户不同语言项目数量
@project_languages_count = JSON.parse(@user_result["project-language"])
@platform_project_languages_count = JSON.parse(@platform_result["project-language"])
@project_languages_count = Cache::UserProjectLanguagesCountService.call(observed_user)
@platform_project_languages_count = Cache::PlatformProjectLanguagesCountService.call
end
end
end

View File

@ -1,15 +0,0 @@
class Users::SystemNotificationHistoriesController < Users::BaseController
before_action :private_user_resources!, only: [:create]
def create
@history = observed_user.system_notification_histories.new(system_notification_id: params[:system_notification_id])
if @history.save
render_ok
else
Rails.logger.info @history.errors.as_json
render_error(@history.errors.full_messages.join(","))
end
rescue Exception => e
uid_logger_error(e.message)
tip_exception(e.message)
end
end

View File

@ -1,36 +0,0 @@
class Users::TemplateMessageSettingsController < Users::BaseController
before_action :check_auth
before_action :get_current_setting
def current_setting
end
def update_setting
Rails.logger.info setting_params[:notification_body]
Rails.logger.info setting_params[:email_body]
@current_setting.notification_body = setting_params[:notification_body].to_hash
@current_setting.email_body = setting_params[:email_body].to_hash
return render_error("保存失败") unless @current_setting.save!
end
private
def check_auth
return render_forbidden unless current_user.admin? || observed_logged_user?
end
def get_current_setting
@current_setting = @_observed_user.user_template_message_setting
@current_setting = UserTemplateMessageSetting.build(@_observed_user.id) if @current_setting.nil?
end
def setting_params
params.require(:setting).permit(notification_body: {}, email_body: {})
end
def valid_setting_params
setting_params[:notification_body].keys.equal?(UserTemplateMessageSetting.init_notification_body.keys) && setting_params[:email_body].keys.equal?(UserTemplateMessageSetting.init_email_body)
end
end

View File

@ -51,8 +51,6 @@ class UsersController < ApplicationController
@projects_common_count = user_projects.common.size
@projects_mirrior_count = user_projects.mirror.size
@projects_sync_mirrior_count = user_projects.sync_mirror.size
# 为了缓存活跃用户的基本信息,后续删除
Cache::V2::OwnerCommonService.new(@user.id).read
end
def watch_users
@ -193,7 +191,7 @@ class UsersController < ApplicationController
def trustie_related_projects
projects = Project.includes(:owner, :members, :project_score).where(id: params[:ids]).order("updated_on desc")
projects_json = []
domain_url = EduSetting.get('host_name')
domain_url = EduSetting.get('host_name') + '/projects'
if projects.present?
projects.each do |p|
project_url = "/#{p.owner.login}/#{p.identifier}"
@ -275,7 +273,7 @@ class UsersController < ApplicationController
interactor = Gitea::User::UpdateInteractor.call(user.login, sync_params)
if interactor.success?
user.update!(password: params[:password], mail: params[:email], status: User::STATUS_EDIT_INFO)
user.update!(password: params[:password], mail: params[:email], status: User::STATUS_ACTIVE)
render_ok
else
render_error(interactor.error)

View File

@ -14,6 +14,7 @@ class WatchersController < ApplicationController
return normal_status(2, "你还没有关注哦") unless current_user.watched?(@target)
current_user.unwatch!(@target)
render_ok({watchers_count: @target.watchers_count, watched: false})
Users::SynchronizationService.new(current_user, @target, false).call if params[:target_type].to_s == "project"
rescue Exception => e
uid_logger_error(e.message)
tip_exception(e.message)
@ -26,6 +27,7 @@ class WatchersController < ApplicationController
return normal_status(2, "你已关注了") if current_user.watched?(@target)
current_user.watch!(@target)
render_ok({watchers_count: @target.watchers_count, watched: true})
Users::SynchronizationService.new(current_user, @target, true).call if params[:target_type].to_s == "project"
rescue Exception => e
uid_logger_error(e.message)
tip_exception(e.message)

View File

@ -0,0 +1,5 @@
module CourseDecorator
def can_visited?
is_public == 1 || User.current.admin_or_business? || User.current.member_of_course?(self)
end
end

View File

@ -0,0 +1,2 @@
module EcCourseTargetDecorator
end

View File

@ -0,0 +1,16 @@
module ExperienceDecorator
def container_type_text
I18n.t("experience.container_type.#{container_type.to_s.underscore}")
end
def content
case container_type.to_s.underscore
when 'game' then
game = Game.find_by(id: container_id)
game.present? ? "通过实训“#{game.challenge.shixun.name}”的第#{game.challenge.position}关获得的奖励" : ''
when 'shixun_publish' then
shixun = Shixun.find_by(id: container_id)
shixun.present? ? "发布实训“#{shixun.name}”获得的奖励" : ''
end
end
end

View File

@ -0,0 +1,39 @@
module GradeDecorator
def container_type_text
I18n.t("grade.container_type.#{container_type.to_s.underscore}")
end
def content
case container_type.to_s.underscore
when 'avatar' then '用户首次上传头像获得的奖励'
when 'phone' then '用户首次绑定手机号码获得的奖励'
when 'mail' then '用户首次绑定邮箱获得的奖励'
when 'attendance' then '用户每天签到获得的奖励'
when 'account' then '新用户首次填写基本资料获得的奖励'
when 'memo' then '发布的评论或者帖子获得平台奖励'
when 'discusses' then '发布的评论获得平台奖励'
when 'star' then '用户给实训评分获得的随机奖励'
when 'feedback' then '反馈的问题获得平台奖励'
when 'authentication' then '用户首次完成实名认证获得的奖励'
when 'professional' then '用户首次完成职业认证获得的奖励'
when 'answer' then
game = Game.find_by(id: container_id)
game.present? ? "查看实训“#{game.challenge.shixun.name}”第#{game.challenge.position}关的参考答案消耗的金币" : ''
when 'game' then
game = Game.find_by(id: container_id)
game.present? ? "通过实训“#{game.challenge.shixun.name}”的第#{game.challenge.position}关获得的奖励" : ''
when 'test_set' then
game = Game.find_by(id: container_id)
game.present? ? "查看实训“#{game.challenge.shixun.name}”的第#{game.challenge.position}关的隐藏测试集消耗的金币" : ''
when 'shixun_publish' then
shixun = Shixun.find_by(id: container_id)
shixun.present? ? "发布实训“#{shixun.name}”获得的奖励" : ''
when 'check_ta_answer' then
game = Game.find_by(id: container_id)
game.present? ? "查看实训“#{game.challenge.shixun.name}”第#{game.challenge.position}关的TA人解答消耗的金币" : ''
when 'hack' then
hack = Hack.find_by(id: container_id)
hack.present? ? "完成了题目解答“#{hack.name}”,获得金币奖励:#{hack.score}" : ''
end
end
end

View File

@ -0,0 +1,5 @@
module LibraryDecorator
extend ApplicationDecorator
display_time_method :published_at, :created_at, :updated_at
end

View File

@ -0,0 +1,5 @@
module ShixunDecorator
def human_status
I18n.t("shixun.status.#{status}")
end
end

View File

@ -0,0 +1,5 @@
module SubjectDecorator
def can_visited?
published? || User.current.admin? || member?(User.current)
end
end

View File

@ -0,0 +1,5 @@
module VideoDecorator
extend ApplicationDecorator
display_time_method :published_at, :created_at, :updated_at
end

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@ -199,36 +199,6 @@ await octokit.request('GET /api/users/:login/messages.json')
Success Data.
</aside>
## 用户阅读系统通知
用户阅读系统通知
> 示例:
```shell
curl -X POST http://localhost:3000/api/users/yystopf/system_notification_histories.json
```
```javascript
await octokit.request('GET /api/users/:login/system_notification_histories.json')
```
### HTTP 请求
`POST /api/users/:login/system_notification_histories.json`
### 请求字段说明:
参数 | 类型 | 字段说明
--------- | ----------- | -----------
|system_notification_id |integer |阅读的系统通知id |
> 返回的JSON示例:
```json
{
"status": 0,
"message": "success"
}
```
## 发送消息
发送消息, 目前只支持atme
@ -402,290 +372,6 @@ await octokit.request('PATCH/PUT /api/users/:login.json')
"message": "success"
}
```
## 获取平台消息设置配置信息
获取平台消息设置配置信息
> 示例:
```shell
curl -X GET http://localhost:3000/api/template_message_settings.json
```
```javascript
await octokit.request('GET /api/template_message_settings.json')
```
### HTTP 请求
`GET /api/template_message_settings.json`
### 返回字段说明:
参数 | 类型 | 字段说明
--------- | ----------- | -----------
|type |string |消息配置类型 |
|type_name |string |消息配置类型含义|
|total_settings_count |int |配置条数|
|settings.name |string |配置名称|
|settings.key |string |配置标识|
|settings.notification_disabled |boolean |站内信设置是否禁用|
|settings.email_disabled |boolean |邮件设置是否禁用|
> 返回的JSON示例:
```json
{
"status": 0,
"message": "响应成功",
"setting_types": [
{
"type": "TemplateMessageSetting::Normal",
"type_name": "",
"total_settings_count": 3,
"settings": [
{
"name": "被拉入或移出组织",
"key": "Organization",
"notification_disabled": true,
"email_disabled": false
},
{
"name": "被拉入或移出项目",
"key": "Project",
"notification_disabled": true,
"email_disabled": false
},
{
"name": "有权限变更",
"key": "Permission",
"notification_disabled": true,
"email_disabled": false
}
]
},
{
"type": "TemplateMessageSetting::CreateOrAssign",
"type_name": "我创建的或负责的",
"total_settings_count": 4,
"settings": [
{
"name": "易修被指派",
"key": "IssueAssigned",
"notification_disabled": true,
"email_disabled": false
},
{
"name": "合并请求被指派",
"key": "PullRequestAssigned",
"notification_disabled": true,
"email_disabled": false
}
]
},
{
"type": "TemplateMessageSetting::ManageProject",
"type_name": "我管理的仓库",
"total_settings_count": 4,
"settings": [
{
"name": "有新的易修",
"key": "Issue",
"notification_disabled": true,
"email_disabled": false
},
{
"name": "有新的合并请求",
"key": "PullRequest",
"notification_disabled": true,
"email_disabled": false
},
{
"name": "有成员变动",
"key": "Member",
"notification_disabled": true,
"email_disabled": false
},
{
"name": "设置更改",
"key": "SettingChanged",
"notification_disabled": true,
"email_disabled": false
}
]
}
]
}
```
<aside class="success">
Success Data.
</aside>
## 获取用户消息设置配置信息
获取用户消息设置配置信息
> 示例:
```shell
curl -X GET http://localhost:3000/api/users/yystopf/template_message_settings.json
```
```javascript
await octokit.request('GET /api/uses/yystopf/template_message_settings.json')
```
### HTTP 请求
`GET /api/users/:user_id/template_message_settings.json`
### 返回字段说明:
参数 | 类型 | 字段说明
--------- | ----------- | -----------
|notification_body |string |站内信配置 |
|email_body |string |邮件配置|
> 返回的JSON示例:
```json
{
"status": 0,
"message": "响应成功",
"user": {
"id": 2,
"type": "User",
"name": "heh",
"login": "yystopf",
"image_url": "system/lets/letter_avatars/2/H/188_239_142/120.png"
},
"notification_body": {
"CreateOrAssign::IssueAssigned": true,
"CreateOrAssign::PullRequestAssigned": true,
"ManageProject::Issue": true,
"ManageProject::PullRequest": true,
"ManageProject::Member": true,
"ManageProject::SettingChanged": true,
"Normal::Organization": true,
"Normal::Project": true,
"Normal::Permission": true
},
"email_body": {
"CreateOrAssign::IssueAssigned": false,
"CreateOrAssign::PullRequestAssigned": false,
"ManageProject::Issue": false,
"ManageProject::PullRequest": false,
"ManageProject::Member": false,
"ManageProject::SettingChanged": true,
"Normal::Organization": false,
"Normal::Project": true,
"Normal::Permission": false
}
}
```
<aside class="success">
Success Data.
</aside>
## 重新设置用户消息设置配置信息
重新设置用户消息设置配置信息
> 示例:
```shell
curl -X POST http://localhost:3000/api/users/yystopf/template_message_settings/update_setting.json
```
```javascript
await octokit.request('POST /api/uses/yystopf/template_message_settings/update_setting.json')
```
### HTTP 请求
`POST /api/users/:user_id/template_message_settings/update_setting.json`
### 请求字段说明:
参数 | 类型 | 字段说明
--------- | ----------- | -----------
|notification_body |string |站内信配置 |
|email_body |string |邮件配置|
> 请求的JSON示例:
```json
{
"setting": {
"notification_body": {
"CreateOrAssign::IssueAssigned": true,
"CreateOrAssign::PullRequestAssigned": true,
"ManageProject::Issue": true,
"ManageProject::PullRequest": true,
"ManageProject::Member": true,
"ManageProject::SettingChanged": true,
"Normal::Organization": true,
"Normal::Project": true,
"Normal::Permission": true
},
"email_body": {
"CreateOrAssign::IssueAssigned": false,
"CreateOrAssign::PullRequestAssigned": false,
"ManageProject::Issue": false,
"ManageProject::PullRequest": false,
"ManageProject::Member": false,
"ManageProject::SettingChanged": true,
"Normal::Organization": false,
"Normal::Project": "t",
"Normal::Permission": false
}
}
}
```
### 返回字段说明:
参数 | 类型 | 字段说明
--------- | ----------- | -----------
|notification_body |string |站内信配置 |
|email_body |string |邮件配置|
> 返回的JSON示例:
```json
{
"status": 0,
"message": "响应成功",
"user": {
"id": 2,
"type": "User",
"name": "heh",
"login": "yystopf",
"image_url": "system/lets/letter_avatars/2/H/188_239_142/120.png"
},
"notification_body": {
"CreateOrAssign::IssueAssigned": true,
"CreateOrAssign::PullRequestAssigned": true,
"ManageProject::Issue": true,
"ManageProject::PullRequest": true,
"ManageProject::Member": true,
"ManageProject::SettingChanged": true,
"Normal::Organization": true,
"Normal::Project": true,
"Normal::Permission": true
},
"email_body": {
"CreateOrAssign::IssueAssigned": false,
"CreateOrAssign::PullRequestAssigned": false,
"ManageProject::Issue": false,
"ManageProject::PullRequest": false,
"ManageProject::Member": false,
"ManageProject::SettingChanged": true,
"Normal::Organization": false,
"Normal::Project": true,
"Normal::Permission": false
}
}
```
<aside class="success">
Success Data.
</aside>
## 获取用户星标项目
获取用户星标项目

View File

@ -0,0 +1,10 @@
class AddSchoolApplyForm
include ActiveModel::Model
attr_accessor :name, :province, :city, :address, :remarks
validates :name, presence: true
# validates :province, presence: true
# validates :city, presence: true
# validates :address, presence: true
end

View File

@ -0,0 +1,27 @@
class ApplyShixunMirrorForm
include ActiveModel::Model
attr_accessor :language, :runtime, :run_method, :attachment_id
validates :language, presence: true
validates :runtime, presence: true
validates :run_method, presence: true
validates :attachment_id, presence: true, numericality: { only_integer: true }
validate :ensure_attachment_presence
def ensure_attachment_presence
return unless attachment_id
if attachment.blank?
errors.add(:attachment_id, :attachment_not_exist)
end
end
def attachment
@attachment ||= Attachment.find_by_id(attachment_id)
end
def to_json
{ language: language, runtime: runtime, run_method: run_method, attachment_id: attachment_id }.to_json
end
end

View File

@ -23,11 +23,7 @@ class BaseForm
end
def check_reversed_keyword(repository_name)
raise "项目标识已被占用." if ReversedKeyword.check_exists?(repository_name)
end
private
def strip(str)
str.to_s.strip.presence
raise "项目标识已被占用." if ReversedKeyword.is_reversed(repository_name).exists?
end
end

View File

@ -0,0 +1,15 @@
class ExaminationBanks::SaveExamForm
include ActiveModel::Model
attr_accessor :discipline_id, :sub_discipline_id, :difficulty, :name, :duration, :tag_discipline_id
validates :discipline_id, presence: true
validates :sub_discipline_id, presence: true
validates :difficulty, presence: true, inclusion: {in: 1..3}, numericality: { only_integer: true }
validates :name, presence: true, length: { maximum: 60, too_long: "不能超过60个字符" }
validate :validate_duration
def validate_duration
raise '时长应为大于0的整数' if duration.present? && duration.to_i < 1
end
end

View File

@ -0,0 +1,12 @@
class ExaminationIntelligentSettings::SaveExamForm
include ActiveModel::Model
attr_accessor :name, :duration
validates :name, presence: true, length: { maximum: 60 }
validate :validate_duration
def validate_duration
raise '时长应为大于0的整数' if duration.present? && duration.to_i < 1
end
end

View File

@ -0,0 +1,11 @@
class ExaminationIntelligentSettings::SaveExamSettingForm
include ActiveModel::Model
attr_accessor :discipline_id, :sub_discipline_id, :source, :difficulty, :tag_discipline_id, :question_settings
validates :discipline_id, presence: true
validates :sub_discipline_id, presence: true
validates :source, presence: true
validates :difficulty, presence: true, inclusion: {in: 1..3}, numericality: { only_integer: true }
validates :question_settings, presence: true
end

View File

@ -3,12 +3,11 @@ class Projects::UpdateForm < BaseForm
validates :name, presence: true
validates :name, length: { maximum: 50 }
validates :description, length: { maximum: 200 }
validates :identifier, format: { with: CustomRegexp::REPOSITORY_NAME_REGEX, multiline: true, message: "只能含有数字、字母、下划线且不能以下划线开头和结尾" }
validate do
check_project_category(project_category_id)
check_project_language(project_language_id)
Rails.logger.info project_identifier
Rails.logger.info identifier
check_repository_name(user_id, identifier) unless identifier.blank? || identifier == project_identifier
end

View File

@ -1,51 +0,0 @@
module Register
class BaseForm < ::BaseForm
include ActiveModel::Model
Error = Class.new(StandardError)
EmailError = Class.new(Error)
LoginError = Class.new(Error)
PhoneError = Class.new(Error)
PasswordFormatError = Class.new(Error)
VerifiCodeError = Class.new(Error)
private
def check_login(login)
login = strip(login)
raise LoginError, "登录名格式有误" unless login =~ CustomRegexp::LOGIN
login_exist = Owner.exists?(login: login) || ReversedKeyword.check_exists?(login)
raise LoginError, '登录名已被使用' if login_exist
end
def check_mail(mail)
mail = strip(mail)
raise EmailError, "邮件格式有误" unless mail =~ CustomRegexp::EMAIL
mail_exist = Owner.exists?(mail: mail)
raise EmailError, '邮箱已被使用' if mail_exist
end
def check_phone(phone)
phone = strip(phone)
raise PhoneError, "手机号格式有误" unless phone =~ CustomRegexp::PHONE
phone_exist = Owner.exists?(phone: phone)
raise PhoneError, '手机号已被使用' if phone_exist
end
def check_password(password)
password = strip(password)
raise PasswordFormatError, "8~16位密码支持字母数字和符号" unless password =~ CustomRegexp::PASSWORD
end
def check_verifi_code(verifi_code, code)
code = strip(code)
# return if code == "123123" # TODO 万能验证码,用于测试
raise VerifiCodeError, "验证码不正确" if verifi_code&.code != code
raise VerifiCodeError, "验证码已失效" if !verifi_code&.effective?
end
end
end

View File

@ -1,19 +0,0 @@
module Register
class CheckColumnsForm < Register::BaseForm
attr_accessor :type, :value
validates :type, presence: true, numericality: true
validates :value, presence: true
validate :check!
def check!
# params[:type] 为事件类型 1登录名(login) 2email(邮箱) 3phone(手机号)
case strip(type).to_i
when 1 then check_login(strip(value))
when 2 then check_mail(strip(value))
when 3 then check_phone(strip(value))
else raise("type值无效")
end
end
end
end

View File

@ -1,27 +0,0 @@
module Register
class Form < Register::BaseForm
# login 登陆方式,支持邮箱、登陆、手机号等
# namespace 用户空间地址
# type: 1手机号注册2邮箱注册
attr_accessor :login, :namespace, :password, :code, :type
validates :login, :code, :password, :namespace, presence: true
validate :check!
def check!
Rails.logger.info "Register::Form params: code: #{code}; login: #{login}; namespace: #{namespace}; password: #{password}; type: #{type}"
db_verifi_code =
if type == 1
check_phone(login)
VerificationCode.where(phone: login, code: code, code_type: 1).last
elsif type == 0
check_mail(login)
VerificationCode.where(email: login, code: code, code_type: 8).last
end
check_login(namespace)
check_verifi_code(db_verifi_code, code)
check_password(password)
end
end
end

View File

@ -0,0 +1,20 @@
class Weapps::CreateCourseForm
include ActiveModel::Model
attr_accessor :course
attr_accessor :name, :course_list_name, :credit, :course_module_types, :end_date
validates :name, presence: true
validates :course_list_name, presence: true
validate :course_name_prefix
validate :check_course_modules
def course_name_prefix
raise '课堂名称应以课程名称开头' unless name.index(course_list_name) && name.index(course_list_name) == 0
end
def check_course_modules
raise '请至少添加一个课堂模块' if course_module_types.blank?
end
end

View File

@ -0,0 +1,15 @@
class Weapps::UpdateCourseForm
include ActiveModel::Model
attr_accessor :course
attr_accessor :name, :course_list_name, :credit, :end_date
validates :name, presence: true
validates :course_list_name, presence: true
validate :course_name_prefix
def course_name_prefix
raise '课堂名称应以课程名称开头' unless name.index(course_list_name) && name.index(course_list_name) == 0
end
end

View File

@ -4,7 +4,7 @@ module Admins::ProjectsHelper
owner = project.owner
if owner.is_a?(User)
link_to(project.owner&.real_name, "/#{project&.owner&.login}", target: '_blank')
link_to(project.owner&.real_name, "/users/#{project&.owner&.login}", target: '_blank')
elsif owner.is_a?(Organization)
link_to(project.owner&.real_name, "/organize/#{project&.owner&.login}", target: '_blank')
else

View File

@ -1,6 +1,6 @@
# 所有的方法请按首字母的顺序依次列出
module ApplicationHelper
include Gitlink::I18n
include Educoder::I18n
include GitHelper
ONE_MINUTE = 60 * 1000
@ -442,14 +442,6 @@ module ApplicationHelper
User.find_by(gitea_uid: gitea_uid)
end
def find_user_in_redis_cache(login, email)
$redis_cache.hgetall("v2-owner-common:#{login}-#{email}")
end
def find_user_in_redis_cache_by_id(id)
$redis_cache.hgetall("v2-owner-common:#{id}")
end
def render_base64_decoded(str)
return nil if str.blank?
Base64.decode64 str
@ -463,11 +455,5 @@ module ApplicationHelper
sidebar_item(url, "数据统计", icon: 'bar-chart', controller: 'root')
end
end
# 1 手机类型0 邮箱类型
# 注意新版的login是自动名生成的
def phone_mail_type value
value =~ /^1\d{10}$/ ? 1 : 0
end
end

View File

@ -1,26 +0,0 @@
module AvatarHelper
def relative_path
"avatars"
end
def storage_path
File.join(Rails.root, "public", "images", relative_path)
end
def disk_filename(source_type,source_id,image_file=nil)
File.join(storage_path, "#{source_type}", "#{source_id}")
end
def url_to_avatar(source)
if File.exist?(disk_filename(source&.class, source&.id))
ctime = File.ctime(disk_filename(source.class, source.id)).to_i
if %w(User Organization).include?(source.class.to_s)
File.join("images", relative_path, ["#{source.class}", "#{source.id}"]) + "?t=#{ctime}"
else
File.join("images/avatars", ["#{source.class}", "#{source.id}"]) + "?t=#{ctime}"
end
elsif source.class.to_s == 'User'
source.get_letter_avatar_url
end
end
end

View File

@ -0,0 +1,2 @@
module BoardsHelper
end

View File

@ -0,0 +1,10 @@
module ChallengesHelper
def match_begin_symbol str
str.gsub(/\A\r/, "\r\r")
end
end

View File

@ -0,0 +1,2 @@
module CourseGroupsHelper
end

View File

@ -0,0 +1,2 @@
module CourseModulesHelper
end

View File

@ -0,0 +1,2 @@
module CourseSecondCategoriesHelper
end

View File

@ -0,0 +1,2 @@
module CourseStagesHelper
end

View File

@ -0,0 +1,298 @@
module CoursesHelper
def member_manager group, teachers
str = ""
members = teachers.select{|teacher| teacher.teacher_course_groups.pluck(:course_group_id).include?(group.id) || teacher.teacher_course_groups.size == 0}
str = members.uniq.size == teachers.size ? "全部教师" : members.map{|member| member.user.real_name}.join("")
str
# teachers.each do |member|
# if member.teacher_course_groups.exists?(course_group_id: group.id) || member.teacher_course_groups.size == 0
# str << member.user.real_name
# end
# end
end
def edit_auth group, teachers
User.current.admin_or_business? ||
teachers.select{|teacher| teacher.user_id == User.current.id &&
(teacher.teacher_course_groups.pluck(:course_group_id).include?(group.id) || teacher.teacher_course_groups.size == 0)}.size > 0
end
# 是否有切换为学生的入口
def switch_student_role is_teacher, course, user
is_teacher && course.course_members.where(user_id: user.id, role: %i(STUDENT)).exists?
end
# 是否有切换为教师的入口
def switch_teacher_role is_student, course, user
is_student && course.course_members.where(user_id: user.id, role: %i(CREATOR PROFESSOR)).exists?
end
# 是否有切换为助教的入口
def switch_assistant_role is_student, course, user
is_student && course.course_members.where(user_id: user.id, role: %i(ASSISTANT_PROFESSOR)).exists?
end
# 课堂结束天数
def course_end_date end_date
if end_date.present?
curr = Time.new
date = ((Date.parse(end_date.to_s) - Date.parse(curr.to_s)).to_i)
date > 0 ? "#{date}天后" : ""
end
end
# 课堂模块的url
def module_url mod, course
return nil if mod.blank? or course.blank?
case mod.module_type
when "announcement"
"/courses/#{course.id}/informs"
when "online_learning"
"/courses/#{course.id}/online_learning"
when "shixun_homework"
"/courses/#{course.id}/shixun_homeworks/#{mod.id}"
when "common_homework"
"/courses/#{course.id}/common_homeworks/#{mod.id}"
when "group_homework"
"/courses/#{course.id}/group_homeworks/#{mod.id}"
when "graduation"
"/courses/#{course.id}/graduation_topics/#{mod.id}"
when "exercise"
"/courses/#{course.id}/exercises/#{mod.id}"
when "poll"
"/courses/#{course.id}/polls/#{mod.id}"
when "attachment"
"/courses/#{course.id}/files/#{mod.id}"
when "board"
course_board = course.course_board
"/courses/#{course.id}/boards/#{course_board.id}"
when "course_group"
"/courses/#{course.id}/course_groups"
when "statistics"
"/courses/#{course.id}/statistics"
when "video"
"/courses/#{course.id}/course_videos"
end
end
# 子目录对应的url
def category_url category, course
case category.category_type
when "shixun_homework"
"/courses/#{course.id}/shixun_homework/#{category.id}"
when "graduation"
if category.name == "毕设选题"
"/courses/#{course.id}/graduation_topics/#{category.course_module_id}"
else
"/courses/#{course.id}/graduation_tasks/#{category.course_module_id}"
end
when "attachment"
"/courses/#{course.id}/file/#{category.id}"
end
end
# 子目录下的任务数
def category_task_count course, category, user
case category.category_type
when "shixun_homework"
get_homework_commons_count(course, 4, category.id)
when "graduation"
if category.name == "毕设选题"
course.graduation_topics_count
else
course.graduation_tasks_count
end
when "attachment"
get_attachment_count(course, category.id)
end
end
# 课堂模块的任务数
def course_task_count(course, module_type)
case module_type
when "shixun_homework"
get_homework_commons_count(course, 4, 0)
when "common_homework"
get_homework_commons_count(course, 1, 0)
when "group_homework"
get_homework_commons_count(course, 3, 0)
when "graduation"
0
when "exercise"
course.exercises_count
when "poll"
course.polls_count
when "attachment"
get_attachment_count(course, 0)
when "board"
course_board = course.course_board
course_board.present? ? course_board.messages.size : 0
when "course_group"
course.course_groups_count
when "announcement"
course.informs.count
when "online_learning"
course.shixuns.count
when "video"
course.course_videos.count + course.live_links.count
end
end
# 当前用户可见的课堂作业type指定作业类型 category_id指定二级目录
def visible_homework course, user, type, category_id=0
if user.teacher_of_course?(course)
homeworks = course.homework_commons.where("homework_type = #{type} and course_second_category_id = #{category_id}")
elsif user.member_of_course?(course)
member = course.course_members.find_by(user_id: user.id, role: 4)
if member.try(:course_group_id).to_i == 0
homeworks = course.homework_commons.where("homework_commons.homework_type = #{type} and publish_time <= '#{Time.now}'
and unified_setting = 1 and course_second_category_id = #{category_id}")
else
not_homework_ids = course.homework_group_settings.where("course_group_id = #{member.try(:course_group_id)} and
(publish_time > '#{Time.now}' or publish_time is null)").pluck(:homework_common_id)
# not_homework_ids = not_homework_ids.blank? ? "(-1)" : "(" + not_homework_ids.map(&:homework_common_id).join(",") + ")"
homeworks = course.homework_commons.where.not(id: not_homework_ids).where("homework_commons.homework_type = #{type} and publish_time <= '#{Time.now}'
and course_second_category_id = #{category_id}")
end
else
homeworks = course.homework_commons.where("homework_type = #{type} and publish_time <= '#{Time.now}' and unified_setting = 1
and course_second_category_id = #{category_id}")
end
homeworks
end
# 当前用户可见的课堂试卷
def visible_exercise course, user
if user.teacher_of_course?(course)
exercises = course.exercises
elsif user.member_of_course?(course)
member = course.course_members.find_by(user_id: user.id, role: 4)
if member.try(:course_group_id).to_i == 0
exercises = course.exercises.where("publish_time <= '#{Time.now}' and unified_setting = 1")
else
not_exercise_ids = course.exercise_group_settings.where("course_group_id = #{member.try(:course_group_id)} and
(publish_time > '#{Time.now}' or publish_time is null)").pluck(:exercise_id)
exercises = course.exercises.where.not(id: not_exercise_ids).where("publish_time <= '#{Time.now}'")
end
else
exercises = course.exercises.where("publish_time <= '#{Time.now}' and unified_setting = 1")
end
exercises
end
# 当前用户可见的课堂问卷
def visible_poll course, user
if user.teacher_of_course?(course)
polls = course.polls
elsif user.member_of_course?(course)
member = course.course_members.find_by(user_id: user.id, role: 4)
if member.try(:course_group_id).to_i == 0
polls = course.polls.where("publish_time <= '#{Time.now}' and unified_setting = 1")
else
not_poll_ids = course.poll_group_settings.where("course_group_id = #{member.try(:course_group_id)} and
(publish_time > '#{Time.now}' or publish_time is null)").pluck(:poll_id)
polls = course.polls.where.not(id: not_poll_ids).where("publish_time <= '#{Time.now}'")
end
else
polls = course.polls.where("publish_time <= '#{Time.now}' and unified_setting = 1")
end
polls
end
# 当前用户可见的课堂资源category_id指定资源的目录
def visible_attachment course, user, category_id=0
result = []
course.attachments.where(course_second_category_id: category_id).each do |attachment|
if attachment.unified_setting
if attachment.is_public == 1 && attachment.is_publish == 1 || user == attachment.author || user.teacher_of_course?(course) || (user.member_of_course?(course) && attachment.is_publish == 1)
result << attachment
end
else
if attachment.is_public == 1 && attachment.is_publish == 1 && !user.member_of_course?(course) || user == attachment.author || user.teacher_of_course?(course)
result << attachment
elsif user.member_of_course?(course) && attachment.is_publish == 1
member = course.course_members.find_by(user_id: user.id, role: 4)
if member.try(:course_group_id).to_i == 0 && attachment.unified_setting
result << attachment
elsif attachment.attachment_group_settings.where("course_group_id = #{member.try(:course_group_id)} and publish_time > '#{Time.now}'").count == 0
result << attachment
end
end
end
end
result
end
# 获取课堂的资源数
def get_attachment_count(course, category_id)
category_id.to_i == 0 ? course.attachments.size : course.attachments.where(course_second_category_id: category_id).size
end
# 获取课堂的作业数
def get_homework_commons_count(course, type, category_id)
category_id == 0 ? HomeworkCommon.where(course_id: course.id, homework_type: type).size :
HomeworkCommon.where(course_id: course.id, homework_type: type, course_second_category_id: category_id).size
end
# 获取课堂的任务数(作业数+试卷数+问卷数)
def get_tasks_count(course)
course.homework_commons_count + course.exercises_count + course.polls_count
end
# 当前用户可见的毕设任务
def visible_graduation_task course, user
if user.teacher_of_course?(course)
tasks = course.graduation_tasks
else
tasks = course.graduation_tasks.where("publish_time <= '#{Time.now}'")
end
tasks
end
# 分班情况
def course_group_info course, user_id
course_group_ids = course.group_course_power(user_id)
course_groups =
if course_group_ids.present?
course.course_groups.where(id: course_group_ids).includes(:course_members)
else
course.course_groups.includes(:course_members)
end
group_info = []
if !course_groups.blank?
course_groups.each do |group|
group_info << {course_group_id: group.id, group_group_name: group.name, count: group.course_members_count}
end
none_group_count = course.students.where(course_group_id: 0).size
group_info << {course_group_id: 0, group_group_name: "未分班", count: none_group_count} if none_group_count > 0 && !course_group_ids.present?
end
return group_info
end
def left_group_info course
group_info = []
if course.course_groups_count > 0
none_group_count = course.students.where(course_group_id: 0).size
group_info << {category_id: 0, category_name: "未分班", position: course.course_groups.pluck(:position).max.to_i + 1,
category_count: none_group_count, category_type: false,
second_category_url: "/courses/#{@course.id}/course_groups/0"}
course.course_groups.each do |course_group|
group_info << {category_id: course_group.id, category_name: course_group.name, position: course_group.position,
category_count: course_group.course_members_count, category_type: false,
second_category_url: "/courses/#{@course.id}/course_groups/#{course_group.id}"}
end
end
group_info
end
def last_subject_shixun course, myshixuns
myshixun = myshixuns.sort{|x,y| y[:updated_at] <=> x[:updated_at] }.first
return "" unless myshixun
stage_shixun = course.course_stage_shixuns.where(shixun_id: myshixun.shixun_id).take
progress = stage_shixun&.course_stage&.position.to_s + "-" + stage_shixun&.position.to_s + " " + myshixun.shixun&.name
end
end

View File

@ -0,0 +1,2 @@
module DiscussesHelper
end

View File

@ -0,0 +1,2 @@
module EduDatasHelper
end

View File

@ -0,0 +1,150 @@
module GraduationTasksHelper
include CoursesHelper
# 教师评阅
def teacher_comment task, user_id
[{ id: 0 ,name: "未评", count: task.uncomment_count(user_id)}, {id: 1, name: "已评", count: task.comment_count(user_id)}]
end
# 作品状态
def task_status task, user_id
[{id: 0, name: "未提交", count: task.unfinished_count(user_id)},
{id: 1, name: "按时提交", count: task.finished_count(user_id)},
{id: 2, name: "延时提交", count: task.delay_finished_count(user_id)}]
end
# 交叉评阅
def cross_comment task, user_id
if task.cross_comment && task.status >= 3
[{id: 1, name: "只看我的交叉评阅", count: task.graduation_work_comment_assignations.myself(user_id).count}]
else
[]
end
end
def task_curr_status task, course
result = {}
status = []
time = ""
if course.try(:is_end)
status << "已结束"
time = course.end_date.present? ? course.end_date.strftime("%Y-%m-%d") : ""
else
if task.status > 1 && task.allow_late && (task.late_time.nil? || task.late_time > Time.now)
status << "补交中"
end
case task.status
when 0
status << "未发布"
time = task.publish_time.present? ? "将于 #{format_time(task.publish_time)} 发布" : "创建于#{time_from_now(task.created_at)}"
when 1
if task.end_time && task.end_time >= Time.now
status << "提交中"
time = how_much_time(task.end_time)
end
when 2
status << "评阅中"
time = task.comment_time.present? ? how_much_time(task.comment_time) : course.end_date.present? ? how_much_time(course.end_date.end_of_day) : ""
when 3
status << "交叉评阅中"
time = course.end_date.present? ? how_much_time(course.end_date.end_of_day) : ""
end
status << "未开启补交" if (!task.allow_late && task.status != 0) #6.11 -hs 新增status不等于0
# 如果还在补交阶段则显示补交结束时间
if task.status > 1 && task.allow_late && task.late_time && task.late_time > Time.now
time = how_much_time(task.late_time)
end
end
result[:status] = status
result[:time] = time
result
end
# 作品数统计type 1 已提交 0 未提交
def grduationwork_count task, type
works = task.graduation_works
type == 1 ? works.select{|work| work.work_status != 0}.size : works.select{|work| work.work_status == 0}.size
end
# 普通/分组 作业作品状态数组
def graduation_work_status task, user_id, course
status = []
work = task.graduation_works.find_by(user_id: user_id)
work = work || GraduationWork.create(graduation_task_id: task.id, user_id: user_id)
late_time = task.late_time || course.end_date
if course.is_end && work && work.work_status > 0
status << "查看作品"
elsif !course.is_end
if task.publish_time && task.publish_time < Time.now
# 作业未截止时
if task.end_time > Time.now
if task.task_type == 2 && task.base_on_project
if work.project_id.nil? || work.project_id == 0
status << "创建项目"
status << "关联项目"
elsif work.work_status == 0
status << "取消关联"
status << "提交作品"
else
status << "修改作品"
end
else
if work.work_status == 0
status << "提交作品"
else
status << "修改作品"
end
end
# 补交阶段
elsif task.allow_late && (late_time.nil? || late_time > Time.now)
if task.task_type == 2 && task.base_on_project
if work.project_id.nil? || work.project_id == 0
status << "创建项目"
status << "关联项目"
elsif work.work_status == 0
status << "取消关联"
status << "补交作品"
else
status << "补交附件"
status << "查看作品"
end
else
if work.work_status == 0
status << "补交作品"
else
status << "补交附件"
status << "查看作品"
end
end
# 匿评阶段
elsif work.work_status != 0
status << "查看作品"
end
end
end
end
# 阶段剩余时间
def task_left_time task
if task.publish_time && task.publish_time < Time.now
if task.end_time > Time.now
status = "剩余提交时间"
time = "#{how_much_time(task.end_time)}"
else
if task.allow_late && task.late_time && task.late_time >= Time.now
status = "剩余补交时间"
time = "#{how_much_time(task.late_time)}"
end
end
end
{status: status, time: time}
end
end

View File

@ -0,0 +1,30 @@
module GraduationTopicsHelper
# 课题类型
def topic_type
[{id: 1, name: "设计"}, {id: 2, name: "论文"}, {id: 3, name: "创作"}]
end
# 课程来源
def topic_source
[{id: 1, name: "生产/社会实际"}, {id: 2, name:"结合科研"}, {id: 3, name: "其它"}]
end
# 课题性质1
def topic_property_first
[{id: 1, name: "真题"}, {id: 2, name:"模拟题"}]
end
# 课题性质2
def topic_property_second
[{id: 1, name: "纵向课题"}, {id: 2, name:"横向课题"}, {id: 3, name: "自选"}]
end
# 课题重复
def topic_repeat
[{id: 1, name: "新题"}, {id: 2, name:"往届题,有新要求"}, {id: 3, name: "往届题,无新要求"}]
end
end

View File

@ -0,0 +1,20 @@
module GraduationWorksHelper
include GraduationTasksHelper
# 作品最终成绩
# 参数: work作品 current_user用户course_identity用户在课堂的身份
def work_final_score work, current_user, course_identity
work_score =
if work.work_score.nil?
"--"
else
if work.check_score_power? current_user, course_identity
format("%.1f", work.work_score < 0 ? 0 : work.work_score.round(1))
else
"**"
end
end
# work_score 最终成绩; late_penalty 迟交扣分; final_score 最终评分
{username: work.user.full_name, login: work.user.login, work_score: work_score, final_score: work.final_score}
end
end

View File

@ -0,0 +1,2 @@
module HackUserLastestCodesHelper
end

View File

@ -0,0 +1,2 @@
module HacksHelper
end

View File

@ -35,16 +35,6 @@ module RepositoriesHelper
end
end
def render_cache_commit_author(author_json)
Rails.logger.info author_json['Email']
if author_json["name"].present? && author_json["email"].present?
return find_user_in_redis_cache(author_json['name'], author_json['email'])
end
if author_json["Name"].present? && author_json["Email"].present?
return find_user_in_redis_cache(author_json['Name'], author_json['Email'])
end
end
def readme_render_decode64_content(str, path)
return nil if str.blank?
begin

View File

@ -0,0 +1,2 @@
module TrustieHacksHelper
end

View File

@ -0,0 +1,69 @@
module Weapps::CoursesHelper
require 'chinese_pinyin'
def teacher_list teachers, user_course_identity
data = []
teachers.each do |teacher|
if teacher.user.present?
teacher_user = teacher.user
name = teacher_user.real_name
role = teacher.role == "CREATOR" ? "管理员" : teacher.role == "PROFESSOR" ? "教师" : "助教"
member_roles = user_course_identity < Course::ASSISTANT_PROFESSOR ? teacher_user.course_role(teacher.course) : []
item = {name: name, course_member_id: teacher.id, login: teacher_user.login, user_id: teacher.user_id, role: role,
school: teacher_user.school_name, image_url: url_to_avatar(teacher_user), member_roles: member_roles}
pinyin = Pinyin.t(name.strip, splitter: '')
first_char = pinyin[0]
letter = first_letter first_char
if data.pluck(:letter).include?(letter)
data.select{|a|a[:letter]==letter}.first[:items] << item
else
data << {letter: letter, items: [item]}
end
end
end
# data = data.sort do |a, b|
# [a[:letter]] <=> [b[:letter]]
# end
# data.push(data.shift) if data.select{|a|a[:letter]=='#'}.first.present? # '#'排在最后
return data
end
def student_list students, excellent, user_course_identity
data = []
students.each do |student|
if student.user.present?
student_user = student.user
name = student_user.real_name
phone = excellent ? "" : student_user.hidden_phone
member_roles = user_course_identity < Course::ASSISTANT_PROFESSOR ? student_user.course_role(student.course) : []
item = {name: name, course_member_id: student.id, login: student_user.login, user_id: student.user_id,
student_id: student_user.student_id, image_url: url_to_avatar(student_user), phone: phone, member_roles: member_roles}
pinyin = Pinyin.t(name.strip, splitter: '')
first_char = pinyin[0]
letter = first_letter first_char
if data.pluck(:letter).include?(letter)
data.select{|a|a[:letter]==letter}.first[:items] << item
else
data << {letter: letter, items: [item]}
end
end
end
# data = data.sort do |a, b|
# [a[:letter]] <=> [b[:letter]]
# end
# data.push(data.shift) if data.select{|a|a[:letter]=='#'}.first.present? # '#'排在最后
return data
end
def first_letter char
if char.ord >= 97 && char.ord <= 122
letter = (char.ord - 32).chr.to_s
elsif char.ord >= 65 && char.ord <= 90
letter = char
else
letter = '#'
end
letter
end
end

View File

@ -0,0 +1,20 @@
class Admins::ImportCourseMemberExcel < BaseImportXlsx
Data = Struct.new(:student_id, :name, :course_id, :role, :course_group_name, :school_id)
def read_each(&block)
sheet.each_row_streaming(pad_cells: true, offset: 1) do |row|
data = row.map(&method(:cell_value))[0..5]
block.call Data.new(*data)
end
end
private
def check_sheet_valid!
raise_import_error('请按照模板格式导入') if sheet.row(1).size != 6
end
def cell_value(obj)
obj&.cell_value&.to_s&.strip
end
end

View File

@ -0,0 +1,23 @@
# 批量发布视频 消息任务
class BatchPublishVideoNotifyJob < ApplicationJob
queue_as :notify
def perform(user_id, video_ids)
user = User.find_by(id: user_id)
return if user.blank?
attrs = %i[user_id trigger_user_id container_id container_type tiding_type status created_at updated_at]
same_attrs = {
user_id: 1,
trigger_user_id: user.id,
container_type: 'Video',
tiding_type: 'Apply', status: 0
}
Tiding.bulk_insert(*attrs) do |worker|
user.videos.where(id: video_ids).each do |video|
worker.add same_attrs.merge(container_id: video.id)
end
end
end
end

View File

@ -1,12 +0,0 @@
class CacheAsyncClearJob < ApplicationJob
queue_as :cache
def perform(type, id=nil)
case type
when "project_common_service"
Cache::V2::ProjectCommonService.new(id).clear
when "owner_common_service"
Cache::V2::OwnnerCommonService.new(id).clear
end
end
end

View File

@ -1,16 +0,0 @@
class CacheAsyncResetJob < ApplicationJob
queue_as :cache
def perform(type, id=nil)
case type
when "platform_statistic_service"
Cache::V2::PlatformStatisticService.new.reset
when "project_common_service"
Cache::V2::ProjectCommonService.new(id).reset
when "owner_common_service"
Cache::V2::OwnnerCommonService.new(id).reset
when "user_statistic_service"
Cache::V2::UserStatisticService.new(id).reset
end
end
end

View File

@ -1,16 +0,0 @@
class CacheAsyncSetJob < ApplicationJob
queue_as :cache
def perform(type, params={}, id=nil)
case type
when "platform_statistic_service"
Cache::V2::PlatformStatisticService.new(params).call
when "project_common_service"
Cache::V2::ProjectCommonService.new(id, params).call
when "owner_common_service"
Cache::V2::OwnnerCommonService.new(id, params).call
when "user_statistic_service"
Cache::V2::UserStatisticService.new(id, params).call
end
end
end

View File

@ -0,0 +1,67 @@
# 学生加入课堂时创建相关任务作品
class CourseAddStudentCreateWorksJob < ApplicationJob
queue_as :default
def perform(course_id, student_ids)
course = Course.find_by(id: course_id)
return if course.blank?
# 如果之前存在相关作品则更新is_delete字段
student_works = StudentWork.joins(:homework_common).where(user_id: student_ids, homework_commons: {course_id: course.id})
student_works.update_all(is_delete: 0)
exercise_users = ExerciseUser.joins(:exercise).where(user_id: student_ids, exercises: {course_id: course.id})
exercise_users.update_all(is_delete: 0)
poll_users = PollUser.joins(:poll).where(user_id: student_ids, polls: {course_id: course.id})
poll_users.update_all(is_delete: 0)
graduation_works = course.graduation_works.where(user_id: student_ids)
graduation_works.update_all(is_delete: 0)
attrs = %i[homework_common_id user_id created_at updated_at]
StudentWork.bulk_insert(*attrs) do |worker|
student_ids.each do |user_id|
same_attrs = {user_id: user_id}
course.homework_commons.where(homework_type: %i[normal group practice]).each do |homework|
next if StudentWork.where(user_id: user_id, homework_common_id: homework.id).any?
worker.add same_attrs.merge(homework_common_id: homework.id)
end
end
end
attrs = %i[exercise_id user_id created_at updated_at]
ExerciseUser.bulk_insert(*attrs) do |worker|
student_ids.each do |user_id|
same_attrs = {user_id: user_id}
course.exercises.each do |exercise|
next if ExerciseUser.where(user_id: user_id, exercise_id: exercise.id).any?
worker.add same_attrs.merge(exercise_id: exercise.id)
end
end
end
attrs = %i[poll_id user_id created_at updated_at]
PollUser.bulk_insert(*attrs) do |worker|
student_ids.each do |user_id|
same_attrs = {user_id: user_id}
course.polls.each do |poll|
next if PollUser.where(user_id: user_id, poll_id: poll.id).any?
worker.add same_attrs.merge(poll_id: poll.id)
end
end
end
attrs = %i[graduation_task_id user_id course_id created_at updated_at]
GraduationWork.bulk_insert(*attrs) do |worker|
student_ids.each do |user_id|
same_attrs = {user_id: user_id, course_id: course.id}
course.graduation_tasks.each do |task|
next if GraduationWork.where(user_id: user_id, graduation_task_id: task.id).any?
worker.add same_attrs.merge(graduation_task_id: task.id)
end
end
end
end
end

View File

@ -0,0 +1,19 @@
class CourseDeleteStudentDeleteWorksJob < ApplicationJob
queue_as :default
def perform(course_id, student_ids)
course = Course.find_by(id: course_id)
return if course.blank?
student_works = StudentWork.joins(:homework_common).where(user_id: student_ids, homework_commons: {course_id: course.id})
student_works.update_all(is_delete: 1)
exercise_users = ExerciseUser.joins(:exercise).where(user_id: student_ids, exercises: {course_id: course.id})
exercise_users.update_all(is_delete: 1)
poll_users = PollUser.joins(:poll).where(user_id: student_ids, polls: {course_id: course.id})
poll_users.update_all(is_delete: 1)
course.graduation_works.where(user_id: student_ids).update_all(is_delete: 1)
end
end

View File

@ -0,0 +1,22 @@
# 删除课堂用户
class CourseDeleteStudentNotifyJob < ApplicationJob
queue_as :notify
def perform(course_id, student_ids, trigger_user_id)
course = Course.find_by(id: course_id)
return if course.blank?
attrs = %i[user_id trigger_user_id container_id container_type belong_container_id
belong_container_type tiding_type created_at updated_at]
same_attrs = {
trigger_user_id: trigger_user_id, container_id: course.id, container_type: 'DeleteCourseMember',
belong_container_id: course.id, belong_container_type: 'Course', tiding_type: 'System'
}
Tiding.bulk_insert(*attrs) do |worker|
student_ids.each do |user_id|
worker.add same_attrs.merge(user_id: user_id)
end
end
end
end

View File

@ -0,0 +1,12 @@
class CreateDiffRecordJob < ApplicationJob
queue_as :default
def perform(user_id, obj_id, obj_klass, column_name, before, after)
user = User.find_by(id: user_id)
obj = obj_klass.constantize.find_by(id: obj_id)
return if user.blank? || obj.blank?
CreateDiffRecordService.call(user, obj, column_name, before, after)
end
end

View File

@ -0,0 +1,21 @@
# 删除部门 消息通知
class DeleteDepartmentNotifyJob < ApplicationJob
queue_as :notify
def perform(department_id, operator_id, user_ids)
department = Department.unscoped.find_by(id: department_id)
return if department.blank? || user_ids.blank?
attrs = %i[ user_id trigger_user_id container_id container_type tiding_type status created_at updated_at]
same_attrs = {
trigger_user_id: operator_id, container_id: department.id, container_type: 'Department',
status: 4, tiding_type: 'System'
}
Tiding.bulk_insert(*attrs) do |worker|
user_ids.each do |user_id|
worker.add same_attrs.merge(user_id: user_id)
end
end
end
end

View File

@ -0,0 +1,44 @@
# 试卷发布 消息通知
class ExercisePublishNotifyJob < ApplicationJob
queue_as :notify
def perform(exercise_id, group_ids)
exercise = Exercise.find_by(id: exercise_id)
return if exercise.blank?
user = exercise.user
course = exercise.course
if group_ids.present?
students = course.students.where(course_group_id: group_ids)
subquery = course.teacher_course_groups.where(course_group_id: group_ids).select(:course_member_id)
teachers = course.teachers.where(id: subquery)
else
students = course.students
teachers = course.teachers
end
attrs = %i[
user_id trigger_user_id container_id container_type parent_container_id parent_container_type
belong_container_id belong_container_type viewed tiding_type created_at updated_at
]
same_attrs = {
trigger_user_id: user.id, container_id: exercise.id, container_type: 'Exercise',
parent_container_id: exercise.id, parent_container_type: 'ExercisePublish',
belong_container_id: exercise.course_id, belong_container_type: 'Course',
viewed: 0, tiding_type: 'Exercise'
}
Tiding.bulk_insert(*attrs) do |worker|
teacher_ids = teachers.pluck(:user_id)
unless exercise.tidings.exists?(parent_container_type: 'ExercisePublish', user_id: teacher_ids)
teacher_ids.each do |user_id|
worker.add same_attrs.merge(user_id: user_id)
end
end
students.pluck(:user_id).each do |user_id|
worker.add same_attrs.merge(user_id: user_id)
end
end
end
end

View File

@ -0,0 +1,17 @@
# 获取阿里云视频信息
class GetAliyunVideoInfoJob < ApplicationJob
queue_as :default
def perform(vod_video_id)
video = Video.find_by(uuid: vod_video_id)
return if video.blank? || video.vod_uploading?
result = AliyunVod::Service.get_play_info(video.uuid)
cover_url = result.dig('VideoBase', 'CoverURL')
file_url = (result.dig('PlayInfoList', 'PlayInfo') || []).first&.[]('PlayURL')
video.cover_url = cover_url if cover_url.present? && video.cover_url.blank?
video.file_url = file_url if file_url.present?
video.save!
end
end

View File

@ -0,0 +1,22 @@
# 毕设任务的交叉评阅分配
class GraduationTaskCrossCommentJob < ApplicationJob
queue_as :default
def perform(graduation_task_id)
task = GraduationTask.find_by(id: graduation_task_id)
return if task.blank?
task.graduation_task_group_assignations.includes(:graduation_group, :graduation_work).each do |assignation|
graduation_group = assignation.graduation_group
work = assignation.graduation_work
if graduation_group.present? && work.present?
member_ids = graduation_group.course_members.pluck(:user_id).uniq
member_ids.each do |user_id|
unless work.graduation_work_comment_assignations.exists?(user_id: user_id)
work.graduation_work_comment_assignations << GraduationWorkCommentAssignation.new(user_id: user_id, graduation_task_id: task.id)
end
end
end
end
end
end

View File

@ -0,0 +1,28 @@
# 任务发布 消息通知
class GraduationTaskPublishNotifyJob < ApplicationJob
queue_as :notify
def perform(graduation_task_id)
task = GraduationTask.find_by(id: graduation_task_id)
return if task.blank?
course = task.course
return if course.blank?
attrs = %i[
user_id trigger_user_id container_id container_type parent_container_id parent_container_type
belong_container_id belong_container_type viewed tiding_type created_at updated_at
]
same_attrs = {
trigger_user_id: task.user_id, container_id: task.id, container_type: 'GraduationTask',
parent_container_id: task.id, parent_container_type: 'TaskPublish',
belong_container_id: task.course_id, belong_container_type: 'Course',
viewed: 0, tiding_type: 'GraduationTask'
}
Tiding.bulk_insert(*attrs) do |worker|
course.course_members.pluck(:user_id).uniq.each do |user_id|
worker.add same_attrs.merge(user_id: user_id)
end
end
end
end

View File

@ -0,0 +1,33 @@
class ResubmitStudentWorkNotifyJob < ApplicationJob
queue_as :notify
def perform(homework_id, student_ids)
homework = HomeworkCommon.find_by(id: homework_id)
return if homework.blank? || student_ids.blank?
course = homework.course
attrs = %i[user_id trigger_user_id container_id container_type parent_container_id parent_container_type
belong_container_id belong_container_type tiding_type viewed created_at updated_at]
same_attrs = {
container_type: 'ResubmitStudentWork', parent_container_id: homework.id, parent_container_type: 'HomeworkCommon',
belong_container_id: course.id, belong_container_type: 'Course', tiding_type: 'HomeworkCommon', viewed: 0
}
Tiding.bulk_insert(*attrs) do |worker|
student_ids.each do |user_id|
next unless User.exists?(id: user_id)
work = homework.student_works.find_by(user_id: user_id)
next if work.blank?
score_user_ids = work.student_works_scores.where.not(score: nil).where(reviewer_role: [1, 2]).pluck(user_id).uniq
next if score_user_ids.blank?
attrs = same_attrs.merge(trigger_user_id: user_id, container_id: work.id)
score_user_ids.each do |user_id|
worker.add attrs.merge(user_id: user_id)
end
end
end
end
end

View File

@ -36,21 +36,17 @@ class SendTemplateMessageJob < ApplicationJob
operator = User.find_by_id(operator_id)
issue = Issue.find_by_id(issue_id)
return unless operator.present? && issue.present?
# receivers = receivers.where.not(id: operator&.id)
receivers = receivers.where.not(id: operator&.id)
receivers_string, content, notification_url = MessageTemplate::IssueAtme.get_message_content(receivers, operator, issue)
Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {operator_id: operator.id, issue_id: issue.id}, 2, operator_id)
Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {operator_id: operator.id, issue_id: issue.id}, 2)
when 'IssueChanged'
operator_id, issue_id, change_params = args[0], args[1], args[2]
operator = User.find_by_id(operator_id)
issue = Issue.find_by_id(issue_id)
return unless operator.present? && issue.present?
receivers = User.where(id: [issue&.assigned_to_id, issue&.author_id]).where.not(id: operator&.id)
receivers_string, content, notification_url = MessageTemplate::IssueChanged.get_message_content(receivers, operator, issue, change_params.symbolize_keys)
receivers_string, content, notification_url = MessageTemplate::IssueChanged.get_message_content(receivers, operator, issue, change_params)
Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {operator_id: operator.id, issue_id: issue.id, change_params: change_params.symbolize_keys})
receivers.find_each do |receiver|
receivers_email_string, email_title, email_content = MessageTemplate::IssueChanged.get_email_message_content(receiver, operator, issue, change_params)
Notice::Write::EmailCreateService.call(receivers_email_string, email_title, email_content)
end
when 'IssueCreatorExpire'
issue_id = args[0]
issue = Issue.find_by_id(issue_id)
@ -65,10 +61,6 @@ class SendTemplateMessageJob < ApplicationJob
receivers = User.where(id: [issue_assigned_to_id, issue_author_id]).where.not(id: operator&.id)
receivers_string, content, notification_url = MessageTemplate::IssueDeleted.get_message_content(receivers, operator, issue_title)
Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {operator_id: operator.id, issue_title: issue_title})
receivers.find_each do |receiver|
receivers_email_string, email_title, email_content = MessageTemplate::IssueDeleted.get_email_message_content(receiver, operator, issue_title)
Notice::Write::EmailCreateService.call(receivers_email_string, email_title, email_content)
end
when 'OrganizationJoined'
user_id, organization_id = args[0], args[1]
user = User.find_by_id(user_id)
@ -201,7 +193,7 @@ class SendTemplateMessageJob < ApplicationJob
receivers_string, content, notification_url = MessageTemplate::ProjectRole.get_message_content(receivers, project, role)
Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {operator_id: operator.id, user_id: user.id, project_id: project.id, role: role})
receivers.find_each do |receiver|
receivers_email_string, email_title, email_content = MessageTemplate::ProjectRole.get_email_message_content(receiver, project, role)
receivers_email_string, email_title, email_content = MessageTemplate::ProjectRole.get_email_message_content(receivers, project, role)
Notice::Write::EmailCreateService.call(receivers_email_string, email_title, email_content)
end
when 'ProjectSettingChanged'
@ -211,7 +203,7 @@ class SendTemplateMessageJob < ApplicationJob
return unless operator.present? && project.present?
receivers = project.all_managers.where.not(id: operator&.id)
receivers_string, content, notification_url = MessageTemplate::ProjectSettingChanged.get_message_content(receivers, operator, project, change_params.symbolize_keys)
Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {operator_id: operator.id, project_id: project.id, change_params: change_params.symbolize_keys})
Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {operator_id: operator.id, project_id: project.id, change_params: change_params})
receivers.find_each do |receiver|
receivers_email_string, email_title, email_content = MessageTemplate::ProjectSettingChanged.get_email_message_content(receiver, operator, project, change_params.symbolize_keys)
Notice::Write::EmailCreateService.call(receivers_email_string, email_title, email_content)
@ -234,9 +226,9 @@ class SendTemplateMessageJob < ApplicationJob
operator = User.find_by_id(operator_id)
pull_request = PullRequest.find_by_id(pull_request_id)
return unless operator.present? && pull_request.present?
# receivers = receivers.where.not(id: operator&.id)
receivers = receivers.where.not(id: operator&.id)
receivers_string, content, notification_url = MessageTemplate::PullRequestAtme.get_message_content(receivers, operator, pull_request)
Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {operator_id: operator.id, pull_request_id: pull_request.id}, 2, operator_id)
Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {operator_id: operator.id, pull_request_id: pull_request.id}, 2)
when 'PullRequestChanged'
operator_id, pull_request_id, change_params = args[0], args[1], args[2]
operator = User.find_by_id(operator_id)
@ -246,10 +238,6 @@ class SendTemplateMessageJob < ApplicationJob
receivers = User.where(id: [issue&.assigned_to_id, pull_request&.user_id]).where.not(id: operator&.id)
receivers_string, content, notification_url = MessageTemplate::PullRequestChanged.get_message_content(receivers, operator, pull_request, change_params.symbolize_keys)
Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {operator_id: operator.id, pull_request_id: pull_request.id, change_params: change_params})
receivers.find_each do |receiver|
receivers_email_string, email_title, email_content = MessageTemplate::PullRequestChanged.get_email_message_content(receiver, operator, pull_request, change_params.symbolize_keys)
Notice::Write::EmailCreateService.call(receivers_email_string, email_title, email_content)
end
when 'PullRequestClosed'
operator_id, pull_request_id = args[0], args[1]
operator = User.find_by_id(operator_id)
@ -258,10 +246,6 @@ class SendTemplateMessageJob < ApplicationJob
receivers = User.where(id: [pull_request&.issue&.assigned_to_id, pull_request&.user_id]).where.not(id: operator&.id)
receivers_string, content, notification_url = MessageTemplate::PullRequestClosed.get_message_content(receivers, operator, pull_request)
Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {operator_id: operator.id, pull_request_id: pull_request.id})
receivers.find_each do |receiver|
receivers_email_string, email_title, email_content = MessageTemplate::PullRequestClosed.get_email_message_content(receiver, operator, pull_request)
Notice::Write::EmailCreateService.call(receivers_email_string, email_title, email_content)
end
when 'PullRequestMerged'
operator_id, pull_request_id = args[0], args[1]
operator = User.find_by_id(operator_id)
@ -270,10 +254,6 @@ class SendTemplateMessageJob < ApplicationJob
receivers = User.where(id: [pull_request&.issue&.assigned_to_id, pull_request&.user_id]).where.not(id: operator&.id)
receivers_string, content, notification_url = MessageTemplate::PullRequestMerged.get_message_content(receivers, operator, pull_request)
Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {operator_id: operator.id, pull_request_id: pull_request.id})
receivers.find_each do |receiver|
receivers_email_string, email_title, email_content = MessageTemplate::PullRequestMerged.get_email_message_content(receiver, operator, pull_request)
Notice::Write::EmailCreateService.call(receivers_email_string, email_title, email_content)
end
end
end
end

View File

@ -1,7 +1,6 @@
module CustomRegexp
PHONE = /1\d{10}/
EMAIL = /\A[a-zA-Z0-9]+([._\\]*[a-zA-Z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+\z/
LOGIN = /^(?!_)(?!.*?_$)[a-zA-Z0-9_-]+$/ #只含有数字、字母、下划线不能以下划线开头和结尾
LASTNAME = /\A[a-zA-Z0-9\u4e00-\u9fa5]+\z/
NICKNAME = /\A[\u4e00-\u9fa5_a-zA-Z0-9]+\z/
PASSWORD = /\A[a-z_A-Z0-9\-\.!@#\$%\\\^&\*\)\(\+=\{\}\[\]\/",'_<>~\·`\?:;|]{8,16}\z/

View File

@ -0,0 +1,18 @@
module EducoderOauth
class << self
attr_accessor :client_id, :client_secret, :base_url, :redirect_uri
def logger
@_logger ||= STDOUT
end
def logger=(l)
@_logger = l
end
def oauth_url
"#{base_url}/oauth2?call_url=/oauth/authorize?client_id=#{client_id}&redirect_uri=#{URI.encode_www_form_component(redirect_uri)}&response_type=code"
end
end
end

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