diff --git a/app/controllers/projects/project_units_controller.rb b/app/controllers/projects/project_units_controller.rb new file mode 100644 index 000000000..ddb90fce2 --- /dev/null +++ b/app/controllers/projects/project_units_controller.rb @@ -0,0 +1,20 @@ +class Projects::ProjectUnitsController < Projects::BaseController + def create + if current_user.admin? || @project.owner?(current_user) + ActiveRecord::Base.transaction do + ProjectUnit.update_by_unit_types!(@project, unit_types) + render_ok + end + else + render_forbidden('你没有权限操作') + end + rescue Exception => e + uid_logger_error(e.message) + tip_exception(e.message) + end + + private + def unit_types + params.fetch(:unit_types, []) + end +end \ No newline at end of file diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 5358a554e..573dbba80 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -2,11 +2,26 @@ class ProjectsController < ApplicationController include ApplicationHelper include OperateProjectAbilityAble include ProjectsHelper - before_action :require_login, except: %i[index branches group_type_list simple show fork_users praise_users watch_users recommend about] + before_action :require_login, except: %i[index branches group_type_list simple show fork_users praise_users watch_users recommend about menu_list] before_action :load_project, except: %i[index group_type_list migrate create recommend] before_action :authorizate_user_can_edit_project!, only: %i[update] before_action :project_public?, only: %i[fork_users praise_users watch_users] + def menu_list + menu = [] + + menu.append(menu_hash_by_name("home")) + menu.append(menu_hash_by_name("code")) if @project.has_menu_permission("code") + menu.append(menu_hash_by_name("issues")) if @project.has_menu_permission("issues") + menu.append(menu_hash_by_name("pulls")) if @project.has_menu_permission("pulls") + menu.append(menu_hash_by_name("devops")) if @project.has_menu_permission("devops") + menu.append(menu_hash_by_name("versions")) if @project.has_menu_permission("versions") + menu.append(menu_hash_by_name("activity")) + menu.append(menu_hash_by_name("setting")) if current_user.admin? || @project.owner?(current_user) + + render json: menu + end + def index scope = Projects::ListQuery.call(params) diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb index 5fb7b7681..3410ddb3e 100644 --- a/app/controllers/repositories_controller.rb +++ b/app/controllers/repositories_controller.rb @@ -11,10 +11,8 @@ class RepositoriesController < ApplicationController before_action :get_latest_commit, only: %i[entries sub_entries top_counts] before_action :get_statistics, only: %i[top_counts] - - def files - result = @project.educoder? ? nil : Gitea::Repository::Files::GetService.call(@project.owner, @project.identifier, @ref) + result = @project.educoder? ? nil : Gitea::Repository::Files::GetService.call(@owner, @project.identifier, @ref, params[:search], @owner.gitea_token) render json: result end diff --git a/app/docs/slate/source/includes/_projects.md b/app/docs/slate/source/includes/_projects.md index 1fbbd0dab..0e2fc13fd 100644 --- a/app/docs/slate/source/includes/_projects.md +++ b/app/docs/slate/source/includes/_projects.md @@ -168,6 +168,55 @@ Remember — a happy kitten is an authenticated kitten! +## 项目导航 +获取项目导航信息 + +> 示例: + +```shell +curl -X GET \ +http://localhost:3000/api/yystopf/ceshi/menu_list | jq +``` + +```javascript +await octokit.request('GET /api/yystopf/ceshi/menu_list') +``` + +### HTTP 请求 +`GET api/:owner/:repo/menu_list` + +### 请求参数 +参数 | 必选 | 默认 | 类型 | 字段说明 +--------- | ------- | ------- | -------- | ---------- +owner |是| |string |用户登录名 +repo |是| |string |项目标识identifier + +### 返回字段说明 +参数 | 类型 | 字段说明 +--------- | ----------- | ----------- +menu_name |string|导航名称, home:主页,code:代码库,issues:易修,pulls:合并请求,devops:工作流,versions:里程碑,activity:动态,setting:仓库设置 + + +> 返回的JSON示例: + +```json +[ + { + "menu_name": "home" + }, + { + "menu_name": "code" + }, + { + "menu_name": "pulls" + }, + { + "menu_name": "activity" + } +] +``` + + ## 项目主页 获取项目主页信息 @@ -212,6 +261,46 @@ attachments |array|附件 Remember — a happy kitten is an authenticated kitten! +## 更改项目导航 +更改项目导航信息 + +> 示例: + +```shell +curl -X POST \ +-H "accept: application/json" \ +-H "Content-Type: application/json" \ +-d "{ \"unit_typs\": [\"code\", \"pulls\"]}" \ +http://localhost:3000/api/yystopf/ceshi/project_units.json +``` + +```javascript +await octokit.request('POST /api/yystopf/ceshi/project_units') +``` + +### HTTP 请求 +`POST /api/yystopf/ceshi/project_units` + +### 请求参数 +参数 | 必选 | 默认 | 类型 | 字段说明 +--------- | ------- | ------- | -------- | ---------- +|unit_types |是| |array | 项目模块内容, 支持以下参数:code:代码库,issues:易修,pulls:合并请求,devops:工作流,versions:里程碑 | + + +### 返回字段说明: +参数 | 类型 | 字段说明 +--------- | ----------- | ----------- +|status |int|返回状态, 0: 表示操作成功 | +|message |string|返回信息说明| + +> 返回的JSON示例: + +```json +{ + "status": 0, + "message": "success" +} +``` ## 创建项目 创建项目 diff --git a/app/docs/slate/source/includes/_repositories.md b/app/docs/slate/source/includes/_repositories.md index 862e96cea..40d3ba2ff 100644 --- a/app/docs/slate/source/includes/_repositories.md +++ b/app/docs/slate/source/includes/_repositories.md @@ -129,11 +129,11 @@ await octokit.request('GET /api/yystopf/ceshi/detail.json') |identifier |string |项目标识 | |name |string |项目名称 | |issues_count |int |项目issue数量| -|pull_requests_count |int |项目issue数量| -|project_identifier |int |项目issue数量| -|praises_count |int |项目issue数量| -|forked_count |int |项目issue数量| -|watchers_count |int |项目issue数量| +|pull_requests_count |int |项目合并请求数量| +|project_identifier |int |项目标识| +|praises_count |int |项目点赞数量| +|forked_count |int |项目复刻数量| +|watchers_count |int |项目关注数量| |versions_count |int |项目里程碑数量| |version_releases_count |int |项目发行版数量| |version_releasesed_count |int |项目发行版已发行数量| @@ -645,7 +645,9 @@ await octokit.request('GET /api/jasder/jasder_test/collaborators.json') > 示例: ```shell -curl -X GET http://localhost:3000/api/yystopf/ceshi/files.json +curl -X GET \ +-d "ref=develop" \ +http://localhost:3000/api/yystopf/ceshi/files.json ``` ```javascript @@ -658,8 +660,10 @@ await octokit.request('GET /api/yystopf/ceshi/files.json') ### 请求参数: 参数 | 必选 | 默认 | 类型 | 字段说明 --------- | ------- | ------- | -------- | ---------- -|owner |是| |string |用户登录名 | -|repo |是| |string |项目标识identifier | +|owner |是| |string |用户登录名 | +|repo |是| |string |项目标识identifier | +|search |否| |string |文件搜索关键词 | +|ref |是| |string |分支名,默认为仓库默认分支 | ### 返回字段说明: diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 6fbc22eb5..b212b50e4 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -1,4 +1,9 @@ module ProjectsHelper + def menu_hash_by_name(name) + { + menu_name: name + } + end def render_zh_project_type(project_type) case project_type diff --git a/app/models/concerns/project_operable.rb b/app/models/concerns/project_operable.rb index 5e8bf43d9..e151613d5 100644 --- a/app/models/concerns/project_operable.rb +++ b/app/models/concerns/project_operable.rb @@ -89,4 +89,7 @@ module ProjectOperable member.member_roles.create!(role: role) end + def has_menu_permission(unit_type) + self.project_units.where(unit_type: unit_type).exists? + end end diff --git a/app/models/project.rb b/app/models/project.rb index 5b05def1c..cde2f1011 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -113,6 +113,7 @@ class Project < ApplicationRecord has_and_belongs_to_many :trackers, :order => "#{Tracker.table_name}.position" has_one :project_detail, dependent: :destroy has_many :team_projects, dependent: :destroy + has_many :project_units, dependent: :destroy 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)} diff --git a/app/models/project_unit.rb b/app/models/project_unit.rb new file mode 100644 index 000000000..b5b4fe290 --- /dev/null +++ b/app/models/project_unit.rb @@ -0,0 +1,35 @@ +# == Schema Information +# +# Table name: project_units +# +# id :integer not null, primary key +# project_id :integer +# unit_type :integer +# created_at :datetime not null +# updated_at :datetime not null +# +# Indexes +# +# index_project_units_on_project_id (project_id) +# + +class ProjectUnit < ApplicationRecord + belongs_to :project + + enum unit_type: {code: 1, issues: 2, pulls: 3, devops: 4, versions: 5} + + validates :unit_type, uniqueness: { scope: :project_id} + + def self.init_types(project_id) + ProjectUnit::unit_types.each do |_, v| + self.create!(project_id: project_id, unit_type: v) + end + end + + def self.update_by_unit_types!(project, types) + project.project_units.where.not(unit_type: types).each(&:destroy!) + types.each do |type| + project.project_units.find_or_create_by!(unit_type: type) + end + end +end diff --git a/app/services/projects/create_service.rb b/app/services/projects/create_service.rb index 25053e953..c6e5b213b 100644 --- a/app/services/projects/create_service.rb +++ b/app/services/projects/create_service.rb @@ -13,6 +13,7 @@ class Projects::CreateService < ApplicationService ActiveRecord::Base.transaction do if @project.save! Project.update_common_projects_count! + ProjectUnit.init_types(@project.id) Repositories::CreateService.new(user, @project, repository_params).call else Rails.logger.info("#############___________create_project_erros______###########{@project.errors.messages}") diff --git a/config/routes.rb b/config/routes.rb index 9aed0ca5e..27af236a5 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -369,6 +369,7 @@ Rails.application.routes.draw do resource :projects, path: '/', except: [:show, :edit] do member do + get :menu_list get :branches get :simple get :watchers, to: 'projects#watch_users' @@ -528,6 +529,7 @@ Rails.application.routes.draw do scope module: :projects do resources :teams, only: [:index, :create, :destroy] + resources :project_units, only: [:create] scope do get( '/blob/*id/diff', diff --git a/db/migrate/20210317012035_create_project_units.rb b/db/migrate/20210317012035_create_project_units.rb new file mode 100644 index 000000000..6b89154f9 --- /dev/null +++ b/db/migrate/20210317012035_create_project_units.rb @@ -0,0 +1,10 @@ +class CreateProjectUnits < ActiveRecord::Migration[5.2] + def change + create_table :project_units do |t| + t.references :project + t.integer :unit_type + + t.timestamps + end + end +end diff --git a/public/docs/api.html b/public/docs/api.html index 64f96b9f3..0f67e27c5 100644 --- a/public/docs/api.html +++ b/public/docs/api.html @@ -342,9 +342,15 @@
  • 推荐项目
  • +
  • + 项目导航 +
  • 项目主页
  • +
  • + 更改项目导航 +
  • 创建项目
  • @@ -972,17 +978,17 @@ http://localhost:3000/api/projects/recommend | jq -

    项目主页

    -

    获取项目主页信息

    +

    项目导航

    +

    获取项目导航信息

    示例:

    curl -X GET \
    -http://localhost:3000/api/jasder/forgeplus/about  | jq
    -
    await octokit.request('GET /api/jasder/forgeplus/about')
    +http://localhost:3000/api/yystopf/ceshi/menu_list  | jq
    +
    await octokit.request('GET /api/yystopf/ceshi/menu_list')
     

    HTTP 请求

    -

    GET api/:owner/:repo/about

    +

    GET api/:owner/:repo/menu_list

    请求参数

    @@ -1017,6 +1023,74 @@ http://localhost:3000/api/jasder/forgeplus/about | jq + + + + +
    menu_namestring导航名称, home:主页,code:代码库,issues:易修,pulls:合并请求,devops:工作流,versions:里程碑,activity:动态,setting:仓库设置
    + +
    +

    返回的JSON示例:

    +
    +
    [
    +    {
    +        "menu_name": "home"
    +    },
    +    {
    +        "menu_name": "code"
    +    },
    +    {
    +        "menu_name": "pulls"
    +    },
    +    {
    +        "menu_name": "activity"
    +    }
    +]
    +

    项目主页

    +

    获取项目主页信息

    + +
    +

    示例:

    +
    +
    curl -X GET \
    +http://localhost:3000/api/jasder/forgeplus/about  | jq
    +
    await octokit.request('GET /api/jasder/forgeplus/about')
    +

    HTTP 请求

    +

    GET api/:owner/:repo/about

    +

    请求参数

    + + + + + + + + + + + + + + + + + + + + + + + +
    参数必选默认类型字段说明
    ownerstring用户登录名
    repostring项目标识identifier
    +

    返回字段说明

    + + + + + + + + @@ -1045,7 +1119,66 @@ http://localhost:3000/api/jasder/forgeplus/about | jq -

    创建项目

    +

    更改项目导航

    +

    更改项目导航信息

    + +
    +

    示例:

    +
    +
    curl -X POST \
    +-H  "accept: application/json" \
    +-H  "Content-Type: application/json" \
    +-d "{ \"unit_typs\": [\"code\", \"pulls\"]}" \
    +http://localhost:3000/api/yystopf/ceshi/project_units.json
    +
    await octokit.request('POST /api/yystopf/ceshi/project_units')
    +

    HTTP 请求

    +

    POST /api/yystopf/ceshi/project_units

    +

    请求参数

    +
    参数类型字段说明
    identifier string project's identifier
    + + + + + + + + + + + + + + + +
    参数必选默认类型字段说明
    unit_typesarray项目模块内容, 支持以下参数:code:代码库,issues:易修,pulls:合并请求,devops:工作流,versions:里程碑
    +

    返回字段说明:

    + + + + + + + + + + + + + + + + + +
    参数类型字段说明
    statusint返回状态, 0: 表示操作成功
    messagestring返回信息说明
    + +
    +

    返回的JSON示例:

    +
    +
    {
    +    "status": 0,
    +    "message": "success"
    +}
    +

    创建项目

    创建项目

    @@ -1062,9 +1195,9 @@ Remember — a happy kitten is an authenticated kitten! -d "license_id=1" \ http://localhost:3000/api/projects.json
    await octokit.request('GET /api/projects.json')
    -

    HTTP 请求

    +

    HTTP 请求

    POST api/projects

    -

    请求参数

    +

    请求参数

    @@ -1138,7 +1271,7 @@ http://localhost:3000/api/projects.json
    参数项目是否私有, true:为私有,false: 公开,默认为公开
    -

    返回字段说明

    +

    返回字段说明

    @@ -1180,9 +1313,9 @@ http://localhost:3000/api/projects.json -d"project_language_id=2"\ http://localhost:3000/api/projects/migrate.json
    await octokit.request('GET /api/projects/migrate.json')
    -

    HTTP 请求

    +

    HTTP 请求

    POST api/projects/migrate.json

    -

    请求参数

    +

    请求参数

    参数
    @@ -1270,7 +1403,7 @@ http://localhost:3000/api/projects/migrate.json
    参数项目是否私有, true:为私有,false: 非私有,默认为公开
    -

    返回字段说明

    +

    返回字段说明

    @@ -1305,9 +1438,9 @@ http://localhost:3000/api/projects/migrate.json
    curl -X POST http://localhost:3000/api/repositories/1244/sync_mirror.json
     
    await octokit.request('POST /api/repositories/1244/sync_mirror.json')
    -

    HTTP 请求

    +

    HTTP 请求

    POST api/repositories/:id/sync_mirror.json

    -

    请求参数

    +

    请求参数

    参数
    @@ -1325,7 +1458,7 @@ http://localhost:3000/api/projects/migrate.json
    参数仓库id
    -

    返回字段说明

    +

    返回字段说明

    @@ -1360,9 +1493,9 @@ http://localhost:3000/api/projects/migrate.json
    curl -X POST http://localhost:3000/api/jasder/forgeplus/forks.json
     
    await octokit.request('POST /api/jaser/jasder_test/forks.json')
    -

    HTTP 请求

    +

    HTTP 请求

    POST api/:owner/:repo/forks.json

    -

    请求参数

    +

    请求参数

    参数
    @@ -1387,7 +1520,7 @@ http://localhost:3000/api/projects/migrate.json
    参数项目标识identifier
    -

    返回字段说明

    +

    返回字段说明

    @@ -1672,27 +1805,27 @@ http://localhost:3000/api/projects/migrate.json - + - + - + - + - + @@ -2635,7 +2768,9 @@ http://localhost:3000/api/jasder/jasder_test/collaborators.json

    示例:

    -
    curl -X GET http://localhost:3000/api/yystopf/ceshi/files.json
    +
    curl -X GET \
    +-d "ref=develop" \
    +http://localhost:3000/api/yystopf/ceshi/files.json
     
    await octokit.request('GET /api/yystopf/ceshi/files.json')
     

    HTTP 请求

    GET /api/:owner/:repo/files

    @@ -2663,6 +2798,20 @@ http://localhost:3000/api/jasder/jasder_test/collaborators.json
    + + + + + + + + + + + + + +
    参数
    pull_requests_count int项目issue数量项目合并请求数量
    project_identifier int项目issue数量项目标识
    praises_count int项目issue数量项目点赞数量
    forked_count int项目issue数量项目复刻数量
    watchers_count int项目issue数量项目关注数量
    versions_countstring 项目标识identifier
    searchstring文件搜索关键词
    refstring分支名,默认为仓库默认分支

    返回字段说明:

    diff --git a/spec/models/project_unit_spec.rb b/spec/models/project_unit_spec.rb new file mode 100644 index 000000000..d95607ca6 --- /dev/null +++ b/spec/models/project_unit_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe ProjectUnit, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end