diff --git a/.merge_file_a17580 b/.merge_file_a17580
deleted file mode 100644
index 47e471767..000000000
--- a/.merge_file_a17580
+++ /dev/null
@@ -1,529 +0,0 @@
-import React, {Component} from 'react';
-import logo from './logo.svg';
-import './App.css';
-import {LocaleProvider} from 'antd'
-import zhCN from 'antd/lib/locale-provider/zh_CN';
-import {
- BrowserRouter as Router,
- Route,
- Switch
-} from 'react-router-dom';
-import axios from 'axios';
-import '@icedesign/base/dist/ICEDesignBase.css';
-
-import '@icedesign/base/index.scss';
-
-import LoginDialog from './modules/login/LoginDialog';
-import Notcompletedysl from './modules/user/Notcompletedysl';
-import Trialapplicationysl from './modules/login/Trialapplicationysl';
-import Trialapplicationreview from './modules/user/Trialapplicationreview';
-import Addcourses from "./modules/courses/coursesPublic/Addcourses";
-import AccountProfile from"./modules/user/AccountProfile";
-
-
-import Trialapplication from './modules/login/Trialapplication'
-
-import NotFoundPage from './NotFoundPage'
-
-import Loading from './Loading'
-
-import Loadable from 'react-loadable';
-
-
-import moment from 'moment'
-
-import {MuiThemeProvider, createMuiTheme} from 'material-ui/styles';
-
-// import './AppConfig'
-
-import history from './history';
-
-import {SnackbarHOC} from 'educoder'
-import {initAxiosInterceptors} from './AppConfig'
-
-
-// !!!tpi需要这个来加载css
-import {TPMIndexHOC} from './modules/tpm/TPMIndexHOC';
-
-
-const theme = createMuiTheme({
- palette: {
- primary: {
- main: '#4CACFF',
- contrastText: 'rgba(255, 255, 255, 0.87)'
- },
- secondary: {main: '#4CACFF'}, // #11cb5f This is just green.A700 as hex.
- },
-});
-//
-// const Trialapplication= Loadable({
-// loader: () =>import('./modules/login/Trialapplication'),
-// loading:Loading,
-// })
-//登入
-const EducoderLogin = Loadable({
- loader: () => import('./modules/login/EducoderLogin'),
- loading: Loading,
-})
-const TestIndex = Loadable({
- loader: () => import('./modules/test'),
- loading: Loading,
-})
-
-const IndexWrapperComponent = Loadable({
- loader: () => import('./modules/page/IndexWrapper'),
- loading: Loading,
-})
-
-const CommentComponent = Loadable({
- loader: () => import('./modules/comment/CommentContainer'),
- loading: Loading,
-})
-
-const TestMaterialDesignComponent = Loadable({
- loader: () => import('./modules/test/md/TestMaterialDesign'),
- loading: Loading,
-})
-const TestCodeMirrorComponent = Loadable({
- loader: () => import('./modules/test/codemirror/TestCodeMirror'),
- loading: Loading,
-})
-
-const TestComponent = Loadable({
- loader: () => import('./modules/test/TestRC'),
- loading: Loading,
-})
-const TestUrlQueryComponent = Loadable({
- loader: () => import('./modules/test/urlquery/TestUrlQuery'),
- loading: Loading,
-})
-
-const TPMIndexComponent = Loadable({
- loader: () => import('./modules/tpm/TPMIndex'),
- loading: Loading,
-})
-const TPMShixunsIndexComponent = Loadable({
- loader: () => import('./modules/tpm/shixuns/ShixunsIndex'),
- loading: Loading,
-})
-
-//实训课程(原实训路径)
-const ShixunPaths = Loadable({
- loader: () => import('./modules/paths/Index'),
- loading: Loading,
-})
-
-//在线课堂
-const CoursesIndex = Loadable({
- loader: () => import('./modules/courses/Index'),
- loading: Loading,
-})
-const SearchPage = Loadable({
- loader: () => import('./search/SearchPage'),
- loading: Loading,
-})
-
-//教学案例
-const MoopCases = Loadable({
- loader: () => import('./modules/moop_cases/index'),
- loading: Loading,
-})
-
-// 课堂讨论
-// const BoardIndex = Loadable({
-// loader: () => import('./modules/courses/boards/BoardIndex'),
-// loading:Loading,
-// })
-
-// //课堂普通作业&分组作业
-// const CoursesWorkIndex = Loadable({
-// loader: () => import('./modules/courses/busyWork/Index'),
-// loading:Loading,
-// })
-//
-
-// const TPMShixunchildIndexComponent = Loadable({
-// loader: () => import('./modules/tpm/shixunchild/ShixunChildIndex'),
-// loading: Loading,
-// })
-
-
-// const TPMshixunfork_listIndexComponent = Loadable({
-// loader: () => import('./modules/tpm/shixunchild/Shixunfork_list'),
-// loading: Loading,
-// })
-
-
-const ForumsIndexComponent = Loadable({
- loader: () => import('./modules/forums/ForumsIndex'),
- loading: Loading,
-})
-
-// trustie plus forum
-// const TPForumsIndexComponent = Loadable({
-// loader: () => import('./modules/tp-forums/TPForumsIndex'),
-// loading: Loading,
-// })
-
-
-// const TestPageComponent = Loadable({
-// loader: () => import('./modules/page/Index'),
-// loading: Loading,
-// })
-
-
-//新建实训
-const Newshixuns = Loadable({
- loader: () => import('./modules/tpm/newshixuns/Newshixuns'),
- loading: Loading,
-})
-
-
-//实训首页
-const ShixunsHome = Loadable({
- loader: () => import('./modules/home/shixunsHome'),
- loading: Loading,
-})
-
-
-const CompatibilityPageLoadable = Loadable({
- loader: () => import('./modules/common/CompatibilityPage'),
- loading: Loading,
-})
-
-//403页面
-const Shixunauthority = Loadable({
- loader: () => import('./modules/403/Shixunauthority'),
- loading: Loading,
-})
-
-
-//404页面
-const Shixunnopage = Loadable({
- loader: () => import('./modules/404/Shixunnopage'),
- loading: Loading,
-})
-
-//500页面
-const http500 = Loadable({
- loader: () => import('./modules/500/http500'),
- loading: Loading,
-})
-
-// 登录注册
-const LoginRegisterPage = Loadable({
- loader: () => import('./modules/user/LoginRegisterPage'),
- loading: Loading,
-})
-const AccountPage = Loadable({
- loader: () => import('./modules/user/AccountPage'),
- loading: Loading,
-})
-
-// 个人主页
-const UsersInfo = Loadable({
- loader: () => import('./modules/user/usersInfo/Infos'),
- loading: Loading,
-})
-
-// 兴趣页面
-const Interestpage = Loadable({
- loader: () => import('./modules/login/EducoderInteresse'),
- loading: Loading,
-})
-
-//众包创新
-const ProjectPackages=Loadable({
- loader: () => import('./modules/projectPackages/ProjectPackageIndex'),
- loading: Loading,
-})
-
-class App extends Component {
- constructor(props) {
- super(props)
- // this.state = {
- // isRenders:false,
- // }
-
- }
-
- componentDidMount() {
- // force an update if the URL changes
- history.listen(() => {
- this.forceUpdate()
- const $ = window.$
- // https://www.trustie.net/issues/21919 可能会有问题
- $("html").animate({ scrollTop: $('html').scrollTop() - 0 })
- });
-
- initAxiosInterceptors(this.props)
-
- //
- // axios.interceptors.response.use((response) => {
- // // console.log("response"+response);
- // if(response!=undefined)
- // // console.log("response"+response.data.statu);
- // if (response&&response.data.status === 407) {
- // this.setState({
- // isRenders: true,
- // })
- // }
- // return response;
- // }, (error) => {
- // //TODO 这里如果样式变了会出现css不加载的情况
- // });
- }
- //修改登录方法
- Modifyloginvalue=()=>{
- this.setState({
- isRender:false,
- })
- }
-
- render() {
-
-
- return (
- <%= notice %> 说明:该界面适用于存储全局变量 <%= notice %>
- Name:
- <%= @edu_setting.name %>
-
- Value:
- <%= @edu_setting.value %>
- 获取用户消息列表 示例: 返回的JSON示例: 发送消息, 目前只支持atme 示例: 请求的JSON示例: 返回的JSON示例: 阅读消息 示例: 返回的JSON示例: 删除消息 示例: 返回的JSON示例: 更改用户信息
')
+ else
+ content.sub!('{ifassigner}', '')
+ end
+ content.sub!('{endassigner}', '')
+ content.gsub!('{assigner1}', assigner1.present? ? assigner1&.real_name : '未指派成员')
+ content.gsub!('{assigner2}', assigner2.present? ? assigner2&.real_name : '未指派成员')
+ else
+ content.gsub!(/({ifassigner})(.*)({endassigner})/, '')
+ end
+ # 易修状态修改
+ if change_params[:status_id].present?
+ status1 = IssueStatus.find_by_id(change_params[:status_id][0])
+ status2 = IssueStatus.find_by_id(change_params[:status_id][1])
+ if change_count > 1
+ content.sub!('{ifstatus}', '
')
+ else
+ content.sub!('{ifstatus}', '')
+ end
+ content.sub!('{endstatus}', '')
+ content.gsub!('{status1}', status1&.name)
+ content.gsub!('{status2}', status2&.name)
+ else
+ content.gsub!(/({ifstatus})(.*)({endstatus})/, '')
+ end
+ # 易修类型修改
+ if change_params[:tracker_id].present?
+ tracker1 = Tracker.find_by_id(change_params[:tracker_id][0])
+ tracker2 = Tracker.find_by_id(change_params[:tracker_id][1])
+ if change_count > 1
+ content.sub!('{iftracker}', '
')
+ else
+ content.sub!('{iftracker}', '')
+ end
+ content.sub!('{endtracker}', '')
+ content.gsub!('{tracker1}', tracker1&.name)
+ content.gsub!('{tracker2}', tracker2&.name)
+ else
+ content.gsub!(/({iftracker})(.*)({endtracker})/, '')
+ end
+ # 易修里程碑修改
+ if change_params[:fixed_version_id].present?
+ fix_version1 = Version.find_by_id(change_params[:fixed_version_id][0])
+ fix_version2 = Version.find_by_id(change_params[:fixed_version_id][1])
+ if change_count > 1
+ content.sub!('{ifmilestone}', '
')
+ else
+ content.sub!('{ifmilestone}', '')
+ end
+ content.sub!('{endmilestone}', '')
+ content.gsub!('{milestone1}', fix_version1.present? ? fix_version1&.name : '未选择里程碑')
+ content.gsub!('{milestone2}', fix_version2.present? ? fix_version2&.name : '未选择里程碑')
+ else
+ content.gsub!(/({ifmilestone})(.*)({endmilestone})/, '')
+ end
+ # 易修标记修改
+ if change_params[:issue_tags_value].present?
+ issue_tags1 = IssueTag.where(id: change_params[:issue_tags_value][0]).distinct
+ issue_tags2 = IssueTag.where(id: change_params[:issue_tags_value][1]).distinct
+ tag1 = issue_tags1.pluck(:name).join(",").blank? ? '未选择标记' : issue_tags1.pluck(:name).join(",")
+ tag2 = issue_tags2.pluck(:name).join(",").blank? ? '未选择标记' : issue_tags2.pluck(:name).join(",")
+ if change_count > 1
+ content.sub!('{iftag}', '
')
+ else
+ content.sub!('{iftag}', '')
+ end
+ content.sub!('{endtag}', '')
+ content.gsub!('{tag1}', tag1)
+ content.gsub!('{tag2}', tag2)
+ else
+ content.gsub!(/({iftag})(.*)({endtag})()/, '')
+ end
+ # 易修优先级修改
+ if change_params[:priority_id].present?
+ priority1 = IssuePriority.find_by_id(change_params[:priority_id][0])
+ priority2 = IssuePriority.find_by_id(change_params[:priority_id][1])
+ if change_count > 1
+ content.sub!('{ifpriority}', '
')
+ else
+ content.sub!('{ifpriority}', '')
+ end
+ content.sub!('{endpriority}', '')
+ content.gsub!('{priority1}', priority1&.name)
+ content.gsub!('{priority2}', priority2&.name)
+ else
+ content.gsub!(/({ifpriority})(.*)({endpriority})/, '')
+ end
+ # 易修完成度修改
+ if change_params[:done_ratio].present?
+ doneratio1 = change_params[:done_ratio][0]
+ doneratio2 = change_params[:done_ratio][1]
+ if change_count > 1
+ content.sub!('{ifdoneratio}', '
')
+ else
+ content.sub!('{ifdoneratio}', '')
+ end
+ content.sub!('{enddoneratio}', '')
+ content.gsub!('{doneratio1}', "#{doneratio1}%")
+ content.gsub!('{doneratio2}', "#{doneratio2}%")
+ else
+ content.gsub!(/({ifdoneratio})(.*)({enddoneratio})/, '')
+ end
+ # 易修指定分支修改
+ if change_params[:branch_name].present?
+ branch1 = change_params[:branch_name][0].blank? ? '分支未指定' : change_params[:branch_name][0]
+ branch2 = change_params[:branch_name][1].blank? ? '分支未指定' : change_params[:branch_name][1]
+ if change_count > 1
+ content.sub!('{ifbranch}', '
')
+ else
+ content.sub!('{ifbranch}', '')
+ end
+ content.sub!('{endbranch}', '')
+ content.gsub!('{branch1}', branch1)
+ content.gsub!('{branch2}', branch2)
+ else
+ content.gsub!(/({ifbranch})(.*)({endbranch})/, '')
+ end
+ # 易修开始日期修改
+ if change_params[:start_date].present?
+ startdate1 = change_params[:start_date][0].blank? ? "未选择开始日期" : change_params[:start_date][0]
+ startdate2 = change_params[:start_date][1].blank? ? "未选择开始日期" : change_params[:start_date][1]
+ if change_count > 1
+ content.sub!('{ifstartdate}', '
')
+ else
+ content.sub!('{ifstartdate}', '')
+ end
+ content.sub!('{endstartdate}', '')
+ content.gsub!('{startdate1}', startdate1 )
+ content.gsub!('{startdate2}', startdate2)
+ else
+ content.gsub!(/({ifstartdate})(.*)({endstartdate})/, '')
+ end
+ # 易修结束日期修改
+ if change_params[:due_date].present?
+ duedate1 = change_params[:due_date][0].blank? ? '未选择结束日期' : change_params[:due_date][0]
+ duedate2 = change_params[:due_date][1].blank? ? '未选择结束日期' : change_params[:due_date][1]
+ if change_count > 1
+ content.sub!('{ifduedate}', '
')
+ else
+ content.sub!('{ifduedate}', '')
+ end
+ content.sub!('{endduedate}', '')
+ content.gsub!('{duedate1}', duedate1)
+ content.gsub!('{duedate2}', duedate2)
+ else
+ content.gsub!(/({ifduedate})(.*)({endduedate})/, '')
+ end
+ return receivers_string(receivers), content, url
+ rescue => e
+ Rails.logger.info("MessageTemplate::IssueAssigned.get_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+
+ def self.get_email_message_content(receiver, operator, issue, change_params)
+ if receiver.user_template_message_setting.present?
+ return '', '', '' unless receiver.user_template_message_setting.email_body["CreateOrAssign::IssueChanged"]
+ end
+ project = issue&.project
+ owner = project&.owner
+ title = email_title
+ title.gsub!('{title}', issue&.subject)
+ content = email
+ content.gsub!('{receiver}', receiver&.real_name)
+ content.gsub!('{baseurl}', base_url)
+ content.gsub!('{login1}', operator&.login)
+ content.gsub!('{nickname1}', operator&.real_name)
+ content.gsub!('{login2}', owner&.login)
+ content.gsub!('{nickname2}', owner&.real_name)
+ content.gsub!('{identifier}', project&.identifier)
+ content.gsub!('{repository}', project&.name)
+ content.gsub!('{title}', issue&.subject)
+ content.gsub!('{id}', issue&.id.to_s)
+ change_count = change_params.keys.size
+ # 易修负责人修改
+ if change_params[:assigned_to_id].present?
+ assigner1 = User.find_by_id(change_params[:assigned_to_id][0])
+ assigner2 = User.find_by_id(change_params[:assigned_to_id][1])
+ if change_count > 1
+ content.sub!('{ifassigner}', '
')
+ else
+ content.sub!('{ifassigner}', '')
+ end
+ content.sub!('{endassigner}', '')
+ content.gsub!('{assigner1}', assigner1.present? ? assigner1&.real_name : '未指派成员')
+ content.gsub!('{assigner2}', assigner2.present? ? assigner2&.real_name : '未指派成员')
+ else
+ content.gsub!(/({ifassigner})(.*)({endassigner})/, '')
+ end
+ # 易修状态修改
+ if change_params[:status_id].present?
+ status1 = IssueStatus.find_by_id(change_params[:status_id][0])
+ status2 = IssueStatus.find_by_id(change_params[:status_id][1])
+ if change_count > 1
+ content.sub!('{ifstatus}', '
')
+ else
+ content.sub!('{ifstatus}', '')
+ end
+ content.sub!('{endstatus}', '')
+ content.gsub!('{status1}', status1&.name)
+ content.gsub!('{status2}', status2&.name)
+ else
+ content.gsub!(/({ifstatus})(.*)({endstatus})/, '')
+ end
+ # 易修类型修改
+ if change_params[:tracker_id].present?
+ tracker1 = Tracker.find_by_id(change_params[:tracker_id][0])
+ tracker2 = Tracker.find_by_id(change_params[:tracker_id][1])
+ if change_count > 1
+ content.sub!('{iftracker}', '
')
+ else
+ content.sub!('{iftracker}', '')
+ end
+ content.sub!('{endtracker}', '')
+ content.gsub!('{tracker1}', tracker1&.name)
+ content.gsub!('{tracker2}', tracker2&.name)
+ else
+ content.gsub!(/({iftracker})(.*)({endtracker})/, '')
+ end
+ # 易修里程碑修改
+ if change_params[:fixed_version_id].present?
+ fix_version1 = Version.find_by_id(change_params[:fixed_version_id][0])
+ fix_version2 = Version.find_by_id(change_params[:fixed_version_id][1])
+ if change_count > 1
+ content.sub!('{ifmilestone}', '
')
+ else
+ content.sub!('{ifmilestone}', '')
+ end
+ content.sub!('{endmilestone}', '')
+ content.gsub!('{milestone1}', fix_version1.present? ? fix_version1&.name : '未选择里程碑')
+ content.gsub!('{milestone2}', fix_version2.present? ? fix_version2&.name : '未选择里程碑')
+ else
+ content.gsub!(/({ifmilestone})(.*)({endmilestone})/, '')
+ end
+ # 易修标记修改
+ if change_params[:issue_tags_value].present?
+ issue_tags1 = IssueTag.where(id: change_params[:issue_tags_value][0]).distinct
+ issue_tags2 = IssueTag.where(id: change_params[:issue_tags_value][1]).distinct
+ tag1 = issue_tags1.pluck(:name).join(",").blank? ? '未选择标记' : issue_tags1.pluck(:name).join(",")
+ tag2 = issue_tags2.pluck(:name).join(",").blank? ? '未选择标记' : issue_tags2.pluck(:name).join(",")
+ if change_count > 1
+ content.sub!('{iftag}', '
')
+ else
+ content.sub!('{iftag}', '')
+ end
+ content.sub!('{endtag}', '')
+ content.gsub!('{tag1}', tag1)
+ content.gsub!('{tag2}', tag2)
+ else
+ content.gsub!(/({iftag})(.*)({endtag})()/, '')
+ end
+ # 易修优先级修改
+ if change_params[:priority_id].present?
+ priority1 = IssuePriority.find_by_id(change_params[:priority_id][0])
+ priority2 = IssuePriority.find_by_id(change_params[:priority_id][1])
+ if change_count > 1
+ content.sub!('{ifpriority}', '
')
+ else
+ content.sub!('{ifpriority}', '')
+ end
+ content.sub!('{endpriority}', '')
+ content.gsub!('{priority1}', priority1&.name)
+ content.gsub!('{priority2}', priority2&.name)
+ else
+ content.gsub!(/({ifpriority})(.*)({endpriority})/, '')
+ end
+ # 易修完成度修改
+ if change_params[:done_ratio].present?
+ doneratio1 = change_params[:done_ratio][0]
+ doneratio2 = change_params[:done_ratio][1]
+ if change_count > 1
+ content.sub!('{ifdoneratio}', '
')
+ else
+ content.sub!('{ifdoneratio}', '')
+ end
+ content.sub!('{enddoneratio}', '')
+ content.gsub!('{doneratio1}', "#{doneratio1}%")
+ content.gsub!('{doneratio2}', "#{doneratio2}%")
+ else
+ content.gsub!(/({ifdoneratio})(.*)({enddoneratio})/, '')
+ end
+ # 易修指定分支修改
+ if change_params[:branch_name].present?
+ branch1 = change_params[:branch_name][0].blank? ? '分支未指定' : change_params[:branch_name][0]
+ branch2 = change_params[:branch_name][1].blank? ? '分支未指定' : change_params[:branch_name][1]
+ if change_count > 1
+ content.sub!('{ifbranch}', '
')
+ else
+ content.sub!('{ifbranch}', '')
+ end
+ content.sub!('{endbranch}', '')
+ content.gsub!('{branch1}', branch1)
+ content.gsub!('{branch2}', branch2)
+ else
+ content.gsub!(/({ifbranch})(.*)({endbranch})/, '')
+ end
+ # 易修开始日期修改
+ if change_params[:start_date].present?
+ startdate1 = change_params[:start_date][0].blank? ? "未选择开始日期" : change_params[:start_date][0]
+ startdate2 = change_params[:start_date][1].blank? ? "未选择开始日期" : change_params[:start_date][1]
+ if change_count > 1
+ content.sub!('{ifstartdate}', '
')
+ else
+ content.sub!('{ifstartdate}', '')
+ end
+ content.sub!('{endstartdate}', '')
+ content.gsub!('{startdate1}', startdate1 )
+ content.gsub!('{startdate2}', startdate2)
+ else
+ content.gsub!(/({ifstartdate})(.*)({endstartdate})/, '')
+ end
+ # 易修结束日期修改
+ if change_params[:due_date].present?
+ duedate1 = change_params[:due_date][0].blank? ? '未选择结束日期' : change_params[:due_date][0]
+ duedate2 = change_params[:due_date][1].blank? ? '未选择结束日期' : change_params[:due_date][1]
+ if change_count > 1
+ content.sub!('{ifduedate}', '
')
+ else
+ content.sub!('{ifduedate}', '')
+ end
+ content.sub!('{endduedate}', '')
+ content.gsub!('{duedate1}', duedate1)
+ content.gsub!('{duedate2}', duedate2)
+ else
+ content.gsub!(/({ifduedate})(.*)({endduedate})/, '')
+ end
+
+ return receiver&.mail, title, content
+ rescue => e
+ Rails.logger.info("MessageTemplate::IssueChanged.get_email_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+end
diff --git a/app/models/message_template/issue_creator_expire.rb b/app/models/message_template/issue_creator_expire.rb
new file mode 100644
index 000000000..38ef2fe29
--- /dev/null
+++ b/app/models/message_template/issue_creator_expire.rb
@@ -0,0 +1,29 @@
+# == 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
diff --git a/app/models/message_template/issue_deleted.rb b/app/models/message_template/issue_deleted.rb
new file mode 100644
index 000000000..c08ee0439
--- /dev/null
+++ b/app/models/message_template/issue_deleted.rb
@@ -0,0 +1,51 @@
+# == 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::IssueDeleted < MessageTemplate
+
+ # MessageTemplate::IssueDeleted.get_message_content(User.where(login: 'yystopf'), User.last, "hahah")
+ def self.get_message_content(receivers, operator, issue_title)
+ receivers.each do |receiver|
+ if receiver.user_template_message_setting.present?
+ receivers = receivers.where.not(id: receiver.id) unless receiver.user_template_message_setting.notification_body["CreateOrAssign::IssueChanged"]
+ end
+ end
+ return '', '', '' if receivers.blank?
+ content = sys_notice.gsub('{nickname}', operator&.real_name).gsub('{title}', issue_title)
+ return receivers_string(receivers), content, notification_url
+ rescue => e
+ Rails.logger.info("MessageTemplate::IssueDeleted.get_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+
+ def self.get_email_message_content(receiver, operator, issue_title)
+ if receiver.user_template_message_setting.present?
+ return '', '', '' unless receiver.user_template_message_setting.email_body["CreateOrAssign::IssueChanged"]
+ end
+ title = email_title
+ title.gsub!('{title}', issue_title)
+ content = email
+ content.gsub!('{receiver}', receiver&.real_name)
+ content.gsub!('{nickname}', operator&.real_name)
+ content.gsub!('{login}', operator&.login)
+ content.gsub!('{baseurl}', base_url)
+ content.gsub!('{title}', issue_title)
+
+ return receiver&.mail, title, content
+ rescue => e
+ Rails.logger.info("MessageTemplate::IssueDeleted.get_email_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+end
diff --git a/app/models/message_template/issue_journal.rb b/app/models/message_template/issue_journal.rb
new file mode 100644
index 000000000..0b3851475
--- /dev/null
+++ b/app/models/message_template/issue_journal.rb
@@ -0,0 +1,25 @@
+# == 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)
+#
+
+# TODO 我创建或负责的易修有新的评论
+class MessageTemplate::IssueJournal < MessageTemplate
+
+ # MessageTemplate::IssueJournal.get_message_content(User.where(login: 'yystopf'))
+ def self.get_message_content(receivers)
+ return receivers_string(receivers), content, url
+ rescue => e
+ Rails.logger.info("MessageTemplate::IssueJournal.get_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+end
diff --git a/app/models/message_template/login_ip_tip.rb b/app/models/message_template/login_ip_tip.rb
new file mode 100644
index 000000000..5c7caa936
--- /dev/null
+++ b/app/models/message_template/login_ip_tip.rb
@@ -0,0 +1,25 @@
+# == 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)
+#
+
+# TODO 登录异常提示
+class MessageTemplate::LoginIpTip < MessageTemplate
+
+ # MessageTemplate::LoginIpTip.get_message_content(User.where(login: 'yystopf'))
+ def self.get_message_content(receivers)
+ return receivers_string(receivers), content, url
+ rescue => e
+ Rails.logger.info("MessageTemplate::LoginIpTip.get_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+end
diff --git a/app/models/message_template/organization_joined.rb b/app/models/message_template/organization_joined.rb
new file mode 100644
index 000000000..22cfb48d0
--- /dev/null
+++ b/app/models/message_template/organization_joined.rb
@@ -0,0 +1,51 @@
+# == 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::OrganizationJoined < MessageTemplate
+
+ # MessageTemplate::OrganizationJoined.get_message_content(User.where(login: 'yystopf'), Organization.last)
+ def self.get_message_content(receivers, organization)
+ receivers.each do |receiver|
+ if receiver.user_template_message_setting.present?
+ receivers = receivers.where.not(id: receiver.id) unless receiver.user_template_message_setting.notification_body["Normal::Organization"]
+ end
+ end
+ return '', '', '' if receivers.blank?
+ content = sys_notice.gsub('{organization}', organization&.real_name)
+ url = notification_url.gsub('{login}', organization&.name)
+ return receivers_string(receivers), content, url
+ rescue => e
+ Rails.logger.info("MessageTemplate::OrganizationJoined.get_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+
+ def self.get_email_message_content(receiver, organization)
+ if receiver.user_template_message_setting.present?
+ return '', '', '' unless receiver.user_template_message_setting.email_body["Normal::Organization"]
+ end
+ title = email_title
+ title.gsub!('{organization}', organization&.real_name)
+ content = email
+ content.gsub!('{receiver}', receiver&.real_name)
+ content.gsub!('{baseurl}', base_url)
+ content.gsub!('{login}', organization&.login)
+ content.gsub!('{organization}', organization&.real_name)
+
+ return receiver&.mail, title, content
+ rescue => e
+ Rails.logger.info("MessageTemplate::OrganizationJoined.get_email_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+end
diff --git a/app/models/message_template/organization_left.rb b/app/models/message_template/organization_left.rb
new file mode 100644
index 000000000..eee752f05
--- /dev/null
+++ b/app/models/message_template/organization_left.rb
@@ -0,0 +1,51 @@
+# == 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::OrganizationLeft < MessageTemplate
+
+ # MessageTemplate::OrganizationLeft.get_message_content(User.where(login: 'yystopf'), Organization.last)
+ def self.get_message_content(receivers, organization)
+ receivers.each do |receiver|
+ if receiver.user_template_message_setting.present?
+ receivers = receivers.where.not(id: receiver.id) unless receiver.user_template_message_setting.notification_body["Normal::Organization"]
+ end
+ end
+ return '', '', '' if receivers.blank?
+ content = sys_notice.gsub('{organization}', organization&.real_name)
+ url = notification_url.gsub('{login}', organization&.name)
+ return receivers_string(receivers), content, url
+ rescue => e
+ Rails.logger.info("MessageTemplate::OrganizationLeft.get_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+
+ def self.get_email_message_content(receiver, organization)
+ if receiver.user_template_message_setting.present?
+ return '', '', '' unless receiver.user_template_message_setting.email_body["Normal::Organization"]
+ end
+ title = email_title
+ title.gsub!('{organization}', organization&.real_name)
+ content = email
+ content.gsub!('{receiver}', receiver&.real_name)
+ content.gsub!('{baseurl}', base_url)
+ content.gsub!('{login}', organization&.login)
+ content.gsub!('{organization}', organization&.real_name)
+
+ return receiver&.mail, title, content
+ rescue => e
+ Rails.logger.info("MessageTemplate::OrganizationLeft.get_email_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+end
diff --git a/app/models/message_template/organization_role.rb b/app/models/message_template/organization_role.rb
new file mode 100644
index 000000000..b6024f614
--- /dev/null
+++ b/app/models/message_template/organization_role.rb
@@ -0,0 +1,53 @@
+# == 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::OrganizationRole < MessageTemplate
+
+ # MessageTemplate::OrganizationRole.get_message_content(User.where(login: 'yystopf'), Organization.last, '管理员')
+ def self.get_message_content(receivers, organization, role)
+ receivers.each do |receiver|
+ if receiver.user_template_message_setting.present?
+ receivers = receivers.where.not(id: receiver.id) unless receiver.user_template_message_setting.notification_body["Normal::Permission"]
+ end
+ end
+ return '', '', '' if receivers.blank?
+ content = sys_notice.gsub('{organization}', organization&.real_name).gsub('{role}', role)
+ url = notification_url.gsub('{login}', organization&.login)
+ return receivers_string(receivers), content, url
+ rescue => e
+ Rails.logger.info("MessageTemplate::OrganizationRole.get_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+
+ def self.get_email_message_content(receiver, organization, role)
+ if receiver.user_template_message_setting.present?
+ return '', '', '' unless receiver.user_template_message_setting.email_body["Normal::Permission"]
+ end
+ title = email_title
+ title.gsub!('{organization}', organization&.real_name)
+ title.gsub!('{role}', role)
+ content = email
+ content.gsub!('{receiver}', receiver&.real_name)
+ content.gsub!('{baseurl}', base_url)
+ content.gsub!('{login}', organization&.login)
+ content.gsub!('{organization}', organization&.real_name)
+ content.gsub!('{role}', role)
+
+ return receiver&.mail, title, content
+ rescue => e
+ Rails.logger.info("MessageTemplate::OrganizationRole.get_email_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+end
diff --git a/app/models/message_template/project_deleted.rb b/app/models/message_template/project_deleted.rb
new file mode 100644
index 000000000..aa45e818e
--- /dev/null
+++ b/app/models/message_template/project_deleted.rb
@@ -0,0 +1,25 @@
+# == 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)
+#
+
+# TODO 我关注的仓库被删除
+class MessageTemplate::ProjectDeleted < MessageTemplate
+
+ # MessageTemplate::ProjectDeleted.get_message_content(User.where(login: 'yystopf'))
+ def self.get_message_content(receivers)
+ return receivers_string(receivers), content, url
+ rescue => e
+ Rails.logger.info("MessageTemplate::ProjectDeleted.get_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+end
diff --git a/app/models/message_template/project_followed.rb b/app/models/message_template/project_followed.rb
new file mode 100644
index 000000000..e9dd9a2a8
--- /dev/null
+++ b/app/models/message_template/project_followed.rb
@@ -0,0 +1,25 @@
+# == 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)
+#
+
+# TODO 我管理的仓库被关注
+class MessageTemplate::ProjectFollowed < MessageTemplate
+
+ # MessageTemplate::ProjectFollowed.get_message_content(User.where(login: 'yystopf'))
+ def self.get_message_content(receivers)
+ return receivers_string(receivers), content, url
+ rescue => e
+ Rails.logger.info("MessageTemplate::ProjectFollowed.get_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+end
diff --git a/app/models/message_template/project_forked.rb b/app/models/message_template/project_forked.rb
new file mode 100644
index 000000000..7cd17222d
--- /dev/null
+++ b/app/models/message_template/project_forked.rb
@@ -0,0 +1,25 @@
+# == 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)
+#
+
+# TODO 我管理的仓库被复刻
+class MessageTemplate::ProjectForked < MessageTemplate
+
+ # MessageTemplate::ProjectForked.get_message_content(User.where(login: 'yystopf'))
+ def self.get_message_content(receivers)
+ return receivers_string(receivers), content, url
+ rescue => e
+ Rails.logger.info("MessageTemplate::ProjectForked.get_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+end
diff --git a/app/models/message_template/project_issue.rb b/app/models/message_template/project_issue.rb
new file mode 100644
index 000000000..9106bcc8f
--- /dev/null
+++ b/app/models/message_template/project_issue.rb
@@ -0,0 +1,66 @@
+# == 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)
+#
+
+# TODO 我管理/关注的仓库有新的易修
+class MessageTemplate::ProjectIssue < MessageTemplate
+
+ # MessageTemplate::ProjectIssue.get_message_content(User.where(login: 'yystopf'), User.where(login: 'forgetest1'), User.last, Issue.last)
+ def self.get_message_content(managers, followers, operator, issue)
+ managers.each do |receiver|
+ if receiver.user_template_message_setting.present?
+ managers = managers.where.not(id: receiver.id) unless receiver.user_template_message_setting.notification_body["ManageProject::Issue"]
+ end
+ end
+ project = issue&.project
+ owner = project&.owner
+ receivers = managers + followers
+ return '', '', '' if receivers.blank?
+ content = sys_notice.gsub('{nickname1}', operator&.real_name).gsub('{nickname2}', owner&.real_name).gsub('{repository}', project&.name).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::ProjectIssue.get_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+
+ def self.get_email_message_content(receiver, is_manager, operator, issue)
+ if receiver.user_template_message_setting.present? && is_manager
+ return '', '', '' unless receiver.user_template_message_setting.email_body["ManageProject::Issue"]
+ end
+ project = issue&.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!('{login1}', operator&.login)
+ content.gsub!('{nickname1}', operator&.real_name)
+ content.gsub!('{nickname2}', owner&.real_name)
+ content.gsub!('{repository}', project&.name)
+ content.gsub!('{login2}', owner&.login)
+ content.gsub!('{identifier}', project&.identifier)
+ content.gsub!('{id}', issue&.id.to_s)
+ content.gsub!('{title}', issue&.subject)
+
+ return receiver&.mail, title, content
+ rescue => e
+ Rails.logger.info("MessageTemplate::ProjectIssue.get_email_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+end
diff --git a/app/models/message_template/project_joined.rb b/app/models/message_template/project_joined.rb
new file mode 100644
index 000000000..b46dc51a7
--- /dev/null
+++ b/app/models/message_template/project_joined.rb
@@ -0,0 +1,54 @@
+# == 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::ProjectJoined < MessageTemplate
+
+ # MessageTemplate::ProjectJoined.get_message_content(User.where(login: 'yystopf'), Project.last)
+ def self.get_message_content(receivers, project)
+ receivers.each do |receiver|
+ if receiver.user_template_message_setting.present?
+ receivers = receivers.where.not(id: receiver.id) unless receiver.user_template_message_setting.notification_body["Normal::Project"]
+ end
+ end
+ return '', '', '' if receivers.blank?
+ content = sys_notice.gsub('{repository}', project&.name)
+ url = notification_url.gsub('{owner}', project&.owner&.login).gsub('{identifier}', project&.identifier)
+ return receivers_string(receivers), content, url
+ rescue => e
+ Rails.logger.info("MessageTemplate::ProjectJoined.get_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+
+ def self.get_email_message_content(receiver, project)
+ if receiver.user_template_message_setting.present?
+ return '', '', '' unless receiver.user_template_message_setting.email_body["Normal::Project"]
+ end
+ title = email_title
+ title.gsub!('{repository}', project&.name)
+
+ content = email
+ content.gsub!('{receiver}', receiver&.real_name)
+ content.gsub!('{baseurl}', base_url)
+ content.gsub!('{login}', project&.owner&.login)
+ content.gsub!('{identifier}', project&.identifier)
+ content.gsub!('{nickname}', project&.owner&.real_name)
+ content.gsub!('{repository}', project&.name)
+
+ return receiver&.mail, title, content
+ rescue => e
+ Rails.logger.info("MessageTemplate::ProjectJoined.get_email_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+end
diff --git a/app/models/message_template/project_left.rb b/app/models/message_template/project_left.rb
new file mode 100644
index 000000000..3dfa7bb61
--- /dev/null
+++ b/app/models/message_template/project_left.rb
@@ -0,0 +1,53 @@
+# == 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::ProjectLeft < MessageTemplate
+
+ # MessageTemplate::ProjectLeft.get_message_content(User.where(login: 'yystopf'), Project.last)
+ def self.get_message_content(receivers, project)
+ receivers.each do |receiver|
+ if receiver.user_template_message_setting.present?
+ receivers = receivers.where.not(id: receiver.id) unless receiver.user_template_message_setting.notification_body["Normal::Project"]
+ end
+ end
+ content = sys_notice.gsub('{repository}', project&.name)
+ url = notification_url.gsub('{owner}', project&.owner&.login).gsub('{identifier}', project&.identifier)
+ return receivers_string(receivers), content, url
+ rescue => e
+ Rails.logger.info("MessageTemplate::ProjectLeft.get_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+
+ def self.get_email_message_content(receiver, project)
+ if receiver.user_template_message_setting.present?
+ return '', '', '' unless receiver.user_template_message_setting.email_body["Normal::Project"]
+ end
+ title = email_title
+ title.gsub!('{repository}', project&.name)
+
+ content = email
+ content.gsub!('{receiver}', receiver&.real_name)
+ content.gsub!('{baseurl}', base_url)
+ content.gsub!('{login}', project&.owner&.login)
+ content.gsub!('{identifier}', project&.identifier)
+ content.gsub!('{nickname}', project&.owner&.real_name)
+ content.gsub!('{repository}', project&.name)
+
+ return receiver&.mail, title, content
+ rescue => e
+ Rails.logger.info("MessageTemplate::ProjectLeft.get_email_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+end
diff --git a/app/models/message_template/project_member_joined.rb b/app/models/message_template/project_member_joined.rb
new file mode 100644
index 000000000..7a781750c
--- /dev/null
+++ b/app/models/message_template/project_member_joined.rb
@@ -0,0 +1,58 @@
+# == 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::ProjectMemberJoined < MessageTemplate
+
+ # MessageTemplate::ProjectMemberJoined.get_message_content(User.where(login: 'yystopf'))
+ def self.get_message_content(receivers, user, project)
+ receivers.each do |receiver|
+ if receiver.user_template_message_setting.present?
+ receivers = receivers.where.not(id: receiver.id) unless receiver.user_template_message_setting.notification_body["ManageProject::Member"]
+ 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}', project&.owner&.login).gsub('{identifier}', project&.identifier)
+ return receivers_string(receivers), content, url
+ rescue => e
+ Rails.logger.info("MessageTemplate::ProjectMemberJoined.get_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+
+ def self.get_email_message_content(receiver, user, project)
+ if receiver.user_template_message_setting.present?
+ return '', '', '' unless receiver.user_template_message_setting.email_body["ManageProject::Member"]
+ end
+ title = email_title
+ title.gsub!('{nickname1}', user&.real_name)
+ title.gsub!('{nickname2}', project&.owner&.real_name)
+ title.gsub!('{repository}', project&.name)
+
+ content = email
+ content.gsub!('{receiver}', receiver&.real_name)
+ content.gsub!('{baseurl}', base_url)
+ content.gsub!('{login1}', user&.login)
+ content.gsub!('{login2}', project&.owner&.login)
+ content.gsub!('{identifier}', project&.identifier)
+ content.gsub!('{nickname1}', user&.real_name)
+ content.gsub!('{nickname2}', project&.owner&.real_name)
+ content.gsub!('{repository}', project&.name)
+
+ return receiver&.mail, title, content
+ rescue => e
+ Rails.logger.info("MessageTemplate::ProjectMemberJoined.get_email_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+end
diff --git a/app/models/message_template/project_member_left.rb b/app/models/message_template/project_member_left.rb
new file mode 100644
index 000000000..f41791233
--- /dev/null
+++ b/app/models/message_template/project_member_left.rb
@@ -0,0 +1,58 @@
+# == 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::ProjectMemberLeft < MessageTemplate
+
+ # MessageTemplate::ProjectMemberLeft.get_message_content(User.where(login: 'yystopf'), User.last, Project.last)
+ def self.get_message_content(receivers, user, project)
+ receivers.each do |receiver|
+ if receiver.user_template_message_setting.present?
+ receivers = receivers.where.not(id: receiver.id) unless receiver.user_template_message_setting.notification_body["ManageProject::Member"]
+ 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}', project&.owner&.login).gsub('{identifier}', project&.identifier)
+ return receivers_string(receivers), content, url
+ rescue => e
+ Rails.logger.info("MessageTemplate::ProjectMemberLeft.get_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+
+ def self.get_email_message_content(receiver, user, project)
+ if receiver.user_template_message_setting.present?
+ return '', '', '' unless receiver.user_template_message_setting.email_body["ManageProject::Member"]
+ end
+ title = email_title
+ title.gsub!('{nickname1}', user&.real_name)
+ title.gsub!('{nickname2}', project&.owner&.real_name)
+ title.gsub!('{repository}', project&.name)
+
+ content = email
+ content.gsub!('{receiver}', receiver&.real_name)
+ content.gsub!('{baseurl}', base_url)
+ content.gsub!('{login1}', user&.login)
+ content.gsub!('{login2}', project&.owner&.login)
+ content.gsub!('{identifier}', project&.identifier)
+ content.gsub!('{nickname1}', user&.real_name)
+ content.gsub!('{nickname2}', project&.owner&.real_name)
+ content.gsub!('{repository}', project&.name)
+
+ return receiver&.mail, title, content
+ rescue => e
+ Rails.logger.info("MessageTemplate::ProjectMemberLeft.get_email_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+end
diff --git a/app/models/message_template/project_milestone.rb b/app/models/message_template/project_milestone.rb
new file mode 100644
index 000000000..14f992cdd
--- /dev/null
+++ b/app/models/message_template/project_milestone.rb
@@ -0,0 +1,25 @@
+# == 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)
+#
+
+# TODO 我管理的仓库有新的里程碑
+class MessageTemplate::ProjectMilestone < MessageTemplate
+
+ # MessageTemplate::ProjectMilestone.get_message_content(User.where(login: 'yystopf'))
+ def self.get_message_content(receivers)
+ return receivers_string(receivers), content, url
+ rescue => e
+ Rails.logger.info("MessageTemplate::ProjectMilestone.get_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+end
diff --git a/app/models/message_template/project_praised.rb b/app/models/message_template/project_praised.rb
new file mode 100644
index 000000000..e6acee6f5
--- /dev/null
+++ b/app/models/message_template/project_praised.rb
@@ -0,0 +1,25 @@
+# == 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)
+#
+
+# TODO 我管理的仓库被点赞
+class MessageTemplate::ProjectPraised < MessageTemplate
+
+ # MessageTemplate::ProjectPraised.get_message_content(User.where(login: 'yystopf'))
+ def self.get_message_content(receivers)
+ return receivers_string(receivers), content, url
+ rescue => e
+ Rails.logger.info("MessageTemplate::ProjectPraised.get_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+end
diff --git a/app/models/message_template/project_pull_request.rb b/app/models/message_template/project_pull_request.rb
new file mode 100644
index 000000000..ac04651ef
--- /dev/null
+++ b/app/models/message_template/project_pull_request.rb
@@ -0,0 +1,66 @@
+# == 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)
+#
+
+# TODO 我管理/关注的仓库有新的合并请求
+class MessageTemplate::ProjectPullRequest < MessageTemplate
+
+ # MessageTemplate::ProjectPullRequest.get_message_content(User.where(login: 'yystopf'), User.where(login: 'testforge2'), User.last, PullRequest.last)
+ def self.get_message_content(managers, followers, operator, pull_request)
+ managers.each do |receiver|
+ if receiver.user_template_message_setting.present?
+ managers = managers.where.not(id: receiver.id) unless receiver.user_template_message_setting.notification_body["ManageProject::PullRequest"]
+ end
+ end
+ project = pull_request&.project
+ owner = project&.owner
+ receivers = managers + followers
+ return '', '', '' if receivers.blank?
+ content = sys_notice.gsub('{nickname1}', operator&.real_name).gsub('{nickname2}', owner&.real_name).gsub('{repository}', project&.name).gsub('{title}', pull_request&.title)
+ url = notification_url.gsub('{owner}', owner&.login).gsub('{identifier}', project&.identifier).gsub('{id}', pull_request&.id.to_s)
+
+ return receivers_string(receivers), content, url
+ rescue => e
+ Rails.logger.info("MessageTemplate::ProjectPullRequest.get_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+
+ def self.get_email_message_content(receiver, is_manager, operator, pull_request)
+ if receiver.user_template_message_setting.present? && is_manager
+ return '', '', '' unless receiver.user_template_message_setting.email_body["ManageProject::PullRequest"]
+ end
+ project = pull_request&.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!('{login1}', operator&.login)
+ content.gsub!('{nickname1}', operator&.real_name)
+ content.gsub!('{nickname2}', owner&.real_name)
+ content.gsub!('{repository}', project&.name)
+ content.gsub!('{login2}', owner&.login)
+ content.gsub!('{identifier}', project&.identifier)
+ content.gsub!('{id}', pull_request&.id.to_s)
+ content.gsub!('{title}', pull_request&.title)
+
+ return receiver&.mail, title, content
+ rescue => e
+ Rails.logger.info("MessageTemplate::ProjectPullRequest.get_email_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+end
diff --git a/app/models/message_template/project_role.rb b/app/models/message_template/project_role.rb
new file mode 100644
index 000000000..e306f5c02
--- /dev/null
+++ b/app/models/message_template/project_role.rb
@@ -0,0 +1,56 @@
+# == 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::ProjectRole < MessageTemplate
+
+ # MessageTemplate::ProjectRole.get_message_content(User.where(login: 'yystopf'), Project.last, '管理员')
+ def self.get_message_content(receivers, project, role)
+ receivers.each do |receiver|
+ if receiver.user_template_message_setting.present?
+ receivers = receivers.where.not(id: receiver.id) unless receiver.user_template_message_setting.notification_body["Normal::Permission"]
+ end
+ end
+ return '', '', '' if receivers.blank?
+ content = sys_notice.gsub('{nickname}', project&.owner&.real_name).gsub('{repository}', project&.name).gsub('{role}', role)
+ url = notification_url.gsub('{owner}', project&.owner&.login).gsub('{identifier}', project&.identifier)
+ return receivers_string(receivers), content, url
+ rescue => e
+ Rails.logger.info("MessageTemplate::ProjectRole.get_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+
+ def self.get_email_message_content(receiver, project, role)
+ if receiver.user_template_message_setting.present?
+ return '', '', '' unless receiver.user_template_message_setting.email_body["Normal::Permission"]
+ end
+ title = email_title
+ title.gsub!('{repository}', project&.name)
+ title.gsub!('{role}', role)
+ title.gsub!('{nickname}', project&.owner&.real_name)
+ content = email
+ content.gsub!('{receiver}', receiver&.real_name)
+ content.gsub!('{baseurl}', base_url)
+ content.gsub!('{login}', project&.owner&.login)
+ content.gsub!('{nickname}', project&.owner&.real_name)
+ content.gsub!('{identifier}', project&.identifier)
+ content.gsub!('{repository}', project&.name)
+ content.gsub!('{role}', role)
+
+ return receiver&.mail, title, content
+ rescue => e
+ Rails.logger.info("MessageTemplate::ProjectRole.get_email_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+end
diff --git a/app/models/message_template/project_setting_changed.rb b/app/models/message_template/project_setting_changed.rb
new file mode 100644
index 000000000..457ab9207
--- /dev/null
+++ b/app/models/message_template/project_setting_changed.rb
@@ -0,0 +1,310 @@
+# == 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::ProjectSettingChanged < MessageTemplate
+
+ # MessageTemplate::ProjectSettingChanged.get_message_content(User.where(login: 'yystopf'), User.last, Project.last, {description: '测试修改项目简介', category: '大数据', language: 'Ruby', permission: '公有', navbar: '易修, 合并请求'})
+ def self.get_message_content(receivers, operator, project, change_params)
+ receivers.each do |receiver|
+ if receiver.user_template_message_setting.present?
+ receivers = receivers.where.not(id: receiver.id) unless receiver.user_template_message_setting.notification_body["ManageProject::SettingChanged"]
+ end
+ end
+ return '', '', '' if receivers.blank?
+ return '', '', '' if change_params.blank?
+ owner = project&.owner
+ content = sys_notice.gsub('{nickname1}', operator&.real_name).gsub('{nickname2}', owner&.real_name).gsub('{repository}', project&.name)
+ url = notification_url.gsub('{owner}', owner&.login).gsub('{identifier}', project&.identifier)
+ change_count = change_params.keys.size
+ # 项目名称更改
+ if change_params[:name].present?
+ if change_count > 1
+ content.sub!('{ifname}', '
')
+ else
+ content.sub!('{ifname}', '')
+ end
+ content.sub!('{endname}', '')
+ content.gsub!('{name}', change_params[:name][1])
+ else
+ content.gsub!(/({ifname})(.*)({endname})/, '')
+ end
+ # 项目标识更改
+ if change_params[:identifier].present?
+ if change_count > 1
+ content.sub!('{ifidentifier}', '
')
+ else
+ content.sub!('{ifidentifier}', '')
+ end
+ content.sub!('{endidentifier}', '')
+ content.gsub!('{identifier}', change_params[:identifier][1])
+ else
+ content.gsub!(/({ifidentifier})(.*)({endidentifier})/, '')
+ end
+ # 项目简介更改
+ if change_params[:description].present?
+ if change_params[:description][1].blank?
+ if change_count > 1
+ content.gsub!(/({ifdescription})(.*)({enddescription})/, '
删除了项目简介')
+ else
+ content.gsub!(/({ifdescription})(.*)({enddescription})/, '删除了项目简介')
+ end
+ else
+ if change_count > 1
+ content.sub!('{ifdescription}', '
')
+ else
+ content.sub!('{ifdescription}', '')
+ end
+ content.sub!('{enddescription}', '')
+ content.gsub!('{description}', change_params[:description][1])
+ end
+ else
+ content.gsub!(/({ifdescription})(.*)({enddescription})/, '')
+ end
+ # 项目类别更改
+ if change_params[:project_category_id].present?
+ category = ProjectCategory.find_by_id(change_params[:project_category_id][1])
+ if category.present?
+ if change_count > 1
+ content.sub!('{ifcategory}', '
')
+ else
+ content.sub!('{ifcategory}', '')
+ end
+ content.sub!('{endcategory}', '')
+ content.gsub!('{category}', category&.name)
+ else
+ if change_count > 1
+ content.gsub!(/({ifcategory})(.*)({endcategory})/, '
删除了项目类别')
+ else
+ content.gsub!(/({ifcategory})(.*)({endcategory})/, '删除了项目类别')
+ end
+ end
+ else
+ content.gsub!(/({ifcategory})(.*)({endcategory})/, '')
+ end
+ # 项目语言更改
+ if change_params[:project_language_id].present?
+ language = ProjectLanguage.find_by_id(change_params[:project_language_id][1])
+ if language.present?
+ if change_count > 1
+ content.sub!('{iflanguage}', '
')
+ else
+ content.sub!('{iflanguage}', '')
+ end
+ content.sub!('{endlanguage}', '')
+ content.gsub!('{language}', language&.name)
+ else
+ if change_count > 1
+ content.gsub!(/({iflanguage})(.*)({endlanguage})/, '
删除了项目语言')
+ else
+ content.gsub!(/({iflanguage})(.*)({endlanguage})/, '删除了项目语言')
+ end
+ end
+ else
+ content.gsub!(/({iflanguage})(.*)({endlanguage})/, '')
+ end
+ # 项目公私有更改
+ if change_params[:is_public].present?
+ permission = change_params[:is_public][1] ? '公有' : '私有'
+ if change_count > 1
+ content.sub!('{ifpermission}', '
')
+ else
+ content.sub!('{ifpermission}', '')
+ end
+ content.sub!('{endpermission}', '')
+ content.gsub!('{permission}', permission)
+ else
+ content.gsub!(/({ifpermission})(.*)({endpermission})/, '')
+ end
+ # 项目导航更改
+ if change_params[:navbar].present?
+ unit_types = project.project_units.order(unit_type: :asc).pluck(:unit_type)
+ unit_types.delete('code')
+ unit_types.unshift('代码库')
+ unit_types.unshift('主页')
+ unit_types.append('动态')
+ navbar = unit_types.join(',')
+ navbar.gsub!('issues', '易修')
+ navbar.gsub!('pulls', '合并请求')
+ navbar.gsub!('wiki', 'Wiki')
+ navbar.gsub!('devops', '工作流')
+ navbar.gsub!('versions', '里程碑')
+ navbar.gsub!('resources', '资源库')
+ if change_count > 1
+ content.sub!('{ifnavbar}', '
')
+ else
+ content.sub!('{ifnavbar}', '')
+ end
+ content.sub!('{endnavbar}', '')
+ content.gsub!('{navbar}', navbar)
+ else
+ content.gsub!(/({ifnavbar})(.*)({endnavbar})/, '')
+ end
+
+ return receivers_string(receivers), content, url
+ rescue => e
+ Rails.logger.info("MessageTemplate::ProjectSettingChanged.get_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+
+ def self.get_email_message_content(receiver, operator, project, change_params)
+ if receiver.user_template_message_setting.present?
+ return '', '', '' unless receiver.user_template_message_setting.email_body["ManageProject::SettingChanged"]
+ end
+ return '', '', '' if change_params.blank?
+ owner = project&.owner
+ title = email_title
+ 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!('{login1}', operator&.login)
+ content.gsub!('{nickname1}', operator&.real_name)
+ content.gsub!('{login2}', owner&.login)
+ content.gsub!('{nickname2}', owner&.real_name)
+ content.gsub!('{identifier}', project&.identifier)
+ content.gsub!('{repository}', project&.name)
+ change_count = change_params.keys.size
+ # 项目名称更改
+ if change_params[:name].present?
+ if change_count > 1
+ content.sub!('{ifname}', '
')
+ else
+ content.sub!('{ifname}', '')
+ end
+ content.sub!('{endname}', '')
+ content.gsub!('{name}', change_params[:name][1])
+ else
+ content.gsub!(/({ifname})(.*)({endname})/, '')
+ end
+ # 项目标识更改
+ if change_params[:identifier].present?
+ if change_count > 1
+ content.sub!('{ifidentifier}', '
')
+ else
+ content.sub!('{ifidentifier}', '')
+ end
+ content.sub!('{endidentifier}', '')
+ content.gsub!('{identifier}', change_params[:identifier][1])
+ else
+ content.gsub!(/({ifidentifier})(.*)({endidentifier})/, '')
+ end
+ # 项目简介更改
+ if change_params[:description].present?
+ if change_params[:description][1].blank?
+ if change_count > 1
+ content.gsub!(/({ifdescription})(.*)({enddescription})/, '
删除了项目简介')
+ else
+ content.gsub!(/({ifdescription})(.*)({enddescription})/, '删除了项目简介')
+ end
+ else
+ if change_count > 1
+ content.sub!('{ifdescription}', '
')
+ else
+ content.sub!('{ifdescription}', '')
+ end
+ content.sub!('{enddescription}', '')
+ content.gsub!('{description}', change_params[:description][1])
+ end
+ else
+ content.gsub!(/({ifdescription})(.*)({enddescription})/, '')
+ end
+ # 项目类别更改
+ if change_params[:project_category_id].present?
+ category = ProjectCategory.find_by_id(change_params[:project_category_id][1])
+ if category.present?
+ if change_count > 1
+ content.sub!('{ifcategory}', '
')
+ else
+ content.sub!('{ifcategory}', '')
+ end
+ content.sub!('{endcategory}', '')
+ content.gsub!('{category}', category&.name)
+ else
+ if change_count > 1
+ content.gsub!(/({ifcategory})(.*)({endcategory})/, '
删除了项目类别')
+ else
+ content.gsub!(/({ifcategory})(.*)({endcategory})/, '删除了项目类别')
+ end
+ end
+ else
+ content.gsub!(/({ifcategory})(.*)({endcategory})/, '')
+ end
+ # 项目语言更改
+ if change_params[:project_language_id].present?
+ language = ProjectLanguage.find_by_id(change_params[:project_language_id][1])
+ if language.present?
+ if change_count > 1
+ content.sub!('{iflanguage}', '
')
+ else
+ content.sub!('{iflanguage}', '')
+ end
+ content.sub!('{endlanguage}', '')
+ content.gsub!('{language}', language&.name)
+ else
+ if change_count > 1
+ content.gsub!(/({iflanguage})(.*)({endlanguage})/, '
删除了项目语言')
+ else
+ content.gsub!(/({iflanguage})(.*)({endlanguage})/, '删除了项目语言')
+ end
+ end
+ else
+ content.gsub!(/({iflanguage})(.*)({endlanguage})/, '')
+ end
+ # 项目公私有更改
+ if change_params[:is_public].present?
+ permission = change_params[:is_public][1] ? '公有' : '私有'
+ if change_count > 1
+ content.sub!('{ifpermission}', '
')
+ else
+ content.sub!('{ifpermission}', '')
+ end
+ content.sub!('{endpermission}', '')
+ content.gsub!('{permission}', permission)
+ else
+ content.gsub!(/({ifpermission})(.*)({endpermission})/, '')
+ end
+ # 项目导航更改
+ if change_params[:navbar].present?
+ unit_types = project.project_units.order(unit_type: :asc).pluck(:unit_type)
+ unit_types.delete('code')
+ unit_types.unshift('代码库')
+ unit_types.unshift('主页')
+ unit_types.append('动态')
+ navbar = unit_types.join(',')
+ navbar.gsub!('issues', '易修')
+ navbar.gsub!('pulls', '合并请求')
+ navbar.gsub!('wiki', 'Wiki')
+ navbar.gsub!('devops', '工作流')
+ navbar.gsub!('versions', '里程碑')
+ navbar.gsub!('resources', '资源库')
+ if change_count > 1
+ content.sub!('{ifnavbar}', '
')
+ else
+ content.sub!('{ifnavbar}', '')
+ end
+ content.sub!('{endnavbar}', '')
+ content.gsub!('{navbar}', navbar)
+ else
+ content.gsub!(/({ifnavbar})(.*)({endnavbar})/, '')
+ end
+
+ return receiver&.mail, title, content
+ rescue => e
+ Rails.logger.info("MessageTemplate::ProjectSettingChanged.get_email_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+end
diff --git a/app/models/message_template/project_transfer.rb b/app/models/message_template/project_transfer.rb
new file mode 100644
index 000000000..7a99276ba
--- /dev/null
+++ b/app/models/message_template/project_transfer.rb
@@ -0,0 +1,25 @@
+# == 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)
+#
+
+# TODO 我关注的仓库被转移
+class MessageTemplate::ProjectTransfer < MessageTemplate
+
+ # MessageTemplate::ProjectTransfer.get_message_content(User.where(login: 'yystopf'))
+ def self.get_message_content(receivers)
+ return receivers_string(receivers), content, url
+ rescue => e
+ Rails.logger.info("MessageTemplate::ProjectTransfer.get_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+end
diff --git a/app/models/message_template/project_version.rb b/app/models/message_template/project_version.rb
new file mode 100644
index 000000000..14ae46306
--- /dev/null
+++ b/app/models/message_template/project_version.rb
@@ -0,0 +1,25 @@
+# == 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)
+#
+
+# TODO 我关注的仓库有新的发行版
+class MessageTemplate::ProjectVersion < MessageTemplate
+
+ # MessageTemplate::ProjectVersion.get_message_content(User.where(login: 'yystopf'))
+ def self.get_message_content(receivers)
+ return receivers_string(receivers), content, url
+ rescue => e
+ Rails.logger.info("MessageTemplate::ProjectVersion.get_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+end
diff --git a/app/models/message_template/pull_request_assigned.rb b/app/models/message_template/pull_request_assigned.rb
new file mode 100644
index 000000000..1101ca46b
--- /dev/null
+++ b/app/models/message_template/pull_request_assigned.rb
@@ -0,0 +1,63 @@
+# == 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::PullRequestAssigned < MessageTemplate
+
+ # MessageTemplate::PullRequestAssigned.get_message_content(User.where(login: 'yystopf'), User.last, PullRequest.last)
+ def self.get_message_content(receivers, operator, pull_request)
+ receivers.each do |receiver|
+ if receiver.user_template_message_setting.present?
+ receivers = receivers.where.not(id: receiver.id) unless receiver.user_template_message_setting.notification_body["Normal::PullRequestAssigned"]
+ end
+ end
+ return '', '', '' if receivers.blank?
+ project = pull_request&.project
+ owner = project&.owner
+ content = sys_notice.gsub('{nickname1}', operator&.real_name).gsub('{nickname2}', owner&.real_name).gsub('{repository}', project&.name).gsub('{title}', pull_request&.title)
+ url = notification_url.gsub('{owner}', owner&.login).gsub('{identifier}', project&.identifier).gsub('{id}', pull_request&.id.to_s)
+ return receivers_string(receivers), content, url
+ rescue => e
+ Rails.logger.info("MessageTemplate::PullRequestAssigned.get_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+
+ def self.get_email_message_content(receiver, operator, pull_request)
+ if receiver.user_template_message_setting.present?
+ return '', '', '' unless receiver.user_template_message_setting.email_body["Normal::PullRequestAssigned"]
+ end
+ project = pull_request&.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!('{nickname1}', operator&.real_name)
+ content.gsub!('{login1}', operator&.login)
+ content.gsub!('{nickname2}', owner&.real_name)
+ content.gsub!('{login2}', owner&.login)
+ content.gsub!('{identifier}', project&.identifier)
+ content.gsub!('{repository}', project&.name)
+ content.gsub!('{baseurl}', base_url)
+ content.gsub!('{title}', pull_request&.title)
+ content.gsub!('{id}', pull_request&.id.to_s)
+
+ return receiver&.mail, title, content
+ rescue => e
+ Rails.logger.info("MessageTemplate::PullRequestAssigned.get_email_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+end
diff --git a/app/models/message_template/pull_request_atme.rb b/app/models/message_template/pull_request_atme.rb
new file mode 100644
index 000000000..54f8c9585
--- /dev/null
+++ b/app/models/message_template/pull_request_atme.rb
@@ -0,0 +1,29 @@
+# == 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::PullRequestAtme < MessageTemplate
+
+ # MessageTemplate::PullRequestAtme.get_message_content(User.where(login: 'yystopf'), User.last, PullRequest.last)
+ def self.get_message_content(receivers, operator, pull_request)
+ project = pull_request&.project
+ owner = project&.owner
+ content = sys_notice.gsub('{nickname}', operator&.real_name).gsub('{title}', pull_request&.title)
+ url = notification_url.gsub('{owner}', owner&.login).gsub('{identifier}', project&.identifier).gsub('{id}', pull_request&.id.to_s)
+ return receivers_string(receivers), content, url
+ rescue => e
+ Rails.logger.info("MessageTemplate::PullRequestAtme.get_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+end
diff --git a/app/models/message_template/pull_request_changed.rb b/app/models/message_template/pull_request_changed.rb
new file mode 100644
index 000000000..729e12060
--- /dev/null
+++ b/app/models/message_template/pull_request_changed.rb
@@ -0,0 +1,192 @@
+# == 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::PullRequestChanged < MessageTemplate
+
+ # MessageTemplate::PullRequestChanged.get_message_content(User.where(login: 'yystopf'), User.last, PullRequest.last, {assigned_to_id: [nil, 203], priority_id: [2, 4], fixed_version_id: [nil, 5], issue_tags_value: ["", "7"]})
+ def self.get_message_content(receivers, operator, pull_request, change_params)
+ receivers.each do |receiver|
+ if receiver.user_template_message_setting.present?
+ receivers = receivers.where.not(id: receiver.id) unless receiver.user_template_message_setting.notification_body["CreateOrAssign::PullRequestChanged"]
+ end
+ end
+ return '', '', '' if receivers.blank?
+ return '', '', '' if change_params.blank?
+ project = pull_request&.project
+ owner = project&.owner
+ issue = pull_request&.issue
+ content = sys_notice.gsub('{nickname1}', operator&.real_name).gsub('{nickname2}', owner&.real_name).gsub('{repository}', project&.name).gsub("{title}", pull_request&.title)
+ url = notification_url.gsub('{owner}', owner&.login).gsub('{identifier}', project&.identifier).gsub('{id}', pull_request&.id.to_s)
+ change_count = change_params.keys.size
+ # 合并请求审查成员修改
+ if change_params[:assigned_to_id].present?
+ assigner1 = User.find_by_id(change_params[:assigned_to_id][0])
+ assigner2 = User.find_by_id(change_params[:assigned_to_id][1])
+ if change_count > 1
+ content.sub!('{ifassigner}', '
')
+ else
+ content.sub!('{ifassigner}', '')
+ end
+ content.sub!('{endassigner}', '')
+ content.gsub!('{assigner1}', assigner1.present? ? assigner1&.real_name : '未指派成员')
+ content.gsub!('{assigner2}', assigner2.present? ? assigner2&.real_name : '未指派成员')
+ else
+ content.gsub!(/({ifassigner})(.*)({endassigner})/, '')
+ end
+ # 合并请求里程碑修改
+ if change_params[:fixed_version_id].present?
+ fix_version1 = Version.find_by_id(change_params[:fixed_version_id][0])
+ fix_version2 = Version.find_by_id(change_params[:fixed_version_id][1])
+ if change_count > 1
+ content.sub!('{ifmilestone}', '
')
+ else
+ content.sub!('{ifmilestone}', '')
+ end
+ content.sub!('{endmilestone}', '')
+ content.gsub!('{milestone1}', fix_version1.present? ? fix_version1&.name : '未选择里程碑')
+ content.gsub!('{milestone2}', fix_version2.present? ? fix_version2&.name : '未选择里程碑')
+ else
+ content.gsub!(/({ifmilestone})(.*)({endmilestone})/, '')
+ end
+ # 合并请求标记修改
+ if change_params[:issue_tags_value].present?
+ issue_tags1 = IssueTag.where(id: change_params[:issue_tags_value][0]).distinct
+ issue_tags2 = IssueTag.where(id: change_params[:issue_tags_value][1]).distinct
+ tag1 = issue_tags1.pluck(:name).join(",").blank? ? '未选择标记' : issue_tags1.pluck(:name).join(",")
+ tag2 = issue_tags2.pluck(:name).join(",").blank? ? '未选择标记' : issue_tags2.pluck(:name).join(",")
+ if change_count > 1
+ content.sub!('{iftag}', '
')
+ else
+ content.sub!('{iftag}', '')
+ end
+ content.sub!('{endtag}', '')
+ content.gsub!('{tag1}', tag1)
+ content.gsub!('{tag2}', tag2)
+ else
+ content.gsub!(/({iftag})(.*)({endtag})()/, '')
+ end
+ # 合并请求优先级修改
+ if change_params[:priority_id].present?
+ priority1 = IssuePriority.find_by_id(change_params[:priority_id][0])
+ priority2 = IssuePriority.find_by_id(change_params[:priority_id][1])
+ if change_count > 1
+ content.sub!('{ifpriority}', '
')
+ else
+ content.sub!('{ifpriority}', '')
+ end
+ content.sub!('{ifpriority}', '')
+ content.sub!('{endpriority}', '')
+ content.gsub!('{priority1}', priority1&.name)
+ content.gsub!('{priority2}', priority2&.name)
+ else
+ content.gsub!(/({ifpriority})(.*)({endpriority})/, '')
+ end
+ return receivers_string(receivers), content, url
+ rescue => e
+ Rails.logger.info("MessageTemplate::PullRequestChanged.get_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+
+ def self.get_email_message_content(receiver, operator, pull_request, change_params)
+ if receiver.user_template_message_setting.present?
+ return '', '', '' unless receiver.user_template_message_setting.email_body["CreateOrAssign::PullRequestChanged"]
+ end
+ project = pull_request&.project
+ owner = project&.owner
+ title = email_title
+ title.gsub!('{title}', pull_request&.title)
+ content = email
+ content.gsub!('{receiver}', receiver&.real_name)
+ content.gsub!('{nickname1}', operator&.real_name)
+ content.gsub!('{login1}', operator&.login)
+ content.gsub!('{nickname2}', owner&.real_name)
+ content.gsub!('{login2}', owner&.login)
+ content.gsub!('{identifier}', project&.identifier)
+ content.gsub!('{repository}', project&.name)
+ content.gsub!('{baseurl}', base_url)
+ content.gsub!('{title}', pull_request&.title)
+ content.gsub!('{id}', pull_request&.id.to_s)
+
+ change_count = change_params.keys.size
+ # 合并请求审查成员修改
+ if change_params[:assigned_to_id].present?
+ assigner1 = User.find_by_id(change_params[:assigned_to_id][0])
+ assigner2 = User.find_by_id(change_params[:assigned_to_id][1])
+ if change_count > 1
+ content.sub!('{ifassigner}', '
')
+ else
+ content.sub!('{ifassigner}', '')
+ end
+ content.sub!('{endassigner}', '')
+ content.gsub!('{assigner1}', assigner1.present? ? assigner1&.real_name : '未指派成员')
+ content.gsub!('{assigner2}', assigner2.present? ? assigner2&.real_name : '未指派成员')
+ else
+ content.gsub!(/({ifassigner})(.*)({endassigner})/, '')
+ end
+ # 合并请求里程碑修改
+ if change_params[:fixed_version_id].present?
+ fix_version1 = Version.find_by_id(change_params[:fixed_version_id][0])
+ fix_version2 = Version.find_by_id(change_params[:fixed_version_id][1])
+ if change_count > 1
+ content.sub!('{ifmilestone}', '
')
+ else
+ content.sub!('{ifmilestone}', '')
+ end
+ content.sub!('{endmilestone}', '')
+ content.gsub!('{milestone1}', fix_version1.present? ? fix_version1&.name : '未选择里程碑')
+ content.gsub!('{milestone2}', fix_version2.present? ? fix_version2&.name : '未选择里程碑')
+ else
+ content.gsub!(/({ifmilestone})(.*)({endmilestone})/, '')
+ end
+ # 合并请求标记修改
+ if change_params[:issue_tags_value].present?
+ issue_tags1 = IssueTag.where(id: change_params[:issue_tags_value][0]).distinct
+ issue_tags2 = IssueTag.where(id: change_params[:issue_tags_value][1]).distinct
+ tag1 = issue_tags1.pluck(:name).join(",").blank? ? '未选择标记' : issue_tags1.pluck(:name).join(",")
+ tag2 = issue_tags2.pluck(:name).join(",").blank? ? '未选择标记' : issue_tags2.pluck(:name).join(",")
+ if change_count > 1
+ content.sub!('{iftag}', '
')
+ else
+ content.sub!('{iftag}', '')
+ end
+ content.sub!('{endtag}', '')
+ content.gsub!('{tag1}', tag1)
+ content.gsub!('{tag2}', tag2)
+ else
+ content.gsub!(/({iftag})(.*)({endtag})()/, '')
+ end
+ # 合并请求优先级修改
+ if change_params[:priority_id].present?
+ priority1 = IssuePriority.find_by_id(change_params[:priority_id][0])
+ priority2 = IssuePriority.find_by_id(change_params[:priority_id][1])
+ if change_count > 1
+ content.sub!('{ifpriority}', '
')
+ else
+ content.sub!('{ifpriority}', '')
+ end
+ content.sub!('{ifpriority}', '')
+ content.sub!('{endpriority}', '')
+ content.gsub!('{priority1}', priority1&.name)
+ content.gsub!('{priority2}', priority2&.name)
+ else
+ content.gsub!(/({ifpriority})(.*)({endpriority})/, '')
+ end
+
+ return receiver&.mail, title, content
+ rescue => e
+ Rails.logger.info("MessageTemplate::PullRequestChanged.get_email_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+end
diff --git a/app/models/message_template/pull_request_closed.rb b/app/models/message_template/pull_request_closed.rb
new file mode 100644
index 000000000..f160ebf20
--- /dev/null
+++ b/app/models/message_template/pull_request_closed.rb
@@ -0,0 +1,61 @@
+# == 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::PullRequestClosed < MessageTemplate
+
+ # MessageTemplate::PullRequestClosed.get_message_content(User.where(login: 'yystopf'), User.last, PullRequest.last)
+ def self.get_message_content(receivers, operator, pull_request)
+ receivers.each do |receiver|
+ if receiver.user_template_message_setting.present?
+ receivers = receivers.where.not(id: receiver.id) unless receiver.user_template_message_setting.notification_body["CreateOrAssign::PullRequestChanged"]
+ end
+ end
+ return '', '', '' if receivers.blank?
+ project = pull_request&.project
+ owner = project&.owner
+ content = sys_notice.gsub('{title}', pull_request&.title)
+ url = notification_url
+ return receivers_string(receivers), content, url
+ rescue => e
+ Rails.logger.info("MessageTemplate::PullRequestClosed.get_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+
+ def self.get_email_message_content(receiver, operator, pull_request)
+ if receiver.user_template_message_setting.present?
+ return '', '', '' unless receiver.user_template_message_setting.email_body["CreateOrAssign::PullRequestChanged"]
+ end
+ project = pull_request&.project
+ owner = project&.owner
+ title = email_title
+ title.gsub!('{title}', pull_request&.title)
+ content = email
+ content.gsub!('{receiver}', receiver&.real_name)
+ content.gsub!('{nickname1}', operator&.real_name)
+ content.gsub!('{login1}', operator&.login)
+ content.gsub!('{nickname2}', owner&.real_name)
+ content.gsub!('{login2}', owner&.login)
+ content.gsub!('{identifier}', project&.identifier)
+ content.gsub!('{repository}', project&.name)
+ content.gsub!('{baseurl}', base_url)
+ content.gsub!('{title}', pull_request&.title)
+ content.gsub!('{id}', pull_request&.id.to_s)
+
+ return receiver&.mail, title, content
+ rescue => e
+ Rails.logger.info("MessageTemplate::PullRequestClosed.get_email_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+end
diff --git a/app/models/message_template/pull_request_journal.rb b/app/models/message_template/pull_request_journal.rb
new file mode 100644
index 000000000..9b2fae949
--- /dev/null
+++ b/app/models/message_template/pull_request_journal.rb
@@ -0,0 +1,25 @@
+# == 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)
+#
+
+# TODO 我创建或负责的合并请求有新的评论
+class MessageTemplate::PullRequestJournal < MessageTemplate
+
+ # MessageTemplate::PullRequestJournal.get_message_content(User.where(login: 'yystopf'))
+ def self.get_message_content(receivers)
+ return receivers_string(receivers), content, url
+ rescue => e
+ Rails.logger.info("MessageTemplate::PullRequestJournal.get_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+end
diff --git a/app/models/message_template/pull_request_merged.rb b/app/models/message_template/pull_request_merged.rb
new file mode 100644
index 000000000..3dccffdd7
--- /dev/null
+++ b/app/models/message_template/pull_request_merged.rb
@@ -0,0 +1,61 @@
+# == 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::PullRequestMerged < MessageTemplate
+
+ # MessageTemplate::PullRequestMerged.get_message_content(User.where(login: 'yystopf'), User.last, PullRequest.last)
+ def self.get_message_content(receivers, operator, pull_request)
+ receivers.each do |receiver|
+ if receiver.user_template_message_setting.present?
+ receivers = receivers.where.not(id: receiver.id) unless receiver.user_template_message_setting.notification_body["CreateOrAssign::PullRequestChanged"]
+ end
+ end
+ return '', '', '' if receivers.blank?
+ project = pull_request&.project
+ owner = project&.owner
+ content = sys_notice.gsub('{title}', pull_request&.title)
+ url = notification_url.gsub('{owner}', owner&.login).gsub('{identifier}', project&.identifier).gsub('{id}', pull_request&.id.to_s)
+ return receivers_string(receivers), content, url
+ rescue => e
+ Rails.logger.info("MessageTemplate::PullRequestMerged.get_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+
+ def self.get_email_message_content(receiver, operator, pull_request)
+ if receiver.user_template_message_setting.present?
+ return '', '', '' unless receiver.user_template_message_setting.email_body["CreateOrAssign::PullRequestChanged"]
+ end
+ project = pull_request&.project
+ owner = project&.owner
+ title = email_title
+ title.gsub!('{title}', pull_request&.title)
+ content = email
+ content.gsub!('{receiver}', receiver&.real_name)
+ content.gsub!('{nickname1}', operator&.real_name)
+ content.gsub!('{login1}', operator&.login)
+ content.gsub!('{nickname2}', owner&.real_name)
+ content.gsub!('{login2}', owner&.login)
+ content.gsub!('{identifier}', project&.identifier)
+ content.gsub!('{repository}', project&.name)
+ content.gsub!('{baseurl}', base_url)
+ content.gsub!('{title}', pull_request&.title)
+ content.gsub!('{id}', pull_request&.id.to_s)
+
+ return receiver&.mail, title, content
+ rescue => e
+ Rails.logger.info("MessageTemplate::PullRequestMerged.get_email_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+end
diff --git a/app/models/mirror.rb b/app/models/mirror.rb
index 67ef73775..b71dce3fb 100644
--- a/app/models/mirror.rb
+++ b/app/models/mirror.rb
@@ -18,7 +18,7 @@ class Mirror < ApplicationRecord
# 0: 同步镜像成功;1: 正在同步镜像;2: 同步失败; 默认值为0
enum status: { succeeded: 0, waiting: 1, failed: 2 }
- after_update :websocket_boardcast, if: :saved_change_to_status?
+ # after_update :websocket_boardcast, if: :saved_change_to_status?
belongs_to :repository, foreign_key: :repo_id
diff --git a/app/models/organization_user.rb b/app/models/organization_user.rb
index cf9e22371..4ff6946b7 100644
--- a/app/models/organization_user.rb
+++ b/app/models/organization_user.rb
@@ -22,6 +22,9 @@ class OrganizationUser < ApplicationRecord
validates :user_id, uniqueness: {scope: :organization_id}
+ after_create :send_create_message_to_notice_system
+ after_destroy :send_destroy_message_to_notice_system
+
def self.build(organization_id, user_id)
org_user = self.find_by(organization_id: organization_id, user_id: user_id)
return org_user unless org_user.nil?
@@ -31,4 +34,12 @@ class OrganizationUser < ApplicationRecord
def teams
organization.teams.joins(:team_users).where(team_users: {user_id: user_id})
end
+
+ def send_create_message_to_notice_system
+ SendTemplateMessageJob.perform_later('OrganizationJoined', self.user_id, self.organization_id) if Site.has_notice_menu?
+ end
+
+ def send_destroy_message_to_notice_system
+ SendTemplateMessageJob.perform_later('OrganizationLeft', self.user_id, self.organization_id) if Site.has_notice_menu?
+ end
end
diff --git a/app/models/project.rb b/app/models/project.rb
index 141648f37..7c48200eb 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -125,8 +125,8 @@ class Project < ApplicationRecord
has_many :has_pinned_users, through: :pinned_projects, source: :user
has_many :webhooks, class_name: "Gitea::Webhook", primary_key: :gpid, foreign_key: :repo_id
- after_save :check_project_members, :reset_cache_data
- before_save :set_invite_code
+ after_save :check_project_members
+ before_save :set_invite_code, :reset_cache_data, :reset_unmember_followed
after_destroy :reset_cache_data
scope :project_statics_select, -> {select(:id,:name, :is_public, :identifier, :status, :project_type, :user_id, :forked_count, :visits, :project_category_id, :project_language_id, :license_id, :ignore_id, :watchers_count, :created_on)}
scope :no_anomory_projects, -> {where("projects.user_id is not null and projects.user_id != ?", 2)}
@@ -135,6 +135,18 @@ class Project < ApplicationRecord
delegate :content, to: :project_detail, allow_nil: true
delegate :name, to: :license, prefix: true, allow_nil: true
+ def self.all_visible(user_id=nil)
+ user_projects_sql = Project.joins(:owner).where(users: {type: 'User'}).to_sql
+ org_public_projects_sql = Project.joins(:owner).merge(Organization.joins(:organization_extension).where(organization_extensions: {visibility: 'common'})).to_sql
+ if user_id.present?
+ org_limit_projects_sql = Project.joins(:owner).merge(Organization.joins(:organization_extension).where(organization_extensions: {visibility: 'limited'})).to_sql
+ org_privacy_projects_sql = Project.joins(:owner).merge(Organization.joins(:organization_extension, :organization_users).where(organization_extensions: {visibility: 'privacy'}, organization_users: {user_id: user_id})).to_sql
+ return Project.from("( #{ user_projects_sql } UNION #{ org_public_projects_sql } UNION #{ org_limit_projects_sql } UNION #{org_privacy_projects_sql} ) AS projects").visible
+ else
+ return Project.from("( #{ user_projects_sql } UNION #{ org_public_projects_sql } ) AS projects").visible
+ end
+ end
+
def reset_cache_data
if changes[:user_id].present?
first_owner = Owner.find_by_id(changes[:user_id].first)
@@ -144,6 +156,12 @@ class Project < ApplicationRecord
self.reset_user_cache_async_job(self.owner)
end
+ def reset_unmember_followed
+ if changes[:is_public].present? && changes[:is_public] == [true, false]
+ self.watchers.where.not(user_id: self.all_collaborators).destroy_all
+ end
+ end
+
def set_invite_code
if self.invite_code.nil?
self.invite_code= self.generate_dcode('invite_code', 6)
diff --git a/app/models/project_trend.rb b/app/models/project_trend.rb
index 8c55c4f94..7642e1dfb 100644
--- a/app/models/project_trend.rb
+++ b/app/models/project_trend.rb
@@ -20,7 +20,8 @@
class ProjectTrend < ApplicationRecord
CLOSE = 'close'
CREATE = 'create'
-
+ MERGE = 'merge'
+
belongs_to :project
belongs_to :trend, polymorphic: true, optional: true
belongs_to :user
diff --git a/app/models/project_unit.rb b/app/models/project_unit.rb
index 3f58e0fa3..efa9e9d79 100644
--- a/app/models/project_unit.rb
+++ b/app/models/project_unit.rb
@@ -32,9 +32,13 @@ class ProjectUnit < ApplicationRecord
types.delete("pulls") if project.sync_mirror?
# 默认code类型自动创建
types << "code"
+ before_units = project.project_units.pluck(:unit_type).sort
project.project_units.where.not(unit_type: types).each(&:destroy!)
types.each do |type|
project.project_units.find_or_create_by!(unit_type: type)
end
+ after_units = project.project_units.pluck(:unit_type).sort
+ return before_units, after_units
end
+
end
diff --git a/app/models/site.rb b/app/models/site.rb
index 58daddf14..af5e78169 100644
--- a/app/models/site.rb
+++ b/app/models/site.rb
@@ -17,17 +17,24 @@ class Site < ApplicationRecord
# common: 普通链接
enum site_type: { add: 0, personal: 1, common: 2 }
+ 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? }
+
def self.set_default_menu
set_add_menu!
set_personal_menu!
set_common_menu!
end
+ def self.has_notice_menu?
+ self.common.where(key: 'notice').present?
+ end
+
private
def self.set_add_menu!
adds= [
- {name: '新建镜像项目', key: 'add_mirror_project', url: '/projects/mirror/new'},
- {name: '新建托管项目', key: 'add_common', url: '/projects/deposit/new'},
+ {name: '新建项目', key: 'add_mirror_project', url: '/projects/mirror/new'},
+ {name: '导入项目', key: 'add_common', url: '/projects/deposit/new'},
{name: '新建组织', key: 'add_r', url: '/organize/new'}]
adds.each { |ele|
diff --git a/app/models/system_notification.rb b/app/models/system_notification.rb
new file mode 100644
index 000000000..6f901b3fd
--- /dev/null
+++ b/app/models/system_notification.rb
@@ -0,0 +1,20 @@
+# == Schema Information
+#
+# Table name: system_notifications
+#
+# id :integer not null, primary key
+# subject :string(255)
+# sub_subject :string(255)
+# content :text(65535)
+# is_top :boolean
+# created_at :datetime not null
+# updated_at :datetime not null
+#
+
+class SystemNotification < ApplicationRecord
+
+ default_scope { order(created_at: :desc)}
+
+ scope :is_top, lambda { where(is_top: true) }
+
+end
diff --git a/app/models/team.rb b/app/models/team.rb
index 72df05097..19d05c77a 100644
--- a/app/models/team.rb
+++ b/app/models/team.rb
@@ -54,4 +54,15 @@ class Team < ApplicationRecord
team_users.where(user_id: user_id).present?
end
+ def authorize_name
+ case self.authorize
+ when 'read' then '报告者'
+ when 'write' then '开发者'
+ when 'admin' then '管理员'
+ when 'owner' then '拥有者'
+ else
+ ''
+ end
+ end
+
end
diff --git a/app/models/template_message_setting.rb b/app/models/template_message_setting.rb
new file mode 100644
index 000000000..a9c81500b
--- /dev/null
+++ b/app/models/template_message_setting.rb
@@ -0,0 +1,30 @@
+# == Schema Information
+#
+# Table name: template_message_settings
+#
+# id :integer not null, primary key
+# type :string(255)
+# name :string(255)
+# key :string(255)
+# openning :boolean
+# notification_disabled :boolean
+# email_disabled :boolean
+# created_at :datetime not null
+# updated_at :datetime not null
+#
+
+class TemplateMessageSetting < ApplicationRecord
+
+ scope :openning, ->() {where(openning: true)}
+
+ def self.type_name
+ ""
+ end
+
+ def self.build_init_data
+ TemplateMessageSetting::CreateOrAssign.build_init_data
+ TemplateMessageSetting::ManageProject.build_init_data
+ TemplateMessageSetting::Normal.build_init_data
+ TemplateMessageSetting::WatchProject.build_init_data
+ end
+end
diff --git a/app/models/template_message_setting/create_or_assign.rb b/app/models/template_message_setting/create_or_assign.rb
new file mode 100644
index 000000000..2c9fa2076
--- /dev/null
+++ b/app/models/template_message_setting/create_or_assign.rb
@@ -0,0 +1,31 @@
+# == Schema Information
+#
+# Table name: template_message_settings
+#
+# id :integer not null, primary key
+# type :string(255)
+# name :string(255)
+# key :string(255)
+# openning :boolean
+# notification_disabled :boolean
+# email_disabled :boolean
+# created_at :datetime not null
+# updated_at :datetime not null
+#
+
+#我创建的或负责的
+class TemplateMessageSetting::CreateOrAssign < TemplateMessageSetting
+
+ def self.type_name
+ "我创建的或负责的"
+ end
+
+ def self.order_index
+ 20
+ end
+
+ def self.build_init_data
+ self.find_or_create_by(name: "易修状态变更", key: "IssueChanged")
+ self.find_or_create_by(name: "合并请求状态变更", key: "PullRequestChanged")
+ end
+end
diff --git a/app/models/template_message_setting/manage_project.rb b/app/models/template_message_setting/manage_project.rb
new file mode 100644
index 000000000..2aa9e4883
--- /dev/null
+++ b/app/models/template_message_setting/manage_project.rb
@@ -0,0 +1,33 @@
+# == Schema Information
+#
+# Table name: template_message_settings
+#
+# id :integer not null, primary key
+# type :string(255)
+# name :string(255)
+# key :string(255)
+# openning :boolean
+# notification_disabled :boolean
+# email_disabled :boolean
+# created_at :datetime not null
+# updated_at :datetime not null
+#
+
+#我管理的
+class TemplateMessageSetting::ManageProject < TemplateMessageSetting
+
+ def self.type_name
+ "我管理的仓库"
+ end
+
+ def self.order_index
+ 30
+ end
+
+ def self.build_init_data
+ self.find_or_create_by(name: "有新的易修", key: "Issue")
+ self.find_or_create_by(name: "有新的合并请求", key: "PullRequest")
+ self.find_or_create_by(name: "有成员变动", key: "Member")
+ self.find_or_create_by(name: "仓库设置被更改", key: "SettingChanged")
+ end
+end
diff --git a/app/models/template_message_setting/normal.rb b/app/models/template_message_setting/normal.rb
new file mode 100644
index 000000000..9090196d5
--- /dev/null
+++ b/app/models/template_message_setting/normal.rb
@@ -0,0 +1,33 @@
+# == Schema Information
+#
+# Table name: template_message_settings
+#
+# id :integer not null, primary key
+# type :string(255)
+# name :string(255)
+# key :string(255)
+# openning :boolean
+# notification_disabled :boolean
+# email_disabled :boolean
+# created_at :datetime not null
+# updated_at :datetime not null
+#
+
+class TemplateMessageSetting::Normal < TemplateMessageSetting
+
+ def self.type_name
+ "我的状态"
+ end
+
+ def self.order_index
+ 10
+ end
+
+ def self.build_init_data
+ self.find_or_create_by(name: "账号有权限变更", key: "Permission")
+ self.find_or_create_by(name: "被拉入或移出组织", key: "Organization")
+ self.find_or_create_by(name: "被拉入或移出项目", key: "Project")
+ self.find_or_create_by(name: "有新的易修指派给我", key: "IssueAssigned")
+ self.find_or_create_by(name: "有新的合并请求指派给我", key: "PullRequestAssigned")
+ end
+end
diff --git a/app/models/template_message_setting/watch_project.rb b/app/models/template_message_setting/watch_project.rb
new file mode 100644
index 000000000..35dfef6db
--- /dev/null
+++ b/app/models/template_message_setting/watch_project.rb
@@ -0,0 +1,29 @@
+# == Schema Information
+#
+# Table name: template_message_settings
+#
+# id :integer not null, primary key
+# type :string(255)
+# name :string(255)
+# key :string(255)
+# openning :boolean
+# notification_disabled :boolean
+# email_disabled :boolean
+# created_at :datetime not null
+# updated_at :datetime not null
+#
+
+#我关注的
+class TemplateMessageSetting::WatchProject < TemplateMessageSetting
+
+ def self.type_name
+ "我关注的仓库"
+ end
+
+ def self.order_index
+ 40
+ end
+
+ def self.build_init_data
+ end
+end
diff --git a/app/models/user.rb b/app/models/user.rb
index 1a7cdeecc..fc4c33618 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -171,6 +171,8 @@ class User < Owner
has_many :pull_requests, dependent: :destroy
has_many :public_keys, class_name: "Gitea::PublicKey",primary_key: :gitea_uid, foreign_key: :owner_id, dependent: :destroy
+ has_one :user_template_message_setting, dependent: :destroy
+
# Groups and active users
scope :active, lambda { where(status: STATUS_ACTIVE) }
scope :like, lambda { |keywords|
@@ -186,7 +188,7 @@ class User < Owner
:show_email, :show_location, :show_department,
:technical_title, :province, :city, :custom_department, to: :user_extension, allow_nil: true
- before_save :update_hashed_password, :set_lastname, :set_profile_completed
+ before_save :update_hashed_password, :set_lastname
after_create do
SyncTrustieJob.perform_later("user", 1) if allow_sync_to_trustie?
end
@@ -757,6 +759,10 @@ class User < Owner
laboratory_id.present? && laboratory_id != 1
end
+ def profile_is_completed?
+ self.nickname.present? && self.gender.present? && self.mail.present? && self.custom_department.present?
+ end
+
protected
def validate_password_length
# 管理员的初始密码是5位
@@ -783,10 +789,6 @@ class User < Owner
def set_lastname
self.lastname = self.nickname if changes[:nickname].present?
end
-
- def set_profile_completed
- self.profile_completed = self.nickname.present? && self.gender.present? && self.mail.present? && self.custom_department.present?
- end
end
diff --git a/app/models/user_template_message_setting.rb b/app/models/user_template_message_setting.rb
new file mode 100644
index 000000000..c581e626e
--- /dev/null
+++ b/app/models/user_template_message_setting.rb
@@ -0,0 +1,72 @@
+# == Schema Information
+#
+# Table name: user_template_message_settings
+#
+# id :integer not null, primary key
+# user_id :integer
+# notification_body :text(65535)
+# email_body :text(65535)
+# created_at :datetime not null
+# updated_at :datetime not null
+#
+# Indexes
+#
+# index_user_template_message_settings_on_user_id (user_id)
+#
+
+class UserTemplateMessageSetting < ApplicationRecord
+ serialize :notification_body, Hash
+ serialize :email_body, Hash
+
+ belongs_to :user
+
+ before_update :set_body_value
+
+ def self.build(user_id)
+ self.create!(user_id: user_id, notification_body: init_notification_body, email_body: init_email_body)
+ end
+
+ def self.init_notification_body
+ {
+ "Normal::Permission": true,
+ "Normal::Project": true,
+ "Normal::Organization": true,
+ "Normal::IssueAssigned": true,
+ "Normal::PullRequestAssigned": true,
+ "CreateOrAssign::IssueChanged": true,
+ "CreateOrAssign::PullRequestChanged": true,
+ "ManageProject::Issue": true,
+ "ManageProject::PullRequest": true,
+ "ManageProject::Member": true,
+ "ManageProject::SettingChanged": true,
+ }.stringify_keys!
+ end
+
+ def self.init_email_body
+ {
+ "Normal::Permission": true,
+ "Normal::Project": true,
+ "Normal::Organization": true,
+ "Normal::IssueAssigned": true,
+ "Normal::PullRequestAssigned": true,
+ "CreateOrAssign::IssueChanged": true,
+ "CreateOrAssign::PullRequestChanged": true,
+ "ManageProject::Issue": true,
+ "ManageProject::PullRequest": true,
+ "ManageProject::Member": true,
+ "ManageProject::SettingChanged": true,
+ }.stringify_keys!
+ end
+
+ private
+
+ def set_body_value
+ self.notification_body.each do |k, v|
+ self.notification_body[k] = ActiveModel::Type::Boolean.new.cast(v).nil? ? false : ActiveModel::Type::Boolean.new.cast(v)
+ end
+
+ self.email_body.each do |k, v|
+ self.email_body[k] = ActiveModel::Type::Boolean.new.cast(v).nil? ? false : ActiveModel::Type::Boolean.new.cast(v)
+ end
+ end
+end
diff --git a/app/models/version_release.rb b/app/models/version_release.rb
index 16b823a78..3c97420ea 100644
--- a/app/models/version_release.rb
+++ b/app/models/version_release.rb
@@ -17,6 +17,7 @@
# created_at :datetime not null
# updated_at :datetime not null
# repository_id :integer
+# sha :string(255)
#
# Indexes
#
@@ -29,4 +30,9 @@ class VersionRelease < ApplicationRecord
has_many :project_trends, as: :trend, dependent: :destroy
scope :releases_size, ->{where(draft: false, prerelease: false).size}
has_many :attachments, as: :container, dependent: :destroy
+
+ def update_sha
+ git_release = Gitea::Versions::GetService.call(user.gitea_token, repository&.owner&.login, repository&.identifier, version_gid)
+ self.update(sha: git_release["sha"])
+ end
end
diff --git a/app/models/watcher.rb b/app/models/watcher.rb
index ccc8eefaa..6a8c94fcc 100644
--- a/app/models/watcher.rb
+++ b/app/models/watcher.rb
@@ -24,6 +24,7 @@ class Watcher < ApplicationRecord
after_save :reset_cache_data
after_destroy :reset_cache_data
+ after_create :send_create_message_to_notice_system
def reset_cache_data
if self.watchable.is_a?(User)
@@ -35,4 +36,8 @@ class Watcher < ApplicationRecord
self.reset_platform_cache_async_job
end
+ def send_create_message_to_notice_system
+ SendTemplateMessageJob.perform_later('FollowTip', self.id) if self.watchable.is_a?(User) if Site.has_notice_menu?
+ end
+
end
diff --git a/app/queries/admins/edu_setting_query.rb b/app/queries/admins/edu_setting_query.rb
new file mode 100644
index 000000000..3e61ffd33
--- /dev/null
+++ b/app/queries/admins/edu_setting_query.rb
@@ -0,0 +1,28 @@
+class Admins::EduSettingQuery < ApplicationQuery
+ include CustomSortable
+
+ attr_reader :params
+
+ sort_columns :id, default_by: :id, default_direction: :desc
+
+ def initialize(params)
+ @params = params
+ end
+
+ def call
+ collection = EduSetting.all
+ collection = filter_settings(collection)
+
+ custom_sort collection, params[:sort_by], params[:sort_direction]
+ end
+
+ def filter_settings(collection)
+ by_search(collection)
+ end
+
+ def by_search(collection)
+ keyword = strip_param(:search)
+ collection.by_search(keyword)
+ end
+
+end
\ No newline at end of file
diff --git a/app/queries/admins/site_query.rb b/app/queries/admins/site_query.rb
new file mode 100644
index 000000000..1d15f0312
--- /dev/null
+++ b/app/queries/admins/site_query.rb
@@ -0,0 +1,35 @@
+class Admins::SiteQuery < ApplicationQuery
+ include CustomSortable
+
+ attr_reader :params
+
+ sort_columns :id, default_by: :id, default_direction: :desc
+
+ def initialize(params)
+ @params = params
+ end
+
+ def call
+ collection = Site.all
+ collection = filter_sites(collection)
+
+ custom_sort collection, params[:sort_by], params[:sort_direction]
+ end
+
+ def filter_sites(collection)
+ collection = by_search(collection)
+ collection = by_stie_type(collection)
+ collection
+ end
+
+ def by_search(collection)
+ keyword = strip_param(:search)
+ collection.by_search(keyword)
+ end
+
+ def by_stie_type(collection)
+ site_type = strip_param(:site_type)
+ collection.by_site_type(site_type)
+ end
+
+end
\ No newline at end of file
diff --git a/app/queries/projects/list_query.rb b/app/queries/projects/list_query.rb
index 04f1d168b..4658408d2 100644
--- a/app/queries/projects/list_query.rb
+++ b/app/queries/projects/list_query.rb
@@ -1,12 +1,13 @@
class Projects::ListQuery < ApplicationQuery
include CustomSortable
- attr_reader :params
+ attr_reader :params, :current_user_id
sort_columns :updated_on, :created_on, :forked_count, :praises_count, default_by: :updated_on, default_direction: :desc
- def initialize(params)
+ def initialize(params, current_user_id=nil)
@params = params
+ @current_user_id = current_user_id
end
def call
diff --git a/app/services/admins/delete_unit_apply_service.rb b/app/services/admins/delete_unit_apply_service.rb
index a64c8d64d..af2e9668d 100644
--- a/app/services/admins/delete_unit_apply_service.rb
+++ b/app/services/admins/delete_unit_apply_service.rb
@@ -18,7 +18,7 @@ class Admins::DeleteUnitApplyService < ApplicationService
use_extensions = UserExtension&.where(school_id: @unit_apply.school_id)
user_ids = UserExtension&.where(school_id: @unit_apply.school_id)&.pluck(:user_id)
- User.where(id: user_ids).update_all(profile_completed: false)
+ User.where(id: user_ids)
use_extensions.update_all(school_id: nil,department_id: nil)
@unit_apply&.user&.user_extension&.update_attribute("department_id", nil)
diff --git a/app/services/admins/import_user_service.rb b/app/services/admins/import_user_service.rb
index 5d4c2e10f..2fac412e1 100644
--- a/app/services/admins/import_user_service.rb
+++ b/app/services/admins/import_user_service.rb
@@ -57,7 +57,7 @@ class Admins::ImportUserService < ApplicationService
password: '12345678',
phone: data.phone,
mail: "#{prefix}#{data.student_id}@qq.com",
- profile_completed: true
+ # profile_completed: true
}
ActiveRecord::Base.transaction do
user = User.create!(attr)
diff --git a/app/services/gitea/organization/repository/create_service.rb b/app/services/gitea/organization/repository/create_service.rb
index 060a8ab05..2990f711e 100644
--- a/app/services/gitea/organization/repository/create_service.rb
+++ b/app/services/gitea/organization/repository/create_service.rb
@@ -15,8 +15,8 @@ class Gitea::Organization::Repository::CreateService < Gitea::ClientService
private
def request_params
- create_params = params.merge(readme: "readme")
- Hash.new.merge(token: token, data: create_params)
+ # create_params = params.merge(readme: "readme")
+ Hash.new.merge(token: token, data: params)
end
def url
diff --git a/app/services/gitea/pull_request/files_service.rb b/app/services/gitea/pull_request/files_service.rb
index 9785588e2..a8cb26627 100644
--- a/app/services/gitea/pull_request/files_service.rb
+++ b/app/services/gitea/pull_request/files_service.rb
@@ -24,7 +24,7 @@ class Gitea::PullRequest::FilesService < Gitea::ClientService
def params
Hash.new.merge(token: token)
end
-
+
def url
"/repos/#{owner}/#{repo}/pulls/#{pull_number}/files".freeze
end
diff --git a/app/services/gitea/repository/branches/list_slice_service.rb b/app/services/gitea/repository/branches/list_slice_service.rb
new file mode 100644
index 000000000..6b643831a
--- /dev/null
+++ b/app/services/gitea/repository/branches/list_slice_service.rb
@@ -0,0 +1,22 @@
+class Gitea::Repository::Branches::ListSliceService < Gitea::ClientService
+ attr_reader :user, :repo
+
+ def initialize(user, repo)
+ @user = user
+ @repo = repo
+ end
+
+ def call
+ response = get(url, params)
+ render_200_response(response)
+ end
+
+ private
+ def params
+ Hash.new.merge(token: user.gitea_token)
+ end
+
+ def url
+ "/repos/#{user.login}/#{repo}/branches/branches_slice".freeze
+ end
+end
diff --git a/app/services/gitea/repository/commits/file_list_service.rb b/app/services/gitea/repository/commits/file_list_service.rb
new file mode 100644
index 000000000..b1606a0f3
--- /dev/null
+++ b/app/services/gitea/repository/commits/file_list_service.rb
@@ -0,0 +1,43 @@
+# Get a list of all commits from a repository
+class Gitea::Repository::Commits::FileListService < Gitea::ClientService
+ attr_reader :owner, :repo_name, :filepath, :args
+
+ # sha: SHA or branch to start listing commits from (usually 'master')
+ # ex:
+ # Gitea::Repository::Commits::ListService.new(@project.owner.login, @project.identifier,
+ # sha: params[:sha], page: params[:page], limit: params[:limit], token: current_user&.gitea_token).call
+ def initialize(owner, repo_name, filepath, **args)
+ @owner = owner
+ @repo_name = repo_name
+ @filepath = filepath
+ @args = args
+ end
+
+ def call
+ response = get(url, params)
+ render_result(response)
+ end
+
+ private
+ def params
+ {sha: args[:sha] || 'master', page: args[:page] || PAGINATE_DEFAULT_PAGE, limit: args[:limit] || PAGINATE_DEFAULT_LIMIT, token: args[:token] || "" }
+ end
+
+ def url
+ "/repos/#{owner}/#{repo_name}/file_commits/#{filepath}".freeze
+ end
+
+ def render_result(response)
+ case response.status
+ when 200
+ result = {}
+ headers = response.headers.to_hash
+ body = JSON.parse(response.body)
+ total_count = headers["x-total"]
+ result.merge(total_count: total_count.to_i, body: body)
+ else
+ nil
+ # {status: -1, message: "#{body['message']}"}
+ end
+ end
+end
diff --git a/app/services/gitea/repository/commits/list_slice_service.rb b/app/services/gitea/repository/commits/list_slice_service.rb
new file mode 100644
index 000000000..04f45f55b
--- /dev/null
+++ b/app/services/gitea/repository/commits/list_slice_service.rb
@@ -0,0 +1,42 @@
+# Get a list of all commits from a repository
+class Gitea::Repository::Commits::ListSliceService < Gitea::ClientService
+ attr_reader :owner, :repo_name, :args
+
+ # sha: SHA or branch to start listing commits from (usually 'master')
+ # ex:
+ # Gitea::Repository::Commits::ListService.new(@project.owner.login, @project.identifier,
+ # sha: params[:sha], page: params[:page], limit: params[:limit], token: current_user&.gitea_token).call
+ def initialize(owner, repo_name, **args)
+ @owner = owner
+ @repo_name = repo_name
+ @args = args
+ end
+
+ def call
+ response = get(url, params)
+ render_result(response)
+ end
+
+ private
+ def params
+ { sha: args[:sha] || 'master', page: args[:page] || PAGINATE_DEFAULT_PAGE, limit: args[:limit] || PAGINATE_DEFAULT_LIMIT, token: args[:token] || "" }
+ end
+
+ def url
+ "/repos/#{owner}/#{repo_name}/commits_slice".freeze
+ end
+
+ def render_result(response)
+ case response.status
+ when 200
+ result = {}
+ headers = response.headers.to_hash
+ body = JSON.parse(response.body)
+ total_count = headers["x-total"]
+ result.merge(total_count: total_count.to_i, body: body)
+ else
+ nil
+ # {status: -1, message: "#{body['message']}"}
+ end
+ end
+end
diff --git a/app/services/gitea/repository/create_service.rb b/app/services/gitea/repository/create_service.rb
index 168aaab24..98a283034 100644
--- a/app/services/gitea/repository/create_service.rb
+++ b/app/services/gitea/repository/create_service.rb
@@ -25,8 +25,8 @@ class Gitea::Repository::CreateService < Gitea::ClientService
private
def request_params
- create_params = params.merge(readme: "readme")
- Hash.new.merge(token: token, data: create_params)
+ # create_params = params.merge(readme: "readme")
+ Hash.new.merge(token: token, data: params)
end
def url
diff --git a/app/services/gitea/repository/get_branch_and_tag_total_num_service.rb b/app/services/gitea/repository/get_branch_and_tag_total_num_service.rb
new file mode 100644
index 000000000..0b8a52467
--- /dev/null
+++ b/app/services/gitea/repository/get_branch_and_tag_total_num_service.rb
@@ -0,0 +1,37 @@
+
+module Gitea
+ module Repository
+ class GetBranchAndTagTotalNumService < Gitea::ClientService
+ attr_reader :owner, :repo, :token
+
+ def initialize(owner, repo, token=nil)
+ @owner = owner
+ @repo = repo
+ @token = token
+ end
+
+ def call
+ response = get(url, params)
+ render_result(response)
+ end
+
+ private
+ def params
+ Hash.new.merge(token: token)
+ end
+
+ def url
+ "/repos/#{owner}/#{repo}/branch_tag_count".freeze
+ end
+
+ def render_result(response)
+ case response.status
+ when 200
+ JSON.parse(response.body)
+ else
+ {}
+ end
+ end
+ end
+ end
+end
diff --git a/app/services/gitea/repository/readme/dir_service.rb b/app/services/gitea/repository/readme/dir_service.rb
new file mode 100644
index 000000000..587fb5d55
--- /dev/null
+++ b/app/services/gitea/repository/readme/dir_service.rb
@@ -0,0 +1,34 @@
+class Gitea::Repository::Readme::DirService < Gitea::ClientService
+ attr_reader :owner, :repo, :ref, :dir, :token
+
+ def initialize(owner, repo, dir, ref='', token=nil)
+ @owner = owner
+ @repo = repo
+ @dir = dir
+ @ref = ref
+ @token = token
+ end
+
+ def call
+ response = get(url, params)
+ status, message, body = render_response(response)
+ json_format(status, message, body)
+ end
+
+ private
+ def params
+ Hash.new.merge(token: token, ref: ref)
+ end
+
+ def url
+ "/repos/#{owner}/#{repo}/readme/#{dir}".freeze
+ end
+
+ def json_format(status, message, body)
+ case status
+ when 200 then success(body)
+ when 404 then error(message, 404)
+ else error(message, status)
+ end
+ end
+end
\ No newline at end of file
diff --git a/app/services/gitea/repository/update_service.rb b/app/services/gitea/repository/update_service.rb
index 0d27922b8..6c4eff1b3 100644
--- a/app/services/gitea/repository/update_service.rb
+++ b/app/services/gitea/repository/update_service.rb
@@ -19,7 +19,8 @@ class Gitea::Repository::UpdateService < Gitea::ClientService
end
def call
- patch(url, data_params)
+ response = patch(url, data_params)
+ render_200_response(response)
end
private
diff --git a/app/services/gitea/versions/get_service.rb b/app/services/gitea/versions/get_service.rb
new file mode 100644
index 000000000..b3c6cf9cc
--- /dev/null
+++ b/app/services/gitea/versions/get_service.rb
@@ -0,0 +1,37 @@
+# Get a list of all commits from a repository
+class Gitea::Versions::GetService < Gitea::ClientService
+ attr_reader :token, :user_name, :repo, :gid, :args
+
+ # sha: SHA or branch to start listing commits from (usually 'master')
+ def initialize(token, user_name, repo, gid, args={})
+ @token = token
+ @user_name = user_name
+ @repo = repo
+ @gid = gid
+ @args = args
+ end
+
+ def call
+ response = get(url, params)
+ render_result(response)
+ end
+
+ private
+ def params
+ args.merge(token: token)
+ end
+
+ def url
+ "/repos/#{@user_name}/#{@repo}/releases/#{@gid}".freeze
+ end
+
+ def render_result(response)
+ body = JSON.parse(response.body)
+ case response.status
+ when 200
+ body
+ else
+ {status: -1, message: "#{body['message']}"}
+ end
+ end
+end
diff --git a/app/services/notice/read/client_service.rb b/app/services/notice/read/client_service.rb
new file mode 100644
index 000000000..95ab8159e
--- /dev/null
+++ b/app/services/notice/read/client_service.rb
@@ -0,0 +1,108 @@
+class Notice::Read::ClientService < ApplicationService
+ attr_reader :url, :params
+
+ def initialize(options={})
+ @url = options[:url]
+ @params = options[:params]
+ end
+
+ def post(url, params={})
+ puts "[notice][read][POST] request params: #{params}"
+ conn.post do |req|
+ req.url = full_url(url)
+ req.body = params[:data].to_json
+ end
+ end
+
+ def get(url, params={})
+ puts "[notice][read][GET] request params: #{params}"
+ conn.get do |req|
+ req.url full_url(url, 'get')
+ params.each_pair do |key, value|
+ req.params["#{key}"] = value
+ end
+ end
+ end
+
+ def delete(url, params={})
+ puts "[notice][read][DELETE] request params: #{params}"
+ conn.delete do |req|
+ req.url full_url(url)
+ req.body = params[:data].to_json
+ end
+ end
+
+ def patch(url, params={})
+ puts "[notice][read][PATCH] request params: #{params}"
+ conn.patch do |req|
+ req.url full_url(url)
+ req.body = params[:data].to_json
+ end
+ end
+
+ def put(url, params={})
+ puts "[notice][read][PUT] request params: #{params}"
+ conn.put do |req|
+ req.url full_url(url)
+ req.body = params[:data].to_json
+ end
+ end
+
+ def platform
+ Notice.notice_config[:platform]
+ end
+
+ private
+ def conn
+ @client ||= begin
+ Faraday.new(url: domain) do |req|
+ req.request :url_encoded
+ req.headers['Content-Type'] = 'application/json'
+ req.adapter Faraday.default_adapter
+ end
+ end
+
+ @client
+ end
+
+ def base_url
+ Notice.notice_config[:base_url]
+ end
+
+ def domain
+ Notice.notice_config[:read_domain]
+ end
+
+ def api_url
+ [domain, base_url].join('')
+ end
+
+ def full_url(api_rest, action='post')
+ url = [api_url, api_rest].join('').freeze
+ url = action === 'get' ? url : URI.escape(url)
+ url = URI.escape(url) unless url.ascii_only?
+ puts "[notice][read] request url: #{url}"
+ return url
+ end
+
+ def log_error(status, body)
+ puts "[notice][read] status: #{status}"
+ puts "[notice][read] body: #{body}"
+ end
+
+ def render_response(response)
+ status = response.status
+ body = JSON.parse(response&.body)
+
+ log_error(status, body)
+
+ if status == 200
+ if body["code"] == 1
+ return [body["code"], body["message"], body["data"]]
+ else
+ puts "[notice][read][ERROR] code: #{body["code"]}"
+ puts "[notice][read][ERROR] message: #{body["message"]}"
+ end
+ end
+ end
+end
\ No newline at end of file
diff --git a/app/services/notice/read/count_service.rb b/app/services/notice/read/count_service.rb
new file mode 100644
index 000000000..fade12278
--- /dev/null
+++ b/app/services/notice/read/count_service.rb
@@ -0,0 +1,25 @@
+class Notice::Read::CountService < Notice::Read::ClientService
+ attr_accessor :receiver, :type
+
+ def initialize(receiver, type=-1)
+ @receiver = receiver
+ @type = type
+ end
+
+ def call
+ result = get(url, request_params)
+ response = render_response(result)
+ end
+
+ private
+ def request_params
+ {
+ receiver: receiver,
+ type: type
+ }.stringify_keys
+ end
+
+ def url
+ "/notification/#{platform}/count".freeze
+ end
+end
\ No newline at end of file
diff --git a/app/services/notice/read/list_service.rb b/app/services/notice/read/list_service.rb
new file mode 100644
index 000000000..3f6645d77
--- /dev/null
+++ b/app/services/notice/read/list_service.rb
@@ -0,0 +1,32 @@
+class Notice::Read::ListService < Notice::Read::ClientService
+ attr_accessor :receiver, :type, :status, :page, :size
+
+ def initialize(receiver, type=-1, status=2, page=1, size=15)
+ @receiver = receiver
+ @type = type
+ @status = status
+ @page = page
+ @size = size
+ end
+
+ def call
+ result = get(url, request_params)
+ response = render_response(result)
+ end
+
+ private
+
+ def request_params
+ {
+ receiver: receiver,
+ page: page,
+ status: status,
+ size: size,
+ type: type
+ }.stringify_keys
+ end
+
+ def url
+ "/notification/#{platform}/list".freeze
+ end
+end
\ No newline at end of file
diff --git a/app/services/notice/write/change_status_service.rb b/app/services/notice/write/change_status_service.rb
new file mode 100644
index 000000000..de2c89815
--- /dev/null
+++ b/app/services/notice/write/change_status_service.rb
@@ -0,0 +1,35 @@
+class Notice::Write::ChangeStatusService < Notice::Write::ClientService
+ attr_accessor :notification_ids, :receiver, :type, :status
+
+ def initialize(notification_ids, receiver, type=-1, status=2)
+ @notification_ids = notification_ids
+ @receiver = receiver
+ @type = type
+ @status = status
+ end
+
+ def call
+ result = put(url, request_params)
+ response = render_response(result)
+ end
+
+ private
+
+ def request_notification_ids
+ notification_ids.join(",")
+ end
+
+ def request_params
+ Hash.new.merge(data: {
+ notificationIds: request_notification_ids,
+ receiver: receiver,
+ type: type,
+ status: status
+ }.stringify_keys)
+ end
+
+ def url
+ "/notification/#{platform}".freeze
+ end
+
+end
\ No newline at end of file
diff --git a/app/services/notice/write/client_service.rb b/app/services/notice/write/client_service.rb
new file mode 100644
index 000000000..c76691cfb
--- /dev/null
+++ b/app/services/notice/write/client_service.rb
@@ -0,0 +1,108 @@
+class Notice::Write::ClientService < ApplicationService
+ attr_reader :url, :params
+
+ def initialize(options={})
+ @url = options[:url]
+ @params = options[:params]
+ end
+
+ def post(url, params={})
+ puts "[notice][write][POST] request params: #{params}"
+ conn.post do |req|
+ req.url full_url(url)
+ req.body = params[:data].to_json
+ end
+ end
+
+ def get(url, params={})
+ puts "[notice][write][GET] request params: #{params}"
+ conn.get do |req|
+ req.url full_url(url, 'get')
+ params.each_pair do |key, value|
+ req.params["#{key}"] = value
+ end
+ end
+ end
+
+ def delete(url, params={})
+ puts "[notice][write][DELETE] request params: #{params}"
+ conn.delete do |req|
+ req.url full_url(url)
+ req.body = params[:data].to_json
+ end
+ end
+
+ def patch(url, params={})
+ puts "[notice][write][PATCH] request params: #{params}"
+ conn.patch do |req|
+ req.url full_url(url)
+ req.body = params[:data].to_json
+ end
+ end
+
+ def put(url, params={})
+ puts "[notice][write][PUT] request params: #{params}"
+ conn.put do |req|
+ req.url full_url(url)
+ req.body = params[:data].to_json
+ end
+ end
+
+ def platform
+ Notice.notice_config[:platform]
+ end
+
+ private
+ def conn
+ @client ||= begin
+ Faraday.new(url: domain) do |req|
+ req.request :url_encoded
+ req.headers['Content-Type'] = 'application/json'
+ req.adapter Faraday.default_adapter
+ end
+ end
+
+ @client
+ end
+
+ def base_url
+ Notice.notice_config[:base_url]
+ end
+
+ def domain
+ Notice.notice_config[:write_domain]
+ end
+
+ def api_url
+ [domain, base_url].join('')
+ end
+
+ def full_url(api_rest, action='post')
+ url = [api_url, api_rest].join('').freeze
+ url = action === 'get' ? url : URI.escape(url)
+ url = URI.escape(url) unless url.ascii_only?
+ puts "[notice][write] request url: #{url}"
+ return url
+ end
+
+ def log_error(status, body)
+ puts "[notice][write] status: #{status}"
+ puts "[notice][write] body: #{body}"
+ end
+
+ def render_response(response)
+ status = response.status
+ body = JSON.parse(response&.body)
+
+ log_error(status, body)
+
+ if status == 200
+ if body["code"] == 1
+ return [body["code"], body["message"], body["data"]]
+ else
+ puts "[notice][write][ERROR] code: #{body["code"]}"
+ puts "[notice][write][ERROR] message: #{body["message"]}"
+ end
+ end
+ end
+end
\ No newline at end of file
diff --git a/app/services/notice/write/create_service.rb b/app/services/notice/write/create_service.rb
new file mode 100644
index 000000000..8dfc88483
--- /dev/null
+++ b/app/services/notice/write/create_service.rb
@@ -0,0 +1,42 @@
+class Notice::Write::CreateService < Notice::Write::ClientService
+ attr_accessor :receivers, :sender, :content, :notification_url, :source, :extra, :type
+
+ def initialize(receivers, content, notification_url, source, extra={}, type=1, sender=-1)
+ @receivers = receivers
+ @sender = sender
+ @content = content
+ @notification_url = notification_url
+ @source = source
+ @extra = extra
+ @type = type
+ end
+
+ def call
+ return nil if request_receivers.blank?
+ result = post(url, request_params)
+ response = render_response(result)
+ end
+
+ private
+
+ def request_receivers
+ receivers.is_a?(Array) ? receivers.join(",") : receivers
+ end
+
+ def request_params
+ Hash.new.merge(data: {
+ receivers: request_receivers,
+ sender: sender,
+ content: content,
+ notification_url: notification_url,
+ source: source,
+ extra: extra.to_json.to_s,
+ type: type
+ }.stringify_keys)
+ end
+
+ def url
+ "/notification/#{platform}".freeze
+ end
+
+end
\ No newline at end of file
diff --git a/app/services/notice/write/delete_service.rb b/app/services/notice/write/delete_service.rb
new file mode 100644
index 000000000..f63584819
--- /dev/null
+++ b/app/services/notice/write/delete_service.rb
@@ -0,0 +1,33 @@
+class Notice::Write::DeleteService < Notice::Write::ClientService
+ attr_accessor :notification_ids, :receiver, :type
+
+ def initialize(notification_ids, receiver, type=-1)
+ @notification_ids = notification_ids
+ @receiver = receiver
+ @type = type
+ end
+
+ def call
+ result = delete(url, request_params)
+ response = render_response(result)
+ end
+
+ private
+
+ def request_notification_ids
+ notification_ids.join(",")
+ end
+
+ def request_params
+ Hash.new.merge(data: {
+ notificationIds: request_notification_ids,
+ receiver: receiver,
+ type: type
+ }.stringify_keys)
+ end
+
+ def url
+ "/notification/#{platform}".freeze
+ end
+
+end
\ No newline at end of file
diff --git a/app/services/notice/write/email_create_service.rb b/app/services/notice/write/email_create_service.rb
new file mode 100644
index 000000000..070b42689
--- /dev/null
+++ b/app/services/notice/write/email_create_service.rb
@@ -0,0 +1,40 @@
+class Notice::Write::EmailCreateService < Notice::Write::ClientService
+ attr_accessor :receivers, :sender, :content, :subject
+
+ def initialize(receivers, subject, content, sender=-1)
+ @receivers = receivers
+ @sender = sender
+ @content = content
+ @subject = subject
+ end
+
+ def call
+ return nil if request_receivers.blank?
+ result = post(url, request_params)
+ response = render_response(result)
+ end
+
+ private
+
+ def request_receivers
+ receivers.is_a?(Array) ? receivers.join(",") : receivers
+ end
+
+ def request_subject
+ "Trustie: #{subject}"
+ end
+
+ def request_params
+ Hash.new.merge(data: {
+ emails: request_receivers,
+ sender: sender,
+ content: content,
+ subject: request_subject
+ }.stringify_keys)
+ end
+
+ def url
+ "/email/#{platform}".freeze
+ end
+
+end
\ No newline at end of file
diff --git a/app/services/organizations/teams/update_service.rb b/app/services/organizations/teams/update_service.rb
index 275dad886..d77bba9e4 100644
--- a/app/services/organizations/teams/update_service.rb
+++ b/app/services/organizations/teams/update_service.rb
@@ -25,7 +25,7 @@ class Organizations::Teams::UpdateService < ApplicationService
private
def update_params
if team.authorize == "owner"
- update_params = params.slice(:description)
+ update_params = params.slice(:description, :nickname)
else
update_params = params.slice(:name, :nickname, :description, :authorize, :includes_all_project, :can_create_org_project)
end
diff --git a/app/services/projects/accept_join_service.rb b/app/services/projects/accept_join_service.rb
index 69cb97603..2bbacad69 100644
--- a/app/services/projects/accept_join_service.rb
+++ b/app/services/projects/accept_join_service.rb
@@ -53,6 +53,8 @@ class Projects::AcceptJoinService < ApplicationService
def operate_project_member
Projects::AddMemberInteractor.call(@project.owner, @project, @applied_project.user, permission)
+ SendTemplateMessageJob.perform_later('ProjectJoined', @user.id, @applied_project.user_id, @project.id) if Site.has_notice_menu?
+ SendTemplateMessageJob.perform_later('ProjectMemberJoined', @user.id, @applied_project.user_id, @project.id) if Site.has_notice_menu?
end
def send_apply_message
diff --git a/app/services/projects/apply_transfer_service.rb b/app/services/projects/apply_transfer_service.rb
index 0d9d41e7d..98847a91c 100644
--- a/app/services/projects/apply_transfer_service.rb
+++ b/app/services/projects/apply_transfer_service.rb
@@ -24,7 +24,7 @@ class Projects::ApplyTransferService < ApplicationService
raise Error, '仓库标识不正确' if @project.identifier != params[:identifier]
raise Error, '该仓库正在迁移' if @project.is_transfering
raise Error, '新拥有者不存在' unless @owner.present?
- raise Error, '新拥有者资料不完善' unless @owner.profile_completed
+ raise Error, '新拥有者资料不完善' if @owner.is_a?(User) && !@owner.profile_is_completed?
raise Error, '新拥有者已经存在同名仓库!' if Project.where(user_id: @owner.id, identifier: params[:identifier]).present?
raise Error, '未拥有转移权限' unless is_permit_owner
end
diff --git a/app/services/projects/create_service.rb b/app/services/projects/create_service.rb
index e7e4924ae..72ad8f161 100644
--- a/app/services/projects/create_service.rb
+++ b/app/services/projects/create_service.rb
@@ -43,7 +43,7 @@ class Projects::CreateService < ApplicationService
ignore_id: params[:ignore_id],
license_id: params[:license_id],
website: params[:website],
- identifier: params[:repository_name] #新增,hs
+ identifier: params[:repository_name]
}
end
diff --git a/app/services/repositories/detail_service.rb b/app/services/repositories/detail_service.rb
index d8853cf45..b2e7a69e6 100644
--- a/app/services/repositories/detail_service.rb
+++ b/app/services/repositories/detail_service.rb
@@ -8,49 +8,34 @@ class Repositories::DetailService < ApplicationService
end
def call
- if @repo.project.educoder?
- return {
- repo: {},
- release: [],
- branch: [],
- tag: [],
- contributor: [],
- language: {},
- readme: {}
- }
- else
- return {
- repo: repo_suitable,
- release: release_suitable,
- branch: branch_suitable,
- tag: tag_suitable,
- contributor: contributor_suitable,
- language: language_suitable,
- readme: readme_suitable
- }
- end
+ return {
+ repo: repo_suitable,
+ contributor: contributor_suitable,
+ language: language_suitable,
+ branch_tag_total_count: branch_tag_total_count
+ }
+ rescue
+ return {
+ repo: {},
+ release: [],
+ branch: [],
+ branch_type: [],
+ tag: [],
+ contributor: [],
+ language: {},
+ readme: {}
+ }
end
private
+ def branch_tag_total_count
+ Gitea::Repository::GetBranchAndTagTotalNumService.call(@owner.login, @repo.identifier, @owner.gitea_token)
+ end
+
def repo_suitable
Gitea::Repository::GetService.call(@owner, @repo.identifier)
end
- def release_suitable
- releases = Gitea::Versions::ListService.call(@owner.gitea_token, @owner.try(:login), @repo.try(:identifier), {page: 1, limit: 1})
- releases.is_a?(Hash) && releases[:status] == -1 ? [] : releases
- end
-
- def branch_suitable
- branches = Gitea::Repository::Branches::ListService.call(@owner, @repo.identifier)
- branches.is_a?(Hash) && branches[:status] == :error ? [] : branches
- end
-
- def tag_suitable
- tags = Gitea::Repository::Tags::ListService.call(@owner&.gitea_token, @owner.login, @repo.identifier)
- tags.is_a?(Hash) && tags[:status] == -1 ? [] : tags
- end
-
def contributor_suitable
contributors = Gitea::Repository::Contributors::GetService.call(@owner, @repo.identifier)
contributors.is_a?(Hash) && contributors.key?(:status) ? [] : contributors
@@ -60,9 +45,4 @@ class Repositories::DetailService < ApplicationService
result = Gitea::Repository::Languages::ListService.call(@owner.login, @repo.identifier, @user&.gitea_token)
result[:status] === :success ? hash_transform_precentagable(result[:body]) : nil
end
-
- def readme_suitable
- result = Gitea::Repository::Readme::GetService.call(@owner.login, @repo.identifier, @repo.default_branch, @owner.gitea_token)
- result[:status] === :success ? result[:body] : nil
- end
end
diff --git a/app/services/repositories/migrate_service.rb b/app/services/repositories/migrate_service.rb
index 2870faba9..cccfaed04 100644
--- a/app/services/repositories/migrate_service.rb
+++ b/app/services/repositories/migrate_service.rb
@@ -32,7 +32,7 @@ class Repositories::MigrateService < ApplicationService
private: params[:hidden],
mirror: wrapper_mirror || false,
auth_username: params[:login],
- auth_password: Base64.decode64(params[:password])
+ auth_password: Base64.decode64(params[:password] || "")
}
end
diff --git a/app/services/users/apply_authentication_service.rb b/app/services/users/apply_authentication_service.rb
index a6b02f431..5e2562105 100644
--- a/app/services/users/apply_authentication_service.rb
+++ b/app/services/users/apply_authentication_service.rb
@@ -7,7 +7,7 @@ class Users::ApplyAuthenticationService < ApplicationService
end
def call
- raise Error, '请先完善基本信息' unless user.profile_completed?
+ raise Error, '请先完善基本信息' unless user.profile_is_completed?
Users::ApplyAuthenticationForm.new(params).validate!
# raise Error, '您已经申请过实名认证了' if ApplyUserAuthentication.real_name_auth.processing.exists?(user_id: user.id)
diff --git a/app/services/users/apply_professional_auth_service.rb b/app/services/users/apply_professional_auth_service.rb
index c94481890..9f3057ddb 100644
--- a/app/services/users/apply_professional_auth_service.rb
+++ b/app/services/users/apply_professional_auth_service.rb
@@ -9,7 +9,7 @@ class Users::ApplyProfessionalAuthService < ApplicationService
end
def call
- raise Error, '请先完善基本信息' unless user.profile_completed?
+ raise Error, '请先完善基本信息' unless user.profile_is_completed?
Users::ApplyProfessionalAuthForm.new(params).validate!
# raise Error, '您已经申请过职业认证了' if ApplyUserAuthentication.professional_auth.processing.exists?(user_id: user.id)
diff --git a/app/services/users/update_account_service.rb b/app/services/users/update_account_service.rb
index 16824a90e..8a0b1885d 100644
--- a/app/services/users/update_account_service.rb
+++ b/app/services/users/update_account_service.rb
@@ -43,7 +43,7 @@ class Users::UpdateAccountService < ApplicationService
end
# 表示资料完整
- user.profile_completed = true
+ # user.profile_completed = true
extension.save!
user.save!
diff --git a/app/views/admins/edu_settings/_form.html.erb b/app/views/admins/edu_settings/_form.html.erb
new file mode 100644
index 000000000..cce930f2a
--- /dev/null
+++ b/app/views/admins/edu_settings/_form.html.erb
@@ -0,0 +1,38 @@
+
\ No newline at end of file
diff --git a/app/views/admins/edu_settings/_list.html.erb b/app/views/admins/edu_settings/_list.html.erb
new file mode 100644
index 000000000..a37cc9bef
--- /dev/null
+++ b/app/views/admins/edu_settings/_list.html.erb
@@ -0,0 +1,36 @@
+
+
+
+
+<%= render partial: 'admins/shared/paginate', locals: { objects: edu_settings } %>
\ No newline at end of file
diff --git a/app/views/admins/edu_settings/edit.js.erb b/app/views/admins/edu_settings/edit.js.erb
new file mode 100644
index 000000000..c2e0405f2
--- /dev/null
+++ b/app/views/admins/edu_settings/edit.js.erb
@@ -0,0 +1,2 @@
+$("#edu_setting-modals").html("<%= j render(partial: 'admins/edu_settings/form', locals: {type: 'update'}) %>")
+$(".edu_setting-change-modal").modal('show');
\ No newline at end of file
diff --git a/app/views/admins/edu_settings/index.html.erb b/app/views/admins/edu_settings/index.html.erb
new file mode 100644
index 000000000..d52480bae
--- /dev/null
+++ b/app/views/admins/edu_settings/index.html.erb
@@ -0,0 +1,22 @@
+<% define_admin_breadcrumbs do %>
+ <% add_admin_breadcrumb('全局变量配置') %>
+<% end %>
+
+
+
+
+
+ <% if edu_settings.present? %>
+ <% edu_settings.each_with_index do |edu_setting, index| %>
+ 序号
+ 变量名
+ 变量值
+ 备注说明
+ <%= sort_tag('创建时间', name: 'created_at', path: admins_edu_settings_path) %>
+ 操作
+
+
+ <% end %>
+ <% else %>
+ <%= render 'admins/shared/no_data_for_table' %>
+ <% end %>
+
+<%= list_index_no((params[:page] || 1).to_i, index) %>
+
+ <%= edu_setting.name %>
+
+ <%= edu_setting.value %>
+
+ <%= overflow_hidden_span display_text(edu_setting.description), width: 200 %>
+ <%= edu_setting.created_at&.strftime('%Y-%m-%d %H:%M') %>
+
+ <%= link_to "编辑", edit_admins_edu_setting_path(edu_setting), remote: true, class: "action" %>
+ <%= link_to "删除", admins_edu_setting_path(edu_setting), method: :delete, data:{confirm: "确认删除的吗?"}, class: "action" %>
+
+ <%= list_index_no((params[:page] || 1).to_i, index) %>
-<%= school&.name || 'Trustie主站' %>
+<%= school&.name || '主站' %>
<% if laboratory.identifier %>
<%= link_to laboratory.site, "https://#{laboratory.site}", target: '_blank' %>
@@ -30,40 +30,10 @@
<%= laboratory.created_at.strftime('%Y-%m-%d %H:%M') %>
-
- <% if school.present? && laboratory.id != 1 %>
- <%= check_box_tag :sync_course,!laboratory.sync_course,laboratory.sync_course,remote:true,data:{id:laboratory.id},class:"laboratory-sync-form" %>
- <% end %>
-
-
- <% if school.present? && laboratory.id != 1 %>
- <%= check_box_tag :sync_subject,!laboratory.sync_subject,laboratory.sync_subject,remote:true,data:{id:laboratory.id},class:"laboratory-sync-form" %>
- <% end %>
-
-
- <% if school.present? && laboratory.id != 1 %>
- <%= check_box_tag :sync_shixun,!laboratory.sync_shixun,laboratory.sync_shixun,remote:true,data:{id:laboratory.id},class:"laboratory-sync-form" %>
- <% end %>
-
- <%= link_to '定制', admins_laboratory_laboratory_setting_path(laboratory), class: 'action' %>
+ <%= link_to '设置', admins_laboratory_laboratory_setting_path(laboratory), class: 'action' %>
<% if school.present? && laboratory.id != 1 %>
- <%= javascript_void_link '添加管理员', class: 'action', data: { laboratory_id: laboratory.id, toggle: 'modal', target: '.admin-add-laboratory-user-modal' } %>
- <%= link_to '同步用户', synchronize_user_admins_laboratory_path(laboratory), remote: true, data: { confirm: '确认同步该单位下的所有用户到云上实验室吗?' }, class: 'action' %>
-<% end %>
-
-
diff --git a/app/views/admins/laboratories/shared/_list.html.erb b/app/views/admins/laboratories/shared/_list.html.erb
index 621ad7a41..0b6466039 100644
--- a/app/views/admins/laboratories/shared/_list.html.erb
+++ b/app/views/admins/laboratories/shared/_list.html.erb
@@ -7,9 +7,6 @@
统计链接
管理员
<%= sort_tag('创建时间', name: 'id', path: admins_laboratories_path) %>
- 同步课堂
- 同步实践课程
- 同步实训
操作
diff --git a/app/views/admins/laboratory_settings/show.html.erb b/app/views/admins/laboratory_settings/show.html.erb
index 67536af24..735f19f0a 100644
--- a/app/views/admins/laboratory_settings/show.html.erb
+++ b/app/views/admins/laboratory_settings/show.html.erb
@@ -86,7 +86,9 @@
Banner设置
+
+
+
+<%= render partial: 'admins/shared/paginate', locals: { objects: message_templates } %>
\ No newline at end of file
diff --git a/app/views/admins/message_templates/edit.js.erb b/app/views/admins/message_templates/edit.js.erb
new file mode 100644
index 000000000..5d797af2f
--- /dev/null
+++ b/app/views/admins/message_templates/edit.js.erb
@@ -0,0 +1,2 @@
+$("#admins-message-templates-content").html("<%= j render partial: 'admins/message_templates/form', locals:{type: 'update'} %>")
+createMDEditor('message-template-email-editor', { height: 500, placeholder: '请输入邮件模版' });
diff --git a/app/views/admins/message_templates/index.html.erb b/app/views/admins/message_templates/index.html.erb
new file mode 100644
index 000000000..54d273332
--- /dev/null
+++ b/app/views/admins/message_templates/index.html.erb
@@ -0,0 +1,12 @@
+<% define_admin_breadcrumbs do %>
+ <% add_admin_breadcrumb('消息模版') %>
+<% end %>
+
+
+
+
+ <% if message_templates.present? %>
+ <% message_templates.each_with_index do |message_template_type, index| %>
+ <% message_template = message_template_type.constantize.last%>
+
+ <% end %>
+ <% else %>
+ <%= render 'admins/shared/no_data_for_table' %>
+ <% end %>
+
+序号
+ 类型
+ 系统消息模版
+ 邮件模版
+ 通知地址
+ 操作
+
+
+
+
+<%= render partial: 'admins/shared/paginate', locals: { objects: sites } %>
\ No newline at end of file
diff --git a/app/views/admins/sites/edit.js.erb b/app/views/admins/sites/edit.js.erb
new file mode 100644
index 000000000..6711ffc1f
--- /dev/null
+++ b/app/views/admins/sites/edit.js.erb
@@ -0,0 +1,2 @@
+$("#site-modals").html("<%= j render(partial: 'admins/sites/form', locals: {type: 'update'}) %>")
+$(".site-change-modal").modal('show');
\ No newline at end of file
diff --git a/app/views/admins/sites/index.html.erb b/app/views/admins/sites/index.html.erb
new file mode 100644
index 000000000..8a5fa1bfc
--- /dev/null
+++ b/app/views/admins/sites/index.html.erb
@@ -0,0 +1,24 @@
+<% define_admin_breadcrumbs do %>
+ <% add_admin_breadcrumb('Setting接口配置') %>
+<% end %>
+
+
+
+
+
+ <% if sites.present? %>
+ <% sites.each_with_index do |site, index| %>
+ 序号
+ 名称
+ 路由
+ 标识
+ 类型
+ <%= sort_tag('创建时间', name: 'created_at', path: admins_sites_path) %>
+ 操作
+
+
+ <% end %>
+ <% else %>
+ <%= render 'admins/shared/no_data_for_table' %>
+ <% end %>
+
+<%= list_index_no((params[:page] || 1).to_i, index) %>
+
+ <%= overflow_hidden_span display_text(site.name), width: 150 %>
+
+ <%= site.url %>
+
+ <%= overflow_hidden_span display_text(site.key), width: 150 %>
+ <%= site.site_type.humanize %>
+ <%= site.created_at&.strftime('%Y-%m-%d %H:%M') %>
+
+ <%= link_to "编辑", edit_admins_site_path(site), remote: true, class: "action" %>
+ <%= link_to "删除", admins_site_path(site), method: :delete, data:{confirm: "确认删除的吗?"}, class: "action" %>
+
+
+
+
+
+<%= render partial: 'admins/shared/paginate', locals: { objects: notifications } %>
\ No newline at end of file
diff --git a/app/views/admins/system_notifications/edit.js.erb b/app/views/admins/system_notifications/edit.js.erb
new file mode 100644
index 000000000..e5929f876
--- /dev/null
+++ b/app/views/admins/system_notifications/edit.js.erb
@@ -0,0 +1,2 @@
+$("#admins-system-notification-content").html("<%= j render(partial: 'admins/system_notifications/form', locals: {type: 'update'}) %>")
+createMDEditor('system-notification-content-editor', { height: 500, placeholder: '请输入邮件模版' });
\ No newline at end of file
diff --git a/app/views/admins/system_notifications/index.html.erb b/app/views/admins/system_notifications/index.html.erb
new file mode 100644
index 000000000..01a35f216
--- /dev/null
+++ b/app/views/admins/system_notifications/index.html.erb
@@ -0,0 +1,21 @@
+<% define_admin_breadcrumbs do %>
+ <% add_admin_breadcrumb('系统通知模版') %>
+<% end %>
+
+
+
+
+
+ <% if notifications.present? %>
+ <% notifications.each_with_index do |notification, index| %>
+ 序号
+ 标题
+ 副标题
+ <%= sort_tag('是否置顶', name: 'is_top', path: admins_system_notifications_path) %>
+ <%= sort_tag('创建时间', name: 'created_at', path: admins_system_notifications_path) %>
+ 操作
+
+
+ <% end %>
+ <% else %>
+ <%= render 'admins/shared/no_data_for_table' %>
+ <% end %>
+
+<%= list_index_no((params[:page] || 1).to_i, index) %>
+ <%= notification.subject %>
+ <%= notification.sub_subject %>
+ <%= notification.is_top ? '√' : '' %>
+ <%= notification.created_at&.strftime('%Y-%m-%d %H:%M') %>
+
+ <%= javascript_void_link '置顶', class: 'action unclose-action', data: { id: notification.id }, style: notification.is_top ? 'display: none;' : '' %>
+ <%= javascript_void_link '取消置顶', class: 'action close-action', data: { id: notification.id }, style: notification.is_top ? '' : 'display: none;' %>
+ <%= link_to "编辑", edit_admins_system_notification_path(notification), remote: true, class: "action" %>
+ <%= link_to "删除", admins_system_notification_path(notification), method: :delete, data:{confirm: "确认删除的吗?"}, class: "action" %>
+
+ <%= pluralize(edu_setting.errors.count, "error") %> prohibited this edu_setting from being saved:
-
-
- <% edu_setting.errors.full_messages.each do |message| %>
-
- Editing Edu Setting
-
-<%= render 'form', edu_setting: @edu_setting %>
-
-<%= link_to 'Show', @edu_setting %> |
-<%= link_to 'Back', edu_settings_path %>
diff --git a/app/views/edu_settings/index.html.erb b/app/views/edu_settings/index.html.erb
deleted file mode 100644
index d49977254..000000000
--- a/app/views/edu_settings/index.html.erb
+++ /dev/null
@@ -1,30 +0,0 @@
-EduCoder公共配置
-
-
-
-
-
-
-
-
-
- <% @edu_settings.each do |edu_setting| %>
- 变量名
- 变量值
-
-
-
- <% end %>
-
-<%= edu_setting.name %>
- <%= edu_setting.value %>
- <%= link_to 'Show', edu_setting %>
- <%= link_to 'Edit', edit_edu_setting_path(edu_setting) %>
- <%= link_to 'Destroy', edu_setting, method: :delete, data: { confirm: 'Are you sure?' } %>
-
-
-<%= link_to 'New Edu Setting', new_edu_setting_path %>
diff --git a/app/views/edu_settings/new.html.erb b/app/views/edu_settings/new.html.erb
deleted file mode 100644
index 8a70e3a63..000000000
--- a/app/views/edu_settings/new.html.erb
+++ /dev/null
@@ -1,5 +0,0 @@
-New Edu Setting
-
-<%= render 'form', edu_setting: @edu_setting %>
-
-<%= link_to 'Back', edu_settings_path %>
diff --git a/app/views/edu_settings/show.html.erb b/app/views/edu_settings/show.html.erb
deleted file mode 100644
index 9d027373f..000000000
--- a/app/views/edu_settings/show.html.erb
+++ /dev/null
@@ -1,14 +0,0 @@
-
+
Users
获取当前登陆用户信息
@@ -971,6 +1018,468 @@ Success — a happy kitten is an authenticated kitten!
+用户消息列表
+
+
+curl -X GET http://localhost:3000/api/users/:login/messages.json
+await octokit.request('GET /api/users/:login/messages.json')
+HTTP 请求
+GET api/users/yystopf/messages.json请求字段说明:
+
+
+
+
+
+参数
+类型
+字段说明
+
+
+type
+string
+消息类型,不传为所有消息,notification为系统消息,atme为@我消息
+
+
+status
+integer
+是否已读,不传为所有消息,1为未读,2为已读
+
+
+limit
+integer
+每页个数
+
+
+page
+integer
+页码
+返回字段说明:
+
+
+
+
+
+参数
+类型
+字段说明
+
+
+total_count
+integer
+消息总数
+
+
+type
+string
+消息类型
+
+
+unread_notification
+integer
+未读系统通知数量
+
+
+unread_atme
+integer
+未读@我数量
+
+
+messages.id
+integer
+消息id
+
+
+messages.status
+integer
+消息是否已读,1为未读,2为已读
+
+
+messages.content
+string
+消息内容
+
+
+messages.notification_url
+string
+消息跳转地址
+
+
+messages.source
+string
+消息来源
+
+
+messages.timeago
+string
+消息时间
+
+
+messages.type
+string
+消息类型,notification为系统消息,atme为@我消息
+
+
+sender
+object
+消息发送者
+消息来源source字段说明
+
+
+
+
+
+
+类型
+说明
+
+
+IssueAssigned
+有新指派给我的易修
+
+
+IssueAssignerExpire
+我负责的易修截止日期到达最后一天
+
+
+IssueAtme
+在易修中@我
+
+
+IssueChanged
+我创建或负责的易修状态变更
+
+
+IssueCreatorExpire
+我创建的易修截止日期到达最后一天
+
+
+IssueDeleted
+我创建或负责的易修删除
+
+
+IssueJournal
+我创建或负责的易修有新的评论
+
+
+LoginIpTip
+登录异常提示
+
+
+OrganizationJoined
+账号被拉入组织
+
+
+OrganizationLeft
+账号被移出组织
+
+
+OrganizationRole
+账号组织权限变更
+
+
+ProjectDeleted
+我关注的仓库被删除
+
+
+ProjectFollowed
+我管理的仓库被关注
+
+
+ProjectForked
+我管理的仓库被复刻
+
+
+ProjectIssue
+我管理/关注的仓库有新的易修
+
+
+ProjectJoined
+账号被拉入项目
+
+
+ProjectLeft
+账号被移出项目
+
+
+ProjectMemberJoined
+我管理的仓库有成员加入
+
+
+ProjectMemberLeft
+我管理的仓库有成员移出
+
+
+ProjectMilestone
+我管理的仓库有新的里程碑
+
+
+ProjectPraised
+我管理的仓库被点赞
+
+
+ProjectPullRequest
+我管理/关注的仓库有新的合并请求
+
+
+ProjectRole
+账号仓库权限变更
+
+
+ProjectSettingChanged
+我管理的仓库项目设置被更改
+
+
+ProjectTransfer
+我关注的仓库被转移
+
+
+ProjectVersion
+我关注的仓库有新的发行版
+
+
+PullRequestAssigned
+有新指派给我的合并请求
+
+
+PullReuqestAtme
+在合并请求中@我
+
+
+PullRequestChanged
+我创建或负责的合并请求状态变更
+
+
+PullRequestClosed
+我创建或负责的合并请求被关闭
+
+
+PullRequestJournal
+我创建或负责的合并请求有新的评论
+
+
+PullRequestMerged
+我创建或负责的合并请求被合并
+
+
+{
+ "total_count": 5,
+ "type": "",
+ "unread_notification": 3,
+ "unread_atme": 2,
+ "messages": [
+ {
+ "id": 1,
+ "status": 1,
+ "content": "Atme Message Content 1",
+ "notification_url": "http://www.baidu.com",
+ "source": "PullRequestAtme",
+ "time_ago": "1天前",
+ "type": "atme",
+ "sender": {
+ "id": 5,
+ "type": "User",
+ "name": "testforge2",
+ "login": "testforge2",
+ "image_url": "system/lets/letter_avatars/2/T/236_177_85/120.png"
+ }
+ },
+ {
+ "id": 2,
+ "status": 0,
+ "content": "Atme Message Content 2",
+ "notification_url": "http://www.baidu.com",
+ "source": "IssueAtme",
+ "time_ago": "1天前",
+ "type": "atme",
+ "sender": {
+ "id": 4,
+ "type": "User",
+ "name": "testforge1",
+ "login": "testforge1",
+ "image_url": "system/lets/letter_avatars/2/T/19_237_174/120.png"
+ }
+ },
+ {
+ "id": 3,
+ "status": 1,
+ "content": "Notification Message Content 1",
+ "notification_url": "http://www.baidu.com",
+ "source": "IssueDelete",
+ "time_ago": "1天前",
+ "type": "notification"
+ },
+ {
+ "id": 4,
+ "status": 0,
+ "content": "Notification Message Content 2",
+ "notification_url": "http://www.baidu.com",
+ "source": "IssueChanged",
+ "time_ago": "1天前",
+ "type": "notification"
+ },
+ {
+ "id": 5,
+ "status": 0,
+ "content": "Notification Message Content 3",
+ "notification_url": "http://www.baidu.com",
+ "source": "ProjectJoined",
+ "time_ago": "1天前",
+ "type": "notification"
+ }
+ ]
+}
+发送消息
+
+
+curl -X POST http://localhost:3000/api/users/:login/messages.json
+await octokit.request('POST /api/users/:login/messages.json')
+HTTP 请求
+POST api/users/yystopf/messages.json请求字段说明:
+
+
+
+
+
+
+参数
+类型
+字段说明
+
+
+type
+string
+消息类型
+
+
+receivers_login
+array
+需要发送消息的用户名数组
+
+
+atmeable_type
+string
+atme消息对象,是从哪里@我的,比如评论:Journal、易修:Issue、合并请求:PullRequest
+
+
+atmeable_id
+integer
+atme消息对象id
+
+
+{
+ "type": "atme",
+ "receivers_login": ["yystopf", "testforge1"],
+ "atmeable_type": "Journal",
+ "atmeable_id": 67
+}
+
+
+{
+ "status": 0,
+ "message": "success"
+}
+阅读消息
+
+
+curl -X POST http://localhost:3000/api/users/:login/messages/read.json
+await octokit.request('POST /api/users/:login/messages/read.json')
+HTTP 请求
+POST api/users/yystopf/messages/read.json请求字段说明:
+
+
+
+
+
+
+参数
+类型
+字段说明
+
+
+type
+string
+消息类型,不传为所有消息,notification为系统消息,atme为@我消息
+
+
+ids
+array
+消息id数组,包含-1则把所有未读消息标记为已读
+
+
+{
+ "status": 0,
+ "message": "success"
+}
+删除消息
+
+
+curl -X DELETE http://localhost:3000/api/users/:login/messages.json
+await octokit.request('DELETE /api/users/:login/messages.json')
+HTTP 请求
+DELETE api/users/yystopf/messages.json请求字段说明:
+
+
+
+
+
+
+参数
+类型
+字段说明
+
+
+type
+string
+消息类型,atme为@我消息
+
+
+ids
+array
+消息id数组,包含-1则把所有消息删除
+
+
+{
+ "status": 0,
+ "message": "success"
+}
+更改用户信息
curl -X PATCH/PUT http://localhost:3000/api/users/yystopf.json
await octokit.request('PATCH/PUT /api/users/:login.json')
-HTTP 请求
+HTTP 请求
PATCH/PUT /api/users/:login.json
| 参数 | @@ -1069,7 +1578,339 @@ Success — a happy kitten is an authenticated kitten! "status": 0, "message": "success" } -
|---|
| 参数 | +类型 | +字段说明 | +
|---|---|---|
| type | +string | +消息配置类型 | +
| type_name | +string | +消息配置类型含义 | +
| total_settings_count | +int | +配置条数 | +
| settings.name | +string | +配置名称 | +
| settings.key | +string | +配置标识 | +
| settings.notification_disabled | +boolean | +站内信设置是否禁用 | +
| settings.email_disabled | +boolean | +邮件设置是否禁用 | +
++返回的JSON示例:
+
{
+ "status": 0,
+ "message": "响应成功",
+ "setting_types": [
+ {
+ "type": "TemplateMessageSetting::Normal",
+ "type_name": "",
+ "total_settings_count": 3,
+ "settings": [
+ {
+ "name": "被拉入或移出组织",
+ "key": "Organization",
+ "notification_disabled": true,
+ "email_disabled": false
+ },
+ {
+ "name": "被拉入或移出项目",
+ "key": "Project",
+ "notification_disabled": true,
+ "email_disabled": false
+ },
+ {
+ "name": "有权限变更",
+ "key": "Permission",
+ "notification_disabled": true,
+ "email_disabled": false
+ }
+ ]
+ },
+ {
+ "type": "TemplateMessageSetting::CreateOrAssign",
+ "type_name": "我创建的或负责的",
+ "total_settings_count": 4,
+ "settings": [
+ {
+ "name": "易修被指派",
+ "key": "IssueAssigned",
+ "notification_disabled": true,
+ "email_disabled": false
+ },
+ {
+ "name": "合并请求被指派",
+ "key": "PullRequestAssigned",
+ "notification_disabled": true,
+ "email_disabled": false
+ }
+ ]
+ },
+ {
+ "type": "TemplateMessageSetting::ManageProject",
+ "type_name": "我管理的仓库",
+ "total_settings_count": 4,
+ "settings": [
+ {
+ "name": "有新的易修",
+ "key": "Issue",
+ "notification_disabled": true,
+ "email_disabled": false
+ },
+ {
+ "name": "有新的合并请求",
+ "key": "PullRequest",
+ "notification_disabled": true,
+ "email_disabled": false
+ },
+ {
+ "name": "有成员变动",
+ "key": "Member",
+ "notification_disabled": true,
+ "email_disabled": false
+ },
+ {
+ "name": "设置更改",
+ "key": "SettingChanged",
+ "notification_disabled": true,
+ "email_disabled": false
+ }
+ ]
+ }
+ ]
+}
+获取用户消息设置配置信息
+ +++示例:
+
curl -X GET http://localhost:3000/api/users/yystopf/template_message_settings.json
+await octokit.request('GET /api/uses/yystopf/template_message_settings.json')
+GET /api/users/:user_id/template_message_settings.json
| 参数 | +类型 | +字段说明 | +
|---|---|---|
| notification_body | +string | +站内信配置 | +
| email_body | +string | +邮件配置 | +
++返回的JSON示例:
+
{
+ "status": 0,
+ "message": "响应成功",
+ "user": {
+ "id": 2,
+ "type": "User",
+ "name": "heh",
+ "login": "yystopf",
+ "image_url": "system/lets/letter_avatars/2/H/188_239_142/120.png"
+ },
+ "notification_body": {
+ "CreateOrAssign::IssueAssigned": true,
+ "CreateOrAssign::PullRequestAssigned": true,
+ "ManageProject::Issue": true,
+ "ManageProject::PullRequest": true,
+ "ManageProject::Member": true,
+ "ManageProject::SettingChanged": true,
+ "Normal::Organization": true,
+ "Normal::Project": true,
+ "Normal::Permission": true
+ },
+ "email_body": {
+ "CreateOrAssign::IssueAssigned": false,
+ "CreateOrAssign::PullRequestAssigned": false,
+ "ManageProject::Issue": false,
+ "ManageProject::PullRequest": false,
+ "ManageProject::Member": false,
+ "ManageProject::SettingChanged": true,
+ "Normal::Organization": false,
+ "Normal::Project": true,
+ "Normal::Permission": false
+ }
+}
+重新设置用户消息设置配置信息
+ +++示例:
+
curl -X POST http://localhost:3000/api/users/yystopf/template_message_settings/update_setting.json
+await octokit.request('POST /api/uses/yystopf/template_message_settings/update_setting.json')
+POST /api/users/:user_id/template_message_settings/update_setting.json
| 参数 | +类型 | +字段说明 | +
|---|---|---|
| notification_body | +string | +站内信配置 | +
| email_body | +string | +邮件配置 | +
++请求的JSON示例:
+
{
+ "setting": {
+ "notification_body": {
+ "CreateOrAssign::IssueAssigned": true,
+ "CreateOrAssign::PullRequestAssigned": true,
+ "ManageProject::Issue": true,
+ "ManageProject::PullRequest": true,
+ "ManageProject::Member": true,
+ "ManageProject::SettingChanged": true,
+ "Normal::Organization": true,
+ "Normal::Project": true,
+ "Normal::Permission": true
+ },
+ "email_body": {
+ "CreateOrAssign::IssueAssigned": false,
+ "CreateOrAssign::PullRequestAssigned": false,
+ "ManageProject::Issue": false,
+ "ManageProject::PullRequest": false,
+ "ManageProject::Member": false,
+ "ManageProject::SettingChanged": true,
+ "Normal::Organization": false,
+ "Normal::Project": "t",
+ "Normal::Permission": false
+ }
+ }
+}
+| 参数 | +类型 | +字段说明 | +
|---|---|---|
| notification_body | +string | +站内信配置 | +
| email_body | +string | +邮件配置 | +
++返回的JSON示例:
+
{
+ "status": 0,
+ "message": "响应成功",
+ "user": {
+ "id": 2,
+ "type": "User",
+ "name": "heh",
+ "login": "yystopf",
+ "image_url": "system/lets/letter_avatars/2/H/188_239_142/120.png"
+ },
+ "notification_body": {
+ "CreateOrAssign::IssueAssigned": true,
+ "CreateOrAssign::PullRequestAssigned": true,
+ "ManageProject::Issue": true,
+ "ManageProject::PullRequest": true,
+ "ManageProject::Member": true,
+ "ManageProject::SettingChanged": true,
+ "Normal::Organization": true,
+ "Normal::Project": true,
+ "Normal::Permission": true
+ },
+ "email_body": {
+ "CreateOrAssign::IssueAssigned": false,
+ "CreateOrAssign::PullRequestAssigned": false,
+ "ManageProject::Issue": false,
+ "ManageProject::PullRequest": false,
+ "ManageProject::Member": false,
+ "ManageProject::SettingChanged": true,
+ "Normal::Organization": false,
+ "Normal::Project": true,
+ "Normal::Permission": false
+ }
+}
+获取用户星标项目
@@ -1077,9 +1918,9 @@ Success — a happy kitten is an authenticated kitten!
curl -X GET http://localhost:3000/api/users/yystopf/is_pinned_projects.json
await octokit.request('GET /api/users/:login/is_pinned_projects.json')
-GET api/users/:login/is_pinned_projects.json
| 参数 | @@ -1264,9 +2105,9 @@ Success — a happy kitten is an authenticated kitten!
|---|
| 参数 | @@ -1310,9 +2151,9 @@ Success — a happy kitten is an authenticated kitten!
|---|
| 参数 | @@ -1351,9 +2192,9 @@ Success — a happy kitten is an authenticated kitten!
|---|
| 参数 | @@ -1440,9 +2281,9 @@ Success — a happy kitten is an authenticated kitten!
|---|
| 参数 | @@ -1456,7 +2297,7 @@ Success — a happy kitten is an authenticated kitten!年份 |
|---|
| 参数 | @@ -1585,9 +2426,9 @@ Success — a happy kitten is an authenticated kitten!
|---|
| 参数 | @@ -1601,7 +2442,7 @@ Success — a happy kitten is an authenticated kitten!日期,格式: 2021-05-28 |
|---|
| 参数 | @@ -1902,9 +2743,9 @@ Success — a happy kitten is an authenticated kitten!
|---|
| 参数 | @@ -1923,7 +2764,7 @@ Success — a happy kitten is an authenticated kitten!时间戳,结束时间,格式:1622131200 |
|---|
| 参数 | @@ -2045,9 +2886,9 @@ Success — a happy kitten is an authenticated kitten!
|---|
| 参数 | @@ -2066,7 +2907,7 @@ Success — a happy kitten is an authenticated kitten!时间戳,结束时间,格式:1622131200 |
|---|
| 参数 | @@ -2127,9 +2968,9 @@ Success — a happy kitten is an authenticated kitten!
|---|
| 参数 | @@ -2148,7 +2989,7 @@ Success — a happy kitten is an authenticated kitten!时间戳,结束时间,格式:1622131200 |
|---|
| 参数 | @@ -2188,9 +3029,9 @@ Success — a happy kitten is an authenticated kitten!
|---|
| 参数 | @@ -2204,7 +3045,7 @@ Success — a happy kitten is an authenticated kitten!用户标识 |
|---|
| 参数 | @@ -2467,9 +3308,9 @@ Success — a happy kitten is an authenticated kitten!
|---|
| 参数 | @@ -2483,7 +3324,7 @@ Success — a happy kitten is an authenticated kitten!用户标识 |
|---|
| 参数 | @@ -2659,9 +3500,9 @@ Success — a happy kitten is an authenticated kitten!
|---|
| 参数 | @@ -2680,7 +3521,7 @@ Success — a happy kitten is an authenticated kitten!迁移id |
|---|
| 参数 | @@ -2850,9 +3691,9 @@ Success — a happy kitten is an authenticated kitten!
|---|
| 参数 | @@ -2871,7 +3712,7 @@ Success — a happy kitten is an authenticated kitten!迁移id |
|---|
| 参数 | @@ -3041,9 +3882,9 @@ Success — a happy kitten is an authenticated kitten!
|---|
| 参数 | @@ -3057,7 +3898,7 @@ Success — a happy kitten is an authenticated kitten!用户标识 |
|---|
| 参数 | @@ -3201,9 +4042,9 @@ Success — a happy kitten is an authenticated kitten!
|---|
| 参数 | @@ -3222,7 +4063,7 @@ Success — a happy kitten is an authenticated kitten!申请id |
|---|
| 参数 | @@ -3360,9 +4201,9 @@ Success — a happy kitten is an authenticated kitten!
|---|
| 参数 | @@ -3381,7 +4222,7 @@ Success — a happy kitten is an authenticated kitten!申请id |
|---|
| 参数 | @@ -5705,16 +6546,16 @@ http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects/organizat "Shell": "0.1%" } } -
|---|
| string | 项目标识identifier | |||
| page | +否 | +1 | +integer | +页码 | +
| limit | +否 | +20 | +integer | +每页个数 | +
| id | +int | +标签id | +
| name | +string | +标签名称 | +
| zipball_url | +string | +标签zip包下载地址 | +
| tarball_url | +string | +标签tar包下载地址 | +
| tagger | +object | +打标签的人 | +
| time_ago | +string | +打标签的时间 | +
| created_at_unix | +string | +打标签的时间戳 | +
| message | +string | +标签信息 | +
| commit | +object | +标签最后一个commit | +
| commit.sha | +string | +commit的id | +
| commit.message | +string | +commit的提交信息 | +
| commit.time_ago | +string | +commit的提交时间 | +
| commit.created_at_unix | +string | +commit的提交时间戳 | +
| commit.committer | +object | +commit的提交者 | +
| commit.author | +object | +commit的作者 | +
++返回的JSON示例:
+
[
+ {
+ "name": "v2.0.0",
+ "id": "c7d0873ee41796d1a0e193063095ccf539a9bf31",
+ "zipball_url": "http://localhost:3000/api/yystopf/csfjkkj/archive/v2.0.0.zip",
+ "tarball_url": "http://localhost:3000/api/yystopf/csfjkkj/archive/v2.0.0.tar.gz",
+ "tagger": {
+ "id": 4,
+ "login": "testforge1",
+ "name": "testforge1",
+ "image_url": "system/lets/letter_avatars/2/T/19_237_174/120.png"
+ },
+ "time_ago": "1天前",
+ "created_at_unix": 1632376903,
+ "message": "jdfkls",
+ "commit": {
+ "sha": "08fe383f1e5ebe2e2a384a8ea3ee890a758c7cd7",
+ "message": "add\n",
+ "time_ago": "1天前",
+ "created_at_unix": 1632376186,
+ "committer": {
+ "id": 4,
+ "login": "testforge1",
+ "name": "testforge1",
+ "image_url": "system/lets/letter_avatars/2/T/19_237_174/120.png"
+ },
+ "author": {
+ "id": 4,
+ "login": "testforge1",
+ "name": "testforge1",
+ "image_url": "system/lets/letter_avatars/2/T/19_237_174/120.png"
+ }
+ }
+ },
+ {
+ "name": "v1.0.0",
+ "id": "12168ad39c3ef201a445a2db181a3e43d50e40dd",
+ "zipball_url": "http://localhost:3000/api/yystopf/csfjkkj/archive/v1.0.0.zip",
+ "tarball_url": "http://localhost:3000/api/yystopf/csfjkkj/archive/v1.0.0.tar.gz",
+ "tagger": {
+ "id": null,
+ "login": "viletyy",
+ "name": "viletyy",
+ "image_url": "system/lets/letter_avatars/2/V/39_141_222/120.png"
+ },
+ "time_ago": "10天前",
+ "created_at_unix": 1631588042,
+ "message": "dfks",
+ "commit": {
+ "sha": "5291b5e45a377c1f7710cc6647259887ed7aaccf",
+ "message": "ADD file via upload\n",
+ "time_ago": "21天前",
+ "created_at_unix": 1630648417,
+ "committer": {
+ "id": null,
+ "login": "yystopf",
+ "name": "yystopf",
+ "image_url": "system/lets/letter_avatars/2/Y/241_125_89/120.png"
+ },
+ "author": {
+ "id": null,
+ "login": "yystopf",
+ "name": "yystopf",
+ "image_url": "system/lets/letter_avatars/2/Y/241_125_89/120.png"
+ }
+ }
+ }
+]
+编辑仓库信息
+ +++示例:
+
curl -X GET http://localhost:3000/api/jasder/jasder_test/edit.json
+await octokit.request('GET /api/jasder/jasder_test/edit.json')
+GET /api/:owner/:repo/edit.json
| 参数 | +必选 | +默认 | +类型 | +字段说明 | +
|---|---|---|---|---|
| owner | +是 | ++ | string | +用户登录名 | +
| repo | +是 | ++ | string | +项目标识identifier | +
| 参数 | +类型 | +字段说明 | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| identifier | string | 仓库标识 | @@ -5817,9 +6863,9 @@ http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects/organizat -d "private=true" \ http://localhost:3000/api/jasder/jasder_test.json
| 参数 | @@ -5879,7 +6925,7 @@ http://localhost:3000/api/jasder/jasder_test.json项目是否私有, true:为私有,false: 公开,默认为公开 |
|---|
| 参数 | @@ -5944,9 +6990,9 @@ http://localhost:3000/api/jasder/jasder_test.json
|---|
| 参数 | @@ -5971,7 +7017,7 @@ http://localhost:3000/api/jasder/jasder_test.json项目标识identifier |
|---|
| 参数 | @@ -6012,83 +7058,8 @@ http://localhost:3000/api/jasder/jasder_test.json -d "user_id=12" \ http://localhost:3000/api/jasder/jasder_test/collaborators.json
|---|
| 参数 | -必选 | -默认 | -类型 | -字段说明 | -
|---|---|---|---|---|
| owner | -是 | -- | string | -用户登录名 | -
| repo | -是 | -- | string | -项目标识identifier | -
| user_id | -是 | -int | -- | 用户id | -
| 参数 | -类型 | -字段说明 | -
|---|---|---|
| status | -int | -返回状态, 0: 表示操作成功 | -
| message | -string | -返回信息说明 | -
--返回的JSON示例:
-
{
- "status": 0,
- "message": "success"
-}
-仓库中删除成员操作
- ---示例:
-
curl -X DELETE \
--d "user_id=12" \
-http://localhost:3000/api/jasder/jasder_test/collaborators.json
-await octokit.request('DELETE /api/jasder/jasder_test/collaborators.json')
DELETE /api/:owner/:repo/collaborators.json
POST /api/:owner/:repo/collaborators.json
++返回的JSON示例:
+
{
+ "status": 0,
+ "message": "success"
+}
+仓库中删除成员操作
+ +++示例:
+
curl -X DELETE \
+-d "user_id=12" \
+http://localhost:3000/api/jasder/jasder_test/collaborators.json
+await octokit.request('DELETE /api/jasder/jasder_test/collaborators.json')
+DELETE /api/:owner/:repo/collaborators.json
| 参数 | +必选 | +默认 | +类型 | +字段说明 | +
|---|---|---|---|---|
| owner | +是 | ++ | string | +用户登录名 | +
| repo | +是 | ++ | string | +项目标识identifier | +
| user_id | +是 | +int | ++ | 用户id | +
| 参数 | +类型 | +字段说明 | +
|---|---|---|
| status | +int | +返回状态, 0: 表示操作成功 | +
| message | +string | +返回信息说明 | +
@@ -6163,9 +7209,9 @@ http://localhost:3000/api/jasder/jasder_test/collaborators.json -d "role=Developer" \ http://localhost:3000/api/jasder/jasder_test/change_role.json返回的JSON示例:
await octokit.request('PUT /api/jasder/jasder_test/change_role.json')
-PUT /api/:owner/:repo/change_role.json
| 参数 | @@ -6204,7 +7250,7 @@ http://localhost:3000/api/jasder/jasder_test/change_role.json取值范围:"Manager", "Developer", "Reporter";分别为项目管理人员(拥有所有操作权限)、项目开发人员(只拥有读写权限)、项目报告人员(只拥有读权限) |
|---|
| 参数 | @@ -6246,9 +7292,9 @@ http://localhost:3000/api/jasder/jasder_test/change_role.json -d "limit=5" \ http://localhost:3000/api/jasder/jasder_test/collaborators.json
|---|
| 参数 | @@ -6287,7 +7333,7 @@ http://localhost:3000/api/jasder/jasder_test/collaborators.json每页多少条数据,默认15条 |
|---|
| 参数 | @@ -6375,9 +7421,9 @@ http://localhost:3000/api/jasder/jasder_test/collaborators.json -d "ref=develop" \ http://localhost:3000/api/yystopf/ceshi/files.json
|---|
| 参数 | @@ -6416,7 +7462,7 @@ http://localhost:3000/api/yystopf/ceshi/files.json分支名,默认为仓库默认分支 |
|---|
| 参数 | @@ -6498,9 +7544,9 @@ http://localhost:3000/api/yystopf/ceshi/files.json -d "ref=develop" \ http://localhost:3000//api/jasder/jasder_test/entries.json
|---|
| 参数 | @@ -6532,7 +7578,7 @@ http://localhost:3000//api/jasder/jasder_test/entries.json分支名称、tag名称或是提交记录id,默认为master分支 |
|---|
| 参数 | @@ -6646,9 +7692,9 @@ http://localhost:3000//api/jasder/jasder_test/entries.json -d "filepath=file" \ http://localhost:3000//api/jasder/jasder_test/sub_entries.json
|---|
| 参数 | @@ -6687,7 +7733,7 @@ http://localhost:3000//api/jasder/jasder_test/sub_entries.json分支名称、tag名称或是提交记录id,默认为master分支 |
|---|
| 参数 | @@ -6773,6 +7819,237 @@ http://localhost:3000//api/jasder/jasder_test/sub_entries.json +
|---|
| 参数 | +必选 | +默认 | +类型 | +字段说明 | +
|---|---|---|---|---|
| owner | +是 | ++ | string | +用户登录名 | +
| repo | +是 | ++ | string | +项目标识identifier | +
| ref | +否 | ++ | string | +分支名称、tag名称或是提交记录id,默认为默认分支 | +
| filepath | +否 | ++ | string | +子目录名称,默认为空 | +
| 参数 | +类型 | +字段说明 | +
|---|---|---|
| type | +string | +文件类型, file:文件,dir:文件目录 | +
| encoding | +string | +编码 | +
| size | +int | +文件夹或文件大小 单位B | +
| name | +string | +文件夹或文件名称 | +
| path | +string | +文件夹或文件相对路径 | +
| content | +string | +文件内容 | +
| sha | +string | +文件commitid | +
++返回的JSON示例:
+
{
+ "type": "file",
+ "encoding": "base64",
+ "size": 24,
+ "name": "README.md",
+ "path": "lib/README.md",
+ "content": "ZGZhc2RhZGpmIGRrZnNsCgpzZGZkZnMK",
+ "sha": "860962cd21c60b1a9e07d723080c87c32c18d44a"
+}
+获取仓库贡献者
+ +++示例:
+
curl -X GET \
+-d "ref=master" \
+-d "filepath=lib" \
+http://localhost:3000/api/yystopf/csfjkkj/contributors.json
+await octokit.request('GET /api/yystopf/csfjkkj/contributors.json')
+GET /api/:owner/:repo/contributors.json
| 参数 | +必选 | +默认 | +类型 | +字段说明 | +
|---|---|---|---|---|
| owner | +是 | ++ | string | +用户登录名 | +
| repo | +是 | ++ | string | +项目标识identifier | +
| ref | +否 | ++ | string | +分支名称、tag名称或是提交记录id,默认为整个仓库 | +
| filepath | +否 | ++ | string | +子目录名称,默认为空 | +
| 参数 | +类型 | +字段说明 | +
|---|---|---|
| total_count | +integer | +贡献者数量 | +
| contributions | +integer | +贡献数量 | +
| login | +string | +用户登录名 | +
| type | +string | +用户类型 | +
| name | +string | +用户昵称 | +
| image_url | +string | +用户头像 | +
++返回的JSON示例:
+
{
+ "contributors": [
+ {
+ "contributions": 5,
+ "login": "testforge2",
+ "type": "User",
+ "name": "testforge2",
+ "image_url": "system/lets/letter_avatars/2/T/236_177_85/120.png"
+ },
+ {
+ "contributions": 79,
+ "login": "yystopf",
+ "type": "User",
+ "name": "yystopf",
+ "image_url": "system/lets/letter_avatars/2/Y/241_125_89/120.png"
+ }
+ ],
+ "total_count": 2
+}
+获取仓库webhooks列表
@@ -6782,9 +8059,9 @@ http://localhost:3000//api/jasder/jasder_test/sub_entries.jsoncurl -X GET \
http://localhost:3000/api/yystopf/ceshi/webhooks.json
await octokit.request('GET /api/yystopf/ceshi/webhooks.json')
-GET /api/:owner/:repo/webhooks.json
| 参数 | @@ -6809,7 +8086,7 @@ http://localhost:3000/api/yystopf/ceshi/webhooks.json项目标识identifier |
|---|
| 参数 | @@ -6911,9 +8188,9 @@ http://localhost:3000/api/yystopf/ceshi/webhooks.json
|---|
| 参数 | @@ -6945,7 +8222,7 @@ http://localhost:3000/api/yystopf/ceshi/webhooks/3/edit.jsonwebhook ID |
|---|
| 参数 | @@ -7146,9 +8423,9 @@ http://localhost:3000/api/yystopf/ceshi/webhooks/3/edit.json
|---|
| 参数 | @@ -7332,7 +8609,7 @@ http://localhost:3000/api/yystopf/ceshi/webhooks.json "branch_filter": "*", "events": ["push"] } -
|---|
| 参数 | @@ -7404,9 +8681,9 @@ http://localhost:3000/api/yystopf/ceshi/webhooks.json
|---|
| 参数 | @@ -7597,7 +8874,7 @@ http://localhost:3000/api/yystopf/ceshi/webhooks/7.json "branch_filter": "*", "events": ["push"] } -
|---|
| 参数 | @@ -7652,7 +8929,7 @@ http://localhost:3000/api/yystopf/ceshi/webhooks/7.jsonwebhook id |
|---|
@@ -7673,9 +8950,9 @@ http://localhost:3000/api/yystopf/ceshi/webhooks/7.json返回的JSON示例:
curl -X GET \
http://localhost:3000/api/yystopf/ceshi/webhooks/3/tasks.json
await octokit.request('GET /api/yystopf/ceshi/webhooks/3/tasks.json')
-GET /api/:owner/:repo/webhooks/:id/tasks.json
| 参数 | @@ -7707,7 +8984,7 @@ http://localhost:3000/api/yystopf/ceshi/webhooks/3/tasks.jsonwebhook ID |
|---|
| 参数 | @@ -7944,9 +9221,9 @@ http://localhost:3000/api/yystopf/ceshi/webhooks/3/tasks.json
|---|
| 参数 | @@ -7978,7 +9255,7 @@ http://localhost:3000/api/yystopf/ceshi/webhooks/3/test.jsonwebhook ID |
|---|
@@ -7990,7 +9267,949 @@ http://localhost:3000/api/yystopf/ceshi/webhooks/3/test.json -返回的JSON示例:
获取合并请求详情接口
+ +++示例:
+
curl -X GET http://localhost:3000/api/Jasder/gitlink/pulls/88.json
+await octokit.request('GET /api/Jasder/gitlink/pulls/88.json')
+GET /api/:owner/:repo/pulls/:id.json
| 参数 | +必选 | +默认 | +类型 | +字段说明 | +
|---|---|---|---|---|
| owner | +是 | ++ | string | +用户登录名 | +
| repo | +是 | ++ | string | +项目标识identifier | +
| id | +是 | ++ | integer | +pull id值 | +
++返回的JSON示例:
+
{
+ "status": 0,
+ "message": "响应成功",
+ "project_name": "Gitlink",
+ "identifier": "forgeplus",
+ "project_identifier": "forgeplus",
+ "pr_time": "52分钟前",
+ "commits_count": 229,
+ "files_count": 328,
+ "comments_count": 0,
+ "comments_total_count": 0,
+ "pull_request": {
+ "id": 1189,
+ "base": "master",
+ "head": "develop",
+ "status": 0,
+ "fork_project_id": null,
+ "is_original": false,
+ "pull_request_staus": "open",
+ "fork_project_user": null,
+ "create_user": "jasder",
+ "mergeable": true,
+ "state": "open"
+ },
+ "issue": {
+ "id": 51888,
+ "subject": "FIx release v3.2.0",
+ "description": null,
+ "is_private": false,
+ "branch_name": null,
+ "project_author_name": "Gitlink",
+ "closed_on": "",
+ "created_at": "2021-10-12 15:51",
+ "assign_user_name": "victor",
+ "assign_user_login": "moshenglv",
+ "author_name": "段甲生",
+ "author_login": "jasder",
+ "author_picture": "images/avatars/User/36480?t=1615520120",
+ "issue_status": "新增",
+ "priority": "正常",
+ "version": null,
+ "issue_tags": null
+ },
+ "conflict_files": []
+}
+获取pull request文件列表
+ +++示例:
+
curl -X GET \
+http://localhost:3000/api/Jason/gitlink/pulls/1/files.json
+await octokit.request('GET /api/jasder/gitlink/pulls/1/files.json')
+GET /api/:owner/:repo/pulls/:id/files.json
| 参数名 | +必选 | +类型 | +说明 | +
|---|---|---|---|
| owner | +是 | +string | +用户登录名 | +
| repo | +是 | +string | +project's identifier | +
| id | +是 | +int | +pull request's id | +
| 参数 | +类型 | +字段说明 | +
|---|---|---|
| - | +- | +- | +
| files_count | +int | +文件更改的总数量 | +
| total_addition | +int | +添加代码总行数 | +
| total_deletion | +int | +删除代码总行数 | +
| files | +array | ++ |
| -- sha | +string | +commit's sha value | +
| -- name | +string | +当前文件名 | +
| -- old_name | +string | +修改之前的文件名称,与name相同的话,说明文件名未更改 | +
| -- addition | +int | +文件添加的行数 | +
| -- deletion | +int | +文件删除的行数 | +
| -- type | +int | +文件类型, 1: 表示该文件只添加了内容,2: 表示该文件内容有修改, 3: 表示文件被删除或者改文件只删除了内容 | +
| -- isCreated | +boolean | +当前文件是否为新增文件, true: 是, false: 否 | +
| -- isDeleted | +boolean | +当前文件是否被删除, true: 是,false: 否 | +
| -- isBin | +boolean | +当前文件是否为二进制文件,true: 是,false: 否 | +
| -- isLFSFile | +boolean | +当前文件是否为LFS文件,true: 是,false: 否 | +
| -- isRenamed | +boolean | +当前文件是否被重命名,true: 是,false: 否 | +
| -- sections | +array | ++ |
| ---- fileName | +string | +文件名称 | +
| ---- lines | +array | ++ |
| ------ leftIdx | +string | +文件变动之前所在行数 | +
| ------ rightIdx | +string | +文件更改后所在行数 | +
| ------ type | +string | +文件变更类型,1: 新增,2: 修改, 3: 删除, 4: diff统计信息 | +
| ------ content | +string | +文件变更的内容 | +
| ------ sectionInfo | +object | ++ |
| -------- path | +string | +文件相对仓库的路径 | +
| -------- lastLeftIdx | +int | ++ |
| -------- lastRightIdx | +int | ++ |
| -------- leftHunkSize | +int | +文件变更之前的行数 | +
| -------- rightHunkSize | +int | +文件变更之后的行数(及当前页面编辑器显示的总行数) | +
| -------- leftIdx | +int | +文件变更之前所在行数 | +
| -------- rightIdx | +int | +文件变更之后所在行数(即:页面编辑器开始显示的行数) | +
++返回的JSON示例:
+
{
+ "files_count": 6,
+ "total_addition": 447,
+ "total_deletion": 0,
+ "files": [
+ {
+ "sha": "xefenisnii",
+ "name": "文件.txt",
+ "old_name": "文件.txt",
+ "index": 6,
+ "addition": 2,
+ "deletion": 0,
+ "type": 1,
+ "isCreated": true,
+ "isDeleted": false,
+ "isBin": false,
+ "isLFSFile": false,
+ "isRenamed": false,
+ "isSubmodule": false,
+ "sections": [
+ {
+ "fileName": "文件.txt",
+ "name": "",
+ "lines": [
+ {
+ "leftIdx": 0,
+ "rightIdx": 0,
+ "type": 4,
+ "content": "@@ -0,0 +1,2 @@",
+ "sectionInfo": {
+ "path": null,
+ "lastLeftIdx": null,
+ "lastRightIdx": null,
+ "leftIdx": 0,
+ "rightIdx": 0,
+ "leftHunkSize": null,
+ "rightHunkSize": null
+ }
+ },
+ {
+ "leftIdx": 0,
+ "rightIdx": 1,
+ "type": 2,
+ "content": "+用例图一致性更新",
+ "sectionInfo": null
+ },
+ {
+ "leftIdx": 0,
+ "rightIdx": 2,
+ "type": 2,
+ "content": "+工程文件直接上传会有文件缺失,现在压缩后上传",
+ "sectionInfo": null
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
+获取pull request的commits列表
+ +++示例:
+
curl -X GET http://localhost:3000/api/jasder/jasder_test/pulls/1/commits.json
+await octokit.request('GET /api/jasder/jasder_test/pulls/1/commits.json')
+GET /api/:owner/:repo/pulls/:id/commits.json
| 参数名 | +必选 | +类型 | +说明 | +
|---|---|---|---|
| owner | +是 | +string | +用户登录名 | +
| repo | +是 | +string | +project's identifier | +
| id | +是 | +int | +pull request's id | +
| 参数 | +类型 | +字段说明 | +
|---|---|---|
| commits_count | +int | +commits总数量 | +
| commits | +array | ++ |
| -- author | +object | +项目作者 | +
| ---- login | +string | +用户login | +
| ---- name | +string | +用户姓名 | +
| ---- image_url | +string | +用户头像 | +
| -- committer | +object | +commit提交用户 | +
| ---- login | +string | +用户login | +
| ---- name | +string | +用户姓名 | +
| ---- image_url | +string | +用户头像 | +
| -- timestamp | +int | +commit的unix时间戳 | +
| -- time_from_now | +string | +commit’s 提交时间距当前时间的时间值 | +
| -- message | +string | +commit说明信息 | +
| -- sha | +string | +commit’s sha值 | +
++返回的JSON示例:
+
{
+ "commits_count": 1,
+ "commits": [
+ {
+ "author": {
+ "id": 36480,
+ "login": "jasder",
+ "name": "段甲生",
+ "image_url": "avatars/User/b"
+ },
+ "committer": {
+ "id": 36480,
+ "login": "jasder",
+ "name": "段甲生",
+ "image_url": "avatars/User/b"
+ },
+ "timestamp": 1604382982,
+ "time_from_now": "3小时前",
+ "message": "add some file\n* Add the tag list page to the release page\n* Apply suggestions from code review\n* Add the tags list view\n* Add the delete tag way on ui\n* Not delete tag and clear message when delete a release\n",
+ "sha": "8f5faee0d3b3be1b8063e84da0c79dd75327b968"
+ }
+ ]
+}
+Compare two commits
+ +++示例:
+
curl -X GET \
+http://localhost:3000/api/Jason/test-txt/compare/master...develop
+
+curl -X GET \
+http://localhost:3000/api/Jason/test-txt/compare/master...Jason/test-txt:develop
+await octokit.request('GET /api/Jason/test-txt/compare/master...Jason/test-txt:develop')
+GET /api/:owner/:repo/compare/{base}...{head}.json
| 参数名 | +必选 | +类型 | +说明 | +
|---|---|---|---|
| owner | +是 | +string | +用户登录名 | +
| repo | +是 | +string | +project's identifier | +
| base | +是 | +string | +pull request's id | +
| head | +是 | +string | +pull request's id | +
| 参数 | +类型 | +字段说明 | +
|---|---|---|
| - | +- | +- | +
| commits_count | +int | +commits总数量 | +
| commits | +array | ++ |
| -- author | +object | +项目作者 | +
| ---- login | +string | +用户login | +
| ---- name | +string | +用户姓名 | +
| ---- image_url | +string | +用户头像 | +
| -- committer | +object | +commit提交用户 | +
| ---- login | +string | +用户login | +
| ---- name | +string | +用户姓名 | +
| ---- image_url | +string | +用户头像 | +
| -- timestamp | +int | +commit的unix时间戳 | +
| -- time_from_now | +string | +commit’s 提交时间距当前时间的时间值 | +
| -- message | +string | +commit说明信息 | +
| -- sha | +string | +commit’s sha值 | +
| diff | +object | ++ |
| -- files_count | +int | +文件更改的总数量 | +
| -- total_addition | +int | +添加代码总行数 | +
| -- total_deletion | +int | +删除代码总行数 | +
| -- files | +Array | ++ |
| -- sha | +string | +commit's sha | +
| -- name | +string | +当前文件名 | +
| -- old_name | +string | +修改之前的文件名称,与name相同的话,说明文件名未更改 | +
| -- addition | +int | +文件添加的行数 | +
| -- deletion | +int | +文件删除的行数 | +
| -- type | +int | +文件类型, 1: 表示该文件只添加了内容,2: 表示该文件内容有修改, 3: 表示文件被删除或者改文件只删除了内容 | +
| -- isCreated | +boolean | +当前文件是否为新增文件, true: 是, false: 否 | +
| -- isDeleted | +boolean | +当前文件是否被删除, true: 是,false: 否 | +
| -- isBin | +boolean | +当前文件是否为二进制文件,true: 是,false: 否 | +
| -- isLFSFile | +boolean | +当前文件是否为LFS文件,true: 是,false: 否 | +
| -- isRenamed | +boolean | +当前文件是否被重命名,true: 是,false: 否 | +
| -- sections | +array | ++ |
| ---- fileName | +string | +文件名称 | +
| ---- lines | +array | ++ |
| ------ leftIdx | +string | +文件变动之前所在行数 | +
| ------ rightIdx | +string | +文件更改后所在行数 | +
| ------ type | +string | +文件变更类型,1: 内容未改动,2: 添加, 3: 删除, 4: diff统计信息 | +
| ------ content | +string | +文件变更的内容 | +
| ------ sectionInfo | +object | ++ |
| -------- path | +string | +文件相对仓库的路径 | +
| -------- lastLeftIdx | +int | ++ |
| -------- lastRightIdx | +int | ++ |
| -------- leftHunkSize | +int | +文件变更之前的行数 | +
| -------- rightHunkSize | +int | +文件变更之后的行数(及当前页面编辑器显示的总行数) | +
| -------- leftIdx | +int | +文件变更之前所在行数 | +
| -------- rightIdx | +int | +文件变更之后所在行数 | +
++返回的JSON示例:
+
{
+ "commits_count": 1,
+ "commits": [
+ {
+ "author": {
+ "id": 36480,
+ "login": "jasder",
+ "name": "段甲生",
+ "image_url": "avatars/User/b"
+ },
+ "committer": {
+ "id": 36480,
+ "login": "jasder",
+ "name": "段甲生",
+ "image_url": "avatars/User/b"
+ },
+ "timestamp": 1604382982,
+ "time_from_now": "4小时前",
+ "message": "add some file\n* Add the tag list page to the release page\n* Apply suggestions from code review\n* Add the tags list view\n* Add the delete tag way on ui\n* Not delete tag and clear message when delete a release\n",
+ "sha": "8f5faee0d3b3be1b8063e84da0c79dd75327b968"
+ }
+ ],
+ "diff": {
+ "files_count": 6,
+ "total_addition": 447,
+ "total_deletion": 0,
+ "files": [
+ {
+ "name": "build.go",
+ "old_name": "build.go",
+ "index": 1,
+ "addition": 33,
+ "deletion": 0,
+ "type": 1,
+ "isCreated": true,
+ "isDeleted": false,
+ "isBin": false,
+ "isLFSFile": false,
+ "isRenamed": false,
+ "isSubmodule": false,
+ "sections": [
+ {
+ "fileName": "build.go",
+ "name": "",
+ "lines": [
+ {
+ "leftIdx": 0,
+ "rightIdx": 0,
+ "type": 4,
+ "content": "@@ -0,0 +1,33 @@",
+ "sectionInfo": {
+ "path": "build.go",
+ "lastLeftIdx": 0,
+ "lastRightIdx": 0,
+ "leftIdx": 0,
+ "rightIdx": 1,
+ "leftHunkSize": 0,
+ "rightHunkSize": 33
+ }
+ },
+ {
+ "leftIdx": 0,
+ "rightIdx": 1,
+ "type": 2,
+ "content": "+// Copyright 2020 The Gitea Authors. All rights reserved.",
+ "sectionInfo": null
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+获取合并请求列表
+ +++示例:
+
curl -X GET http://localhost:3000/api/Jasder/gitlink/pulls.json
+await octokit.request('GET /api/Jasder/gitlink/pulls.json')
+GET /api/:owner/:repo/pulls.json
| 参数 | +必选 | +默认 | +类型 | +字段说明 | +
|---|---|---|---|---|
| owner | +是 | ++ | string | +用户登录名 | +
| repo | +是 | ++ | string | +项目标识identifier | +
++返回的JSON示例:
+
{
+ "status": 0,
+ "message": "响应成功",
+ "open_count": 4,
+ "close_count": 51,
+ "merged_issues_size": 123,
+ "search_count": 4,
+ "limit": null,
+ "user_admin_or_member": true,
+ "user_admin_or_developer": true,
+ "project_name": "Gitlink",
+ "project_author_name": "Gitlink",
+ "issues": [
+ {
+ "pull_request_id": 1189,
+ "pull_request_status": 0,
+ "pull_request_head": "develop",
+ "pull_request_base": "master",
+ "pull_request_staus": "open",
+ "is_original": false,
+ "fork_project_id": null,
+ "fork_project_identifier": null,
+ "fork_project_user": null,
+ "id": 51888,
+ "name": "FIx release v3.2.0",
+ "pr_time": "59分钟前",
+ "assign_user_name": "victor",
+ "assign_user_login": "moshenglv",
+ "author_name": "段甲生",
+ "author_login": "jasder",
+ "avatar_url": "images/avatars/User/36480?t=1615520120",
+ "priority": "正常",
+ "version": null,
+ "journals_count": 0,
+ "issue_tags": null
+ }
+ ]
+}
+
+ {receiver},您好!
+ {nickname1}在 {nickname2}/{repository} 指派给你一个易修:{title}
+
+
+ 扫一扫,关注trustie微信公众号,更方便获取平台动态,消息推送等提醒
+ 想了解更多信息,请访问 www.trustie.net
+
如果您在使用中有任何的疑问和建议,欢迎您给我们反馈意见
+ QQ群:1071514693
Trustie团队
+ +
+ {receiver},您好!
+ 在项目 {nickname2}/{repository} 的易修 {title} 中:
+ {ifassigner}{nickname1}将负责人从 {assigner1} 修改为 {assigner2}{endassigner}
+ {ifstatus}{nickname1}将状态从 {status1} 修改为 {status2}{endstatus}
+ {iftracker}{nickname1}将类型从 {tracker1} 修改为 {tracker2}{endtracker}
+ {ifpriority}{nickname1}将优先级从 {priority1} 修改为 {priority2}{endpriority}
+ {ifmilestone}{nickname1}将里程碑从 {milestone1} 修改为 {milestone2}{endmilestone}
+ {iftag}{nickname1}将标记从 {tag1} 修改为 {tag2}{endtag}
+ {ifdoneratio}{nickname1}将完成度从 {doneratio1} 修改为 {doneratio2}{enddoneratio}
+ {ifbranch}{nickname1}将指定分支从 {branch1} 修改为 {branch2}{endbranch}
+ {ifstartdate}{nickname1}将开始日期从 {startdate1} 修改为 {startdate2}{endstartdate}
+ {ifduedate}{nickname1}将结束日期从 {duedate1} 修改为 {duedate2}{endduedate}
+
+
+ 扫一扫,关注trustie微信公众号,更方便获取平台动态,消息推送等提醒
+ 想了解更多信息,请访问 www.trustie.net
+
如果您在使用中有任何的疑问和建议,欢迎您给我们反馈意见
+ QQ群:1071514693
Trustie团队
+ +
+ {receiver},您好!
+ {nickname}已将易修 {title} 删除
+
+
+ 扫一扫,关注trustie微信公众号,更方便获取平台动态,消息推送等提醒
+ 想了解更多信息,请访问 www.trustie.net
+
如果您在使用中有任何的疑问和建议,欢迎您给我们反馈意见
+ QQ群:1071514693
Trustie团队
+ +
+ {receiver},您好!
+ 你已加入 {organization} 组织
+
+
+ 扫一扫,关注trustie微信公众号,更方便获取平台动态,消息推送等提醒
+ 想了解更多信息,请访问 www.trustie.net
+
如果您在使用中有任何的疑问和建议,欢迎您给我们反馈意见
+ QQ群:1071514693
Trustie团队
+ +
+ {receiver},您好!
+ 你已被移出 {organization} 组织
+
+
+ 扫一扫,关注trustie微信公众号,更方便获取平台动态,消息推送等提醒
+ 想了解更多信息,请访问 www.trustie.net
+
如果您在使用中有任何的疑问和建议,欢迎您给我们反馈意见
+ QQ群:1071514693
Trustie团队
+ +
+ {receiver},您好!
+ 组织 {organization} 已把你的角色修改为 {role}
+
+
+ 扫一扫,关注trustie微信公众号,更方便获取平台动态,消息推送等提醒
+ 想了解更多信息,请访问 www.trustie.net
+
如果您在使用中有任何的疑问和建议,欢迎您给我们反馈意见
+ QQ群:1071514693
Trustie团队
+ +
+ {receiver},您好!
+ {nickname1}在 {nickname2}/{repository} 新建了一个易修:{title}
+
+
+ 扫一扫,关注trustie微信公众号,更方便获取平台动态,消息推送等提醒
+ 想了解更多信息,请访问 www.trustie.net
+
如果您在使用中有任何的疑问和建议,欢迎您给我们反馈意见
+ QQ群:1071514693
Trustie团队
+ +
+ {receiver},您好!
+ 你已加入 {nickname}/{repository} 项目
+
+
+ 扫一扫,关注trustie微信公众号,更方便获取平台动态,消息推送等提醒
+ 想了解更多信息,请访问 www.trustie.net
+
如果您在使用中有任何的疑问和建议,欢迎您给我们反馈意见
+ QQ群:1071514693
Trustie团队
+ +
+ {receiver},您好!
+ 你已被移出 {nickname}/{repository} 项目
+
+
+ 扫一扫,关注trustie微信公众号,更方便获取平台动态,消息推送等提醒
+ 想了解更多信息,请访问 www.trustie.net
+
如果您在使用中有任何的疑问和建议,欢迎您给我们反馈意见
+ QQ群:1071514693
Trustie团队
+ +
+ {receiver},您好!
+ {nickname1} 已加入项目 {nickname2}/{repository}
+
+
+ 扫一扫,关注trustie微信公众号,更方便获取平台动态,消息推送等提醒
+ 想了解更多信息,请访问 www.trustie.net
+
如果您在使用中有任何的疑问和建议,欢迎您给我们反馈意见
+ QQ群:1071514693
Trustie团队
+ +
+ {receiver},您好!
+ {nickname1} 已被移出项目 {nickname2}/{repository}
+
+
+ 扫一扫,关注trustie微信公众号,更方便获取平台动态,消息推送等提醒
+ 想了解更多信息,请访问 www.trustie.net
+
如果您在使用中有任何的疑问和建议,欢迎您给我们反馈意见
+ QQ群:1071514693
Trustie团队
+ +
+ {receiver},您好!
+ {nickname1}在 {nickname2}/{repository} 提交了一个合并请求:{title}
+
+
+ 扫一扫,关注trustie微信公众号,更方便获取平台动态,消息推送等提醒
+ 想了解更多信息,请访问 www.trustie.net
+
如果您在使用中有任何的疑问和建议,欢迎您给我们反馈意见
+ QQ群:1071514693
Trustie团队
+ +
+ {receiver},您好!
+ 项目 {nickname}/{repository} 已把你的角色修改为 {role}
+
+
+ 扫一扫,关注trustie微信公众号,更方便获取平台动态,消息推送等提醒
+ 想了解更多信息,请访问 www.trustie.net
+
如果您在使用中有任何的疑问和建议,欢迎您给我们反馈意见
+ QQ群:1071514693
Trustie团队
+ +
+ {receiver},您好!
+ {nickname1} 更改 {nickname2}/{repository} 的仓库设置:
+ {ifname}更改项目名称为"{name}"{endname}
+ {ifidentifier}更改项目标识为"{identifier}"{endidentifier}
+ {ifdescription}更改项目简介为"{description}"{enddescription}
+ {ifcategory}更改项目类别为"{category}"{endcategory}
+ {iflanguage}更改项目语言为"{language}"{endlanguage}
+ {ifpermission}将仓库设为"{permission}"{endpermission}
+ {ifnavbar}将项目导航更改为"{navbar}"{endnavbar}
+
+
+ 扫一扫,关注trustie微信公众号,更方便获取平台动态,消息推送等提醒
+ 想了解更多信息,请访问 www.trustie.net
+
如果您在使用中有任何的疑问和建议,欢迎您给我们反馈意见
+ QQ群:1071514693
Trustie团队
+ +
+ {receiver},您好!
+ {nickname1}在 {nickname2}/{repository} 指派给你一个合并请求:{title}
+
+
+ 扫一扫,关注trustie微信公众号,更方便获取平台动态,消息推送等提醒
+ 想了解更多信息,请访问 www.trustie.net
+
如果您在使用中有任何的疑问和建议,欢迎您给我们反馈意见
+ QQ群:1071514693
Trustie团队
+ +
+ {receiver},您好!
+ 在项目 {nickname2}/{repository} 的合并请求 {title} 中:
+ {ifassigner}{nickname1}将负责人从 {assigner1} 修改为 {assigner2}{endassigner}
+ {ifmilestone}{nickname1}将里程碑从 {milestone1} 修改为 {milestone2}{endmilestone}
+ {iftag}{nickname1}将标记从 {tag1} 修改为 {tag2}{endtag}
+ {ifpriority}{nickname1}将优先级从 {priority1} 修改为 {priority2}{endpriority}
+
+
+ 扫一扫,关注trustie微信公众号,更方便获取平台动态,消息推送等提醒
+ 想了解更多信息,请访问 www.trustie.net
+
如果您在使用中有任何的疑问和建议,欢迎您给我们反馈意见
+ QQ群:1071514693
Trustie团队
+ +
+ {receiver},您好!
+ 你提交的合并请求:{title} 被拒绝;
+
+
+ 扫一扫,关注trustie微信公众号,更方便获取平台动态,消息推送等提醒
+ 想了解更多信息,请访问 www.trustie.net
+
如果您在使用中有任何的疑问和建议,欢迎您给我们反馈意见
+ QQ群:1071514693
Trustie团队
+ +
+ {receiver},您好!
+ 你提交的合并请求:{title} 已通过;
+
+
+ 扫一扫,关注trustie微信公众号,更方便获取平台动态,消息推送等提醒
+ 想了解更多信息,请访问 www.trustie.net
+
如果您在使用中有任何的疑问和建议,欢迎您给我们反馈意见
+ QQ群:1071514693
Trustie团队
+ +