diff --git a/app/controllers/users/messages_controller.rb b/app/controllers/users/messages_controller.rb
new file mode 100644
index 000000000..0433d41ad
--- /dev/null
+++ b/app/controllers/users/messages_controller.rb
@@ -0,0 +1,121 @@
+class Users::MessagesController < Users::BaseController
+ before_action :private_user_resources!
+
+ def index
+ data = {
+ "receiver": 2,
+ "type": @message_type,
+ "unread_total": 5,
+ "unread_notification": 3,
+ "unread_atme": 2,
+ "records": [
+ {
+ "id": 1,
+ "sender": 5,
+ "receiver": 2,
+ "content": "Atme Message Content 1",
+ "status": 1,
+ "type": 2,
+ "source": "PullRequestAtme",
+ "notification_url": "http://www.baidu.com",
+ "created_at": "2021-09-09 14:34:40"
+ },
+ {
+ "id": 2,
+ "sender": 4,
+ "receiver": 2,
+ "content": "Atme Message Content 2",
+ "status": 0,
+ "type": 2,
+ "source": "IssueAtme",
+ "notification_url": "http://www.baidu.com",
+ "created_at": "2021-09-09 14:34:40"
+ },
+ {
+ "id": 3,
+ "sender": -1,
+ "receiver": 2,
+ "content": "Notification Message Content 1",
+ "status": 1,
+ "type": 1,
+ "source": "IssueDelete",
+ "notification_url": "http://www.baidu.com",
+ "created_at": "2021-09-09 14:34:40"
+ },
+ {
+ "id": 4,
+ "sender": -1,
+ "receiver": 2,
+ "content": "Notification Message Content 2",
+ "status": 0,
+ "type": 1,
+ "source": "IssueChanged",
+ "notification_url": "http://www.baidu.com",
+ "created_at": "2021-09-09 14:34:40"
+ },
+ {
+ "id": 5,
+ "sender": -1,
+ "receiver": 2,
+ "content": "Notification Message Content 3",
+ "status": 0,
+ "type": 1,
+ "source": "ProjectJoined",
+ "notification_url": "http://www.baidu.com",
+ "created_at": "2021-09-09 14:34:40"
+ }
+ ],
+ "records_count": 5,
+ "page_num": 1,
+ "total_page_size": 1,
+ "page_size": 10
+ }
+ result = [1, "请求成功", data]
+ return render_error if result.nil?
+ puts result
+ @data = result[2].stringify_keys
+
+ end
+
+ def create
+ return render_forbidden unless %w(3).include(@message_type)
+ render_ok
+ end
+
+ def delete
+ return render_forbidden unless %w(2).include(@message_type)
+ render_ok
+ end
+
+ def read
+ render_ok
+ end
+
+ private
+ def message_type
+ @message_type = begin
+ case params[:type]
+ when "notification"
+ 1
+ when "atme"
+ 2
+ else
+ -1
+ end
+ end
+ end
+
+ def message_params
+ {
+ sender: current_user.id,
+ reservers: @receiver.id,
+ type: @message_type,
+ content: params[:content]
+ }
+ end
+
+
+ def find_receiver
+ @receiver = User.find_by(login: params[:receiver_login])
+ end
+end
\ No newline at end of file
diff --git a/app/docs/slate/source/includes/_users.md b/app/docs/slate/source/includes/_users.md
index bb4fd2b66..f49fdcf6b 100644
--- a/app/docs/slate/source/includes/_users.md
+++ b/app/docs/slate/source/includes/_users.md
@@ -1,7 +1,7 @@
# Users
@@ -47,6 +47,254 @@ await octokit.request('GET /api/users/me.json')
Success Data.
+## 用户消息列表
+获取用户消息列表
+
+> 示例:
+
+```shell
+curl -X GET http://localhost:3000/api/users/:login/messages.json
+```
+
+```javascript
+await octokit.request('GET /api/users/:login/messages.json')
+```
+
+### HTTP 请求
+`GET api/users/yystopf/messages.json`
+
+### 请求字段说明:
+参数 | 类型 | 字段说明
+--------- | ----------- | -----------
+|type | string | 消息类型,不传为所有消息,notification为系统消息,atme为@我消息|
+|status | integer | 是否已读,不传为所有消息,0为未读,1为已读 |
+|limit | integer | 每页个数 |
+|page | integer | 页码 |
+
+### 返回字段说明:
+参数 | 类型 | 字段说明
+--------- | ----------- | -----------
+|total_count | integer | 消息总数 |
+|type | string | 消息类型 |
+|unread_notification | integer | 未读系统通知数量 |
+|unread_atme | integer | 未读@我数量 |
+|messages.id | integer | 消息id |
+|messages.status | integer | 消息是否已读,0为未读,1为已读 |
+|messages.content | string | 消息内容 |
+|messages.notification_url | string | 消息跳转地址 |
+|messages.source | string | 消息来源 |
+|messages.type | string | 消息类型,notification为系统消息,atme为@我消息|
+|sender | object | 消息发送者 |
+
+#### 消息来源source字段说明
+类型|说明
+--------- | -----------
+|IssueAssigned | 有新指派给我的易修 |
+|IssueAssignerExpire | 我负责的易修截止日期到达最后一天 |
+|IssueAtme | 在易修中@我 |
+|IssueChanged | 我创建或负责的易修状态变更 |
+|IssueCreatorExpire | 我创建的易修截止日期到达最后一天 |
+|IssueDeleted | 我创建或负责的易修删除 |
+|IssueJournal | 我创建或负责的易修有新的评论 |
+|LoginIpTip | 登录异常提示 |
+|OrganizationJoined | 账号被拉入组织 |
+|OrganizationLeft | 账号被移出组织 |
+|OrganizationRole | 账号组织权限变更 |
+|ProjectDelete | 我关注的仓库被删除 |
+|ProjectFollowed | 我管理的仓库被关注 |
+|ProjectForked | 我管理的仓库被复刻 |
+|ProjectIssue | 我管理/关注的仓库有新的易修 |
+|ProjectJoined | 账号被拉入项目 |
+|ProjectLeft | 账号被移出项目 |
+|ProjectMemberJoined | 我管理的仓库有成员加入 |
+|ProjectMemberLeft | 我管理的仓库有成员移出 |
+|ProjectMilestone | 我管理的仓库有新的里程碑 |
+|ProjectPraised | 我管理的仓库被点赞 |
+|ProjectPullRequest | 我管理/关注的仓库有新的合并请求 |
+|ProjectRole | 账号仓库权限变更 |
+|ProjectSettingChanged | 我管理的仓库项目设置被更改 |
+|ProjectTransfer | 我关注的仓库被转移 |
+|ProjectVersion | 我关注的仓库有新的发行版 |
+|PullRequestAssigned | 有新指派给我的合并请求 |
+|PullReuqestAtme | 在合并请求中@我 |
+|PullRequestChanged | 我创建或负责的合并请求状态变更 |
+|PullRequestJournal | 我创建或负责的合并请求有新的评论 |
+
+
+> 返回的JSON示例:
+
+```json
+{
+ "total_count": 5,
+ "type": "",
+ "unread_notification": 3,
+ "unread_atme": 2,
+ "messages": [
+ {
+ "id": 1,
+ "status": 1,
+ "content": "Atme Message Content 1",
+ "notification_url": "http://www.baidu.com",
+ "source": "PullRequestAtme",
+ "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",
+ "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",
+ "type": "notification"
+ },
+ {
+ "id": 4,
+ "status": 0,
+ "content": "Notification Message Content 2",
+ "notification_url": "http://www.baidu.com",
+ "source": "IssueChanged",
+ "type": "notification"
+ },
+ {
+ "id": 5,
+ "status": 0,
+ "content": "Notification Message Content 3",
+ "notification_url": "http://www.baidu.com",
+ "source": "ProjectJoined",
+ "type": "notification"
+ }
+ ]
+}
+```
+
+
+## 发送消息
+发送消息
+
+> 示例:
+
+```shell
+curl -X POST http://localhost:3000/api/users/:login/messages.json
+```
+
+```javascript
+await octokit.request('POST /api/users/:login/messages.json')
+```
+
+### HTTP 请求
+`POST api/users/yystopf/messages.json`
+
+### 请求字段说明:
+参数 | 类型 | 字段说明
+--------- | ----------- | -----------
+|type | string | 消息类型 |
+|recervers_login | array | 需要发送消息的用户名数组|
+|content | string | 消息内容 |
+
+> 返回的JSON示例:
+
+```json
+{
+ "status": 0,
+ "message": "success"
+}
+```
+
+
+## 阅读消息
+阅读消息
+
+> 示例:
+
+```shell
+curl -X POST http://localhost:3000/api/users/:login/messages/read.json
+```
+
+```javascript
+await octokit.request('POST /api/users/:login/messages/read.json')
+```
+
+### HTTP 请求
+`POST api/users/yystopf/messages/read.json`
+
+### 请求字段说明:
+参数 | 类型 | 字段说明
+--------- | ----------- | -----------
+|type | string | 消息类型,不传为所有消息,notification为系统消息,atme为@我消息|
+|ids | array | 消息id数组,包含-1则把所有未读消息标记为已读|
+
+> 返回的JSON示例:
+
+```json
+{
+ "status": 0,
+ "message": "success"
+}
+```
+
+
+## 删除消息
+删除消息
+
+> 示例:
+
+```shell
+curl -X DELETE http://localhost:3000/api/users/:login/messages.json
+```
+
+```javascript
+await octokit.request('DELETE /api/users/:login/messages.json')
+```
+
+### HTTP 请求
+`DELETE api/users/yystopf/messages.json`
+
+### 请求字段说明:
+参数 | 类型 | 字段说明
+--------- | ----------- | -----------
+|type | string | 消息类型,atme为@我消息|
+|ids | array | 消息id数组,包含-1则把所有消息删除|
+
+> 返回的JSON示例:
+
+```json
+{
+ "status": 0,
+ "message": "success"
+}
+```
+
+
+
## 更改用户信息
更改用户信息
diff --git a/app/libs/notice.rb b/app/libs/notice.rb
new file mode 100644
index 000000000..93d5cb42d
--- /dev/null
+++ b/app/libs/notice.rb
@@ -0,0 +1,21 @@
+module Notice
+ class << self
+ def notice_config
+ notice_config = {}
+
+ begin
+ config = Rails.application.config_for(:configuration).symbolize_keys!
+ notice_config = config[:notice].symbolize_keys!
+ raise 'notice config missing' if notice_config.blank?
+ rescue => exception
+ raise ex if Rails.env.production?
+
+ puts %Q{\033[33m [warning] gitea config or configuration.yml missing,
+ please add it or execute 'cp config/configuration.yml.example config/configuration.yml' \033[0m}
+ notice_config = {}
+ end
+
+ notice_config
+ end
+ end
+end
\ No newline at end of file
diff --git a/app/models/message_template.rb b/app/models/message_template.rb
new file mode 100644
index 000000000..f19b77fb8
--- /dev/null
+++ b/app/models/message_template.rb
@@ -0,0 +1,14 @@
+# == 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
+#
+
+class MessageTemplate < ApplicationRecord
+end
diff --git a/app/models/message_template/issue_assigned.rb b/app/models/message_template/issue_assigned.rb
new file mode 100644
index 000000000..51e3e6174
--- /dev/null
+++ b/app/models/message_template/issue_assigned.rb
@@ -0,0 +1,15 @@
+# == 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
+#
+
+# 有新指派给我的易修
+class MessageTemplate::IssueAssigned < MessageTemplate
+end
diff --git a/app/models/message_template/issue_assigner_expire.rb b/app/models/message_template/issue_assigner_expire.rb
new file mode 100644
index 000000000..03af6163c
--- /dev/null
+++ b/app/models/message_template/issue_assigner_expire.rb
@@ -0,0 +1,15 @@
+# == 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
+#
+
+# 我负责的易修截止日期到达最后一天
+class MessageTemplate::IssueAssignerExpire < MessageTemplate
+end
diff --git a/app/models/message_template/issue_atme.rb b/app/models/message_template/issue_atme.rb
new file mode 100644
index 000000000..d09155828
--- /dev/null
+++ b/app/models/message_template/issue_atme.rb
@@ -0,0 +1,15 @@
+# == 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
+#
+
+# 在易修中@我
+class MessageTemplate::IssueAtme < MessageTemplate
+end
\ No newline at end of file
diff --git a/app/models/message_template/issue_changed.rb b/app/models/message_template/issue_changed.rb
new file mode 100644
index 000000000..98772ab0e
--- /dev/null
+++ b/app/models/message_template/issue_changed.rb
@@ -0,0 +1,15 @@
+# == 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
+#
+
+# 我创建或负责的易修状态变更
+class MessageTemplate::IssueChanged < MessageTemplate
+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..ee1940714
--- /dev/null
+++ b/app/models/message_template/issue_creator_expire.rb
@@ -0,0 +1,15 @@
+# == 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
+#
+
+# 我创建的易修截止日期到达最后一天
+class MessageTemplate::IssueCreatorExpire < MessageTemplate
+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..d25fbffd0
--- /dev/null
+++ b/app/models/message_template/issue_deleted.rb
@@ -0,0 +1,15 @@
+# == 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
+#
+
+# 我创建或负责的易修删除
+class MessageTemplate::IssueDeleted < MessageTemplate
+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..4252704c3
--- /dev/null
+++ b/app/models/message_template/issue_journal.rb
@@ -0,0 +1,15 @@
+# == 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
+#
+
+# 我创建或负责的易修有新的评论
+class MessageTemplate::IssueJournal < MessageTemplate
+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..a86e03a50
--- /dev/null
+++ b/app/models/message_template/login_ip_tip.rb
@@ -0,0 +1,15 @@
+# == 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
+#
+
+# 登录异常提示
+class MessageTemplate::LoginIpTip < MessageTemplate
+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..4440bb742
--- /dev/null
+++ b/app/models/message_template/organization_joined.rb
@@ -0,0 +1,15 @@
+# == 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
+#
+
+# 账号被拉入组织
+class MessageTemplate::OrganizationJoined < MessageTemplate
+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..9d346b7b9
--- /dev/null
+++ b/app/models/message_template/organization_left.rb
@@ -0,0 +1,15 @@
+# == 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
+#
+
+# 账号被移出组织
+class MessageTemplate::OrganizationLeft < MessageTemplate
+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..1222a6242
--- /dev/null
+++ b/app/models/message_template/organization_role.rb
@@ -0,0 +1,15 @@
+# == 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
+#
+
+# 账号组织权限变更
+class MessageTemplate::OrganizationRole < MessageTemplate
+end
diff --git a/app/models/message_template/project_delete.rb b/app/models/message_template/project_delete.rb
new file mode 100644
index 000000000..b03813f3a
--- /dev/null
+++ b/app/models/message_template/project_delete.rb
@@ -0,0 +1,15 @@
+# == 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
+#
+
+# 我关注的仓库被删除
+class MessageTemplate::ProjectDelete < MessageTemplate
+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..654e19c7e
--- /dev/null
+++ b/app/models/message_template/project_followed.rb
@@ -0,0 +1,15 @@
+# == 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
+#
+
+# 我管理的仓库被关注
+class MessageTemplate::ProjectFollowed < MessageTemplate
+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..711460c01
--- /dev/null
+++ b/app/models/message_template/project_forked.rb
@@ -0,0 +1,15 @@
+# == 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
+#
+
+# 我管理的仓库被复刻
+class MessageTemplate::ProjectForked < MessageTemplate
+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..fc34d9a52
--- /dev/null
+++ b/app/models/message_template/project_issue.rb
@@ -0,0 +1,15 @@
+# == 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
+#
+
+# 我管理/关注的仓库有新的易修
+class MessageTemplate::ProjectIssue < MessageTemplate
+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..6d21a39e1
--- /dev/null
+++ b/app/models/message_template/project_joined.rb
@@ -0,0 +1,15 @@
+# == 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
+#
+
+# 账号被拉入项目
+class MessageTemplate::ProjectJoined < MessageTemplate
+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..f95467f0a
--- /dev/null
+++ b/app/models/message_template/project_left.rb
@@ -0,0 +1,16 @@
+# == 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
+#
+
+# 账号被移出项目
+class MessageTemplate::ProjectLeft < MessageTemplate
+
+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..6e4e1accc
--- /dev/null
+++ b/app/models/message_template/project_member_joined.rb
@@ -0,0 +1,15 @@
+# == 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
+#
+
+# 我管理的仓库有成员加入
+class MessageTemplate::ProjectMemberJoined < MessageTemplate
+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..3259034d7
--- /dev/null
+++ b/app/models/message_template/project_member_left.rb
@@ -0,0 +1,15 @@
+# == 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
+#
+
+# 我管理的仓库有成员移出
+class MessageTemplate::ProjectMemberLeft < MessageTemplate
+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..b1ff0b9e2
--- /dev/null
+++ b/app/models/message_template/project_milestone.rb
@@ -0,0 +1,15 @@
+# == 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
+#
+
+# 我管理的仓库有新的里程碑
+class MessageTemplate::ProjectMilestone < MessageTemplate
+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..ebbdfd93f
--- /dev/null
+++ b/app/models/message_template/project_praised.rb
@@ -0,0 +1,15 @@
+# == 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
+#
+
+# 我管理的仓库被点赞
+class MessageTemplate::ProjectPraised < MessageTemplate
+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..b1706eb91
--- /dev/null
+++ b/app/models/message_template/project_pull_request.rb
@@ -0,0 +1,15 @@
+# == 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
+#
+
+# 我管理/关注的仓库有新的合并请求
+class MessageTemplate::ProjectPullRequest < MessageTemplate
+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..a59df5361
--- /dev/null
+++ b/app/models/message_template/project_role.rb
@@ -0,0 +1,15 @@
+# == 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
+#
+
+# 账号仓库权限变更
+class MessageTemplate::ProjectRole < MessageTemplate
+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..1c4040f5d
--- /dev/null
+++ b/app/models/message_template/project_setting_changed.rb
@@ -0,0 +1,15 @@
+# == 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
+#
+
+# 我管理的仓库项目设置被更改
+class MessageTemplate::ProjectSettingChanged < MessageTemplate
+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..38998d03b
--- /dev/null
+++ b/app/models/message_template/project_transfer.rb
@@ -0,0 +1,15 @@
+# == 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
+#
+
+# 我关注的仓库被转移
+class MessageTemplate::ProjectTransfer < MessageTemplate
+end
\ No newline at end of file
diff --git a/app/models/message_template/project_version.rb b/app/models/message_template/project_version.rb
new file mode 100644
index 000000000..330dfe95d
--- /dev/null
+++ b/app/models/message_template/project_version.rb
@@ -0,0 +1,15 @@
+# == 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
+#
+
+# 我关注的仓库有新的发行版
+class MessageTemplate::ProjectVersion < MessageTemplate
+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..1be86530c
--- /dev/null
+++ b/app/models/message_template/pull_request_assigned.rb
@@ -0,0 +1,15 @@
+# == 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
+#
+
+# 有新指派给我的合并请求
+class MessageTemplate::PullRequestAssigned < MessageTemplate
+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..afa7a4006
--- /dev/null
+++ b/app/models/message_template/pull_request_atme.rb
@@ -0,0 +1,15 @@
+# == 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
+#
+
+# 在合并请求中@我
+class MessageTemplate::PullReuqestAtme < MessageTemplate
+end
\ No newline at end of file
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..002de3a28
--- /dev/null
+++ b/app/models/message_template/pull_request_changed.rb
@@ -0,0 +1,15 @@
+# == 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
+#
+
+# 我创建或负责的合并请求状态变更
+class MessageTemplate::PullRequestChanged < MessageTemplate
+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..0f79d1663
--- /dev/null
+++ b/app/models/message_template/pull_request_journal.rb
@@ -0,0 +1,15 @@
+# == 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
+#
+
+# 我创建或负责的合并请求有新的评论
+class MessageTemplate::PullRequestJournal < MessageTemplate
+end
diff --git a/app/services/notice/client_service.rb b/app/services/notice/client_service.rb
new file mode 100644
index 000000000..a2ada88c6
--- /dev/null
+++ b/app/services/notice/client_service.rb
@@ -0,0 +1,108 @@
+class Notice::ClientService < ApplicationService
+ attr_reader :url, :params
+
+ def initialize(options={})
+ @url = options[:url]
+ @params = options[:params]
+ end
+
+ def post(url, params={})
+ puts "[notice][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][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][DELETE] request params: #{params}"
+ conn.delete do |req|
+ req.url full_url(url)
+ reb.body = params[:data].to_json
+ end
+ end
+
+ def patch(url, params={})
+ puts "[notice][PATCH] request params: #{params}"
+ conn.patch do |req|
+ req.url full_url(url)
+ reb.body = params[:data].to_json
+ end
+ end
+
+ def put(url, params={})
+ puts "[notice][PUT] request params: #{params}"
+ conn.put do |req|
+ req.url full_url(url)
+ reb.body = params[:data].to_json
+ end
+ 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[:domain]
+ end
+
+ def platform
+ Notice.notice_config[:platform]
+ 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] request url: #{url}"
+ return url
+ end
+
+ def log_error(status, body)
+ puts "[notice] status: #{status}"
+ puts "[notice] body: #{body&.force_encoding('UTF-8')}"
+ end
+
+ def render_response(response)
+ status = response.status
+ body = response&.body
+
+ log_error(status, body)
+
+ if status == 200
+ if body["code"] == 1
+ return [body["code"], body["message"], body["data"]]
+ else
+ puts "[notice][ERROR] code: #{body["code"]}"
+ puts "[notice][ERROR] message: #{body["message"]}"
+ end
+ end
+ end
+end
\ No newline at end of file
diff --git a/app/views/users/get_user_info.json.jbuilder b/app/views/users/get_user_info.json.jbuilder
index 067019ef9..bf5ab8822 100644
--- a/app/views/users/get_user_info.json.jbuilder
+++ b/app/views/users/get_user_info.json.jbuilder
@@ -21,4 +21,5 @@ json.province @user.province
json.city @user.city
json.custom_department @user.custom_department
json.description @user.description
-json.(@user, :show_email, :show_department, :show_location)
\ No newline at end of file
+json.(@user, :show_email, :show_department, :show_location)
+json.message_unread_total 5
\ No newline at end of file
diff --git a/app/views/users/messages/_message.json.jbuilder b/app/views/users/messages/_message.json.jbuilder
new file mode 100644
index 000000000..1d8a9b264
--- /dev/null
+++ b/app/views/users/messages/_message.json.jbuilder
@@ -0,0 +1,22 @@
+json.id message["id"]
+# json.receiver do
+# json.partial! '/users/user_simple', locals: {user: current_user}
+# end
+json.status message["status"]
+json.content message["content"]
+json.notification_url message["notification_url"]
+json.source message["source"]
+case message["type"]
+when 1
+ json.type "notification"
+when 2
+ json.type "atme"
+ json.sender do
+ sender = User.find_by_id(message["sender"])
+ if sender.present?
+ json.partial! '/users/user_simple', locals: {user: sender}
+ else
+ json.nil
+ end
+ end
+end
diff --git a/app/views/users/messages/index.json.jbuilder b/app/views/users/messages/index.json.jbuilder
new file mode 100644
index 000000000..b16d806b7
--- /dev/null
+++ b/app/views/users/messages/index.json.jbuilder
@@ -0,0 +1,7 @@
+json.total_count @data["records_count"]
+json.type %w(notification atme).include?(params[:type]) ? params[:type] : ""
+json.unread_notification @data["unread_notification"]
+json.unread_atme @data["unread_atme"]
+json.messages @data["records"].each do |message|
+ json.partial! "message", message: message.stringify_keys
+end
\ No newline at end of file
diff --git a/config/configuration.yml.example b/config/configuration.yml.example
index c8fe96ca2..61217d4e7 100644
--- a/config/configuration.yml.example
+++ b/config/configuration.yml.example
@@ -57,6 +57,9 @@ default: &default
domain: 'https://testgit.trustie.net'
base_url: '/api/v1'
+ notice:
+ domain: ''
+ base_url: ''
production:
<<: *default
diff --git a/config/routes.rb b/config/routes.rb
index dc8892081..2d5bb9ed5 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -300,6 +300,13 @@ Rails.application.routes.draw do
# resources :recent_contacts, only: [:index]
# resource :private_message_details, only: [:show]
# resource :unread_message_info, only: [:show]
+
+ # 通知中心
+ resources :messages, only: [:index, :create, :delete] do
+ collection do
+ post :read
+ end
+ end
end
resources :tidings, only: [:index]
diff --git a/db/migrate/20210909030759_create_message_templates.rb b/db/migrate/20210909030759_create_message_templates.rb
new file mode 100644
index 000000000..dbae7f55d
--- /dev/null
+++ b/db/migrate/20210909030759_create_message_templates.rb
@@ -0,0 +1,11 @@
+class CreateMessageTemplates < ActiveRecord::Migration[5.2]
+ def change
+ create_table :message_templates do |t|
+ t.string :type
+ t.text :sys_notice
+ t.text :email
+
+ t.timestamps
+ end
+ end
+end
diff --git a/public/docs/api.html b/public/docs/api.html
index 35099a4e8..b6083dcd2 100644
--- a/public/docs/api.html
+++ b/public/docs/api.html
@@ -345,6 +345,18 @@
获取当前登陆用户信息
+
+ 用户消息列表
+
+
+ 发送消息
+
+
+ 阅读消息
+
+
+ 删除消息
+
更改用户信息
@@ -909,7 +921,7 @@ Success — a happy kitten is an authenticated kitten!
Users
获取当前登陆用户信息
@@ -971,6 +983,435 @@ Success — a happy kitten is an authenticated kitten!
+用户消息列表
+获取用户消息列表
+
+
+示例:
+
+curl -X GET http://localhost:3000/api/users/:login/messages.json
+
await octokit.request('GET /api/users/:login/messages.json')
+
HTTP 请求
+GET api/users/yystopf/messages.json
+请求字段说明:
+
+
+参数 |
+类型 |
+字段说明 |
+
+
+
+type |
+string |
+消息类型,不传为所有消息,notification为系统消息,atme为@我消息 |
+
+
+status |
+integer |
+是否已读,不传为所有消息,0为未读,1为已读 |
+
+
+limit |
+integer |
+每页个数 |
+
+
+page |
+integer |
+页码 |
+
+
+返回字段说明:
+
+
+参数 |
+类型 |
+字段说明 |
+
+
+
+total_count |
+integer |
+消息总数 |
+
+
+type |
+string |
+消息类型 |
+
+
+unread_notification |
+integer |
+未读系统通知数量 |
+
+
+unread_atme |
+integer |
+未读@我数量 |
+
+
+messages.id |
+integer |
+消息id |
+
+
+messages.status |
+integer |
+消息是否已读,0为未读,1为已读 |
+
+
+messages.content |
+string |
+消息内容 |
+
+
+messages.notification_url |
+string |
+消息跳转地址 |
+
+
+messages.source |
+string |
+消息来源 |
+
+
+messages.type |
+string |
+消息类型,notification为系统消息,atme为@我消息 |
+
+
+sender |
+object |
+消息发送者 |
+
+
+消息来源source字段说明
+
+
+类型 |
+说明 |
+
+
+
+IssueAssigned |
+有新指派给我的易修 |
+
+
+IssueAssignerExpire |
+我负责的易修截止日期到达最后一天 |
+
+
+IssueAtme |
+在易修中@我 |
+
+
+IssueChanged |
+我创建或负责的易修状态变更 |
+
+
+IssueCreatorExpire |
+我创建的易修截止日期到达最后一天 |
+
+
+IssueDeleted |
+我创建或负责的易修删除 |
+
+
+IssueJournal |
+我创建或负责的易修有新的评论 |
+
+
+LoginIpTip |
+登录异常提示 |
+
+
+OrganizationJoined |
+账号被拉入组织 |
+
+
+OrganizationLeft |
+账号被移出组织 |
+
+
+OrganizationRole |
+账号组织权限变更 |
+
+
+ProjectDelete |
+我关注的仓库被删除 |
+
+
+ProjectFollowed |
+我管理的仓库被关注 |
+
+
+ProjectForked |
+我管理的仓库被复刻 |
+
+
+ProjectIssue |
+我管理/关注的仓库有新的易修 |
+
+
+ProjectJoined |
+账号被拉入项目 |
+
+
+ProjectLeft |
+账号被移出项目 |
+
+
+ProjectMemberJoined |
+我管理的仓库有成员加入 |
+
+
+ProjectMemberLeft |
+我管理的仓库有成员移出 |
+
+
+ProjectMilestone |
+我管理的仓库有新的里程碑 |
+
+
+ProjectPraised |
+我管理的仓库被点赞 |
+
+
+ProjectPullRequest |
+我管理/关注的仓库有新的合并请求 |
+
+
+ProjectRole |
+账号仓库权限变更 |
+
+
+ProjectSettingChanged |
+我管理的仓库项目设置被更改 |
+
+
+ProjectTransfer |
+我关注的仓库被转移 |
+
+
+ProjectVersion |
+我关注的仓库有新的发行版 |
+
+
+PullRequestAssigned |
+有新指派给我的合并请求 |
+
+
+PullReuqestAtme |
+在合并请求中@我 |
+
+
+PullRequestChanged |
+我创建或负责的合并请求状态变更 |
+
+
+PullRequestJournal |
+我创建或负责的合并请求有新的评论 |
+
+
+
+
+返回的JSON示例:
+
+{
+ "total_count": 5,
+ "type": "",
+ "unread_notification": 3,
+ "unread_atme": 2,
+ "messages": [
+ {
+ "id": 1,
+ "status": 1,
+ "content": "Atme Message Content 1",
+ "notification_url": "http://www.baidu.com",
+ "source": "PullRequestAtme",
+ "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",
+ "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",
+ "type": "notification"
+ },
+ {
+ "id": 4,
+ "status": 0,
+ "content": "Notification Message Content 2",
+ "notification_url": "http://www.baidu.com",
+ "source": "IssueChanged",
+ "type": "notification"
+ },
+ {
+ "id": 5,
+ "status": 0,
+ "content": "Notification Message Content 3",
+ "notification_url": "http://www.baidu.com",
+ "source": "ProjectJoined",
+ "type": "notification"
+ }
+ ]
+}
+
+
+发送消息
+发送消息
+
+
+示例:
+
+curl -X POST http://localhost:3000/api/users/:login/messages.json
+
await octokit.request('POST /api/users/:login/messages.json')
+
HTTP 请求
+POST api/users/yystopf/messages.json
+请求字段说明:
+
+
+参数 |
+类型 |
+字段说明 |
+
+
+
+type |
+string |
+消息类型 |
+
+
+recervers_login |
+array |
+需要发送消息的用户名数组 |
+
+
+content |
+string |
+消息内容 |
+
+
+
+
+返回的JSON示例:
+
+{
+ "status": 0,
+ "message": "success"
+}
+
+
+阅读消息
+阅读消息
+
+
+示例:
+
+curl -X POST http://localhost:3000/api/users/:login/messages/read.json
+
await octokit.request('POST /api/users/:login/messages/read.json')
+
HTTP 请求
+POST api/users/yystopf/messages/read.json
+请求字段说明:
+
+
+参数 |
+类型 |
+字段说明 |
+
+
+
+type |
+string |
+消息类型,不传为所有消息,notification为系统消息,atme为@我消息 |
+
+
+ids |
+array |
+消息id数组,包含-1则把所有未读消息标记为已读 |
+
+
+
+
+返回的JSON示例:
+
+{
+ "status": 0,
+ "message": "success"
+}
+
+
+删除消息
+删除消息
+
+
+示例:
+
+curl -X DELETE http://localhost:3000/api/users/:login/messages.json
+
await octokit.request('DELETE /api/users/:login/messages.json')
+
HTTP 请求
+DELETE api/users/yystopf/messages.json
+请求字段说明:
+
+
+参数 |
+类型 |
+字段说明 |
+
+
+
+type |
+string |
+消息类型,atme为@我消息 |
+
+
+ids |
+array |
+消息id数组,包含-1则把所有消息删除 |
+
+
+
+
+返回的JSON示例:
+
+{
+ "status": 0,
+ "message": "success"
+}
+
+
更改用户信息
更改用户信息
@@ -979,9 +1420,9 @@ 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')
-
HTTP 请求
+HTTP 请求
PATCH/PUT /api/users/:login.json
-请求字段说明:
+请求字段说明:
参数 |
@@ -1077,9 +1518,9 @@ Success — a happy kitten is an authenticated kitten!
curl -X GET http://localhost:3000/api/users/yystopf/is_pinned_projects.json
await octokit.request('GET /api/users/:login/is_pinned_projects.json')
-
HTTP 请求
+HTTP 请求
GET api/users/:login/is_pinned_projects.json
-返回字段说明:
+返回字段说明:
参数 |
@@ -1264,9 +1705,9 @@ 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 请求
+HTTP 请求
POST /api/users/:login/is_pinned_projects/pin.json
-请求字段说明:
同时设定多个星标项目
+请求字段说明:
同时设定多个星标项目
参数 |
@@ -1310,9 +1751,9 @@ Success — a happy kitten is an authenticated kitten!
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 请求
+HTTP 请求
PATCH/PUT /api/users/:login/is_pinned_projects/:id.json
-请求字段说明:
+请求字段说明:
参数 |
@@ -1351,9 +1792,9 @@ Success — a happy kitten is an authenticated kitten!
curl -X GET http://localhost:3000/api/users/yystopf/statistics/activity.json
await octokit.request('GET /api/users/:login/statistics/activity.json')
-
HTTP 请求
+HTTP 请求
GET /api/users/:login/statistics/activity.json
-返回字段说明:
+返回字段说明:
参数 |
@@ -1440,9 +1881,9 @@ Success — a happy kitten is an authenticated kitten!
curl -X GET http://localhost:3000/api/users/yystopf/headmaps.json
await octokit.request('GET /api/users/:login/headmaps.json')
-
HTTP 请求
+HTTP 请求
GET api/users/:login/headmaps.json
-请求字段说明:
+请求字段说明:
参数 |
@@ -1456,7 +1897,7 @@ Success — a happy kitten is an authenticated kitten!
年份 |
-返回字段说明:
+返回字段说明:
参数 |
@@ -1585,9 +2026,9 @@ 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')
-
HTTP 请求
+HTTP 请求
GET api/users/:login/project_trends.json
-请求字段说明:
+请求字段说明:
参数 |
@@ -1601,7 +2042,7 @@ Success — a happy kitten is an authenticated kitten!
日期,格式: 2021-05-28 |
-返回字段说明:
+返回字段说明:
参数 |
@@ -1902,9 +2343,9 @@ Success — a happy kitten is an authenticated kitten!
curl -X GET http://localhost:3000/api/users/yystopf/statistics/develop.json
await octokit.request('GET /api/users/:login/statistics/develop.json')
-
HTTP 请求
+HTTP 请求
GET /api/users/:login/statistics/develop.json
-请求字段说明:
+请求字段说明:
参数 |
@@ -1923,7 +2364,7 @@ Success — a happy kitten is an authenticated kitten!
时间戳,结束时间,格式:1622131200 |
-返回字段说明:
+返回字段说明:
参数 |
@@ -2045,9 +2486,9 @@ Success — a happy kitten is an authenticated kitten!
curl -X GET http://localhost:3000/api/users/yystopf/statistics/role.json
await octokit.request('GET /api/users/:login/statistics/role.json')
-
HTTP 请求
+HTTP 请求
GET /api/users/:login/statistics/role.json
-请求字段说明:
+请求字段说明:
参数 |
@@ -2066,7 +2507,7 @@ Success — a happy kitten is an authenticated kitten!
时间戳,结束时间,格式:1622131200 |
-返回字段说明:
+返回字段说明:
参数 |
@@ -2127,9 +2568,9 @@ Success — a happy kitten is an authenticated kitten!
curl -X GET http://localhost:3000/api/users/yystopf/statistics/major.json
await octokit.request('GET /api/users/:login/statistics/major.json')
-
HTTP 请求
+HTTP 请求
GET /api/users/:login/statistics/major.json
-请求字段说明:
+请求字段说明:
参数 |
@@ -2148,7 +2589,7 @@ Success — a happy kitten is an authenticated kitten!
时间戳,结束时间,格式:1622131200 |
-返回字段说明:
+返回字段说明:
参数 |
@@ -2188,9 +2629,9 @@ Success — a happy kitten is an authenticated kitten!
curl -X GET http://localhost:3000/api/users/yystopf/applied_messages.json
await octokit.request('GET /api/users/:login/applied_messages.json')
-
HTTP 请求
+HTTP 请求
GET /api/users/:login/applied_messages.json
-请求字段说明:
+请求字段说明:
参数 |
@@ -2204,7 +2645,7 @@ Success — a happy kitten is an authenticated kitten!
用户标识 |
-返回字段说明:
+返回字段说明:
参数 |
@@ -2467,9 +2908,9 @@ Success — a happy kitten is an authenticated kitten!
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 请求
+HTTP 请求
GET /api/users/:login/applied_transfer_projects.json
-请求字段说明:
+请求字段说明:
参数 |
@@ -2483,7 +2924,7 @@ Success — a happy kitten is an authenticated kitten!
用户标识 |
-返回字段说明:
+返回字段说明:
参数 |
@@ -2659,200 +3100,9 @@ Success — a happy kitten is an authenticated kitten!
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 请求
+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
-请求字段说明:
+请求字段说明:
参数 |
@@ -2996,6 +3246,197 @@ Success — a happy kitten is an authenticated kitten!
+
+返回的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示例:
@@ -3041,9 +3482,9 @@ Success — a happy kitten is an authenticated kitten!
curl -X GET http://localhost:3000/api/users/yystopf/applied_projects.json
await octokit.request('GET /api/users/:login/applied_projects.json')
-
HTTP 请求
+HTTP 请求
GET /api/users/:login/applied_projects.json
-请求字段说明:
+请求字段说明:
参数 |
@@ -3057,7 +3498,7 @@ Success — a happy kitten is an authenticated kitten!
用户标识 |
-返回字段说明:
+返回字段说明:
参数 |
@@ -3201,9 +3642,9 @@ Success — a happy kitten is an authenticated kitten!
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 请求
+HTTP 请求
GET /api/users/:login/applied_projects/:id/accept.json
-请求字段说明:
+请求字段说明:
参数 |
@@ -3222,7 +3663,7 @@ Success — a happy kitten is an authenticated kitten!
申请id |
-返回字段说明:
+返回字段说明:
参数 |
@@ -3360,9 +3801,9 @@ Success — a happy kitten is an authenticated kitten!
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 请求
+HTTP 请求
GET /api/users/:login/applied_projects/:id/refuse.json
-请求字段说明:
+请求字段说明:
参数 |
@@ -3381,7 +3822,7 @@ Success — a happy kitten is an authenticated kitten!
申请id |
-返回字段说明:
+返回字段说明:
参数 |
diff --git a/spec/models/message_template_spec.rb b/spec/models/message_template_spec.rb
new file mode 100644
index 000000000..8f1d26fcd
--- /dev/null
+++ b/spec/models/message_template_spec.rb
@@ -0,0 +1,5 @@
+require 'rails_helper'
+
+RSpec.describe MessageTemplate, type: :model do
+ pending "add some examples to (or delete) #{__FILE__}"
+end