| @@ -113,6 +113,8 @@ http://localhost:3000/ | |||||
| ### API | ### API | ||||
| - [API](api_document.md) | - [API](api_document.md) | ||||
| - [API](showdoc.com.cn) | |||||
| 账号:forgeplus@admin.com 密码:forge123 | |||||
| ## 贡献代码 | ## 贡献代码 | ||||
| @@ -0,0 +1,11 @@ | |||||
| class Organizations::BaseController < ApplicationController | |||||
| include ApplicationHelper | |||||
| def load_organization | |||||
| @organization = Organization.find_by(login: params[:id]) || Organization.find_by(id: params[:id]) | |||||
| render_not_found if @organization.nil? | |||||
| @organization | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,74 @@ | |||||
| class Organizations::OrganizationsController < Organizations::BaseController | |||||
| before_action :require_login, except: [:index] | |||||
| before_action :convert_base64_image!, only: [:create, :update] | |||||
| before_action :load_organization, only: [:update, :destroy] | |||||
| def index | |||||
| if current_user.logged? | |||||
| @organizations = Organization.with_visibility(%w(common limited)) + | |||||
| Organization.with_visibility("privacy").joins(:organization_users).where(organization_users: {user_id: current_user.id}) | |||||
| else | |||||
| @organizations = Organization.with_visibility("common") | |||||
| end | |||||
| kaminary_array_paginate(@organizations) | |||||
| end | |||||
| def create | |||||
| ActiveRecord::Base.transaction do | |||||
| @organization = Organizations::CreateService.call(current_user, organization_params) | |||||
| Util.write_file(@image, avatar_path(@organization)) if params[:image].present? | |||||
| end | |||||
| rescue Exception => e | |||||
| uid_logger_error(e.message) | |||||
| tip_exception(e.message) | |||||
| end | |||||
| def update | |||||
| ActiveRecord::Base.transaction do | |||||
| login = @organization.login | |||||
| @organization.update!(login: organization_params[:name]) if organization_params[:name].present? | |||||
| @organization.organization_extension.update_attributes!(organization_params.except(:name)) | |||||
| Gitea::Organization::UpdateService.call(current_user.gitea_token, login, @organization) | |||||
| Util.write_file(@image, avatar_path(@organization)) if params[:image].present? | |||||
| end | |||||
| rescue Exception => e | |||||
| uid_logger_error(e.message) | |||||
| tip_exception(e.message) | |||||
| end | |||||
| def destroy | |||||
| render_unauthorized unless current_user.check_password?(password) | |||||
| render_forbidden("您没有权限进行该操作") unless @organization.check_owner?(current_user) | |||||
| ActiveRecord::Base.transaction do | |||||
| Gitea::Organization::DeleteService.call(current_user.gitea_token, @organization.login) | |||||
| @organization.destroy! | |||||
| end | |||||
| render_ok | |||||
| rescue Exception => e | |||||
| uid_logger_error(e.message) | |||||
| tip_exception(e.message) | |||||
| end | |||||
| private | |||||
| def convert_base64_image! | |||||
| max_size = EduSetting.get('upload_avatar_max_size') | |||||
| @image = Util.convert_base64_image(params[:image].to_s.strip, max_size: max_size) | |||||
| rescue Base64ImageConverter::Error => ex | |||||
| render_error(ex.message) | |||||
| end | |||||
| def avatar_path(organization) | |||||
| ApplicationController.helpers.disk_filename(organization.class, organization.id) | |||||
| end | |||||
| def organization_params | |||||
| params.permit(:name, :description, :website, :location, | |||||
| :repo_admin_change_team_access, :visibility, | |||||
| :max_repo_creation) | |||||
| end | |||||
| def password | |||||
| params.fetch(:password, "") | |||||
| end | |||||
| end | |||||
| @@ -11,6 +11,11 @@ | |||||
| # sync_subject :boolean default("0") | # sync_subject :boolean default("0") | ||||
| # sync_shixun :boolean default("0") | # sync_shixun :boolean default("0") | ||||
| # | # | ||||
| # Indexes | |||||
| # | |||||
| # index_laboratories_on_identifier (identifier) UNIQUE | |||||
| # index_laboratories_on_school_id (school_id) | |||||
| # | |||||
| class Laboratory < ApplicationRecord | class Laboratory < ApplicationRecord | ||||
| belongs_to :school, optional: true | belongs_to :school, optional: true | ||||
| @@ -6,6 +6,10 @@ | |||||
| # laboratory_id :integer | # laboratory_id :integer | ||||
| # config :text(65535) | # config :text(65535) | ||||
| # | # | ||||
| # Indexes | |||||
| # | |||||
| # index_laboratory_settings_on_laboratory_id (laboratory_id) | |||||
| # | |||||
| class LaboratorySetting < ApplicationRecord | class LaboratorySetting < ApplicationRecord | ||||
| belongs_to :laboratory | belongs_to :laboratory | ||||
| @@ -0,0 +1,88 @@ | |||||
| # == Schema Information | |||||
| # | |||||
| # Table name: users | |||||
| # | |||||
| # id :integer not null, primary key | |||||
| # login :string(255) default(""), not null | |||||
| # hashed_password :string(40) default(""), not null | |||||
| # firstname :string(30) default(""), not null | |||||
| # lastname :string(255) default(""), not null | |||||
| # mail :string(60) | |||||
| # admin :boolean default("0"), not null | |||||
| # status :integer default("1"), not null | |||||
| # last_login_on :datetime | |||||
| # language :string(5) default("") | |||||
| # auth_source_id :integer | |||||
| # created_on :datetime | |||||
| # updated_on :datetime | |||||
| # type :string(255) | |||||
| # identity_url :string(255) | |||||
| # mail_notification :string(255) default(""), not null | |||||
| # salt :string(64) | |||||
| # gid :integer | |||||
| # visits :integer default("0") | |||||
| # excellent_teacher :integer default("0") | |||||
| # excellent_student :integer default("0") | |||||
| # phone :string(255) | |||||
| # authentication :boolean default("0") | |||||
| # grade :integer default("0") | |||||
| # experience :integer default("0") | |||||
| # nickname :string(255) | |||||
| # show_realname :boolean default("1") | |||||
| # professional_certification :boolean default("0") | |||||
| # ID_number :string(255) | |||||
| # certification :integer default("0") | |||||
| # homepage_teacher :boolean default("0") | |||||
| # homepage_engineer :boolean default("0") | |||||
| # is_test :integer default("0") | |||||
| # ecoder_user_id :integer default("0") | |||||
| # business :boolean default("0") | |||||
| # profile_completed :boolean default("0") | |||||
| # laboratory_id :integer | |||||
| # platform :string(255) default("0") | |||||
| # gitea_token :string(255) | |||||
| # gitea_uid :integer | |||||
| # is_shixun_marker :boolean default("0") | |||||
| # is_sync_pwd :boolean default("1") | |||||
| # watchers_count :integer default("0") | |||||
| # devops_step :integer default("0") | |||||
| # | |||||
| # Indexes | |||||
| # | |||||
| # index_users_on_ecoder_user_id (ecoder_user_id) | |||||
| # index_users_on_homepage_engineer (homepage_engineer) | |||||
| # index_users_on_homepage_teacher (homepage_teacher) | |||||
| # index_users_on_laboratory_id (laboratory_id) | |||||
| # index_users_on_login (login) | |||||
| # index_users_on_mail (mail) | |||||
| # index_users_on_type (type) | |||||
| # | |||||
| class Organization < ApplicationRecord | |||||
| self.table_name = "users" | |||||
| default_scope { where(type: "Organization") } | |||||
| has_one :organization_extension, dependent: :destroy | |||||
| has_many :teams, dependent: :destroy | |||||
| has_many :organization_users, dependent: :destroy | |||||
| has_many :team_users, dependent: :destroy | |||||
| validates :login, presence: true | |||||
| validates_uniqueness_of :login, :if => Proc.new { |user| user.login_changed? && user.login.present? }, case_sensitive: false | |||||
| delegate :description, :website, :location, :repo_admin_change_team_access, :visibility, :max_repo_creation, to: :organization_extension, allow_nil: true | |||||
| scope :with_visibility, ->(visibility) { joins(:organization_extension).where(organization_extensions: {visibility: visibility}) if visibility.present? } | |||||
| def self.build(name) | |||||
| self.create!(login: name) | |||||
| end | |||||
| def owner_team | |||||
| teams.where(authorize: 4).take | |||||
| end | |||||
| def check_owner?(user) | |||||
| owner_team.team_users.where(user_id: user.id).present? | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,36 @@ | |||||
| # == Schema Information | |||||
| # | |||||
| # Table name: organization_extensions | |||||
| # | |||||
| # id :integer not null, primary key | |||||
| # organization_id :integer | |||||
| # description :string(255) | |||||
| # website :string(255) | |||||
| # location :string(255) | |||||
| # repo_admin_change_team_access :boolean default("0") | |||||
| # visibility :integer default("0") | |||||
| # max_repo_creation :integer default("-1") | |||||
| # created_at :datetime not null | |||||
| # updated_at :datetime not null | |||||
| # | |||||
| # Indexes | |||||
| # | |||||
| # index_organization_extensions_on_organization_id (organization_id) | |||||
| # | |||||
| class OrganizationExtension < ApplicationRecord | |||||
| belongs_to :organization | |||||
| enum visibility: {common: 0, limited: 1, privacy: 2} | |||||
| def self.build(organization_id, description, website, location, repo_admin_change_team_access, visibility, max_repo_creation) | |||||
| self.create!(organization_id: organization_id, | |||||
| description: description, | |||||
| website: website, | |||||
| location: location, | |||||
| repo_admin_change_team_access: repo_admin_change_team_access, | |||||
| visibility: visibility, | |||||
| max_repo_creation: max_repo_creation) | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,25 @@ | |||||
| # == Schema Information | |||||
| # | |||||
| # Table name: organization_users | |||||
| # | |||||
| # id :integer not null, primary key | |||||
| # user_id :integer | |||||
| # organization_id :integer | |||||
| # is_creator :boolean default("0") | |||||
| # created_at :datetime not null | |||||
| # updated_at :datetime not null | |||||
| # | |||||
| # Indexes | |||||
| # | |||||
| # index_organization_users_on_organization_id (organization_id) | |||||
| # index_organization_users_on_user_id (user_id) | |||||
| # | |||||
| class OrganizationUser < ApplicationRecord | |||||
| belongs_to :organization | |||||
| def self.build(organization_id, user_id, is_creator) | |||||
| self.create!(organization_id: organization_id, user_id: user_id, is_creator: is_creator) | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,44 @@ | |||||
| # == Schema Information | |||||
| # | |||||
| # Table name: teams | |||||
| # | |||||
| # id :integer not null, primary key | |||||
| # organization_id :integer | |||||
| # name :string(255) | |||||
| # description :string(255) | |||||
| # authorize :integer default("0") | |||||
| # num_projects :integer default("0") | |||||
| # num_users :integer default("0") | |||||
| # includes_all_project :boolean default("0") | |||||
| # can_create_org_project :boolean default("0") | |||||
| # gtid :integer | |||||
| # created_at :datetime not null | |||||
| # updated_at :datetime not null | |||||
| # | |||||
| # Indexes | |||||
| # | |||||
| # index_teams_on_organization_id (organization_id) | |||||
| # | |||||
| class Team < ApplicationRecord | |||||
| belongs_to :organization | |||||
| has_many :team_projects, dependent: :destroy | |||||
| has_many :team_units, dependent: :destroy | |||||
| has_many :team_users, dependent: :destroy | |||||
| enum authorize: {common: 0, read: 1, write: 2, admin: 3, owner: 4} | |||||
| def self.build(organization_id, name, description, authorize, includes_all_project, can_create_org_project) | |||||
| self.create!(organization_id: organization_id, | |||||
| name: name, | |||||
| description: description, | |||||
| authorize: authorize, | |||||
| includes_all_project: includes_all_project, | |||||
| can_create_org_project: can_create_org_project) | |||||
| end | |||||
| def self.build_owner(organization_id) | |||||
| self.build(organization_id, "Owner", "", 4, true, true) | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,28 @@ | |||||
| # == Schema Information | |||||
| # | |||||
| # Table name: team_projects | |||||
| # | |||||
| # id :integer not null, primary key | |||||
| # organization_id :integer | |||||
| # project_id :integer | |||||
| # team_id :integer | |||||
| # created_at :datetime not null | |||||
| # updated_at :datetime not null | |||||
| # | |||||
| # Indexes | |||||
| # | |||||
| # index_team_projects_on_organization_id (organization_id) | |||||
| # index_team_projects_on_project_id (project_id) | |||||
| # index_team_projects_on_team_id (team_id) | |||||
| # | |||||
| class TeamProject < ApplicationRecord | |||||
| belongs_to :organization | |||||
| belongs_to :project | |||||
| belongs_to :team, counter_cache: :num_projects | |||||
| def self.build(organization_id, team_id, project_id) | |||||
| self.create!(organization_id: organization_id, team_id: team_id, project_id: project_id) | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,36 @@ | |||||
| # == Schema Information | |||||
| # | |||||
| # Table name: team_units | |||||
| # | |||||
| # id :integer not null, primary key | |||||
| # organization_id :integer | |||||
| # team_id :integer | |||||
| # unit_type :integer | |||||
| # created_at :datetime not null | |||||
| # updated_at :datetime not null | |||||
| # | |||||
| # Indexes | |||||
| # | |||||
| # index_team_units_on_organization_id (organization_id) | |||||
| # index_team_units_on_team_id (team_id) | |||||
| # | |||||
| class TeamUnit < ApplicationRecord | |||||
| belongs_to :organization | |||||
| belongs_to :team | |||||
| enum unit_type: {code: 1, issue: 2, pull_request: 3, releases: 4} | |||||
| validates :unit_type, uniqueness: { scope: [:organization_id, :team_id]} | |||||
| def self.build(organization_id, team_id, unit_type) | |||||
| self.create!(organization_id: organization_id, team_id: team_id, unit_type: unit_type) | |||||
| end | |||||
| def self.build_owner(organization_id, team_id) | |||||
| self.unit_types.keys.each do |u_type| | |||||
| self.build(organization_id, team_id, u_type) | |||||
| end | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,28 @@ | |||||
| # == Schema Information | |||||
| # | |||||
| # Table name: team_users | |||||
| # | |||||
| # id :integer not null, primary key | |||||
| # organization_id :integer | |||||
| # team_id :integer | |||||
| # user_id :integer | |||||
| # created_at :datetime not null | |||||
| # updated_at :datetime not null | |||||
| # | |||||
| # Indexes | |||||
| # | |||||
| # index_team_users_on_organization_id (organization_id) | |||||
| # index_team_users_on_team_id (team_id) | |||||
| # index_team_users_on_user_id (user_id) | |||||
| # | |||||
| class TeamUser < ApplicationRecord | |||||
| belongs_to :organization | |||||
| belongs_to :team, counter_cache: :num_users | |||||
| belongs_to :user | |||||
| def self.build(organization_id, user_id, team_id) | |||||
| self.create!(organization_id: organization_id, user_id: user_id, team_id: team_id) | |||||
| end | |||||
| end | |||||
| @@ -59,6 +59,7 @@ | |||||
| # | # | ||||
| class User < ApplicationRecord | class User < ApplicationRecord | ||||
| default_scope {where(type: %w(User AnonymousUser))} | |||||
| extend Enumerize | extend Enumerize | ||||
| include Watchable | include Watchable | ||||
| @@ -132,7 +132,8 @@ class Gitea::ClientService < ApplicationService | |||||
| when 204 | when 204 | ||||
| puts "[gitea] " | puts "[gitea] " | ||||
| raise Error, "[gitea] delete ok" | |||||
| # raise Error, "[gitea] delete ok" | |||||
| {status: 204} | |||||
| when 409 | when 409 | ||||
| message = "创建失败,请检查该分支合并是否已存在" | message = "创建失败,请检查该分支合并是否已存在" | ||||
| raise Error, mark + message | raise Error, mark + message | ||||
| @@ -0,0 +1,43 @@ | |||||
| class Gitea::Organization::CreateService < Gitea::ClientService | |||||
| attr_reader :token, :org | |||||
| def initialize(token, org) | |||||
| @token = token | |||||
| @org = org | |||||
| end | |||||
| def call | |||||
| response = post(url, request_params) | |||||
| render_status(response) | |||||
| end | |||||
| private | |||||
| def request_params | |||||
| create_params = { | |||||
| username: org.login, | |||||
| description: org.description, | |||||
| location: org.location, | |||||
| repo_admin_change_team_access: org.repo_admin_change_team_access, | |||||
| visibility: visibility(org.visibility), | |||||
| website: org.website | |||||
| } | |||||
| Hash.new.merge(token: token, data: create_params) | |||||
| end | |||||
| def visibility(visibility) | |||||
| case visibility | |||||
| when "common" | |||||
| "public" | |||||
| when "limited" | |||||
| "limited" | |||||
| when "privacy" | |||||
| "private" | |||||
| else | |||||
| "public" | |||||
| end | |||||
| end | |||||
| def url | |||||
| "/orgs".freeze | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,23 @@ | |||||
| class Gitea::Organization::DeleteService < Gitea::ClientService | |||||
| attr_reader :token, :name | |||||
| def initialize(token, name) | |||||
| @token = token | |||||
| @name = name | |||||
| end | |||||
| def call | |||||
| response = delete(url, params) | |||||
| render_status(response) | |||||
| end | |||||
| private | |||||
| def params | |||||
| Hash.new.merge(token: token) | |||||
| end | |||||
| def url | |||||
| "/orgs/#{name}".freeze | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,44 @@ | |||||
| class Gitea::Organization::UpdateService < Gitea::ClientService | |||||
| attr_reader :token, :login, :org | |||||
| def initialize(token, login, org) | |||||
| @token = token | |||||
| @login = login | |||||
| @org = org | |||||
| end | |||||
| def call | |||||
| response = patch(url, request_params) | |||||
| render_status(response) | |||||
| end | |||||
| private | |||||
| def request_params | |||||
| update_params = { | |||||
| username: org.login, | |||||
| description: org.description, | |||||
| location: org.location, | |||||
| repo_admin_change_team_access: org.repo_admin_change_team_access, | |||||
| visibility: visibility(org.visibility), | |||||
| website: org.website | |||||
| } | |||||
| Hash.new.merge(token: token, data: update_params) | |||||
| end | |||||
| def visibility(visibility) | |||||
| case visibility | |||||
| when "common" | |||||
| "public" | |||||
| when "limited" | |||||
| "limited" | |||||
| when "privacy" | |||||
| "private" | |||||
| else | |||||
| "public" | |||||
| end | |||||
| end | |||||
| def url | |||||
| "/orgs/#{login}".freeze | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,28 @@ | |||||
| class Organizations::CreateService < ApplicationService | |||||
| attr_reader :user, :params | |||||
| def initialize(user, params) | |||||
| @user = user | |||||
| @params = params | |||||
| end | |||||
| def call | |||||
| Rails.logger.info("######Organization create_service begin######") | |||||
| Rails.logger.info("######params #{params}######") | |||||
| ActiveRecord::Base.transaction do | |||||
| @organization = Organization.build(params[:name]) | |||||
| org_extension = OrganizationExtension.build(@organization.id, params[:description], params[:website], | |||||
| params[:location], params[:repo_admin_change_team_access], | |||||
| params[:visibility], params[:max_repo_creation]) | |||||
| team = Team.build_owner(@organization.id) | |||||
| TeamUnit.build_owner(@organization.id, team.id) | |||||
| OrganizationUser.build(@organization.id, user.id, true) | |||||
| TeamUser.build(@organization.id, user.id, team.id) | |||||
| Gitea::Organization::CreateService.call(user.gitea_token, @organization) | |||||
| Rails.logger.info("######Organization create_service end######") | |||||
| end | |||||
| @organization | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,9 @@ | |||||
| json.id organization.id | |||||
| json.name organization.login | |||||
| json.description organization.description | |||||
| json.website organization.website | |||||
| json.location organization.location | |||||
| json.repo_admin_change_team_access organization.repo_admin_change_team_access | |||||
| json.visibility organization.visibility | |||||
| json.max_repo_creation organization.max_repo_creation | |||||
| json.avatar_url url_to_avatar(organization) | |||||
| @@ -0,0 +1 @@ | |||||
| json.partial! "detail", organization: @organization | |||||
| @@ -0,0 +1,3 @@ | |||||
| json.organizations @organizations do |organization| | |||||
| json.partial! "detail", organization: organization | |||||
| end | |||||
| @@ -0,0 +1 @@ | |||||
| json.partial! "detail", organization: @organization | |||||
| @@ -103,6 +103,19 @@ Rails.application.routes.draw do | |||||
| put 'commons/unhidden', to: 'commons#unhidden' | put 'commons/unhidden', to: 'commons#unhidden' | ||||
| delete 'commons/delete', to: 'commons#delete' | delete 'commons/delete', to: 'commons#delete' | ||||
| scope module: :organizations do | |||||
| resources :organizations do | |||||
| end | |||||
| resources :teams do | |||||
| resources :team_users do | |||||
| end | |||||
| resources :team_projects do | |||||
| end | |||||
| end | |||||
| end | |||||
| resources :issues, except: [:index, :new,:create, :update, :edit, :destroy] do | resources :issues, except: [:index, :new,:create, :update, :edit, :destroy] do | ||||
| resources :journals, only: [:index, :create, :destroy, :edit, :update] do | resources :journals, only: [:index, :create, :destroy, :edit, :update] do | ||||
| member do | member do | ||||
| @@ -0,0 +1,11 @@ | |||||
| class CreateOrganizationUsers < ActiveRecord::Migration[5.2] | |||||
| def change | |||||
| create_table :organization_users do |t| | |||||
| t.references :user | |||||
| t.references :organization | |||||
| t.boolean :is_creator, comment: "是否为创建者", default: false | |||||
| t.timestamps | |||||
| end | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,15 @@ | |||||
| class CreateOrganizationExtensions < ActiveRecord::Migration[5.2] | |||||
| def change | |||||
| create_table :organization_extensions do |t| | |||||
| t.references :organization | |||||
| t.string :description, comment: "组织描述" | |||||
| t.string :website, comment: "组织官方网站" | |||||
| t.string :location, comment: "组织地区" | |||||
| t.boolean :repo_admin_change_team_access, comment: "项目管理员是否可以添加或移除团队的访问权限", default: false | |||||
| t.integer :visibility, comment: "组织可见性", default: 0 | |||||
| t.integer :max_repo_creation, comment: "组织最大仓库数", default: -1 | |||||
| t.timestamps | |||||
| end | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,17 @@ | |||||
| class CreateTeams < ActiveRecord::Migration[5.2] | |||||
| def change | |||||
| create_table :teams do |t| | |||||
| t.references :organization | |||||
| t.string :name, comment: "团队名称" | |||||
| t.string :description, comment: "团队描述" | |||||
| t.integer :authorize, comment: "团队权限", default: 0 | |||||
| t.integer :num_projects, comment: "团队项目数量", default: 0 | |||||
| t.integer :num_users, comment: "团队成员数量", default: 0 | |||||
| t.boolean :includes_all_project, comment: "团队是否拥有所有项目", default: false | |||||
| t.boolean :can_create_org_project, comment: "团队是否能创建项目", default: false | |||||
| t.integer :gtid, comment: "团队在gitea里的id" | |||||
| t.timestamps | |||||
| end | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,11 @@ | |||||
| class CreateTeamProjects < ActiveRecord::Migration[5.2] | |||||
| def change | |||||
| create_table :team_projects do |t| | |||||
| t.references :organization | |||||
| t.references :project | |||||
| t.references :team | |||||
| t.timestamps | |||||
| end | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,10 @@ | |||||
| class CreateTeamUsers < ActiveRecord::Migration[5.2] | |||||
| def change | |||||
| create_table :team_users do |t| | |||||
| t.references :organization | |||||
| t.references :team | |||||
| t.references :user | |||||
| t.timestamps | |||||
| end | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,11 @@ | |||||
| class CreateTeamUnits < ActiveRecord::Migration[5.2] | |||||
| def change | |||||
| create_table :team_units do |t| | |||||
| t.references :organization | |||||
| t.references :team | |||||
| t.integer :unit_type, comment: "访问单元类型" | |||||
| t.timestamps | |||||
| end | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1 @@ | |||||
| Subproject commit 6348a15cdb954862dc1b7b5f045a432bcfde7dc4 | |||||
| @@ -0,0 +1,5 @@ | |||||
| require 'rails_helper' | |||||
| RSpec.describe OrganizationExtension, type: :model do | |||||
| pending "add some examples to (or delete) #{__FILE__}" | |||||
| end | |||||
| @@ -0,0 +1,5 @@ | |||||
| require 'rails_helper' | |||||
| RSpec.describe OrganizationUser, type: :model do | |||||
| pending "add some examples to (or delete) #{__FILE__}" | |||||
| end | |||||
| @@ -0,0 +1,5 @@ | |||||
| require 'rails_helper' | |||||
| RSpec.describe TeamProject, type: :model do | |||||
| pending "add some examples to (or delete) #{__FILE__}" | |||||
| end | |||||
| @@ -0,0 +1,5 @@ | |||||
| require 'rails_helper' | |||||
| RSpec.describe Team, type: :model do | |||||
| pending "add some examples to (or delete) #{__FILE__}" | |||||
| end | |||||
| @@ -0,0 +1,5 @@ | |||||
| require 'rails_helper' | |||||
| RSpec.describe TeamUnit, type: :model do | |||||
| pending "add some examples to (or delete) #{__FILE__}" | |||||
| end | |||||
| @@ -0,0 +1,5 @@ | |||||
| require 'rails_helper' | |||||
| RSpec.describe TeamUser, type: :model do | |||||
| pending "add some examples to (or delete) #{__FILE__}" | |||||
| end | |||||