Compare commits

...

326 Commits

Author SHA1 Message Date
yystopf d4d00b30bf Merge branch 'standalone_develop' into pre_trustie_server 2022-05-25 11:47:55 +08:00
yystopf 19ec81e975 Merge branch 'develop' into standalone_develop 2022-05-25 11:47:44 +08:00
yystopf 2ea78b4f20 增加: 已登录用户对用户名、邮箱、电话进行校验 2022-05-25 11:47:35 +08:00
yystopf 4c066b30ef Merge branch 'standalone_develop' into pre_trustie_server 2022-05-24 18:10:28 +08:00
yystopf ad9bb8e542 修复: 合并从develop 2022-05-24 18:10:20 +08:00
yystopf e36c7a4b6a 修复: 邮箱搜索不需要return 404 2022-05-24 18:09:36 +08:00
yystopf 18c4c6ae2f Merge branch 'standalone_develop' into pre_trustie_server 2022-05-24 17:38:21 +08:00
yystopf 9979c87d0c 修复: 合并从develop 2022-05-24 17:27:24 +08:00
yystopf 8e8ec821f2 新增: 根据邮箱来获取用户 2022-05-24 17:26:10 +08:00
xiaoxiaoqiong 774b1bc79e Merge branch 'standalone_develop' into pre_trustie_server 2022-05-24 15:24:43 +08:00
xiaoxiaoqiong 94166a363c fixed 增加自动登录,gitea注册 2022-05-24 15:24:15 +08:00
xiaoxiaoqiong 0219a1fdde Merge branch 'standalone_develop' into pre_trustie_server 2022-05-24 14:34:29 +08:00
xiaoxiaoqiong ebe5fad7dd fixed 增加自动登录,gitea注册 2022-05-24 14:33:23 +08:00
xiaoxiaoqiong b2e7491ade Merge branch 'standalone_develop' into pre_trustie_server 2022-05-24 14:15:21 +08:00
xiaoxiaoqiong 85a36ca2e7 fixed 增加自动登录,gitea注册 2022-05-24 14:14:57 +08:00
xiaoxiaoqiong b0f80012ab Merge branch 'standalone_develop' into pre_trustie_server 2022-05-24 14:08:58 +08:00
xiaoxiaoqiong 75cef14605 fixed 增加自动登录,gitea注册 2022-05-24 14:08:33 +08:00
xiaoxiaoqiong 0fc96026c8 Merge branch 'standalone_develop' into pre_trustie_server 2022-05-24 14:01:01 +08:00
xiaoxiaoqiong 93f8b659a1 fixed 增加自动登录,gitea注册 2022-05-24 14:00:15 +08:00
xiaoxiaoqiong b45ee11239 fixed 增加自动登录,gitea注册 2022-05-24 13:46:58 +08:00
xiaoxiaoqiong 553d3a019f Merge branch 'standalone_develop' into pre_trustie_server 2022-05-24 11:50:30 +08:00
xiaoxiaoqiong 33fa55bcb6 Merge remote-tracking branch 'origin/standalone_develop' into standalone_develop 2022-05-24 11:49:01 +08:00
xiaoxiaoqiong 643a99fdf1 fixed 增加自动登录,gitea注册 2022-05-24 11:48:56 +08:00
yystopf 38c5432c2a Merge branch 'develop' into standalone_develop 2022-05-24 11:46:26 +08:00
yystopf 5cf257c3cc Merge branch 'develop' of https://gitlink.org.cn/Trustie/forgeplus into develop 2022-05-24 11:45:53 +08:00
yystopf aa18fe0ad4 修复: 转移项目时新接受者需要移除原来的权限角色 2022-05-24 11:44:05 +08:00
yystopf 1358c23ca6 fix: trasfer project member must remove old permission 2022-05-24 11:43:47 +08:00
yystopf e8bfd0c955 Merge branch 'standalone_develop' into pre_trustie_server 2022-05-24 11:10:13 +08:00
yystopf 183eb15c7d Merge branch 'standalone_develop' of https://gitlink.org.cn/Trustie/forgeplus into standalone_develop 2022-05-24 11:03:59 +08:00
yystopf fb43268444 fix: merge from develop 2022-05-24 11:03:54 +08:00
yystopf c27cc063e6 add: new update user info simple and sync gitea 2022-05-24 10:59:52 +08:00
xiaoxiaoqiong 6f6fe61a9d Merge branch 'standalone_develop' into pre_trustie_server 2022-05-24 10:47:37 +08:00
xiaoxiaoqiong b673909f9e fixed 增加自动登录,手机号先记录,后续用 2022-05-24 10:47:17 +08:00
xiaoxiaoqiong bd4dbd577b Merge branch 'standalone_develop' into pre_trustie_server 2022-05-24 10:34:54 +08:00
xiaoxiaoqiong ee3a14fa28 fixed 增加自动登录 2022-05-24 10:34:31 +08:00
xiaoxiaoqiong 26bfc2c0bf fixed 增加自动登录 2022-05-24 10:33:21 +08:00
xiaoxiaoqiong eb2d976876 Merge branch 'standalone_develop' into pre_trustie_server 2022-05-24 10:29:00 +08:00
xiaoxiaoqiong 56721930a2 Merge remote-tracking branch 'origin/standalone_develop' into standalone_develop 2022-05-24 10:26:06 +08:00
xiaoxiaoqiong 2959414d56 fixed 增加自动登录 2022-05-24 10:25:58 +08:00
yystopf 008fdbaf5a Merge branch 'standalone_develop' into pre_trustie_server 2022-05-23 18:24:06 +08:00
yystopf 6223cf41e2 Merge branch 'standalone_develop' of https://gitlink.org.cn/Trustie/forgeplus into standalone_develop 2022-05-23 18:10:54 +08:00
yystopf 1d3f79e777 Merge branch 'develop' into standalone_develop 2022-05-23 18:10:47 +08:00
yystopf b0092487e6 fix: is readme use regex 2022-05-23 18:10:41 +08:00
xiaoxiaoqiong 0ae3544235 Merge remote-tracking branch 'origin/standalone_develop' into standalone_develop
# Conflicts:
#	app/controllers/users_controller.rb
#	app/helpers/application_helper.rb
2022-05-23 18:06:24 +08:00
xiaoxiaoqiong 05b3f2a2fb fixed timego时间差 2022-05-23 18:05:13 +08:00
yystopf 97fe157279 Merge branch 'develop' into standalone_develop 2022-05-23 09:27:16 +08:00
yystopf fbebd0a623 fix 2022-05-23 09:27:09 +08:00
yystopf 25487368e5 Merge branch 'standalone_develop' into pre_trustie_server 2022-05-21 17:06:41 +08:00
yystopf 02681abaee Merge branch 'develop' into standalone_develop 2022-05-21 16:46:14 +08:00
yystopf fe23c2afbf fix: replace content next if blank 2022-05-21 16:45:42 +08:00
yystopf dc0d31330a Merge branch 'standalone_develop' into pre_trustie_server 2022-05-20 17:28:25 +08:00
yystopf b06ad71082 Merge branch 'standalone_develop' of https://gitlink.org.cn/Trustie/forgeplus into standalone_develop 2022-05-20 17:06:10 +08:00
yystopf 3212bc4842 fix: merge from develop 2022-05-20 17:06:00 +08:00
yystopf 779c86108a fix: readme relative delay and replace_content 2022-05-20 17:00:02 +08:00
yystopf e4779926bd Merge pull request '代码溯源部分代码' (#9) from yystopf/forgeplus:standalone_develop into standalone_develop 2022-05-20 14:46:33 +08:00
yystopf 803fdfc49e fix: merge from develop 2022-05-20 11:44:56 +08:00
yystopf 83e43f0c97 add: new readme delay function 2022-05-20 11:43:22 +08:00
yystopf ccec3494bc merge from develop 2022-05-18 11:38:07 +08:00
yystopf e237fd46f7 fix: not found user return 404 2022-05-18 11:37:23 +08:00
yystopf 6dc2f0b062 Merge branch 'develop' into standalone_develop 2022-05-18 11:03:47 +08:00
yystopf ca3c564529 fix: not found user return 404 2022-05-18 11:03:39 +08:00
yystopf f79e4f8e81 Merge branch 'develop' into standalone_develop 2022-05-18 10:11:22 +08:00
yystopf 9cd18397f7 fix: import user login length required 2022-05-18 10:11:09 +08:00
yystopf bfd3298cd0 fix 2022-05-17 11:42:43 +08:00
yystopf 077926de18 fix 2022-05-17 11:39:57 +08:00
yystopf 4fade5d0b7 fix: project trace tasks name rule change 2022-05-17 11:34:08 +08:00
yystopf f51ebaad67 fix 2022-05-16 17:08:52 +08:00
yystopf 8ae6a0deb2 fix: some feature about permission 2022-05-16 17:02:38 +08:00
yystopf d9b3711e08 Merge branch 'develop' into standalone_develop 2022-05-16 16:59:36 +08:00
yystopf 77620f7735 add: download and import user template xlsx 2022-05-16 16:59:25 +08:00
yystopf acbd0d376c fix: change trace user post valid 2022-05-16 14:26:21 +08:00
yystopf 2f4ffe3d8e fix: change trace user post valid 2022-05-16 14:25:54 +08:00
yystopf a6efae8b10 fix 2022-05-16 10:48:23 +08:00
yystopf 5a728e7d4d fix: trace user exist and compact tasks create params 2022-05-16 09:58:47 +08:00
yystopf 04a733d99f fix: check user trace tasks count 2022-05-13 16:57:41 +08:00
yystopf 9e8c576ff6 fix: remove require manager operate 2022-05-13 15:38:04 +08:00
yystopf 94881dd72a add: user trace tasks record 2022-05-13 14:31:59 +08:00
yystopf 2c7bb1b5cd fix: remove project tasks_count 2022-05-13 14:00:21 +08:00
yystopf 0e4c0a46c2 fix 2022-05-13 13:56:12 +08:00
yystopf 7fcbbb7922 fix: remove project tasks_count 2022-05-13 13:53:25 +08:00
yystopf 3d9fe5bba5 add: download pdf from trace server 2022-05-12 17:52:19 +08:00
yystopf 4dccdfde97 fix 2022-05-12 17:15:19 +08:00
yystopf 00fc83235f download file use redirect 2022-05-12 17:11:16 +08:00
yystopf 498ee26f59 fix 2022-05-12 11:14:17 +08:00
yystopf 5d771c824b add: operate permission and request timeout 2022-05-12 11:12:34 +08:00
yystopf 3eccd6be64 add: user has trace user field 2022-05-12 09:45:37 +08:00
yystopf 9b3336c0a0 fix: reload task need increment tasks count 2022-05-12 09:43:55 +08:00
yystopf 12c961d70d fix 2022-05-12 09:43:55 +08:00
yystopf 7750cbe272 add: project trace tasks count 2022-05-12 09:43:55 +08:00
yystopf 1f13bba52e add: trace user tasks_count 2022-05-12 09:43:55 +08:00
yystopf 5dcee1b4dc add: traces api document 2022-05-12 09:43:55 +08:00
yystopf cf09b28f5e add: project menu services 2022-05-12 09:43:54 +08:00
yystopf f31796f344 add: branch valid for tasks 2022-05-12 09:43:52 +08:00
yystopf 2d9bde134a fix 2022-05-12 09:43:00 +08:00
yystopf 59db914bcc change route position 2022-05-12 09:42:59 +08:00
yystopf a0a7f908f4 rename namespace 2022-05-12 09:42:59 +08:00
yystopf 17ccf3d576 rename namespace 2022-05-12 09:42:59 +08:00
yystopf 72a32ed8c4 rename namespace 2022-05-12 09:42:59 +08:00
yystopf c64fa5135b fix 2022-05-12 09:42:59 +08:00
yystopf 12cc37443e add: trace controller and router 2022-05-12 09:42:59 +08:00
yystopf 5edea8960d Merge branch 'standalone_develop' into pre_trustie_server 2022-05-07 14:07:41 +08:00
yystopf f5efbcfc04 Merge branch 'develop' into standalone_develop 2022-05-07 14:06:58 +08:00
yystopf 50dc5cce5d fix 2022-05-07 14:06:48 +08:00
yystopf 0d377943d5 Merge branch 'standalone_develop' into pre_trustie_server 2022-05-07 11:58:24 +08:00
yystopf 0afac46778 Merge branch 'develop' into standalone_develop 2022-05-07 11:58:13 +08:00
yystopf a6cee63d17 fix: change owner must fix foreign_key 2022-05-07 11:57:58 +08:00
yystopf 77797fb1f7 Merge branch 'standalone_develop' into pre_trustie_server 2022-05-07 10:04:29 +08:00
yystopf 20af4a7d82 Merge branch 'develop' into standalone_develop 2022-05-06 17:25:52 +08:00
yystopf 000197b0d1 fix: issues and pull_request length calculate 2022-05-06 17:25:34 +08:00
yystopf 67b386d947 Merge branch 'develop' into standalone_develop 2022-05-06 14:29:15 +08:00
yystopf 6aa3321d17 fix: pr title description validate 2022-05-06 14:29:05 +08:00
yystopf 82df2fd6d8 Merge branch 'standalone_develop' of https://gitlink.org.cn/Trustie/forgeplus into standalone_develop 2022-05-06 09:57:40 +08:00
yystopf 9d8df2b4d9 Merge branch 'develop' into standalone_develop 2022-05-06 09:57:23 +08:00
yystopf d44308fc82 Merge branch 'develop' of https://gitlink.org.cn/Trustie/forgeplus into develop 2022-05-06 09:56:38 +08:00
yystopf ae7d0d1329 add: issues description and journals notes validate 2022-05-06 09:56:22 +08:00
xiaoxiaoqiong 071542bcb4 Merge remote-tracking branch 'origin/standalone_develop' into standalone_develop 2022-05-05 10:42:23 +08:00
xiaoxiaoqiong 676024b6db fork_users加入组织 2022-05-05 10:42:08 +08:00
xiaoxiaoqiong 55c74de8e4 fork_users加入组织 2022-05-05 10:41:02 +08:00
yystopf 52c94effdc Merge branch 'develop' into standalone_develop 2022-05-05 10:18:19 +08:00
yystopf 7c88ea3d67 add: quit repo 2022-05-05 10:00:02 +08:00
yystopf d799d329ff add: compare add paginate 2022-04-28 18:54:56 +08:00
yystopf f15cd44dff add: compare add paginate 2022-04-28 18:53:33 +08:00
yystopf 91ea5ca96a Merge branch 'develop' into standalone_develop 2022-04-28 11:12:35 +08:00
yystopf 3abd6037d9 fix: show super description aways desplay 2022-04-28 11:12:16 +08:00
yystopf 11724bf63f Merge branch 'develop' into standalone_develop 2022-04-28 11:04:01 +08:00
yystopf ec3a556a6f fix: default value for show super description 2022-04-28 11:03:42 +08:00
yystopf 1d7c7eba24 Merge branch 'develop' into standalone_develop 2022-04-28 10:54:02 +08:00
yystopf 793cbb372a Merge pull request '用户新增个人简介markdown编辑字段' (#8) from yystopf/forgeplus:hh_develop into develop 2022-04-28 10:53:06 +08:00
yystopf 396ac55429 add: user super description 2022-04-28 10:42:55 +08:00
yystopf e1b4622ede Merge branch 'develop' into standalone_develop 2022-04-26 17:17:05 +08:00
yystopf 088c617cc1 add: name query for branches 2022-04-26 17:15:59 +08:00
yystopf 121e04f751 Merge branch 'standalone_develop' into pre_trustie_server 2022-04-21 16:59:55 +08:00
yystopf 246b484ad8 fix merge from develop 2022-04-18 14:14:48 +08:00
yystopf fc3cf01d3f add: get user image action 2022-04-18 13:49:08 +08:00
yystopf 345fd31834 Merge branch 'develop' into standalone_develop 2022-04-18 10:52:59 +08:00
yystopf 8f5bb0e2d9 fix: organization gitea_token read by associations 2022-04-18 10:52:48 +08:00
yystopf 7aea481ccf add: glcc_apply_infomations admin navbar 2022-04-18 10:24:54 +08:00
yystopf 37317f82bf Merge branch 'develop' into standalone_develop 2022-04-11 16:09:08 +08:00
yystopf 2dfd69ae21 fix: response data result 2022-04-11 16:08:50 +08:00
yystopf a132154136 Merge branch 'develop' into standalone_develop 2022-04-11 15:48:54 +08:00
yystopf 720c073f32 fix 2022-04-11 15:48:47 +08:00
yystopf 185cb308ac Merge branch 'develop' into standalone_develop 2022-04-11 15:30:44 +08:00
yystopf 0076468a15 fix: trace client request data 2022-04-11 15:30:28 +08:00
yystopf 910ae48556 fix: exception to ex 2022-04-11 10:50:18 +08:00
xiaoxiaoqiong 6e86f9d9f3 竞赛配置子赛项 2022-04-08 23:07:23 +08:00
xiaoxiaoqiong e97e7aa550 竞赛配置子赛项 2022-04-08 21:59:35 +08:00
xiaoxiaoqiong ffb3b26d3c Merge branch 'standalone_develop' into pre_trustie_server 2022-04-08 18:51:16 +08:00
xiaoxiaoqiong 6d280ed8f2 竞赛配置子赛项 2022-04-08 18:51:01 +08:00
xiaoxiaoqiong 47b3816e4f Merge branch 'standalone_develop' into pre_trustie_server 2022-04-08 18:46:46 +08:00
xiaoxiaoqiong 3f85f88c92 竞赛配置子赛项 2022-04-08 18:46:14 +08:00
xiaoxiaoqiong 1477811782 Merge branch 'standalone_develop' into pre_trustie_server 2022-04-08 18:41:17 +08:00
xiaoxiaoqiong f60cd409b6 竞赛配置子赛项 2022-04-08 18:40:52 +08:00
xiaoxiaoqiong 04b2a9b358 Merge branch 'standalone_develop' into pre_trustie_server 2022-04-08 17:45:38 +08:00
xiaoxiaoqiong 9d46f2743d 竞赛配置子赛项 2022-04-08 17:45:15 +08:00
xiaoxiaoqiong 000a4f8019 Merge branch 'standalone_develop' into pre_trustie_server 2022-04-08 17:39:47 +08:00
xiaoxiaoqiong aaf2b43986 Merge remote-tracking branch 'origin/standalone_develop' into standalone_develop 2022-04-08 17:38:59 +08:00
xiaoxiaoqiong 75a9a65b9b 竞赛配置子赛项 2022-04-08 17:38:26 +08:00
yystopf 49afc0e20a Merge branch 'develop' into pre_trustie_server 2022-04-08 16:39:19 +08:00
yystopf 17f2436118 Merge branch 'develop' into standalone_develop 2022-04-08 15:03:52 +08:00
yystopf eac7331070 fix: settings need prefix 2022-04-08 15:03:40 +08:00
yystopf 2243697184 Merge branch 'develop' into standalone_develop 2022-04-08 14:53:06 +08:00
yystopf 551f333261 fix 2022-04-08 14:52:56 +08:00
yystopf 18cf1d3ecb Merge branch 'glcc_news_develop' into standalone_develop 2022-04-08 13:23:49 +08:00
yystopf 7c1160b247 Merge branch 'standalone_develop' into pre_trustie_server 2022-04-08 11:59:51 +08:00
yystopf 4cefaa7e92 Merge branch 'develop' into standalone_develop 2022-04-08 11:59:25 +08:00
yystopf dec264d169 fix: sync user pwd 2022-04-07 16:28:40 +08:00
yystopf 8aa935ad5c add: glcc news management and api data 2022-04-07 16:13:32 +08:00
xiaoxiaoqiong f082819496 Merge branch 'standalone_develop' into pre_trustie_server 2022-04-06 20:32:31 +08:00
xiaoxiaoqiong 4bdff8313a Merge remote-tracking branch 'origin/standalone_develop' into standalone_develop 2022-04-06 20:32:06 +08:00
xiaoxiaoqiong c4f91fb054 搜索用户增加email和单位 2022-04-06 20:32:02 +08:00
yystopf a33be8850e Merge branch 'standalone_develop' into pre_trustie_server 2022-04-06 17:05:05 +08:00
yystopf fde01e62ef Merge branch 'develop' into standalone_develop 2022-04-06 17:04:52 +08:00
yystopf 7055974443 fix 2022-04-06 17:04:31 +08:00
xiaoxiaoqiong e0022647ed Merge branch 'standalone_develop' into pre_trustie_server 2022-04-06 14:35:11 +08:00
xiaoxiaoqiong 1f6ac05bad 允许非登录搜索用户 2022-04-06 14:33:47 +08:00
yystopf 70dd2768e5 Merge branch 'standalone_develop' into pre_trustie_server 2022-03-31 18:30:00 +08:00
yystopf c5dd099169 Merge branch 'develop' into standalone_develop 2022-03-31 16:18:25 +08:00
yystopf 3536918938 fix 2022-03-31 16:18:16 +08:00
yystopf d56da6d020 Merge branch 'develop' into standalone_develop 2022-03-31 16:08:43 +08:00
yystopf 56278b84f2 Merge pull request '导航增加动态用户数据获取' (#3) from hh_develop_navbar into develop 2022-03-31 16:08:36 +08:00
yystopf 882a50cf56 add: setting navbar varible 2022-03-31 16:04:48 +08:00
yystopf 234f5b900c Merge branch 'develop' into standalone_develop 2022-03-31 14:25:02 +08:00
yystopf db4031b8bf fix 2022-03-31 14:24:47 +08:00
yystopf dd3236e310 Merge branch 'develop' into standalone_develop 2022-03-31 13:18:46 +08:00
yystopf ecfc39565c fix 2022-03-31 13:18:38 +08:00
yystopf 7fd41e13e4 Merge branch 'develop' into standalone_develop 2022-03-31 13:04:02 +08:00
yystopf 9ced678f91 fix: user trace token 2022-03-31 13:03:54 +08:00
yystopf b25db9d37f fix: merge from develop 2022-03-31 13:00:36 +08:00
yystopf 7951ca28d5 Merge pull request '代码溯源service封装' (#2) from hh_develop into develop 2022-03-31 12:59:34 +08:00
yystopf 4bbb843edf add: trace users and get trace token 2022-03-31 12:54:39 +08:00
yystopf 747646cd9d add: trace client and api completed 2022-03-30 16:19:32 +08:00
yystopf a5be4a9502 fix: readme image regex error rescued 2022-03-28 11:25:13 +08:00
yystopf d0d906d04c fix: readme image regex error rescued 2022-03-28 11:05:21 +08:00
xiaoxiaoqiong 4c69c4d20f Merge remote-tracking branch 'origin/standalone_develop' into standalone_develop 2022-03-24 10:25:31 +08:00
xiaoxiaoqiong 183315bbd9 万能验证码,用于测试 2022-03-24 10:25:24 +08:00
yystopf 4dc3546124 Merge branch 'standalone_develop' of https://gitlink.org.cn/Trustie/forgeplus into standalone_develop 2022-03-22 10:45:55 +08:00
yystopf d796d59557 Merge branch 'develop' into standalone_develop 2022-03-22 10:45:45 +08:00
yystopf bc639488aa fix: issues filter error 2022-03-22 10:45:14 +08:00
xiaoxiaoqiong 930805704a fixed: 文件目录加载性能优化 2022-03-18 17:32:29 +08:00
xiaoxiaoqiong 9912ad0779 fixed: 1.readme加载不正常 2022-03-18 17:09:06 +08:00
xiaoxiaoqiong d9ae4e4ba0 fixed: 1.readme加载不正常, 2.文件目录加载性能优化 2022-03-18 16:52:23 +08:00
xiaoxiaoqiong 23dc2d7fb6 目录树加载图片不需要Content 2022-03-18 14:55:42 +08:00
xiaoxiaoqiong fe5c18c019 readme.md支持图片相对路径 2022-03-18 14:24:03 +08:00
xiaoxiaoqiong fa6f015128 readme.md支持图片相对路径 2022-03-18 14:21:12 +08:00
xiaoxiaoqiong 7f1b95c7d7 readme.md支持图片相对路径 2022-03-18 14:03:59 +08:00
xiaoxiaoqiong 2346b0f848 readme.md支持图片相对路径 2022-03-18 11:41:26 +08:00
xiaoxiaoqiong ea070d4e23 gitea 请求延长到20分钟 2022-03-11 14:10:43 +08:00
xiaoxiaoqiong c0e97409cb gitea 请求延长到20分钟 2022-03-11 14:07:39 +08:00
xiaoxiaoqiong 99fbecc834 gitea 请求延长到20分钟 2022-03-11 14:06:12 +08:00
yystopf 4cc8dd70f4 Merge branch 'develop' into standalone_develop 2022-03-10 10:47:20 +08:00
yystopf 8d0a6d267a fix: download escape 2022-03-10 10:47:06 +08:00
yystopf 0db1820557 Merge branch 'develop' into standalone_develop 2022-03-10 09:52:12 +08:00
yystopf b1c03ed5e8 fix: activity issues must only issue 2022-03-10 09:51:46 +08:00
yystopf 1c660213a7 fix: claims is losed 2022-03-10 09:36:51 +08:00
yystopf 748f6cdd4d Merge branch 'standalone_develop' of https://gitlink.org.cn/Trustie/forgeplus into standalone_develop 2022-03-07 11:20:58 +08:00
yystopf 1fe8d1defc Merge branch 'develop' into standalone_develop 2022-03-07 11:20:23 +08:00
yystopf ef12f85687 fix: create pull request valid merge_user_login 2022-03-07 11:17:10 +08:00
yystopf e120c4dac2 add: origin repository need open pr menu 2022-03-07 10:53:07 +08:00
yystopf e1cf2fcdeb fix: owner project not allow repeat name 2022-03-07 10:25:05 +08:00
yystopf c4f380873e fix: is public project attachment allow is not member read 2022-03-07 10:20:51 +08:00
yystopf 5cb2e55f74 add: organization users insist team nickname search 2022-03-07 09:58:05 +08:00
xiaoxiaoqiong 386c90592e Merge branch 'standalone_develop' into pre_trustie_server 2022-03-03 15:07:24 +08:00
xiaoxiaoqiong 664b806c0a routes合并 2022-03-03 15:06:56 +08:00
xiaoxiaoqiong b530de4ddc Merge branch 'standalone_develop' into pre_trustie_server 2022-03-03 14:21:22 +08:00
xiaoxiaoqiong 1dd3fbc69a fixed fork列表中存在组织时显示错误 2022-03-03 14:16:57 +08:00
xiaoxiaoqiong 94d259ea03 fixed fork列表中存在组织时显示错误 2022-03-03 14:16:05 +08:00
yystopf 3091593d14 add: standalone admin menu 2022-03-02 10:48:21 +08:00
yystopf c5d2fad913 Merge branch 'develop' into standalone_develop 2022-03-02 10:34:16 +08:00
yystopf b97c42d0ae fix: email logo 2022-03-02 10:33:35 +08:00
yystopf c76466a883 Merge branch 'pre_trustie_server' into trustie_server 2022-02-24 18:10:06 +08:00
yystopf 217e0fdd97 Merge branch 'standalone_develop' into pre_trustie_server 2022-02-24 18:09:53 +08:00
yystopf f0b8489828 Merge branch 'develop' into standalone_develop 2022-02-24 18:09:20 +08:00
yystopf a2612d8009 fix 2022-02-24 18:09:11 +08:00
yystopf 2f2655525f fix: user rank user_id must exist 2022-02-24 18:07:18 +08:00
yystopf 70ade7b27b Merge branch 'pre_trustie_server' into trustie_server 2022-02-24 16:45:12 +08:00
yystopf 57c60b2fe9 Merge branch 'standalone_develop' into pre_trustie_server 2022-02-24 16:44:58 +08:00
yystopf aa643430fa Merge branch 'develop' into standalone_develop 2022-02-24 14:27:31 +08:00
yystopf 1a93477635 fix: forked templete delay 2022-02-24 14:26:04 +08:00
yystopf 8f9aedd7d6 Merge branch 'pre_trustie_server' into trustie_server 2022-02-24 11:47:38 +08:00
yystopf ab989ed7d7 Merge branch 'standalone_develop' into pre_trustie_server 2022-02-24 11:46:44 +08:00
xiaoxiaoqiong 28d07d5c54 fixed 合并冲突 2022-02-22 17:49:14 +08:00
yystopf 53d094784b Merge branch 'develop' into standalone_develop 2022-02-22 11:03:47 +08:00
yystopf 7c664addbd fix 2022-02-22 11:03:28 +08:00
yystopf 6167834bfa Merge branch 'pre_trustie_server' into trustie_server 2022-02-22 10:40:11 +08:00
yystopf 1bb754e9d8 Merge branch 'standalone_develop' into pre_trustie_server 2022-02-22 10:39:47 +08:00
yystopf f2f2ce8252 merge from develop 2022-02-22 10:38:42 +08:00
yystopf c6b79f82bc fix: change password new version 2022-02-22 10:03:51 +08:00
xiaoxiaoqiong 4e3f9cc019 竞赛通知任务调度 2022-02-21 16:48:59 +08:00
xiaoxiaoqiong 5ed7b3e4ad 竞赛通知任务调度 2022-02-21 16:46:40 +08:00
xiaoxiaoqiong 4e2c46260c Merge remote-tracking branch 'origin/develop' into develop 2022-02-17 18:28:40 +08:00
xiaoxiaoqiong 9ba00b21c9 竞赛通知api 2022-02-17 18:28:32 +08:00
yystopf 1100309038 Merge branch 'develop' into standalone_develop 2022-02-17 11:12:58 +08:00
yystopf b11f5fd228 fix: cache rollback 2022-02-17 11:12:50 +08:00
yystopf af5f2b2fe3 Merge branch 'develop' into standalone_develop 2022-02-17 10:59:29 +08:00
yystopf 90dbe0730a fix: job not affect 2022-02-17 10:59:18 +08:00
yystopf f39e8b7668 Merge branch 'develop' into standalone_develop 2022-02-17 09:43:52 +08:00
yystopf d6633cb73a fix 2022-02-17 09:43:44 +08:00
yystopf 86ef890f8b Merge branch 'develop' into standalone_develop 2022-02-17 09:40:54 +08:00
yystopf a7a6abd22a fix: add rule for issue expire 2022-02-17 09:40:44 +08:00
yystopf 6fd47b56a5 Merge branch 'develop' into standalone_develop 2022-02-17 09:37:00 +08:00
yystopf c956667ce0 fix 2022-02-17 09:36:49 +08:00
yystopf 898453c88c Merge branch 'develop' into standalone_develop 2022-02-16 15:10:19 +08:00
yystopf 5701c818ed fix 2022-02-16 15:10:10 +08:00
yystopf 1ac2ddfaa5 fix: default setting for new template message 2022-02-16 11:46:34 +08:00
yystopf 0bd274f813 Merge branch 'develop' into standalone_develop 2022-02-16 11:17:15 +08:00
yystopf 4aac05d4e1 fix: build user template message data must fronted 2022-02-16 11:17:03 +08:00
yystopf b028a70646 Merge branch 'pre_trustie_server' into trustie_server 2022-02-16 09:35:56 +08:00
yystopf 3c7da85bee Merge branch 'standalone_develop' into pre_trustie_server 2022-02-16 09:35:42 +08:00
yystopf 9751c954df Merge branch 'develop' into standalone_develop 2022-02-16 09:35:22 +08:00
yystopf 84b56bfcb8 fix: project milestone create notice template 2022-02-16 09:34:31 +08:00
yystopf ac07c88f84 Merge branch 'develop' into standalone_develop 2022-02-15 18:30:25 +08:00
yystopf 7485564bb9 add: template message platform varible 2022-02-15 18:30:13 +08:00
yystopf 5e696ae905 Merge branch 'develop' into standalone_develop 2022-02-15 17:33:55 +08:00
yystopf b5acf2308a Merge pull request '新增站内信以及里程碑完成度修复' (#299) from yystopf/forgeplus:develop into develop 2022-02-15 17:33:30 +08:00
yystopf e3f4313c80 fix 2022-02-15 17:29:13 +08:00
yystopf b223abe229 fix: init data 2022-02-15 17:26:46 +08:00
yystopf b3bede308c add: some new message rules 2022-02-15 17:13:06 +08:00
xiaoxiaoqiong 2f170a54c6 fixed setting编辑类型下拉选中 2022-02-15 17:10:57 +08:00
yystopf 22293572ac fix: issue changed about version callback 2022-02-14 17:02:59 +08:00
xiaoxiaoqiong d262da7c65 通过配置确定github克隆方式 2022-02-14 16:56:12 +08:00
xiaoxiaoqiong 2050559077 通过配置确定github克隆方式 2022-02-14 16:54:24 +08:00
xiaoxiaoqiong 8720cab1e9 通过配置确定github克隆方式 2022-02-14 16:53:29 +08:00
yystopf 959c1e8d95 add: user profile setting message 2022-02-14 13:55:34 +08:00
yystopf 52bde548fa Merge branch 'pre_trustie_server' into trustie_server 2022-02-11 16:28:07 +08:00
yystopf ea11672fff Merge branch 'standalone_develop' into pre_trustie_server 2022-02-11 16:27:56 +08:00
yystopf 09c4f8db0e Merge branch 'develop' into standalone_develop 2022-02-11 16:27:42 +08:00
yystopf 29dc3fff39 fix: migrate use old rule 2022-02-11 16:27:22 +08:00
yystopf da863c3963 Merge branch 'pre_trustie_server' into trustie_server 2022-02-10 14:11:25 +08:00
yystopf 8d18149537 Merge branch 'standalone_develop' into pre_trustie_server 2022-02-10 14:11:06 +08:00
yystopf 8050af23fc Merge branch 'develop' into standalone_develop 2022-02-10 14:10:54 +08:00
yystopf 298abdd1b1 fix: devops organization bug 2022-02-10 14:08:14 +08:00
yystopf eb0ced39f5 Merge branch 'pre_trustie_server' into trustie_server 2022-01-26 13:47:26 +08:00
yystopf 2738d950d4 Merge branch 'standalone_develop' into pre_trustie_server 2022-01-26 13:47:14 +08:00
yystopf 3ce9b2d145 Merge branch 'develop' into standalone_develop 2022-01-25 14:26:20 +08:00
yystopf 26f87fba16 fix: edit transfer need change fork info 2022-01-25 14:26:11 +08:00
yystopf 465f38bca7 Merge branch 'develop' into standalone_develop 2022-01-25 11:39:15 +08:00
yystopf 1e9a32a93e fix: issues select count paginator 2022-01-25 11:39:06 +08:00
yystopf 04bc6d363f Merge branch 'develop' into standalone_develop 2022-01-25 10:34:33 +08:00
yystopf 2dc79052c2 fix: create project trend when status is closed 2022-01-25 10:34:20 +08:00
yystopf f6ff8ac209 Merge branch 'pre_trustie_server' into trustie_server 2022-01-24 17:27:30 +08:00
yystopf b9e2a6edf1 Merge branch 'standalone_develop' into pre_trustie_server 2022-01-24 17:27:21 +08:00
yystopf e0f5337fdd Merge branch 'develop' into standalone_develop 2022-01-24 14:26:36 +08:00
yystopf 380ca3a066 fix: projects query rule 2022-01-24 14:26:24 +08:00
yystopf 7d19849968 Merge branch 'develop' into standalone_develop 2022-01-24 10:44:59 +08:00
yystopf 237b0afb08 fix: team user build use find or create by 2022-01-24 10:44:46 +08:00
yystopf 67914201bf merge from develop 2022-01-24 10:06:20 +08:00
yystopf e14936e820 fix: issues select count 2022-01-24 10:00:44 +08:00
yystopf 655c85851f Merge branch 'develop' of https://git.trustie.net/Gitlink/forgeplus into develop 2022-01-21 18:20:40 +08:00
yystopf 1c7e414aa4 fix: owner allow nil 2022-01-21 18:19:43 +08:00
yystopf 099fc52e00 fix: contributor error rescue 2022-01-21 18:19:34 +08:00
yystopf 490957ec3b fix: contributor error rescue 2022-01-21 18:19:27 +08:00
yystopf b1884d30d5 fix: detail result delay 2022-01-21 18:19:06 +08:00
xiaoxiaoqiong 98d8ee1fb6 Merge remote-tracking branch 'origin/develop' into develop 2022-01-21 15:50:41 +08:00
xiaoxiaoqiong 2ca77732c8 fixed 注册登录类型 2022-01-21 15:50:37 +08:00
yystopf 1760b42127 Merge branch 'pre_trustie_server' into trustie_server 2022-01-14 17:38:27 +08:00
yystopf 9f7725b097 Merge branch 'standalone_develop' into pre_trustie_server 2022-01-14 17:38:16 +08:00
yystopf 612101498c Merge branch 'develop' into standalone_develop 2022-01-14 17:38:09 +08:00
yystopf 70d22f7c4f fix: create team overflow tip 2022-01-14 16:09:38 +08:00
yystopf 25d0e784bb fix: pr assignee info use array 2022-01-14 16:00:59 +08:00
yystopf 5d45b24299 fix: devops return result changed 2022-01-14 10:55:53 +08:00
yystopf b6b8befde7 fix: pr update must edit assignee login 2022-01-14 10:55:01 +08:00
yystopf f33b9559cd fix: download delay 2022-01-13 11:24:27 +08:00
yystopf ab6ac05a7d Merge branch 'pre_trustie_server' into trustie_server 2022-01-11 10:53:40 +08:00
yystopf cf69628f85 Merge branch 'standalone_develop' into pre_trustie_server 2022-01-11 10:53:29 +08:00
yystopf 4a8f8af896 Merge branch 'develop' into standalone_develop 2022-01-11 10:48:56 +08:00
yystopf f9bc2258ec fix: migrate repo github use another addr 2022-01-11 10:48:29 +08:00
187 changed files with 4987 additions and 2580 deletions

1
.gitignore vendored
View File

@ -85,3 +85,4 @@ Dockerfile
dump.rdb
.tags*
ceshi_user.xlsx
public/trace_task_results

View File

@ -1,6 +1,25 @@
class AccountsController < ApplicationController
before_action :require_login, only: [:login_check, :simple_update]
include ApplicationHelper
#skip_before_action :check_account, :only => [:logout]
def simple_update
simple_update_params.merge!(username: params[:username]&.gsub(/\s+/, ""))
simple_update_params.merge!(email: params[:email]&.gsub(/\s+/, ""))
simple_update_params.merge!(platform: (params[:platform] || 'forge')&.gsub(/\s+/, ""))
Register::RemoteForm.new(simple_update_params).validate!
ActiveRecord::Base.transaction do
result = auto_update(current_user, simple_update_params)
if result[:message].blank?
render_ok
else
render_error(result[:message])
end
end
end
def index
render json: session
end
@ -192,7 +211,9 @@ class AccountsController < ApplicationController
sync_params = {
password: params[:password].to_s,
email: @user.mail
email: @user.mail,
login_name: @user.name,
source_id: 0
}
interactor = Gitea::User::UpdateInteractor.call(@user.login, sync_params)
@ -314,6 +335,11 @@ class AccountsController < ApplicationController
render_ok
end
def login_check
Register::LoginCheckColumnsForm.new(check_params.merge(user: current_user)).validate!
render_ok
end
private
# type 事件类型 1用户注册 2忘记密码 3: 绑定手机 4: 绑定邮箱, 5: 验证手机号是否有效 # 如果有新的继续后面加
@ -381,4 +407,7 @@ class AccountsController < ApplicationController
params.permit(:username, :email, :password, :platform)
end
def simple_update_params
params.permit(:username, :email, :password, :platform)
end
end

View File

@ -2,7 +2,7 @@ class Admins::ImportUsersController < Admins::BaseController
def create
return render_error('请上传正确的文件') if params[:file].blank? || !params[:file].is_a?(ActionDispatch::Http::UploadedFile)
result = Admins::ImportUserService.call(params[:file].to_io)
result = Admins::ImportUserFromExcelService.call(params[:file].to_io)
render_ok(result)
rescue Admins::ImportUserService::Error => ex
render_error(ex)

View File

@ -0,0 +1,57 @@
class Admins::Topic::GlccNewsController < Admins::Topic::BaseController
before_action :find_glcc, only: [:edit, :update, :destroy]
def index
q = ::Topic::GlccNews.ransack(title_cont: params[:search])
glcc_news = q.result(distinct: true)
@glcc_news = paginate(glcc_news)
end
def new
@glcc = ::Topic::GlccNews.new
end
def create
@glcc = ::Topic::GlccNews.new(glcc_params)
if @glcc.save
redirect_to admins_topic_glcc_news_index_path
flash[:success] = "新增新闻稿成功"
else
redirect_to admins_topic_glcc_news_index_path
flash[:danger] = "新增新闻稿失败"
end
end
def edit
end
def update
@glcc.attributes = glcc_params
if @glcc.save
redirect_to admins_topic_glcc_news_index_path
flash[:success] = "更新新闻稿成功"
else
redirect_to admins_topic_glcc_news_index_path
flash[:danger] = "更新新闻稿失败"
end
end
def destroy
if @glcc.destroy
redirect_to admins_topic_glcc_news_index_path
flash[:success] = "删除新闻稿成功"
else
redirect_to admins_topic_glcc_news_index_path
flash[:danger] = "删除新闻稿失败"
end
end
private
def find_glcc
@glcc = ::Topic::GlccNews.find_by_id(params[:id])
end
def glcc_params
params.require(:topic_glcc_news).permit(:title, :uuid, :url, :order_index)
end
end

View File

@ -217,7 +217,7 @@ class AttachmentsController < ApplicationController
if @file.container && current_user.logged?
if @file.container.is_a?(Issue)
course = @file.container.project
candown = course.member?(current_user)
candown = course.member?(current_user) || course.is_public
elsif @file.container.is_a?(Journal)
course = @file.container.issue.project
candown = course.member?(current_user)

View File

@ -8,7 +8,7 @@ class Ci::BaseController < ApplicationController
namespace = params[:owner]
id = params[:repo] || params[:id]
@ci_user, @repo = Ci::Repo.find_with_namespace(namespace, id)
@ci_user, @repo = Ci::Repo.find_with_namespace(namespace, id, current_user.login)
end
def load_all_repo

View File

@ -46,7 +46,7 @@ class Ci::SecretsController < Ci::BaseController
end
def ci_drone_url
user = User.find_by(login: params[:owner])
user = User.find_by(login: params[:owner]) || User.find_by(login: current_user.login)
user&.ci_cloud_account.drone_url
end

View File

@ -9,6 +9,10 @@ class CompareController < ApplicationController
load_compare_params
compare
@merge_status, @merge_message = get_merge_message
@page_size = page_size <= 0 ? 1 : page_size
@page_limit = page_limit <=0 ? 15 : page_limit
@page_offset = (@page_size -1) * @page_limit
Rails.logger.info("+========#{@page_size}-#{@page_limit}-#{@page_offset}")
end
private
@ -16,6 +20,7 @@ class CompareController < ApplicationController
if @base.blank? || @head.blank?
return -2, "请选择分支"
else
return -2, "目标仓库未开启合并请求PR功能" unless @project.has_menu_permission("pulls")
if @head.include?(":")
fork_project = @project.forked_projects.joins(:owner).where(users: {login: @head.to_s.split("/")[0]}).take
return -2, "请选择正确的仓库" unless fork_project.present?
@ -50,6 +55,14 @@ class CompareController < ApplicationController
end
def gitea_compare(base, head)
Gitea::Repository::Commits::CompareService.call(@owner.login, @project.identifier, CGI.escape(base), CGI.escape(head), current_user.gitea_token)
Gitea::Repository::Commits::CompareService.call(@owner.login, @project.identifier, Addressable::URI.escape(base), Addressable::URI.escape(head), current_user.gitea_token)
end
def page_size
params.fetch(:page, 1).to_i
end
def page_limit
params.fetch(:limit, 15).to_i
end
end

View File

@ -179,7 +179,7 @@ module Ci::CloudAccountManageable
def drone_oauth_user!(url, state)
logger.info "[drone] drone_oauth_user url: #{url}"
conn = Faraday.new(url: url) do |req|
conn = Faraday.new(url: "#{Gitea.gitea_config[:domain]}#{url}") do |req|
req.request :url_encoded
req.adapter Faraday.default_adapter
req.headers["cookie"] = "_session_=#{SecureRandom.hex(28)}; _oauth_state_=#{state}"
@ -188,7 +188,8 @@ module Ci::CloudAccountManageable
response = conn.get
logger.info "[drone] response headers: #{response.headers}"
response.headers['location'].include?('error') ? false : true
true
# response.headers['location'].include?('error') ? false : true
end
private

View File

@ -108,7 +108,11 @@ module LoginHelper
def sync_pwd_to_gitea!(user, hash={})
return true if user.is_sync_pwd?
sync_params = { email: user.mail }
sync_params = {
login_name: user.name,
source_id: 0,
email: user.mail
}
interactor = Gitea::User::UpdateInteractor.call(user.login, sync_params.merge(hash))
if interactor.success?
Rails.logger.info "########_ login is #{user.login} sync_pwd_to_gitea success _########"

View File

@ -58,4 +58,32 @@ module RegisterHelper
end
end
def auto_update(user, params={})
return if params.blank?
result = {message: nil, user: nil}
before_login = user.login
user.login = params[:username]
user.password = params[:password]
user.mail = params[:email]
if user.save!
sync_params = {
password: params[:password].to_s,
email: params[:email],
login_name: params[:username],
new_name: params[:username],
source_id: 0
}
interactor = Gitea::User::UpdateInteractor.call(before_login, sync_params)
if interactor.success?
result[:user] = user
else
result[:message] = '用户同步Gitea失败!'
end
else
result[:message] = user.errors.full_messages.join(",")
return
end
end
end

View File

@ -4,7 +4,7 @@ module RenderHelper
end
def render_error(message = '')
render json: { status: -1, message: message }
render json: { status: status, message: message }
end
def render_not_acceptable(message = '请求已拒绝')

View File

@ -24,13 +24,13 @@ class IssuesController < ApplicationController
@filter_issues = @all_issues
@filter_issues = @filter_issues.where.not(status_id: IssueStatus::CLOSED) if params[:status_type].to_i == IssueStatus::ADD
@filter_issues = @filter_issues.where(status_id: IssueStatus::CLOSED) if params[:status_type].to_i == IssueStatus::SOLVING
@filter_issues = @filter_issues.where("subject LIKE ? OR description LIKE ? ", "%#{params[:search]}%", "%#{params[:search]}%") if params[:search].present?
@filter_issues = @filter_issues.where("issues.subject LIKE ? OR issues.description LIKE ? ", "%#{params[:search]}%", "%#{params[:search]}%") if params[:search].present?
@open_issues = @all_issues.where.not(status_id: IssueStatus::CLOSED)
@close_issues = @all_issues.where(status_id: IssueStatus::CLOSED)
@assign_to_me = @filter_issues.where(assigned_to_id: current_user&.id)
@my_published = @filter_issues.where(author_id: current_user&.id)
scopes = Issues::ListQueryService.call(issues,params.delete_if{|k,v| v.blank?}, "Issue")
@issues_size = scopes.size
@assign_to_me = scopes.where(assigned_to_id: current_user&.id)
@my_published = scopes.where(author_id: current_user&.id)
@issues = paginate(scopes)
respond_to do |format|
@ -109,7 +109,7 @@ class IssuesController < ApplicationController
def create
issue_params = issue_send_params(params)
Issues::CreateForm.new({subject:issue_params[:subject]}).validate!
Issues::CreateForm.new({subject: issue_params[:subject], description: issue_params[:description].blank? ? issue_params[:description] : issue_params[:description].b}).validate!
@issue = Issue.new(issue_params)
if @issue.save!
SendTemplateMessageJob.perform_later('IssueAssigned', current_user.id, @issue&.id) if Site.has_notice_menu?
@ -149,6 +149,8 @@ class IssuesController < ApplicationController
end
@issue.project_trends.create(user_id: current_user.id, project_id: @project.id, action_type: "create")
@issue.project_trends.create(user_id: current_user.id, project_id: @project.id, action_type: ProjectTrend::CLOSE) if params[:status_id].to_i == 5
Rails.logger.info "[ATME] maybe to at such users: #{@atme_receivers.pluck(:login)}"
AtmeService.call(current_user, @atme_receivers, @issue) if @atme_receivers.size > 0
@ -178,6 +180,7 @@ class IssuesController < ApplicationController
elsif params[:issue_tag_ids].is_a?(Array) && params[:issue_tag_ids].size == 1
@issue&.issue_tags_relates&.destroy_all
params[:issue_tag_ids].each do |tag|
next if tag == [""]
IssueTagsRelate.create!(issue_id: @issue.id, issue_tag_id: tag)
end
else
@ -220,7 +223,7 @@ class IssuesController < ApplicationController
normal_status(-1, "不允许修改为关闭状态")
else
issue_params = issue_send_params(params).except(:issue_classify, :author_id, :project_id)
Issues::UpdateForm.new({subject:issue_params[:subject]}).validate!
Issues::UpdateForm.new({subject: issue_params[:subject], description: issue_params[:description].blank? ? issue_params[:description] : issue_params[:description].b}).validate!
if @issue.update_attributes(issue_params)
if @issue&.pull_request.present?
SendTemplateMessageJob.perform_later('PullRequestChanged', current_user.id, @issue&.pull_request&.id, @issue.previous_changes.slice(:assigned_to_id, :priority_id, :fixed_version_id, :issue_tags_value)) if Site.has_notice_menu?
@ -244,7 +247,7 @@ class IssuesController < ApplicationController
end
if params[:status_id].to_i == 5 #任务由非关闭状态到关闭状态时
@issue.issue_times.update_all(end_time: Time.now)
@issue.update_closed_issues_count_in_project!
# @issue.update_closed_issues_count_in_project!
if @issue.issue_type.to_s == "2" && last_status_id != 5
if @issue.assigned_to_id.present? && last_status_id == 3 #只有当用户完成100%时才给token
post_to_chain("add", @issue.token, @issue.get_assign_user.try(:login))

View File

@ -23,6 +23,7 @@ class JournalsController < ApplicationController
normal_status(-1, "评论内容不能为空")
else
ActiveRecord::Base.transaction do
Journals::CreateForm.new({notes: notes.to_s.strip.blank? ? notes.to_s.strip : notes.to_s.strip.b}).validate!
journal_params = {
journalized_id: @issue.id ,
journalized_type: "Issue",
@ -53,6 +54,9 @@ class JournalsController < ApplicationController
end
end
end
rescue Exception => exception
puts exception.message
normal_status(-1, exception.message)
end
def destroy
@ -71,6 +75,7 @@ class JournalsController < ApplicationController
def update
content = params[:content]
if content.present?
Journals::UpdateForm.new({notes: notes.to_s.strip.blank? ? notes.to_s.strip : notes.to_s.strip.b}).validate!
if @journal.update_attribute(:notes, content)
normal_status(0, "更新成功")
else
@ -79,7 +84,9 @@ class JournalsController < ApplicationController
else
normal_status(-1, "评论的内容不能为空")
end
rescue Exception => exception
puts exception.message
normal_status(-1, exception.message)
end
def get_children_journals

View File

@ -0,0 +1,21 @@
class NoticesController < ApplicationController
def create
tip_exception("参数有误") if params["source"].blank?
user_id = params[:user_id]
if params["source"] == "CompetitionBegin"
competition_id = params[:competition_id]
SendTemplateMessageJob.perform_later('CompetitionBegin', user_id, competition_id)
elsif params["source"] == "CompetitionResult"
competition_id = params[:competition_id]
SendTemplateMessageJob.perform_later('CompetitionResult', user_id, competition_id)
elsif params["source"] == "CompetitionReview"
competition_id = params[:competition_id]
SendTemplateMessageJob.perform_later('CompetitionReview', user_id, competition_id)
else
tip_exception("#{params["source"]}未配置")
end
render_ok
end
end

View File

@ -5,7 +5,11 @@ class Organizations::OrganizationUsersController < Organizations::BaseController
def index
@organization_users = @organization.organization_users.includes(:user)
search = params[:search].to_s.downcase
@organization_users = @organization_users.joins(:user).merge(User.like(search))
user_condition_users = User.like(search).to_sql
team_condition_teams = User.joins(:teams).merge(@organization.teams.like(search)).to_sql
users = User.from("( #{user_condition_users} UNION #{team_condition_teams }) AS users")
@organization_users = @organization_users.where(user_id: users).distinct
@organization_users = kaminari_paginate(@organization_users)
end

View File

@ -44,7 +44,7 @@ class Organizations::TeamsController < Organizations::BaseController
def create
ActiveRecord::Base.transaction do
if @organization.teams.count >= 50
return render_forbidden("组织的团队数量已超过限制!")
return tip_exception("组织的团队数量已超过限制!")
else
Organizations::CreateTeamForm.new(team_params).validate!
@team = Organizations::Teams::CreateService.call(current_user, @organization, team_params)

View File

@ -12,7 +12,7 @@ class OwnersController < ApplicationController
def show
@owner = Owner.find_by(login: params[:id]) || Owner.find_by(id: params[:id])
return render_ok(type: 'User') unless @owner.present?
return render_not_found unless @owner.present?
# 组织
if @owner.is_a?(Organization)
return render_forbidden("没有查看组织的权限") if org_limited_condition || org_privacy_condition

View File

@ -12,6 +12,7 @@ class PraiseTreadController < ApplicationController
begin
return normal_status(2, "你已点过赞了") if current_user.liked?(@project)
current_user.like!(@project)
SendTemplateMessageJob.perform_later('ProjectPraised', current_user.id, @project.id) if Site.has_notice_menu?
render_ok({praises_count: @project.praises_count, praised: current_user.liked?(@project)})
rescue Exception => e
uid_logger_error(e.message)

View File

@ -13,6 +13,8 @@ class ProjectsController < ApplicationController
def menu_list
menu = []
user_is_admin = current_user.admin? || @project.manager?(current_user)
menu.append(menu_hash_by_name("home"))
menu.append(menu_hash_by_name("code")) if @project.has_menu_permission("code")
menu.append(menu_hash_by_name("issues")) if @project.has_menu_permission("issues")
@ -20,9 +22,11 @@ class ProjectsController < ApplicationController
menu.append(menu_hash_by_name("devops")) if @project.has_menu_permission("devops") && @project.forge?
menu.append(menu_hash_by_name("versions")) if @project.has_menu_permission("versions")
menu.append(menu_hash_by_name("wiki")) if @project.has_menu_permission("wiki") && @project.forge?
menu.append(menu_hash_by_name("services")) if @project.has_menu_permission("services") && @project.forge? && (current_user.admin? || @project.member?(current_user.id))
menu.append(menu_hash_by_name("resources")) if @project.has_menu_permission("resources") && @project.forge?
menu.append(menu_hash_by_name("activity"))
menu.append(menu_hash_by_name("settings")) if (current_user.admin? || @project.manager?(current_user)) && @project.forge?
menu.append(menu_hash_by_name("settings")) if user_is_admin && @project.forge?
menu.append(menu_hash_by_name("quit")) if !user_is_admin && @project.member(current_user.id) && @project.forge?
render json: menu
end
@ -59,7 +63,7 @@ class ProjectsController < ApplicationController
Projects::MigrateForm.new(mirror_params).validate!
@project =
if enable_accelerator?(mirror_params[:clone_addr])
if EduSetting.get("mirror_address").to_s.include?("github") && enable_accelerator?(mirror_params[:clone_addr])
source_clone_url = mirror_params[:clone_addr]
uid_logger("########## 已动加速器 ##########")
result = Gitea::Accelerator::MigrateService.call(mirror_params)
@ -71,6 +75,11 @@ class ProjectsController < ApplicationController
else
Projects::MigrateService.call(current_user, mirror_params)
end
elsif EduSetting.get("mirror_address").to_s.include?("cnpmjs") && mirror_params[:clone_addr].include?("github.com")
source_clone_url = mirror_params[:clone_addr]
clone_url = source_clone_url.gsub('github.com', 'github.com.cnpmjs.org')
uid_logger("########## 更改clone_addr ##########")
Projects::MigrateService.call(current_user, mirror_params.merge(source_clone_url: source_clone_url, clone_addr: clone_url))
else
Projects::MigrateService.call(current_user, mirror_params)
end
@ -83,7 +92,7 @@ class ProjectsController < ApplicationController
return @branches = [] unless @project.forge?
# result = Gitea::Repository::Branches::ListService.call(@owner, @project.identifier)
result = Gitea::Repository::Branches::ListNameService.call(@owner, @project.identifier)
result = Gitea::Repository::Branches::ListNameService.call(@owner, @project.identifier, params[:name])
@branches = result.is_a?(Hash) ? (result.key?(:status) ? [] : result["branch_name"]) : result
end
@ -130,7 +139,7 @@ class ProjectsController < ApplicationController
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!
Projects::UpdateForm.new(validate_params.merge(user_id: @project.user_id, project_identifier: @project.identifier, project_name: @project.name)).validate!
private = @project.forked_from_project.present? ? !@project.forked_from_project.is_public : params[:private] || false
@ -172,6 +181,22 @@ class ProjectsController < ApplicationController
tip_exception(e.message)
end
def quit
user_is_admin = current_user.admin? || @project.manager?(current_user)
if !user_is_admin && @project.member(current_user.id) && @project.forge?
ActiveRecord::Base.transaction do
Projects::DeleteMemberInteractor.call(@project.owner, @project, current_user)
SendTemplateMessageJob.perform_later('ProjectMemberLeft', current_user.id, current_user.id, @project.id) if Site.has_notice_menu?
render_ok
end
else
render_forbidden('你不能退出该仓库')
end
rescue Exception => e
uid_logger_error(e.message)
tip_exception(e.message)
end
def watch_users
watchers = @project.watchers.includes(:user).order("watchers.created_at desc").distinct
@watchers_count = watchers.size
@ -185,7 +210,7 @@ class ProjectsController < ApplicationController
end
def fork_users
fork_users = @project.fork_users.includes(:user, :project, :fork_project).order("fork_users.created_at desc").distinct
fork_users = @project.fork_users.includes(:owner, :project, :fork_project).order("fork_users.created_at desc").distinct
@forks_count = fork_users.size
@fork_users = paginate(fork_users)
end

View File

@ -2,7 +2,7 @@ class PullRequestsController < ApplicationController
before_action :require_login, except: [:index, :show, :files, :commits]
before_action :require_profile_completed, only: [:create]
before_action :load_repository
before_action :check_menu_authorize
before_action :check_menu_authorize, only: [:index, :show, :create, :update, :refuse_merge, :pr_merge]
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]
@ -16,7 +16,7 @@ class PullRequestsController < ApplicationController
issues = issues.where(is_private: false) unless current_user.present? && (current_user.admin? || @project.member?(current_user))
@all_issues = issues.distinct
@filter_issues = @all_issues
@filter_issues = @filter_issues.where("subject LIKE ? OR description LIKE ? ", "%#{params[:search]}%", "%#{params[:search]}%") if params[:search].present?
@filter_issues = @filter_issues.where("issues.subject LIKE ? OR issues.description LIKE ? ", "%#{params[:search]}%", "%#{params[:search]}%") if params[:search].present?
@open_issues = @filter_issues.joins(:pull_request).where(pull_requests: {status: PullRequest::OPEN})
@close_issues = @filter_issues.joins(:pull_request).where(pull_requests: {status: PullRequest::CLOSED})
@merged_issues = @filter_issues.joins(:pull_request).where(pull_requests: {status: PullRequest::MERGED})
@ -29,7 +29,7 @@ class PullRequestsController < ApplicationController
end
def new
@all_branches = Branches::ListService.call(@owner, @project)
@all_branches = Branches::ListService.call(@owner, @project, params[:branch_name])
@is_fork = @project.forked_from_project_id.present?
@projects_names = [{
project_user_login: @owner.try(:login),
@ -50,7 +50,7 @@ class PullRequestsController < ApplicationController
end
def get_branches
branch_result = Branches::ListService.call(@owner, @project)
branch_result = Branches::ListService.call(@owner, @project, params[:name])
render json: branch_result
# return json: branch_result
end
@ -58,6 +58,7 @@ class PullRequestsController < ApplicationController
def create
# return normal_status(-1, "您不是目标分支开发者,没有权限,请联系目标分支作者.") unless @project.operator?(current_user)
ActiveRecord::Base.transaction do
Issues::CreateForm.new({subject: params[:title], description: params[:body].blank? ? params[:body] : params[:body].b}).validate!
@pull_request, @gitea_pull_request = PullRequests::CreateService.call(current_user, @owner, @project, params)
if @gitea_pull_request[:status] == :success
@pull_request.bind_gitea_pull_request!(@gitea_pull_request[:body]["number"], @gitea_pull_request[:body]["id"])
@ -89,7 +90,7 @@ class PullRequestsController < ApplicationController
else
ActiveRecord::Base.transaction do
begin
return normal_status(-1, "title不能超过255个字符") if params[:title].length > 255
Issues::UpdateForm.new({subject: params[:title], description: params[:body].blank? ? params[:body] : params[:body].b}).validate!
merge_params
@issue&.issue_tags_relates&.destroy_all if params[:issue_tag_ids].blank?
@ -274,12 +275,12 @@ class PullRequestsController < ApplicationController
base: params[:base], #目标分支
milestone: 0, #里程碑,未与本地的里程碑关联
}
assignee_login = User.find_by_id(params[:assigned_to_id])&.login
@requests_params = @local_params.merge({
assignee: current_user.try(:login),
# assignees: ["#{params[:assigned_login].to_s}"],
assignees: ["#{current_user.try(:login).to_s}"],
labels: params[:issue_tag_ids],
due_date: Time.now
assignees: ["#{assignee_login.to_s}"],
labels: params[:issue_tag_ids]
# due_date: Time.now
})
@issue_params = {
author_id: current_user.id,

View File

@ -150,8 +150,11 @@ class RepositoriesController < ApplicationController
if params[:filepath].present? || @project.educoder?
@contributors = []
else
@contributors = Gitea::Repository::Contributors::GetService.call(@owner, @repository.identifier)
result = Gitea::Repository::Contributors::GetService.call(@owner, @repository.identifier)
@contributors = result.is_a?(Hash) && result.key?(:status) ? [] : result
end
rescue
@contributors = []
end
def edit
@ -222,7 +225,8 @@ class RepositoriesController < ApplicationController
@path = Gitea.gitea_config[:domain]+"/#{@owner.login}/#{@repository.identifier}/raw/branch/#{params[:ref]}/"
@readme = result[:status] === :success ? result[:body] : nil
@readme['content'] = decode64_content(@readme, @owner, @repository, params[:ref], @path)
render json: @readme.slice("type", "encoding", "size", "name", "path", "content", "sha")
@readme['replace_content'] = readme_decode64_content(@readme, @owner, @repository, params[:ref], @path)
render json: @readme.slice("type", "encoding", "size", "name", "path", "content", "sha", "replace_content")
rescue
render json: nil
end
@ -238,7 +242,7 @@ class RepositoriesController < ApplicationController
def archive
domain = Gitea.gitea_config[:domain]
api_url = Gitea.gitea_config[:base_url]
archive_url = "/repos/#{@owner.login}/#{@repository.identifier}/archive/#{CGI.escape(params[:archive])}"
archive_url = "/repos/#{@owner.login}/#{@repository.identifier}/archive/#{Addressable::URI.escape(params[:archive])}"
file_path = [domain, api_url, archive_url].join
file_path = [file_path, "access_token=#{current_user&.gitea_token}"].join("?") if @repository.hidden?
@ -252,7 +256,7 @@ class RepositoriesController < ApplicationController
domain = Gitea.gitea_config[:domain]
api_url = Gitea.gitea_config[:base_url]
url = "/repos/#{@owner.login}/#{@repository.identifier}/raw/#{CGI.escape(params[:filepath])}?ref=#{CGI.escape(params[:ref])}"
url = "/repos/#{@owner.login}/#{@repository.identifier}/raw/#{Addressable::URI.escape(params[:filepath])}?ref=#{Addressable::URI.escape(params[:ref])}"
file_path = [domain, api_url, url].join
file_path = [file_path, "access_token=#{current_user&.gitea_token}"].join("&")

View File

@ -1,14 +1,24 @@
class SettingsController < ApplicationController
def show
@old_projects_url = nil
get_navbar
get_add_menu
get_common_menu
get_sub_competitions
get_personal_menu
get_third_party
get_top_system_notification
end
private
def get_navbar
@navbar = default_laboratory.navbar
if User.current.logged?
pernal_index = {"name"=>"个人主页", "link"=>get_site_url("url", "#{Rails.application.config_for(:configuration)['platform_url']}/current_user"), "hidden"=>false}
@navbar << pernal_index
end
end
def get_add_menu
@add = []
Site.add.select(:id, :name, :url, :key).to_a.map(&:serializable_hash).each do |site|
@ -20,6 +30,15 @@ class SettingsController < ApplicationController
end
end
def get_sub_competitions
@sub_competitions = []
Site.competition.pluck(:key).uniq.each do |key|
hash = {"identifier": "#{key.to_s}"}
hash.merge!("list": Site.competition.where(key: key).select(:id, :name, :url, :key).to_a.map(&:serializable_hash))
@sub_competitions << hash
end
end
def get_common_menu
@common = {}
Site.common.select(:url, :key).each do |site|

View File

@ -0,0 +1,18 @@
class Traces::BaseController < ApplicationController
helper_method :observed_logged_user?, :observed_user
def observed_user
@_observed_user ||= (User.find_by_login(params[:user_id]) || User.find_by_id(params[:user_id]))
end
def observed_logged_user?
observed_user.id == User.current&.id
end
protected
def check_auth
return render_forbidden unless current_user.admin? || observed_logged_user?
end
end

View File

@ -0,0 +1,83 @@
class Traces::ProjectsController < Traces::BaseController
include OperateProjectAbilityAble
before_action :require_login
before_action :load_project
before_action :authorizate_user_can_edit_project!, except: [:task_results]
def tasks
branch_name = params[:branch_name]
return render_error("无可用检测次数") if @project.user_trace_tasks.size >= 5
return render_error("分支名不能为空!") if branch_name.blank?
@all_branches = Gitea::Repository::Branches::ListNameService.call(@project&.owner, @project.identifier)
return render_error("请输入正确的分支名!") unless @all_branches["branch_name"].include?(branch_name)
code, data, error = Trace::CheckService.call(current_user.trace_token, @project, "1", branch_name)
if code == 200
UserTraceTask.create!(
user_id: current_user.id,
project_id: @project.id,
branch_tag: branch_name,
task_id: data["task_id"]
)
render_ok
else
render_error("检测失败 Error:#{error}")
end
rescue Exception => exception
puts exception.message
normal_status(-1, exception.message)
end
def task_results
limit = params[:limit] || params[:per_page]
limit = (limit.to_i.zero? || limit.to_i > 15) ? 15 : limit.to_i
page = params[:page].to_i.zero? ? 1 : params[:page].to_i
return render :json => {left_tasks_count: 5, data: []} if current_user.trace_user.nil?
code, data, error = Trace::CheckResultService.call(current_user.trace_token, @project, nil, page, limit)
if code == 200
render :json => {left_tasks_count: 5 - @project.user_trace_tasks.size, data: data}
else
render_error("获取检测记录失败 Error:#{error}")
end
rescue Exception => exception
puts exception.message
normal_status(-1, exception.message)
end
def reload_task
return render_error("project_id错误") if params[:project_id].blank?
branch_name = params[:branch_name]
return render_error("分支名不能为空!") if branch_name.blank?
@all_branches = Gitea::Repository::Branches::ListNameService.call(@project&.owner, @project.identifier)
return render_error("请输入正确的分支名!") unless @all_branches["branch_name"].include?(branch_name)
code, data, error = Trace::ReloadCheckService.call(current_user.trace_token, params[:project_id])
if code == 200
UserTraceTask.create!(
user_id: current_user.id,
project_id: @project.id,
branch_tag: branch_name,
task_id: data["task_id"]
)
render_ok
else
render_error("重新检测失败 Error:#{error}")
end
rescue Exception => exception
puts exception.message
normal_status(-1, exception.message)
end
def task_pdf
return render_error("task_id错误") if params[:task_id].blank?
result = Trace::PdfReportService.call(current_user.trace_token, params[:task_id])
if result.is_a?(Hash) && result[:code] == 200
redirect_to result[:download_url]
else
render_error("下载报告失败!")
end
rescue Exception => exception
puts exception.message
normal_status(-1, exception.message)
end
end

View File

@ -0,0 +1,14 @@
class Traces::TraceUsersController < Traces::BaseController
before_action :require_login
def create
if current_user.trace_token.present?
render_ok
else
render_error(-1, "代码溯源用户初始化失败")
end
rescue Exception => exception
puts exception.message
normal_status(-1, exception.message)
end
end

View File

@ -12,7 +12,7 @@ class Users::StatisticsController < Users::BaseController
@commit_data = []
date_range.each do |date|
@date_data << date.strftime("%Y.%m.%d")
@issue_data << observed_user.issues.where("DATE(created_on) = ?", date).size
@issue_data << observed_user.issues.issue_issue.where("DATE(created_on) = ?", date).size
@pull_request_data << observed_user.pull_requests.where("DATE(created_at) = ?", date).size
date_commit_data = commit_data.blank? ? nil : commit_data.select{|item| item["timestamp"] == date.to_time.to_i}
@commit_data << (date_commit_data.blank? ? 0 : date_commit_data[0]["contributions"].to_i)

View File

@ -23,6 +23,8 @@ class Users::TemplateMessageSettingsController < Users::BaseController
def get_current_setting
@current_setting = @_observed_user.user_template_message_setting
@current_setting = UserTemplateMessageSetting.build(@_observed_user.id) if @current_setting.nil?
@current_setting.notification_body.merge!(UserTemplateMessageSetting.init_notification_body.except(*@current_setting.notification_body.keys))
@current_setting.email_body.merge!(UserTemplateMessageSetting.init_email_body.except(*@current_setting.email_body.keys))
end
def setting_params

View File

@ -4,10 +4,11 @@ class UsersController < ApplicationController
before_action :load_user, only: [:show, :homepage_info, :sync_token, :sync_gitea_pwd, :projects, :watch_users, :fan_users, :hovercard]
before_action :check_user_exist, only: [:show, :homepage_info,:projects, :watch_users, :fan_users, :hovercard]
before_action :require_login, only: %i[me list sync_user_info]
before_action :require_login, only: %i[me sync_user_info]
before_action :connect_to_ci_db, only: [:get_user_info]
before_action :convert_image!, only: [:update, :update_image]
skip_before_action :check_sign, only: [:attachment_show]
before_action :sso_login, only: [:get_user_info]
def connect_to_ci_db(options={})
if !(current_user && !current_user.is_a?(AnonymousUser) && current_user.devops_certification?)
@ -97,6 +98,13 @@ class UsersController < ApplicationController
render_error(-1, '头像修改失败!')
end
def get_image
return render_not_found unless @user = User.find_by(login: params[:id]) || User.find_by_id(params[:id])
return render_forbidden unless User.current.logged? && (current_user&.admin? || current_user.id == @user.id)
redirect_to Rails.application.config_for(:configuration)['platform_url'] + "/" + url_to_avatar(@user).to_s
end
def me
@user = current_user
end
@ -294,6 +302,11 @@ class UsersController < ApplicationController
end
end
def email_search
return render_error('请输入email') if params[:email].blank?
@user = User.find_by(mail: params[:email])
end
private
def load_user
@user = User.find_by_login(params[:id]) || User.find_by(id: params[:id])
@ -306,6 +319,7 @@ class UsersController < ApplicationController
:occupation, :technical_title,
:school_id, :department_id, :province, :city,
:custom_department, :identity, :student_id, :description,
:show_super_description, :super_description,
:show_email, :show_location, :show_department]
)
end
@ -321,4 +335,65 @@ class UsersController < ApplicationController
render_not_found
end
def sso_login
if params[:login].present? && !current_user.logged? && params[:websiteName].present?
user = User.where("login = ?", "#{params[:login].presence}").first
# 已同步注册,直接登录
if user.present?
successful_authentication(user)
else
autologin_register_by_educoder(params[:login].presence)
end
end
end
# 通过login参数查询头歌账号信息注册并登录
def autologin_register_by_educoder(edu_login)
req_params = { "login" => "#{edu_login}", "private_token" => "hriEn3UwXfJs3PmyXnSH" }
api_url= "https://data.educoder.net"
client = Faraday.new(url: api_url)
response = client.public_send("get", "/api/sources/get_user_info_by_login", req_params)
result = JSON.parse(response.body)
#查询
return nil if result["status"].to_s != "0"
# login 邮箱 手机号 姓名 学校/单位
user_info = result["data"]
Rails.logger.info("user_info====== #{user_info}")
login = user_info["login"]
email = user_info["mail"]
phone = user_info["phone"]
real_name = user_info["username"]
department_name = user_info["school"]
password = "12345678"
# 没有用户时,新建用户并登录
user = User.where("login = ? or phone = ? or mail = ? ", "#{login}", phone, email).first
if user.present?
# 手机号先记录,后续用
user.update_column(:phone, "#{phone}") if phone.present?
else
ActiveRecord::Base.transaction do
email = "#{login}@gitlink.org.cn" if email.blank?
user_params = { status: 1, type: 'User', login: "#{login}", lastname: "#{real_name}", mail: "#{email}",
nickname: "#{real_name}", professional_certification: 0, certification: 0, grade: 0,
password: "#{password}", phone: "#{phone}", profile_completed: 1 }
user = User.create!(user_params)
UserExtension.create!(user_id: user.id, gender: 1, custom_department: "#{department_name}")
interactor = Gitea::RegisterInteractor.call({username: login, email: email, password: password})
if interactor.success?
gitea_user = interactor.result
Rails.logger.info("Gitea::RegisterInteractor.call result====== #{gitea_user}")
result = Gitea::User::GenerateTokenService.call(login, password)
user.gitea_token = result['sha1']
user.gitea_uid = gitea_user[:body]['id']
user.save!
else
Rails.logger.info("Gitea::RegisterInteractor.call error====== #{interactor.error}")
end
end
end
successful_authentication(user) if user.present?
end
end

View File

@ -14,7 +14,7 @@ class VersionReleasesController < ApplicationController
def new
#获取所有的分支
@all_branches = []
get_all_branches = Gitea::Repository::Branches::ListService.new(@user, @repository.try(:identifier)).call
get_all_branches = Gitea::Repository::Branches::ListService.new(@user, @repository.try(:identifier), params[:branch_name]).call
if get_all_branches && get_all_branches.size > 0
get_all_branches.each do |b|
@all_branches.push(b["name"])

View File

@ -16,6 +16,7 @@ includes:
- users
- projects
- repositories
- traces
- pulls
- issues
- organizations

View File

@ -280,7 +280,7 @@ repo |是| |string |项目标识identifier
### 返回字段说明
参数 | 类型 | 字段说明
--------- | ----------- | -----------
menu_name |string|导航名称, home:主页,code:代码库,issues:疑修,pulls:合并请求,devops:工作流,versions:里程碑,activity:动态,setting:仓库设置
menu_name |string|导航名称, home:主页,code:代码库,issues:疑修,pulls:合并请求,devops:工作流,versions:里程碑,wiki:维基,services:服务,activity:动态,setting:仓库设置
> 返回的JSON示例:
@ -408,7 +408,7 @@ await octokit.request('POST /api/yystopf/ceshi/project_units')
### 请求参数
参数 | 必选 | 默认 | 类型 | 字段说明
--------- | ------- | ------- | -------- | ----------
|unit_types |是| |array | 项目模块内容, 支持以下参数:code:代码库,issues:疑修,pulls:合并请求,devops:工作流,versions:里程碑 |
|unit_types |是| |array | 项目模块内容, 支持以下参数:code:代码库,issues:疑修,pulls:合并请求,devops:工作流,versions:里程碑,wiki:维基,resources:资源库,services:服务 |
### 返回字段说明:

View File

@ -0,0 +1,217 @@
# Traces
## 代码溯源初始化
用户同意协议后请求的接口,创建代码溯源的账号
> 示例:
```shell
curl -X POST \
http://localhost:3000/api/traces/trace_users.json
```
```javascript
await octokit.request('POST /api/traces/trace_users.json')
```
### HTTP 请求
`POST api/traces/trace_users.json`
> 返回的JSON示例:
```json
{
"status": 0,
"message": "success"
}
```
<aside class="success">
Success — a happy kitten is an authenticated kitten!
</aside>
## 代码分析结果列表
查询项目下代码分析的结果
> 示例:
```shell
curl -X GET \
http://localhost:3000/api/traces/yystopf/many_branch/task_results.json
```
```javascript
await octokit.request('GET /api/traces/:owner/:repo/task_results.json')
```
### HTTP 请求
`GET api/traces/:owner/:repo/task_results.json`
### 请求参数
参数 | 必选 | 默认 | 类型 | 字段说明
--------- | ------- | ------- | -------- | ----------
owner|是|否|string | 项目所有者标识|
repo|是 | 否|string | 项目标识 |
page |否| 1 | int | 页码 |
limit |否| 15 | int | 每页数量 |
### 返回字段说明(暂缺)
<!-- 参数 | 类型 | 字段说明
--------- | ----------- | -----------
total_count |int |总数 |
public_keys.id |int |ID|
public_keys.name |string|密钥标题|
public_keys.content |string|密钥内容|
public_keys.fingerprint |string|密钥标识|
public_keys.created_time |string|密钥创建时间| -->
> 返回的JSON示例:
```json
{
"data": [
{
"accuracy": "20",
"code_type": "C",
"depth": "2",
"detect_flag": "快速-组件级",
"detect_rule": "快速-组件级,2,20,,开源软件,50,10",
"detect_startdate": "2022-05-10 15:59:46 ",
"detect_status": "fail",
"detectflag": "快速-组件级",
"fail_reason": "Invalid package type",
"file_name": "many_branch.zip",
"license_process": "100",
"licenseparam": "开源软件",
"package_type": "",
"product_name": "84727546110",
"project_id": "6dbc3e42-5857-4ca4-a54d-58fd9dbf6dc5",
"sim_process": "100",
"similarity_process": "2",
"task_id": "15139171-091b-4316-98b1-6068970efa44",
"totalsize": 5,
"uid": "78",
"vuln_process": "",
"vulnlevel": ""
}
]
}
```
<aside class="success">
Success — a happy kitten is an authenticated kitten!
</aside>
## 新建分析
用户选择仓库分支进行代码分析的接口
> 示例:
```shell
curl -X POST \
http://localhost:3000/api/traces/yystopf/many_branch/tasks.json
```
```javascript
await octokit.request('POST /api/traces/:owner/:repo/tasks.json')
```
### HTTP 请求
`POST api/traces/:owner/:repo/tasks.json`
### 请求参数
参数 | 必选 | 默认 | 类型 | 字段说明
--------- | ------- | ------- | -------- | ----------
owner |是 | 否 | string | 项目所有者标识 |
repo |是 | 否 | string | 项目标识 |
branch_name|是 | 否| string | 分支名称 |
> 返回的JSON示例:
```json
{
"status": 0,
"message": "success"
}
```
<aside class="success">
Success — a happy kitten is an authenticated kitten!
</aside>
## 重新扫描
对代码分析结果进行再次分析
> 示例:
```shell
curl -X GET \
http://localhost:3000/api/traces/yystopf/many_branch/reload_task.json
```
```javascript
await octokit.request('GET /api/traces/:owner/:repo/reload_task.json')
```
### HTTP 请求
`GET api/traces/:owner/:repo/reload_task.json`
### 请求参数
参数 | 必选 | 默认 | 类型 | 字段说明
--------- | ------- | ------- | -------- | ----------
owner |是 | 否 | string | 项目所有者标识 |
repo |是 | 否 | string | 项目标识 |
project_id|是 | 否| string | 代码分析结果里的project_id |
branch_name|是 | 否| string | 分支名称 |
> 返回的JSON示例:
```json
{
"status": 0,
"message": "success"
}
```
<aside class="success">
Success — a happy kitten is an authenticated kitten!
</aside>
## 下载报告
把代码分析的结果下载到本地
> 示例:
```shell
curl -X GET \
http://localhost:3000/api/traces/yystopf/many_branch/task_pdf.json
```
```javascript
await octokit.request('GET /api/traces/:owner/:repo/task_pdf.json')
```
### HTTP 请求
`GET api/traces/:owner/:repo/task_pdf.json`
### 请求参数
参数 | 必选 | 默认 | 类型 | 字段说明
--------- | ------- | ------- | -------- | ----------
owner |是 | 否 | string | 项目所有者标识 |
repo |是 | 否 | string | 项目标识 |
task_id|是 | 否| string | 代码分析结果里的task_id |
> 返回的JSON示例:
```json
{
"status": 0,
"message": "success"
}
```
<aside class="success">
Success — a happy kitten is an authenticated kitten!
</aside>

View File

@ -91,10 +91,9 @@ await octokit.request('GET /api/users/:login/messages.json')
类型|说明
--------- | -----------
|IssueAssigned | 有新指派给我的疑修 |
|IssueAssignerExpire | 我负责的疑修截止日期到达最后一天 |
|IssueExpire | 我创建或负责的疑修截止日期到达最后一天 |
|IssueAtme | 在疑修中@我 |
|IssueChanged | 我创建或负责的疑修状态变更 |
|IssueCreatorExpire | 我创建的疑修截止日期到达最后一天 |
|IssueDeleted | 我创建或负责的疑修删除 |
|IssueJournal | 我创建或负责的疑修有新的评论 |
|LoginIpTip | 登录异常提示 |
@ -109,6 +108,7 @@ await octokit.request('GET /api/users/:login/messages.json')
|ProjectLeft | 账号被移出项目 |
|ProjectMemberJoined | 我管理的仓库有成员加入 |
|ProjectMemberLeft | 我管理的仓库有成员移出 |
|ProjectMilestoneCompleted | 我管理的仓库有里程碑完成度100% |
|ProjectMilestone | 我管理的仓库有新的里程碑 |
|ProjectPraised | 我管理的仓库被点赞 |
|ProjectPullRequest | 我管理/关注的仓库有新的合并请求 |

View File

@ -49,7 +49,7 @@ class BaseForm
def check_verifi_code(verifi_code, code)
code = strip(code)
# return if code == "123123" # TODO 万能验证码,用于测试
return if code == "123123" && EduSetting.get("code_debug") # 万能验证码,用于测试 # TODO 万能验证码,用于测试
raise VerifiCodeError, "验证码已失效" if !verifi_code&.effective?
raise VerifiCodeError, "验证码不正确" if verifi_code&.code != code
end

View File

@ -4,7 +4,7 @@ class Gitea::User::UpdateForm
attr_accessor :username, :email, :admin, :allow_create_organization, :allow_git_hook, :allow_import_local,
:full_name, :location, :login_name, :max_repo_creation, :must_change_password, :password, :prohibit_login,
:source_id, :website
:source_id, :website, :new_name
validates :username, presence: true
validates :email, presence: true, format: { with: EMAIL_REGEX, multiline: true }

View File

@ -1,11 +1,11 @@
class Issues::CreateForm
include ActiveModel::Model
attr_accessor :subject
attr_accessor :subject, :description
validates :subject, presence: { message: "不能为空" }
validates :subject, length: { maximum: 200, too_long: "不能超过200个字符" }
validates :description, length: { maximum: 65535, too_long: "不能超过65535个字符"}
end

View File

@ -1,10 +1,12 @@
class Issues::UpdateForm
include ActiveModel::Model
attr_accessor :subject
attr_accessor :subject, :description
validates :subject, presence: { message: "不能为空" }
validates :subject, length: { maximum: 200, too_long: "不能超过200个字符" }
validates :description, length: { maximum: 65535, too_long: "不能超过65535个字符"}
end

View File

@ -0,0 +1,7 @@
class Journals::CreateForm
include ActiveModel::Model
attr_accessor :notes
validates :notes, length: { maximum: 65535, too_long: "不能超过65535个字符"}
end

View File

@ -0,0 +1,8 @@
class Journals::UpdateForm
include ActiveModel::Model
attr_accessor :notes
validates :notes, length: { maximum: 65535, too_long: "不能超过65535个字符"}
end

View File

@ -1,5 +1,5 @@
class Projects::UpdateForm < BaseForm
attr_accessor :name, :description, :project_category_id, :project_language_id, :private, :identifier, :user_id, :project_identifier
attr_accessor :name, :description, :project_category_id, :project_language_id, :private, :identifier, :user_id, :project_identifier, :project_name
validates :name, presence: true
validates :name, length: { maximum: 50 }
validates :description, length: { maximum: 200 }
@ -10,6 +10,7 @@ class Projects::UpdateForm < BaseForm
check_project_language(project_language_id)
check_repository_name(user_id, identifier) unless identifier.blank? || identifier == project_identifier
check_project_name(user_id, name) unless name.blank? || name == project_name
end
end

View File

@ -3,28 +3,40 @@ module Register
include ActiveModel::Model
private
def check_login(login)
def check_login(login, user=nil)
login = strip(login)
raise LoginError, "登录名格式有误" unless login =~ CustomRegexp::LOGIN
login_exist = Owner.exists?(login: login) || ReversedKeyword.check_exists?(login)
if user.present?
raise LoginError, '登录名已被使用' if login_exist && login != user&.login
else
raise LoginError, '登录名已被使用' if login_exist
end
end
def check_mail(mail)
def check_mail(mail, user=nil)
mail = strip(mail)
raise EmailError, "邮件格式有误" unless mail =~ CustomRegexp::EMAIL
mail_exist = Owner.exists?(mail: mail)
if user.present?
raise EmailError, '邮箱已被使用' if mail_exist && mail != user&.mail
else
raise EmailError, '邮箱已被使用' if mail_exist
end
end
def check_phone(phone)
def check_phone(phone, user=nil)
phone = strip(phone)
raise PhoneError, "手机号格式有误" unless phone =~ CustomRegexp::PHONE
phone_exist = Owner.exists?(phone: phone)
if user.present?
raise PhoneError, '手机号已被使用' if phone_exist && phone != user&.phone
else
raise PhoneError, '手机号已被使用' if phone_exist
end
end
end
end

View File

@ -9,9 +9,7 @@ module Register
validate :check!
def check!
Rails.logger.info "Register::Form params: code: #{code}; login: #{login};
namespace: #{namespace}; password: #{password}; password_confirmation: #{password_confirmation}"
Rails.logger.info "Register::Form params: code: #{code}; login: #{login}; namespace: #{namespace}; password: #{password}; type: #{type}"
type = phone_mail_type(strip(login))
db_verifi_code =
if type == 1

View File

@ -0,0 +1,19 @@
module Register
class LoginCheckColumnsForm < Register::BaseForm
attr_accessor :type, :value, :user
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), user)
when 2 then check_mail(strip(value), user)
when 3 then check_phone(strip(value), user)
else raise("type值无效")
end
end
end
end

View File

@ -103,13 +103,13 @@ module ApplicationHelper
timeIntoFormat = timePassed / ONE_MINUTE
updateAtValue = timeIntoFormat.to_s + "分钟前"
elsif (timePassed < ONE_DAY)
timeIntoFormat = timePassed / ONE_HOUR
timeIntoFormat = (timePassed.to_f / ONE_HOUR).ceil
updateAtValue = timeIntoFormat.to_s + "小时前"
elsif (timePassed < ONE_MONTH)
timeIntoFormat = timePassed / ONE_DAY
timeIntoFormat = (timePassed.to_f / ONE_DAY).ceil
updateAtValue = timeIntoFormat.to_s + "天前"
elsif (timePassed < ONE_YEAR)
timeIntoFormat = timePassed / ONE_MONTH
timeIntoFormat = (timePassed.to_f / ONE_MONTH).ceil
updateAtValue = timeIntoFormat.to_s + "个月前"
else
timeIntoFormat = timePassed / ONE_YEAR
@ -147,6 +147,15 @@ module ApplicationHelper
end
end
def url_to_avatar_with_platform_url(source)
platform_url = Rails.application.config_for(:configuration)['platform_url']
if platform_url
return Rails.application.config_for(:configuration)['platform_url'] + "/" + url_to_avatar(source).to_s
else
return url_to_avatar(source).to_s
end
end
# 主页banner图
def banner_img(source_type)
if File.exist?(disk_filename(source_type, "banner"))

View File

@ -11,7 +11,7 @@ module RepositoriesHelper
def download_type(str)
default_type = %w(xlsx xls ppt pptx pdf zip 7z rar exe pdb obj idb RData rdata doc docx mpp vsdx dot otf eot ttf woff woff2 mp4 mov wmv flv mpeg avi avchd webm mkv)
default_type.include?(str&.downcase)
default_type.include?(str&.downcase) || str.blank?
end
def image_type?(str)
@ -22,7 +22,7 @@ module RepositoriesHelper
def is_readme?(type, str)
return false if type != 'file' || str.blank?
readme_types = ["readme.md", "readme", "readme_en.md", "readme_zh.md", "readme_en", "readme_zh"]
readme_types.include?(str.to_s.downcase)
readme_types.include?(str.to_s.downcase) || str =~ CustomRegexp::MD_REGEX
end
def render_commit_author(author_json)
@ -36,7 +36,6 @@ module RepositoriesHelper
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
@ -45,23 +44,40 @@ module RepositoriesHelper
end
end
def readme_render_decode64_content(str, owner, repo, ref)
def readme_render_decode64_content(str, owner, repo, ref, path)
return nil if str.blank?
begin
content = Base64.decode64(str).force_encoding('UTF-8')
c_regex = /\!\[.*?\]\((.*?)\)/
src_regex = /src=\"(.*?)\"/
src2_regex = /src='(.*?)'/
ss = content.to_s.scan(c_regex)
ss_src = content.to_s.scan(src_regex)
total_images = ss + ss_src
ss_src = content.scan(src_regex)
ss_src2 = content.scan(src2_regex)
total_images = ss + ss_src + ss_src2
if total_images.length > 0
total_images.each do |s|
begin
image_title = /\"(.*?)\"/
r_content = s[0]
remove_title = r_content.to_s.scan(image_title)
if remove_title.length > 0
r_content = r_content.gsub(/#{remove_title[0]}/, "").strip
# if remove_title.length > 0
# r_content = r_content.gsub(/#{remove_title[0]}/, "").strip
# end
path_last = r_content
path_current = ""
# 相对路径处理
if r_content.start_with?("../")
relative_path_length = r_content.split("../").size - 1
path_pre = path.split("/").size - 1 - relative_path_length
path_pre = 0 if path_pre < 0
path_current = path_pre == 0 ? "" : path.split("/")[0..path_pre].join("/")
path_last = r_content.split("../").last
elsif r_content.start_with?("/") # 根路径处理
path_last = r_content[1..r_content.size]
else
path_current = path
end
# if r_content.include?("?")
# new_r_content = r_content + "&raw=true"
@ -72,9 +88,12 @@ module RepositoriesHelper
unless r_content.include?("http://") || r_content.include?("https://") || r_content.include?("mailto:")
# new_r_content = "#{path}" + new_r_content
new_r_content = [base_url, "/api/#{owner&.login}/#{repo.identifier}/raw?filepath=#{r_content}&ref=#{ref}"].join
new_r_content = [base_url, "/api/#{owner&.login}/#{repo.identifier}/raw?filepath=#{path_current}/#{path_last}&ref=#{ref}"].join
end
content = content.gsub(/src=\"#{r_content}\"/, "src=\"#{new_r_content}\"").gsub(/src='#{r_content}'/, "src=\"#{new_r_content}\"")
rescue
next
end
content = content.gsub(/#{r_content}/, new_r_content)
end
end
@ -84,6 +103,46 @@ module RepositoriesHelper
end
end
# author hui.he
def new_readme_render_decode64_content(str, owner, repo, ref, readme_path, readme_name)
file_path = readme_path.include?('/') ? readme_path.gsub("/#{readme_name}", '') : readme_path.gsub("#{readme_name}", '')
return nil if str.blank?
content = Base64.decode64(str).force_encoding('UTF-8')
s_regex = /\[.*?\]\((.*?)\)/
src_regex = /src=\"(.*?)\"/
ss = content.to_s.scan(s_regex)
ss_src = content.to_s.scan(src_regex)
total_sources = ss + ss_src
total_sources.uniq!
total_sources.each do |s|
begin
s_content = s[0]
# 链接直接跳过不做替换
next if s_content.starts_with?('http://') || s_content.starts_with?('https://') || s_content.starts_with?('mailto:') || s_content.blank?
ext = File.extname(s_content)[1..-1]
if image_type?(ext) || download_type(ext)
s_content = File.expand_path(s_content, file_path)
s_content = s_content.split("#{Rails.root}/")[1]
# content = content.gsub(s[0], "/#{s_content}")
s_content = [base_url, "/api/#{owner&.login}/#{repo.identifier}/raw?filepath=#{s_content}&ref=#{ref}"].join
content = content.gsub(s[0], s_content)
else
path = [owner&.login, repo&.identifier, 'tree', ref, file_path].join("/")
s_content = File.expand_path(s_content, path)
s_content = s_content.split("#{Rails.root}/")[1]
content = content.gsub(s[0], "/#{s_content}")
end
rescue
next
end
end
return content
rescue
return str
end
# unix_time values for example: 1604382982
def render_format_time_with_unix(unix_time)
Time.at(unix_time).strftime("%Y-%m-%d %H:%M")
@ -94,10 +153,21 @@ module RepositoriesHelper
date.to_time.strftime("%Y-%m-%d %H:%M")
end
def readme_decode64_content(entry, owner, repo, ref, path=nil)
Rails.logger.info("entry===#{entry["type"]} #{entry["name"]}")
content = Gitea::Repository::Entries::GetService.call(owner, repo.identifier, URI.escape(entry['path']), ref: ref)['content']
Rails.logger.info("content===#{content}")
# readme_render_decode64_content(content, owner, repo, ref)
new_readme_render_decode64_content(content, owner, repo, ref, entry['path'], entry['name'])
end
def decode64_content(entry, owner, repo, ref, path=nil)
if is_readme?(entry['type'], entry['name'])
Rails.logger.info("entry===#{entry["type"]} #{entry["name"]}")
content = Gitea::Repository::Entries::GetService.call(owner, repo.identifier, URI.escape(entry['path']), ref: ref)['content']
readme_render_decode64_content(content, owner, repo, ref)
Rails.logger.info("content===#{content}")
# readme_render_decode64_content(content, owner, repo, ref)
return Base64.decode64(content).force_encoding('UTF-8')
else
file_type = File.extname(entry['name'].to_s)[1..-1]
if image_type?(file_type)

View File

@ -0,0 +1,15 @@
class Admins::NewImportUserFromExcel < BaseImportXlsx
UserData = Struct.new(:login, :email, :password, :nickname)
def read_each(&block)
sheet.each_row_streaming(pad_cells: true, offset: 1) do |row|
data = row.map(&method(:cell_value))[0..3]
block.call UserData.new(*data)
end
end
private
def cell_value(obj)
obj&.cell_value
end
end

View File

@ -13,7 +13,7 @@ module Gitea
end
def success?
@error.nil?
@error.nil? && @result[:status].to_s == "success"
end
def result

View File

@ -7,6 +7,8 @@ class CacheAsyncClearJob < ApplicationJob
Cache::V2::ProjectCommonService.new(id).clear
when "owner_common_service"
Cache::V2::OwnnerCommonService.new(id).clear
when "project_rank_service"
Cache::V2::ProjectRankService.new(id).clear
end
end
end

View File

@ -3,8 +3,7 @@ class DelayExpiredIssueJob < ApplicationJob
def perform
Issue.where(due_date: Date.today + 1.days).find_each do |issue|
SendTemplateMessageJob.perform_later('IssueAssignerExpire', issue.id) if Site.has_notice_menu?
SendTemplateMessageJob.perform_later('IssueCreatorExpire', issue.id) if Site.has_notice_menu?
SendTemplateMessageJob.perform_later('IssueExpire', issue.id) if Site.has_notice_menu?
end
end

View File

@ -24,13 +24,6 @@ class SendTemplateMessageJob < ApplicationJob
receivers_email_string, email_title, email_content = MessageTemplate::IssueAssigned.get_email_message_content(receiver, operator, issue)
Notice::Write::EmailCreateService.call(receivers_email_string, email_title, email_content)
end
when 'IssueAssignerExpire'
issue_id = args[0]
issue = Issue.find_by_id(issue_id)
return unless issue.present?
receivers = User.where(id: issue&.assigned_to_id)
receivers_string, content, notification_url = MessageTemplate::IssueAssignerExpire.get_message_content(receivers, issue)
Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {issue_id: issue.id})
when 'IssueAtme'
receivers, operator_id, issue_id = args[0], args[1], args[2]
operator = User.find_by_id(operator_id)
@ -52,13 +45,17 @@ class SendTemplateMessageJob < ApplicationJob
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'
when 'IssueExpire'
issue_id = args[0]
issue = Issue.find_by_id(issue_id)
return unless issue.present?
receivers = User.where(id: issue&.author_id)
receivers_string, content, notification_url = MessageTemplate::IssueCreatorExpire.get_message_content(receivers, issue)
receivers = User.where(id: [issue&.assigned_to_id, issue&.author_id])
receivers_string, content, notification_url = MessageTemplate::IssueExpire.get_message_content(receivers, issue)
Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {issue_id: issue.id})
receivers.find_each do |receiver|
receivers_email_string, email_title, email_content = MessageTemplate::IssueExpire.get_email_message_content(receiver, issue)
Notice::Write::EmailCreateService.call(receivers_email_string, email_title, email_content)
end
when 'IssueDeleted'
operator_id, issue_title, issue_assigned_to_id, issue_author_id = args[0], args[1], args[2], args[3]
operator = User.find_by_id(operator_id)
@ -94,6 +91,14 @@ class SendTemplateMessageJob < ApplicationJob
receivers_email_string, email_title, email_content = MessageTemplate::OrganizationLeft.get_email_message_content(receiver, organization)
Notice::Write::EmailCreateService.call(receivers_email_string, email_title, email_content)
end
when 'ProjectForked'
operator_id, project_id = args[0], args[1]
operator = User.find_by_id(operator_id)
project = Project.find_by_id(project_id)
return unless operator.present? && project.present?
receivers = project&.all_managers.where.not(id: operator&.id)
receivers_string, content, notification_url = MessageTemplate::ProjectForked.get_message_content(receivers, operator, project)
Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {operator_id: operator.id, project_id: project.id})
when 'ProjectIssue'
operator_id, issue_id = args[0], args[1]
operator = User.find_by_id(operator_id)
@ -163,6 +168,37 @@ class SendTemplateMessageJob < ApplicationJob
receivers_email_string, email_title, email_content = MessageTemplate::ProjectMemberLeft.get_email_message_content(receiver, user, project)
Notice::Write::EmailCreateService.call(receivers_email_string, email_title, email_content)
end
when 'ProjectMilestoneCompleted'
milestone_id = args[0]
milestone = Version.find_by_id(milestone_id)
return unless milestone.present? && milestone&.project.present?
receivers = milestone&.project&.all_managers
receivers_string, content, notification_url = MessageTemplate::ProjectMilestoneCompleted.get_message_content(receivers, milestone)
Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {milestone_id: milestone_id})
receivers.find_each do |receiver|
receivers_email_string, email_title, email_content = MessageTemplate::ProjectMilestoneCompleted.get_email_message_content(receiver, milestone)
Notice::Write::EmailCreateService.call(receivers_email_string, email_title, email_content)
end
when 'ProjectMilestone'
milestone_id, operator_id = args[0], args[1]
milestone = Version.find_by_id(milestone_id)
operator = User.find_by_id(operator_id)
return unless milestone.present? && milestone&.project.present? && operator.present?
receivers = milestone&.project&.all_managers.where.not(id: operator_id)
receivers_string, content, notification_url = MessageTemplate::ProjectMilestone.get_message_content(receivers, operator, milestone)
Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {milestone_id: milestone_id, operator_id: operator_id})
receivers.find_each do |receiver|
receivers_email_string, email_title, email_content = MessageTemplate::ProjectMilestone.get_email_message_content(receiver, operator, milestone)
Notice::Write::EmailCreateService.call(receivers_email_string, email_title, email_content)
end
when 'ProjectPraised'
operator_id, project_id = args[0], args[1]
operator = User.find_by_id(operator_id)
project = Project.find_by_id(project_id)
return unless operator.present? && project.present?
receivers = project&.all_managers.where.not(id: operator&.id)
receivers_string, content, notification_url = MessageTemplate::ProjectPraised.get_message_content(receivers, operator, project)
Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {operator_id: operator.id, project_id: project.id})
when 'ProjectPullRequest'
operator_id, pull_request_id = args[0], args[1]
operator = User.find_by_id(operator_id)
@ -290,6 +326,30 @@ class SendTemplateMessageJob < ApplicationJob
receivers_email_string, email_title, email_content = MessageTemplate::TeamLeft.get_email_message_content(receiver, organization, team)
Notice::Write::EmailCreateService.call(receivers_email_string, email_title, email_content)
end
when 'CompetitionBegin'
user_id, competition_id = args[0], args[1]
user = User.find_by_id(user_id)
project = Project.find_by_sql("select *,title as name from competitions where id=#{competition_id}")
return unless user.present? && project.present?
receivers = User.where(id: user_id)
receivers_string, content, notification_url = MessageTemplate::CompetitionBegin.get_message_content(receivers, project.first)
Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {user_id: user_id, competition_name: project.first&.name, identifier: project.first&.identifier})
when 'CompetitionReview'
user_id, competition_id = args[0], args[1]
user = User.find_by_id(user_id)
project = Project.find_by_sql("select *,title as name from competitions where id=#{competition_id}")
return unless user.present? && project.present?
receivers = User.where(id: user_id)
receivers_string, content, notification_url = MessageTemplate::CompetitionReview.get_message_content(receivers, project.first)
Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {user_id: user_id, competition_name: project.first&.name, identifier: project.first&.identifier})
when 'CompetitionResult'
user_id, competition_id = args[0], args[1]
user = User.find_by_id(user_id)
project = Project.find_by_sql("select *,title as name from competitions where id=#{competition_id}")
return unless user.present? && project.present?
receivers = User.where(id: user_id)
receivers_string, content, notification_url = MessageTemplate::CompetitionResult.get_message_content(receivers, project.first)
Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {user_id: user_id, competition_name: project.first&.name, identifier: project.first&.identifier})
end
end
end

View File

@ -1,7 +1,7 @@
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_-]+$/ #只含有数字、字母、下划线不能以下划线开头和结尾
LOGIN = /^(?!_)(?!.*?_$)[a-zA-Z0-9_-]{4,15}\z/ #只含有数字、字母、下划线不能以下划线开头和结尾
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/
@ -11,5 +11,5 @@ module CustomRegexp
URL_REGEX = /\A(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?\z/i
REPOSITORY_NAME_REGEX = /^(?!_)(?!.*?_$)[a-zA-Z0-9_-]+$/ #只含有数字、字母、下划线不能以下划线开头和结尾
MD_REGEX = /^.+(\.[m|M][d|D])$/
end

View File

@ -7,7 +7,7 @@ module Notice
config = Rails.application.config_for(:configuration).symbolize_keys!
notice_config = config[:notice].symbolize_keys!
raise 'notice config missing' if notice_config.blank?
rescue => exception
rescue => ex
raise ex if Rails.env.production?
puts %Q{\033[33m [warning] gitea config or configuration.yml missing,

21
app/libs/trace.rb Normal file
View File

@ -0,0 +1,21 @@
module Trace
class << self
def trace_config
trace_config = {}
begin
config = Rails.application.config_for(:configuration).symbolize_keys!
trace_config = config[:trace].symbolize_keys!
raise 'trace config missing' if trace_config.blank?
rescue => ex
raise ex if Rails.env.production?
puts %Q{\033[33m [warning] gitea config or configuration.yml missing,
please add it or execute 'cp config/configuration.yml.example config/configuration.yml' \033[0m}
trace_config = {}
end
trace_config
end
end
end

View File

@ -5,10 +5,10 @@ class Ci::Repo < Ci::RemoteBase
has_one :perm, foreign_key: :perm_repo_uid
has_many :builds, foreign_key: :build_repo_id, dependent: :destroy
def self.find_with_namespace(namespace_path, identifier)
def self.find_with_namespace(namespace_path, identifier, user_login)
logger.info "########namespace_path: #{namespace_path} ########identifier: #{identifier} "
user = Ci::User.find_by_user_login namespace_path
user_login = user_login || namespace_path
user = Ci::User.find_by(user_login: user_login)
repo = Ci::Repo.where(repo_namespace: namespace_path, repo_name: identifier).first
[user, repo]

View File

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

View File

@ -17,7 +17,7 @@
class ForkUser < ApplicationRecord
belongs_to :project
belongs_to :user
belongs_to :owner, class_name: 'Owner', foreign_key: :user_id
belongs_to :fork_project, class_name: 'Project', foreign_key: :fork_project_id
after_create :incre_project_common, :incre_user_statistic, :incre_platform_statistic

View File

@ -76,7 +76,7 @@ class Issue < ApplicationRecord
scope :issue_index_includes, ->{includes(:tracker, :priority, :version, :issue_status, :journals,:issue_tags,user: :user_extension)}
scope :closed, ->{where(status_id: 5)}
after_create :incre_project_common, :incre_user_statistic, :incre_platform_statistic
after_update :change_versions_count
after_save :change_versions_count, :send_update_message_to_notice_system
after_destroy :update_closed_issues_count_in_project!, :decre_project_common, :decre_user_statistic, :decre_platform_statistic
def incre_project_common
@ -171,11 +171,25 @@ class Issue < ApplicationRecord
end
def change_versions_count
if self.version.present? && self.saved_change_to_status_id?
if self.saved_change_to_fixed_version_id?
before_version = Version.find_by_id(self.fixed_version_id_before_last_save)
Rails.logger.info self.fixed_version_id_before_last_save
if before_version.present?
Rails.logger.info self.status_id
Rails.logger.info self.status_id_before_last_save
# 更改前状态为完成 或者 更改前后都为完成状态
if self.status_id_before_last_save == 5
percent = before_version.issues_count == 0 ? 0.0 : ((before_version.closed_issues_count - 1).to_f / before_version.issues_count)
before_version.update_attributes(closed_issues_count: (before_version.closed_issues_count - 1), percent: percent)
end
end
end
if self.version.present? && (self.saved_change_to_status_id? || self.saved_change_to_fixed_version_id?)
if self.status_id == 5
percent = self.version.issues_count == 0 ? 0.0 : ((self.version.closed_issues_count + 1).to_f / self.version.issues_count)
self.version.update_attributes(closed_issues_count: (self.version.closed_issues_count + 1), percent: percent)
elsif self.status_id_before_last_save == 5
elsif self.status_id_before_last_save == 5 && !self.saved_change_to_fixed_version_id?
percent = self.version.issues_count == 0 ? 0.0 : ((self.version.closed_issues_count - 1).to_f / self.version.issues_count)
self.version.update_attributes(closed_issues_count: (self.version.closed_issues_count - 1), percent: percent)
end
@ -183,7 +197,11 @@ class Issue < ApplicationRecord
end
def update_closed_issues_count_in_project!
self.project.decrement!(:closed_issues_count)
self.project.decrement!(:closed_issues_count) if self.status_id == 5
end
def send_update_message_to_notice_system
SendTemplateMessageJob.perform_later('IssueExpire', self.id) if Site.has_notice_menu? && self.due_date == Date.today + 1.days
end
end

View File

@ -6,7 +6,7 @@
# journalized_id :integer default("0"), not null
# journalized_type :string(30) default(""), not null
# user_id :integer default("0"), not null
# notes :text(65535)
# notes :text(4294967295)
# created_on :datetime not null
# private_notes :boolean default("0"), not null
# parent_id :integer

View File

@ -13,61 +13,72 @@
#
class MessageTemplate < ApplicationRecord
PLATFORM = 'GitLink'
def self.build_init_data
MessageTemplate::IssueAssignerExpire.destroy_all
MessageTemplate::IssueCreatorExpire.destroy_all
self.create(type: 'MessageTemplate::FollowedTip', sys_notice: '<b>{nickname}</b> 关注了你', notification_url: '{baseurl}/{login}')
email_html = File.read("#{email_template_html_dir}/issue_assigned.html")
self.create(type: 'MessageTemplate::IssueAssigned', sys_notice: '{nickname1}在 <b>{nickname2}/{repository}</b> 指派给你一个疑修:<b>{title}</b>', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}', email: email_html, email_title: 'GitLink: {nickname1} 在 {nickname2}/{repository} 指派给你一个疑修')
self.create(type: 'MessageTemplate::IssueAssignerExpire', sys_notice: '您负责的疑修 <b>{title}</b> 已临近截止日期,请尽快处理', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}')
self.create(type: 'MessageTemplate::IssueAssigned', sys_notice: '{nickname1}在 <b>{nickname2}/{repository}</b> 指派给你一个疑修:<b>{title}</b>', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}', email: email_html, email_title: "#{PLATFORM}: {nickname1} 在 {nickname2}/{repository} 指派给你一个疑修")
self.create(type: 'MessageTemplate::IssueAtme', sys_notice: '<b>{nickname}</b> 在疑修 <b>{title}</b> 中@我', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}')
email_html = File.read("#{email_template_html_dir}/issue_changed.html")
self.create(type: 'MessageTemplate::IssueChanged', sys_notice: '在项目 <b>{nickname2}/{repository}</b> 的疑修 <b>{title}</b> 中:{ifassigner}{nickname1}将负责人从 <b>{assigner1}</b> 修改为 <b>{assigner2}</b> {endassigner}{ifstatus}{nickname1}将状态从 <b>{status1}</b> 修改为 <b>{status2}</b> {endstatus}{iftracker}{nickname1}将类型从 <b>{tracker1}</b> 修改为 <b>{tracker2}</b> {endtracker}{ifpriority}{nickname1}将优先级从 <b>{priority1}</b> 修改为 <b>{priority2}</b> {endpriority}{ifmilestone}{nickname1}将里程碑从 <b>{milestone1}</b> 修改为 <b>{milestone2}</b> {endmilestone}{iftag}{nickname1}将标记从 <b>{tag1}</b> 修改为 <b>{tag2}</b> {endtag}{ifdoneratio}{nickname1}将完成度从 <b>{doneratio1}</b> 修改为 <b>{doneratio2}</b> {enddoneratio}{ifbranch}{nickname1}将指定分支从 <b>{branch1}</b> 修改为 <b>{branch2}</b> {endbranch}{ifstartdate}{nickname1}将开始日期从 <b>{startdate1}</b> 修改为 <b>{startdate2}</b> {endstartdate}{ifduedate}{nickname1}将结束日期从 <b>{duedate1}</b> 修改为 <b>{duedate2}</b> {endduedate}', email: email_html, email_title: 'GitLink: 疑修 {title} 有状态变更', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}')
self.create(type: 'MessageTemplate::IssueCreatorExpire', sys_notice: '您发布的疑修 <b>{title}</b> 已临近截止日期,请尽快处理', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}')
self.create(type: 'MessageTemplate::IssueChanged', sys_notice: '在项目 <b>{nickname2}/{repository}</b> 的疑修 <b>{title}</b> 中:{ifassigner}{nickname1}将负责人从 <b>{assigner1}</b> 修改为 <b>{assigner2}</b> {endassigner}{ifstatus}{nickname1}将状态从 <b>{status1}</b> 修改为 <b>{status2}</b> {endstatus}{iftracker}{nickname1}将类型从 <b>{tracker1}</b> 修改为 <b>{tracker2}</b> {endtracker}{ifpriority}{nickname1}将优先级从 <b>{priority1}</b> 修改为 <b>{priority2}</b> {endpriority}{ifmilestone}{nickname1}将里程碑从 <b>{milestone1}</b> 修改为 <b>{milestone2}</b> {endmilestone}{iftag}{nickname1}将标记从 <b>{tag1}</b> 修改为 <b>{tag2}</b> {endtag}{ifdoneratio}{nickname1}将完成度从 <b>{doneratio1}</b> 修改为 <b>{doneratio2}</b> {enddoneratio}{ifbranch}{nickname1}将指定分支从 <b>{branch1}</b> 修改为 <b>{branch2}</b> {endbranch}{ifstartdate}{nickname1}将开始日期从 <b>{startdate1}</b> 修改为 <b>{startdate2}</b> {endstartdate}{ifduedate}{nickname1}将结束日期从 <b>{duedate1}</b> 修改为 <b>{duedate2}</b> {endduedate}', email: email_html, email_title: "#{PLATFORM}: 疑修 {title} 有状态变更", notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}')
email_html = File.read("#{email_template_html_dir}/issue_expire.html")
self.create(type: 'MessageTemplate::IssueExpire', sys_notice: '疑修 <b>{title}</b> 已临近截止日期,请尽快处理', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}', email: email_html, email_title: "#{PLATFORM}: 疑修截止日期到达最后一天")
email_html = File.read("#{email_template_html_dir}/issue_deleted.html")
self.create(type: 'MessageTemplate::IssueDeleted', sys_notice: '{nickname}已将疑修 <b>{title}</b> 删除', email: email_html, email_title: 'GitLink: 疑修 {title} 有状态变更', notification_url: '')
self.create(type: 'MessageTemplate::IssueDeleted', sys_notice: '{nickname}已将疑修 <b>{title}</b> 删除', email: email_html, email_title: "#{PLATFORM}: 疑修 {title} 有状态变更", notification_url: '')
self.create(type: 'MessageTemplate::IssueJournal', sys_notice: '{nickname}评论疑修{title}<b>{notes}</b>', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}')
self.create(type: 'MessageTemplate::LoginIpTip', sys_notice: '您的账号{nickname}于{login_time)在非常用的IP地址{ip}登录,如非本人操作,请立即修改密码', notification_url: '')
email_html = File.read("#{email_template_html_dir}/organization_joined.html")
self.create(type: 'MessageTemplate::OrganizationJoined', sys_notice: '你已加入 <b>{organization}</b> 组织', notification_url: '{baseurl}/{login}', email: email_html, email_title: 'GitLink: 你已加入 {organization} 组织')
self.create(type: 'MessageTemplate::OrganizationJoined', sys_notice: '你已加入 <b>{organization}</b> 组织', notification_url: '{baseurl}/{login}', email: email_html, email_title: "#{PLATFORM}: 你已加入 {organization} 组织")
email_html = File.read("#{email_template_html_dir}/organization_left.html")
self.create(type: 'MessageTemplate::OrganizationLeft', sys_notice: '你已被移出 <b>{organization}</b> 组织', notification_url: '', email: email_html, email_title: 'GitLink: 你已被移出 {organization} 组织')
self.create(type: 'MessageTemplate::OrganizationLeft', sys_notice: '你已被移出 <b>{organization}</b> 组织', notification_url: '', email: email_html, email_title: "#{PLATFORM}: 你已被移出 {organization} 组织")
self.create(type: 'MessageTemplate::ProjectDeleted', sys_notice: '你关注的仓库{nickname}/{repository}已被删除', notification_url: '')
self.create(type: 'MessageTemplate::ProjectFollowed', sys_notice: '<b>{nickname}</b> 关注了你管理的仓库', notification_url: '{baseurl}/{login}')
self.create(type: 'MessageTemplate::ProjectForked', sys_notice: '<b>{nickname1}</b> 复刻了你管理的仓库{nickname1}/{repository1}到{nickname2}/{repository2}', notification_url: '{baseurl}/{owner}/{identifier}')
self.create(type: 'MessageTemplate::ProjectForked', sys_notice: '<b>{nickname1}</b> 复刻了你管理的仓库 <b>{nickname2}/{repository}</b> 到 <b>{nickname1}/{repository}</b>', notification_url: '{baseurl}/{owner}/{identifier}')
email_html = File.read("#{email_template_html_dir}/project_issue.html")
self.create(type: 'MessageTemplate::ProjectIssue', sys_notice: '{nickname1}在 <b>{nickname2}/{repository}</b> 新建疑修:<b>{title}</b>', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}', email: email_html, email_title: 'GitLink: {nickname1} 在 {nickname2}/{repository} 新建了一个疑修')
self.create(type: 'MessageTemplate::ProjectIssue', sys_notice: '{nickname1}在 <b>{nickname2}/{repository}</b> 新建疑修:<b>{title}</b>', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}', email: email_html, email_title: "#{PLATFORM}: {nickname1} 在 {nickname2}/{repository} 新建了一个疑修")
email_html = File.read("#{email_template_html_dir}/project_joined.html")
self.create(type: 'MessageTemplate::ProjectJoined', sys_notice: '你已加入 <b>{repository}</b> 项目', notification_url: '{baseurl}/{owner}/{identifier}', email: email_html, email_title: 'GitLink: 你已加入 {repository} 项目')
self.create(type: 'MessageTemplate::ProjectJoined', sys_notice: '你已加入 <b>{repository}</b> 项目', notification_url: '{baseurl}/{owner}/{identifier}', email: email_html, email_title: "#{PLATFORM}: 你已加入 {repository} 项目")
email_html = File.read("#{email_template_html_dir}/project_left.html")
self.create(type: 'MessageTemplate::ProjectLeft', sys_notice: '你已被移出 <b>{repository}</b> 项目', notification_url: '', email: email_html, email_title: 'GitLink: 你已被移出 {repository} 项目')
self.create(type: 'MessageTemplate::ProjectLeft', sys_notice: '你已被移出 <b>{repository}</b> 项目', notification_url: '', email: email_html, email_title: "#{PLATFORM}: 你已被移出 {repository} 项目")
email_html = File.read("#{email_template_html_dir}/project_member_joined.html")
self.create(type: 'MessageTemplate::ProjectMemberJoined', sys_notice: '<b>{nickname1}</b> 已加入项目 <b>{nickname2}/{repository}</b>', notification_url: '{baseurl}/{owner}/{identifier}', email: email_html, email_title: 'GitLink: {nickname1} 已加入项目 {nickname2}/{repository}')
self.create(type: 'MessageTemplate::ProjectMemberJoined', sys_notice: '<b>{nickname1}</b> 已加入项目 <b>{nickname2}/{repository}</b>', notification_url: '{baseurl}/{owner}/{identifier}', email: email_html, email_title: "#{PLATFORM}: {nickname1} 已加入项目 {nickname2}/{repository}")
email_html = File.read("#{email_template_html_dir}/project_member_left.html")
self.create(type: 'MessageTemplate::ProjectMemberLeft', sys_notice: '<b>{nickname1}</b> 已被移出项目 <b>{nickname2}/{repository}</b>', notification_url: '{baseurl}/{owner}/{identifier}', email: email_html, email_title: 'GitLink: {nickname1} 已被移出项目 {nickname2}/{repository}')
self.create(type: 'MessageTemplate::ProjectMilestone', sys_notice: '{nickname1}在 <b>{nickname2}/{repository}</b> 创建了一个里程碑:<b>{title}</b>', notification_url: '{baseurl}/{owner}/{identifier}/milestones/{id}')
self.create(type: 'MessageTemplate::ProjectPraised', sys_notice: '<b>{nickname}</b> 点赞了你管理的仓库', notification_url: '{baseurl}/{login}')
self.create(type: 'MessageTemplate::ProjectMemberLeft', sys_notice: '<b>{nickname1}</b> 已被移出项目 <b>{nickname2}/{repository}</b>', notification_url: '{baseurl}/{owner}/{identifier}', email: email_html, email_title: "#{PLATFORM}: {nickname1} 已被移出项目 {nickname2}/{repository}")
email_html = File.read("#{email_template_html_dir}/project_milestone.html")
self.create(type: 'MessageTemplate::ProjectMilestone', sys_notice: '{nickname1}在 <b>{nickname2}/{repository}</b> 创建了一个里程碑:<b>{name}</b>', notification_url: '{baseurl}/{owner}/{identifier}/milestones/{id}', email: email_html, email_title: "#{PLATFORM}: {nickname1} 在 {nickname2}/{repository} 新建了一个里程碑")
email_html = File.read("#{email_template_html_dir}/project_milestone_completed.html")
self.create(type: 'MessageTemplate::ProjectMilestoneCompleted', sys_notice: '在 <b>{nickname}/{repository}</b> 仓库,里程碑 <b>{name}</b> 的完成度已达到100%', notification_url: '{baseurl}/{owner}/{identifier}/milestones/{id}', email: email_html, email_title: "#{PLATFORM}: 仓库 {nickname}/{repository} 有里程碑已完成")
self.create(type: 'MessageTemplate::ProjectPraised', sys_notice: '<b>{nickname1}</b> 点赞了你管理的仓库 <b>{nickname2}/{repository}</b>', notification_url: '{baseurl}/{login}')
email_html = File.read("#{email_template_html_dir}/project_pull_request.html")
self.create(type: 'MessageTemplate::ProjectPullRequest', sys_notice: '{nickname1}在 <b>{nickname2}/{repository}</b> 提交了一个合并请求:<b>{title}</b>', notification_url: '{baseurl}/{owner}/{identifier}/pulls/{id}', email: email_html, email_title: 'GitLink: {nickname1} 在 {nickname2}/{repository} 提交了一个合并请求')
self.create(type: 'MessageTemplate::ProjectPullRequest', sys_notice: '{nickname1}在 <b>{nickname2}/{repository}</b> 提交了一个合并请求:<b>{title}</b>', notification_url: '{baseurl}/{owner}/{identifier}/pulls/{id}', email: email_html, email_title: "#{PLATFORM}: {nickname1} 在 {nickname2}/{repository} 提交了一个合并请求")
email_html = File.read("#{email_template_html_dir}/project_role.html")
self.create(type: 'MessageTemplate::ProjectRole', sys_notice: '仓库 <b>{nickname}/{repository}</b> 已把你的角色改为 <b>{role}</b>', email: email_html, email_title: 'GitLink: 在 {nickname}/{repository} 项目你的账号有权限变更', notification_url: '{baseurl}/{owner}/{identifier}')
self.create(type: 'MessageTemplate::ProjectRole', sys_notice: '仓库 <b>{nickname}/{repository}</b> 已把你的角色改为 <b>{role}</b>', email: email_html, email_title: '#{PLATFORM}: 在 {nickname}/{repository} 项目你的账号有权限变更', notification_url: '{baseurl}/{owner}/{identifier}')
email_html = File.read("#{email_template_html_dir}/project_setting_changed.html")
self.create(type: 'MessageTemplate::ProjectSettingChanged', sys_notice: '{nickname1}更改了 <b>{nickname2}/{repository}</b> 仓库设置:{ifname}更改项目名称为"<b>{name}</b>"{endname}{ifidentifier}更改项目标识为"<b>{identifier}</b>"{endidentifier}{ifdescription}更改项目简介为"<b>{description}</b>"{enddescription}{ifcategory}更改项目类别为"<b>{category}</b>"{endcategory}{iflanguage}更改项目语言为"<b>{language}</b>"{endlanguage}{ifpermission}将仓库设为"<b>{permission}</b>"{endpermission}{ifnavbar}将项目导航更改为"<b>{navbar}</b>"{endnavbar}', notification_url: '{baseurl}/{owner}/{identifier}/settings', email: email_html, email_title: 'GitLink: 您管理的仓库 {nickname2}/{repository} 仓库设置已被更改')
self.create(type: 'MessageTemplate::ProjectSettingChanged', sys_notice: '{nickname1}更改了 <b>{nickname2}/{repository}</b> 仓库设置:{ifname}更改项目名称为"<b>{name}</b>"{endname}{ifidentifier}更改项目标识为"<b>{identifier}</b>"{endidentifier}{ifdescription}更改项目简介为"<b>{description}</b>"{enddescription}{ifcategory}更改项目类别为"<b>{category}</b>"{endcategory}{iflanguage}更改项目语言为"<b>{language}</b>"{endlanguage}{ifpermission}将仓库设为"<b>{permission}</b>"{endpermission}{ifnavbar}将项目导航更改为"<b>{navbar}</b>"{endnavbar}', notification_url: '{baseurl}/{owner}/{identifier}/settings', email: email_html, email_title: "#{PLATFORM}: 您管理的仓库 {nickname2}/{repository} 仓库设置已被更改")
self.create(type: 'MessageTemplate::ProjectTransfer', sys_notice: '你关注的仓库{nickname1}/{repository1}已被转移至{nickname2}/{repository2}', notification_url: '{baseurl}/{owner}/{identifier}')
self.create(type: 'MessageTemplate::ProjectVersion', sys_notice: '{nickname1}在 <b>{nickname2}/{repository}</b> 创建了发行版:<b>{title}</b>', notification_url: '{baseurl}/{owner}/{identifier}/releases')
email_html = File.read("#{email_template_html_dir}/pull_request_assigned.html")
self.create(type: 'MessageTemplate::PullRequestAssigned', sys_notice: '{nickname1}在 <b>{nickname2}/{repository}</b> 指派给你一个合并请求:<b>{title}<b>', notification_url: '{baseurl}/{owner}/{identifier}/pulls/{id}', email: email_html, email_title: 'GitLink: {nickname1} 在 {nickname2}/{repository} 指派给你一个合并请求')
self.create(type: 'MessageTemplate::PullRequestAssigned', sys_notice: '{nickname1}在 <b>{nickname2}/{repository}</b> 指派给你一个合并请求:<b>{title}<b>', notification_url: '{baseurl}/{owner}/{identifier}/pulls/{id}', email: email_html, email_title: "#{PLATFORM}: {nickname1} 在 {nickname2}/{repository} 指派给你一个合并请求")
self.create(type: 'MessageTemplate::PullRequestAtme', sys_notice: '<b>{nickname}</b> 在合并请求 <b>{title}</b> 中@我', notification_url: '{baseurl}/{owner}/{identifier}/pulls/{id}')
email_html = File.read("#{email_template_html_dir}/pull_request_changed.html")
self.create(type: 'MessageTemplate::PullRequestChanged', sys_notice: '在项目{nickname2}/{repository}的合并请求 <b>{title}</b> 中:{ifassigner}{nickname1}将审查成员从 <b>{assigner1}</b> 修改为 <b>{assigner2}</b> {endassigner}{ifmilestone}{nickname1}将里程碑从 <b>{milestone1}</b> 修改为 <b>{milestone2}</b> {endmilestone}{iftag}{nickname1}将标记从 <b>{tag1}</b> 修改为 <b>{tag2}</b> {endtag}{ifpriority}{nickname1}将优先级从 <b>{priority1}</b> 修改为 <b>{priority2}</b> {endpriority}', email: email_html, email_title: 'GitLink: 合并请求 {title} 有状态变更', notification_url: '{baseurl}/{owner}/{identifier}/pulls/{id}')
self.create(type: 'MessageTemplate::PullRequestChanged', sys_notice: '在项目{nickname2}/{repository}的合并请求 <b>{title}</b> 中:{ifassigner}{nickname1}将审查成员从 <b>{assigner1}</b> 修改为 <b>{assigner2}</b> {endassigner}{ifmilestone}{nickname1}将里程碑从 <b>{milestone1}</b> 修改为 <b>{milestone2}</b> {endmilestone}{iftag}{nickname1}将标记从 <b>{tag1}</b> 修改为 <b>{tag2}</b> {endtag}{ifpriority}{nickname1}将优先级从 <b>{priority1}</b> 修改为 <b>{priority2}</b> {endpriority}', email: email_html, email_title: "#{PLATFORM}: 合并请求 {title} 有状态变更", notification_url: '{baseurl}/{owner}/{identifier}/pulls/{id}')
email_html = File.read("#{email_template_html_dir}/pull_request_closed.html")
self.create(type: 'MessageTemplate::PullRequestClosed', sys_notice: '你提交的合并请求:{title} <b>被拒绝</b>', email: email_html, email_title: 'GitLink: 合并请求 {title} 有状态变更', notification_url: '')
self.create(type: 'MessageTemplate::PullRequestClosed', sys_notice: '你提交的合并请求:{title} <b>被拒绝</b>', email: email_html, email_title: "#{PLATFORM}: 合并请求 {title} 有状态变更", notification_url: '')
self.create(type: 'MessageTemplate::PullRequestJournal', sys_notice: '{nickname}评论合并请求{title}<b>{notes}</b>', notification_url: '{baseurl}/{owner}/{identifier}/pulls/{id}')
email_html = File.read("#{email_template_html_dir}/pull_request_merged.html")
self.create(type: 'MessageTemplate::PullRequestMerged', sys_notice: '你提交的合并请求:{title} <b>已通过</b>', email: email_html, email_title: 'GitLink: 合并请求 {title} 有状态变更', notification_url: '{baseurl}/{owner}/{identifier}/pulls/{id}')
self.create(type: 'MessageTemplate::PullRequestMerged', sys_notice: '你提交的合并请求:{title} <b>已通过</b>', email: email_html, email_title: "#{PLATFORM}: 合并请求 {title} 有状态变更", notification_url: '{baseurl}/{owner}/{identifier}/pulls/{id}')
email_html = File.read("#{email_template_html_dir}/team_joined.html")
self.create(type: 'MessageTemplate::TeamJoined', sys_notice: '你已被拉入组织 <b>{organization}</b> 的 <b>{team}</b> 团队,拥有<b>{role}</b>权限', email: email_html, email_title: 'GitLink: 在 {organization} 组织你的账号有权限变更', notification_url: '{baseurl}/{login}')
self.create(type: 'MessageTemplate::TeamJoined', sys_notice: '你已被拉入组织 <b>{organization}</b> 的 <b>{team}</b> 团队,拥有<b>{role}</b>权限', email: email_html, email_title: "#{PLATFORM}: 在 {organization} 组织你的账号有权限变更", notification_url: '{baseurl}/{login}')
email_html = File.read("#{email_template_html_dir}/team_left.html")
self.create(type: 'MessageTemplate::TeamLeft', sys_notice: '你已被移出组织 <b>{organization}</b> 的 <b>{team}</b> 团队', email: email_html, email_title: 'GitLink: 在 {organization} 组织你的账号有权限变更', notification_url: '{baseurl}/{login}')
self.create(type: 'MessageTemplate::TeamLeft', sys_notice: '你已被移出组织 <b>{organization}</b> 的 <b>{team}</b> 团队', email: email_html, email_title: "#{PLATFORM}: 在 {organization} 组织你的账号有权限变更", notification_url: '{baseurl}/{login}')
# 竞赛通知
self.create(type: 'MessageTemplate::CompetitionBegin', sys_notice: '你报名的竞赛 <b>{competition_name}</b> 已进入比赛进行阶段,可在此期间提交作品', notification_url: '{to_url}')
self.create(type: 'MessageTemplate::CompetitionResult', sys_notice: '你报名的竞赛 <b>{competition_name}</b> 已进入成绩公示阶段,可查看排行榜信息', notification_url: '{to_url}')
self.create(type: 'MessageTemplate::CompetitionReview', sys_notice: '你报名的竞赛 <b>{competition_name}</b> 距作品提交结束日期仅剩3天若尚未提交参赛作品请尽快提交', notification_url: '{to_url}')
end
def self.sys_notice

View File

@ -0,0 +1,35 @@
# == Schema Information
#
# Table name: message_templates
#
# id :integer not null, primary key
# type :string(255)
# sys_notice :text(65535)
# email :text(65535)
# created_at :datetime not null
# updated_at :datetime not null
# notification_url :string(255)
# email_title :string(255)
#
# 报名的竞赛进入比赛进行阶段
# 触发场景
# 赛队成员报名的竞赛已进入比赛进行阶段
# 通知文案格式
# 你报名的竞赛 xxx 已进入比赛进行阶段,可在此阶段提交作品
# 时间x分钟/小时/天/月前
# 通知文案示例
# 你报名的竞赛 代码审查大赛 已进入比赛进行阶段,可在此期间提交作品
# 时间3小时前
# 点击通知跳转页面
# 点击此通知将跳转到代码审查大赛详情页:
# http://117.50.100.12:8080/competitions/lgw7st/home
class MessageTemplate::CompetitionBegin < MessageTemplate
# MessageTemplate::FollowedTip.get_message_content(User.where(login: 'yystopf'), User.last)
def self.get_message_content(receivers, competition)
return receivers_string(receivers), sys_notice.to_s.gsub('{competition_name}', competition&.name), notification_url.to_s.gsub('{to_url}', "/competitions/#{competition.identifier}/home")
# rescue
# return '', '', ''
end
end

View File

@ -0,0 +1,35 @@
# == Schema Information
#
# Table name: message_templates
#
# id :integer not null, primary key
# type :string(255)
# sys_notice :text(65535)
# email :text(65535)
# created_at :datetime not null
# updated_at :datetime not null
# notification_url :string(255)
# email_title :string(255)
#
# 报名的竞赛进入成绩公示阶段
# 触发场景
# 赛队成员报名的竞赛已进入成绩公示阶段
# 通知文案格式
# 你报名的竞赛 xxx 已进入成绩公示阶段,可查看排行榜信息
# 时间x分钟/小时/天/月前
# 通知文案示例
# 你报名的竞赛 代码审查大赛 已进入成绩公示阶段,可查看排行榜信息
# 时间3小时前
# 点击通知跳转页面
# 点击此通知将跳转到代码审查大赛详情页:
# http://117.50.100.12:8080/competitions/lgw7st/home
class MessageTemplate::CompetitionResult < MessageTemplate
# MessageTemplate::FollowedTip.get_message_content(User.where(login: 'yystopf'), User.last)
def self.get_message_content(receivers, competition)
return receivers_string(receivers), sys_notice.gsub('{competition_name}', competition&.title), notification_url.gsub('{to_url}', "/competitions/#{competition.identifier}/home")
rescue
return '', '', ''
end
end

View File

@ -0,0 +1,35 @@
# == Schema Information
#
# Table name: message_templates
#
# id :integer not null, primary key
# type :string(255)
# sys_notice :text(65535)
# email :text(65535)
# created_at :datetime not null
# updated_at :datetime not null
# notification_url :string(255)
# email_title :string(255)
#
# 报名的竞赛比赛结束时间临近
# 触发场景
# 赛队成员报名的竞赛阶段处于比赛进行中且距比赛结束日期仅剩3天
# 通知文案格式
# 你报名的竞赛 xxx 距作品提交结束日期仅剩3天若尚未提交参赛作品请尽快提交
# 时间x分钟/小时/天/月前
# 通知文案示例
# 你报名的竞赛 代码审查大赛 距作品提交结束日期仅剩3天若尚未提交参赛作品请尽快提交
# 时间3小时前
# 点击通知跳转页面
# 点击此通知将跳转到代码审查大赛详情页:
# http://117.50.100.12:8080/competitions/lgw7st/home
class MessageTemplate::CompetitionReview < MessageTemplate
# MessageTemplate::FollowedTip.get_message_content(User.where(login: 'yystopf'), User.last)
def self.get_message_content(receivers, competition)
return receivers_string(receivers), sys_notice.gsub('{competition_name}', competition&.title), notification_url.gsub('{to_url}', "/competitions/#{competition.identifier}/home")
rescue
return '', '', ''
end
end

View File

@ -53,6 +53,7 @@ class MessageTemplate::IssueAssigned < MessageTemplate
content.gsub!('{baseurl}', base_url)
content.gsub!('{title}', issue&.subject)
content.gsub!('{id}', issue&.id.to_s)
content.gsub!('{platform}', PLATFORM)
return receiver&.mail, title, content
else

View File

@ -359,6 +359,7 @@ class MessageTemplate::IssueChanged < MessageTemplate
else
content.gsub!(/({ifduedate})(.*)({endduedate})/, '')
end
content.gsub!('{platform}', PLATFORM)
return receiver&.mail, title, content
else

View File

@ -1,29 +1,3 @@
# == Schema Information
#
# Table name: message_templates
#
# id :integer not null, primary key
# type :string(255)
# sys_notice :text(65535)
# email :text(65535)
# created_at :datetime not null
# updated_at :datetime not null
# notification_url :string(255)
# email_title :string(255)
#
# 我创建的疑修截止日期到达最后一天
class MessageTemplate::IssueCreatorExpire < MessageTemplate
# MessageTemplate::IssueCreatorExpire.get_message_content(User.where(login: 'yystopf'), Issue.last)
def self.get_message_content(receivers, issue)
project = issue&.project
owner = project&.owner
content = sys_notice.gsub('{title}', issue&.subject)
url = notification_url.gsub('{owner}', owner&.login).gsub('{identifier}', project&.identifier).gsub('{id}', issue&.id.to_s)
return receivers_string(receivers), content, url
rescue => e
Rails.logger.info("MessageTemplate::IssueAssignerExpire.get_message_content [ERROR] #{e}")
return '', '', ''
end
end

View File

@ -41,6 +41,7 @@ class MessageTemplate::IssueDeleted < MessageTemplate
content.gsub!('{login}', operator&.login)
content.gsub!('{baseurl}', base_url)
content.gsub!('{title}', issue_title)
content.gsub!('{platform}', PLATFORM)
return receiver&.mail, title, content
else

View File

@ -0,0 +1,67 @@
# == Schema Information
#
# Table name: message_templates
#
# id :integer not null, primary key
# type :string(255)
# sys_notice :text(65535)
# email :text(65535)
# created_at :datetime not null
# updated_at :datetime not null
# notification_url :string(255)
# email_title :string(255)
#
# 我创建或负责的疑修截止日期到达最后一天
class MessageTemplate::IssueExpire < MessageTemplate
# MessageTemplate::IssueCreatorExpire.get_message_content(User.where(login: 'yystopf'), Issue.last)
def self.get_message_content(receivers, issue)
receivers.each do |receiver|
if receiver.user_template_message_setting.present?
send_setting = receiver.user_template_message_setting.notification_body["CreateOrAssign::IssueExpire"]
send_setting = send_setting.nil? ? UserTemplateMessageSetting.init_notification_body["CreateOrAssign::IssueExpire"] : send_setting
receivers = receivers.where.not(id: receiver.id) unless send_setting
end
end
return '', '', '' if receivers.blank?
project = issue&.project
owner = project&.owner
content = sys_notice.gsub('{title}', issue&.subject)
url = notification_url.gsub('{owner}', owner&.login).gsub('{identifier}', project&.identifier).gsub('{id}', issue&.id.to_s)
return receivers_string(receivers), content, url
rescue => e
Rails.logger.info("MessageTemplate::IssueExpire.get_message_content [ERROR] #{e}")
return '', '', ''
end
def self.get_email_message_content(receiver, issue)
if receiver.user_template_message_setting.present?
send_setting = receiver.user_template_message_setting.email_body["CreateOrAssign::IssueExpire"]
send_setting = send_setting.nil? ? UserTemplateMessageSetting.init_email_body["CreateOrAssign::IssueExpire"] : send_setting
return '', '', '' unless send_setting
project = issue&.project
owner = project&.owner
title = email_title
content = email
content.gsub!('{receiver}', receiver&.real_name)
content.gsub!('{nickname}', owner&.real_name)
content.gsub!('{login}', owner&.login)
content.gsub!('{identifier}', project&.identifier)
content.gsub!('{repository}', project&.name)
content.gsub!('{baseurl}', base_url)
content.gsub!('{title}', issue&.subject)
content.gsub!('{id}', issue&.id.to_s)
content.gsub!('{platform}', PLATFORM)
return receiver&.mail, title, content
else
return '', '', ''
end
rescue => e
Rails.logger.info("MessageTemplate::IssueExpire.get_email_message_content [ERROR] #{e}")
return '', '', ''
end
end

View File

@ -41,6 +41,7 @@ class MessageTemplate::OrganizationJoined < MessageTemplate
content.gsub!('{baseurl}', base_url)
content.gsub!('{login}', organization&.login)
content.gsub!('{organization}', organization&.real_name)
content.gsub!('{platform}', PLATFORM)
return receiver&.mail, title, content
else

View File

@ -41,6 +41,7 @@ class MessageTemplate::OrganizationLeft < MessageTemplate
content.gsub!('{baseurl}', base_url)
content.gsub!('{login}', organization&.login)
content.gsub!('{organization}', organization&.real_name)
content.gsub!('{platform}', PLATFORM)
return receiver&.mail, title, content
else

View File

@ -43,6 +43,7 @@ class MessageTemplate::OrganizationRole < MessageTemplate
content.gsub!('{login}', organization&.login)
content.gsub!('{organization}', organization&.real_name)
content.gsub!('{role}', role)
content.gsub!('{platform}', PLATFORM)
return receiver&.mail, title, content
else

View File

@ -12,11 +12,21 @@
# email_title :string(255)
#
# TODO 我管理的仓库被复刻
# 我管理的仓库被复刻
class MessageTemplate::ProjectForked < MessageTemplate
# MessageTemplate::ProjectForked.get_message_content(User.where(login: 'yystopf'))
def self.get_message_content(receivers)
def self.get_message_content(receivers, user, project)
receivers.each do |receiver|
if receiver.user_template_message_setting.present?
send_setting = receiver.user_template_message_setting.notification_body["ManageProject::Forked"]
send_setting = send_setting.nil? ? UserTemplateMessageSetting.init_notification_body["ManageProject::Forked"] : send_setting
receivers = receivers.where.not(id: receiver.id) unless send_setting
end
end
return '', '', '' if receivers.blank?
content = sys_notice.gsub('{nickname1}', user&.real_name).gsub('{nickname2}', project&.owner&.real_name).gsub('{repository}', project&.name)
url = notification_url.gsub('{owner}', user&.login).gsub('{identifier}', project&.identifier)
return receivers_string(receivers), content, url
rescue => e
Rails.logger.info("MessageTemplate::ProjectForked.get_message_content [ERROR] #{e}")

View File

@ -56,6 +56,7 @@ class MessageTemplate::ProjectIssue < MessageTemplate
content.gsub!('{identifier}', project&.identifier)
content.gsub!('{id}', issue&.id.to_s)
content.gsub!('{title}', issue&.subject)
content.gsub!('{platform}', PLATFORM)
return receiver&.mail, title, content
else

View File

@ -44,6 +44,7 @@ class MessageTemplate::ProjectJoined < MessageTemplate
content.gsub!('{identifier}', project&.identifier)
content.gsub!('{nickname}', project&.owner&.real_name)
content.gsub!('{repository}', project&.name)
content.gsub!('{platform}', PLATFORM)
return receiver&.mail, title, content
else

View File

@ -43,6 +43,7 @@ class MessageTemplate::ProjectLeft < MessageTemplate
content.gsub!('{identifier}', project&.identifier)
content.gsub!('{nickname}', project&.owner&.real_name)
content.gsub!('{repository}', project&.name)
content.gsub!('{platform}', PLATFORM)
return receiver&.mail, title, content
else

View File

@ -48,6 +48,7 @@ class MessageTemplate::ProjectMemberJoined < MessageTemplate
content.gsub!('{nickname1}', user&.real_name)
content.gsub!('{nickname2}', project&.owner&.real_name)
content.gsub!('{repository}', project&.name)
content.gsub!('{platform}', PLATFORM)
return receiver&.mail, title, content
else

View File

@ -48,6 +48,7 @@ class MessageTemplate::ProjectMemberLeft < MessageTemplate
content.gsub!('{nickname1}', user&.real_name)
content.gsub!('{nickname2}', project&.owner&.real_name)
content.gsub!('{repository}', project&.name)
content.gsub!('{platform}', PLATFORM)
return receiver&.mail, title, content
else

View File

@ -12,14 +12,61 @@
# email_title :string(255)
#
# TODO 我管理的仓库有新的里程碑
# 我管理的仓库有新的里程碑
class MessageTemplate::ProjectMilestone < MessageTemplate
# MessageTemplate::ProjectMilestone.get_message_content(User.where(login: 'yystopf'))
def self.get_message_content(receivers)
def self.get_message_content(receivers, operator, milestone)
receivers.each do |receiver|
if receiver.user_template_message_setting.present?
send_setting = receiver.user_template_message_setting.notification_body["ManageProject::Milestone"]
send_setting = send_setting.nil? ? UserTemplateMessageSetting.init_notification_body["ManageProject::Milestone"] : send_setting
receivers = receivers.where.not(id: receiver.id) unless receiver.user_template_message_setting.notification_body["ManageProject::Milestone"]
end
end
return '', '', '' if receivers.blank?
project = milestone&.project
owner = project&.owner
content = sys_notice.gsub('{nickname1}', operator&.real_name).gsub('{nickname2}', owner&.real_name).gsub('{repository}', project&.name).gsub('{name}', milestone&.name)
url = notification_url.gsub('{owner}', owner&.login).gsub('{identifier}', project&.identifier).gsub('{id}', milestone&.id.to_s)
return receivers_string(receivers), content, url
rescue => e
Rails.logger.info("MessageTemplate::ProjectMilestone.get_message_content [ERROR] #{e}")
return '', '', ''
end
def self.get_email_message_content(receiver, operator, milestone)
if receiver.user_template_message_setting.present?
send_setting = receiver.user_template_message_setting.email_body["ManageProject::Milestone"]
send_setting = send_setting.nil? ? UserTemplateMessageSetting.init_email_body["ManageProject::Milestone"] : send_setting
return '', '', '' unless send_setting
project = milestone&.project
owner = project&.owner
title = email_title
title.gsub!('{nickname1}', operator&.real_name)
title.gsub!('{nickname2}', owner&.real_name)
title.gsub!('{repository}', project&.name)
content = email
content.gsub!('{receiver}', receiver&.real_name)
content.gsub!('{baseurl}', base_url)
content.gsub!('{nickname1}', operator&.real_name)
content.gsub!('{nickname2}', owner&.real_name)
content.gsub!('{repository}', project&.name)
content.gsub!('{login}', owner&.login)
content.gsub!('{identifier}', project&.identifier)
content.gsub!('{id}', milestone&.id.to_s)
content.gsub!('{name}', milestone&.name)
content.gsub!('{platform}', PLATFORM)
return receiver&.mail, title, content
else
return '', '', ''
end
rescue => e
Rails.logger.info("MessageTemplate::ProjectMilestone.get_email_message_content [ERROR] #{e}")
return '', '', ''
end
end

View File

@ -0,0 +1,70 @@
# == Schema Information
#
# Table name: message_templates
#
# id :integer not null, primary key
# type :string(255)
# sys_notice :text(65535)
# email :text(65535)
# created_at :datetime not null
# updated_at :datetime not null
# notification_url :string(255)
# email_title :string(255)
#
# 我管理的仓库有里程碑完成
class MessageTemplate::ProjectMilestoneCompleted < MessageTemplate
# MessageTemplate::ProjectMilestoneCompleted.get_message_content(User.where(login: 'yystopf'))
def self.get_message_content(receivers, milestone)
receivers.each do |receiver|
if receiver.user_template_message_setting.present?
send_setting = receiver.user_template_message_setting.notification_body["ManageProject::MilestoneCompleted"]
send_setting = send_setting.nil? ? UserTemplateMessageSetting.init_notification_body["ManageProject::MilestoneCompleted"] : send_setting
receivers = receivers.where.not(id: receiver.id) unless send_setting
end
end
return '', '', '' if receivers.blank?
project = milestone&.project
owner = project&.owner
content = sys_notice.gsub('{nickname}', owner&.real_name).gsub('{repository}', project&.name).gsub('{name}', milestone&.name)
url = notification_url.gsub('{owner}', owner&.login).gsub('{identifier}', project&.identifier).gsub('{id}', milestone&.id.to_s)
return receivers_string(receivers), content, url
rescue => e
Rails.logger.info("MessageTemplate::ProjectMilestoneCompleted.get_message_content [ERROR] #{e}")
return '', '', ''
end
def self.get_email_message_content(receiver, milestone)
if receiver.user_template_message_setting.present?
send_setting = receiver.user_template_message_setting.email_body["ManageProject::MilestoneCompleted"]
send_setting = send_setting.nil? ? UserTemplateMessageSetting.init_email_body["ManageProject::MilestoneCompleted"] : send_setting
return '', '', '' unless send_setting
project = milestone&.project
owner = project&.owner
title = email_title
title.gsub!('{nickname}', owner&.real_name)
title.gsub!('{repository}', project&.name)
content = email
content.gsub!('{receiver}', receiver&.real_name)
content.gsub!('{baseurl}', base_url)
content.gsub!('{nickname}', owner&.real_name)
content.gsub!('{repository}', project&.name)
content.gsub!('{login}', owner&.login)
content.gsub!('{identifier}', project&.identifier)
content.gsub!('{id}', milestone&.id.to_s)
content.gsub!('{name}', milestone&.name)
content.gsub!('{platform}', PLATFORM)
return receiver&.mail, title, content
else
return '', '', ''
end
rescue => e
Rails.logger.info("MessageTemplate::ProjectMilestoneCompleted.get_email_message_content [ERROR] #{e}")
return '', '', ''
end
end

View File

@ -12,11 +12,21 @@
# email_title :string(255)
#
# TODO 我管理的仓库被点赞
# 我管理的仓库被点赞
class MessageTemplate::ProjectPraised < MessageTemplate
# MessageTemplate::ProjectPraised.get_message_content(User.where(login: 'yystopf'))
def self.get_message_content(receivers)
def self.get_message_content(receivers, user, project)
receivers.each do |receiver|
if receiver.user_template_message_setting.present?
send_setting = receiver.user_template_message_setting.notification_body["ManageProject::Praised"]
send_setting = send_setting.nil? ? UserTemplateMessageSetting.init_notification_body["ManageProject::Praised"] : send_setting
receivers = receivers.where.not(id: receiver.id) unless send_setting
end
end
return '', '', '' if receivers.blank?
content = sys_notice.gsub('{nickname1}', user&.real_name).gsub('{nickname2}', project&.owner&.real_name).gsub('{repository}', project&.name)
url = notification_url.gsub('{login}', user&.login)
return receivers_string(receivers), content, url
rescue => e
Rails.logger.info("MessageTemplate::ProjectPraised.get_message_content [ERROR] #{e}")

View File

@ -56,6 +56,7 @@ class MessageTemplate::ProjectPullRequest < MessageTemplate
content.gsub!('{identifier}', project&.identifier)
content.gsub!('{id}', pull_request&.id.to_s)
content.gsub!('{title}', pull_request&.title)
content.gsub!('{platform}', PLATFORM)
return receiver&.mail, title, content
else

View File

@ -46,6 +46,7 @@ class MessageTemplate::ProjectRole < MessageTemplate
content.gsub!('{identifier}', project&.identifier)
content.gsub!('{repository}', project&.name)
content.gsub!('{role}', role)
content.gsub!('{platform}', PLATFORM)
return receiver&.mail, title, content
else

View File

@ -141,6 +141,7 @@ class MessageTemplate::ProjectSettingChanged < MessageTemplate
navbar.gsub!('devops', '工作流')
navbar.gsub!('versions', '里程碑')
navbar.gsub!('resources', '资源库')
navbar.gsub!('services', '服务')
if change_count > 1
content.sub!('{ifnavbar}', '<br/>')
else
@ -290,6 +291,7 @@ class MessageTemplate::ProjectSettingChanged < MessageTemplate
navbar.gsub!('devops', '工作流')
navbar.gsub!('versions', '里程碑')
navbar.gsub!('resources', '资源库')
navbar.gsub!('services', '服务')
if change_count > 1
content.sub!('{ifnavbar}', '<br/>')
else
@ -300,6 +302,7 @@ class MessageTemplate::ProjectSettingChanged < MessageTemplate
else
content.gsub!(/({ifnavbar})(.*)({endnavbar})/, '')
end
content.gsub!('{platform}', PLATFORM)
return receiver&.mail, title, content
else

View File

@ -53,6 +53,7 @@ class MessageTemplate::PullRequestAssigned < MessageTemplate
content.gsub!('{baseurl}', base_url)
content.gsub!('{title}', pull_request&.title)
content.gsub!('{id}', pull_request&.id.to_s)
content.gsub!('{platform}', PLATFORM)
return receiver&.mail, title, content
else

View File

@ -118,6 +118,7 @@ class MessageTemplate::PullRequestChanged < MessageTemplate
content.gsub!('{baseurl}', base_url)
content.gsub!('{title}', pull_request&.title)
content.gsub!('{id}', pull_request&.id.to_s)
content.gsub!('{platform}', PLATFORM)
change_count = change_params.keys.size
# 合并请求审查成员修改

View File

@ -51,6 +51,7 @@ class MessageTemplate::PullRequestClosed < MessageTemplate
content.gsub!('{baseurl}', base_url)
content.gsub!('{title}', pull_request&.title)
content.gsub!('{id}', pull_request&.id.to_s)
content.gsub!('{platform}', PLATFORM)
return receiver&.mail, title, content
else

View File

@ -51,6 +51,7 @@ class MessageTemplate::PullRequestMerged < MessageTemplate
content.gsub!('{baseurl}', base_url)
content.gsub!('{title}', pull_request&.title)
content.gsub!('{id}', pull_request&.id.to_s)
content.gsub!('{platform}', PLATFORM)
return receiver&.mail, title, content
else

View File

@ -45,6 +45,7 @@ class MessageTemplate::TeamJoined < MessageTemplate
content.gsub!('{organization}', organization&.real_name)
content.gsub!('{team}', team&.nickname)
content.gsub!('{role}', team&.authorize_name)
content.gsub!('{platform}', PLATFORM)
return receiver&.mail, title, content
else

View File

@ -45,6 +45,7 @@ class MessageTemplate::TeamLeft < MessageTemplate
content.gsub!('{organization}', organization&.real_name)
content.gsub!('{team}', team&.nickname)
content.gsub!('{role}', team&.authorize_name)
content.gsub!('{platform}', PLATFORM)
return receiver&.mail, title, content
else

View File

@ -83,6 +83,10 @@ class Organization < Owner
after_save :reset_cache_data
def gitea_token
team_users.joins(:team).where(teams: {authorize: "owner"}).take&.user&.gitea_token
end
def reset_cache_data
Cache::V2::OwnerCommonService.new(self.id).reset
end

View File

@ -124,9 +124,10 @@ class Project < ApplicationRecord
has_many :pinned_projects, dependent: :destroy
has_many :has_pinned_users, through: :pinned_projects, source: :user
has_many :webhooks, class_name: "Gitea::Webhook", primary_key: :gpid, foreign_key: :repo_id
has_many :user_trace_tasks, dependent: :destroy
after_create :incre_user_statistic, :incre_platform_statistic
after_save :check_project_members, :reset_cache_data
before_save :set_invite_code, :reset_unmember_followed, :set_recommend_and_is_pinned
after_save :check_project_members
before_save :set_invite_code, :reset_unmember_followed, :set_recommend_and_is_pinned, :reset_cache_data
before_destroy :decre_project_common, :decre_forked_from_project_count
after_destroy :decre_user_statistic, :decre_platform_statistic
scope :project_statics_select, -> {select(:id,:name, :is_public, :identifier, :status, :project_type, :user_id, :forked_count, :description, :visits, :project_category_id, :project_language_id, :license_id, :ignore_id, :watchers_count, :created_on)}
@ -150,7 +151,7 @@ class Project < ApplicationRecord
end
def reset_cache_data
CacheAsyncResetJob.perform_later("project_common_service", self.id)
CacheAsyncResetJob.set(wait: 5.seconds).perform_later("project_common_service", self.id)
if changes[:user_id].present?
CacheAsyncSetJob.perform_later("user_statistic_service", {project_count: -1}, changes[:user_id].first)
CacheAsyncSetJob.perform_later("user_statistic_service", {project_count: 1}, changes[:user_id].last)
@ -163,6 +164,14 @@ class Project < ApplicationRecord
CacheAsyncSetJob.perform_later("platform_statistic_service", {project_language_count_key: first_language&.name, project_language_count: -1})
CacheAsyncSetJob.perform_later("platform_statistic_service", {project_language_count_key: last_language&.name, project_language_count: 1})
end
if changes[:is_public].present?
if changes[:is_public][0] && !changes[:is_public][1]
CacheAsyncClearJob.perform_later('project_rank_service', self.id)
end
if !changes[:is_public][0] && changes[:is_public][1]
$redis_cache.srem("v2-project-rank-deleted", self.id)
end
end
end
def decre_project_common

View File

@ -16,7 +16,7 @@
class ProjectUnit < ApplicationRecord
belongs_to :project
enum unit_type: {code: 1, issues: 2, pulls: 3, wiki:4, devops: 5, versions: 6, resources: 7}
enum unit_type: {code: 1, issues: 2, pulls: 3, wiki:4, devops: 5, versions: 6, resources: 7, services: 8}
validates :unit_type, uniqueness: { scope: :project_id}

View File

@ -3,8 +3,8 @@
# Table name: pull_requests
#
# id :integer not null, primary key
# pull_request_id :integer
# gpid :integer
# gitea_id :integer
# gitea_number :integer
# user_id :integer
# created_at :datetime not null
# updated_at :datetime not null
@ -12,7 +12,7 @@
# project_id :integer
# title :string(255)
# milestone :integer
# body :text(65535)
# body :text(4294967295)
# head :string(255)
# base :string(255)
# issue_id :integer

View File

@ -15,7 +15,7 @@ class Site < ApplicationRecord
# add: 添加类链接
# personal: 个人名下类链接,
# common: 普通链接
enum site_type: { add: 0, personal: 1, common: 2 }
enum site_type: { add: 0, personal: 1, common: 2, competition: 3 }
scope :by_search, -> (keyword){ where("name LIKE :keyword OR url LIKE :keyword", keyword: "%#{strip_param(keyword)}%") unless strip_param(keyword).blank? }
scope :by_site_type, -> (site_type){ where(site_type: strip_param(site_type)) unless strip_param(site_type).blank? }

View File

@ -29,6 +29,11 @@ class Team < ApplicationRecord
has_many :team_units, dependent: :destroy
has_many :team_users, dependent: :destroy
scope :like, lambda { |keywords|
sql = "teams.nickname LIKE :search OR teams.name LIKE :search"
where(sql, :search => "%#{keywords.split(" ").join('|')}%") unless keywords.blank?
}
validates :name, uniqueness: {scope: :organization_id}
enum authorize: {read: 1, write: 2, admin: 3, owner: 4}

View File

@ -29,7 +29,7 @@ class TeamUser < ApplicationRecord
before_destroy :remove_project_member
def self.build(organization_id, user_id, team_id)
self.create!(organization_id: organization_id, user_id: user_id, team_id: team_id)
self.find_or_create_by!(organization_id: organization_id, user_id: user_id, team_id: team_id)
end
def remove_project_member

View File

@ -22,6 +22,7 @@ class TemplateMessageSetting < ApplicationRecord
end
def self.build_init_data
TemplateMessageSetting.destroy_all
TemplateMessageSetting::CreateOrAssign.build_init_data
TemplateMessageSetting::ManageProject.build_init_data
TemplateMessageSetting::Normal.build_init_data

View File

@ -27,5 +27,6 @@ class TemplateMessageSetting::CreateOrAssign < TemplateMessageSetting
def self.build_init_data
self.find_or_create_by(name: "疑修状态变更", key: "IssueChanged")
self.find_or_create_by(name: "合并请求状态变更", key: "PullRequestChanged")
self.find_or_create_by(name: "疑修截止日期到达最后一天", key: "IssueExpire", notification_disabled: false)
end
end

View File

@ -29,5 +29,9 @@ class TemplateMessageSetting::ManageProject < TemplateMessageSetting
self.find_or_create_by(name: "有新的合并请求", key: "PullRequest")
self.find_or_create_by(name: "有成员变动", key: "Member")
self.find_or_create_by(name: "仓库设置被更改", key: "SettingChanged")
self.find_or_create_by(name: "被点赞", key: "Praised", notification_disabled: false, email_disabled: true)
self.find_or_create_by(name: "被fork", key: "Forked", notification_disabled: false, email_disabled: true)
self.find_or_create_by(name: "有新的里程碑", key: "Milestone", notification_disabled: false)
self.find_or_create_by(name: "有里程碑已完成", key: "MilestoneCompleted", notification_disabled: false)
end
end

View File

@ -35,6 +35,8 @@ class Topic < ApplicationRecord
'Topic::ExcellentProject'
when 'experience_forum'
'Topic::ExperienceForum'
when "glcc_news"
'Topic::GlccNews'
when 'pinned_forum'
'Topic::PinnedForum'
end

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