| @@ -0,0 +1,26 @@ | |||||
| class Projects::AppliedTransferProjectsController < Projects::BaseController | |||||
| before_action :check_auth | |||||
| def organizations | |||||
| @organizations = Organization.includes(:organization_extension).joins(team_users: :team).where(team_users: {user_id: current_user.id}, teams: {authorize: %w(admin owner)}) | |||||
| end | |||||
| def create | |||||
| @applied_transfer_project = Projects::ApplyTransferService.call(current_user, @project, params) | |||||
| rescue Exception => e | |||||
| uid_logger_error(e.message) | |||||
| tip_exception(e.message) | |||||
| end | |||||
| def cancel | |||||
| @applied_transfer_project = Projects::CancelTransferService.call(current_user, @project) | |||||
| rescue Exception => e | |||||
| uid_logger_error(e.message) | |||||
| tip_exception(e.message) | |||||
| end | |||||
| private | |||||
| def check_auth | |||||
| return render_forbidden unless current_user.admin? ||@project.owner?(current_user) | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,18 @@ | |||||
| class Users::AppliedMessagesController < Users::BaseController | |||||
| before_action :check_auth | |||||
| after_action :view_messages, only: [:index] | |||||
| def index | |||||
| @applied_messages = @_observed_user.applied_messages.order(viewed: :asc, created_at: :desc) | |||||
| @applied_messages = paginate @applied_messages | |||||
| end | |||||
| private | |||||
| def check_auth | |||||
| return render_forbidden unless observed_logged_user? | |||||
| end | |||||
| def view_messages | |||||
| @applied_messages.update_all(viewed: 'viewed') | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,41 @@ | |||||
| class Users::AppliedTransferProjectsController < Users::BaseController | |||||
| before_action :check_auth | |||||
| before_action :find_applied_transfer_project, except: [:index] | |||||
| before_action :find_project, except: [:index] | |||||
| def index | |||||
| user_collection_sql = AppliedTransferProject.where(owner_id: @_observed_user.id).to_sql | |||||
| org_collection_sql = AppliedTransferProject.where(owner_id: Organization.joins(team_users: :team).where(team_users: {user_id: @_observed_user.id}, teams: {authorize: %w(admin owner)} )).to_sql | |||||
| @applied_transfer_projects = AppliedTransferProject.from("( #{ user_collection_sql } UNION #{ org_collection_sql } ) AS applied_transfer_projects") | |||||
| @applied_transfer_projects = paginate @applied_transfer_projects.order("created_at desc") | |||||
| end | |||||
| # 接受迁移 | |||||
| def accept | |||||
| @applied_transfer_project = Projects::AcceptTransferService.call(current_user, @project) | |||||
| rescue Exception => e | |||||
| uid_logger_error(e.message) | |||||
| tip_exception(e.message) | |||||
| end | |||||
| # 拒绝迁移 | |||||
| def refuse | |||||
| @applied_transfer_project = Projects::RefuseTransferService.call(current_user, @project) | |||||
| rescue Exception => e | |||||
| uid_logger_error(e.message) | |||||
| tip_exception(e.message) | |||||
| end | |||||
| private | |||||
| def check_auth | |||||
| return render_forbidden unless observed_logged_user? | |||||
| end | |||||
| def find_applied_transfer_project | |||||
| @applied_transfer_project = AppliedTransferProject.find_by_id params[:id] | |||||
| end | |||||
| def find_project | |||||
| @project = @applied_transfer_project.project | |||||
| end | |||||
| end | |||||
| @@ -27,11 +27,20 @@ class UsersController < ApplicationController | |||||
| def show | def show | ||||
| #待办事项,现在未做 | #待办事项,现在未做 | ||||
| @undo_events = 0 | |||||
| if User.current.login == @user.login | |||||
| @waiting_applied_messages = @user.applied_messages.waiting | |||||
| @common_applied_transfer_projects = AppliedTransferProject.where(owner_id: @user.id).common + AppliedTransferProject.where(owner_id: Organization.joins(team_users: :team).where(team_users: {user_id: @user.id}, teams: {authorize: %w(admin owner)} )).common | |||||
| @undo_events = @waiting_applied_messages.size + @common_applied_transfer_projects.size | |||||
| else | |||||
| @waiting_applied_messages = AppliedMessage.none | |||||
| @common_applied_transfer_projects = AppliedTransferProject.none | |||||
| @undo_events = 0 | |||||
| end | |||||
| #用户的组织数量 | #用户的组织数量 | ||||
| # @user_composes_count = @user.composes.size | # @user_composes_count = @user.composes.size | ||||
| @user_composes_count = 0 | @user_composes_count = 0 | ||||
| @user_org_count = User.current.logged? ? @user.organizations.with_visibility(%w(common limited)).size + @user.organizations.with_visibility("privacy").joins(:organization_users).where(organization_users: {user_id: current_user.id}).size : @user.organizations.with_visibility("common").size | |||||
| user_organizations = User.current.logged? ? @user.organizations.with_visibility(%w(common limited)) + @user.organizations.with_visibility("privacy").joins(:team_users).where(team_users: {user_id: current_user.id}) : @user.organizations.with_visibility("common") | |||||
| @user_org_count = user_organizations.size | |||||
| user_projects = User.current.logged? && (User.current.admin? || User.current.login == @user.login) ? @user.projects : @user.projects.visible | user_projects = User.current.logged? && (User.current.admin? || User.current.login == @user.login) ? @user.projects : @user.projects.visible | ||||
| @projects_common_count = user_projects.common.size | @projects_common_count = user_projects.common.size | ||||
| @projects_mirrior_count = user_projects.mirror.size | @projects_mirrior_count = user_projects.mirror.size | ||||
| @@ -526,3 +526,241 @@ await octokit.request('POST /api/jaser/jasder_test/forks.json') | |||||
| "identifier": "newadm" | "identifier": "newadm" | ||||
| } | } | ||||
| ``` | ``` | ||||
| ## 用户管理的组织列表 | |||||
| 用户管理的组织列表 | |||||
| > 示例: | |||||
| ```shell | |||||
| curl -X GET \ | |||||
| http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects/organizations.json | jq | |||||
| ``` | |||||
| ```javascript | |||||
| await octokit.request('GET /api/:owner/:repo/applied_transfer_projects/organizations') | |||||
| ``` | |||||
| ### HTTP 请求 | |||||
| `GET api/:owner/:repo/applied_transfer_projects/organizations` | |||||
| ### 请求参数 | |||||
| 参数 | 必选 | 默认 | 类型 | 字段说明 | |||||
| --------- | ------- | ------- | -------- | ---------- | |||||
| owner |是| |string |用户登录名 | |||||
| repo |是| |string |项目标识identifier | |||||
| ### 返回字段说明 | |||||
| 参数 | 类型 | 字段说明 | |||||
| --------- | ----------- | ----------- | |||||
| name |string|组织标识 | |||||
| nickname |string|组织名称 | |||||
| description|string|组织描述 | |||||
| avatar_url|string|组织头像 | |||||
| > 返回的JSON示例: | |||||
| ```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" | |||||
| } | |||||
| ] | |||||
| } | |||||
| ``` | |||||
| ## 迁移项目 | |||||
| 迁移项目,edit接口is_transfering为true表示正在迁移 | |||||
| > 示例: | |||||
| ```shell | |||||
| curl -X POST http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects.json | |||||
| ``` | |||||
| ```javascript | |||||
| await octokit.request('POST /api/:owner/:repo/applied_transfer_projects.json') | |||||
| ``` | |||||
| ### HTTP 请求 | |||||
| `POST /api/:owner/:repo/applied_transfer_projects.json` | |||||
| ### 请求参数 | |||||
| 参数 | 必选 | 默认 | 类型 | 字段说明 | |||||
| --------- | ------- | ------- | -------- | ---------- | |||||
| |owner |是| |string |用户登录名 | | |||||
| |repo |是| |string |项目标识identifier | | |||||
| |owner_name|是| |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示例: | |||||
| ```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分钟前" | |||||
| } | |||||
| ``` | |||||
| ## 取消迁移项目 | |||||
| 迁移项目,edit接口is_transfering为true表示正在迁移 | |||||
| > 示例: | |||||
| ```shell | |||||
| curl -X POST http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects/cancel.json | |||||
| ``` | |||||
| ```javascript | |||||
| await octokit.request('POST /api/:owner/:repo/applied_transfer_projects/cancel.json') | |||||
| ``` | |||||
| ### HTTP 请求 | |||||
| `POST /api/:owner/:repo/applied_transfer_projects/cancel.json` | |||||
| ### 请求参数 | |||||
| 参数 | 必选 | 默认 | 类型 | 字段说明 | |||||
| --------- | ------- | ------- | -------- | ---------- | |||||
| |owner |是| |string |用户登录名 | | |||||
| |repo |是| |string |项目标识identifier | | |||||
| ### 返回字段说明 | |||||
| 参数 | 类型 | 字段说明 | |||||
| --------- | ----------- | ----------- | |||||
| |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示例: | |||||
| ```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分钟前" | |||||
| } | |||||
| ``` | |||||
| @@ -1,3 +1,9 @@ | |||||
| <!-- | |||||
| * @Date: 2021-03-01 10:35:21 | |||||
| * @LastEditors: viletyy | |||||
| * @LastEditTime: 2021-04-26 10:47:30 | |||||
| * @FilePath: /forgeplus/app/docs/slate/source/includes/_users.md | |||||
| --> | |||||
| # Users | # Users | ||||
| ## 获取当前登陆用户信息 | ## 获取当前登陆用户信息 | ||||
| @@ -40,3 +46,390 @@ await octokit.request('GET /api/users/me.json') | |||||
| <aside class="success"> | <aside class="success"> | ||||
| Success Data. | Success Data. | ||||
| </aside> | </aside> | ||||
| ## 待办事项-用户通知信息 | |||||
| 待办事项-用户通知信息 | |||||
| > 示例: | |||||
| ```shell | |||||
| curl -X GET http://localhost:3000/api/users/yystopf/applied_messages.json | |||||
| ``` | |||||
| ```javascript | |||||
| 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.owner.id |int |通知主体的迁移接受者的id | | |||||
| |applied.owner.type |string |通知主体的迁移接受者的类型 | | |||||
| |applied.owner.name |string |通知主体的迁移接受者的名称 | | |||||
| |applied.owner.login |string |通知主体的迁移接受者的标识 | | |||||
| |applied.owner.image_url |string |通知主体的迁移接受者头像 | | |||||
| |applied_type |string |通知类型 | | |||||
| |name |string | 通知内容 | | |||||
| |viewed |string|是否已读,waiting:未读,viewed:已读| | |||||
| |status |string|通知状态, canceled:已取消,common: 正常,successed:成功,failure:失败| | |||||
| |time_ago |string|通知时间| | |||||
| > 返回的JSON示例: | |||||
| ```json | |||||
| { | |||||
| "total_count": 5, | |||||
| "applied_messages": [ | |||||
| { | |||||
| "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分钟前" | |||||
| }, | |||||
| ... | |||||
| ] | |||||
| } | |||||
| ``` | |||||
| ## 待办事项-接受仓库 | |||||
| 待办事项-接受仓库 | |||||
| > 示例: | |||||
| ```shell | |||||
| curl -X GET http://localhost:3000/api/users/yystopf/applied_transfer_projects.json | |||||
| ``` | |||||
| ```javascript | |||||
| 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示例: | |||||
| ```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小时前" | |||||
| }, | |||||
| ... | |||||
| ] | |||||
| } | |||||
| ``` | |||||
| ## 用户接受迁移 | |||||
| 用户接受迁移 | |||||
| > 示例: | |||||
| ```shell | |||||
| curl -X POST http://localhost:3000/api/users/yystopf/applied_transfer_projects/2/accept.json | |||||
| ``` | |||||
| ```javascript | |||||
| 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示例: | |||||
| ```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小时前" | |||||
| } | |||||
| ``` | |||||
| ## 用户拒绝迁移 | |||||
| 用户拒绝迁移 | |||||
| > 示例: | |||||
| ```shell | |||||
| curl -X POST http://localhost:3000/api/users/yystopf/applied_transfer_projects/2/refuse.json | |||||
| ``` | |||||
| ```javascript | |||||
| 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示例: | |||||
| ```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小时前" | |||||
| } | |||||
| ``` | |||||
| @@ -0,0 +1,47 @@ | |||||
| class SendTransferProjectAppliedMessageJob < ApplicationJob | |||||
| queue_as :default | |||||
| def perform(applied_transfer_project, applied_user, message_status) | |||||
| project = applied_transfer_project.project | |||||
| owner = project.owner | |||||
| return unless project.present? | |||||
| return unless owner.present? | |||||
| if owner.is_a?(Organization) | |||||
| receivers = project.managers + owner.team_users.joins(:team).where(teams: {authorize: %w(owner admin)}) | |||||
| else | |||||
| receivers = project.managers | |||||
| end | |||||
| receivers.each do |rec| | |||||
| next if applied_user.id == rec.user_id # 自己不要给自己发通知 | |||||
| AppliedMessage.create!(user_id: rec.user_id, | |||||
| applied: applied_transfer_project, | |||||
| status: message_status, | |||||
| name: build_name(project.name, applied_transfer_project&.owner&.real_name, message_status, applied_user&.real_name), | |||||
| applied_user_id: applied_user.id, | |||||
| project_id: project.id) | |||||
| end | |||||
| if message_status == 'successed' # 如果转移成功,给转移发起者发通知已转移成功 | |||||
| AppliedMessage.find_or_create_by!(user_id: applied_transfer_project.user_id, | |||||
| applied: applied_transfer_project, | |||||
| status: message_status, | |||||
| name: build_name(project.name, applied_transfer_project&.owner&.real_name, message_status), | |||||
| applied_user_id: applied_user.id, | |||||
| project_id: project.id) | |||||
| end | |||||
| end | |||||
| private | |||||
| def build_name(repo_name, owner_name, message_status, applied_name="") | |||||
| case message_status | |||||
| when 'canceled' | |||||
| return "取消转移【#{repo_name}】仓库" | |||||
| when 'common' | |||||
| return "正在将【#{repo_name}】仓库转移给【#{owner_name}】" | |||||
| when 'successed' | |||||
| return "【#{repo_name}】仓库成功转移给【#{owner_name}】" | |||||
| when 'failure' | |||||
| return "拒绝转移【#{repo_name}】仓库" | |||||
| end | |||||
| "" | |||||
| end | |||||
| end | |||||
| @@ -19,5 +19,10 @@ | |||||
| class AppliedMessage < ApplicationRecord | class AppliedMessage < ApplicationRecord | ||||
| belongs_to :user | belongs_to :user | ||||
| belongs_to :applied, polymorphic: true | belongs_to :applied, polymorphic: true | ||||
| belongs_to :project | |||||
| belongs_to :applied_user, class_name: 'User' | |||||
| enum viewed: {waiting: 0, viewed: 1} | |||||
| enum status: {canceled: -1, common: 0, successed: 1, failure: 2} # -1 已取消 0 正在操作 1 操作成功 2 操作失败 | |||||
| end | end | ||||
| @@ -0,0 +1,28 @@ | |||||
| # == Schema Information | |||||
| # | |||||
| # Table name: applied_transfer_projects | |||||
| # | |||||
| # id :integer not null, primary key | |||||
| # project_id :integer | |||||
| # owner_id :integer | |||||
| # user_id :integer | |||||
| # status :integer default("0") | |||||
| # created_at :datetime not null | |||||
| # updated_at :datetime not null | |||||
| # | |||||
| # Indexes | |||||
| # | |||||
| # index_applied_transfer_projects_on_owner_id (owner_id) | |||||
| # index_applied_transfer_projects_on_project_id (project_id) | |||||
| # index_applied_transfer_projects_on_user_id (user_id) | |||||
| # | |||||
| class AppliedTransferProject < ApplicationRecord | |||||
| belongs_to :project | |||||
| belongs_to :user # 操作者 | |||||
| belongs_to :owner # 接收个人或组织 | |||||
| has_many :applied_messages, as: :applied, dependent: :destroy | |||||
| enum status: {canceled: -1, common: 0, accepted: 1, refused: 2} # -1 已取消 0 待操作 1 已接收 2 已拒绝 | |||||
| end | |||||
| @@ -66,4 +66,6 @@ class Owner < ApplicationRecord | |||||
| has_many :projects, foreign_key: :user_id, dependent: :destroy | has_many :projects, foreign_key: :user_id, dependent: :destroy | ||||
| has_many :repositories, foreign_key: :user_id, dependent: :destroy | has_many :repositories, foreign_key: :user_id, dependent: :destroy | ||||
| has_many :applied_transfer_projects, dependent: :destroy | |||||
| end | end | ||||
| @@ -112,6 +112,7 @@ class Project < ApplicationRecord | |||||
| has_one :project_detail, dependent: :destroy | has_one :project_detail, dependent: :destroy | ||||
| has_many :team_projects, dependent: :destroy | has_many :team_projects, dependent: :destroy | ||||
| has_many :project_units, dependent: :destroy | has_many :project_units, dependent: :destroy | ||||
| has_one :applied_transfer_project,-> { order created_at: :desc }, dependent: :destroy | |||||
| after_save :check_project_members | after_save :check_project_members | ||||
| 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 :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)} | ||||
| @@ -295,4 +296,7 @@ class Project < ApplicationRecord | |||||
| update_column(:updated_on, time) | update_column(:updated_on, time) | ||||
| end | end | ||||
| def is_transfering | |||||
| applied_transfer_project&.common? ? true : false | |||||
| end | |||||
| end | end | ||||
| @@ -148,9 +148,11 @@ class User < Owner | |||||
| has_many :trail_auth_apply_actions, -> { where(container_type: 'TrialAuthorization') }, class_name: 'ApplyAction' | has_many :trail_auth_apply_actions, -> { where(container_type: 'TrialAuthorization') }, class_name: 'ApplyAction' | ||||
| # has_many :attendances | # has_many :attendances | ||||
| has_many :applied_messages, dependent: :destroy | |||||
| has_many :operate_applied_messages, class_name: 'AppliedMessage', dependent: :destroy | |||||
| # 项目 | # 项目 | ||||
| has_many :applied_projects, dependent: :destroy | has_many :applied_projects, dependent: :destroy | ||||
| has_many :operate_applied_transfer_projects, class_name: 'AppliedTransferProject', dependent: :destroy | |||||
| # 教学案例 | # 教学案例 | ||||
| # has_many :libraries, dependent: :destroy | # has_many :libraries, dependent: :destroy | ||||
| @@ -0,0 +1,49 @@ | |||||
| class Projects::AcceptTransferService < ApplicationService | |||||
| attr_accessor :applied_transfer_project, :owner | |||||
| attr_reader :user, :project | |||||
| def initialize(user, project) | |||||
| @user = user | |||||
| @project = project | |||||
| @applied_transfer_project = project.applied_transfer_project | |||||
| @owner = @applied_transfer_project.owner | |||||
| end | |||||
| def call | |||||
| Rails.logger.info("###### Project accept_transfer_service begin ######") | |||||
| ActiveRecord::Base.transaction do | |||||
| validate! | |||||
| update_apply | |||||
| operate_project | |||||
| send_apply_message | |||||
| end | |||||
| Rails.logger.info("##### Project accept_transfer_service end ######") | |||||
| return @applied_transfer_project | |||||
| end | |||||
| private | |||||
| def validate! | |||||
| raise Error, '该仓库未在迁移' unless @applied_transfer_project.present? && @project.is_transfering | |||||
| raise Error, '未拥有接受转移权限' unless is_permit_operator | |||||
| end | |||||
| def is_permit_operator | |||||
| return true if @user == @owner | |||||
| return @owner.is_a?(Organization) && @owner.is_admin?(@user) | |||||
| end | |||||
| def update_apply | |||||
| @applied_transfer_project.update!(status: 'accepted') | |||||
| end | |||||
| def operate_project | |||||
| @project = Projects::TransferService.call(@project, @owner) | |||||
| end | |||||
| def send_apply_message | |||||
| SendTransferProjectAppliedMessageJob.perform_now(@applied_transfer_project, @user, 'successed') | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,43 @@ | |||||
| class Projects::ApplyTransferService < ApplicationService | |||||
| attr_accessor :owner, :applied_transfer_project | |||||
| attr_reader :user, :project, :params | |||||
| def initialize(user, project, params) | |||||
| @user = user | |||||
| @project = project | |||||
| @params = params | |||||
| @owner = Owner.find_by(login: params[:owner_name]) | |||||
| end | |||||
| def call | |||||
| Rails.logger.info("###### Project apply_transfer_service begin ######") | |||||
| validate! | |||||
| create_apply | |||||
| send_apply_message | |||||
| Rails.logger.info("###### Project apply_transfer_service end ######") | |||||
| return @applied_transfer_project | |||||
| end | |||||
| private | |||||
| def validate! | |||||
| raise Error, '仓库标识不正确' if @project.identifier != params[:identifier] | |||||
| raise Error, '该仓库正在迁移' if @project.is_transfering | |||||
| raise Error, '新拥有者不存在' unless @owner.present? | |||||
| raise Error, '新拥有者已经存在同名仓库!' if Project.where(user_id: @owner.id, identifier: params[:identifier]).present? | |||||
| raise Error, '未拥有转移权限' unless is_permit_owner | |||||
| end | |||||
| def is_permit_owner | |||||
| return true unless @owner.is_a?(Organization) | |||||
| return @owner.is_owner?(@user) | |||||
| end | |||||
| def create_apply | |||||
| @applied_transfer_project = AppliedTransferProject.create!(user_id: user.id, project_id: project.id, owner_id: @owner.id) | |||||
| end | |||||
| def send_apply_message | |||||
| SendTransferProjectAppliedMessageJob.perform_now(@applied_transfer_project, @user, 'common') | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,33 @@ | |||||
| class Projects::CancelTransferService < ApplicationService | |||||
| attr_accessor :applied_transfer_project | |||||
| attr_reader :user, :project | |||||
| def initialize(user, project) | |||||
| @user = user | |||||
| @project = project | |||||
| @applied_transfer_project = project.applied_transfer_project | |||||
| end | |||||
| def call | |||||
| Rails.logger.info("###### Project cancel_transfer_service begin ######") | |||||
| validate! | |||||
| update_apply | |||||
| send_apply_message | |||||
| Rails.logger.info("###### Project cancel_transfer_service end ######") | |||||
| return @applied_transfer_project | |||||
| end | |||||
| private | |||||
| def validate! | |||||
| raise Error, '该仓库未在迁移' unless @applied_transfer_project.present? && @project.is_transfering | |||||
| end | |||||
| def update_apply | |||||
| @applied_transfer_project.update!(status: 'canceled') | |||||
| end | |||||
| def send_apply_message | |||||
| SendTransferProjectAppliedMessageJob.perform_now(@applied_transfer_project, @user, 'canceled') | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,40 @@ | |||||
| class Projects::RefuseTransferService < ApplicationService | |||||
| attr_accessor :applied_transfer_project, :owner | |||||
| attr_reader :user, :project | |||||
| def initialize(user, project) | |||||
| @user = user | |||||
| @project = project | |||||
| @applied_transfer_project = project.applied_transfer_project | |||||
| @owner = @applied_transfer_project.owner | |||||
| end | |||||
| def call | |||||
| Rails.logger.info("###### Project refuse_transfer_service begin ######") | |||||
| validate! | |||||
| update_apply | |||||
| send_apply_message | |||||
| Rails.logger.info("###### Project refuse_transfer_service end ######") | |||||
| return @applied_transfer_project | |||||
| end | |||||
| private | |||||
| def validate! | |||||
| raise Error, '该仓库未在迁移' unless @applied_transfer_project.present? && @project.is_transfering | |||||
| raise Error, '未拥有拒绝转移权限' unless is_permit_operator | |||||
| end | |||||
| def is_permit_operator | |||||
| return true if @user == @owner | |||||
| return @owner.is_a?(Organization) && @owner.is_admin?(@user) | |||||
| end | |||||
| def update_apply | |||||
| @applied_transfer_project.update!(status: 'refused') | |||||
| end | |||||
| def send_apply_message | |||||
| SendTransferProjectAppliedMessageJob.perform_now(@applied_transfer_project, @user, 'failure') | |||||
| end | |||||
| end | |||||
| @@ -23,6 +23,7 @@ class Projects::TransferService < ApplicationService | |||||
| private | private | ||||
| def update_owner | def update_owner | ||||
| project.members.find_by(user_id: owner.id).destroy! if owner.is_a?(User) | |||||
| project.update!(user_id: new_owner.id) | project.update!(user_id: new_owner.id) | ||||
| end | end | ||||
| @@ -0,0 +1,5 @@ | |||||
| json.id organization.id | |||||
| json.name organization.login | |||||
| json.nickname organization.nickname.blank? ? organization.name : organization.nickname | |||||
| json.description organization.description | |||||
| json.avatar_url url_to_avatar(organization) | |||||
| @@ -0,0 +1,21 @@ | |||||
| project = object.project | |||||
| json.project do | |||||
| json.id project.id | |||||
| json.identifier project.identifier | |||||
| json.name project.name | |||||
| json.description project.description | |||||
| json.is_public project.is_public | |||||
| json.owner do | |||||
| json.partial! "/users/user_simple", locals: {user: project.owner} | |||||
| end | |||||
| end | |||||
| json.user do | |||||
| json.partial! "/users/user_simple", locals: {user: object.user} | |||||
| end | |||||
| json.owner do | |||||
| json.partial! "/users/user_simple", locals: {user: object.owner} | |||||
| end | |||||
| json.id object.id | |||||
| json.status object.status | |||||
| json.created_at format_time(object.created_at) | |||||
| json.time_ago time_from_now(object.created_at) | |||||
| @@ -0,0 +1 @@ | |||||
| json.partial! "/projects/applied_transfer_projects/detail", locals: {object: @applied_transfer_project} | |||||
| @@ -0,0 +1 @@ | |||||
| json.partial! "/projects/applied_transfer_projects/detail", locals: {object: @applied_transfer_project} | |||||
| @@ -0,0 +1,4 @@ | |||||
| json.total_count @organizations.size | |||||
| json.organizations @organizations do |org| | |||||
| json.partial! "/organizations/organizations/simple", locals: {organization: org} | |||||
| end | |||||
| @@ -7,4 +7,9 @@ json.project_language_id @project.project_language_id | |||||
| json.private !@project.is_public | json.private !@project.is_public | ||||
| json.website @project.website | json.website @project.website | ||||
| json.project_units @project.project_units.pluck(:unit_type) | json.project_units @project.project_units.pluck(:unit_type) | ||||
| json.lesson_url @project.lesson_url | |||||
| json.lesson_url @project.lesson_url | |||||
| json.permission render_permission(current_user, @project) | |||||
| json.is_transfering @project.is_transfering | |||||
| json.transfer do | |||||
| json.partial! "/users/user_simple", locals: {user: @project&.applied_transfer_project&.owner} | |||||
| end | |||||
| @@ -1,4 +1,9 @@ | |||||
| json.id user.id | |||||
| json.name user.real_name | |||||
| json.login user.login | |||||
| json.image_url url_to_avatar(user) | |||||
| if user.present? | |||||
| json.id user.id | |||||
| json.type user.type | |||||
| json.name user.real_name | |||||
| json.login user.login | |||||
| json.image_url url_to_avatar(user) | |||||
| else | |||||
| json.nil! | |||||
| end | |||||
| @@ -0,0 +1,26 @@ | |||||
| # project = object.project | |||||
| # json.project do | |||||
| # json.id project.id | |||||
| # json.identifier project.identifier | |||||
| # json.name project.name | |||||
| # json.description project.description | |||||
| # json.is_public project.is_public | |||||
| # json.owner do | |||||
| # json.partial! "/users/user_simple", locals: {user: project.owner} | |||||
| # end | |||||
| # end | |||||
| # json.user do | |||||
| # json.partial! "/users/user_simple", locals: {user: object.user} | |||||
| # end | |||||
| json.applied do | |||||
| json.partial! "/projects/applied_transfer_projects/detail", locals: {object: object.applied} | |||||
| end | |||||
| json.applied_user do | |||||
| json.partial! "/users/user_simple", locals: {user: object.applied_user} | |||||
| end | |||||
| json.applied_type object.applied_type | |||||
| json.name object.name | |||||
| json.viewed object.viewed | |||||
| json.status object.status | |||||
| json.created_at format_time(object.created_at) | |||||
| json.time_ago time_from_now(object.created_at) | |||||
| @@ -0,0 +1,4 @@ | |||||
| json.total_count @applied_messages.total_count | |||||
| json.applied_messages @applied_messages do |message| | |||||
| json.partial! "/users/applied_messages/detail", locals: {object: message} | |||||
| end | |||||
| @@ -0,0 +1 @@ | |||||
| json.partial! "/projects/applied_transfer_projects/detail", locals: {object: @applied_transfer_project} | |||||
| @@ -0,0 +1,4 @@ | |||||
| json.total_count @applied_transfer_projects.total_count | |||||
| json.applied_transfer_projects @applied_transfer_projects do |apply| | |||||
| json.partial! "/projects/applied_transfer_projects/detail", locals: {object: apply} | |||||
| end | |||||
| @@ -0,0 +1 @@ | |||||
| json.partial! "/projects/applied_transfer_projects/detail", locals: {object: @applied_transfer_project} | |||||
| @@ -10,6 +10,8 @@ json.user_identity @user.identity | |||||
| json.is_watch current_user&.watched?(@user) | json.is_watch current_user&.watched?(@user) | ||||
| json.watched_count @user.fan_count #粉丝 | json.watched_count @user.fan_count #粉丝 | ||||
| json.watching_count @user.follow_count #关注数 | json.watching_count @user.follow_count #关注数 | ||||
| json.undo_messages @waiting_applied_messages.size | |||||
| json.undo_transfer_projects @common_applied_transfer_projects.size | |||||
| json.undo_events @undo_events | json.undo_events @undo_events | ||||
| json.user_composes_count @user_composes_count | json.user_composes_count @user_composes_count | ||||
| json.user_org_count @user_org_count | json.user_org_count @user_org_count | ||||
| @@ -257,6 +257,13 @@ Rails.application.routes.draw do | |||||
| end | end | ||||
| scope module: :users do | scope module: :users do | ||||
| resources :applied_messages, only: [:index] | |||||
| resources :applied_transfer_projects, only: [:index] do | |||||
| member do | |||||
| post :accept | |||||
| post :refuse | |||||
| end | |||||
| end | |||||
| resources :organizations, only: [:index] | resources :organizations, only: [:index] | ||||
| # resources :projects, only: [:index] | # resources :projects, only: [:index] | ||||
| # resources :subjects, only: [:index] | # resources :subjects, only: [:index] | ||||
| @@ -533,6 +540,12 @@ Rails.application.routes.draw do | |||||
| scope module: :projects do | scope module: :projects do | ||||
| resources :teams, only: [:index, :create, :destroy] | resources :teams, only: [:index, :create, :destroy] | ||||
| resources :project_units, only: [:index, :create] | resources :project_units, only: [:index, :create] | ||||
| resources :applied_transfer_projects, only: [:create] do | |||||
| collection do | |||||
| get :organizations | |||||
| post :cancel | |||||
| end | |||||
| end | |||||
| scope do | scope do | ||||
| get( | get( | ||||
| '/blob/*id/diff', | '/blob/*id/diff', | ||||
| @@ -0,0 +1,12 @@ | |||||
| class CreateAppliedTransferProjects < ActiveRecord::Migration[5.2] | |||||
| def change | |||||
| create_table :applied_transfer_projects do |t| | |||||
| t.references :project | |||||
| t.references :owner | |||||
| t.references :user | |||||
| t.integer :status, default: 0 | |||||
| t.timestamps | |||||
| end | |||||
| end | |||||
| end | |||||