diff --git a/app/models/laboratory.rb b/app/models/laboratory.rb index 73002a84..699800c9 100644 --- a/app/models/laboratory.rb +++ b/app/models/laboratory.rb @@ -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 diff --git a/app/models/laboratory_setting.rb b/app/models/laboratory_setting.rb index 5013dd54..61c677de 100644 --- a/app/models/laboratory_setting.rb +++ b/app/models/laboratory_setting.rb @@ -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 diff --git a/app/models/license.rb b/app/models/license.rb index dcd5528f..0a14fb85 100644 --- a/app/models/license.rb +++ b/app/models/license.rb @@ -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 diff --git a/app/models/member.rb b/app/models/member.rb index 408710a0..e72ae7c6 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -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 # diff --git a/app/models/organization.rb b/app/models/organization.rb index 48dab55a..c652f4e3 100644 --- a/app/models/organization.rb +++ b/app/models/organization.rb @@ -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 # diff --git a/app/models/project.rb b/app/models/project.rb index 9aa6283f..a787afe3 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -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) +# + diff --git a/app/models/sponsorship.rb b/app/models/sponsorship.rb index ccd2d853..c761f2c4 100644 --- a/app/models/sponsorship.rb +++ b/app/models/sponsorship.rb @@ -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) + 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 - 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 - end - false + success end def self.monthly_payment diff --git a/app/models/token.rb b/app/models/token.rb index db778c6b..c9e45a86 100644 --- a/app/models/token.rb +++ b/app/models/token.rb @@ -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 diff --git a/app/models/user.rb b/app/models/user.rb index 3bde74b7..15e47cb7 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -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 diff --git a/app/models/wallet.rb b/app/models/wallet.rb index 64bcd942..d0f198bd 100644 --- a/app/models/wallet.rb +++ b/app/models/wallet.rb @@ -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