| @@ -11,6 +11,11 @@ | |||
| # sync_subject :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 | |||
| belongs_to :school, optional: true | |||
| @@ -6,6 +6,10 @@ | |||
| # laboratory_id :integer | |||
| # config :text(65535) | |||
| # | |||
| # Indexes | |||
| # | |||
| # index_laboratory_settings_on_laboratory_id (laboratory_id) | |||
| # | |||
| class LaboratorySetting < ApplicationRecord | |||
| belongs_to :laboratory | |||
| @@ -7,7 +7,6 @@ | |||
| # content :text(65535) | |||
| # created_at :datetime not null | |||
| # updated_at :datetime not null | |||
| # is_secret :boolean default("0") | |||
| # | |||
| class License < ApplicationRecord | |||
| @@ -11,7 +11,6 @@ | |||
| # course_group_id :integer default("0") | |||
| # is_collect :integer default("1") | |||
| # graduation_group_id :integer default("0") | |||
| # is_apply_signature :boolean default("0") | |||
| # | |||
| # Indexes | |||
| # | |||
| @@ -45,7 +45,12 @@ | |||
| # is_shixun_marker :boolean default("0") | |||
| # is_sync_pwd :boolean default("1") | |||
| # watchers_count :integer default("0") | |||
| # sponsor_certification :integer default("0") | |||
| # sponsor_num :integer default("0") | |||
| # sponsored_num :integer default("0") | |||
| # description :text(65535) | |||
| # devops_step :integer default("0") | |||
| # award_time :datetime | |||
| # | |||
| # Indexes | |||
| # | |||
| @@ -1,74 +1,75 @@ | |||
| # == Schema Information | |||
| # | |||
| # Table name: projects | |||
| # | |||
| # id :integer not null, primary key | |||
| # name :string(255) default(""), not null | |||
| # description :text(4294967295) | |||
| # homepage :string(255) default("") | |||
| # is_public :boolean default("1"), not null | |||
| # parent_id :integer | |||
| # created_on :datetime | |||
| # updated_on :datetime | |||
| # identifier :string(255) | |||
| # status :integer default("1"), not null | |||
| # lft :integer | |||
| # rgt :integer | |||
| # inherit_members :boolean default("0"), not null | |||
| # project_type :integer default("0") | |||
| # hidden_repo :boolean default("0"), not null | |||
| # attachmenttype :integer default("1") | |||
| # user_id :integer | |||
| # dts_test :integer default("0") | |||
| # enterprise_name :string(255) | |||
| # organization_id :integer | |||
| # project_new_type :integer | |||
| # gpid :integer | |||
| # forked_from_project_id :integer | |||
| # forked_count :integer default("0") | |||
| # publish_resource :integer default("0") | |||
| # visits :integer default("0") | |||
| # hot :integer default("0") | |||
| # invite_code :string(255) | |||
| # qrcode :string(255) | |||
| # qrcode_expiretime :integer default("0") | |||
| # script :text(65535) | |||
| # training_status :integer default("0") | |||
| # rep_identifier :string(255) | |||
| # project_category_id :integer | |||
| # project_language_id :integer | |||
| # license_id :integer | |||
| # ignore_id :integer | |||
| # praises_count :integer default("0") | |||
| # watchers_count :integer default("0") | |||
| # issues_count :integer default("0") | |||
| # pull_requests_count :integer default("0") | |||
| # language :string(255) | |||
| # versions_count :integer default("0") | |||
| # issue_tags_count :integer default("0") | |||
| # closed_issues_count :integer default("0") | |||
| # open_devops :boolean default("0") | |||
| # gitea_webhook_id :integer | |||
| # open_devops_count :integer default("0") | |||
| # recommend :boolean default("0") | |||
| # platform :integer default("0") | |||
| # default_branch :string(255) default("master") | |||
| # website :string(255) | |||
| # | |||
| # Indexes | |||
| # | |||
| # index_projects_on_forked_from_project_id (forked_from_project_id) | |||
| # index_projects_on_identifier (identifier) | |||
| # index_projects_on_is_public (is_public) | |||
| # index_projects_on_lft (lft) | |||
| # index_projects_on_name (name) | |||
| # index_projects_on_platform (platform) | |||
| # index_projects_on_project_type (project_type) | |||
| # index_projects_on_recommend (recommend) | |||
| # index_projects_on_rgt (rgt) | |||
| # index_projects_on_status (status) | |||
| # index_projects_on_updated_on (updated_on) | |||
| # | |||
| # == Schema Information | |||
| # | |||
| # Table name: projects | |||
| # | |||
| # id :integer not null, primary key | |||
| # name :string(255) default(""), not null | |||
| # description :text(4294967295) | |||
| # homepage :string(255) default("") | |||
| # is_public :boolean default("1"), not null | |||
| # parent_id :integer | |||
| # created_on :datetime | |||
| # updated_on :datetime | |||
| # identifier :string(255) | |||
| # status :integer default("1"), not null | |||
| # lft :integer | |||
| # rgt :integer | |||
| # inherit_members :boolean default("0"), not null | |||
| # project_type :integer default("0") | |||
| # hidden_repo :boolean default("0"), not null | |||
| # attachmenttype :integer default("1") | |||
| # user_id :integer | |||
| # dts_test :integer default("0") | |||
| # enterprise_name :string(255) | |||
| # organization_id :integer | |||
| # project_new_type :integer | |||
| # gpid :integer | |||
| # forked_from_project_id :integer | |||
| # forked_count :integer default("0") | |||
| # publish_resource :integer default("0") | |||
| # visits :integer default("0") | |||
| # hot :integer default("0") | |||
| # invite_code :string(255) | |||
| # qrcode :string(255) | |||
| # qrcode_expiretime :integer default("0") | |||
| # script :text(65535) | |||
| # training_status :integer default("0") | |||
| # rep_identifier :string(255) | |||
| # project_category_id :integer | |||
| # project_language_id :integer | |||
| # license_id :integer | |||
| # ignore_id :integer | |||
| # praises_count :integer default("0") | |||
| # watchers_count :integer default("0") | |||
| # issues_count :integer default("0") | |||
| # pull_requests_count :integer default("0") | |||
| # language :string(255) | |||
| # versions_count :integer default("0") | |||
| # issue_tags_count :integer default("0") | |||
| # closed_issues_count :integer default("0") | |||
| # open_devops :boolean default("0") | |||
| # gitea_webhook_id :integer | |||
| # open_devops_count :integer default("0") | |||
| # recommend :boolean default("0") | |||
| # platform :integer default("0") | |||
| # default_branch :string(255) default("master") | |||
| # website :string(255) | |||
| # | |||
| # Indexes | |||
| # | |||
| # index_projects_on_forked_from_project_id (forked_from_project_id) | |||
| # index_projects_on_identifier (identifier) | |||
| # index_projects_on_is_public (is_public) | |||
| # index_projects_on_lft (lft) | |||
| # index_projects_on_name (name) | |||
| # index_projects_on_platform (platform) | |||
| # index_projects_on_project_type (project_type) | |||
| # index_projects_on_recommend (recommend) | |||
| # index_projects_on_rgt (rgt) | |||
| # index_projects_on_status (status) | |||
| # index_projects_on_updated_on (updated_on) | |||
| # | |||
| @@ -26,19 +26,18 @@ class Sponsorship < ApplicationRecord | |||
| sponsor_wallet = sponsor.get_wallet | |||
| developer_wallet = developer.get_wallet | |||
| success = false | |||
| Wallet.transaction do | |||
| return false if sponsor.wallet.balance < amount | |||
| sponsor_wallet.update(balance: sponsor_wallet.balance -= amount) | |||
| developer_wallet.update(balance: developer_wallet.balance += amount) | |||
| update(accumulate: self.accumulate += amount) | |||
| end | |||
| reason = "#{sponsor.full_name}向#{developer.full_name}的赞助支付。" | |||
| coinchange = CoinChange.new(amount: amount, reason: reason, to_wallet_id: developer_wallet.id, from_wallet_id: sponsor_wallet.id) | |||
| if coinchange.save | |||
| return true | |||
| success = sponsor_wallet.pay(amount) | |||
| if success | |||
| success developer_wallet.receive(amount) | |||
| update(accumulate: self.accumulate += amount) | |||
| reason = "#{sponsor.full_name}向#{developer.full_name}的赞助支付。" | |||
| coinchange = CoinChange.new(amount: amount, reason: reason, to_wallet_id: developer_wallet.id, from_wallet_id: sponsor_wallet.id) | |||
| return true if coinchange.save | |||
| end | |||
| end | |||
| false | |||
| success | |||
| end | |||
| def self.monthly_payment | |||
| @@ -1,18 +1,19 @@ | |||
| # == Schema Information | |||
| # | |||
| # Table name: tokens | |||
| # | |||
| # id :integer not null, primary key | |||
| # user_id :integer default("0"), not null | |||
| # action :string(30) default(""), not null | |||
| # value :string(40) default(""), not null | |||
| # created_on :datetime not null | |||
| # | |||
| # Indexes | |||
| # | |||
| # index_tokens_on_user_id (user_id) | |||
| # tokens_value (value) UNIQUE | |||
| # | |||
| # == Schema Information | |||
| # | |||
| # Table name: tokens | |||
| # | |||
| # id :integer not null, primary key | |||
| # user_id :integer default("0"), not null | |||
| # action :string(30) default(""), not null | |||
| # value :string(40) default(""), not null | |||
| # created_on :datetime not null | |||
| # | |||
| # Indexes | |||
| # | |||
| # index_tokens_on_user_id (user_id) | |||
| # tokens_value (value) UNIQUE | |||
| # | |||
| # | |||
| # This program is free software; you can redistribute it and/or | |||
| @@ -757,10 +757,23 @@ class User < Owner | |||
| end | |||
| def get_wallet | |||
| # if wallet.nil? | |||
| # Wallet.transaction(isolation: :serializable) do | |||
| # if wallet.nil? | |||
| # create_wallet(balance: 100) | |||
| # reason = "系统初始赠送" | |||
| # CoinChange.create(amount: amount, reason: reason, to_wallet_id: wallet.id) | |||
| # end | |||
| # end | |||
| # end | |||
| if wallet.nil? | |||
| create_wallet(balance: 100) | |||
| reason = "系统初始赠送" | |||
| CoinChange.create(amount: amount, reason: reason, to_wallet_id: wallet.id) | |||
| Wallet.wallet_lock.lock | |||
| if wallet.nil? | |||
| create_wallet(balance: 100) | |||
| reason = "系统初始赠送" | |||
| CoinChange.create(amount: amount, reason: reason, to_wallet_id: wallet.id) | |||
| end | |||
| Wallet.wallet_lock.unlock | |||
| end | |||
| wallet | |||
| end | |||
| @@ -773,7 +786,7 @@ class User < Owner | |||
| self.update_column(:award_time, Time.now) | |||
| amount = 2 | |||
| user_wallet = get_wallet | |||
| user_wallet.update(balance: user_wallet.balance += amount) | |||
| user_wallet.receive(amount) | |||
| reason = "每日登录奖励" | |||
| CoinChange.create(amount: amount, reason: reason, to_wallet_id: user_wallet.id) | |||
| end | |||
| @@ -14,4 +14,29 @@ class Wallet < ApplicationRecord | |||
| has_many :outcome, class_name: 'CoinChange', foreign_key: 'from_wallet_id', dependent: :destroy | |||
| has_many :income, class_name: 'CoinChange', foreign_key: 'to_wallet_id', dependent: :destroy | |||
| validates :balance, presence: true | |||
| @@wallet_lock = Mutex.new | |||
| def receive(amount) | |||
| with_lock do | |||
| self.balance += amount | |||
| save! | |||
| end | |||
| end | |||
| def pay(amount) | |||
| with_lock do | |||
| if self.balance < amount | |||
| reload | |||
| return false | |||
| else | |||
| self.balance -= amount | |||
| save! | |||
| end | |||
| end | |||
| true | |||
| end | |||
| def self.wallet_lock | |||
| @@wallet_lock | |||
| end | |||
| end | |||