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示例: 返回的JSON示例: 获取用户星标项目 示例: 返回的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,16 +1018,16 @@ Success — a happy kitten is an authenticated kitten!
-更改用户信息
-用户消息列表
+
-curl -X PATCH/PUT http://localhost:3000/api/users/yystopf.json
-await octokit.request('PATCH/PUT /api/users/:login.json')
+curl -X GET http://localhost:3000/api/users/:login/messages.json
+await octokit.request('GET /api/users/:login/messages.json')
HTTP 请求
-PATCH/PUT /api/users/:login.jsonGET api/users/yystopf/messages.json请求字段说明:
+
@@ -990,222 +1037,229 @@ Success — a happy kitten is an authenticated kitten!
-
user.nickname
+type
string
-用户昵称
+消息类型,不传为所有消息,notification为系统消息,atme为@我消息
-
user.image
-base64/file
-用户头像
+status
+integer
+是否已读,不传为所有消息,1为未读,2为已读
-
user.user_extension_attributes.gender
-int
-性别, 0男 1女
+limit
+integer
+每页个数
-
+user.user_extension_attributes.province
-string
-省份
+page
+integer
+页码
返回字段说明:
+
-
-
-
+
+user.user_extension_attributes.city
+参数
+类型
+字段说明
+
+
+total_count
+integer
+消息总数
+
+
type
string
-城市
+消息类型
-
+user.user_extension_attributes.description
+unread_notification
+integer
+未读系统通知数量
+
+
+unread_atme
+integer
+未读@我数量
+
+
+messages.id
+integer
+消息id
+
+
+messages.status
+integer
+消息是否已读,1为未读,2为已读
+
+
messages.content
string
-简介
+消息内容
-
user.user_extension_attributes.custom_department
+messages.notification_url
string
-单位名称
+消息跳转地址
-
user.user_extension_attributes.technical_title
+messages.source
string
-职业
+消息来源
-
user.user_extension_attributes.show_email
-bool
-是否展示邮箱
+messages.timeago
+string
+消息时间
-
user.user_extension_attributes.show_location
-bool
-是否展示位置
+messages.type
+string
+消息类型,notification为系统消息,atme为@我消息
-
user.user_extension_attributes.show_department
-bool
-是否展示公司
+sender
+object
+消息发送者
-
-{
- "user": {
- "nickname": "xxx",
- "user_extension_attributes": {
- "gender": 0,
- "province": "湖南",
- "city": "长沙",
- "description": "个性签名",
- "custom_department": "湖南智擎科技有限公司",
- }
- }
-}
-
-
-{
- "status": 0,
- "message": "success"
-}
-获取用户星标项目
-
-
-curl -X GET http://localhost:3000/api/users/yystopf/is_pinned_projects.json
-await octokit.request('GET /api/users/:login/is_pinned_projects.json')
-HTTP 请求
-GET api/users/:login/is_pinned_projects.json返回字段说明:
+消息来源source字段说明
@@ -1213,42 +1267,69 @@ Success — a happy kitten is an authenticated kitten!
-
参数
类型
-字段说明
+说明
-
total_count
-int
-星标项目数量
+IssueAssigned
+有新指派给我的易修
-
identifier
-string
-项目标识
+IssueAssignerExpire
+我负责的易修截止日期到达最后一天
-
name
-string
-项目名称
+IssueAtme
+在易修中@我
-
description
-string
-项目描述
+IssueChanged
+我创建或负责的易修状态变更
-
visits
-int
-项目访问数量
+IssueCreatorExpire
+我创建的易修截止日期到达最后一天
-
praises_count
-int
-项目点赞数量
+IssueDeleted
+我创建或负责的易修删除
-
watchers_count
-int
-项目关注数量
+IssueJournal
+我创建或负责的易修有新的评论
-
issues_count
-int
-项目issue数量
+LoginIpTip
+登录异常提示
-
pull_requests_count
-int
-项目合并请求数量
+OrganizationJoined
+账号被拉入组织
-
forked_count
-int
-项目复刻数量
+OrganizationLeft
+账号被移出组织
-
is_public
-bool
-项目是否公开
+OrganizationRole
+账号组织权限变更
-
mirror_url
-string
-镜像地址
+ProjectDeleted
+我关注的仓库被删除
-
type
-int
-项目类型 0 普通项目 1 普通镜像项目 2 同步镜像项目
+ProjectFollowed
+我管理的仓库被关注
-
time_ago
-string
-上次更新时间
+ProjectForked
+我管理的仓库被复刻
-
open_devops
-int
-是否开启devops
+ProjectIssue
+我管理/关注的仓库有新的易修
-
forked_from_project_id
-int
-fork项目id
+ProjectJoined
+账号被拉入项目
-
platform
-string
-项目平台
+ProjectLeft
+账号被移出项目
-
author.name
-string
-项目拥有者名称
+ProjectMemberJoined
+我管理的仓库有成员加入
-
author.type
-string
-项目拥有者类型
+ProjectMemberLeft
+我管理的仓库有成员移出
-
author.login
-string
-项目拥有者用户名
+ProjectMilestone
+我管理的仓库有新的里程碑
-
author.image_url
-string
-项目拥有者头像
+ProjectPraised
+我管理的仓库被点赞
-
category.name
-string
-项目分类名称
+ProjectPullRequest
+我管理/关注的仓库有新的合并请求
-
language.name
-string
-项目语言名称
+ProjectRole
+账号仓库权限变更
-
+position
-int
-项目排序
+ProjectSettingChanged
+我管理的仓库项目设置被更改
+
+
+ProjectTransfer
+我关注的仓库被转移
+
+
+ProjectVersion
+我关注的仓库有新的发行版
+
+
+PullRequestAssigned
+有新指派给我的合并请求
+
+
+PullReuqestAtme
+在合并请求中@我
+
+
+PullRequestChanged
+我创建或负责的合并请求状态变更
+
+
+PullRequestClosed
+我创建或负责的合并请求被关闭
+
+
+PullRequestJournal
+我创建或负责的合并请求有新的评论
+
+
PullRequestMerged
+我创建或负责的合并请求被合并
{
- "total_count": 1,
- "projects": [
+ "total_count": 5,
+ "type": "",
+ "unread_notification": 3,
+ "unread_atme": 2,
+ "messages": [
{
- "id": 89,
- "repo_id": 89,
- "identifier": "monkey",
- "name": "boke",
- "description": "dkkd",
- "visits": 4,
- "praises_count": 0,
- "watchers_count": 0,
- "issues_count": 0,
- "pull_requests_count": 0,
- "forked_count": 0,
- "is_public": true,
- "mirror_url": "https://github.com/viletyy/monkey.git",
- "type": 1,
- "last_update_time": 1619685144,
- "time_ago": "27天前",
- "forked_from_project_id": null,
- "open_devops": false,
- "platform": "forge",
- "author": {
- "name": "测试组织",
- "type": "Organization",
- "login": "ceshi_org",
- "image_url": "images/avatars/Organization/9?t=1612706073"
- },
- "category": {
- "id": 3,
- "name": "深度学习"
- },
- "language": {
- "id": 2,
- "name": "C"
+ "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"
}
]
}
@@ -1256,17 +1337,17 @@ Success — a happy kitten is an authenticated kitten!
-用户添加星标项目
-发送消息
+
-curl -X POST http://localhost:3000/api/users/yystopf/is_pinned_projects/pin.json
-await octokit.request('GET /api/users/:login/is_pinned_projects/pin.json')
-HTTP 请求
-POST /api/users/:login/is_pinned_projects/pin.json请求字段说明:
同时设定多个星标项目
+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请求字段说明:
-
参数
@@ -1275,26 +1356,37 @@ Success — a happy kitten is an authenticated kitten!
-
+is_pinned_project_ids
+type
+string
+消息类型
+
+
-receivers_login
array
-设定为星标项目的id
+需要发送消息的用户名数组
只设定一个星标项目
-
+
-
-
参数
-类型
-字段说明
+atmeable_type
+string
+atme消息对象,是从哪里@我的,比如评论:Journal、易修:Issue、合并请求:PullRequest
-
is_pinned_project_id
+atmeable_id
integer
-设定为星标项目的id
+atme消息对象id
+
+{
+ "type": "atme",
+ "receivers_login": ["yystopf", "testforge1"],
+ "atmeable_type": "Journal",
+ "atmeable_id": 67
+}
+
@@ -1302,16 +1394,20 @@ Success — a happy kitten is an authenticated kitten!
"status": 0,
"message": "success"
}
-星标项目展示排序
-阅读消息
+
-curl -X PATCH http://localhost:3000/api/users/yystopf/is_pinned_projects/11.json
-await octokit.request('PATCH/PUT /api/users/:login/is_pinned_projects/:id.json')
-HTTP 请求
-PATCH/PUT /api/users/:login/is_pinned_projects/:id.jsoncurl -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请求字段说明:
-
@@ -1321,21 +1417,17 @@ Success — a happy kitten is an authenticated kitten!
-
+pinned_projects.position
-int
-排序,数字越大排名越前
+type
+string
+消息类型,不传为所有消息,notification为系统消息,atme为@我消息
+
+
ids
+array
+消息id数组,包含-1则把所有未读消息标记为已读
-
-{
- "pinned_project": {
- "position": 1
- }
-}
-
@@ -1343,17 +1435,21 @@ Success — a happy kitten is an authenticated kitten!
"status": 0,
"message": "success"
}
-用户近期活动统计
-
用户近期活动统计, 默认显示近一周的数据
+ + +删除消息
-示例:
curl -X GET http://localhost:3000/api/users/yystopf/statistics/activity.json
-await octokit.request('GET /api/users/:login/statistics/activity.json')
-GET /api/users/:login/statistics/activity.json
curl -X DELETE http://localhost:3000/api/users/:login/messages.json
+await octokit.request('DELETE /api/users/:login/messages.json')
+DELETE api/users/yystopf/messages.json
| 参数 | @@ -1362,24 +1458,14 @@ Success — a happy kitten is an authenticated kitten!|||||
|---|---|---|---|---|---|
| dates | -array | -时间 | -|||
| issues_count | -array | -易修数量 | -|||
| pull_requests_count | -array | -合并请求数量 | +type | +string | +消息类型,atme为@我消息 |
| commtis_count | +ids | array | -贡献数量 | +消息id数组,包含-1则把所有消息删除 |
返回的JSON示例:
{
- "dates": [
- "2021.05.21",
- "2021.05.22",
- "2021.05.23",
- "2021.05.24",
- "2021.05.25",
- "2021.05.26",
- "2021.05.27",
- "2021.05.28"
- ],
- "issues_count": [
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0
- ],
- "pull_requests_count": [
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0
- ],
- "commits_count": [
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0
- ]
+ "status": 0,
+ "message": "success"
}
获取用户贡献度
+更改用户信息
-示例:
curl -X GET http://localhost:3000/api/users/yystopf/headmaps.json
-await octokit.request('GET /api/users/:login/headmaps.json')
-GET api/users/:login/headmaps.json
curl -X PATCH/PUT http://localhost:3000/api/users/yystopf.json
+await octokit.request('PATCH/PUT /api/users/:login.json')
+PATCH/PUT /api/users/:login.json
| 参数 | @@ -1451,125 +1499,221 @@ Success — a happy kitten is an authenticated kitten!||||
|---|---|---|---|---|
| year | +user.nickname | string | -年份 | +用户昵称 |
| 参数 | -类型 | -字段说明 | +user.image | +base64/file | +用户头像 |
|---|---|---|---|---|---|
| total_contributions | +user.user_extension_attributes.gender | int | -所选时间内的总贡献度 | +性别, 0男 1女 | |
| headmaps.date | +user.user_extension_attributes.province | string | -时间 | +省份 | |
| headmaps.contributions | -int | -贡献度 | +user.user_extension_attributes.city | +string | +城市 | +
| user.user_extension_attributes.description | +string | +简介 | +|||
| user.user_extension_attributes.custom_department | +string | +单位名称 | +|||
| user.user_extension_attributes.technical_title | +string | +职业 | +|||
| user.user_extension_attributes.show_email | +bool | +是否展示邮箱 | +|||
| user.user_extension_attributes.show_location | +bool | +是否展示位置 | +|||
| user.user_extension_attributes.show_department | +bool | +是否展示公司 |
++请求的JSON示例:
+
{
+ "user": {
+ "nickname": "xxx",
+ "user_extension_attributes": {
+ "gender": 0,
+ "province": "湖南",
+ "city": "长沙",
+ "description": "个性签名",
+ "custom_department": "湖南智擎科技有限公司",
+ }
+ }
+}
+返回的JSON示例:
{
- "total_contributions": 139,
- "headmaps": [
- {
- "date": "2021-02-07",
- "contributions": 1
- },
- {
- "date": "2021-02-21",
- "contributions": 13
- },
- {
- "date": "2021-02-25",
- "contributions": 5
- },
- {
- "date": "2021-03-01",
- "contributions": 2
- },
- {
- "date": "2021-03-04",
- "contributions": 1
- },
- {
- "date": "2021-03-15",
- "contributions": 9
- },
- {
- "date": "2021-03-22",
- "contributions": 14
- },
- {
- "date": "2021-03-24",
- "contributions": 1
- },
- {
- "date": "2021-03-30",
- "contributions": 11
- },
- {
- "date": "2021-04-06",
- "contributions": 1
- },
- {
- "date": "2021-04-12",
- "contributions": 1
- },
- {
- "date": "2021-04-13",
- "contributions": 2
- },
- {
- "date": "2021-04-19",
- "contributions": 3
- },
- {
- "date": "2021-04-23",
- "contributions": 37
- },
- {
- "date": "2021-04-25",
- "contributions": 2
- },
- {
- "date": "2021-04-26",
- "contributions": 6
- },
- {
- "date": "2021-04-28",
- "contributions": 1
- },
- {
- "date": "2021-04-29",
- "contributions": 18
- },
+ "status": 0,
+ "message": "success"
+}
+获取平台消息设置配置信息
+ +++示例:
+
curl -X GET http://localhost:3000/api/template_message_settings.json
+await octokit.request('GET /api/template_message_settings.json')
+GET /api/template_message_settings.json
| 参数 | +类型 | +字段说明 | +
|---|---|---|
| type | +string | +消息配置类型 | +
| type_name | +string | +消息配置类型含义 | +
| total_settings_count | +int | +配置条数 | +
| settings.name | +string | +配置名称 | +
| settings.key | +string | +配置标识 | +
| settings.notification_disabled | +boolean | +站内信设置是否禁用 | +
| settings.email_disabled | +boolean | +邮件设置是否禁用 | +
++返回的JSON示例:
+
{
+ "status": 0,
+ "message": "响应成功",
+ "setting_types": [
{
- "date": "2021-04-30",
- "contributions": 9
+ "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
+ }
+ ]
},
{
- "date": "2021-05-04",
- "contributions": 1
+ "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
+ }
+ ]
},
{
- "date": "2021-05-06",
- "contributions": 1
+ "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
+ }
+ ]
}
]
}
@@ -1577,17 +1721,17 @@ Success — a happy kitten is an authenticated kitten!
-获取用户动态
-获取用户动态
+获取用户消息设置配置信息
+获取用户消息设置配置信息
示例:
-curl -X GET http://localhost:3000/api/users/yystopf/project_trends.json
-
await octokit.request('GET /api/users/:login/project_trends.json')
+curl -X GET http://localhost:3000/api/users/yystopf/template_message_settings.json
+
await octokit.request('GET /api/uses/yystopf/template_message_settings.json')
HTTP 请求
-GET api/users/:login/project_trends.json
-请求字段说明:
+GET /api/users/:user_id/template_message_settings.json
+返回字段说明:
参数
@@ -1596,12 +1740,68 @@ Success — a happy kitten is an authenticated kitten!
-date
+notification_body
string
-日期,格式: 2021-05-28
+站内信配置
+
+
+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')
+
HTTP 请求
+POST /api/users/:user_id/template_message_settings/update_setting.json
+请求字段说明:
参数
@@ -1610,301 +1810,2400 @@ Success — a happy kitten is an authenticated kitten!
-total_count
-int
-所选时间内的总动态数
-
-
-project_trends.trend_type
+notification_body
string
-动态类型,Issue:易修,VersionRelease:版本发布,PullRequest:合并请求
+站内信配置
-project_trends.action_type
+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
+ }
+ }
+}
+
返回字段说明:
+
-project_trends.trend_id
-integer
-动态id
+参数
+类型
+字段说明
+
-project_trends.user_name
+notification_body
string
-用户名称
+站内信配置
-project_trends.user_login
+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 GET http://localhost:3000/api/users/yystopf/is_pinned_projects.json
+
await octokit.request('GET /api/users/:login/is_pinned_projects.json')
+
HTTP 请求
+GET api/users/:login/is_pinned_projects.json
+返回字段说明:
+
+
+参数
+类型
+字段说明
+
-project_trends.user_avatar
+total_count
+int
+星标项目数量
+
+
+identifier
string
-用户头像
+项目标识
-project_trends.action_time
+name
string
-操作时间
+项目名称
-project_trends.name
+description
string
-动态标题
+项目描述
-
-
-
-返回的JSON示例:
-
-{
- "total_count": 16,
- "project_trends": [
- {
- "id": 27,
- "trend_type": "Issue",
- "action_type": "创建了工单",
- "trend_id": 18,
- "user_name": "yystopf",
- "user_login": "yystopf",
- "user_avatar": "system/lets/letter_avatars/2/Y/241_125_89/120.png",
- "action_time": "21天前",
- "name": "31213123123",
- "issue_type": "1",
- "status_id": 2,
- "priority_id": 4,
- "created_at": "2021-05-07 15:39",
- "updated_at": "2021-05-27 15:42",
- "assign_user_name": "yystopf",
- "assign_user_login": "yystopf",
- "issue_journal_size": 1,
- "issue_journals": []
- },
- {
- "id": 8,
- "trend_type": "VersionRelease",
- "action_type": "创建了版本发布",
- "trend_id": 8,
- "user_name": "yystopf",
- "user_login": "yystopf",
- "user_avatar": "system/lets/letter_avatars/2/Y/241_125_89/120.png",
- "action_time": "24天前",
- "name": "heihei1",
- "tag_name": "v1.0",
- "target_commitish": "master",
- "tarball_url": "http://localhost:10080/forgeceshiorg1/ceshi1/archive/v1.0.tar.gz",
- "zipball_url": "http://localhost:10080/forgeceshiorg1/ceshi1/archive/v1.0.zip",
- "url": "http://localhost:10080/api/v1/repos/forgeceshiorg1/ceshi1/releases/84",
- "version_gid": "84",
- "created_at": "2021-05-04 12:04"
- },
- {
- "id": 25,
- "trend_type": "PullRequest",
- "action_type": "关闭了合并请求",
- "trend_id": 14,
- "user_name": "yystopf",
- "user_login": "yystopf",
- "user_avatar": "system/lets/letter_avatars/2/Y/241_125_89/120.png",
- "action_time": "28天前",
- "name": "13",
- "created_at": "2021-04-30 15:39"
- },
- {
- "id": 24,
- "trend_type": "PullRequest",
- "action_type": "创建了合并请求",
- "trend_id": 13,
- "user_name": "yystopf",
- "user_login": "yystopf",
- "user_avatar": "system/lets/letter_avatars/2/Y/241_125_89/120.png",
- "action_time": "28天前",
- "name": "211212",
- "created_at": "2021-04-30 15:37"
- },
- {
- "id": 23,
- "trend_type": "PullRequest",
- "action_type": "创建了合并请求",
- "trend_id": 12,
- "user_name": "yystopf",
- "user_login": "yystopf",
- "user_avatar": "system/lets/letter_avatars/2/Y/241_125_89/120.png",
- "action_time": "28天前",
- "name": "奇偶哦iu",
- "created_at": "2021-04-30 10:19"
- },
- {
- "id": 22,
- "trend_type": "PullRequest",
- "action_type": "创建了合并请求",
- "trend_id": 11,
- "user_name": "yystopf",
- "user_login": "yystopf",
- "user_avatar": "system/lets/letter_avatars/2/Y/241_125_89/120.png",
- "action_time": "28天前",
- "name": "2112123",
- "created_at": "2021-04-29 18:46"
- },
- {
- "id": 21,
- "trend_type": "PullRequest",
- "action_type": "关闭了合并请求",
- "trend_id": 10,
- "user_name": "yystopf",
- "user_login": "yystopf",
- "user_avatar": "system/lets/letter_avatars/2/Y/241_125_89/120.png",
- "action_time": "28天前",
- "name": "23123",
- "created_at": "2021-04-29 18:45"
- },
- {
- "id": 20,
- "trend_type": "PullRequest",
- "action_type": "创建了合并请求",
- "trend_id": 9,
- "user_name": "yystopf",
- "user_login": "yystopf",
- "user_avatar": "system/lets/letter_avatars/2/Y/241_125_89/120.png",
- "action_time": "28天前",
- "name": "33",
- "created_at": "2021-04-29 18:37"
- },
- {
- "id": 19,
- "trend_type": "PullRequest",
- "action_type": "关闭了合并请求",
- "trend_id": 8,
- "user_name": "yystopf",
- "user_login": "yystopf",
- "user_avatar": "system/lets/letter_avatars/2/Y/241_125_89/120.png",
- "action_time": "28天前",
- "name": "gggg",
- "created_at": "2021-04-29 17:51"
- },
+
+visits
+int
+项目访问数量
+
+
+praises_count
+int
+项目点赞数量
+
+
+watchers_count
+int
+项目关注数量
+
+
+issues_count
+int
+项目issue数量
+
+
+pull_requests_count
+int
+项目合并请求数量
+
+
+forked_count
+int
+项目复刻数量
+
+
+is_public
+bool
+项目是否公开
+
+
+mirror_url
+string
+镜像地址
+
+
+type
+int
+项目类型 0 普通项目 1 普通镜像项目 2 同步镜像项目
+
+
+time_ago
+string
+上次更新时间
+
+
+open_devops
+int
+是否开启devops
+
+
+forked_from_project_id
+int
+fork项目id
+
+
+platform
+string
+项目平台
+
+
+author.name
+string
+项目拥有者名称
+
+
+author.type
+string
+项目拥有者类型
+
+
+author.login
+string
+项目拥有者用户名
+
+
+author.image_url
+string
+项目拥有者头像
+
+
+category.name
+string
+项目分类名称
+
+
+language.name
+string
+项目语言名称
+
+
+position
+int
+项目排序
+
+
+
+
+返回的JSON示例:
+
+{
+ "total_count": 1,
+ "projects": [
{
- "id": 16,
- "trend_type": "Issue",
- "action_type": "创建了工单",
- "trend_id": 8,
- "user_name": "yystopf",
- "user_login": "yystopf",
- "user_avatar": "system/lets/letter_avatars/2/Y/241_125_89/120.png",
- "action_time": "1个月前",
- "name": "hjhkj",
- "issue_type": "1",
- "status_id": 1,
- "priority_id": 2,
- "created_at": "2021-04-19 10:52",
- "updated_at": "2021-04-19 10:52",
- "assign_user_name": null,
- "assign_user_login": null,
- "issue_journal_size": 0,
- "issue_journals": []
- },
+ "id": 89,
+ "repo_id": 89,
+ "identifier": "monkey",
+ "name": "boke",
+ "description": "dkkd",
+ "visits": 4,
+ "praises_count": 0,
+ "watchers_count": 0,
+ "issues_count": 0,
+ "pull_requests_count": 0,
+ "forked_count": 0,
+ "is_public": true,
+ "mirror_url": "https://github.com/viletyy/monkey.git",
+ "type": 1,
+ "last_update_time": 1619685144,
+ "time_ago": "27天前",
+ "forked_from_project_id": null,
+ "open_devops": false,
+ "platform": "forge",
+ "author": {
+ "name": "测试组织",
+ "type": "Organization",
+ "login": "ceshi_org",
+ "image_url": "images/avatars/Organization/9?t=1612706073"
+ },
+ "category": {
+ "id": 3,
+ "name": "深度学习"
+ },
+ "language": {
+ "id": 2,
+ "name": "C"
+ }
+ }
+ ]
+}
+
+
+用户添加星标项目
+用户添加星标项目
+
+
+示例:
+
+curl -X POST http://localhost:3000/api/users/yystopf/is_pinned_projects/pin.json
+
await octokit.request('GET /api/users/:login/is_pinned_projects/pin.json')
+
HTTP 请求
+POST /api/users/:login/is_pinned_projects/pin.json
+请求字段说明:
同时设定多个星标项目
+
+
+参数
+类型
+字段说明
+
+
+
+is_pinned_project_ids
+array
+设定为星标项目的id
+
+
+只设定一个星标项目
+
+
+参数
+类型
+字段说明
+
+
+
+is_pinned_project_id
+integer
+设定为星标项目的id
+
+
+
+
+返回的JSON示例:
+
+{
+ "status": 0,
+ "message": "success"
+}
+
星标项目展示排序
+星标项目展示排序
+
+
+示例:
+
+curl -X PATCH http://localhost:3000/api/users/yystopf/is_pinned_projects/11.json
+
await octokit.request('PATCH/PUT /api/users/:login/is_pinned_projects/:id.json')
+
HTTP 请求
+PATCH/PUT /api/users/:login/is_pinned_projects/:id.json
+请求字段说明:
+
+
+参数
+类型
+字段说明
+
+
+
+pinned_projects.position
+int
+排序,数字越大排名越前
+
+
+
+
+请求的JSON示例:
+
+{
+ "pinned_project": {
+ "position": 1
+ }
+}
+
+
+返回的JSON示例:
+
+{
+ "status": 0,
+ "message": "success"
+}
+
用户近期活动统计
+用户近期活动统计, 默认显示近一周的数据
+
+
+示例:
+
+curl -X GET http://localhost:3000/api/users/yystopf/statistics/activity.json
+
await octokit.request('GET /api/users/:login/statistics/activity.json')
+
HTTP 请求
+GET /api/users/:login/statistics/activity.json
+返回字段说明:
+
+
+参数
+类型
+字段说明
+
+
+
+dates
+array
+时间
+
+
+issues_count
+array
+易修数量
+
+
+pull_requests_count
+array
+合并请求数量
+
+
+commtis_count
+array
+贡献数量
+
+
+
+
+返回的JSON示例:
+
+{
+ "dates": [
+ "2021.05.21",
+ "2021.05.22",
+ "2021.05.23",
+ "2021.05.24",
+ "2021.05.25",
+ "2021.05.26",
+ "2021.05.27",
+ "2021.05.28"
+ ],
+ "issues_count": [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ "pull_requests_count": [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ "commits_count": [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ]
+}
+
+
+获取用户贡献度
+获取用户贡献度
+
+
+示例:
+
+curl -X GET http://localhost:3000/api/users/yystopf/headmaps.json
+
await octokit.request('GET /api/users/:login/headmaps.json')
+
HTTP 请求
+GET api/users/:login/headmaps.json
+请求字段说明:
+
+
+参数
+类型
+字段说明
+
+
+
+year
+string
+年份
+
+
+返回字段说明:
+
+
+参数
+类型
+字段说明
+
+
+
+total_contributions
+int
+所选时间内的总贡献度
+
+
+headmaps.date
+string
+时间
+
+
+headmaps.contributions
+int
+贡献度
+
+
+
+
+返回的JSON示例:
+
+{
+ "total_contributions": 139,
+ "headmaps": [
+ {
+ "date": "2021-02-07",
+ "contributions": 1
+ },
+ {
+ "date": "2021-02-21",
+ "contributions": 13
+ },
+ {
+ "date": "2021-02-25",
+ "contributions": 5
+ },
+ {
+ "date": "2021-03-01",
+ "contributions": 2
+ },
+ {
+ "date": "2021-03-04",
+ "contributions": 1
+ },
+ {
+ "date": "2021-03-15",
+ "contributions": 9
+ },
+ {
+ "date": "2021-03-22",
+ "contributions": 14
+ },
+ {
+ "date": "2021-03-24",
+ "contributions": 1
+ },
+ {
+ "date": "2021-03-30",
+ "contributions": 11
+ },
+ {
+ "date": "2021-04-06",
+ "contributions": 1
+ },
+ {
+ "date": "2021-04-12",
+ "contributions": 1
+ },
+ {
+ "date": "2021-04-13",
+ "contributions": 2
+ },
+ {
+ "date": "2021-04-19",
+ "contributions": 3
+ },
+ {
+ "date": "2021-04-23",
+ "contributions": 37
+ },
+ {
+ "date": "2021-04-25",
+ "contributions": 2
+ },
+ {
+ "date": "2021-04-26",
+ "contributions": 6
+ },
+ {
+ "date": "2021-04-28",
+ "contributions": 1
+ },
+ {
+ "date": "2021-04-29",
+ "contributions": 18
+ },
+ {
+ "date": "2021-04-30",
+ "contributions": 9
+ },
+ {
+ "date": "2021-05-04",
+ "contributions": 1
+ },
+ {
+ "date": "2021-05-06",
+ "contributions": 1
+ }
+ ]
+}
+
+
+获取用户动态
+获取用户动态
+
+
+示例:
+
+curl -X GET http://localhost:3000/api/users/yystopf/project_trends.json
+
await octokit.request('GET /api/users/:login/project_trends.json')
+
HTTP 请求
+GET api/users/:login/project_trends.json
+请求字段说明:
+
+
+参数
+类型
+字段说明
+
+
+
+date
+string
+日期,格式: 2021-05-28
+
+
+返回字段说明:
+
+
+参数
+类型
+字段说明
+
+
+
+total_count
+int
+所选时间内的总动态数
+
+
+project_trends.trend_type
+string
+动态类型,Issue:易修,VersionRelease:版本发布,PullRequest:合并请求
+
+
+project_trends.action_type
+string
+操作类型
+
+
+project_trends.trend_id
+integer
+动态id
+
+
+project_trends.user_name
+string
+用户名称
+
+
+project_trends.user_login
+string
+用户用户名
+
+
+project_trends.user_avatar
+string
+用户头像
+
+
+project_trends.action_time
+string
+操作时间
+
+
+project_trends.name
+string
+动态标题
+
+
+
+
+返回的JSON示例:
+
+{
+ "total_count": 16,
+ "project_trends": [
+ {
+ "id": 27,
+ "trend_type": "Issue",
+ "action_type": "创建了工单",
+ "trend_id": 18,
+ "user_name": "yystopf",
+ "user_login": "yystopf",
+ "user_avatar": "system/lets/letter_avatars/2/Y/241_125_89/120.png",
+ "action_time": "21天前",
+ "name": "31213123123",
+ "issue_type": "1",
+ "status_id": 2,
+ "priority_id": 4,
+ "created_at": "2021-05-07 15:39",
+ "updated_at": "2021-05-27 15:42",
+ "assign_user_name": "yystopf",
+ "assign_user_login": "yystopf",
+ "issue_journal_size": 1,
+ "issue_journals": []
+ },
+ {
+ "id": 8,
+ "trend_type": "VersionRelease",
+ "action_type": "创建了版本发布",
+ "trend_id": 8,
+ "user_name": "yystopf",
+ "user_login": "yystopf",
+ "user_avatar": "system/lets/letter_avatars/2/Y/241_125_89/120.png",
+ "action_time": "24天前",
+ "name": "heihei1",
+ "tag_name": "v1.0",
+ "target_commitish": "master",
+ "tarball_url": "http://localhost:10080/forgeceshiorg1/ceshi1/archive/v1.0.tar.gz",
+ "zipball_url": "http://localhost:10080/forgeceshiorg1/ceshi1/archive/v1.0.zip",
+ "url": "http://localhost:10080/api/v1/repos/forgeceshiorg1/ceshi1/releases/84",
+ "version_gid": "84",
+ "created_at": "2021-05-04 12:04"
+ },
+ {
+ "id": 25,
+ "trend_type": "PullRequest",
+ "action_type": "关闭了合并请求",
+ "trend_id": 14,
+ "user_name": "yystopf",
+ "user_login": "yystopf",
+ "user_avatar": "system/lets/letter_avatars/2/Y/241_125_89/120.png",
+ "action_time": "28天前",
+ "name": "13",
+ "created_at": "2021-04-30 15:39"
+ },
+ {
+ "id": 24,
+ "trend_type": "PullRequest",
+ "action_type": "创建了合并请求",
+ "trend_id": 13,
+ "user_name": "yystopf",
+ "user_login": "yystopf",
+ "user_avatar": "system/lets/letter_avatars/2/Y/241_125_89/120.png",
+ "action_time": "28天前",
+ "name": "211212",
+ "created_at": "2021-04-30 15:37"
+ },
+ {
+ "id": 23,
+ "trend_type": "PullRequest",
+ "action_type": "创建了合并请求",
+ "trend_id": 12,
+ "user_name": "yystopf",
+ "user_login": "yystopf",
+ "user_avatar": "system/lets/letter_avatars/2/Y/241_125_89/120.png",
+ "action_time": "28天前",
+ "name": "奇偶哦iu",
+ "created_at": "2021-04-30 10:19"
+ },
+ {
+ "id": 22,
+ "trend_type": "PullRequest",
+ "action_type": "创建了合并请求",
+ "trend_id": 11,
+ "user_name": "yystopf",
+ "user_login": "yystopf",
+ "user_avatar": "system/lets/letter_avatars/2/Y/241_125_89/120.png",
+ "action_time": "28天前",
+ "name": "2112123",
+ "created_at": "2021-04-29 18:46"
+ },
+ {
+ "id": 21,
+ "trend_type": "PullRequest",
+ "action_type": "关闭了合并请求",
+ "trend_id": 10,
+ "user_name": "yystopf",
+ "user_login": "yystopf",
+ "user_avatar": "system/lets/letter_avatars/2/Y/241_125_89/120.png",
+ "action_time": "28天前",
+ "name": "23123",
+ "created_at": "2021-04-29 18:45"
+ },
+ {
+ "id": 20,
+ "trend_type": "PullRequest",
+ "action_type": "创建了合并请求",
+ "trend_id": 9,
+ "user_name": "yystopf",
+ "user_login": "yystopf",
+ "user_avatar": "system/lets/letter_avatars/2/Y/241_125_89/120.png",
+ "action_time": "28天前",
+ "name": "33",
+ "created_at": "2021-04-29 18:37"
+ },
+ {
+ "id": 19,
+ "trend_type": "PullRequest",
+ "action_type": "关闭了合并请求",
+ "trend_id": 8,
+ "user_name": "yystopf",
+ "user_login": "yystopf",
+ "user_avatar": "system/lets/letter_avatars/2/Y/241_125_89/120.png",
+ "action_time": "28天前",
+ "name": "gggg",
+ "created_at": "2021-04-29 17:51"
+ },
+ {
+ "id": 16,
+ "trend_type": "Issue",
+ "action_type": "创建了工单",
+ "trend_id": 8,
+ "user_name": "yystopf",
+ "user_login": "yystopf",
+ "user_avatar": "system/lets/letter_avatars/2/Y/241_125_89/120.png",
+ "action_time": "1个月前",
+ "name": "hjhkj",
+ "issue_type": "1",
+ "status_id": 1,
+ "priority_id": 2,
+ "created_at": "2021-04-19 10:52",
+ "updated_at": "2021-04-19 10:52",
+ "assign_user_name": null,
+ "assign_user_login": null,
+ "issue_journal_size": 0,
+ "issue_journals": []
+ },
+ {
+ "id": 7,
+ "trend_type": "VersionRelease",
+ "action_type": "创建了版本发布",
+ "trend_id": 7,
+ "user_name": "yystopf",
+ "user_login": "yystopf",
+ "user_avatar": "system/lets/letter_avatars/2/Y/241_125_89/120.png",
+ "action_time": "1个月前",
+ "name": "v3.0.1",
+ "tag_name": "v3.0.1",
+ "target_commitish": "master",
+ "tarball_url": "http://localhost:10080/yystopf/ceshirepo1/archive/v3.0.1.tar.gz",
+ "zipball_url": "http://localhost:10080/yystopf/ceshirepo1/archive/v3.0.1.zip",
+ "url": "http://localhost:10080/api/v1/repos/yystopf/ceshirepo1/releases/78",
+ "version_gid": "78",
+ "created_at": "2021-03-30 15:51"
+ },
+ {
+ "id": 6,
+ "trend_type": "VersionRelease",
+ "action_type": "创建了版本发布",
+ "trend_id": 6,
+ "user_name": "yystopf",
+ "user_login": "yystopf",
+ "user_avatar": "system/lets/letter_avatars/2/Y/241_125_89/120.png",
+ "action_time": "1个月前",
+ "name": "v3.0.0",
+ "tag_name": "v3.0.0",
+ "target_commitish": "master",
+ "tarball_url": "http://localhost:10080/yystopf/ceshirepo1/archive/v3.0.0.tar.gz",
+ "zipball_url": "http://localhost:10080/yystopf/ceshirepo1/archive/v3.0.0.zip",
+ "url": "http://localhost:10080/api/v1/repos/yystopf/ceshirepo1/releases/77",
+ "version_gid": "77",
+ "created_at": "2021-03-30 15:33"
+ },
+ {
+ "id": 5,
+ "trend_type": "VersionRelease",
+ "action_type": "创建了版本发布",
+ "trend_id": 5,
+ "user_name": "yystopf",
+ "user_login": "yystopf",
+ "user_avatar": "system/lets/letter_avatars/2/Y/241_125_89/120.png",
+ "action_time": "1个月前",
+ "name": "v1.0.0",
+ "tag_name": "v1.0.0",
+ "target_commitish": "master",
+ "tarball_url": "http://localhost:10080/yystopf/ceshirepo1/archive/v1.0.0.tar.gz",
+ "zipball_url": "http://localhost:10080/yystopf/ceshirepo1/archive/v1.0.0.zip",
+ "url": "http://localhost:10080/api/v1/repos/yystopf/ceshirepo1/releases/76",
+ "version_gid": "76",
+ "created_at": "2021-03-30 15:27"
+ },
+ {
+ "id": 2,
+ "trend_type": "VersionRelease",
+ "action_type": "创建了版本发布",
+ "trend_id": 2,
+ "user_name": "yystopf",
+ "user_login": "yystopf",
+ "user_avatar": "system/lets/letter_avatars/2/Y/241_125_89/120.png",
+ "action_time": "2个月前",
+ "name": "vvvv",
+ "tag_name": "v1.1",
+ "target_commitish": "dev",
+ "tarball_url": "http://localhost:10080/yystopf/virus_blog/archive/v1.1.tar.gz",
+ "zipball_url": "http://localhost:10080/yystopf/virus_blog/archive/v1.1.zip",
+ "url": "http://localhost:10080/api/v1/repos/yystopf/virus_blog/releases/6",
+ "version_gid": "6",
+ "created_at": "2021-03-15 14:18"
+ },
+ {
+ "id": 2,
+ "trend_type": "PullRequest",
+ "action_type": "创建了合并请求",
+ "trend_id": 2,
+ "user_name": "yystopf",
+ "user_login": "yystopf",
+ "user_avatar": "system/lets/letter_avatars/2/Y/241_125_89/120.png",
+ "action_time": "3个月前",
+ "name": "444",
+ "created_at": "2021-02-25 17:31"
+ }
+ ]
+}
+
+
+用户开发能力
+用户开发能力, 默认为所有时间下的开发能力
+
+
+示例:
+
+curl -X GET http://localhost:3000/api/users/yystopf/statistics/develop.json
+
await octokit.request('GET /api/users/:login/statistics/develop.json')
+
HTTP 请求
+GET /api/users/:login/statistics/develop.json
+请求字段说明:
+
+
+参数
+类型
+字段说明
+
+
+
+start_time
+integer
+时间戳,开始时间,格式:1621526400
+
+
+end_time
+integer
+时间戳,结束时间,格式:1622131200
+
+
+返回字段说明:
+
+
+参数
+类型
+字段说明
+
+
+
+influence
+int
+影响力
+
+
+contribution
+int
+贡献度
+
+
+activity
+int
+活跃度
+
+
+experience
+int
+项目经验
+
+
+language
+int
+语言能力
+
+
+languages_percent
+float
+语言百分比
+
+
+each_language_score
+int
+各门语言分数
+
+
+
+
+返回的JSON示例:
+
+{
+ "platform": {
+ "influence": 61,
+ "contribution": 75,
+ "activity": 66,
+ "experience": 95,
+ "language": 87,
+ "languages_percent": {
+ "CSS": 0.03,
+ "C#": 0.13,
+ "Ruby": 0.04,
+ "Go": 0.05,
+ "C": 0.19,
+ "Java": 0.34,
+ "Python": 0.09,
+ "C+": 0.01,
+ "C++": 0.11,
+ "Scala": 0.01,
+ "HTML": 0.01
+ },
+ "each_language_score": {
+ "CSS": 71,
+ "C#": 86,
+ "Ruby": 75,
+ "Go": 77,
+ "C": 90,
+ "Java": 93,
+ "Python": 83,
+ "C+": 66,
+ "C++": 85,
+ "Scala": 66,
+ "HTML": 66
+ }
+ },
+ "user": {
+ "influence": 60,
+ "contribution": 72,
+ "activity": 65,
+ "experience": 88,
+ "language": 84,
+ "languages_percent": {
+ "C": 0.25,
+ "C#": 0.33,
+ "C++": 0.13,
+ "CSS": 0.08,
+ "Go": 0.04,
+ "HTML": 0.04,
+ "Java": 0.04,
+ "Ruby": 0.08
+ },
+ "each_language_score": {
+ "C": 81,
+ "C#": 84,
+ "C++": 75,
+ "CSS": 71,
+ "Go": 66,
+ "HTML": 66,
+ "Java": 66,
+ "Ruby": 71
+ }
+ }
+}
+
+
+用户角色定位
+用户角色定位,默认显示所有时间下的角色定位数据
+
+
+示例:
+
+curl -X GET http://localhost:3000/api/users/yystopf/statistics/role.json
+
await octokit.request('GET /api/users/:login/statistics/role.json')
+
HTTP 请求
+GET /api/users/:login/statistics/role.json
+请求字段说明:
+
+
+参数
+类型
+字段说明
+
+
+
+start_time
+integer
+时间戳,开始时间,格式:1621526400
+
+
+end_time
+integer
+时间戳,结束时间,格式:1622131200
+
+
+返回字段说明:
+
+
+参数
+类型
+字段说明
+
+
+
+total_projects_count
+int
+用户所有的项目数量
+
+
+role.object.count
+int
+用户该语言下的项目数量
+
+
+role.object.percent
+float
+用户该语言下的项目占比
+
+
+
+
+返回的JSON示例:
+
+{
+ "total_projects_count": 27,
+ "role": {
+ "owner": {
+ "count": 24,
+ "percent": 0.89
+ },
+ "manager": {
+ "count": 1,
+ "percent": 0.04
+ },
+ "developer": {
+ "count": 2,
+ "percent": 0.07
+ },
+ "reporter": {
+ "count": 0,
+ "percent": 0.0
+ }
+ }
+}
+
+
+用户专业定位
+用户专业定位,默认显示所有时间下的专业定位数据
+
+
+示例:
+
+curl -X GET http://localhost:3000/api/users/yystopf/statistics/major.json
+
await octokit.request('GET /api/users/:login/statistics/major.json')
+
HTTP 请求
+GET /api/users/:login/statistics/major.json
+请求字段说明:
+
+
+参数
+类型
+字段说明
+
+
+
+start_time
+integer
+时间戳,开始时间,格式:1621526400
+
+
+end_time
+integer
+时间戳,结束时间,格式:1622131200
+
+
+返回字段说明:
+
+
+参数
+类型
+字段说明
+
+
+
+categories
+int
+用户项目分类
+
+
+
+
+返回的JSON示例:
+
+{
+ "categories": [
+ "大数据",
+ "机器学习",
+ "深度学习",
+ "人工智能",
+ "智慧医疗",
+ "云计算"
+ ]
+}
+
+
+待办事项-用户通知信息
+待办事项-用户通知信息
+
+
+示例:
+
+curl -X GET http://localhost:3000/api/users/yystopf/applied_messages.json
+
await octokit.request('GET /api/users/:login/applied_messages.json')
+
HTTP 请求
+GET /api/users/:login/applied_messages.json
+请求字段说明:
+
+
+参数
+类型
+字段说明
+
+
+
+login
+string
+用户标识
+
+
+返回字段说明:
+
+
+参数
+类型
+字段说明
+
+
+
+applied
+object
+通知主体
+
+
+applied.id
+int
+通知主体的迁移id
+
+
+applied.status
+string
+通知主体的迁移状态,canceled:取消,common:正在迁移, accept:已接受,refuse:已拒绝
+
+
+applied.time_ago
+string
+通知主体的迁移创建的时间
+
+
+applied.project.id
+int
+通知主体的迁移项目的id
+
+
+applied.project.identifier
+string
+通知主体的迁移项目的标识
+
+
+applied.project.name
+string
+通知主体的迁移项目的名称
+
+
+applied.project.description
+string
+通知主体的迁移项目的描述
+
+
+applied.project.is_public
+bool
+通知主体的迁移项目是否公开
+
+
+applied.project.owner.id
+bool
+通知主体的迁移项目拥有者id
+
+
+applied.project.owner.type
+string
+通知主体的迁移项目拥有者类型
+
+
+applied.project.owner.name
+string
+通知主体的迁移项目拥有者昵称
+
+
+applied.project.owner.login
+string
+通知主体的迁移项目拥有者标识
+
+
+applied.project.owner.image_url
+string
+通知主体的迁移项目拥有者头像
+
+
+applied.user.id
+int
+通知主体的迁移创建者的id
+
+
+applied.user.type
+string
+通知主体的迁移创建者的类型
+
+
+applied.user.name
+string
+通知主体的迁移创建者的名称
+
+
+applied.user.login
+string
+通知主体的迁移创建者的标识
+
+
+applied.user.image_url
+string
+通知主体的迁移创建者头像
+
+
+applied_user.id
+int
+通知发起者的id
+
+
+applied_user.type
+string
+通知发起者的类型
+
+
+applied_user.name
+string
+通知发起者的名称
+
+
+applied_user.login
+string
+通知发起者的标识
+
+
+applied_user.image_url
+string
+通知发起者头像
+
+
+applied_type
+string
+通知类型
+
+
+name
+string
+通知内容
+
+
+viewed
+string
+是否已读,waiting:未读,viewed:已读
+
+
+status
+string
+通知状态, canceled:已取消,common: 正常,successed:成功,failure:失败
+
+
+time_ago
+string
+通知时间
+
+
+
+
+返回的JSON示例:
+
+{
+ "total_count": 5,
+ "applied_messages": [
+ {
+ "applied": {
+ "project": {
+ "id": 74,
+ "identifier": "hehuisssjssjjsjs",
+ "name": "hehuisssjssjjsjs",
+ "description": "wwww",
+ "is_public": false,
+ "owner": {
+ "id": 10,
+ "type": "User",
+ "name": "testforge1",
+ "login": "testforge1",
+ "image_url": "system/lets/letter_avatars/2/T/19_237_174/120.png"
+ }
+ },
+ "user": {
+ "id": 6,
+ "type": "User",
+ "name": "何慧",
+ "login": "yystopf",
+ "image_url": "images/avatars/User/6?t=1622513134"
+ },
+ "id": 6,
+ "status": "accepted",
+ "created_at": "2021-06-09 16:34",
+ "time_ago": "1分钟前"
+ },
+ "applied_user": {
+ "id": 6,
+ "type": "User",
+ "name": "何慧",
+ "login": "yystopf",
+ "image_url": "images/avatars/User/6?t=1622513134"
+ },
+ "applied_type": "AppliedProject",
+ "name": "已通过你加入【hehuisssjssjjsjs】仓库的申请。",
+ "viewed": "waiting",
+ "status": "successed",
+ "created_at": "2021-06-09 16:34",
+ "time_ago": "1分钟前"
+ },
+ {
+ "applied": {
+ "project": {
+ "id": 86,
+ "identifier": "ceshi_repo1",
+ "name": "测试项目啊1",
+ "description": "二十多",
+ "is_public": true,
+ "owner": {
+ "id": 52,
+ "type": "Organization",
+ "name": "身份卡手动阀",
+ "login": "ceshi1",
+ "image_url": "images/avatars/Organization/52?t=1618805056"
+ }
+ },
+ "user": {
+ "id": 6,
+ "type": "User",
+ "name": "yystopf",
+ "login": "yystopf",
+ "image_url": "system/lets/letter_avatars/2/Y/241_125_89/120.png"
+ },
+ "owner": {
+ "id": 9,
+ "type": "Organization",
+ "name": "测试组织",
+ "login": "ceshi_org",
+ "image_url": "images/avatars/Organization/9?t=1612706073"
+ },
+ "id": 4,
+ "status": "common",
+ "created_at": "2021-04-26 09:54",
+ "time_ago": "35分钟前"
+ },
+ "applied_user": {
+ "id": 6,
+ "type": "User",
+ "name": "yystopf",
+ "login": "yystopf",
+ "image_url": "system/lets/letter_avatars/2/Y/241_125_89/120.png"
+ },
+ "applied_type": "AppliedTransferProject",
+ "name": "正在将【测试项目啊1】仓库转移给【测试组织】",
+ "viewed": "viewed",
+ "status": "common",
+ "created_at": "2021-04-26 09:54",
+ "time_ago": "35分钟前"
+ },
+ ...
+ ]
+}
+
待办事项-接受仓库
+待办事项-接受仓库
+
+
+示例:
+
+curl -X GET http://localhost:3000/api/users/yystopf/applied_transfer_projects.json
+
await octokit.request('GET /api/users/:login/applied_transfer_projects.json')
+
HTTP 请求
+GET /api/users/:login/applied_transfer_projects.json
+请求字段说明:
+
+
+参数
+类型
+字段说明
+
+
+
+login
+string
+用户标识
+
+
+返回字段说明:
+
+
+参数
+类型
+字段说明
+
+
+
+id
+int
+迁移id
+
+
+status
+string
+迁移状态,canceled:取消,common:正在迁移, accept:已接受,refuse:已拒绝
+
+
+time_ago
+string
+迁移创建的时间
+
+
+project.id
+int
+迁移项目的id
+
+
+project.identifier
+string
+迁移项目的标识
+
+
+project.name
+string
+迁移项目的名称
+
+
+project.description
+string
+迁移项目的描述
+
+
+project.is_public
+bool
+迁移项目是否公开
+
+
+project.owner.id
+bool
+迁移项目拥有者id
+
+
+project.owner.type
+string
+迁移项目拥有者类型
+
+
+project.owner.name
+string
+迁移项目拥有者昵称
+
+
+project.owner.login
+string
+迁移项目拥有者标识
+
+
+project.owner.image_url
+string
+迁移项目拥有者头像
+
+
+user.id
+int
+迁移创建者的id
+
+
+user.type
+string
+迁移创建者的类型
+
+
+user.name
+string
+迁移创建者的名称
+
+
+user.login
+string
+迁移创建者的标识
+
+
+user.image_url
+string
+迁移创建者头像
+
+
+owner.id
+int
+迁移接受者的id
+
+
+owner.type
+string
+迁移接受者的类型
+
+
+owner.name
+string
+迁移接受者的名称
+
+
+owner.login
+string
+迁移接受者的标识
+
+
+owner.image_url
+string
+迁移接受者头像
+
+
+
+
+返回的JSON示例:
+
+{
+ "total_count": 4,
+ "applied_transfer_projects": [
+ {
+ "project": {
+ "id": 86,
+ "identifier": "ceshi_repo1",
+ "name": "测试项目啊1",
+ "description": "二十多",
+ "is_public": true,
+ "owner": {
+ "id": 52,
+ "type": "Organization",
+ "name": "身份卡手动阀",
+ "login": "ceshi1",
+ "image_url": "images/avatars/Organization/52?t=1618805056"
+ }
+ },
+ "user": {
+ "id": 6,
+ "type": "User",
+ "name": "yystopf",
+ "login": "yystopf",
+ "image_url": "system/lets/letter_avatars/2/Y/241_125_89/120.png"
+ },
+ "owner": {
+ "id": 52,
+ "type": "Organization",
+ "name": "身份卡手动阀",
+ "login": "ceshi1",
+ "image_url": "images/avatars/Organization/52?t=1618805056"
+ },
+ "id": 1,
+ "status": "canceled",
+ "created_at": "2021-04-25 18:06",
+ "time_ago": "16小时前"
+ },
+ ...
+ ]
+}
+
用户接受迁移
+用户接受迁移
+
+
+示例:
+
+curl -X POST http://localhost:3000/api/users/yystopf/applied_transfer_projects/2/accept.json
+
await octokit.request('GET /api/users/:login/applied_transfer_projects/:id/accept.json')
+
HTTP 请求
+GET /api/users/:login/applied_transfer_projects/:id/accept.json
+请求字段说明:
+
+
+参数
+类型
+字段说明
+
+
+
+login
+string
+用户标识
+
+
+id
+int
+迁移id
+
+
+返回字段说明:
+
+
+参数
+类型
+字段说明
+
+
+
+id
+int
+迁移id
+
+
+status
+string
+迁移状态,canceled:取消,common:正在迁移, accept:已接受,refuse:已拒绝
+
+
+time_ago
+string
+迁移创建的时间
+
+
+project.id
+int
+迁移项目的id
+
+
+project.identifier
+string
+迁移项目的标识
+
+
+project.name
+string
+迁移项目的名称
+
+
+project.description
+string
+迁移项目的描述
+
+
+project.is_public
+bool
+迁移项目是否公开
+
+
+project.owner.id
+bool
+迁移项目拥有者id
+
+
+project.owner.type
+string
+迁移项目拥有者类型
+
+
+project.owner.name
+string
+迁移项目拥有者昵称
+
+
+project.owner.login
+string
+迁移项目拥有者标识
+
+
+project.owner.image_url
+string
+迁移项目拥有者头像
+
+
+user.id
+int
+迁移创建者的id
+
+
+user.type
+string
+迁移创建者的类型
+
+
+user.name
+string
+迁移创建者的名称
+
+
+user.login
+string
+迁移创建者的标识
+
+
+user.image_url
+string
+迁移创建者头像
+
+
+owner.id
+int
+迁移接受者的id
+
+
+owner.type
+string
+迁移接受者的类型
+
+
+owner.name
+string
+迁移接受者的名称
+
+
+owner.login
+string
+迁移接受者的标识
+
+
+owner.image_url
+string
+迁移接受者头像
+
+
+
+
+返回的JSON示例:
+
+{
+ "project": {
+ "id": 86,
+ "identifier": "ceshi_repo1",
+ "name": "测试项目啊1",
+ "description": "二十多",
+ "is_public": true,
+ "owner": {
+ "id": 52,
+ "type": "Organization",
+ "name": "身份卡手动阀",
+ "login": "ceshi1",
+ "image_url": "images/avatars/Organization/52?t=1618805056"
+ }
+ },
+ "user": {
+ "id": 6,
+ "type": "User",
+ "name": "yystopf",
+ "login": "yystopf",
+ "image_url": "system/lets/letter_avatars/2/Y/241_125_89/120.png"
+ },
+ "owner": {
+ "id": 52,
+ "type": "Organization",
+ "name": "身份卡手动阀",
+ "login": "ceshi1",
+ "image_url": "images/avatars/Organization/52?t=1618805056"
+ },
+ "id": 1,
+ "status": "canceled",
+ "created_at": "2021-04-25 18:06",
+ "time_ago": "16小时前"
+}
+
用户拒绝迁移
+用户拒绝迁移
+
+
+示例:
+
+curl -X POST http://localhost:3000/api/users/yystopf/applied_transfer_projects/2/refuse.json
+
await octokit.request('GET /api/users/:login/applied_transfer_projects/:id/refuse.json')
+
HTTP 请求
+GET /api/users/:login/applied_transfer_projects/:id/refuse.json
+请求字段说明:
+
+
+参数
+类型
+字段说明
+
+
+
+login
+string
+用户标识
+
+
+id
+int
+迁移id
+
+
+返回字段说明:
+
+
+参数
+类型
+字段说明
+
+
+
+id
+int
+迁移id
+
+
+status
+string
+迁移状态,canceled:取消,common:正在迁移, accept:已接受,refuse:已拒绝
+
+
+time_ago
+string
+迁移创建的时间
+
+
+project.id
+int
+迁移项目的id
+
+
+project.identifier
+string
+迁移项目的标识
+
+
+project.name
+string
+迁移项目的名称
+
+
+project.description
+string
+迁移项目的描述
+
+
+project.is_public
+bool
+迁移项目是否公开
+
+
+project.owner.id
+bool
+迁移项目拥有者id
+
+
+project.owner.type
+string
+迁移项目拥有者类型
+
+
+project.owner.name
+string
+迁移项目拥有者昵称
+
+
+project.owner.login
+string
+迁移项目拥有者标识
+
+
+project.owner.image_url
+string
+迁移项目拥有者头像
+
+
+user.id
+int
+迁移创建者的id
+
+
+user.type
+string
+迁移创建者的类型
+
+
+user.name
+string
+迁移创建者的名称
+
+
+user.login
+string
+迁移创建者的标识
+
+
+user.image_url
+string
+迁移创建者头像
+
+
+owner.id
+int
+迁移接受者的id
+
+
+owner.type
+string
+迁移接受者的类型
+
+
+owner.name
+string
+迁移接受者的名称
+
+
+owner.login
+string
+迁移接受者的标识
+
+
+owner.image_url
+string
+迁移接受者头像
+
+
+
+
+返回的JSON示例:
+
+{
+ "project": {
+ "id": 86,
+ "identifier": "ceshi_repo1",
+ "name": "测试项目啊1",
+ "description": "二十多",
+ "is_public": true,
+ "owner": {
+ "id": 52,
+ "type": "Organization",
+ "name": "身份卡手动阀",
+ "login": "ceshi1",
+ "image_url": "images/avatars/Organization/52?t=1618805056"
+ }
+ },
+ "user": {
+ "id": 6,
+ "type": "User",
+ "name": "yystopf",
+ "login": "yystopf",
+ "image_url": "system/lets/letter_avatars/2/Y/241_125_89/120.png"
+ },
+ "owner": {
+ "id": 52,
+ "type": "Organization",
+ "name": "身份卡手动阀",
+ "login": "ceshi1",
+ "image_url": "images/avatars/Organization/52?t=1618805056"
+ },
+ "id": 1,
+ "status": "canceled",
+ "created_at": "2021-04-25 18:06",
+ "time_ago": "16小时前"
+}
+
待办事项-项目申请
+待办事项-项目申请
+
+
+示例:
+
+curl -X GET http://localhost:3000/api/users/yystopf/applied_projects.json
+
await octokit.request('GET /api/users/:login/applied_projects.json')
+
HTTP 请求
+GET /api/users/:login/applied_projects.json
+请求字段说明:
+
+
+参数
+类型
+字段说明
+
+
+
+login
+string
+用户标识
+
+
+返回字段说明:
+
+
+参数
+类型
+字段说明
+
+
+
+id
+int
+申请id
+
+
+status
+string
+申请状态,canceled:取消,common:正在申请, accept:已接受,refuse:已拒绝
+
+
+time_ago
+string
+申请创建的时间
+
+
+project.id
+int
+申请项目的id
+
+
+project.identifier
+string
+申请项目的标识
+
+
+project.name
+string
+申请项目的名称
+
+
+project.description
+string
+申请项目的描述
+
+
+project.is_public
+bool
+申请项目是否公开
+
+
+project.owner.id
+bool
+申请项目拥有者id
+
+
+project.owner.type
+string
+申请项目拥有者类型
+
+
+project.owner.name
+string
+申请项目拥有者昵称
+
+
+project.owner.login
+string
+申请项目拥有者标识
+
+
+project.owner.image_url
+string
+申请项目拥有者头像
+
+
+user.id
+int
+申请创建者的id
+
+
+user.type
+string
+申请创建者的类型
+
+
+user.name
+string
+申请创建者的名称
+
+
+user.login
+string
+申请创建者的标识
+
+
+user.image_url
+string
+申请创建者头像
+
+
+
+
+返回的JSON示例:
+
+{
+ "total_count": 4,
+ "applied_transfer_projects": [
{
+ "project": {
+ "id": 74,
+ "identifier": "hehuisssjssjjsjs",
+ "name": "hehuisssjssjjsjs",
+ "description": "wwww",
+ "is_public": false,
+ "owner": {
+ "id": 10,
+ "type": "User",
+ "name": "testforge1",
+ "login": "testforge1",
+ "image_url": "system/lets/letter_avatars/2/T/19_237_174/120.png"
+ }
+ },
+ "user": {
+ "id": 6,
+ "type": "User",
+ "name": "何慧",
+ "login": "yystopf",
+ "image_url": "images/avatars/User/6?t=1622513134"
+ },
"id": 7,
- "trend_type": "VersionRelease",
- "action_type": "创建了版本发布",
- "trend_id": 7,
- "user_name": "yystopf",
- "user_login": "yystopf",
- "user_avatar": "system/lets/letter_avatars/2/Y/241_125_89/120.png",
- "action_time": "1个月前",
- "name": "v3.0.1",
- "tag_name": "v3.0.1",
- "target_commitish": "master",
- "tarball_url": "http://localhost:10080/yystopf/ceshirepo1/archive/v3.0.1.tar.gz",
- "zipball_url": "http://localhost:10080/yystopf/ceshirepo1/archive/v3.0.1.zip",
- "url": "http://localhost:10080/api/v1/repos/yystopf/ceshirepo1/releases/78",
- "version_gid": "78",
- "created_at": "2021-03-30 15:51"
- },
- {
- "id": 6,
- "trend_type": "VersionRelease",
- "action_type": "创建了版本发布",
- "trend_id": 6,
- "user_name": "yystopf",
- "user_login": "yystopf",
- "user_avatar": "system/lets/letter_avatars/2/Y/241_125_89/120.png",
- "action_time": "1个月前",
- "name": "v3.0.0",
- "tag_name": "v3.0.0",
- "target_commitish": "master",
- "tarball_url": "http://localhost:10080/yystopf/ceshirepo1/archive/v3.0.0.tar.gz",
- "zipball_url": "http://localhost:10080/yystopf/ceshirepo1/archive/v3.0.0.zip",
- "url": "http://localhost:10080/api/v1/repos/yystopf/ceshirepo1/releases/77",
- "version_gid": "77",
- "created_at": "2021-03-30 15:33"
- },
- {
- "id": 5,
- "trend_type": "VersionRelease",
- "action_type": "创建了版本发布",
- "trend_id": 5,
- "user_name": "yystopf",
- "user_login": "yystopf",
- "user_avatar": "system/lets/letter_avatars/2/Y/241_125_89/120.png",
- "action_time": "1个月前",
- "name": "v1.0.0",
- "tag_name": "v1.0.0",
- "target_commitish": "master",
- "tarball_url": "http://localhost:10080/yystopf/ceshirepo1/archive/v1.0.0.tar.gz",
- "zipball_url": "http://localhost:10080/yystopf/ceshirepo1/archive/v1.0.0.zip",
- "url": "http://localhost:10080/api/v1/repos/yystopf/ceshirepo1/releases/76",
- "version_gid": "76",
- "created_at": "2021-03-30 15:27"
- },
- {
- "id": 2,
- "trend_type": "VersionRelease",
- "action_type": "创建了版本发布",
- "trend_id": 2,
- "user_name": "yystopf",
- "user_login": "yystopf",
- "user_avatar": "system/lets/letter_avatars/2/Y/241_125_89/120.png",
- "action_time": "2个月前",
- "name": "vvvv",
- "tag_name": "v1.1",
- "target_commitish": "dev",
- "tarball_url": "http://localhost:10080/yystopf/virus_blog/archive/v1.1.tar.gz",
- "zipball_url": "http://localhost:10080/yystopf/virus_blog/archive/v1.1.zip",
- "url": "http://localhost:10080/api/v1/repos/yystopf/virus_blog/releases/6",
- "version_gid": "6",
- "created_at": "2021-03-15 14:18"
+ "status": "common",
+ "created_at": "2021-06-09 16:41",
+ "time_ago": "7分钟前"
},
- {
- "id": 2,
- "trend_type": "PullRequest",
- "action_type": "创建了合并请求",
- "trend_id": 2,
- "user_name": "yystopf",
- "user_login": "yystopf",
- "user_avatar": "system/lets/letter_avatars/2/Y/241_125_89/120.png",
- "action_time": "3个月前",
- "name": "444",
- "created_at": "2021-02-25 17:31"
+ ...
+ ]
+}
+
用户接受申请
+用户接受申请
+
+
+示例:
+
+curl -X POST http://localhost:3000/api/users/yystopf/applied_projects/2/accept.json
+
await octokit.request('GET /api/users/:login/applied_projects/:id/accept.json')
+
HTTP 请求
+GET /api/users/:login/applied_projects/:id/accept.json
+请求字段说明:
+
+
+参数
+类型
+字段说明
+
+
+
+login
+string
+用户标识
+
+
+id
+int
+申请id
+
+
+返回字段说明:
+
+
+参数
+类型
+字段说明
+
+
+
+id
+int
+申请id
+
+
+status
+string
+申请状态,canceled:取消,common:正在申请, accept:已接受,refuse:已拒绝
+
+
+time_ago
+string
+申请创建的时间
+
+
+project.id
+int
+申请项目的id
+
+
+project.identifier
+string
+申请项目的标识
+
+
+project.name
+string
+申请项目的名称
+
+
+project.description
+string
+申请项目的描述
+
+
+project.is_public
+bool
+申请项目是否公开
+
+
+project.owner.id
+bool
+申请项目拥有者id
+
+
+project.owner.type
+string
+申请项目拥有者类型
+
+
+project.owner.name
+string
+申请项目拥有者昵称
+
+
+project.owner.login
+string
+申请项目拥有者标识
+
+
+project.owner.image_url
+string
+申请项目拥有者头像
+
+
+user.id
+int
+申请创建者的id
+
+
+user.type
+string
+申请创建者的类型
+
+
+user.name
+string
+申请创建者的名称
+
+
+user.login
+string
+申请创建者的标识
+
+
+user.image_url
+string
+申请创建者头像
+
+
+
+
+返回的JSON示例:
+
+{
+ "project": {
+ "id": 74,
+ "identifier": "hehuisssjssjjsjs",
+ "name": "hehuisssjssjjsjs",
+ "description": "wwww",
+ "is_public": false,
+ "owner": {
+ "id": 10,
+ "type": "User",
+ "name": "testforge1",
+ "login": "testforge1",
+ "image_url": "system/lets/letter_avatars/2/T/19_237_174/120.png"
}
- ]
+ },
+ "user": {
+ "id": 6,
+ "type": "User",
+ "name": "何慧",
+ "login": "yystopf",
+ "image_url": "images/avatars/User/6?t=1622513134"
+ },
+ "id": 7,
+ "status": "accept",
+ "created_at": "2021-06-09 16:41",
+ "time_ago": "7分钟前"
}
-
-
-用户开发能力
-用户开发能力, 默认为所有时间下的开发能力
+
用户拒绝申请
+用户拒绝申请
示例:
-curl -X GET http://localhost:3000/api/users/yystopf/statistics/develop.json
-
await octokit.request('GET /api/users/:login/statistics/develop.json')
-
HTTP 请求
-GET /api/users/:login/statistics/develop.json
-请求字段说明:
+curl -X POST http://localhost:3000/api/users/yystopf/applied_projects/2/refuse.json
+
await octokit.request('GET /api/users/:login/applied_projects/:id/refuse.json')
+
HTTP 请求
+GET /api/users/:login/applied_projects/:id/refuse.json
+请求字段说明:
参数
@@ -1913,17 +4212,17 @@ Success — a happy kitten is an authenticated kitten!
-start_time
-integer
-时间戳,开始时间,格式:1621526400
+login
+string
+用户标识
-end_time
-integer
-时间戳,结束时间,格式:1622131200
+id
+int
+申请id
-返回字段说明:
+返回字段说明:
参数
@@ -1932,39 +4231,94 @@ Success — a happy kitten is an authenticated kitten!
-influence
+id
int
-影响力
+申请id
-contribution
-int
-贡献度
+status
+string
+申请状态,canceled:取消,common:正在申请, accept:已接受,refuse:已拒绝
-activity
-int
-活跃度
+time_ago
+string
+申请创建的时间
-experience
+project.id
int
-项目经验
+申请项目的id
-language
-int
-语言能力
+project.identifier
+string
+申请项目的标识
-languages_percent
-float
-语言百分比
+project.name
+string
+申请项目的名称
-each_language_score
+project.description
+string
+申请项目的描述
+
+
+project.is_public
+bool
+申请项目是否公开
+
+
+project.owner.id
+bool
+申请项目拥有者id
+
+
+project.owner.type
+string
+申请项目拥有者类型
+
+
+project.owner.name
+string
+申请项目拥有者昵称
+
+
+project.owner.login
+string
+申请项目拥有者标识
+
+
+project.owner.image_url
+string
+申请项目拥有者头像
+
+
+user.id
int
-各门语言分数
+申请创建者的id
+
+
+user.type
+string
+申请创建者的类型
+
+
+user.name
+string
+申请创建者的名称
+
+
+user.login
+string
+申请创建者的标识
+
+
+user.image_url
+string
+申请创建者头像
@@ -1972,164 +4326,78 @@ Success — a happy kitten is an authenticated kitten!
返回的JSON示例:
{
- "platform": {
- "influence": 61,
- "contribution": 75,
- "activity": 66,
- "experience": 95,
- "language": 87,
- "languages_percent": {
- "CSS": 0.03,
- "C#": 0.13,
- "Ruby": 0.04,
- "Go": 0.05,
- "C": 0.19,
- "Java": 0.34,
- "Python": 0.09,
- "C+": 0.01,
- "C++": 0.11,
- "Scala": 0.01,
- "HTML": 0.01
- },
- "each_language_score": {
- "CSS": 71,
- "C#": 86,
- "Ruby": 75,
- "Go": 77,
- "C": 90,
- "Java": 93,
- "Python": 83,
- "C+": 66,
- "C++": 85,
- "Scala": 66,
- "HTML": 66
+ "project": {
+ "id": 74,
+ "identifier": "hehuisssjssjjsjs",
+ "name": "hehuisssjssjjsjs",
+ "description": "wwww",
+ "is_public": false,
+ "owner": {
+ "id": 10,
+ "type": "User",
+ "name": "testforge1",
+ "login": "testforge1",
+ "image_url": "system/lets/letter_avatars/2/T/19_237_174/120.png"
}
},
"user": {
- "influence": 60,
- "contribution": 72,
- "activity": 65,
- "experience": 88,
- "language": 84,
- "languages_percent": {
- "C": 0.25,
- "C#": 0.33,
- "C++": 0.13,
- "CSS": 0.08,
- "Go": 0.04,
- "HTML": 0.04,
- "Java": 0.04,
- "Ruby": 0.08
- },
- "each_language_score": {
- "C": 81,
- "C#": 84,
- "C++": 75,
- "CSS": 71,
- "Go": 66,
- "HTML": 66,
- "Java": 66,
- "Ruby": 71
- }
- }
+ "id": 6,
+ "type": "User",
+ "name": "何慧",
+ "login": "yystopf",
+ "image_url": "images/avatars/User/6?t=1622513134"
+ },
+ "id": 7,
+ "status": "accept",
+ "created_at": "2021-06-09 16:41",
+ "time_ago": "7分钟前"
}
-
-
-用户角色定位
-用户角色定位,默认显示所有时间下的角色定位数据
+
Projects
申请加入项目
+申请加入项目
示例:
-curl -X GET http://localhost:3000/api/users/yystopf/statistics/role.json
-
await octokit.request('GET /api/users/:login/statistics/role.json')
-
HTTP 请求
-GET /api/users/:login/statistics/role.json
-请求字段说明:
-
-
-参数
-类型
-字段说明
-
-
-
-start_time
-integer
-时间戳,开始时间,格式:1621526400
-
-
-end_time
-integer
-时间戳,结束时间,格式:1622131200
-
-
-返回字段说明:
+curl -X POST http://localhost:3000/api/applied_projects.json
+
await octokit.request('POST /api/appliedr_projects.json')
+
HTTP 请求
+POST /api/applied_projects.json
+请求参数
参数
+必选
+默认
类型
字段说明
-total_projects_count
-int
-用户所有的项目数量
-
-
-role.object.count
-int
-用户该语言下的项目数量
+applied_project.code
+是
+
+string
+邀请码
-role.object.percent
-float
-用户该语言下的项目占比
+applied_project.role
+否
+
+string
+项目权限,reporter: 报告者, developer: 开发者,manager:管理员
-返回的JSON示例:
+请求的JSON示例
{
- "total_projects_count": 27,
- "role": {
- "owner": {
- "count": 24,
- "percent": 0.89
- },
- "manager": {
- "count": 1,
- "percent": 0.04
- },
- "developer": {
- "count": 2,
- "percent": 0.07
- },
- "reporter": {
- "count": 0,
- "percent": 0.0
- }
- }
+ "applied_project": {
+ "code": "1una34",
+ "role": "developer"
+ }
}
-
-
-用户专业定位
-用户专业定位,默认显示所有时间下的专业定位数据
-
-
-示例:
-
-curl -X GET http://localhost:3000/api/users/yystopf/statistics/major.json
-
await octokit.request('GET /api/users/:login/statistics/major.json')
-
HTTP 请求
-GET /api/users/:login/statistics/major.json
-请求字段说明:
+| 参数 | @@ -2138,352 +4406,362 @@ Success — a happy kitten is an authenticated kitten!|||||
|---|---|---|---|---|---|
| start_time | -integer | -时间戳,开始时间,格式:1621526400 | +id | +int | +申请id |
| end_time | -integer | -时间戳,结束时间,格式:1622131200 | +status | +string | +申请状态,canceled:取消,common:正在申请, accept:已接受,refuse:已拒绝 |
| 参数 | -类型 | -字段说明 | +time_ago | +string | +项目申请创建的时间 |
|---|---|---|---|---|---|
| categories | +project.id | int | -用户项目分类 | +申请项目的id |
--返回的JSON示例:
-
{
- "categories": [
- "大数据",
- "机器学习",
- "深度学习",
- "人工智能",
- "智慧医疗",
- "云计算"
- ]
-}
-待办事项-用户通知信息
- ---示例:
-
curl -X GET http://localhost:3000/api/users/yystopf/applied_messages.json
-await octokit.request('GET /api/users/:login/applied_messages.json')
-GET /api/users/:login/applied_messages.json
| 参数 | -类型 | -字段说明 | +project.identifier | +string | +申请项目的标识 |
|---|---|---|---|---|---|
| login | +project.name | string | -用户标识 | +申请项目的名称 |
| 参数 | -类型 | -字段说明 | +project.description | +string | +申请项目的描述 |
|---|---|---|---|---|---|
| applied | -object | -通知主体 | +project.is_public | +bool | +申请项目是否公开 |
| applied.id | -int | -通知主体的迁移id | +project.owner.id | +bool | +申请项目拥有者id |
| applied.status | +project.owner.type | string | -通知主体的迁移状态,canceled:取消,common:正在迁移, accept:已接受,refuse:已拒绝 | +申请项目拥有者类型 | |
| applied.time_ago | +project.owner.name | string | -通知主体的迁移创建的时间 | +申请项目拥有者昵称 | |
| applied.project.id | +project.owner.login | +string | +申请项目拥有者标识 | +||
| project.owner.image_url | +string | +申请项目拥有者头像 | +|||
| user.id | int | -通知主体的迁移项目的id | +申请创建者的id | ||
| applied.project.identifier | +user.type | +string | +申请创建者的类型 | +||
| user.name | +string | +申请创建者的名称 | +|||
| user.login | +string | +申请创建者的标识 | +|||
| user.image_url | +string | +申请创建者头像 | +
++返回的JSON示例:
+
{
+ "project": {
+ "id": 74,
+ "identifier": "hehuisssjssjjsjs",
+ "name": "hehuisssjssjjsjs",
+ "description": "wwww",
+ "is_public": false,
+ "owner": {
+ "id": 10,
+ "type": "User",
+ "name": "testforge1",
+ "login": "testforge1",
+ "image_url": "system/lets/letter_avatars/2/T/19_237_174/120.png"
+ }
+ },
+ "user": {
+ "id": 6,
+ "type": "User",
+ "name": "何慧",
+ "login": "yystopf",
+ "image_url": "images/avatars/User/6?t=1622513134"
+ },
+ "id": 7,
+ "status": "common",
+ "created_at": "2021-06-09 16:41",
+ "time_ago": "1分钟前"
+}
+获取项目列表,也可以更加相关条件过滤搜素
+ +++示例:
+
curl -X GET \
+-d "page=1" \
+-d "limit=5" \
+http://localhost:3000/api/projects | jq
+await octokit.request('GET /api/projects')
+GET api/projects
| 参数 | +必选 | +默认 | +类型 | +字段说明 | +|||
|---|---|---|---|---|---|---|---|
| page | +false | +1 | string | -通知主体的迁移项目的标识 | +页数,第几页 | ||
| applied.project.name | +limit | +false | +15 | string | -通知主体的迁移项目的名称 | +每页多少条数据,默认15条 | |
| applied.project.description | +sort_by | +false | +string | -通知主体的迁移项目的描述 | +排序类型, 取值:updated_on、created_on、forked_count、praises_count; updated_on: 更新时间排序,created_on: 创建时间排序,forked_count: fork数据排序,praises_count: 点赞数量排序,默认为updated_on更新时间排序 | ||
| applied.project.is_public | -bool | -通知主体的迁移项目是否公开 | +sort_direction | +false | ++ | string | +排序方式,取值为: desc、asc; desc: 降序排序, asc: 升序排序, 默认为:desc |
| applied.project.owner.id | -bool | -通知主体的迁移项目拥有者id | +search | +false | ++ | string | +按照项目名称搜索 |
| applied.project.owner.type | -string | -通知主体的迁移项目拥有者类型 | +category_id | +false | ++ | int | +项目类别id |
| applied.project.owner.name | -string | -通知主体的迁移项目拥有者昵称 | +language_id | +false | ++ | int | +项目语言id |
| applied.project.owner.login | +project_type | +false | +string | -通知主体的迁移项目拥有者标识 | +项目类型, 取值为:common、mirror; common:开源托管项目, mirror:开源镜像项目 |
| applied.project.owner.image_url | -string | -通知主体的迁移项目拥有者头像 | +参数 | +类型 | +字段说明 |
|---|---|---|---|---|---|
| applied.user.id | +total_count | int | -通知主体的迁移创建者的id | +项目总条数 | |
| applied.user.type | +id | string | -通知主体的迁移创建者的类型 | +项目id | |
| applied.user.name | +name | string | -通知主体的迁移创建者的名称 | +项目名称 | |
| applied.user.login | +description | string | -通知主体的迁移创建者的标识 | +项目简介 | |
| applied.user.image_url | -string | -通知主体的迁移创建者头像 | +visits | +int | +流量数 |
| applied_user.id | +forked_count | int | -通知发起者的id | +被fork的数量 | |
| applied_user.type | -string | -通知发起者的类型 | +praises_count | +int | +star数量 |
| applied_user.name | -string | -通知发起者的名称 | +is_public | +boolean | +是否公开, true:公开,false:未公开 |
| applied_user.login | +mirror_url | string | -通知发起者的标识 | +镜像url | |
| applied_user.image_url | -string | -通知发起者头像 | +last_update_time | +int | +最后更新时间,为UNIX格式的时间戳 |
| applied_type | -string | -通知类型 | +author | +object | +项目创建者 |
| name | +-- name | string | -通知内容 | +用户名,也是用户标识 | |
| viewed | -string | -是否已读,waiting:未读,viewed:已读 | +category | +object | +项目类别 |
| status | -string | -通知状态, canceled:已取消,common: 正常,successed:成功,failure:失败 | +-- id | +int | +项目类型id |
| time_ago | +-- name | string | -通知时间 | +项目类型名称 | +|
| language | +object | +项目语言 |
--返回的JSON示例:
-
{
- "total_count": 5,
- "applied_messages": [
- {
- "applied": {
- "project": {
- "id": 74,
- "identifier": "hehuisssjssjjsjs",
- "name": "hehuisssjssjjsjs",
- "description": "wwww",
- "is_public": false,
- "owner": {
- "id": 10,
- "type": "User",
- "name": "testforge1",
- "login": "testforge1",
- "image_url": "system/lets/letter_avatars/2/T/19_237_174/120.png"
- }
- },
- "user": {
- "id": 6,
- "type": "User",
- "name": "何慧",
- "login": "yystopf",
- "image_url": "images/avatars/User/6?t=1622513134"
- },
- "id": 6,
- "status": "accepted",
- "created_at": "2021-06-09 16:34",
- "time_ago": "1分钟前"
- },
- "applied_user": {
- "id": 6,
- "type": "User",
- "name": "何慧",
- "login": "yystopf",
- "image_url": "images/avatars/User/6?t=1622513134"
- },
- "applied_type": "AppliedProject",
- "name": "已通过你加入【hehuisssjssjjsjs】仓库的申请。",
- "viewed": "waiting",
- "status": "successed",
- "created_at": "2021-06-09 16:34",
- "time_ago": "1分钟前"
- },
- {
- "applied": {
- "project": {
- "id": 86,
- "identifier": "ceshi_repo1",
- "name": "测试项目啊1",
- "description": "二十多",
- "is_public": true,
- "owner": {
- "id": 52,
- "type": "Organization",
- "name": "身份卡手动阀",
- "login": "ceshi1",
- "image_url": "images/avatars/Organization/52?t=1618805056"
- }
- },
- "user": {
- "id": 6,
- "type": "User",
- "name": "yystopf",
- "login": "yystopf",
- "image_url": "system/lets/letter_avatars/2/Y/241_125_89/120.png"
- },
- "owner": {
- "id": 9,
- "type": "Organization",
- "name": "测试组织",
- "login": "ceshi_org",
- "image_url": "images/avatars/Organization/9?t=1612706073"
- },
- "id": 4,
- "status": "common",
- "created_at": "2021-04-26 09:54",
- "time_ago": "35分钟前"
- },
- "applied_user": {
- "id": 6,
- "type": "User",
- "name": "yystopf",
- "login": "yystopf",
- "image_url": "system/lets/letter_avatars/2/Y/241_125_89/120.png"
- },
- "applied_type": "AppliedTransferProject",
- "name": "正在将【测试项目啊1】仓库转移给【测试组织】",
- "viewed": "viewed",
- "status": "common",
- "created_at": "2021-04-26 09:54",
- "time_ago": "35分钟前"
- },
- ...
- ]
-}
-待办事项-接受仓库
- ---示例:
-
curl -X GET http://localhost:3000/api/users/yystopf/applied_transfer_projects.json
-await octokit.request('GET /api/users/:login/applied_transfer_projects.json')
-GET /api/users/:login/applied_transfer_projects.json
| 参数 | -类型 | -字段说明 | +-- id | +int | +项目语言id |
|---|---|---|---|---|---|
| login | +-- name | string | -用户标识 | +项目语言名称 |
++返回的JSON示例:
+
{
+ "total_count": 3096,
+ "projects": [
+ {
+ "id": 1400794,
+ "repo_id": 1402452,
+ "identifier": "cscw_2021_sponsor",
+ "name": "Sponsor机制下的开源贡献",
+ "description": "CSCW 2021 sponsor机制研究",
+ "visits": 5,
+ "praises_count": 0,
+ "forked_count": 0,
+ "is_public": true,
+ "mirror_url": null,
+ "type": 0,
+ "last_update_time": 1611971671,
+ "time_ago": "2天前",
+ "forked_from_project_id": null,
+ "open_devops": false,
+ "platform": "forge",
+ "author": {
+ "name": "张迅晖",
+ "login": "Nigel",
+ "image_url": "images/avatars/User/3675?t=1611832880"
+ },
+ "category": {
+ "id": 13,
+ "name": "云计算和大数据"
+ },
+ "language": {
+ "id": 34,
+ "name": "Python3.6"
+ }
+ }
+ ]
+}
+获取推荐项目列表
+ +++示例:
+
curl -X GET \
+http://localhost:3000/api/projects/recommend | jq
+await octokit.request('GET /api/projects/recommend.json')
+GET api/projects/recommend
| 参数 | @@ -2492,195 +4770,159 @@ Success — a happy kitten is an authenticated kitten!|||||
|---|---|---|---|---|---|
| id | -int | -迁移id | -|||
| status | -string | -迁移状态,canceled:取消,common:正在迁移, accept:已接受,refuse:已拒绝 | -|||
| time_ago | -string | -迁移创建的时间 | -|||
| project.id | +total_count | int | -迁移项目的id | +项目总条数 | |
| project.identifier | +id | string | -迁移项目的标识 | +项目id | |
| project.name | +name | string | -迁移项目的名称 | +项目名称 | |
| project.description | +description | string | -迁移项目的描述 | -||
| project.is_public | -bool | -迁移项目是否公开 | +项目简介 | ||
| project.owner.id | -bool | -迁移项目拥有者id | +visits | +int | +流量数 |
| project.owner.type | -string | -迁移项目拥有者类型 | +forked_count | +int | +被fork的数量 |
| project.owner.name | -string | -迁移项目拥有者昵称 | +praises_count | +int | +star数量 |
| project.owner.login | -string | -迁移项目拥有者标识 | +is_public | +boolean | +是否公开, true:公开,false:未公开 |
| project.owner.image_url | +mirror_url | string | -迁移项目拥有者头像 | +镜像url | |
| user.id | +last_update_time | int | -迁移创建者的id | -||
| user.type | -string | -迁移创建者的类型 | +最后更新时间,为UNIX格式的时间戳 | ||
| user.name | -string | -迁移创建者的名称 | +author | +object | +项目创建者 |
| user.login | +-- name | string | -迁移创建者的标识 | +用户名,也是用户标识 | |
| user.image_url | -string | -迁移创建者头像 | +category | +object | +项目类别 |
| owner.id | +-- id | int | -迁移接受者的id | +项目类型id | |
| owner.type | +-- name | string | -迁移接受者的类型 | +项目类型名称 | |
| owner.name | -string | -迁移接受者的名称 | +language | +object | +项目语言 |
| owner.login | -string | -迁移接受者的标识 | +-- id | +int | +项目语言id |
| owner.image_url | +-- name | string | -迁移接受者头像 | +项目语言名称 |
-返回的JSON示例:
{
- "total_count": 4,
- "applied_transfer_projects": [
- {
- "project": {
- "id": 86,
- "identifier": "ceshi_repo1",
- "name": "测试项目啊1",
- "description": "二十多",
- "is_public": true,
- "owner": {
- "id": 52,
- "type": "Organization",
- "name": "身份卡手动阀",
- "login": "ceshi1",
- "image_url": "images/avatars/Organization/52?t=1618805056"
- }
- },
- "user": {
- "id": 6,
- "type": "User",
- "name": "yystopf",
- "login": "yystopf",
- "image_url": "system/lets/letter_avatars/2/Y/241_125_89/120.png"
- },
- "owner": {
- "id": 52,
- "type": "Organization",
- "name": "身份卡手动阀",
- "login": "ceshi1",
- "image_url": "images/avatars/Organization/52?t=1618805056"
- },
- "id": 1,
- "status": "canceled",
- "created_at": "2021-04-25 18:06",
- "time_ago": "16小时前"
- },
- ...
- ]
-}
-用户接受迁移
+[
+ {
+ "id": 20,
+ "repo_id": 2,
+ "identifier": "PNAekinmH",
+ "name": "FNILL",
+ "visits": 13567,
+ "author": {
+ "name": "王一达",
+ "login": "wangyida",
+ "image_url": "avatars/User/b"
+ },
+ "category": {
+ "id": 8,
+ "name": "其他"
+ }
+ }
+]
+获取项目导航信息
-示例:
curl -X POST http://localhost:3000/api/users/yystopf/applied_transfer_projects/2/accept.json
-await octokit.request('GET /api/users/:login/applied_transfer_projects/:id/accept.json')
-GET /api/users/:login/applied_transfer_projects/:id/accept.json
curl -X GET \
+http://localhost:3000/api/yystopf/ceshi/menu_list | jq
+await octokit.request('GET /api/yystopf/ceshi/menu_list')
+GET api/:owner/:repo/menu_list
| 参数 | +必选 | +默认 | 类型 | 字段说明 | |||
|---|---|---|---|---|---|---|---|
| login | +owner | +是 | +string | -用户标识 | +用户登录名 | ||
| id | -int | -迁移id | +repo | +是 | ++ | string | +项目标识identifier |
| 参数 | @@ -2689,189 +4931,175 @@ Success — a happy kitten is an authenticated kitten!||||
|---|---|---|---|---|
| id | -int | -迁移id | -||
| status | -string | -迁移状态,canceled:取消,common:正在迁移, accept:已接受,refuse:已拒绝 | -||
| time_ago | -string | -迁移创建的时间 | -||
| project.id | -int | -迁移项目的id | -||
| project.identifier | -string | -迁移项目的标识 | -||
| project.name | -string | -迁移项目的名称 | -||
| project.description | -string | -迁移项目的描述 | -||
| project.is_public | -bool | -迁移项目是否公开 | -||
| project.owner.id | -bool | -迁移项目拥有者id | -||
| project.owner.type | -string | -迁移项目拥有者类型 | -||
| project.owner.name | -string | -迁移项目拥有者昵称 | -||
| project.owner.login | -string | -迁移项目拥有者标识 | -||
| project.owner.image_url | +menu_name | string | -迁移项目拥有者头像 | +导航名称, home:主页,code:代码库,issues:易修,pulls:合并请求,devops:工作流,versions:里程碑,activity:动态,setting:仓库设置 |
++返回的JSON示例:
+
[
+ {
+ "menu_name": "home"
+ },
+ {
+ "menu_name": "code"
+ },
+ {
+ "menu_name": "pulls"
+ },
+ {
+ "menu_name": "activity"
+ }
+]
+获取项目主页信息
+ +++示例:
+
curl -X GET \
+http://localhost:3000/api/jasder/forgeplus/about | jq
+await octokit.request('GET /api/jasder/forgeplus/about')
+GET api/:owner/:repo/about
| user.id | -int | -迁移创建者的id | +参数 | +必选 | +默认 | +类型 | +字段说明 |
|---|---|---|---|---|---|---|---|
| user.type | +owner | +是 | +string | -迁移创建者的类型 | +用户登录名 | ||
| user.name | +repo | +是 | +string | -迁移创建者的名称 | +项目标识identifier |
| user.login | -string | -迁移创建者的标识 | +参数 | +类型 | +字段说明 |
|---|---|---|---|---|---|
| user.image_url | +identifier | string | -迁移创建者头像 | -||
| owner.id | -int | -迁移接受者的id | +project's identifier | ||
| owner.type | +content | string | -迁移接受者的类型 | +主页内容 | |
| owner.name | -string | -迁移接受者的名称 | +attachments | +array | +附件 |
++返回的JSON示例:
+
{
+ "content": "",
+ "identifier": "forgeplus",
+ attachments: []
+}
+项目模块信息
+ +++示例:
+
curl -X GET \
+http://localhost:3000/api/yystopf/ceshi/project_units.json
+await octokit.request('GET /api/yystopf/ceshi/project_units')
+GET /api/yystopf/ceshi/project_units
| owner.login | -string | -迁移接受者的标识 | +参数 | +类型 | +字段说明 |
|---|---|---|---|---|---|
| owner.image_url | +type | string | -迁移接受者头像 | +模块名称 |
-返回的JSON示例:
{
- "project": {
- "id": 86,
- "identifier": "ceshi_repo1",
- "name": "测试项目啊1",
- "description": "二十多",
- "is_public": true,
- "owner": {
- "id": 52,
- "type": "Organization",
- "name": "身份卡手动阀",
- "login": "ceshi1",
- "image_url": "images/avatars/Organization/52?t=1618805056"
- }
- },
- "user": {
- "id": 6,
- "type": "User",
- "name": "yystopf",
- "login": "yystopf",
- "image_url": "system/lets/letter_avatars/2/Y/241_125_89/120.png"
+[
+ {
+ "type": "code"
},
- "owner": {
- "id": 52,
- "type": "Organization",
- "name": "身份卡手动阀",
- "login": "ceshi1",
- "image_url": "images/avatars/Organization/52?t=1618805056"
+ {
+ "type": "pulls"
},
- "id": 1,
- "status": "canceled",
- "created_at": "2021-04-25 18:06",
- "time_ago": "16小时前"
-}
-
用户拒绝迁移
-用户拒绝迁移
+ {
+ "type": "issues"
+ }
+]
+更改项目模块展示
-示例:
curl -X POST http://localhost:3000/api/users/yystopf/applied_transfer_projects/2/refuse.json
-await octokit.request('GET /api/users/:login/applied_transfer_projects/:id/refuse.json')
-GET /api/users/:login/applied_transfer_projects/:id/refuse.json
curl -X POST \
+-H "accept: application/json" \
+-H "Content-Type: application/json" \
+-d "{ \"unit_typs\": [\"code\", \"pulls\"]}" \
+http://localhost:3000/api/yystopf/ceshi/project_units.json
+await octokit.request('POST /api/yystopf/ceshi/project_units')
+POST /api/yystopf/ceshi/project_units
| 参数 | +必选 | +默认 | 类型 | 字段说明 | |||
|---|---|---|---|---|---|---|---|
| login | -string | -用户标识 | -|||||
| id | -int | -迁移id | +unit_types | +是 | ++ | array | +项目模块内容, 支持以下参数:code:代码库,issues:易修,pulls:合并请求,devops:工作流,versions:里程碑 |
| 参数 | @@ -2880,119 +5108,134 @@ Success — a happy kitten is an authenticated kitten!|||
|---|---|---|---|
| id | -int | -迁移id | -|
| status | -string | -迁移状态,canceled:取消,common:正在迁移, accept:已接受,refuse:已拒绝 | -|
| time_ago | -string | -迁移创建的时间 | -|
| project.id | int | -迁移项目的id | -|
| project.identifier | -string | -迁移项目的标识 | -|
| project.name | -string | -迁移项目的名称 | +返回状态, 0: 表示操作成功 |
| project.description | +message | string | -迁移项目的描述 | -
| project.is_public | -bool | -迁移项目是否公开 | +返回信息说明 |
++返回的JSON示例:
+
{
+ "status": 0,
+ "message": "success"
+}
+创建项目
+ +++示例:
+
curl -X POST \
+-d "user_id=36401" \
+-d "name=hnfl_demo" \
+-d "description=my first project" \
+-d "repository_name=hnfl_demo" \
+-d "project_category_id=1" \
+-d "project_language_id=2" \
+-d "ignore_id=2" \
+-d "license_id=1" \
+http://localhost:3000/api/projects.json
+await octokit.request('GET /api/projects.json')
+POST api/projects
| project.owner.id | -bool | -迁移项目拥有者id | +参数 | +必选 | +默认 | +类型 | +字段说明 |
|---|---|---|---|---|---|---|---|
| project.owner.type | -string | -迁移项目拥有者类型 | +user_id | +是 | ++ | int | +用户id或者组织id |
| project.owner.name | +name | +是 | +string | -迁移项目拥有者昵称 | +项目名称 | ||
| project.owner.login | +description | +是 | +string | -迁移项目拥有者标识 | +项目描述 | ||
| project.owner.image_url | +repository_name | +是 | +string | -迁移项目拥有者头像 | +仓库名称, 只含有数字、字母、下划线不能以下划线开头和结尾,且唯一 | ||
| user.id | +project_category_id | +是 | +int | -迁移创建者的id | -|||
| user.type | -string | -迁移创建者的类型 | -|||||
| user.name | -string | -迁移创建者的名称 | +项目类别id | ||||
| user.login | -string | -迁移创建者的标识 | +project_language_id | +是 | ++ | int | +项目语言id |
| user.image_url | -string | -迁移创建者头像 | +ignore_id | +否 | ++ | int | +gitignore相关id |
| owner.id | +license_id | +否 | +int | -迁移接受者的id | +开源许可证id | ||
| owner.type | -string | -迁移接受者的类型 | +private | +否 | ++ | boolean | +项目是否私有, true:为私有,false: 公开,默认为公开 |
| owner.name | -string | -迁移接受者的名称 | +参数 | +类型 | +字段说明 |
|---|---|---|---|---|---|
| owner.login | -string | -迁移接受者的标识 | +id | +int | +id |
| owner.image_url | +name | string | -迁移接受者头像 | +项目名称 |
返回的JSON示例:
{
- "project": {
- "id": 86,
- "identifier": "ceshi_repo1",
- "name": "测试项目啊1",
- "description": "二十多",
- "is_public": true,
- "owner": {
- "id": 52,
- "type": "Organization",
- "name": "身份卡手动阀",
- "login": "ceshi1",
- "image_url": "images/avatars/Organization/52?t=1618805056"
- }
- },
- "user": {
- "id": 6,
- "type": "User",
- "name": "yystopf",
- "login": "yystopf",
- "image_url": "system/lets/letter_avatars/2/Y/241_125_89/120.png"
- },
- "owner": {
- "id": 52,
- "type": "Organization",
- "name": "身份卡手动阀",
- "login": "ceshi1",
- "image_url": "images/avatars/Organization/52?t=1618805056"
- },
- "id": 1,
- "status": "canceled",
- "created_at": "2021-04-25 18:06",
- "time_ago": "16小时前"
+ "id": 3240,
+ "name": "好项目"
}
-待办事项-项目申请
+创建镜像项目
-示例:
curl -X GET http://localhost:3000/api/users/yystopf/applied_projects.json
-await octokit.request('GET /api/users/:login/applied_projects.json')
-GET /api/users/:login/applied_projects.json
| 参数 | -类型 | -字段说明 | -
|---|---|---|
| login | -string | -用户标识 | -
curl -X POST \
+-d "user_id=36408" \
+-d "clone_addr=https://gitea.com/mx8090alex/golden.git" \
+-d "name=golden_mirror1" \
+-d "description=golden_mirror" \
+-d "project_category_id=1" \
+-d "project_language_id=2" \
+http://localhost:3000/api/projects/migrate.json
+await octokit.request('GET /api/projects/migrate.json')
+POST api/projects/migrate.json
| 参数 | +必选 | +默认 | 类型 | 字段说明 | |||
|---|---|---|---|---|---|---|---|
| id | +user_id | +是 | +int | -申请id | +用户id或者组织id | ||
| status | +name | +是 | +string | -申请状态,canceled:取消,common:正在申请, accept:已接受,refuse:已拒绝 | +项目名称 | ||
| time_ago | +clone_addr | +是 | +string | -申请创建的时间 | -|||
| project.id | -int | -申请项目的id | +镜像项目clone地址 | ||||
| project.identifier | +description | +否 | +string | -申请项目的标识 | +项目描述 | ||
| project.name | +repository_name | +是 | +string | -申请项目的名称 | +仓库名称, 只含有数字、字母、下划线不能以下划线开头和结尾,且唯一 | ||
| project.description | -string | -申请项目的描述 | +project_category_id | +是 | ++ | int | +项目类别id |
| project.is_public | -bool | -申请项目是否公开 | +project_language_id | +是 | ++ | int | +项目语言id |
| project.owner.id | -bool | -申请项目拥有者id | +is_mirror | +否 | ++ | boolean | +是否设置为镜像, true:是, false:否,默认为否 |
| project.owner.type | +auth_username | +否 | +string | -申请项目拥有者类型 | +镜像源仓库的登录用户名 | ||
| project.owner.name | +auth_password | +否 | +string | -申请项目拥有者昵称 | +镜像源仓库的登录秘密 | ||
| project.owner.login | -string | -申请项目拥有者标识 | +private | +否 | ++ | boolean | +项目是否私有, true:为私有,false: 非私有,默认为公开 |
| project.owner.image_url | -string | -申请项目拥有者头像 | +参数 | +类型 | +字段说明 |
|---|---|---|---|---|---|
| user.id | +id | int | -申请创建者的id | -||
| user.type | -string | -申请创建者的类型 | -|||
| user.name | -string | -申请创建者的名称 | -|||
| user.login | -string | -申请创建者的标识 | +id | ||
| user.image_url | +name | string | -申请创建者头像 | +项目名称 |
返回的JSON示例:
{
- "total_count": 4,
- "applied_transfer_projects": [
- {
- "project": {
- "id": 74,
- "identifier": "hehuisssjssjjsjs",
- "name": "hehuisssjssjjsjs",
- "description": "wwww",
- "is_public": false,
- "owner": {
- "id": 10,
- "type": "User",
- "name": "testforge1",
- "login": "testforge1",
- "image_url": "system/lets/letter_avatars/2/T/19_237_174/120.png"
- }
- },
- "user": {
- "id": 6,
- "type": "User",
- "name": "何慧",
- "login": "yystopf",
- "image_url": "images/avatars/User/6?t=1622513134"
- },
- "id": 7,
- "status": "common",
- "created_at": "2021-06-09 16:41",
- "time_ago": "7分钟前"
- },
- ...
- ]
+ "id": 3241,
+ "name": "这是一个镜像项目"
}
-用户接受申请
+手动同步镜像
-示例:
curl -X POST http://localhost:3000/api/users/yystopf/applied_projects/2/accept.json
-await octokit.request('GET /api/users/:login/applied_projects/:id/accept.json')
-GET /api/users/:login/applied_projects/:id/accept.json
curl -X POST http://localhost:3000/api/repositories/1244/sync_mirror.json
+await octokit.request('POST /api/repositories/1244/sync_mirror.json')
+POST api/repositories/:id/sync_mirror.json
| 参数 | +必选 | +默认 | 类型 | 字段说明 | |
|---|---|---|---|---|---|
| login | -string | -用户标识 | -|||
| id | +是 | +int | -申请id | +仓库id |
| 参数 | @@ -3231,94 +5415,149 @@ Success — a happy kitten is an authenticated kitten!||||
|---|---|---|---|---|
| id | -int | -申请id | -||
| status | -string | -申请状态,canceled:取消,common:正在申请, accept:已接受,refuse:已拒绝 | +int | +状态码, 0:标识请求成功 |
| time_ago | +message | string | -申请创建的时间 | -|
| project.id | -int | -申请项目的id | +服务端返回的信息说明 |
++返回的JSON示例:
+
{
+ "status": 0,
+ "message": "success"
+}
+fork项目
+ +++示例:
+
curl -X POST http://localhost:3000/api/jasder/forgeplus/forks.json
+await octokit.request('POST /api/jaser/jasder_test/forks.json')
+POST api/:owner/:repo/forks.json
| project.identifier | -string | -申请项目的标识 | +参数 | +必选 | +默认 | +类型 | +字段说明 |
|---|---|---|---|---|---|---|---|
| project.name | +owner | +是 | +string | -申请项目的名称 | +用户登录名 | ||
| project.description | +repo | +是 | +string | -申请项目的描述 | +项目标识identifier |
| project.is_public | -bool | -申请项目是否公开 | +参数 | +类型 | +字段说明 |
|---|---|---|---|---|---|
| project.owner.id | -bool | -申请项目拥有者id | +id | +int | +项目id |
| project.owner.type | +identifier | string | -申请项目拥有者类型 | +项目标识 |
++返回的JSON示例:
+
{
+ "id": 3290,
+ "identifier": "newadm"
+}
+用户管理的组织列表
+ +++示例:
+
curl -X GET \
+http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects/organizations.json | jq
+await octokit.request('GET /api/:owner/:repo/applied_transfer_projects/organizations')
+GET api/:owner/:repo/applied_transfer_projects/organizations
| project.owner.name | -string | -申请项目拥有者昵称 | +参数 | +必选 | +默认 | +类型 | +字段说明 |
|---|---|---|---|---|---|---|---|
| project.owner.login | +owner | +是 | +string | -申请项目拥有者标识 | +用户登录名 | ||
| project.owner.image_url | +repo | +是 | +string | -申请项目拥有者头像 | +项目标识identifier |
| user.id | -int | -申请创建者的id | +参数 | +类型 | +字段说明 |
|---|---|---|---|---|---|
| user.type | +name | string | -申请创建者的类型 | +组织标识 | |
| user.name | +nickname | string | -申请创建者的名称 | +组织名称 | |
| user.login | +description | string | -申请创建者的标识 | +组织描述 | |
| user.image_url | -string | -申请创建者头像 | +avatar_url | +string|组织头像 | +
返回的JSON示例:
{
- "project": {
- "id": 74,
- "identifier": "hehuisssjssjjsjs",
- "name": "hehuisssjssjjsjs",
- "description": "wwww",
- "is_public": false,
- "owner": {
- "id": 10,
- "type": "User",
- "name": "testforge1",
- "login": "testforge1",
- "image_url": "system/lets/letter_avatars/2/T/19_237_174/120.png"
+ "total_count": 3,
+ "organizations": [
+ {
+ "id": 9,
+ "name": "ceshi_org",
+ "nickname": "测试组织",
+ "description": "测试组织",
+ "avatar_url": "images/avatars/Organization/9?t=1612706073"
+ },
+ {
+ "id": 51,
+ "name": "ceshi",
+ "nickname": "测试组织哈哈哈",
+ "description": "23212312",
+ "avatar_url": "images/avatars/Organization/51?t=1618800723"
+ },
+ {
+ "id": 52,
+ "name": "ceshi1",
+ "nickname": "身份卡手动阀",
+ "description": "1231手动阀是的",
+ "avatar_url": "images/avatars/Organization/52?t=1618805056"
}
- },
- "user": {
- "id": 6,
- "type": "User",
- "name": "何慧",
- "login": "yystopf",
- "image_url": "images/avatars/User/6?t=1622513134"
- },
- "id": 7,
- "status": "accept",
- "created_at": "2021-06-09 16:41",
- "time_ago": "7分钟前"
+ ]
}
-用户拒绝申请
+迁移项目,edit接口is_transfering为true表示正在迁移
-示例:
curl -X POST http://localhost:3000/api/users/yystopf/applied_projects/2/refuse.json
-await octokit.request('GET /api/users/:login/applied_projects/:id/refuse.json')
-GET /api/users/:login/applied_projects/:id/refuse.json
curl -X POST http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects.json
+await octokit.request('POST /api/:owner/:repo/applied_transfer_projects.json')
+POST /api/:owner/:repo/applied_transfer_projects.json
| 参数 | +必选 | +默认 | 类型 | 字段说明 | |||
|---|---|---|---|---|---|---|---|
| login | +owner | +是 | +string | -用户标识 | +用户登录名 | ||
| id | -int | -申请id | +repo | +是 | ++ | string | +项目标识identifier | +
| owner_name | +是 | ++ | string | +迁移对象标识 |
| 参数 | @@ -3392,92 +5643,117 @@ Success — a happy kitten is an authenticated kitten!|||
|---|---|---|---|
| id | int | -申请id | +项目id |
| status | string | -申请状态,canceled:取消,common:正在申请, accept:已接受,refuse:已拒绝 | +项目迁移状态,canceled:取消,common:正在迁移, accept:已接受,refuse:已拒绝 |
| time_ago | string | -申请创建的时间 | +项目迁移创建的时间 |
| project.id | int | -申请项目的id | +迁移项目的id |
| project.identifier | string | -申请项目的标识 | +迁移项目的标识 |
| project.name | string | -申请项目的名称 | +迁移项目的名称 |
| project.description | string | -申请项目的描述 | +迁移项目的描述 |
| project.is_public | bool | -申请项目是否公开 | +迁移项目是否公开 |
| project.owner.id | bool | -申请项目拥有者id | +迁移项目拥有者id |
| project.owner.type | string | -申请项目拥有者类型 | +迁移项目拥有者类型 |
| project.owner.name | string | -申请项目拥有者昵称 | +迁移项目拥有者昵称 |
| project.owner.login | string | -申请项目拥有者标识 | +迁移项目拥有者标识 |
| project.owner.image_url | string | -申请项目拥有者头像 | +迁移项目拥有者头像 |
| user.id | int | -申请创建者的id | +迁移创建者的id |
| user.type | string | -申请创建者的类型 | +迁移创建者的类型 |
| user.name | string | -申请创建者的名称 | +迁移创建者的名称 |
| user.login | string | -申请创建者的标识 | +迁移创建者的标识 |
| user.image_url | string | -申请创建者头像 | +迁移创建者头像 | +
| owner.id | +int | +迁移接受者的id | +|
| owner.type | +string | +迁移接受者的类型 | +|
| owner.name | +string | +迁移接受者的名称 | +|
| owner.login | +string | +迁移接受者的标识 | +|
| owner.image_url | +string | +迁移接受者头像 |
{
"project": {
- "id": 74,
- "identifier": "hehuisssjssjjsjs",
- "name": "hehuisssjssjjsjs",
- "description": "wwww",
- "is_public": false,
+ "id": 86,
+ "identifier": "ceshi_repo1",
+ "name": "测试项目啊1",
+ "description": "二十多",
+ "is_public": true,
"owner": {
- "id": 10,
- "type": "User",
- "name": "testforge1",
- "login": "testforge1",
- "image_url": "system/lets/letter_avatars/2/T/19_237_174/120.png"
+ "id": 52,
+ "type": "Organization",
+ "name": "身份卡手动阀",
+ "login": "ceshi1",
+ "image_url": "images/avatars/Organization/52?t=1618805056"
}
},
"user": {
"id": 6,
"type": "User",
- "name": "何慧",
+ "name": "yystopf",
"login": "yystopf",
- "image_url": "images/avatars/User/6?t=1622513134"
+ "image_url": "system/lets/letter_avatars/2/Y/241_125_89/120.png"
},
- "id": 7,
- "status": "accept",
- "created_at": "2021-06-09 16:41",
- "time_ago": "7分钟前"
+ "owner": {
+ "id": 9,
+ "type": "Organization",
+ "name": "测试组织",
+ "login": "ceshi_org",
+ "image_url": "images/avatars/Organization/9?t=1612706073"
+ },
+ "id": 4,
+ "status": "common",
+ "created_at": "2021-04-26 09:54",
+ "time_ago": "1分钟前"
}
-申请加入项目
+迁移项目,edit接口is_transfering为true表示正在迁移
-示例:
curl -X POST http://localhost:3000/api/applied_projects.json
-await octokit.request('POST /api/appliedr_projects.json')
-POST /api/applied_projects.json
curl -X POST http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects/cancel.json
+await octokit.request('POST /api/:owner/:repo/applied_transfer_projects/cancel.json')
+POST /api/:owner/:repo/applied_transfer_projects/cancel.json
| 参数 | @@ -3532,31 +5815,21 @@ Success — a happy kitten is an authenticated kitten!|||||||
|---|---|---|---|---|---|---|---|
| applied_project.code | +owner | 是 | string | -邀请码 | +用户登录名 | ||
| applied_project.role | -否 | +repo | +是 | string | -项目权限,reporter: 报告者, developer: 开发者,manager:管理员 | +项目标识identifier |
--请求的JSON示例
-
{
- "applied_project": {
- "code": "1una34",
- "role": "developer"
- }
-}
-| 参数 | @@ -3567,92 +5840,117 @@ Success — a happy kitten is an authenticated kitten!|||
|---|---|---|---|
| id | int | -申请id | +迁移id |
| status | string | -申请状态,canceled:取消,common:正在申请, accept:已接受,refuse:已拒绝 | +迁移状态,canceled:取消,common:正在迁移, accept:已接受,refuse:已拒绝 |
| time_ago | string | -项目申请创建的时间 | +迁移创建的时间 |
| project.id | int | -申请项目的id | +迁移项目的id |
| project.identifier | string | -申请项目的标识 | +迁移项目的标识 |
| project.name | string | -申请项目的名称 | +迁移项目的名称 |
| project.description | string | -申请项目的描述 | +迁移项目的描述 |
| project.is_public | bool | -申请项目是否公开 | +迁移项目是否公开 |
| project.owner.id | bool | -申请项目拥有者id | +迁移项目拥有者id |
| project.owner.type | string | -申请项目拥有者类型 | +迁移项目拥有者类型 |
| project.owner.name | string | -申请项目拥有者昵称 | +迁移项目拥有者昵称 |
| project.owner.login | string | -申请项目拥有者标识 | +迁移项目拥有者标识 |
| project.owner.image_url | string | -申请项目拥有者头像 | +迁移项目拥有者头像 |
| user.id | int | -申请创建者的id | +迁移创建者的id |
| user.type | string | -申请创建者的类型 | +迁移创建者的类型 |
| user.name | string | -申请创建者的名称 | +迁移创建者的名称 |
| user.login | string | -申请创建者的标识 | +迁移创建者的标识 |
| user.image_url | string | -申请创建者头像 | +迁移创建者头像 | +
| owner.id | +int | +迁移接受者的id | +|
| owner.type | +string | +迁移接受者的类型 | +|
| owner.name | +string | +迁移接受者的名称 | +|
| owner.login | +string | +迁移接受者的标识 | +|
| owner.image_url | +string | +迁移接受者头像 |
{
"project": {
- "id": 74,
- "identifier": "hehuisssjssjjsjs",
- "name": "hehuisssjssjjsjs",
- "description": "wwww",
- "is_public": false,
+ "id": 86,
+ "identifier": "ceshi_repo1",
+ "name": "测试项目啊1",
+ "description": "二十多",
+ "is_public": true,
"owner": {
- "id": 10,
- "type": "User",
- "name": "testforge1",
- "login": "testforge1",
- "image_url": "system/lets/letter_avatars/2/T/19_237_174/120.png"
+ "id": 52,
+ "type": "Organization",
+ "name": "身份卡手动阀",
+ "login": "ceshi1",
+ "image_url": "images/avatars/Organization/52?t=1618805056"
}
},
"user": {
"id": 6,
"type": "User",
- "name": "何慧",
+ "name": "yystopf",
"login": "yystopf",
- "image_url": "images/avatars/User/6?t=1622513134"
+ "image_url": "system/lets/letter_avatars/2/Y/241_125_89/120.png"
},
- "id": 7,
+ "owner": {
+ "id": 9,
+ "type": "Organization",
+ "name": "测试组织",
+ "login": "ceshi_org",
+ "image_url": "images/avatars/Organization/9?t=1612706073"
+ },
+ "id": 4,
"status": "common",
- "created_at": "2021-06-09 16:41",
+ "created_at": "2021-04-26 09:54",
"time_ago": "1分钟前"
}
-获取项目列表,也可以更加相关条件过滤搜素
+仓库详情
-示例:
curl -X GET \
--d "page=1" \
--d "limit=5" \
-http://localhost:3000/api/projects | jq
-await octokit.request('GET /api/projects')
+curl -X GET http://localhost:3000/api/jasder/jasder_test.json
+
await octokit.request('GET /api/jasder/jasder_test.json')
+
HTTP 请求
+GET /api/:owner/:repo
+请求参数:
+
+
+参数
+必选
+默认
+类型
+字段说明
+
+
+
+owner
+是
+
+string
+用户登录名
+
+
+repo
+是
+
+string
+项目标识identifier
+
+
+返回字段说明:
+
+
+参数
+类型
+字段说明
+
+
+
+id
+int
+id
+
+
+name
+string
+项目名称
+
+
+identifier
+string
+项目标识
+
+
+is_public
+boolean
+项目是否公开, true:公开,false:私有
+
+
+description
+string
+项目简介
+
+
+repo_id
+int
+仓库id
+
+
+repo_identifier
+string
+仓库标识
+
+
+
+
+返回的JSON示例:
+
+{
+ "name": "ni项目",
+ "identifier": "mirror_demo",
+ "is_public": true,
+ "description": "my first project mirror_demo",
+ "repo_id": 75073,
+ "repo_identifier": "mirror_demo"
+}
+
仓库详情(简版)
+仓库详情
+
+
+示例:
+
+curl -X GET http://localhost:3000/api/jasder/jasder_test/simple.json
+
await octokit.request('GET /api/jasder/jasder_test/simple.json')
HTTP 请求
-GET api/projects
-请求参数
+GET /api/:owner/:repo/simple
+请求参数:
+
+
+参数
+必选
+默认
+类型
+字段说明
+
+
+
+owner
+是
+
+string
+用户登录名
+
+
+repo
+是
+
+string
+项目标识identifier
+
+
+返回字段说明:
参数
-必选
-默认
类型
字段说明
-page
-false
-1
-string
-页数,第几页
+id
+int
+id
-limit
-false
-15
+name
string
-每页多少条数据,默认15条
+项目名称
-sort_by
-false
-
+identifier
string
-排序类型, 取值:updated_on、created_on、forked_count、praises_count; updated_on: 更新时间排序,created_on: 创建时间排序,forked_count: fork数据排序,praises_count: 点赞数量排序,默认为updated_on更新时间排序
+项目标识
-sort_direction
-false
-
-string
-排序方式,取值为: desc、asc; desc: 降序排序, asc: 升序排序, 默认为:desc
+is_public
+boolean
+项目是否公开, true:公开,false:私有
-search
-false
-
+description
string
-按照项目名称搜索
-
-
-category_id
-false
-
-int
-项目类别id
+项目简介
-language_id
-false
-
+repo_id
int
-项目语言id
+仓库id
-project_type
-false
-
+repo_identifier
string
-项目类型, 取值为:common、mirror; common:开源托管项目, mirror:开源镜像项目
+仓库标识
-返回字段说明
+
+
+返回的JSON示例:
+
+{
+ "name": "ni项目",
+ "identifier": "mirror_demo",
+ "is_public": true,
+ "description": "my first project mirror_demo",
+ "repo_id": 75073,
+ "repo_identifier": "mirror_demo"
+}
+
仓库详情(新版)
+仓库详情
+
+
+示例:
+
+curl -X GET http://localhost:3000/api/yystopf/ceshi/detail.json
+
await octokit.request('GET /api/yystopf/ceshi/detail.json')
+
HTTP 请求
+GET /api/:owner/:repo/detail
+请求参数:
参数
+必选
+默认
类型
字段说明
-total_count
-int
-项目总条数
-
-
-id
+owner
+是
+
string
-项目id
+用户登录名
-name
+repo
+是
+
string
-项目名称
+项目标识identifier
+
+返回字段说明:
+
-description
-string
-项目简介
+参数
+类型
+字段说明
+
-visits
-int
-流量数
+content
+string
+仓库简介
-forked_count
-int
-被fork的数量
+website
+string
+仓库网址
-praises_count
-int
-star数量
+readme
+string
+readme文件|
-is_public
-boolean
-是否公开, true:公开,false:未公开
+identifier
+string
+项目标识
-mirror_url
+name
string
-镜像url
+项目名称
-last_update_time
+issues_count
int
-最后更新时间,为UNIX格式的时间戳
-
-
-author
-object
-项目创建者
-
-
--- name
-string
-用户名,也是用户标识
+项目issue数量
-category
-object
-项目类别
+pull_requests_count
+int
+项目合并请求数量
--- id
+project_identifier
int
-项目类型id
+项目标识
--- name
-string
-项目类型名称
+praises_count
+int
+项目点赞数量
-language
-object
-项目语言
+forked_count
+int
+项目复刻数量
--- id
+watchers_count
int
-项目语言id
+项目关注数量
--- name
-string
-项目语言名称
+versions_count
+int
+项目里程碑数量
-
-
-
-返回的JSON示例:
-
-{
- "total_count": 3096,
- "projects": [
- {
- "id": 1400794,
- "repo_id": 1402452,
- "identifier": "cscw_2021_sponsor",
- "name": "Sponsor机制下的开源贡献",
- "description": "CSCW 2021 sponsor机制研究",
- "visits": 5,
- "praises_count": 0,
- "forked_count": 0,
- "is_public": true,
- "mirror_url": null,
- "type": 0,
- "last_update_time": 1611971671,
- "time_ago": "2天前",
- "forked_from_project_id": null,
- "open_devops": false,
- "platform": "forge",
- "author": {
- "name": "张迅晖",
- "login": "Nigel",
- "image_url": "images/avatars/User/3675?t=1611832880"
- },
- "category": {
- "id": 13,
- "name": "云计算和大数据"
- },
- "language": {
- "id": 34,
- "name": "Python3.6"
- }
- }
- ]
-}
-
-
-推荐项目
-获取推荐项目列表
-
-
-示例:
-
-curl -X GET \
-http://localhost:3000/api/projects/recommend | jq
-
await octokit.request('GET /api/projects/recommend.json')
-
HTTP 请求
-GET api/projects/recommend
-返回字段说明
-
-参数
-类型
-字段说明
+version_releases_count
+int
+项目发行版数量
-
-total_count
+version_releasesed_count
int
-项目总条数
+项目发行版已发行数量
-id
+permission
string
-项目id
+项目权限
-name
+mirror_url
string
-项目名称
+镜像地址
-description
-string
-项目简介
+mirror
+bool
+是否为镜像项目
-visits
+type
int
-流量数
+项目类型 0 普通项目 1 普通镜像项目 2 同步镜像项目
-forked_count
+open_devops
int
-被fork的数量
+是否开启devops
-praises_count
-int
-star数量
+watched
+bool
+是否关注
-is_public
-boolean
-是否公开, true:公开,false:未公开
+praised
+bool
+是否点赞
-mirror_url
-string
-镜像url
+status
+int
+项目状态
-last_update_time
+forked_from_project_id
int
-最后更新时间,为UNIX格式的时间戳
+fork项目id
-author
+fork_info
object
-项目创建者
+fork项目信息
--- name
+size
string
-用户名,也是用户标识
+仓库大小
-category
-object
-项目类别
+ssh_url
+string
+项目ssh地址
--- id
+clone_url
+string
+项目克隆地址
+
+
+default_branch
+string
+仓库默认分支
+
+
+empty
+bool
+仓库是否为空
+
+
+full_name
+string
+仓库全称
+
+
+private
+bool
+仓库是否为私有项目
+
+
+license_name
+string
+许可证名称
+
+
+release_versions.list.name
+string
+项目issue数量
+
+
+release_versions.list.tag_name
+string
+发行版标签名称
+
+
+release_versions.list.created_at
+string
+发行版创建时间
+
+
+release_versions.total_count
int
-项目类型id
+发行版数量
--- name
+branches.list.name
string
-项目类型名称
+分支名称
-language
-object
-项目语言
+branches.total_count
+int
+分支数量
--- id
+tags.list.name
+string
+标签名称
+
+
+tags.total_count
int
-项目语言id
+标签数量
--- name
+contributors.list.contributions
+int
+贡献数量
+
+
+contributors.list.login
string
-项目语言名称
+贡献者登录名
+
+
+contributors.list.name
+string
+贡献者用户名称
+
+
+contributors.list.image_url
+string
+贡献者头像
+
+
+languages
+object
+项目语言占比
返回的JSON示例:
-[
- {
- "id": 20,
+{
+ "content": "仓库简介",
+ "website": "仓库网址",
+ "readme": {
+ "type": "file",
+ "encoding": "base64",
+ "size": 9,
+ "name": "README.md",
+ "path": "README.md",
+ "content": "# ceshi\n\n",
+ "sha": ""
+ },
+ "identifier": "ceshi",
+ "name": "测试项目",
+ "project_id": 2,
"repo_id": 2,
- "identifier": "PNAekinmH",
- "name": "FNILL",
- "visits": 13567,
- "author": {
- "name": "王一达",
- "login": "wangyida",
- "image_url": "avatars/User/b"
+ "issues_count": 0,
+ "pull_requests_count": 0,
+ "project_identifier": "ceshi",
+ "praises_count": 0,
+ "forked_count": 0,
+ "watchers_count": 0,
+ "versions_count": 0,
+ "version_releases_count": 0,
+ "version_releasesed_count": 0,
+ "permission": "Reporter",
+ "mirror_url": null,
+ "mirror": false,
+ "type": 0,
+ "open_devops": false,
+ "watched": false,
+ "praised": false,
+ "status": 1,
+ "forked_from_project_id": 1,
+ "fork_info": {
+ "fork_form_name": "测试项目",
+ "fork_project_user_login": "ceshi_org",
+ "fork_project_identifier": "ceshi",
+ "fork_project_user_name": "ceshi_org"
},
- "category": {
- "id": 8,
- "name": "其他"
+ "size": "25.0 KB",
+ "ssh_url": "virus@localhost:yystopf/ceshi.git",
+ "clone_url": "http://localhost:10080/yystopf/ceshi.git",
+ "default_branch": "master",
+ "empty": false,
+ "full_name": "yystopf/ceshi",
+ "private": false,
+ "license_name": "gnu-javamail-exception",
+ "release_versions": {
+ "list": [
+ {
+ "id": 2,
+ "name": "vvvv",
+ "tag_name": "v1.1",
+ "created_at": "2019-07-18 10:16"
+ }
+ ],
+ "total_count": 1
+ },
+ "branches": {
+ "list": [
+ {
+ "name": "master"
+ }
+ ],
+ "total_count": 1
+ },
+ "tags": {
+ "list": [
+ {
+ "name": "v1.1"
+ },
+ {
+ "name": "v1.0"
+ }
+ ],
+ "total_count": 2
+ },
+ "contributors": {
+ "list": [
+ {
+ "contributions": 1,
+ "gid": 2,
+ "login": "yystopf",
+ "type": "User",
+ "name": "yystopf",
+ "image_url": "avatars/User/b"
+ }
+ ],
+ "total_count": 1
+ },
+ "languages": {
+ "HTML": "50.9%",
+ "Ruby": "25.6%",
+ "JavaScript": "21.4%",
+ "CSS": "1.3%",
+ "CoffeeScript": "0.7%",
+ "Shell": "0.1%"
}
- }
-]
-
-
-项目导航
-获取项目导航信息
+}
+
仓库标签列表
+仓库标签列表
示例:
-curl -X GET \
-http://localhost:3000/api/yystopf/ceshi/menu_list | jq
-
await octokit.request('GET /api/yystopf/ceshi/menu_list')
+curl -X GET http://localhost:3000/api/yystopf/csfjkkj/tags.json
+
await octokit.request('GET /api/yystopf/csfjkkj/tags.json')
HTTP 请求
-GET api/:owner/:repo/menu_list
-请求参数
+GET /api/:owner/:repo/tags.json
+请求参数:
参数
@@ -4080,231 +6580,188 @@ http://localhost:3000/api/yystopf/ceshi/menu_list | jq
string
项目标识identifier
-
-返回字段说明
-
-参数
-类型
-字段说明
+page
+否
+1
+integer
+页码
-
-menu_name
-string
-导航名称, home:主页,code:代码库,issues:易修,pulls:合并请求,devops:工作流,versions:里程碑,activity:动态,setting:仓库设置
+limit
+否
+20
+integer
+每页个数
-
-
-返回的JSON示例:
-
-[
- {
- "menu_name": "home"
- },
- {
- "menu_name": "code"
- },
- {
- "menu_name": "pulls"
- },
- {
- "menu_name": "activity"
- }
-]
-
项目主页
-获取项目主页信息
-
-
-示例:
-
-curl -X GET \
-http://localhost:3000/api/jasder/forgeplus/about | jq
-
await octokit.request('GET /api/jasder/forgeplus/about')
-
HTTP 请求
-GET api/:owner/:repo/about
-请求参数
+返回字段说明:
参数
-必选
-默认
类型
字段说明
-owner
-是
-
+id
+int
+标签id
+
+
+name
string
-用户登录名
+标签名称
-repo
-是
-
+zipball_url
string
-项目标识identifier
+标签zip包下载地址
-
-返回字段说明
-
-参数
-类型
-字段说明
+tarball_url
+string
+标签tar包下载地址
-
-identifier
+tagger
+object
+打标签的人
+
+
+time_ago
string
-project's identifier
+打标签的时间
-content
+created_at_unix
string
-主页内容
+打标签的时间戳
-attachments
-array
-附件
+message
+string
+标签信息
-
-
-
-返回的JSON示例:
-
-{
- "content": "",
- "identifier": "forgeplus",
- attachments: []
-}
-
-
-项目模块信息
-项目模块信息
-
-
-示例:
-
-curl -X GET \
-http://localhost:3000/api/yystopf/ceshi/project_units.json
-
await octokit.request('GET /api/yystopf/ceshi/project_units')
-
HTTP 请求
-GET /api/yystopf/ceshi/project_units
-返回字段说明:
-
-参数
-类型
-字段说明
+commit
+object
+标签最后一个commit
-
-type
+commit.sha
string
-模块名称
+commit的id
-
-
-
-返回的JSON示例:
-
-[
- {
- "type": "code"
- },
- {
- "type": "pulls"
- },
- {
- "type": "issues"
- }
-]
-
更改项目模块展示
-更改项目模块展示
-
-
-示例:
-
-curl -X POST \
--H "accept: application/json" \
--H "Content-Type: application/json" \
--d "{ \"unit_typs\": [\"code\", \"pulls\"]}" \
-http://localhost:3000/api/yystopf/ceshi/project_units.json
-
await octokit.request('POST /api/yystopf/ceshi/project_units')
-
HTTP 请求
-POST /api/yystopf/ceshi/project_units
-请求参数
-
-参数
-必选
-默认
-类型
-字段说明
+commit.message
+string
+commit的提交信息
-
-unit_types
-是
-
-array
-项目模块内容, 支持以下参数:code:代码库,issues:易修,pulls:合并请求,devops:工作流,versions:里程碑
+commit.time_ago
+string
+commit的提交时间
-
-返回字段说明:
-
-参数
-类型
-字段说明
+commit.created_at_unix
+string
+commit的提交时间戳
-
-status
-int
-返回状态, 0: 表示操作成功
+commit.committer
+object
+commit的提交者
-message
-string
-返回信息说明
+commit.author
+object
+commit的作者
返回的JSON示例:
-{
- "status": 0,
- "message": "success"
-}
-
创建项目
-创建项目
+[
+ {
+ "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 POST \
--d "user_id=36401" \
--d "name=hnfl_demo" \
--d "description=my first project" \
--d "repository_name=hnfl_demo" \
--d "project_category_id=1" \
--d "project_language_id=2" \
--d "ignore_id=2" \
--d "license_id=1" \
-http://localhost:3000/api/projects.json
-
await octokit.request('GET /api/projects.json')
-
HTTP 请求
-POST api/projects
-请求参数
+curl -X GET http://localhost:3000/api/jasder/jasder_test/edit.json
+
await octokit.request('GET /api/jasder/jasder_test/edit.json')
+
HTTP 请求
+GET /api/:owner/:repo/edit.json
+请求参数:
参数
@@ -4315,86 +6772,67 @@ http://localhost:3000/api/projects.json
-user_id
-是
-
-int
-用户id或者组织id
-
-
-name
+owner
是
string
-项目名称
+用户登录名
-description
+repo
是
string
-项目描述
+项目标识identifier
+
+返回字段说明:
+
-repository_name
-是
-
-string
-仓库名称, 只含有数字、字母、下划线不能以下划线开头和结尾,且唯一
+参数
+类型
+字段说明
+
-project_category_id
-是
-
-int
-项目类别id
+identifier
+string
+仓库标识
-project_language_id
-是
-
+project_id
int
-项目语言id
+项目id
-ignore_id
-否
-
-int
-gitignore相关id
+project_name
+string
+项目名称
-license_id
-否
-
-int
-开源许可证id
+project_identifier
+string
+项目标识
-private
-否
-
-boolean
-项目是否私有, true:为私有,false: 公开,默认为公开
+project_description
+string
+项目简介
-
-返回字段说明
-
-参数
-类型
-字段说明
+project_category_id
+int
+项目类别id
-
-id
+project_language_id
int
-id
+项目语言id
-name
-string
-项目名称
+private
+boolean
+项目是否私有, true:为私有,false: 公开
@@ -4402,27 +6840,32 @@ http://localhost:3000/api/projects.json
返回的JSON示例:
{
- "id": 3240,
- "name": "好项目"
+ "identifier": "project",
+ "project_id": 3263,
+ "project_name": "项目",
+ "project_identifier": "project identifier",
+ "project_description": "project description",
+ "project_category_id": 1,
+ "project_language_id": 2,
+ "private": false
}
-
创建镜像项目
-创建镜像项目
+
修改仓库信息
+修改仓库信息
示例:
-curl -X POST \
--d "user_id=36408" \
--d "clone_addr=https://gitea.com/mx8090alex/golden.git" \
--d "name=golden_mirror1" \
--d "description=golden_mirror" \
+curl -X PATCH \
+-d "name=hnfl_demo" \
+-d "description=my first project" \
-d "project_category_id=1" \
-d "project_language_id=2" \
-http://localhost:3000/api/projects/migrate.json
-
await octokit.request('GET /api/projects/migrate.json')
-
HTTP 请求
-POST api/projects/migrate.json
-请求参数
+-d "private=true" \
+http://localhost:3000/api/jasder/jasder_test.json
+
await octokit.request('PATCH /api/jasder/jasder_test.json')
+
HTTP 请求
+PATCH /api/:owner/:repo
+请求参数:
参数
@@ -4433,27 +6876,20 @@ http://localhost:3000/api/projects/migrate.json
-user_id
+id
是
int
-用户id或者组织id
+项目id
name
-是
+否
string
项目名称
-clone_addr
-是
-
-string
-镜像项目clone地址
-
-
description
否
@@ -4461,56 +6897,35 @@ http://localhost:3000/api/projects/migrate.json
项目描述
-repository_name
-是
-
-string
-仓库名称, 只含有数字、字母、下划线不能以下划线开头和结尾,且唯一
-
-
project_category_id
-是
+否
int
项目类别id
project_language_id
-是
+否
int
项目语言id
-is_mirror
-否
-
-boolean
-是否设置为镜像, true:是, false:否,默认为否
-
-
-auth_username
-否
-
-string
-镜像源仓库的登录用户名
-
-
-auth_password
+default_branch
否
string
-镜像源仓库的登录秘密
+默认分支名称
private
否
boolean
-项目是否私有, true:为私有,false: 非私有,默认为公开
+项目是否私有, true:为私有,false: 公开,默认为公开
-返回字段说明
+返回字段说明:
参数
@@ -4524,64 +6939,34 @@ http://localhost:3000/api/projects/migrate.json
id
+identifier
+string
+项目标识
+
+
name
string
项目名称
-
-
-
-返回的JSON示例:
-
-{
- "id": 3241,
- "name": "这是一个镜像项目"
-}
-
同步镜像
-手动同步镜像
-
-
-示例:
-
-curl -X POST http://localhost:3000/api/repositories/1244/sync_mirror.json
-
await octokit.request('POST /api/repositories/1244/sync_mirror.json')
-
HTTP 请求
-POST api/repositories/:id/sync_mirror.json
-请求参数
-
-参数
-必选
-默认
-类型
-字段说明
+description
+string
+项目简介
-
-id
-是
-
+project_category_id
int
-仓库id
-
-
-返回字段说明
-
-
-参数
-类型
-字段说明
+项目类别id
-
-status
+project_language_id
int
-状态码, 0:标识请求成功
+项目语言id
-message
-string
-服务端返回的信息说明
+private
+否
+boolean
@@ -4589,20 +6974,25 @@ http://localhost:3000/api/projects/migrate.json
返回的JSON示例:
{
- "status": 0,
- "message": "success"
+ "id": 3263,
+ "identifier": "project identifier",
+ "name": "project name",
+ "description": "project description",
+ "project_category_id": 1,
+ "project_language_id": 2,
+ "is_public": true
}
-
Fork项目
-fork项目
+删除仓库
-示例:
curl -X POST http://localhost:3000/api/jasder/forgeplus/forks.json
-await octokit.request('POST /api/jaser/jasder_test/forks.json')
-POST api/:owner/:repo/forks.json
curl -X DELETE http://localhost:3000/api/jasder/jasder_test.json
+await octokit.request('DELETE /api/jasder/jasder_test.json')
+PATCH /api/:owner/:repo
| 参数 | @@ -4627,7 +7017,7 @@ http://localhost:3000/api/projects/migrate.json项目标识identifier |
|---|
| 参数 | @@ -4636,14 +7026,14 @@ http://localhost:3000/api/projects/migrate.json||||
|---|---|---|---|---|
| id | +status | int | -项目id | +返回状态, 0: 表示操作成功 |
| identifier | +message | string | -项目标识 | +返回信息说明 |
返回的JSON示例:
{
- "id": 3290,
- "identifier": "newadm"
+ "status": 0,
+ "message": "success"
}
-用户管理的组织列表
+ + +仓库中添加成员操作
-示例:
curl -X GET \
-http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects/organizations.json | jq
-await octokit.request('GET /api/:owner/:repo/applied_transfer_projects/organizations')
-GET api/:owner/:repo/applied_transfer_projects/organizations
curl -X POST \
+-d "user_id=12" \
+http://localhost:3000/api/jasder/jasder_test/collaborators.json
+await octokit.request('POST /api/jasder/jasder_test/collaborators.json')
+POST /api/:owner/:repo/collaborators.json
| 参数 | @@ -4689,8 +7084,15 @@ http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects/organizatstring | 项目标识identifier | ||
|---|---|---|---|---|
| user_id | +是 | +int | ++ | 用户id | +
| 参数 | @@ -4699,24 +7101,14 @@ http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects/organizat|||||
|---|---|---|---|---|---|
| name | -string | -组织标识 | -|||
| nickname | -string | -组织名称 | +status | +int | +返回状态, 0: 表示操作成功 |
| description | +message | string | -组织描述 | -||
| avatar_url | -string|组织头像 | -+ | 返回信息说明 |
返回的JSON示例:
{
- "total_count": 3,
- "organizations": [
- {
- "id": 9,
- "name": "ceshi_org",
- "nickname": "测试组织",
- "description": "测试组织",
- "avatar_url": "images/avatars/Organization/9?t=1612706073"
- },
- {
- "id": 51,
- "name": "ceshi",
- "nickname": "测试组织哈哈哈",
- "description": "23212312",
- "avatar_url": "images/avatars/Organization/51?t=1618800723"
- },
- {
- "id": 52,
- "name": "ceshi1",
- "nickname": "身份卡手动阀",
- "description": "1231手动阀是的",
- "avatar_url": "images/avatars/Organization/52?t=1618805056"
- }
- ]
+ "status": 0,
+ "message": "success"
}
-迁移项目,edit接口is_transfering为true表示正在迁移
+ + +仓库中删除成员操作
-示例:
curl -X POST http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects.json
-await octokit.request('POST /api/:owner/:repo/applied_transfer_projects.json')
-POST /api/:owner/:repo/applied_transfer_projects.json
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
| 参数 | @@ -4784,14 +7160,14 @@ http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects/organizat项目标识identifier | ||||||
|---|---|---|---|---|---|---|---|
| owner_name | +user_id | 是 | +int | - | string | -迁移对象标识 | +用户id |
| 参数 | @@ -4800,170 +7176,42 @@ http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects/organizat||||
|---|---|---|---|---|
| id | -int | -项目id | -||
| status | -string | -项目迁移状态,canceled:取消,common:正在迁移, accept:已接受,refuse:已拒绝 | -||
| time_ago | -string | -项目迁移创建的时间 | -||
| project.id | -int | -迁移项目的id | -||
| project.identifier | -string | -迁移项目的标识 | -||
| project.name | -string | -迁移项目的名称 | -||
| project.description | -string | -迁移项目的描述 | -||
| project.is_public | -bool | -迁移项目是否公开 | -||
| project.owner.id | -bool | -迁移项目拥有者id | -||
| project.owner.type | -string | -迁移项目拥有者类型 | -||
| project.owner.name | -string | -迁移项目拥有者昵称 | -||
| project.owner.login | -string | -迁移项目拥有者标识 | -||
| project.owner.image_url | -string | -迁移项目拥有者头像 | -||
| user.id | -int | -迁移创建者的id | -||
| user.type | -string | -迁移创建者的类型 | -||
| user.name | -string | -迁移创建者的名称 | -||
| user.login | -string | -迁移创建者的标识 | -||
| user.image_url | -string | -迁移创建者头像 | -||
| owner.id | int | -迁移接受者的id | -||
| owner.type | -string | -迁移接受者的类型 | -||
| owner.name | -string | -迁移接受者的名称 | -||
| owner.login | -string | -迁移接受者的标识 | +返回状态, 0: 表示操作成功 | |
| owner.image_url | +message | string | -迁移接受者头像 | +返回信息说明 |
-返回的JSON示例:
{
- "project": {
- "id": 86,
- "identifier": "ceshi_repo1",
- "name": "测试项目啊1",
- "description": "二十多",
- "is_public": true,
- "owner": {
- "id": 52,
- "type": "Organization",
- "name": "身份卡手动阀",
- "login": "ceshi1",
- "image_url": "images/avatars/Organization/52?t=1618805056"
- }
- },
- "user": {
- "id": 6,
- "type": "User",
- "name": "yystopf",
- "login": "yystopf",
- "image_url": "system/lets/letter_avatars/2/Y/241_125_89/120.png"
- },
- "owner": {
- "id": 9,
- "type": "Organization",
- "name": "测试组织",
- "login": "ceshi_org",
- "image_url": "images/avatars/Organization/9?t=1612706073"
- },
- "id": 4,
- "status": "common",
- "created_at": "2021-04-26 09:54",
- "time_ago": "1分钟前"
+{
+ "status": 0,
+ "message": "success"
}
-
取消迁移项目
-迁移项目,edit接口is_transfering为true表示正在迁移
+更改仓库成员角色
-示例:
curl -X POST http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects/cancel.json
-await octokit.request('POST /api/:owner/:repo/applied_transfer_projects/cancel.json')
-POST /api/:owner/:repo/applied_transfer_projects/cancel.json
curl -X PUT \
+-d "user_id=12" \
+-d "role=Developer" \
+http://localhost:3000/api/jasder/jasder_test/change_role.json
+await octokit.request('PUT /api/jasder/jasder_test/change_role.json')
+PUT /api/:owner/:repo/change_role.json
| 参数 | @@ -4987,8 +7235,22 @@ http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects/organizatstring | 项目标识identifier | ||
|---|---|---|---|---|
| user_id | +是 | +int | ++ | 用户id | +
| role | +是 | +string | ++ | 取值范围:"Manager", "Developer", "Reporter";分别为项目管理人员(拥有所有操作权限)、项目开发人员(只拥有读写权限)、项目报告人员(只拥有读权限) | +
| 参数 | @@ -4997,119 +7259,127 @@ http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects/organizat||||
|---|---|---|---|---|
| id | -int | -迁移id | -||
| status | -string | -迁移状态,canceled:取消,common:正在迁移, accept:已接受,refuse:已拒绝 | -||
| time_ago | -string | -迁移创建的时间 | -||
| project.id | int | -迁移项目的id | +返回状态, 0: 表示操作成功 | |
| project.identifier | +message | string | -迁移项目的标识 | +返回信息说明 |
++返回的JSON示例:
+
{
+ "status": 0,
+ "message": "success"
+}
+获取仓库成员列表
+ +++示例:
+
curl -X GET \
+-d "page=1" \
+-d "limit=5" \
+http://localhost:3000/api/jasder/jasder_test/collaborators.json
+await octokit.request('GET /api/jasder/jasder_test/collaborators.json')
+GET /api/:owner/:repo/collaborators.json
| project.name | -string | -迁移项目的名称 | +参数 | +必选 | +默认 | +类型 | +字段说明 |
|---|---|---|---|---|---|---|---|
| project.description | +owner | +是 | +string | -迁移项目的描述 | -|||
| project.is_public | -bool | -迁移项目是否公开 | -|||||
| project.owner.id | -bool | -迁移项目拥有者id | +用户登录名 | ||||
| project.owner.type | +repo | +是 | +string | -迁移项目拥有者类型 | +项目标识identifier | ||
| project.owner.name | +page | +否 | +string | -迁移项目拥有者昵称 | +页数,第几页 | ||
| project.owner.login | +limit | +否 | +string | -迁移项目拥有者标识 | +每页多少条数据,默认15条 |
| project.owner.image_url | -string | -迁移项目拥有者头像 | +参数 | +类型 | +字段说明 |
|---|---|---|---|---|---|
| user.id | +total_count | int | -迁移创建者的id | -||
| user.type | -string | -迁移创建者的类型 | +返回记录总条数 | ||
| user.name | -string | -迁移创建者的名称 | +members | +array | +项目成员信息 |
| user.login | -string | -迁移创建者的标识 | +-- id | +int | +用户id |
| user.image_url | +-- name | string | -迁移创建者头像 | -||
| owner.id | -int | -迁移接受者的id | +用户名称 | ||
| owner.type | +-- login | string | -迁移接受者的类型 | +用户登录名/标识 | |
| owner.name | +-- image_url | string | -迁移接受者的名称 | +用户头像 | |
| owner.login | -string | -迁移接受者的标识 | +-- is_owner | +boolean | +是否是项目的拥有者,true:是, false:不是 |
| owner.image_url | +-- role | string | -迁移接受者头像 | +该用户在项目中的角色, Manager: 管理员(拥有操作权限); Developer:开发人员(只拥有读写权限); Reporter:报告人员(只拥有读权限) |
返回的JSON示例:
{
- "project": {
- "id": 86,
- "identifier": "ceshi_repo1",
- "name": "测试项目啊1",
- "description": "二十多",
- "is_public": true,
- "owner": {
- "id": 52,
- "type": "Organization",
- "name": "身份卡手动阀",
- "login": "ceshi1",
- "image_url": "images/avatars/Organization/52?t=1618805056"
- }
- },
- "user": {
- "id": 6,
- "type": "User",
- "name": "yystopf",
- "login": "yystopf",
- "image_url": "system/lets/letter_avatars/2/Y/241_125_89/120.png"
- },
- "owner": {
- "id": 9,
- "type": "Organization",
- "name": "测试组织",
- "login": "ceshi_org",
- "image_url": "images/avatars/Organization/9?t=1612706073"
+ "total_count": 2,
+ "members": [
+ {
+ "id": 36401,
+ "name": "name",
+ "login": "login",
+ "image_url": "avatars/User/b",
+ "is_owner": true,
+ "role": "Manager"
},
- "id": 4,
- "status": "common",
- "created_at": "2021-04-26 09:54",
- "time_ago": "1分钟前"
+ {
+ "id": 36399,
+ "name": "name",
+ "login": "login",
+ "image_url": "avatars/User/b",
+ "is_owner": false,
+ "role": "Developer"
+ }
+ ]
}
-仓库详情
+ + +获取仓库所有文件
-示例:
curl -X GET http://localhost:3000/api/jasder/jasder_test.json
-await octokit.request('GET /api/jasder/jasder_test.json')
-GET /api/:owner/:repo
curl -X GET \
+-d "ref=develop" \
+http://localhost:3000/api/yystopf/ceshi/files.json
+await octokit.request('GET /api/yystopf/ceshi/files.json')
+GET /api/:owner/:repo/files
| 参数 | @@ -5184,8 +7447,22 @@ http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects/organizatstring | 项目标识identifier | ||
|---|---|---|---|---|
| search | +否 | ++ | string | +文件搜索关键词 | +
| ref | +是 | ++ | string | +分支名,默认为仓库默认分支 | +
| 参数 | @@ -5194,64 +7471,82 @@ http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects/organizat|||||
|---|---|---|---|---|---|
| id | -int | -id | -|||
| name | string | -项目名称 | +文件名称 | ||
| identifier | +path | string | -项目标识 | +文件路径 | |
| is_public | -boolean | -项目是否公开, true:公开,false:私有 | +sha | +string | +文件标识 |
| description | +type | string | -项目简介 | +文件类型 | |
| repo_id | +size | int | -仓库id | +文件大小 | |
| repo_identifier | +url | string | -仓库标识 | +文件地址 |
-返回的JSON示例:
{
- "name": "ni项目",
- "identifier": "mirror_demo",
- "is_public": true,
- "description": "my first project mirror_demo",
- "repo_id": 75073,
- "repo_identifier": "mirror_demo"
-}
-仓库详情
+[
+ {
+ "name": ".gitignore",
+ "path": ".gitignore",
+ "sha": "f83922d01ae60f6e637a1a2b9f08871b4f87dfc8",
+ "type": "file",
+ "size": 63,
+ "url": "http://localhost:10080/api/v1/repos/yystopf/ceshi/contents/.gitignore?ref=master",
+ "html_url": "http://localhost:10080/yystopf/ceshi/src/branch/master/.gitignore"
+ },
+ {
+ "name": "LICENSE",
+ "path": "LICENSE",
+ "sha": "8f3b9ab0d08afd3a624d822e3971a2f42b3bc2b9",
+ "type": "file",
+ "size": 341,
+ "url": "http://localhost:10080/api/v1/repos/yystopf/ceshi/contents/LICENSE?ref=master",
+ "html_url": "http://localhost:10080/yystopf/ceshi/src/branch/master/LICENSE"
+ },
+ {
+ "name": "README.md",
+ "path": "README.md",
+ "sha": "1bc8a60ac6ddc876ebc4b60fc68991435bfad93e",
+ "type": "file",
+ "size": 9,
+ "url": "http://localhost:10080/api/v1/repos/yystopf/ceshi/contents/README.md?ref=master",
+ "html_url": "http://localhost:10080/yystopf/ceshi/src/branch/master/README.md"
+ }
+]
+获取仓库代码目录
-示例:
curl -X GET http://localhost:3000/api/jasder/jasder_test/simple.json
-await octokit.request('GET /api/jasder/jasder_test/simple.json')
-GET /api/:owner/:repo/simple
curl -X GET \
+-d "ref=develop" \
+http://localhost:3000//api/jasder/jasder_test/entries.json
+await octokit.request('GET /api/jasder/jasder_test/entries.json')
+GET /api/:owner/:repo/entries.json
| 参数 | @@ -5275,8 +7570,15 @@ http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects/organizatstring | 项目标识identifier | ||
|---|---|---|---|---|
| ref | +否 | ++ | string | +分支名称、tag名称或是提交记录id,默认为master分支 | +
| 参数 | @@ -5285,6 +7587,16 @@ http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects/organizat||||
|---|---|---|---|---|
| last_commit | +object | ++ | ||
| -- commit | +object | ++ | ||
| id | int | id | @@ -5292,32 +7604,32 @@ http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects/organizat||
| name | string | -项目名称 | +文件夹或文件名称 | |
| identifier | +path | string | -项目标识 | -|
| is_public | -boolean | -项目是否公开, true:公开,false:私有 | +文件夹或文件相对路径 | |
| description | +type | string | -项目简介 | +文件类型, file:文件,dir:文件目录 |
| repo_id | +size | int | -仓库id | +文件夹或文件大小 单位B |
| repo_identifier | +content | string | -仓库标识 | +文件内容 | +
| target | +string | +标签 |
返回的JSON示例:
{
- "name": "ni项目",
- "identifier": "mirror_demo",
- "is_public": true,
- "description": "my first project mirror_demo",
- "repo_id": 75073,
- "repo_identifier": "mirror_demo"
+ "last_commit": {
+ "commit": {
+ "sha": "3f2de4f78d2d7050486535082cd11cdfc9f3679e",
+ "url": "http://localhost:3003//api/repositories/api-cloud-platform/commits/3f2de4f78d2d7050486535082cd11cdfc9f3679e",
+ "message": "update README.md.",
+ "author": {
+ "name": "Gitee",
+ "email": "noreply@gitee.com",
+ "date": "2020-03-02T20:23:18+08:00"
+ },
+ "committer": {
+ "name": "Gitee",
+ "email": "noreply@gitee.com",
+ "date": "2020-03-02T20:23:18+08:00"
+ },
+ "timestamp": 1583151798,
+ "time_from_now": "3个月前"
+ },
+ "author": null,
+ "committer": null
+ },
+ "entries": [
+ {
+ "name": "ace-gate",
+ "path": "ace-gate",
+ "sha": "c83f85fc63b14edcd6fc502eee9996f5a9993eca",
+ "type": "dir",
+ "size": 0,
+ "content": null,
+ "target": null,
+ "commit": {
+ "message": "v2.9 升级alibaba组件release版本\n",
+ "sha": "6117eaab86f71115f42f2a46ff1683015cda798d",
+ "created_at": "1970-01-01 08:00",
+ "time_from_now": "1年前",
+ "created_at_unix": null
+ }
+ }
+ ]
}
-仓库详情
+ + +获取仓库代码子目录或者文件
-示例:
curl -X GET http://localhost:3000/api/yystopf/ceshi/detail.json
-await octokit.request('GET /api/yystopf/ceshi/detail.json')
-GET /api/:owner/:repo/detail
curl -X GET \
+-d "ref=master" \
+-d "filepath=file" \
+http://localhost:3000//api/jasder/jasder_test/sub_entries.json
+await octokit.request('GET /api/jasder/jasder_test/sub_entries.json')
+GET /api/:owner/:repo/sub_entries.json
| 参数 | @@ -5355,250 +7707,320 @@ http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects/organizat||||
|---|---|---|---|---|
| owner | 是 | -- | string | -用户登录名 | -
| repo | -是 | -- | string | -项目标识identifier | -
| 参数 | -类型 | -字段说明 | -|||||
|---|---|---|---|---|---|---|---|
| content | -string | -仓库简介 | -|||||
| website | -string | -仓库网址 | -|||||
| readme | -string | -readme文件| | -|||||
| identifier | -string | -项目标识 | -|||||
| name | +string | -项目名称 | +用户登录名 | ||||
| issues_count | -int | -项目issue数量 | +repo | +是 | ++ | string | +项目标识identifier |
| pull_requests_count | -int | -项目合并请求数量 | +filepath | +是 | +string | +文件夹、文件的相对路径 | +|
| project_identifier | -int | -项目标识 | +ref | +否 | ++ | string | +分支名称、tag名称或是提交记录id,默认为master分支 |
| praises_count | -int | -项目点赞数量 | +参数 | +类型 | +字段说明 |
|---|---|---|---|---|---|
| forked_count | +id | int | -项目复刻数量 | +id | |
| watchers_count | -int | -项目关注数量 | +name | +string | +文件夹或文件名称 |
| versions_count | -int | -项目里程碑数量 | +path | +string | +文件夹或文件相对路径 |
| version_releases_count | -int | -项目发行版数量 | +type | +string | +文件类型, file:文件,dir:文件目录 |
| version_releasesed_count | +size | int | -项目发行版已发行数量 | +文件夹或文件大小 单位KB | |
| permission | +content | string | -项目权限 | +文件内容, | |
| mirror_url | +target | string | -镜像地址 | +标签 | |
| mirror | -bool | -是否为镜像项目 | +url | +string | +文件访问链接,带分支 |
| type | -int | -项目类型 0 普通项目 1 普通镜像项目 2 同步镜像项目 | +html_url | +string | +文件访问链接,未标识分支 |
| open_devops | -int | -是否开启devops | +git_url | +string | +文件夹或文件的git仓库访问链接 |
| watched | -bool | -是否关注 | +download_url | +string | +文件下载、文件内容访问链接 |
++返回的JSON示例:
+
[
+ {
+ "name": "build.rc",
+ "path": "lib/build.rc",
+ "type": "",
+ "size": 1268,
+ "content": null,
+ "target": null,
+ "url": "http://localhost:3003/api/v1/repos/18816895620/mirror_demo/contents/lib/build.rc?ref=master",
+ "html_url": "http://localhost:3003/18816895620/mirror_demo/src/branch/master/lib/build.rc",
+ "git_url": "http://localhost:3003/api/v1/repos/18816895620/mirror_demo/git/blobs/191fcf1a63b3777e2977fcede7dd5309efdd70fe",
+ "download_url": null
+ }
+]
+获取仓库README文件
+ +++示例:
+
curl -X GET \
+-d "ref=master" \
+-d "filepath=lib" \
+http://localhost:3000/api/yystopf/csfjkkj/readme.json
+await octokit.request('GET /api/yystopf/csfjkkj/readme.json')
+GET /api/:owner/:repo/readme.json
| praised | -bool | -是否点赞 | +参数 | +必选 | +默认 | +类型 | +字段说明 |
|---|---|---|---|---|---|---|---|
| status | -int | -项目状态 | +owner | +是 | ++ | string | +用户登录名 |
| forked_from_project_id | -int | -fork项目id | +repo | +是 | ++ | string | +项目标识identifier |
| fork_info | -object | -fork项目信息 | +ref | +否 | ++ | string | +分支名称、tag名称或是提交记录id,默认为默认分支 |
| size | +filepath | +否 | +string | -仓库大小 | +子目录名称,默认为空 |
| ssh_url | -string | -项目ssh地址 | +参数 | +类型 | +字段说明 |
|---|---|---|---|---|---|
| clone_url | +type | string | -项目克隆地址 | +文件类型, file:文件,dir:文件目录 | |
| default_branch | +encoding | string | -仓库默认分支 | +编码 | |
| empty | -bool | -仓库是否为空 | +size | +int | +文件夹或文件大小 单位B |
| full_name | +name | string | -仓库全称 | +文件夹或文件名称 | |
| private | -bool | -仓库是否为私有项目 | +path | +string | +文件夹或文件相对路径 |
| license_name | +content | string | -许可证名称 | +文件内容 | |
| release_versions.list.name | +sha | string | -项目issue数量 | +文件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
| release_versions.list.tag_name | -string | -发行版标签名称 | +参数 | +必选 | +默认 | +类型 | +字段说明 |
|---|---|---|---|---|---|---|---|
| release_versions.list.created_at | +owner | +是 | +string | -发行版创建时间 | +用户登录名 | ||
| release_versions.total_count | -int | -发行版数量 | +repo | +是 | ++ | string | +项目标识identifier |
| branches.list.name | +ref | +否 | +string | -分支名称 | +分支名称、tag名称或是提交记录id,默认为整个仓库 | ||
| branches.total_count | -int | -分支数量 | +filepath | +否 | ++ | string | +子目录名称,默认为空 |
| tags.list.name | -string | -标签名称 | +参数 | +类型 | +字段说明 |
|---|---|---|---|---|---|
| tags.total_count | -int | -标签数量 | +total_count | +integer | +贡献者数量 |
| contributors.list.contributions | -int | +contributions | +integer | 贡献数量 | |
| contributors.list.login | +login | string | -贡献者登录名 | +用户登录名 | |
| contributors.list.name | +type | string | -贡献者用户名称 | +用户类型 | |
| contributors.list.image_url | +name | string | -贡献者头像 | +用户昵称 | |
| languages | -object | -项目语言占比 | +image_url | +string | +用户头像 |
返回的JSON示例:
{
- "content": "仓库简介",
- "website": "仓库网址",
- "readme": {
- "type": "file",
- "encoding": "base64",
- "size": 9,
- "name": "README.md",
- "path": "README.md",
- "content": "# ceshi\n\n",
- "sha": ""
- },
- "identifier": "ceshi",
- "name": "测试项目",
- "project_id": 2,
- "repo_id": 2,
- "issues_count": 0,
- "pull_requests_count": 0,
- "project_identifier": "ceshi",
- "praises_count": 0,
- "forked_count": 0,
- "watchers_count": 0,
- "versions_count": 0,
- "version_releases_count": 0,
- "version_releasesed_count": 0,
- "permission": "Reporter",
- "mirror_url": null,
- "mirror": false,
- "type": 0,
- "open_devops": false,
- "watched": false,
- "praised": false,
- "status": 1,
- "forked_from_project_id": 1,
- "fork_info": {
- "fork_form_name": "测试项目",
- "fork_project_user_login": "ceshi_org",
- "fork_project_identifier": "ceshi",
- "fork_project_user_name": "ceshi_org"
- },
- "size": "25.0 KB",
- "ssh_url": "virus@localhost:yystopf/ceshi.git",
- "clone_url": "http://localhost:10080/yystopf/ceshi.git",
- "default_branch": "master",
- "empty": false,
- "full_name": "yystopf/ceshi",
- "private": false,
- "license_name": "gnu-javamail-exception",
- "release_versions": {
- "list": [
- {
- "id": 2,
- "name": "vvvv",
- "tag_name": "v1.1",
- "created_at": "2019-07-18 10:16"
- }
- ],
- "total_count": 1
- },
- "branches": {
- "list": [
- {
- "name": "master"
- }
- ],
- "total_count": 1
- },
- "tags": {
- "list": [
- {
- "name": "v1.1"
- },
- {
- "name": "v1.0"
- }
- ],
- "total_count": 2
- },
- "contributors": {
- "list": [
- {
- "contributions": 1,
- "gid": 2,
- "login": "yystopf",
- "type": "User",
- "name": "yystopf",
- "image_url": "avatars/User/b"
- }
- ],
- "total_count": 1
- },
- "languages": {
- "HTML": "50.9%",
- "Ruby": "25.6%",
- "JavaScript": "21.4%",
- "CSS": "1.3%",
- "CoffeeScript": "0.7%",
- "Shell": "0.1%"
- }
+ "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列表
-示例:
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
curl -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
| 参数 | @@ -5740,7 +8086,7 @@ http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects/organizat项目标识identifier |
|---|
| 参数 | @@ -5749,44 +8095,39 @@ http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects/organizat|||||
|---|---|---|---|---|---|
| identifier | -string | -仓库标识 | -|||
| project_id | +id | int | -项目id | +id | |
| project_name | +url | string | -项目名称 | +地址 | |
| project_identifier | +http_method | string | -项目标识 | +请求方式 | |
| project_description | -string | -项目简介 | +is_active | +bool | +是否激活 |
| project_category_id | -int | -项目类别id | +type | +string | +类型 |
| project_language_id | -int | -项目语言id | +last_status | +string | +最后一次推送的状态 |
| private | -boolean | -项目是否私有, true:为私有,false: 公开 | +create_time | +string | +创建时间 |
返回的JSON示例:
{
- "identifier": "project",
- "project_id": 3263,
- "project_name": "项目",
- "project_identifier": "project identifier",
- "project_description": "project description",
- "project_category_id": 1,
- "project_language_id": 2,
- "private": false
+ "total_count": 4,
+ "webhooks": [
+ {
+ "id": 2,
+ "url": "https://oapi.dingtalk.com/robot/send?access_token=7e1e19d0eddb6a5e33c5c2c4e66f4c88f9437184b9ed2c2653194c6374c7d513",
+ "http_method": "",
+ "is_active": true,
+ "type": "dingtalk",
+ "last_status": "succeed",
+ "create_time": "2021-07-12 10:50:07"
+ },
+ {
+ "id": 3,
+ "url": "http://localhost:3000",
+ "http_method": "GET",
+ "is_active": true,
+ "type": "gitea",
+ "last_status": "succeed",
+ "create_time": "2021-07-26 10:03:45"
+ },
+ {
+ "id": 4,
+ "url": "http://localhost:10081",
+ "http_method": "POST",
+ "is_active": true,
+ "type": "gitea",
+ "last_status": "waiting",
+ "create_time": "2021-07-26 16:56:53"
+ },
+ {
+ "id": 5,
+ "url": "http://localhost:3001",
+ "http_method": "POST",
+ "is_active": true,
+ "type": "gitea",
+ "last_status": "fail",
+ "create_time": "2021-07-26 16:58:23"
+ }
+ ]
}
-修改仓库信息
+ + +获取仓库单个webhook
-示例:
curl -X PATCH \
--d "name=hnfl_demo" \
--d "description=my first project" \
--d "project_category_id=1" \
--d "project_language_id=2" \
--d "private=true" \
-http://localhost:3000/api/jasder/jasder_test.json
-await octokit.request('PATCH /api/jasder/jasder_test.json')
-PATCH /api/:owner/:repo
curl -X GET \
+http://localhost:3000/api/yystopf/ceshi/webhooks/3/edit.json
+await octokit.request('GET /api/yystopf/ceshi/webhooks/3/edit.json')
+GET /api/:owner/:repo/webhooks/:id/edit.json
| 参数 | @@ -5830,56 +8201,28 @@ http://localhost:3000/api/jasder/jasder_test.json||||||||
|---|---|---|---|---|---|---|---|---|
| id | +owner | 是 | - | int | -项目id | -|||
| name | -否 | -- | string | -项目名称 | -||||
| description | -否 | -string | -项目描述 | -|||||
| project_category_id | -否 | -- | int | -项目类别id | -||||
| project_language_id | -否 | -- | int | -项目语言id | +用户登录名 | |||
| default_branch | -否 | +repo | +是 | string | -默认分支名称 | +项目标识identifier | ||
| private | -否 | +id | +是 | - | boolean | -项目是否私有, true:为私有,false: 公开,默认为公开 | +integer | +webhook ID |
| 参数 | @@ -5893,101 +8236,142 @@ http://localhost:3000/api/jasder/jasder_test.jsonid | ||||
|---|---|---|---|---|---|
| identifier | +url | string | -项目标识 | +地址 | |
| name | +content_type | string | -项目名称 | +POST Content Type | |
| description | +http_method | string | -项目简介 | +请求方式 | |
| project_category_id | -int | -项目类别id | +secret | ++ | string |
| project_language_id | -int | -项目语言id | +is_active | +bool | +是否激活 |
| private | -否 | -boolean | +type | +string | +类型 |
--返回的JSON示例:
-
{
- "id": 3263,
- "identifier": "project identifier",
- "name": "project name",
- "description": "project description",
- "project_category_id": 1,
- "project_language_id": 2,
- "is_public": true
-}
-删除仓库
- ---示例:
-
curl -X DELETE http://localhost:3000/api/jasder/jasder_test.json
-await octokit.request('DELETE /api/jasder/jasder_test.json')
-PATCH /api/:owner/:repo
| 参数 | -必选 | -默认 | -类型 | -字段说明 | +last_status | +string | +最后一次推送的状态, waiting 等待,fail 失败,succeed 成功 |
|---|---|---|---|---|---|---|---|
| owner | -是 | -+ | branch_filter | string | -用户登录名 | +分支过滤 | |
| repo | -是 | -+ | events | string | -项目标识identifier | +触发条件 | +|
| create_time | +string | +创建时间 |
| 参数 | -类型 | -字段说明 | +含义 | |
|---|---|---|---|---|
| status | -int | -返回状态, 0: 表示操作成功 | +create | +创建分支或标签 |
| message | -string | -返回信息说明 | +delete | +分支或标签删除 | +
| fork | +仓库被fork | +|||
| push | +git仓库推送 | +|||
| issue | +易修已打开、已关闭、已重新打开或编辑 | +|||
| issue_assign | +易修被指派 | +|||
| issue_label | +易修标签被更新或删除 | +|||
| issue_milestone | +易修被收入里程碑 | +|||
| issue_comment | +易修评论 | +|||
| pull_request | +合并请求 | +|||
| pull_request_assign | +合并请求被指派 | +|||
| pull_request_label | +合并请求被贴上标签 | +|||
| pull_request_milestone | +合并请求被记录于里程碑中 | +|||
| pull_request_comment | +合并请求被评论 | +|||
| pull_request_review_approved | +合并请求被批准 | +|||
| pull_request_review_rejected | +合并请求被拒绝 | +|||
| pull_request_review_comment | +合并请求被提出审查意见 | +|||
| pull_request_sync | +合并请求被同步 | +|||
| repository | +创建或删除仓库 | +|||
| release | +版本发布 |
返回的JSON示例:
{
- "status": 0,
- "message": "success"
+ "id": 3,
+ "http_method": "GET",
+ "content_type": "form",
+ "url": "http://localhost:3000",
+ "secret": "123456",
+ "last_status": "succeed",
+ "is_active": true,
+ "type": "gitea",
+ "create_time": "2021-07-26 10:03:45",
+ "branch_filter": "*",
+ "events": [
+ "create",
+ "delete",
+ "fork",
+ "issues",
+ "issue_assign",
+ "issue_label",
+ "issue_milestone",
+ "issue_comment",
+ "push",
+ "pull_request",
+ "pull_request_assign",
+ "pull_request_label",
+ "pull_request_milestone",
+ "pull_request_comment",
+ "pull_request_review",
+ "pull_request_sync",
+ "repository",
+ "release"
+ ]
}