| @@ -73,7 +73,7 @@ vendor/bundle/ | |||||
| /public/admin | /public/admin | ||||
| /mysql_data | /mysql_data | ||||
| /public/repo/ | /public/repo/ | ||||
| /coverage | |||||
| .generators | .generators | ||||
| .rakeTasks | .rakeTasks | ||||
| @@ -59,6 +59,7 @@ gem 'ransack' | |||||
| group :development, :test do | group :development, :test do | ||||
| gem 'rspec-rails', '~> 3.8' | gem 'rspec-rails', '~> 3.8' | ||||
| gem 'rails-controller-testing' | |||||
| end | end | ||||
| group :development do | group :development do | ||||
| @@ -77,6 +78,7 @@ group :test do | |||||
| gem 'capybara', '>= 2.15', '< 4.0' | gem 'capybara', '>= 2.15', '< 4.0' | ||||
| gem 'selenium-webdriver' | gem 'selenium-webdriver' | ||||
| gem 'chromedriver-helper' | gem 'chromedriver-helper' | ||||
| gem 'simplecov', '~>0.12.0', require: false | |||||
| end | end | ||||
| gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] | gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] | ||||
| @@ -101,6 +103,7 @@ gem 'rails-i18n', '~> 5.1' | |||||
| gem 'sidekiq',"5.2.8" | gem 'sidekiq',"5.2.8" | ||||
| gem 'sinatra' | gem 'sinatra' | ||||
| gem "sidekiq-cron", "1.2.0" | gem "sidekiq-cron", "1.2.0" | ||||
| gem 'whenever' | |||||
| # batch insert | # batch insert | ||||
| gem 'bulk_insert' | gem 'bulk_insert' | ||||
| @@ -131,6 +134,9 @@ gem 'harmonious_dictionary', '~> 0.0.1' | |||||
| gem 'parallel', '~> 1.19', '>= 1.19.1' | gem 'parallel', '~> 1.19', '>= 1.19.1' | ||||
| # log | |||||
| gem 'multi_logger' | |||||
| gem 'letter_avatar' | gem 'letter_avatar' | ||||
| gem 'jwt' | gem 'jwt' | ||||
| @@ -121,4 +121,4 @@ You may obtain a copy of Mulan PSL v2 at: | |||||
| THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, | THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, | ||||
| EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, | EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, | ||||
| MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. | MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. | ||||
| See the Mulan PSL v2 for more details. | |||||
| See the Mulan PSL v2 for more details. | |||||
| @@ -0,0 +1,2 @@ | |||||
| // Place all the behaviors and hooks related to the matching controller here. | |||||
| // All this logic will automatically be available in application.js. | |||||
| @@ -0,0 +1,2 @@ | |||||
| // Place all the behaviors and hooks related to the matching controller here. | |||||
| // All this logic will automatically be available in application.js. | |||||
| @@ -0,0 +1,2 @@ | |||||
| // Place all the behaviors and hooks related to the matching controller here. | |||||
| // All this logic will automatically be available in application.js. | |||||
| @@ -0,0 +1,2 @@ | |||||
| // Place all the behaviors and hooks related to the matching controller here. | |||||
| // All this logic will automatically be available in application.js. | |||||
| @@ -0,0 +1,3 @@ | |||||
| // Place all the styles related to the log controller here. | |||||
| // They will automatically be included in application.css. | |||||
| // You can use Sass (SCSS) here: http://sass-lang.com/ | |||||
| @@ -0,0 +1,84 @@ | |||||
| body { | |||||
| background-color: #fff; | |||||
| color: #333; | |||||
| margin: 33px; | |||||
| font-family: verdana, arial, helvetica, sans-serif; | |||||
| font-size: 13px; | |||||
| line-height: 18px; | |||||
| } | |||||
| p, ol, ul, td { | |||||
| font-family: verdana, arial, helvetica, sans-serif; | |||||
| font-size: 13px; | |||||
| line-height: 18px; | |||||
| } | |||||
| pre { | |||||
| background-color: #eee; | |||||
| padding: 10px; | |||||
| font-size: 11px; | |||||
| } | |||||
| a { | |||||
| color: #000; | |||||
| &:visited { | |||||
| color: #666; | |||||
| } | |||||
| &:hover { | |||||
| color: #fff; | |||||
| background-color: #000; | |||||
| } | |||||
| } | |||||
| th { | |||||
| padding-bottom: 5px; | |||||
| } | |||||
| td { | |||||
| padding: 0 5px 7px; | |||||
| } | |||||
| div { | |||||
| &.field, &.actions { | |||||
| margin-bottom: 10px; | |||||
| } | |||||
| } | |||||
| #notice { | |||||
| color: green; | |||||
| } | |||||
| .field_with_errors { | |||||
| padding: 2px; | |||||
| background-color: red; | |||||
| display: table; | |||||
| } | |||||
| #error_explanation { | |||||
| width: 450px; | |||||
| border: 2px solid red; | |||||
| padding: 7px 7px 0; | |||||
| margin-bottom: 20px; | |||||
| background-color: #f0f0f0; | |||||
| h2 { | |||||
| text-align: left; | |||||
| font-weight: bold; | |||||
| padding: 5px 5px 5px 15px; | |||||
| font-size: 12px; | |||||
| margin: -7px -7px 0; | |||||
| background-color: #c00; | |||||
| color: #fff; | |||||
| } | |||||
| ul li { | |||||
| font-size: 12px; | |||||
| list-style: square; | |||||
| } | |||||
| } | |||||
| label { | |||||
| display: block; | |||||
| } | |||||
| @@ -0,0 +1,3 @@ | |||||
| // Place all the styles related to the SponsorTiers controller here. | |||||
| // They will automatically be included in application.css. | |||||
| // You can use Sass (SCSS) here: http://sass-lang.com/ | |||||
| @@ -0,0 +1,3 @@ | |||||
| // Place all the styles related to the Sponsorships controller here. | |||||
| // They will automatically be included in application.css. | |||||
| // You can use Sass (SCSS) here: http://sass-lang.com/ | |||||
| @@ -0,0 +1,3 @@ | |||||
| // Place all the styles related to the Wallets controller here. | |||||
| // They will automatically be included in application.css. | |||||
| // You can use Sass (SCSS) here: http://sass-lang.com/ | |||||
| @@ -4,13 +4,13 @@ class AccountsController < ApplicationController | |||||
| #skip_before_action :check_account, :only => [:logout] | #skip_before_action :check_account, :only => [:logout] | ||||
| def simple_update | |||||
| def simple_update | |||||
| simple_update_params.merge!(username: params[:username]&.gsub(/\s+/, "")) | simple_update_params.merge!(username: params[:username]&.gsub(/\s+/, "")) | ||||
| simple_update_params.merge!(email: params[:email]&.gsub(/\s+/, "")) | simple_update_params.merge!(email: params[:email]&.gsub(/\s+/, "")) | ||||
| simple_update_params.merge!(platform: (params[:platform] || 'forge')&.gsub(/\s+/, "")) | simple_update_params.merge!(platform: (params[:platform] || 'forge')&.gsub(/\s+/, "")) | ||||
| Register::RemoteForm.new(simple_update_params).validate! | Register::RemoteForm.new(simple_update_params).validate! | ||||
| ActiveRecord::Base.transaction do | |||||
| ActiveRecord::Base.transaction do | |||||
| result = auto_update(current_user, simple_update_params) | result = auto_update(current_user, simple_update_params) | ||||
| if result[:message].blank? | if result[:message].blank? | ||||
| render_ok | render_ok | ||||
| @@ -270,6 +270,7 @@ class AccountsController < ApplicationController | |||||
| set_autologin_cookie(user) | set_autologin_cookie(user) | ||||
| UserAction.create(:action_id => user.try(:id), :action_type => "Login", :user_id => user.try(:id), :ip => request.remote_ip) | UserAction.create(:action_id => user.try(:id), :action_type => "Login", :user_id => user.try(:id), :ip => request.remote_ip) | ||||
| # user.daily_reward | |||||
| user.update_column(:last_login_on, Time.now) | user.update_column(:last_login_on, Time.now) | ||||
| session[:"#{default_yun_session}"] = user.id | session[:"#{default_yun_session}"] = user.id | ||||
| Rails.logger.info("#########_____session_default_yun_session__________###############{default_yun_session}") | Rails.logger.info("#########_____session_default_yun_session__________###############{default_yun_session}") | ||||
| @@ -342,11 +343,11 @@ class AccountsController < ApplicationController | |||||
| render_ok | render_ok | ||||
| end | end | ||||
| def login_check | |||||
| def login_check | |||||
| Register::LoginCheckColumnsForm.new(check_params.merge(user: current_user)).validate! | Register::LoginCheckColumnsForm.new(check_params.merge(user: current_user)).validate! | ||||
| render_ok | render_ok | ||||
| end | end | ||||
| private | private | ||||
| # type 事件类型 1:用户注册 2:忘记密码 3: 绑定手机 4: 绑定邮箱, 5: 验证手机号是否有效 # 如果有新的继续后面加 | # type 事件类型 1:用户注册 2:忘记密码 3: 绑定手机 4: 绑定邮箱, 5: 验证手机号是否有效 # 如果有新的继续后面加 | ||||
| @@ -389,7 +390,7 @@ class AccountsController < ApplicationController | |||||
| params.require(:user).permit(:login, :email, :phone) | params.require(:user).permit(:login, :email, :phone) | ||||
| end | end | ||||
| def login_params | |||||
| def login_params | |||||
| params.require(:account).permit(:login, :password) | params.require(:account).permit(:login, :password) | ||||
| end | end | ||||
| @@ -404,7 +405,7 @@ class AccountsController < ApplicationController | |||||
| def reset_password_params | def reset_password_params | ||||
| params.permit(:login, :password, :password_confirmation, :code) | params.permit(:login, :password, :password_confirmation, :code) | ||||
| end | end | ||||
| def find_user | def find_user | ||||
| phone_or_mail = strip(reset_password_params[:login]) | phone_or_mail = strip(reset_password_params[:login]) | ||||
| User.where("phone = :search OR mail = :search", search: phone_or_mail).last | User.where("phone = :search OR mail = :search", search: phone_or_mail).last | ||||
| @@ -413,7 +414,7 @@ class AccountsController < ApplicationController | |||||
| def remote_register_params | def remote_register_params | ||||
| params.permit(:username, :email, :password, :platform) | params.permit(:username, :email, :password, :platform) | ||||
| end | end | ||||
| def simple_update_params | def simple_update_params | ||||
| params.permit(:username, :email, :password, :platform) | params.permit(:username, :email, :password, :platform) | ||||
| end | end | ||||
| @@ -10,12 +10,14 @@ class ApplicationController < ActionController::Base | |||||
| include LoggerHelper | include LoggerHelper | ||||
| include LoginHelper | include LoginHelper | ||||
| include RegisterHelper | include RegisterHelper | ||||
| include UpdateHelper | |||||
| protect_from_forgery prepend: true, unless: -> { request.format.json? } | protect_from_forgery prepend: true, unless: -> { request.format.json? } | ||||
| before_action :check_sign | before_action :check_sign | ||||
| before_action :user_setup | before_action :user_setup | ||||
| #before_action :check_account | #before_action :check_account | ||||
| after_action :user_trace_log | |||||
| # TODO | # TODO | ||||
| # check sql query time | # check sql query time | ||||
| @@ -25,6 +27,8 @@ class ApplicationController < ActionController::Base | |||||
| # end | # end | ||||
| end | end | ||||
| before_action :update_last_login_on | |||||
| DCODES = %W(2 3 4 5 6 7 8 9 a b c f e f g h i j k l m n o p q r s t u v w x y z) | DCODES = %W(2 3 4 5 6 7 8 9 a b c f e f g h i j k l m n o p q r s t u v w x y z) | ||||
| OPENKEY = Rails.application.config_for(:configuration)['sign_key'] || "79e33abd4b6588941ab7622aed1e67e8" | OPENKEY = Rails.application.config_for(:configuration)['sign_key'] || "79e33abd4b6588941ab7622aed1e67e8" | ||||
| @@ -82,7 +86,7 @@ class ApplicationController < ActionController::Base | |||||
| unless login =~ /^[a-zA-Z0-9]+([._\\]*[a-zA-Z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/ || login =~ /^1\d{10}$/ | unless login =~ /^[a-zA-Z0-9]+([._\\]*[a-zA-Z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/ || login =~ /^1\d{10}$/ | ||||
| tip_exception(-2, "请输入正确的手机号或邮箱") | tip_exception(-2, "请输入正确的手机号或邮箱") | ||||
| end | end | ||||
| user_exist = Owner.exists?(phone: login) || Owner.exists?(mail: login) | user_exist = Owner.exists?(phone: login) || Owner.exists?(mail: login) | ||||
| if user_exist && type.to_i == 1 | if user_exist && type.to_i == 1 | ||||
| tip_exception(-2, "该手机号码或邮箱已被注册") | tip_exception(-2, "该手机号码或邮箱已被注册") | ||||
| @@ -305,7 +309,7 @@ class ApplicationController < ActionController::Base | |||||
| User.current = User.find_by(id: @doorkeeper_token.resource_owner_id) | User.current = User.find_by(id: @doorkeeper_token.resource_owner_id) | ||||
| end | end | ||||
| end | end | ||||
| else | |||||
| else | |||||
| User.current = find_current_user | User.current = find_current_user | ||||
| uid_logger("user_setup: " + (User.current.logged? ? "#{User.current.try(:login)} (id=#{User.current.try(:id)})" : "anonymous")) | uid_logger("user_setup: " + (User.current.logged? ? "#{User.current.try(:login)} (id=#{User.current.try(:id)})" : "anonymous")) | ||||
| @@ -363,7 +367,19 @@ class ApplicationController < ActionController::Base | |||||
| # RSS key authentication does not start a session | # RSS key authentication does not start a session | ||||
| User.find_by_rss_key(params[:key]) | User.find_by_rss_key(params[:key]) | ||||
| end | end | ||||
| end | |||||
| end | |||||
| def user_trace_log | |||||
| user = current_user | |||||
| # print("*********************url:", request.url, "****routes", request.request_method) | |||||
| Rails.logger.user_trace.info("{id: #{user.id}, login: #{user.login}, url: #{request.url}, method: #{request.method}, params: #{params}, response_code: #{response.code}, time: #{Time.now}}") | |||||
| end | |||||
| def user_trace_update_log(old_value_hash) | |||||
| user = current_user | |||||
| str = "{id: #{user.id}, login: #{user.login}, url: #{request.url}, method: #{request.method}, params: #{params.merge(old_value: old_value_hash)}, response_code: #{response.code}, time: #{Time.now}}" | |||||
| Rails.logger.user_trace.info(str) | |||||
| end | |||||
| def try_to_autologin | def try_to_autologin | ||||
| if cookies[autologin_cookie_name] | if cookies[autologin_cookie_name] | ||||
| @@ -389,12 +405,17 @@ class ApplicationController < ActionController::Base | |||||
| respond_to do |format| | respond_to do |format| | ||||
| format.json | format.json | ||||
| end | end | ||||
| end | |||||
| end | |||||
| ## 输出错误信息 | |||||
| def error_status(message = nil) | |||||
| @status = -1 | |||||
| @message = message | |||||
| ## 输出错误信息 | |||||
| def error_status(message = nil) | |||||
| @status = -1 | |||||
| @message = message | |||||
| end | |||||
| # 实训等对应的仓库地址 | |||||
| def repo_ip_url(repo_path) | |||||
| "#{edu_setting('git_address_ip')}/#{repo_path}" | |||||
| end | end | ||||
| def repo_url(repo_path) | def repo_url(repo_path) | ||||
| @@ -633,6 +654,23 @@ class ApplicationController < ActionController::Base | |||||
| ss | ss | ||||
| end | end | ||||
| def strip_html(text, len=0, endss="...") | |||||
| ss = "" | |||||
| if !text.nil? && text.length>0 | |||||
| ss=text.gsub(/<\/?.*?>/, '').strip | |||||
| ss = ss.gsub(/ */, '') | |||||
| ss = ss.gsub(/\r\n/,'') #新增 | |||||
| ss = ss.gsub(/\n/,'') #新增 | |||||
| if len > 0 && ss.length > len | |||||
| ss = ss[0, len] + endss | |||||
| elsif len > 0 && ss.length <= len | |||||
| ss = ss | |||||
| #ss = truncate(ss, :length => len) | |||||
| end | |||||
| end | |||||
| ss | |||||
| end | |||||
| # Returns a string that can be used as filename value in Content-Disposition header | # Returns a string that can be used as filename value in Content-Disposition header | ||||
| def filename_for_content_disposition(name) | def filename_for_content_disposition(name) | ||||
| request.env['HTTP_USER_AGENT'] =~ %r{MSIE|Trident|Edge} ? ERB::Util.url_encode(name) : name | request.env['HTTP_USER_AGENT'] =~ %r{MSIE|Trident|Edge} ? ERB::Util.url_encode(name) : name | ||||
| @@ -644,8 +682,8 @@ class ApplicationController < ActionController::Base | |||||
| # 获取Oauth Client | # 获取Oauth Client | ||||
| def get_client(site) | def get_client(site) | ||||
| client_id = Rails.configuration.Gitlink['client_id'] | |||||
| client_secret = Rails.configuration.Gitlink['client_secret'] | |||||
| client_id = Rails.configuration.educoder['client_id'] | |||||
| client_secret = Rails.configuration.educoder['client_secret'] | |||||
| OAuth2::Client.new(client_id, client_secret, site: site) | OAuth2::Client.new(client_id, client_secret, site: site) | ||||
| end | end | ||||
| @@ -665,7 +703,7 @@ class ApplicationController < ActionController::Base | |||||
| def kaminari_paginate(relation) | def kaminari_paginate(relation) | ||||
| limit = params[:limit] || params[:per_page] | limit = params[:limit] || params[:per_page] | ||||
| limit = (limit.to_i.zero? || limit.to_i > 50) ? 50 : limit.to_i | |||||
| limit = (limit.to_i.zero? || limit.to_i > 15) ? 15 : limit.to_i | |||||
| page = params[:page].to_i.zero? ? 1 : params[:page].to_i | page = params[:page].to_i.zero? ? 1 : params[:page].to_i | ||||
| relation.page(page).per(limit) | relation.page(page).per(limit) | ||||
| @@ -750,11 +788,11 @@ class ApplicationController < ActionController::Base | |||||
| # @project = nil if !@project.is_public? | # @project = nil if !@project.is_public? | ||||
| # render_forbidden and return | # render_forbidden and return | ||||
| else | else | ||||
| if @project.present? | |||||
| if @project.present? | |||||
| logger.info "###########: has project and but can't read project" | logger.info "###########: has project and but can't read project" | ||||
| @project = nil | @project = nil | ||||
| render_forbidden and return | render_forbidden and return | ||||
| else | |||||
| else | |||||
| logger.info "###########:project not found" | logger.info "###########:project not found" | ||||
| @project = nil | @project = nil | ||||
| render_not_found and return | render_not_found and return | ||||
| @@ -799,21 +837,54 @@ class ApplicationController < ActionController::Base | |||||
| end | end | ||||
| private | private | ||||
| def object_not_found | |||||
| uid_logger("Missing template or cant't find record, responding with 404") | |||||
| render json: {message: "您访问的页面不存在或已被删除", status: 404} | |||||
| false | |||||
| def update_last_login_on | |||||
| if current_user.logged? | |||||
| current_user.update_column(:last_login_on, Time.now) | |||||
| end | |||||
| end | end | ||||
| def object_not_found | |||||
| uid_logger("Missing template or cant't find record, responding with 404") | |||||
| render json: {message: "您访问的页面不存在或已被删除", status: 404} | |||||
| false | |||||
| end | |||||
| def tip_show(exception) | def tip_show(exception) | ||||
| uid_logger("Tip show status is #{exception.status}, message is #{exception.message}") | uid_logger("Tip show status is #{exception.status}, message is #{exception.message}") | ||||
| render json: exception.tip_json | render json: exception.tip_json | ||||
| end | end | ||||
| def render_parameter_missing | |||||
| render json: { status: -1, message: '参数缺失' } | |||||
| end | |||||
| def set_export_cookies | def set_export_cookies | ||||
| cookies[:fileDownload] = true | cookies[:fileDownload] = true | ||||
| end | end | ||||
| # 149课程的评审用户数据创建(包含创建课堂学生) | |||||
| def open_class_user | |||||
| user = User.find_by(login: "OpenClassUser") | |||||
| unless user | |||||
| ActiveRecord::Base.transaction do | |||||
| user_params = {status: 1, login: "OpenClassUser", lastname: "开放课程", | |||||
| nickname: "开放课程", professional_certification: 1, certification: 1, grade: 0, | |||||
| password: "12345678", phone: "11122223333", profile_completed: 1} | |||||
| user = User.create!(user_params) | |||||
| UserExtension.create!(user_id: user.id, gender: 0, school_id: 3396, :identity => 1, :student_id => "openclassuser") # 3396 | |||||
| subject = Subject.find_by(id: 149) | |||||
| if subject | |||||
| subject.courses.each do |course| | |||||
| CourseMember.create!(course_id: course.id, role: 3, user_id: user.id) if !course.course_members.exists?(user_id: user.id) | |||||
| end | |||||
| end | |||||
| end | |||||
| end | |||||
| user | |||||
| end | |||||
| # 记录热门搜索关键字 | # 记录热门搜索关键字 | ||||
| def record_search_keyword | def record_search_keyword | ||||
| keyword = params[:keyword].to_s.strip | keyword = params[:keyword].to_s.strip | ||||
| @@ -6,10 +6,10 @@ class CompareController < ApplicationController | |||||
| end | end | ||||
| def show | def show | ||||
| if params[:type] == "sha" | |||||
| if params[:type] == "sha" | |||||
| load_compare_params | load_compare_params | ||||
| @compare_result ||= gitea_compare(@base, @head) | @compare_result ||= gitea_compare(@base, @head) | ||||
| else | |||||
| else | |||||
| load_compare_params | load_compare_params | ||||
| compare | compare | ||||
| @merge_status, @merge_message = get_merge_message | @merge_status, @merge_message = get_merge_message | ||||
| @@ -63,7 +63,7 @@ class CompareController < ApplicationController | |||||
| Gitea::Repository::Commits::CompareService.call(@owner.login, @project.identifier, Addressable::URI.escape(base), Addressable::URI.escape(head), current_user.gitea_token) | Gitea::Repository::Commits::CompareService.call(@owner.login, @project.identifier, Addressable::URI.escape(base), Addressable::URI.escape(head), current_user.gitea_token) | ||||
| end | end | ||||
| def page_size | |||||
| def page_size | |||||
| params.fetch(:page, 1).to_i | params.fetch(:page, 1).to_i | ||||
| end | end | ||||
| @@ -44,6 +44,7 @@ module LoginHelper | |||||
| set_autologin_cookie(user) | set_autologin_cookie(user) | ||||
| UserAction.create(action_id: user&.id, action_type: 'Login', user_id: user&.id, ip: request.remote_ip) | UserAction.create(action_id: user&.id, action_type: 'Login', user_id: user&.id, ip: request.remote_ip) | ||||
| # user.daily_reward | |||||
| user.update_column(:last_login_on, Time.now) | user.update_column(:last_login_on, Time.now) | ||||
| # 注册完成后有一天的试用申请(先去掉) | # 注册完成后有一天的试用申请(先去掉) | ||||
| # UserDayCertification.create(user_id: user.id, status: 1) | # UserDayCertification.create(user_id: user.id, status: 1) | ||||
| @@ -3,9 +3,12 @@ class ForksController < ApplicationController | |||||
| before_action :require_profile_completed, only: [:create] | before_action :require_profile_completed, only: [:create] | ||||
| before_action :load_project | before_action :load_project | ||||
| before_action :authenticate_project!, :authenticate_user! | before_action :authenticate_project!, :authenticate_user! | ||||
| skip_after_action :user_trace_log, only: [:create] | |||||
| def create | def create | ||||
| @new_project = Projects::ForkService.new(current_user, @project, params[:organization]).call | @new_project = Projects::ForkService.new(current_user, @project, params[:organization]).call | ||||
| user = current_user | |||||
| Rails.logger.user_trace.info("{id: #{user.id}, login: #{user.login}, url: #{request.url}, method: #{request.method}, params: #{params.merge(forkee: @new_project.id)}, response_code: #{response.code}, time: #{Time.now}}") | |||||
| end | end | ||||
| private | private | ||||
| @@ -11,6 +11,8 @@ class IssuesController < ApplicationController | |||||
| before_action :set_issue, only: [:edit, :update, :destroy, :show, :copy, :close_issue, :lock_issue] | before_action :set_issue, only: [:edit, :update, :destroy, :show, :copy, :close_issue, :lock_issue] | ||||
| before_action :check_token_enough, :find_atme_receivers, only: [:create, :update] | before_action :check_token_enough, :find_atme_receivers, only: [:create, :update] | ||||
| skip_after_action :user_trace_log, only: [:update] | |||||
| include ApplicationHelper | include ApplicationHelper | ||||
| include TagChosenHelper | include TagChosenHelper | ||||
| @@ -218,6 +220,7 @@ class IssuesController < ApplicationController | |||||
| # end | # end | ||||
| # end | # end | ||||
| # end | # end | ||||
| issue_hash = old_value_to_hash(@issue, params) | |||||
| if @issue.issue_type.to_s == "2" && params[:status_id].to_i == 5 && @issue.author_id != current_user.try(:id) | if @issue.issue_type.to_s == "2" && params[:status_id].to_i == 5 && @issue.author_id != current_user.try(:id) | ||||
| normal_status(-1, "不允许修改为关闭状态") | normal_status(-1, "不允许修改为关闭状态") | ||||
| @@ -225,6 +228,9 @@ class IssuesController < ApplicationController | |||||
| issue_params = issue_send_params(params).except(:issue_classify, :author_id, :project_id) | issue_params = issue_send_params(params).except(:issue_classify, :author_id, :project_id) | ||||
| Issues::UpdateForm.new({subject: issue_params[:subject], description: issue_params[:description].blank? ? issue_params[:description] : issue_params[:description].b}).validate! | Issues::UpdateForm.new({subject: issue_params[:subject], description: issue_params[:description].blank? ? issue_params[:description] : issue_params[:description].b}).validate! | ||||
| if @issue.update_attributes(issue_params) | if @issue.update_attributes(issue_params) | ||||
| user_trace_update_log(issue_hash) | |||||
| if @issue&.pull_request.present? | if @issue&.pull_request.present? | ||||
| SendTemplateMessageJob.perform_later('PullRequestChanged', current_user.id, @issue&.pull_request&.id, @issue.previous_changes.slice(:assigned_to_id, :priority_id, :fixed_version_id, :issue_tags_value)) if Site.has_notice_menu? | SendTemplateMessageJob.perform_later('PullRequestChanged', current_user.id, @issue&.pull_request&.id, @issue.previous_changes.slice(:assigned_to_id, :priority_id, :fixed_version_id, :issue_tags_value)) if Site.has_notice_menu? | ||||
| SendTemplateMessageJob.perform_later('PullRequestAssigned', current_user.id, @issue&.pull_request&.id ) if @issue.previous_changes[:assigned_to_id].present? && Site.has_notice_menu? | SendTemplateMessageJob.perform_later('PullRequestAssigned', current_user.id, @issue&.pull_request&.id ) if @issue.previous_changes[:assigned_to_id].present? && Site.has_notice_menu? | ||||
| @@ -4,6 +4,7 @@ class JournalsController < ApplicationController | |||||
| before_action :set_issue | before_action :set_issue | ||||
| before_action :check_issue_permission | before_action :check_issue_permission | ||||
| before_action :set_journal, only: [:destroy, :edit, :update] | before_action :set_journal, only: [:destroy, :edit, :update] | ||||
| skip_after_action :user_trace_log, only: [:update] | |||||
| def index | def index | ||||
| @page = params[:page] || 1 | @page = params[:page] || 1 | ||||
| @@ -74,9 +75,11 @@ class JournalsController < ApplicationController | |||||
| def update | def update | ||||
| content = params[:content] | content = params[:content] | ||||
| if content.present? | |||||
| if content.present? | |||||
| old_value = old_value_to_hash(@journal, params) | |||||
| Journals::UpdateForm.new({notes: notes.to_s.strip.blank? ? notes.to_s.strip : notes.to_s.strip.b}).validate! | Journals::UpdateForm.new({notes: notes.to_s.strip.blank? ? notes.to_s.strip : notes.to_s.strip.b}).validate! | ||||
| if @journal.update_attribute(:notes, content) | if @journal.update_attribute(:notes, content) | ||||
| user_trace_update_log(old_value) | |||||
| normal_status(0, "更新成功") | normal_status(0, "更新成功") | ||||
| else | else | ||||
| normal_status(-1, "更新失败") | normal_status(-1, "更新失败") | ||||
| @@ -0,0 +1,19 @@ | |||||
| class LogController < ApplicationController | |||||
| def list | |||||
| path = "#{Rails.root}/log" | |||||
| @file_list = [] | |||||
| Dir.foreach(path) do |file| | |||||
| @file_list << file | |||||
| end | |||||
| @file_list = @file_list.sort | |||||
| end | |||||
| def download | |||||
| path = "#{Rails.root}/log/#{params[:filename]}" | |||||
| if params[:filename] && File.exist?(path) && File.file?(path) | |||||
| send_file(path, filename: params[:filename]) | |||||
| else | |||||
| render json: { message: 'no such file!' } | |||||
| end | |||||
| end | |||||
| end | |||||
| @@ -6,6 +6,7 @@ class MembersController < ApplicationController | |||||
| before_action :operate! | before_action :operate! | ||||
| before_action :check_member_exists!, only: %i[create] | before_action :check_member_exists!, only: %i[create] | ||||
| before_action :check_member_not_exists!, only: %i[remove change_role] | before_action :check_member_not_exists!, only: %i[remove change_role] | ||||
| skip_after_action :user_trace_log, only: [:change_role] | |||||
| def create | def create | ||||
| interactor = Projects::AddMemberInteractor.call(@project.owner, @project, @user) | interactor = Projects::AddMemberInteractor.call(@project.owner, @project, @user) | ||||
| @@ -42,7 +43,9 @@ class MembersController < ApplicationController | |||||
| end | end | ||||
| def change_role | def change_role | ||||
| old_value = @project.members.where(user_id: params[:user_id])[0].roles.last.name | |||||
| interactor = Projects::ChangeMemberRoleInteractor.call(@project.owner, @project, @user, params[:role]) | interactor = Projects::ChangeMemberRoleInteractor.call(@project.owner, @project, @user, params[:role]) | ||||
| user_trace_update_log(old_value) | |||||
| SendTemplateMessageJob.perform_later('ProjectRole', current_user.id, @user.id, @project.id, message_role_name) if Site.has_notice_menu? | SendTemplateMessageJob.perform_later('ProjectRole', current_user.id, @user.id, @project.id, message_role_name) if Site.has_notice_menu? | ||||
| render_response(interactor) | render_response(interactor) | ||||
| rescue Exception => e | rescue Exception => e | ||||
| @@ -6,6 +6,8 @@ class PullRequestsController < ApplicationController | |||||
| before_action :find_pull_request, except: [:index, :new, :create, :check_can_merge,:get_branches,:create_merge_infos, :files, :commits] | before_action :find_pull_request, except: [:index, :new, :create, :check_can_merge,:get_branches,:create_merge_infos, :files, :commits] | ||||
| before_action :load_pull_request, only: [:files, :commits] | before_action :load_pull_request, only: [:files, :commits] | ||||
| before_action :find_atme_receivers, only: [:create, :update] | before_action :find_atme_receivers, only: [:create, :update] | ||||
| skip_after_action :user_trace_log, only: [:update] | |||||
| include TagChosenHelper | include TagChosenHelper | ||||
| include ApplicationHelper | include ApplicationHelper | ||||
| @@ -103,8 +105,13 @@ class PullRequestsController < ApplicationController | |||||
| reviewers = User.where(id: params[:reviewer_ids]) | reviewers = User.where(id: params[:reviewer_ids]) | ||||
| @pull_request.reviewers = reviewers | @pull_request.reviewers = reviewers | ||||
| old_issue_value = old_value_to_hash(@issue, @issue_params) | |||||
| old_pr_value = old_value_to_hash(@pull_request, @local_params.compact) | |||||
| old_value = {issue: old_issue_value, pull_request: old_pr_value} | |||||
| if @issue.update_attributes(@issue_params) | if @issue.update_attributes(@issue_params) | ||||
| if @pull_request.update_attributes(@local_params.compact) | if @pull_request.update_attributes(@local_params.compact) | ||||
| user_trace_update_log(old_value) | |||||
| gitea_pull = Gitea::PullRequest::UpdateService.call(@owner.login, @repository.identifier, | gitea_pull = Gitea::PullRequest::UpdateService.call(@owner.login, @repository.identifier, | ||||
| @pull_request.gitea_number, @requests_params, current_user.gitea_token) | @pull_request.gitea_number, @requests_params, current_user.gitea_token) | ||||
| @@ -119,7 +126,7 @@ class PullRequestsController < ApplicationController | |||||
| end | end | ||||
| else | else | ||||
| return normal_status(-1, "请输入正确的标记。") | return normal_status(-1, "请输入正确的标记。") | ||||
| end | |||||
| end | |||||
| end | end | ||||
| if params[:status_id].to_i == 5 | if params[:status_id].to_i == 5 | ||||
| @issue.issue_times.update_all(end_time: Time.now) | @issue.issue_times.update_all(end_time: Time.now) | ||||
| @@ -1,6 +1,7 @@ | |||||
| class SettingsController < ApplicationController | class SettingsController < ApplicationController | ||||
| def show | def show | ||||
| @old_projects_url = nil | @old_projects_url = nil | ||||
| @old_projects_url = "https://www.trustie.net/users/#{current_user.try(:login)}/projects" if User.current.logged? | |||||
| get_navbar | get_navbar | ||||
| get_add_menu | get_add_menu | ||||
| get_common_menu | get_common_menu | ||||
| @@ -12,14 +13,14 @@ class SettingsController < ApplicationController | |||||
| end | end | ||||
| private | private | ||||
| def get_navbar | |||||
| def get_navbar | |||||
| @navbar = default_laboratory.navbar | @navbar = default_laboratory.navbar | ||||
| if User.current.logged? | if User.current.logged? | ||||
| pernal_index = {"name"=>"个人主页", "link"=>get_site_url("url", "#{Rails.application.config_for(:configuration)['platform_url']}/current_user"), "hidden"=>false} | pernal_index = {"name"=>"个人主页", "link"=>get_site_url("url", "#{Rails.application.config_for(:configuration)['platform_url']}/current_user"), "hidden"=>false} | ||||
| @navbar << pernal_index | @navbar << pernal_index | ||||
| end | end | ||||
| end | end | ||||
| def get_add_menu | def get_add_menu | ||||
| @add = [] | @add = [] | ||||
| Site.add.select(:id, :name, :url, :key).to_a.map(&:serializable_hash).each do |site| | Site.add.select(:id, :name, :url, :key).to_a.map(&:serializable_hash).each do |site| | ||||
| @@ -86,7 +87,7 @@ class SettingsController < ApplicationController | |||||
| } | } | ||||
| end | end | ||||
| end | end | ||||
| def get_top_system_notification | def get_top_system_notification | ||||
| @top_system_notification = SystemNotification.is_top.first | @top_system_notification = SystemNotification.is_top.first | ||||
| end | end | ||||
| @@ -0,0 +1,90 @@ | |||||
| class SponsorTiersController < ApplicationController | |||||
| before_action :set_sponsor_tier, only: [:show, :edit, :update, :destroy] | |||||
| before_action :check_sponsor, only: [:show] | |||||
| before_action :require_login, only: [:create, :update, :destroy] | |||||
| # GET /sponsor_tiers | |||||
| # GET /sponsor_tiers.json | |||||
| def index | |||||
| # @sponsor_tiers = SponsorTier.all | |||||
| user = User.find_by_login(params[:login]) | |||||
| @sponsor_tiers = user.sponsor_tier | |||||
| end | |||||
| # GET /sponsor_tiers/1 | |||||
| # GET /sponsor_tiers/1.json | |||||
| def show | |||||
| end | |||||
| # POST /sponsor_tiers | |||||
| # POST /sponsor_tiers.json | |||||
| def create | |||||
| # print("------------\n", sponsor_tier_params, "\n------------\n") | |||||
| @check_sponsorship = nil | |||||
| @sponsor_tier = SponsorTier.new(sponsor_tier_params) | |||||
| respond_to do |format| | |||||
| if @sponsor_tier.user_id == User.current.id && @sponsor_tier.save | |||||
| format.html { redirect_to @sponsor_tier, notice: 'Sponsor tier was successfully created.' } | |||||
| format.json { render :show, status: :created, location: @sponsor_tier } | |||||
| # render json: {status: 1, message: '创建成功' } | |||||
| else | |||||
| format.html { render :new } | |||||
| format.json { render json: @sponsor_tier.errors, status: :unprocessable_entity } | |||||
| end | |||||
| end | |||||
| end | |||||
| # PATCH/PUT /sponsor_tiers/1 | |||||
| # PATCH/PUT /sponsor_tiers/1.json | |||||
| def update | |||||
| @check_sponsorship = nil | |||||
| old_value = old_value_to_hash(@sponsor_tier, params) | |||||
| respond_to do |format| | |||||
| if User.current.id == @sponsor_tier.user_id && @sponsor_tier.update(sponsor_tier_update_params) | |||||
| user_trace_update_log(old_value) | |||||
| format.html { redirect_to @sponsor_tier, notice: 'Sponsor tier was successfully updated.' } | |||||
| format.json { render :show, status: :ok, location: @sponsor_tier } | |||||
| # render json: {status: 1, message: '修改成功' } | |||||
| else | |||||
| format.html { render :edit } | |||||
| format.json { render json: @sponsor_tier.errors, status: :unprocessable_entity } | |||||
| # format.json { render status: :unprocessable_entity } | |||||
| # render json: {status: -1, message: '修改失败' } | |||||
| end | |||||
| end | |||||
| end | |||||
| # DELETE /sponsor_tiers/1 | |||||
| # DELETE /sponsor_tiers/1.json | |||||
| def destroy | |||||
| if User.current.id == @sponsor_tier.user_id | |||||
| @sponsor_tier.destroy | |||||
| respond_to do |format| | |||||
| format.html { redirect_to sponsor_tiers_url, notice: 'Sponsor tier was successfully destroyed.' } | |||||
| format.json { head :no_content } | |||||
| end | |||||
| else | |||||
| format.json { render json: @sponsor_tier.errors, status: :unprocessable_entity } | |||||
| end | |||||
| end | |||||
| private | |||||
| # Use callbacks to share common setup or constraints between actions. | |||||
| def check_sponsor | |||||
| @check_sponsorship = Sponsorship.where("sponsor_id=? AND developer_id=?", current_user.id, @sponsor_tier.user.id) | |||||
| end | |||||
| def set_sponsor_tier | |||||
| @sponsor_tier = SponsorTier.find(params[:id]) | |||||
| end | |||||
| def sponsor_tier_update_params | |||||
| params.require(:sponsor_tier).permit(:tier, :description) | |||||
| end | |||||
| # Only allow a list of trusted parameters through. | |||||
| def sponsor_tier_params | |||||
| params.require(:sponsor_tier).permit(:tier, :user_id, :description) | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,212 @@ | |||||
| class SponsorshipsController < ApplicationController | |||||
| before_action :set_sponsorship, only: [:show, :edit, :update, :destroy] | |||||
| # before_action :require_login, except: [:index, :stopped, :sponsored, :sponsoring, :stopped_sponsored, :stopped_sponsoring] | |||||
| before_action :require_login, only: [:create, :edit, :update, :destroy] | |||||
| skip_after_action :user_trace_log, only: [:update] | |||||
| # GET /sponsorships | |||||
| # GET /sponsorships.json | |||||
| def index | |||||
| @sponsorships = Sponsorship.all | |||||
| end | |||||
| def stopped | |||||
| @stopped_sponsorships = StoppedSponsorship.all | |||||
| end | |||||
| def sponsored | |||||
| if User.current.id == Integer(params[:id]) | |||||
| @sponsorships = Sponsorship.where('developer_id=?', params[:id]) | |||||
| else | |||||
| @sponsorships = Sponsorship.where('developer_id=? AND visible=1', params[:id]) | |||||
| end | |||||
| sort = params[:sort_by] || 'created_at' | |||||
| sort_direction = params[:sort_direction] || 'desc' | |||||
| @sponsorships = @sponsorships.reorder("#{sort} #{sort_direction}") | |||||
| @total = @sponsorships.length | |||||
| @sponsorships = kaminari_paginate(@sponsorships) | |||||
| end | |||||
| def sponsoring | |||||
| if User.current.id == Integer(params[:id]) | |||||
| @sponsorships = Sponsorship.where('sponsor_id=?', params[:id]) | |||||
| else | |||||
| @sponsorships = Sponsorship.where('sponsor_id=? AND visible=1', params[:id]) | |||||
| end | |||||
| sort = params[:sort_by] || 'created_at' | |||||
| sort_direction = params[:sort_direction] || 'desc' | |||||
| @sponsorships = @sponsorships.reorder("#{sort} #{sort_direction}") | |||||
| @total = @sponsorships.length | |||||
| @sponsorships = kaminari_paginate(@sponsorships) | |||||
| end | |||||
| def stopped_sponsored | |||||
| if User.current.id == Integer(params[:id]) | |||||
| @stopped_sponsorships = StoppedSponsorship.where('developer_id=?', params[:id]) | |||||
| else | |||||
| @stopped_sponsorships = StoppedSponsorship.where('developer_id=? AND visible=1', params[:id]) | |||||
| end | |||||
| sort = params[:sort_by] || 'created_at' | |||||
| sort_direction = params[:sort_direction] || 'desc' | |||||
| @stopped_sponsorships = @stopped_sponsorships.reorder("#{sort} #{sort_direction}") | |||||
| @total = @stopped_sponsorships.length | |||||
| @stopped_sponsorships = kaminari_paginate(@stopped_sponsorships) | |||||
| end | |||||
| def stopped_sponsoring | |||||
| if User.current.id == Integer(params[:id]) | |||||
| @stopped_sponsorships = StoppedSponsorship.where('sponsor_id=?', params[:id]) | |||||
| else | |||||
| @stopped_sponsorships = StoppedSponsorship.where('sponsor_id=? AND visible=1', params[:id]) | |||||
| end | |||||
| sort = params[:sort_by] || 'created_at' | |||||
| sort_direction = params[:sort_direction] || 'desc' | |||||
| @stopped_sponsorships = @stopped_sponsorships.reorder("#{sort} #{sort_direction}") | |||||
| @total = @stopped_sponsorships.length | |||||
| @stopped_sponsorships = kaminari_paginate(@stopped_sponsorships) | |||||
| end | |||||
| # GET /sponsorships/1 | |||||
| # GET /sponsorships/1.json | |||||
| def show; end | |||||
| # POST /sponsorships | |||||
| # POST /sponsorships.json | |||||
| def create | |||||
| sponsor_id = User.current.id | |||||
| check_sponsorship = Sponsorship.where('sponsor_id=? AND developer_id=?', sponsor_id, params[:developer_id]) | |||||
| @sponsorship = Sponsorship.new(sponsorship_params.merge({sponsor_id: sponsor_id})) | |||||
| unless check_sponsorship.length.zero? | |||||
| return render json: {status: -1, message: '您已经赞助了TA' } | |||||
| end | |||||
| if @sponsorship.pay && @sponsorship.save | |||||
| if params[:single] && @sponsorship.stop | |||||
| return render json: { status: 1, message: '赞助成功' } | |||||
| elsif !params[:single] | |||||
| User.current.update(sponsor_num: User.current.sponsor_num+1) | |||||
| @sponsorship.developer.update(sponsored_num: @sponsorship.developer.sponsored_num + 1) | |||||
| return render json: { status: 1, message: '赞助成功' } | |||||
| else | |||||
| return render json: { status: -1, message: '赞助失败' } | |||||
| end | |||||
| else | |||||
| return render json: { status: -1, message: '赞助失败' } | |||||
| end | |||||
| # return render_result message: '赞助成功' if @sponsorship.save | |||||
| # respond_to do |format| | |||||
| # if check_sponsorship.length.zero? && @sponsorship.save | |||||
| # format.html { redirect_to @sponsorship, notice: 'Sponsorship was successfully created.' } | |||||
| # format.json { render :show, status: :created, location: @sponsorship } | |||||
| # # render_result status=0, message="赞助成功" | |||||
| # else | |||||
| # format.html { render :new } | |||||
| # format.json { render json: @sponsorship.errors, status: :unprocessable_entity } | |||||
| # end | |||||
| # end | |||||
| end | |||||
| # PATCH/PUT /sponsorships/1 | |||||
| # PATCH/PUT /sponsorships/1.json | |||||
| def update | |||||
| # respond_to do |format| | |||||
| # if @sponsorship.update(sponsorship_params) | |||||
| # format.html { redirect_to @sponsorship, notice: 'Sponsorship was successfully updated.' } | |||||
| # format.json { render :show, status: :ok, location: @sponsorship } | |||||
| # else | |||||
| # format.html { render :edit } | |||||
| # format.json { render json: @sponsorship.errors, status: :unprocessable_entity } | |||||
| # end | |||||
| # end | |||||
| if @sponsorship.sponsor.id != current_user.id | |||||
| return render json: {status: 401, message: '没有权限' } | |||||
| end | |||||
| old_value = old_value_to_hash(@sponsorship, params) | |||||
| if @sponsorship.update(sponsorship_params) | |||||
| user_trace_update_log(old_value) | |||||
| render json: {status: 1, message: '修改成功' } | |||||
| else | |||||
| render json: {status: -1, message: '修改失败' } | |||||
| end | |||||
| end | |||||
| # DELETE /sponsorships/1 | |||||
| # DELETE /sponsorships/1.json | |||||
| def destroy | |||||
| # @sponsorship.destroy | |||||
| # respond_to do |format| | |||||
| # format.html { redirect_to sponsorships_url, notice: 'Sponsorship was successfully destroyed.' } | |||||
| # format.json { head :no_content } | |||||
| # end | |||||
| developer = @sponsorship.developer | |||||
| sponsor = @sponsorship.sponsor | |||||
| if (User.current.id == developer.id || User.current.id == sponsor.id) && developer.update(sponsored_num: developer.sponsored_num-1) && sponsor.update(sponsor_num: sponsor.sponsor_num-1) && @sponsorship.stop | |||||
| render json: {status: 1, message: '终止成功'} | |||||
| else | |||||
| render json: {status: -1, message: '失败'} | |||||
| end | |||||
| end | |||||
| def community_data | |||||
| @sponsorships = Sponsorship.all | |||||
| t1 = Time.now | |||||
| t2 = Time.new(t1.year, t1.month, t1.day - 6) | |||||
| @stopped_sponsorships = StoppedSponsorship.where('created_at >= ?', t2) | |||||
| @community_data_array = to_array(@sponsorships, @stopped_sponsorships) | |||||
| end | |||||
| private | |||||
| # Use callbacks to share common setup or constraints between actions. | |||||
| def set_sponsorship | |||||
| @sponsorship = Sponsorship.find(params[:id]) | |||||
| end | |||||
| # Only allow a list of trusted parameters through. | |||||
| def sponsorship_params | |||||
| params.require(:sponsorship).permit(:amount, :visible, :sponsor_id, :developer_id, :single, :page, :limit, :sort_by, :search) | |||||
| end | |||||
| def to_array(sponsorships, stopped_sponsorships) | |||||
| t1 = Time.now | |||||
| start_time = Time.new(t1.year, t1.month, t1.day - 6) | |||||
| sponsor = Array.new(7) | |||||
| sponsored = Array.new(7) | |||||
| date = Array.new(7) | |||||
| # date[0] = Time.new(start_time.year, start_time.month, start_time.day) | |||||
| index = 0 | |||||
| (0..6).each do |i| | |||||
| # 更新日期,date[i]表示第i天0点 | |||||
| date[i] = Time.new(start_time.year, start_time.month, start_time.day + i) | |||||
| end_time = Time.new(start_time.year, start_time.month, start_time.day + i+1) | |||||
| sponsor_set = Set.new | |||||
| sponsored_set = Set.new | |||||
| # 所有创建时间早于今天23:59的sponsorship | |||||
| today_sponsor = sponsorships.where('created_at < ?', end_time) | |||||
| # 所有结束时间晚于今天0:00的stopped_sponsorship | |||||
| today_stopped_sponsor = stopped_sponsorships.where('created_at <= ?', date[i]) | |||||
| today_sponsor.each do |s| | |||||
| sponsor_set.add s.sponsor_id | |||||
| sponsored_set.add s.developer_id | |||||
| end | |||||
| today_stopped_sponsor.each do |s| | |||||
| sponsor_set.add s.sponsor_id | |||||
| sponsored_set.add s.developer_id | |||||
| end | |||||
| sponsor[i] = sponsor_set.size | |||||
| sponsored[i] = sponsored_set.size | |||||
| end | |||||
| Array[sponsor, sponsored, date] | |||||
| end | |||||
| end | |||||
| @@ -94,11 +94,11 @@ class UsersController < ApplicationController | |||||
| end | end | ||||
| end | end | ||||
| def update_image | |||||
| return render_not_found unless @user = User.find_by(login: params[:id]) || User.find_by_id(params[:id]) | |||||
| def update_image | |||||
| return render_not_found unless @user = User.find_by(login: params[:id]) || User.find_by_id(params[:id]) | |||||
| return render_forbidden unless User.current.logged? && (current_user&.admin? || current_user.id == @user.id) | return render_forbidden unless User.current.logged? && (current_user&.admin? || current_user.id == @user.id) | ||||
| Util.write_file(@image, avatar_path(@user)) | |||||
| Util.write_file(@image, avatar_path(@user)) | |||||
| return render_ok({message: '头像修改成功'}) | return render_ok({message: '头像修改成功'}) | ||||
| rescue Exception => e | rescue Exception => e | ||||
| uid_logger_error(e.message) | uid_logger_error(e.message) | ||||
| @@ -141,6 +141,10 @@ class UsersController < ApplicationController | |||||
| end | end | ||||
| # TODO 等消息上线再打开注释 | # TODO 等消息上线再打开注释 | ||||
| #@tidding_count = unviewed_tiddings(current_user) if current_user.present? | #@tidding_count = unviewed_tiddings(current_user) if current_user.present? | ||||
| # | |||||
| if(@user.logged?) | |||||
| @user.daily_reward | |||||
| end | |||||
| rescue Exception => e | rescue Exception => e | ||||
| uid_logger_error(e.message) | uid_logger_error(e.message) | ||||
| missing_template | missing_template | ||||
| @@ -302,6 +306,21 @@ class UsersController < ApplicationController | |||||
| render_ok | render_ok | ||||
| end | end | ||||
| def update_sponsor_description | |||||
| @user = User.find params[:id] | |||||
| if @user.id == User.current.id | |||||
| # @user.update(description: params[:description]) | |||||
| @user.sponsor_description = params[:sponsor_description] | |||||
| if @user.save! | |||||
| render_ok | |||||
| else | |||||
| render_error | |||||
| end | |||||
| else | |||||
| render_error | |||||
| end | |||||
| end | |||||
| def sync_user_info | def sync_user_info | ||||
| user = User.find_by_login params[:login] | user = User.find_by_login params[:login] | ||||
| return render_forbidden unless user === current_user | return render_forbidden unless user === current_user | ||||
| @@ -322,7 +341,7 @@ class UsersController < ApplicationController | |||||
| end | end | ||||
| end | end | ||||
| def email_search | |||||
| def email_search | |||||
| return render_error('请输入email') if params[:email].blank? | return render_error('请输入email') if params[:email].blank? | ||||
| @user = User.find_by(mail: params[:email]) | @user = User.find_by(mail: params[:email]) | ||||
| end | end | ||||
| @@ -339,7 +358,7 @@ class UsersController < ApplicationController | |||||
| :occupation, :technical_title, | :occupation, :technical_title, | ||||
| :school_id, :department_id, :province, :city, | :school_id, :department_id, :province, :city, | ||||
| :custom_department, :identity, :student_id, :description, | :custom_department, :identity, :student_id, :description, | ||||
| :show_super_description, :super_description, | |||||
| :show_super_description, :super_description,:sponsor_description, | |||||
| :show_email, :show_location, :show_department] | :show_email, :show_location, :show_department] | ||||
| ) | ) | ||||
| end | end | ||||
| @@ -4,6 +4,7 @@ class VersionReleasesController < ApplicationController | |||||
| before_action :require_login, except: [:index, :show] | before_action :require_login, except: [:index, :show] | ||||
| before_action :check_release_authorize, except: [:index, :show] | before_action :check_release_authorize, except: [:index, :show] | ||||
| before_action :find_version , only: [:show, :edit, :update, :destroy] | before_action :find_version , only: [:show, :edit, :update, :destroy] | ||||
| skip_after_action :user_trace_log, only: [:update] | |||||
| def index | def index | ||||
| @version_releases = kaminari_paginate(@repository.version_releases.order(created_at: :desc)) | @version_releases = kaminari_paginate(@repository.version_releases.order(created_at: :desc)) | ||||
| @@ -22,7 +23,7 @@ class VersionReleasesController < ApplicationController | |||||
| end | end | ||||
| end | end | ||||
| def show | |||||
| def show | |||||
| # @release = Gitea::Versions::GetService.call(current_user.gitea_token, @user&.login, @repository&.identifier, @version&.version_gid) | # @release = Gitea::Versions::GetService.call(current_user.gitea_token, @user&.login, @repository&.identifier, @version&.version_gid) | ||||
| end | end | ||||
| @@ -83,14 +84,14 @@ class VersionReleasesController < ApplicationController | |||||
| ActiveRecord::Base.transaction do | ActiveRecord::Base.transaction do | ||||
| begin | begin | ||||
| version_params = releases_params | version_params = releases_params | ||||
| old_value = old_value_to_hash(@version, version_params) | |||||
| if @version.update_attributes!(version_params) | if @version.update_attributes!(version_params) | ||||
| create_attachments(params[:attachment_ids], @version) if params[:attachment_ids].present? | create_attachments(params[:attachment_ids], @version) if params[:attachment_ids].present? | ||||
| git_version_release = Gitea::Versions::UpdateService.new(current_user.gitea_token, @user.try(:login), @repository.try(:identifier), version_params, @version.try(:version_gid)).call | git_version_release = Gitea::Versions::UpdateService.new(current_user.gitea_token, @user.try(:login), @repository.try(:identifier), version_params, @version.try(:version_gid)).call | ||||
| unless git_version_release | unless git_version_release | ||||
| raise Error, "更新失败" | raise Error, "更新失败" | ||||
| end | end | ||||
| user_trace_update_log(old_value) | |||||
| normal_status(0, "更新成功") | normal_status(0, "更新成功") | ||||
| else | else | ||||
| normal_status(-1, "更新失败") | normal_status(-1, "更新失败") | ||||
| @@ -0,0 +1,113 @@ | |||||
| class WalletsController < ApplicationController | |||||
| before_action :require_login, except: :community_data | |||||
| def balance | |||||
| user = User.find_by_id(params[:id]) | |||||
| @wallet = user.get_wallet | |||||
| end | |||||
| def coin_changes | |||||
| user = User.find_by_id(params[:id]) | |||||
| @wallet = user.get_wallet | |||||
| if params[:category] == 'all' | |||||
| scope = CoinChange.where('to_wallet_id = ? OR from_wallet_id = ?', @wallet.id, @wallet.id) | |||||
| elsif params[:category] == 'income' | |||||
| # @coin_changes = CoinChange.where('to_wallet_id = ?', @wallet.id).limit(100) | |||||
| scope = @wallet.income | |||||
| elsif params[:category] == 'outcome' | |||||
| scope = @wallet.outcome | |||||
| end | |||||
| sort = params[:sort_by] || "created_at" | |||||
| sort_direction = params[:sort_direction] || "desc" | |||||
| scope = scope.reorder("#{sort} #{sort_direction}") unless scope.nil? | |||||
| @total = 0 | |||||
| @total = scope.length unless scope.nil? | |||||
| @coin_changes = kaminari_paginate(scope) unless scope.nil? | |||||
| end | |||||
| def balance_chart | |||||
| user = User.find_by_id(params[:id]) | |||||
| @wallet = user.get_wallet | |||||
| scope = CoinChange.where('to_wallet_id = ? OR from_wallet_id = ?', @wallet.id, @wallet.id) | |||||
| t1 = Time.now | |||||
| t2 = Time.new(t1.year, t1.month, t1.day - 6) | |||||
| @balance_chart_data = scope.where('created_at > ? AND created_at < ?', t2, t1) | |||||
| @balance_chart_array = to_array(@balance_chart_data, @wallet.id) | |||||
| end | |||||
| def community_data | |||||
| t1 = Time.now | |||||
| t2 = Time.new(t1.year, t1.month, t1.day - 6) | |||||
| coin_changes = CoinChange.where('created_at >= ?', t2) | |||||
| @community_data_array = community_data_to_array(coin_changes) | |||||
| end | |||||
| private | |||||
| def to_array(data, id) | |||||
| t1 = Time.now | |||||
| start_time = Time.new(t1.year, t1.month, t1.day - 6) | |||||
| end_time = Time.new(start_time.year, start_time.month, start_time.day + 1) | |||||
| income = Array.new(7, 0) # 收入、支出 | |||||
| outcome = Array.new(7, 0) | |||||
| date = Array.new(7) | |||||
| date[0] = Time.new(start_time.year, start_time.month, start_time.day) | |||||
| index = 0 | |||||
| data.each do |i| | |||||
| # 更新日期 | |||||
| until (i.created_at >= start_time) && (i.created_at < end_time) | |||||
| index += 1 | |||||
| start_time = end_time | |||||
| end_time = Time.new(start_time.year, start_time.month, start_time.day + 1) | |||||
| date[index] = Time.new(start_time.year, start_time.month, start_time.day) | |||||
| end | |||||
| if i.from_wallet_id == id | |||||
| outcome[index] += i.amount | |||||
| else | |||||
| next if params[:sponsor] == true && i.from_wallet_id.nil? | |||||
| income[index] += i.amount | |||||
| end | |||||
| end | |||||
| until end_time >= Time.now | |||||
| index += 1 | |||||
| start_time = end_time | |||||
| end_time = Time.new(start_time.year, start_time.month, start_time.day + 1) | |||||
| date[index] = Time.new(start_time.year, start_time.month, start_time.day) | |||||
| end | |||||
| Array[income, outcome, date] | |||||
| end | |||||
| def community_data_to_array(coin_changes) | |||||
| t1 = Time.now | |||||
| start_time = Time.new(t1.year, t1.month, t1.day - 6) | |||||
| nums = Array.new(7, 0) | |||||
| date = Array.new(7) | |||||
| end_time = Array.new(7) | |||||
| # date[0] = Time.new(start_time.year, start_time.month, start_time.day) | |||||
| index = 0 | |||||
| (0..6).each do |i| | |||||
| # 更新日期,date[i]表示第i天0点 | |||||
| date[i] = Time.new(start_time.year, start_time.month, start_time.day + i) | |||||
| end_time[i] = Time.new(start_time.year, start_time.month, start_time.day + i+1) | |||||
| end | |||||
| coin_changes.each do |cc| | |||||
| (0..6).each do |i| | |||||
| if !cc.from_wallet_id.nil? && cc.created_at>=date[i] && cc.created_at<end_time[i] | |||||
| nums[i] += 1 | |||||
| end | |||||
| end | |||||
| end | |||||
| Array[nums, date] | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,2 @@ | |||||
| module LogHelper | |||||
| end | |||||
| @@ -0,0 +1,2 @@ | |||||
| module SponsorTiersHelper | |||||
| end | |||||
| @@ -0,0 +1,2 @@ | |||||
| module SponsorshipsHelper | |||||
| end | |||||
| @@ -0,0 +1,6 @@ | |||||
| module UpdateHelper | |||||
| def old_value_to_hash(old_value, params) | |||||
| params = params.dup.stringify_keys | |||||
| old_value.attributes.select { |key, value| params.key?(key) } | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,2 @@ | |||||
| module WalletsHelper | |||||
| end | |||||
| @@ -0,0 +1,15 @@ | |||||
| class MonthlyPaymentWorker | |||||
| include Sidekiq::Worker | |||||
| include Sidetiq::Schedulable | |||||
| recurrence do | |||||
| minutely(2) | |||||
| # monthly.day_of_month(12) #每月的12号0点执行 | |||||
| # monthly.day_of_month(23).hour_of_day(20) #每月的12号1点执行 | |||||
| end | |||||
| def perform(*args) | |||||
| Sponsorship.monthly_payment | |||||
| puts Time.now, 'sponsor payment done' | |||||
| end | |||||
| end | |||||
| @@ -17,7 +17,7 @@ | |||||
| # disk_directory :string(255) | # disk_directory :string(255) | ||||
| # attachtype :integer default("1") | # attachtype :integer default("1") | ||||
| # is_public :integer default("1") | # is_public :integer default("1") | ||||
| # copy_from :string(255) | |||||
| # copy_from :integer | |||||
| # quotes :integer default("0") | # quotes :integer default("0") | ||||
| # is_publish :integer default("1") | # is_publish :integer default("1") | ||||
| # publish_time :datetime | # publish_time :datetime | ||||
| @@ -26,15 +26,15 @@ | |||||
| # cloud_url :string(255) default("") | # cloud_url :string(255) default("") | ||||
| # course_second_category_id :integer default("0") | # course_second_category_id :integer default("0") | ||||
| # delay_publish :boolean default("0") | # delay_publish :boolean default("0") | ||||
| # link :string(255) | |||||
| # clone_id :integer | |||||
| # | # | ||||
| # Indexes | # Indexes | ||||
| # | # | ||||
| # index_attachments_on_author_id (author_id) | # index_attachments_on_author_id (author_id) | ||||
| # index_attachments_on_clone_id (clone_id) | |||||
| # index_attachments_on_container_id_and_container_type (container_id,container_type) | # index_attachments_on_container_id_and_container_type (container_id,container_type) | ||||
| # index_attachments_on_course_second_category_id (course_second_category_id) | |||||
| # index_attachments_on_created_on (created_on) | # index_attachments_on_created_on (created_on) | ||||
| # index_attachments_on_is_public (is_public) | |||||
| # index_attachments_on_quotes (quotes) | |||||
| # | # | ||||
| @@ -39,15 +39,18 @@ | |||||
| # business :boolean default("0") | # business :boolean default("0") | ||||
| # profile_completed :boolean default("0") | # profile_completed :boolean default("0") | ||||
| # laboratory_id :integer | # laboratory_id :integer | ||||
| # is_shixun_marker :boolean default("0") | |||||
| # admin_visitable :boolean default("0") | |||||
| # collaborator :boolean default("0") | |||||
| # platform :string(255) default("0") | |||||
| # gitea_token :string(255) | |||||
| # gitea_uid :integer | # gitea_uid :integer | ||||
| # is_shixun_marker :boolean default("0") | |||||
| # is_sync_pwd :boolean default("1") | # is_sync_pwd :boolean default("1") | ||||
| # watchers_count :integer default("0") | # watchers_count :integer default("0") | ||||
| # sponsor_certification :integer default("0") | |||||
| # sponsor_num :integer default("0") | |||||
| # sponsored_num :integer default("0") | |||||
| # sponsor_description :text(65535) | |||||
| # devops_step :integer default("0") | # devops_step :integer default("0") | ||||
| # gitea_token :string(255) | |||||
| # platform :string(255) | |||||
| # award_time :datetime | |||||
| # | # | ||||
| # Indexes | # Indexes | ||||
| # | # | ||||
| @@ -55,9 +58,8 @@ | |||||
| # index_users_on_homepage_engineer (homepage_engineer) | # index_users_on_homepage_engineer (homepage_engineer) | ||||
| # index_users_on_homepage_teacher (homepage_teacher) | # index_users_on_homepage_teacher (homepage_teacher) | ||||
| # index_users_on_laboratory_id (laboratory_id) | # index_users_on_laboratory_id (laboratory_id) | ||||
| # index_users_on_login (login) UNIQUE | |||||
| # index_users_on_mail (mail) UNIQUE | |||||
| # index_users_on_phone (phone) UNIQUE | |||||
| # index_users_on_login (login) | |||||
| # index_users_on_mail (mail) | |||||
| # index_users_on_type (type) | # index_users_on_type (type) | ||||
| # | # | ||||
| @@ -0,0 +1,19 @@ | |||||
| # == Schema Information | |||||
| # | |||||
| # Table name: coin_changes | |||||
| # | |||||
| # id :integer not null, primary key | |||||
| # amount :integer | |||||
| # description :string(255) | |||||
| # reason :string(255) | |||||
| # to_wallet_id :integer | |||||
| # from_wallet_id :integer | |||||
| # created_at :datetime not null | |||||
| # updated_at :datetime not null | |||||
| # | |||||
| class CoinChange < ApplicationRecord | |||||
| belongs_to :to_wallet, class_name: 'Wallet' | |||||
| belongs_to :from_wallet, class_name: 'Wallet', optional: true | |||||
| validates :amount, presence: true | |||||
| end | |||||
| @@ -1,18 +1,19 @@ | |||||
| # == Schema Information | |||||
| # | |||||
| # Table name: edu_settings | |||||
| # | |||||
| # id :integer not null, primary key | |||||
| # name :string(255) | |||||
| # value :string(255) | |||||
| # created_at :datetime not null | |||||
| # updated_at :datetime not null | |||||
| # description :string(255) | |||||
| # | |||||
| # Indexes | |||||
| # | |||||
| # index_edu_settings_on_name (name) UNIQUE | |||||
| # | |||||
| # == Schema Information | |||||
| # | |||||
| # Table name: edu_settings | |||||
| # | |||||
| # id :integer not null, primary key | |||||
| # name :string(255) | |||||
| # value :string(255) | |||||
| # created_at :datetime not null | |||||
| # updated_at :datetime not null | |||||
| # description :string(255) | |||||
| # | |||||
| # Indexes | |||||
| # | |||||
| # index_edu_settings_on_name (name) UNIQUE | |||||
| # | |||||
| class EduSetting < ApplicationRecord | class EduSetting < ApplicationRecord | ||||
| after_commit :expire_value_cache | after_commit :expire_value_cache | ||||
| @@ -1,3 +1,24 @@ | |||||
| # == Schema Information | |||||
| # | |||||
| # Table name: public_key | |||||
| # | |||||
| # id :integer not null, primary key | |||||
| # owner_id :integer not null | |||||
| # name :string(255) not null | |||||
| # fingerprint :string(255) not null | |||||
| # content :text(65535) not null | |||||
| # mode :integer default("2"), not null | |||||
| # type :integer default("1"), not null | |||||
| # login_source_id :integer default("0"), not null | |||||
| # created_unix :integer | |||||
| # updated_unix :integer | |||||
| # | |||||
| # Indexes | |||||
| # | |||||
| # IDX_public_key_fingerprint (fingerprint) | |||||
| # IDX_public_key_owner_id (owner_id) | |||||
| # | |||||
| class Gitea::PublicKey < Gitea::Base | class Gitea::PublicKey < Gitea::Base | ||||
| self.inheritance_column = nil # FIX The single-table inheritance mechanism failed | self.inheritance_column = nil # FIX The single-table inheritance mechanism failed | ||||
| # establish_connection :gitea_db | # establish_connection :gitea_db | ||||
| @@ -6,9 +6,6 @@ | |||||
| # type :integer | # type :integer | ||||
| # status :integer | # status :integer | ||||
| # conflicted_files :text(65535) | # conflicted_files :text(65535) | ||||
| # commits_ahead :integer | |||||
| # commits_behind :integer | |||||
| # changed_protected_files :text(65535) | |||||
| # issue_id :integer | # issue_id :integer | ||||
| # index :integer | # index :integer | ||||
| # head_repo_id :integer | # head_repo_id :integer | ||||
| @@ -20,6 +17,11 @@ | |||||
| # merged_commit_id :string(40) | # merged_commit_id :string(40) | ||||
| # merger_id :integer | # merger_id :integer | ||||
| # merged_unix :integer | # merged_unix :integer | ||||
| # commits_ahead :integer | |||||
| # commits_behind :integer | |||||
| # changed_protected_files :text(65535) | |||||
| # commit_num :integer | |||||
| # changed_files :integer | |||||
| # | # | ||||
| # Indexes | # Indexes | ||||
| # | # | ||||
| @@ -1,3 +1,36 @@ | |||||
| # == Schema Information | |||||
| # | |||||
| # Table name: webhook | |||||
| # | |||||
| # id :integer not null, primary key | |||||
| # repo_id :integer | |||||
| # org_id :integer | |||||
| # url :text(65535) | |||||
| # http_method :string(255) | |||||
| # content_type :integer | |||||
| # secret :text(65535) | |||||
| # events :text(65535) | |||||
| # is_active :boolean | |||||
| # meta :text(65535) | |||||
| # last_status :integer | |||||
| # created_unix :integer | |||||
| # updated_unix :integer | |||||
| # is_system_webhook :boolean default("0"), not null | |||||
| # type :string(16) | |||||
| # branch_filter :text(65535) | |||||
| # signature :text(65535) | |||||
| # is_ssl :boolean | |||||
| # hook_task_type :integer | |||||
| # | |||||
| # Indexes | |||||
| # | |||||
| # IDX_webhook_created_unix (created_unix) | |||||
| # IDX_webhook_is_active (is_active) | |||||
| # IDX_webhook_org_id (org_id) | |||||
| # IDX_webhook_repo_id (repo_id) | |||||
| # IDX_webhook_updated_unix (updated_unix) | |||||
| # | |||||
| class Gitea::Webhook < Gitea::Base | class Gitea::Webhook < Gitea::Base | ||||
| serialize :events, JSON | serialize :events, JSON | ||||
| self.inheritance_column = nil | self.inheritance_column = nil | ||||
| @@ -10,4 +43,4 @@ class Gitea::Webhook < Gitea::Base | |||||
| enum hook_task_type: {gogs: 1, slack: 2, gitea: 3, discord: 4, dingtalk: 5, telegram: 6, msteams: 7, feishu: 8, matrix: 9} | enum hook_task_type: {gogs: 1, slack: 2, gitea: 3, discord: 4, dingtalk: 5, telegram: 6, msteams: 7, feishu: 8, matrix: 9} | ||||
| enum last_status: {waiting: 0, succeed: 1, fail: 2} | enum last_status: {waiting: 0, succeed: 1, fail: 2} | ||||
| enum content_type: {json: 1, form: 2} | enum content_type: {json: 1, form: 2} | ||||
| end | |||||
| end | |||||
| @@ -1,6 +1,34 @@ | |||||
| class Gitea::WebhookTask < Gitea::Base | |||||
| # == Schema Information | |||||
| # | |||||
| # Table name: hook_task | |||||
| # | |||||
| # id :integer not null, primary key | |||||
| # repo_id :integer | |||||
| # hook_id :integer | |||||
| # uuid :string(255) | |||||
| # payload_content :text(65535) | |||||
| # event_type :string(255) | |||||
| # is_delivered :boolean | |||||
| # delivered :integer | |||||
| # is_succeed :boolean | |||||
| # request_content :text(65535) | |||||
| # response_content :text(65535) | |||||
| # type :string(255) | |||||
| # url :text(65535) | |||||
| # signature :text(65535) | |||||
| # http_method :string(255) | |||||
| # content_type :integer | |||||
| # is_ssl :boolean | |||||
| # | |||||
| # Indexes | |||||
| # | |||||
| # IDX_hook_task_repo_id (repo_id) | |||||
| # | |||||
| class Gitea::WebhookTask < Gitea::Base | |||||
| serialize :payload_content, JSON | serialize :payload_content, JSON | ||||
| serialize :request_content, JSON | serialize :request_content, JSON | ||||
| serialize :response_content, JSON | |||||
| self.inheritance_column = nil | self.inheritance_column = nil | ||||
| @@ -12,7 +40,7 @@ class Gitea::WebhookTask < Gitea::Base | |||||
| def response_content_json | def response_content_json | ||||
| JSON.parse(response_content) | JSON.parse(response_content) | ||||
| rescue | |||||
| rescue | |||||
| {} | {} | ||||
| end | end | ||||
| end | |||||
| end | |||||
| @@ -10,7 +10,6 @@ | |||||
| # sync_course :boolean default("0") | # sync_course :boolean default("0") | ||||
| # sync_subject :boolean default("0") | # sync_subject :boolean default("0") | ||||
| # sync_shixun :boolean default("0") | # sync_shixun :boolean default("0") | ||||
| # is_local :boolean default("0") | |||||
| # | # | ||||
| # Indexes | # Indexes | ||||
| # | # | ||||
| @@ -39,15 +39,18 @@ | |||||
| # business :boolean default("0") | # business :boolean default("0") | ||||
| # profile_completed :boolean default("0") | # profile_completed :boolean default("0") | ||||
| # laboratory_id :integer | # laboratory_id :integer | ||||
| # is_shixun_marker :boolean default("0") | |||||
| # admin_visitable :boolean default("0") | |||||
| # collaborator :boolean default("0") | |||||
| # platform :string(255) default("0") | |||||
| # gitea_token :string(255) | |||||
| # gitea_uid :integer | # gitea_uid :integer | ||||
| # is_shixun_marker :boolean default("0") | |||||
| # is_sync_pwd :boolean default("1") | # is_sync_pwd :boolean default("1") | ||||
| # watchers_count :integer default("0") | # watchers_count :integer default("0") | ||||
| # sponsor_certification :integer default("0") | |||||
| # sponsor_num :integer default("0") | |||||
| # sponsored_num :integer default("0") | |||||
| # sponsor_description :text(65535) | |||||
| # devops_step :integer default("0") | # devops_step :integer default("0") | ||||
| # gitea_token :string(255) | |||||
| # platform :string(255) | |||||
| # award_time :datetime | |||||
| # | # | ||||
| # Indexes | # Indexes | ||||
| # | # | ||||
| @@ -55,9 +58,8 @@ | |||||
| # index_users_on_homepage_engineer (homepage_engineer) | # index_users_on_homepage_engineer (homepage_engineer) | ||||
| # index_users_on_homepage_teacher (homepage_teacher) | # index_users_on_homepage_teacher (homepage_teacher) | ||||
| # index_users_on_laboratory_id (laboratory_id) | # index_users_on_laboratory_id (laboratory_id) | ||||
| # index_users_on_login (login) UNIQUE | |||||
| # index_users_on_mail (mail) UNIQUE | |||||
| # index_users_on_phone (phone) UNIQUE | |||||
| # index_users_on_login (login) | |||||
| # index_users_on_mail (mail) | |||||
| # index_users_on_type (type) | # index_users_on_type (type) | ||||
| # | # | ||||
| @@ -0,0 +1,16 @@ | |||||
| # == Schema Information | |||||
| # | |||||
| # Table name: passed_waitlists | |||||
| # | |||||
| # id :integer not null, primary key | |||||
| # applicant_id :string(255) | |||||
| # integer :string(255) | |||||
| # reviewer_id :string(255) | |||||
| # created_at :datetime not null | |||||
| # updated_at :datetime not null | |||||
| # | |||||
| class PassedWaitlist < ApplicationRecord | |||||
| belongs_to :applicant, class_name: 'User' | |||||
| belongs_to :reviewer, class_name: 'User' | |||||
| end | |||||
| @@ -124,7 +124,7 @@ class Project < ApplicationRecord | |||||
| has_many :pinned_projects, dependent: :destroy | has_many :pinned_projects, dependent: :destroy | ||||
| has_many :has_pinned_users, through: :pinned_projects, source: :user | has_many :has_pinned_users, through: :pinned_projects, source: :user | ||||
| has_many :webhooks, class_name: "Gitea::Webhook", primary_key: :gpid, foreign_key: :repo_id | has_many :webhooks, class_name: "Gitea::Webhook", primary_key: :gpid, foreign_key: :repo_id | ||||
| has_many :user_trace_tasks, dependent: :destroy | |||||
| has_many :user_trace_tasks, dependent: :destroy | |||||
| has_many :project_invite_links, dependent: :destroy | has_many :project_invite_links, dependent: :destroy | ||||
| after_create :incre_user_statistic, :incre_platform_statistic | after_create :incre_user_statistic, :incre_platform_statistic | ||||
| after_save :check_project_members | after_save :check_project_members | ||||
| @@ -192,7 +192,7 @@ class Project < ApplicationRecord | |||||
| end | end | ||||
| end | end | ||||
| def incre_user_statistic | |||||
| def incre_user_statistic | |||||
| CacheAsyncSetJob.perform_later("user_statistic_service", {project_count: 1, project_language_count_key: self.project_language&.name, project_language_count: 1}, self.user_id) | CacheAsyncSetJob.perform_later("user_statistic_service", {project_count: 1, project_language_count_key: self.project_language&.name, project_language_count: 1}, self.user_id) | ||||
| end | end | ||||
| @@ -235,7 +235,7 @@ class Project < ApplicationRecord | |||||
| unless self.is_public | unless self.is_public | ||||
| self.recommend = false | self.recommend = false | ||||
| self.recommend_index = 0 | self.recommend_index = 0 | ||||
| self.is_pinned = false | |||||
| self.is_pinned = false | |||||
| end | end | ||||
| end | end | ||||
| @@ -27,6 +27,7 @@ | |||||
| # | # | ||||
| # Indexes | # Indexes | ||||
| # | # | ||||
| # index_repositories_on_identifier (identifier) | |||||
| # index_repositories_on_project_id (project_id) | # index_repositories_on_project_id (project_id) | ||||
| # index_repositories_on_user_id (user_id) | # index_repositories_on_user_id (user_id) | ||||
| # | # | ||||
| @@ -0,0 +1,16 @@ | |||||
| # == Schema Information | |||||
| # | |||||
| # Table name: sponsor_tiers | |||||
| # | |||||
| # id :integer not null, primary key | |||||
| # tier :integer | |||||
| # created_at :datetime not null | |||||
| # updated_at :datetime not null | |||||
| # description :string(255) default("") | |||||
| # user_id :integer | |||||
| # | |||||
| class SponsorTier < ApplicationRecord | |||||
| belongs_to :user | |||||
| end | |||||
| @@ -0,0 +1,49 @@ | |||||
| # == Schema Information | |||||
| # | |||||
| # Table name: sponsorships | |||||
| # | |||||
| # id :integer not null, primary key | |||||
| # amount :integer | |||||
| # visible :integer | |||||
| # sponsor_id :integer | |||||
| # developer_id :integer | |||||
| # created_at :datetime not null | |||||
| # updated_at :datetime not null | |||||
| # accumulate :integer default("0") | |||||
| # | |||||
| class Sponsorship < ApplicationRecord | |||||
| belongs_to :sponsor, class_name: 'User' | |||||
| belongs_to :developer, class_name: 'User' | |||||
| validates :amount, presence: true | |||||
| def stop | |||||
| stopped_sponsorship = StoppedSponsorship.new(developer_id: developer_id, sponsor_id: sponsor_id, start_time: created_at, amount: amount, visible: visible, accumulate: accumulate) | |||||
| stopped_sponsorship.save && destroy | |||||
| end | |||||
| def pay | |||||
| sponsor_wallet = sponsor.get_wallet | |||||
| developer_wallet = developer.get_wallet | |||||
| success = false | |||||
| Wallet.transaction do | |||||
| success = sponsor_wallet.pay(amount) | |||||
| if 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 | |||||
| success | |||||
| end | |||||
| def self.monthly_payment | |||||
| sponsorships = Sponsorship.all | |||||
| sponsorships.each do |s| | |||||
| s.stop unless s.pay | |||||
| end | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,26 @@ | |||||
| # == Schema Information | |||||
| # | |||||
| # Table name: statistics | |||||
| # | |||||
| # id :integer not null, primary key | |||||
| # dau :integer | |||||
| # created_at :datetime not null | |||||
| # updated_at :datetime not null | |||||
| # wau :integer | |||||
| # mau :integer | |||||
| # | |||||
| class Statistic < ApplicationRecord | |||||
| def self.record | |||||
| users = User.all | |||||
| count = 0 | |||||
| t = Time.now - 1.day | |||||
| # t = Time.now.at_beginning_of_day | |||||
| users.each do |u| | |||||
| if !u.last_login_on.nil? && u.last_login_on >= t | |||||
| count += 1 | |||||
| end | |||||
| end | |||||
| Statistic.create(dau: count) | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,20 @@ | |||||
| # == Schema Information | |||||
| # | |||||
| # Table name: stopped_sponsorships | |||||
| # | |||||
| # id :integer not null, primary key | |||||
| # amount :integer | |||||
| # sponsor_id :integer | |||||
| # developer_id :integer | |||||
| # created_at :datetime not null | |||||
| # updated_at :datetime not null | |||||
| # start_time :datetime | |||||
| # visible :integer | |||||
| # accumulate :integer default("0") | |||||
| # | |||||
| class StoppedSponsorship < ApplicationRecord | |||||
| belongs_to :sponsor, class_name: 'User' | |||||
| belongs_to :developer, class_name: 'User' | |||||
| validates :amount, presence: true | |||||
| end | |||||
| @@ -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 | # This program is free software; you can redistribute it and/or | ||||
| @@ -39,15 +39,18 @@ | |||||
| # business :boolean default("0") | # business :boolean default("0") | ||||
| # profile_completed :boolean default("0") | # profile_completed :boolean default("0") | ||||
| # laboratory_id :integer | # laboratory_id :integer | ||||
| # is_shixun_marker :boolean default("0") | |||||
| # admin_visitable :boolean default("0") | |||||
| # collaborator :boolean default("0") | |||||
| # platform :string(255) default("0") | |||||
| # gitea_token :string(255) | |||||
| # gitea_uid :integer | # gitea_uid :integer | ||||
| # is_shixun_marker :boolean default("0") | |||||
| # is_sync_pwd :boolean default("1") | # is_sync_pwd :boolean default("1") | ||||
| # watchers_count :integer default("0") | # watchers_count :integer default("0") | ||||
| # sponsor_certification :integer default("0") | |||||
| # sponsor_num :integer default("0") | |||||
| # sponsored_num :integer default("0") | |||||
| # sponsor_description :text(65535) | |||||
| # devops_step :integer default("0") | # devops_step :integer default("0") | ||||
| # gitea_token :string(255) | |||||
| # platform :string(255) | |||||
| # award_time :datetime | |||||
| # | # | ||||
| # Indexes | # Indexes | ||||
| # | # | ||||
| @@ -55,9 +58,8 @@ | |||||
| # index_users_on_homepage_engineer (homepage_engineer) | # index_users_on_homepage_engineer (homepage_engineer) | ||||
| # index_users_on_homepage_teacher (homepage_teacher) | # index_users_on_homepage_teacher (homepage_teacher) | ||||
| # index_users_on_laboratory_id (laboratory_id) | # index_users_on_laboratory_id (laboratory_id) | ||||
| # index_users_on_login (login) UNIQUE | |||||
| # index_users_on_mail (mail) UNIQUE | |||||
| # index_users_on_phone (phone) UNIQUE | |||||
| # index_users_on_login (login) | |||||
| # index_users_on_mail (mail) | |||||
| # index_users_on_type (type) | # index_users_on_type (type) | ||||
| # | # | ||||
| @@ -161,6 +163,18 @@ class User < Owner | |||||
| has_many :project_trends, dependent: :destroy | has_many :project_trends, dependent: :destroy | ||||
| has_many :oauths , dependent: :destroy | has_many :oauths , dependent: :destroy | ||||
| # sponsor | |||||
| has_many :as_sponsors, class_name: 'Sponsorship', foreign_key: 'sponsor_id', dependent: :destroy | |||||
| has_many :as_sponsored, class_name: 'Sponsorship', foreign_key: 'developer_id', dependent: :destroy | |||||
| has_many :stopped_sponsors, class_name: 'StoppedSponsorship', foreign_key: 'sponsor_id', dependent: :destroy | |||||
| has_many :stopped_sponsored, class_name: 'StoppedSponsorship', foreign_key: 'developer_id', dependent: :destroy | |||||
| has_many :sponsor_tier, dependent: :destroy | |||||
| has_one :wallet, dependent: :destroy | |||||
| has_many :waitlist, class_name: 'Waitlist', foreign_key: 'reviewer_id' | |||||
| has_many :passed_waitlist, class_name: 'PassedWaitlist', foreign_key: 'reviewer_id' #as reviewer | |||||
| has_one :application, class_name: 'Waitlist', foreign_key: 'applicant_id' | |||||
| has_one :passed_application, class_name: 'PassedWaitlist', foreign_key: 'applicant_id' | |||||
| has_many :organization_users, dependent: :destroy | has_many :organization_users, dependent: :destroy | ||||
| has_many :organizations, through: :organization_users | has_many :organizations, through: :organization_users | ||||
| has_many :pinned_projects, dependent: :destroy | has_many :pinned_projects, dependent: :destroy | ||||
| @@ -646,6 +660,7 @@ class User < Owner | |||||
| # Returns the user who matches the given autologin +key+ or nil | # Returns the user who matches the given autologin +key+ or nil | ||||
| def self.try_to_autologin(key) | def self.try_to_autologin(key) | ||||
| user = Token.find_active_user('autologin', key) | user = Token.find_active_user('autologin', key) | ||||
| # user.daily_reward if user | |||||
| user.update(last_login_on: Time.now) if user | user.update(last_login_on: Time.now) if user | ||||
| user | user | ||||
| end | end | ||||
| @@ -817,6 +832,36 @@ class User < Owner | |||||
| laboratory_id.present? && laboratory_id != 1 | laboratory_id.present? && laboratory_id != 1 | ||||
| end | end | ||||
| def get_wallet | |||||
| if wallet.nil? | |||||
| Wallet.transaction(isolation: :serializable) do | |||||
| if wallet.nil? | |||||
| create_wallet(balance: 100) | |||||
| reason = "系统初始赠送" | |||||
| CoinChange.create(amount: 100, reason: reason, to_wallet_id: wallet.id) | |||||
| end | |||||
| end | |||||
| end | |||||
| wallet | |||||
| end | |||||
| def daily_reward | |||||
| if !Rails.application.config_for(:configuration)["sponsor"] | |||||
| return | |||||
| end | |||||
| t1 = Time.now | |||||
| t2 = Time.new(t1.year, t1.month, t1.day) | |||||
| if(award_time.nil? or t2 > award_time) | |||||
| self.update_column(:award_time, Time.now) | |||||
| amount = 2 | |||||
| user_wallet = get_wallet | |||||
| user_wallet.receive(amount) | |||||
| reason = "每日登录奖励" | |||||
| CoinChange.create(amount: amount, reason: reason, to_wallet_id: user_wallet.id) | |||||
| end | |||||
| end | |||||
| def profile_is_completed? | def profile_is_completed? | ||||
| self.nickname.present? && self.mail.present? | self.nickname.present? && self.mail.present? | ||||
| end | end | ||||
| @@ -12,9 +12,7 @@ | |||||
| # | # | ||||
| # Indexes | # Indexes | ||||
| # | # | ||||
| # index_user_actions_on_ip (ip) | |||||
| # index_user_actions_on_user_id (user_id) | |||||
| # index_user_actions_on_user_id_and_action_type (user_id,action_type) | |||||
| # index_user_actions_on_ip (ip) | |||||
| # | # | ||||
| class UserAction < ApplicationRecord | class UserAction < ApplicationRecord | ||||
| @@ -10,13 +10,10 @@ | |||||
| # updated_at :datetime not null | # updated_at :datetime not null | ||||
| # register_status :integer default("0") | # register_status :integer default("0") | ||||
| # action_status :integer default("0") | # action_status :integer default("0") | ||||
| # is_delete :boolean default("0") | |||||
| # user_id :integer | |||||
| # | # | ||||
| # Indexes | # Indexes | ||||
| # | # | ||||
| # index_user_agents_on_ip (ip) | |||||
| # index_user_agents_on_user_id (user_id) | |||||
| # index_user_agents_on_ip (ip) UNIQUE | |||||
| # | # | ||||
| class UserAgent < ApplicationRecord | class UserAgent < ApplicationRecord | ||||
| @@ -0,0 +1,16 @@ | |||||
| # == Schema Information | |||||
| # | |||||
| # Table name: waitlists | |||||
| # | |||||
| # id :integer not null, primary key | |||||
| # applicant_id :string(255) | |||||
| # integer :string(255) | |||||
| # reviewer_id :string(255) | |||||
| # created_at :datetime not null | |||||
| # updated_at :datetime not null | |||||
| # | |||||
| class Waitlist < ApplicationRecord | |||||
| belongs_to :applicant, class_name: 'User' | |||||
| belongs_to :reviewer, class_name: 'User', optional: true | |||||
| end | |||||
| @@ -0,0 +1,42 @@ | |||||
| # == Schema Information | |||||
| # | |||||
| # Table name: wallets | |||||
| # | |||||
| # id :integer not null, primary key | |||||
| # balance :integer | |||||
| # user_id :integer | |||||
| # created_at :datetime not null | |||||
| # updated_at :datetime not null | |||||
| # | |||||
| class Wallet < ApplicationRecord | |||||
| belongs_to :user | |||||
| 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 | |||||
| @@ -0,0 +1 @@ | |||||
| json.array! @file_list | |||||
| @@ -0,0 +1,13 @@ | |||||
| <%= simple_form_for(@sponsor_tier) do |f| %> | |||||
| <%= f.error_notification %> | |||||
| <%= f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present? %> | |||||
| <div class="form-inputs"> | |||||
| <%= f.input :tier %> | |||||
| </div> | |||||
| <div class="form-actions"> | |||||
| <%= f.button :submit %> | |||||
| </div> | |||||
| <% end %> | |||||
| @@ -0,0 +1,2 @@ | |||||
| json.extract! sponsor_tier, :id, :tier, :description, :created_at, :updated_at | |||||
| json.url sponsor_tier_url(sponsor_tier, format: :json) | |||||
| @@ -0,0 +1,6 @@ | |||||
| <h1>Editing Sponsor Tier</h1> | |||||
| <%= render 'form', sponsor_tier: @sponsor_tier %> | |||||
| <%= link_to 'Show', @sponsor_tier %> | | |||||
| <%= link_to 'Back', sponsor_tiers_path %> | |||||
| @@ -0,0 +1 @@ | |||||
| json.array! @sponsor_tiers, partial: "sponsor_tiers/sponsor_tier", as: :sponsor_tier | |||||
| @@ -0,0 +1,5 @@ | |||||
| <h1>New Sponsor Tier</h1> | |||||
| <%= render 'form', sponsor_tier: @sponsor_tier %> | |||||
| <%= link_to 'Back', sponsor_tiers_path %> | |||||
| @@ -0,0 +1,9 @@ | |||||
| <p id="notice"><%= notice %></p> | |||||
| <p> | |||||
| <strong>Tier:</strong> | |||||
| <%= @sponsor_tier.tier %> | |||||
| </p> | |||||
| <%= link_to 'Edit', edit_sponsor_tier_path(@sponsor_tier) %> | | |||||
| <%= link_to 'Back', sponsor_tiers_path %> | |||||
| @@ -0,0 +1,9 @@ | |||||
| json.tier do | |||||
| json.partial! "sponsor_tiers/sponsor_tier", sponsor_tier: @sponsor_tier | |||||
| end | |||||
| if @check_sponsorship.nil? || @check_sponsorship.length.zero? | |||||
| json.is_sponsoring false | |||||
| else | |||||
| json.is_sponsoring true | |||||
| json.sponsorship_id @check_sponsorship[0].id | |||||
| end | |||||
| @@ -0,0 +1,16 @@ | |||||
| <%= simple_form_for(@sponsorship) do |f| %> | |||||
| <%= f.error_notification %> | |||||
| <%= f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present? %> | |||||
| <div class="form-inputs"> | |||||
| <%= f.input :amount %> | |||||
| <%= f.input :visible %> | |||||
| <%= f.input :sponsor_id %> | |||||
| <%= f.input :developer_id %> | |||||
| </div> | |||||
| <div class="form-actions"> | |||||
| <%= f.button :submit %> | |||||
| </div> | |||||
| <% end %> | |||||
| @@ -0,0 +1,2 @@ | |||||
| json.extract! sponsorship, :id, :amount, :visible, :sponsor_id, :developer_id, :created_at, :updated_at, :accumulate | |||||
| json.url sponsorship_url(sponsorship, format: :json) | |||||
| @@ -0,0 +1,12 @@ | |||||
| json.sponsor do | |||||
| json.array! (0..6).each do |i| | |||||
| json.y @community_data_array[0][i] | |||||
| json.x @community_data_array[2][i].to_date | |||||
| end | |||||
| end | |||||
| json.sponsored do | |||||
| json.array! (0..6).each do |i| | |||||
| json.y @community_data_array[1][i] | |||||
| json.x @community_data_array[2][i].to_date | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,6 @@ | |||||
| <h1>Editing Sponsorship</h1> | |||||
| <%= render 'form', sponsorship: @sponsorship %> | |||||
| <%= link_to 'Show', @sponsorship %> | | |||||
| <%= link_to 'Back', sponsorships_path %> | |||||
| @@ -0,0 +1,33 @@ | |||||
| <p id="notice"><%= notice %></p> | |||||
| <h1>Sponsorships</h1> | |||||
| <table> | |||||
| <thead> | |||||
| <tr> | |||||
| <th>Amount</th> | |||||
| <th>Visible</th> | |||||
| <th>Sponsor</th> | |||||
| <th>Developer</th> | |||||
| <th colspan="3"></th> | |||||
| </tr> | |||||
| </thead> | |||||
| <tbody> | |||||
| <% @sponsorships.each do |sponsorship| %> | |||||
| <tr> | |||||
| <td><%= sponsorship.amount %></td> | |||||
| <td><%= sponsorship.visible %></td> | |||||
| <td><%= sponsorship.sponsor_id %></td> | |||||
| <td><%= sponsorship.developer_id %></td> | |||||
| <td><%= link_to 'Show', sponsorship %></td> | |||||
| <td><%= link_to 'Edit', edit_sponsorship_path(sponsorship) %></td> | |||||
| <td><%= link_to 'Destroy', sponsorship, method: :delete, data: { confirm: 'Are you sure?' } %></td> | |||||
| </tr> | |||||
| <% end %> | |||||
| </tbody> | |||||
| </table> | |||||
| <br> | |||||
| <%= link_to 'New Sponsorship', new_sponsorship_path %> | |||||
| @@ -0,0 +1 @@ | |||||
| json.array! @sponsorships, partial: "sponsorships/sponsorship", as: :sponsorship | |||||
| @@ -0,0 +1,5 @@ | |||||
| <h1>New Sponsorship</h1> | |||||
| <%= render 'form', sponsorship: @sponsorship %> | |||||
| <%= link_to 'Back', sponsorships_path %> | |||||
| @@ -0,0 +1,24 @@ | |||||
| <p id="notice"><%= notice %></p> | |||||
| <p> | |||||
| <strong>Amount:</strong> | |||||
| <%= @sponsorship.amount %> | |||||
| </p> | |||||
| <p> | |||||
| <strong>Visible:</strong> | |||||
| <%= @sponsorship.visible %> | |||||
| </p> | |||||
| <p> | |||||
| <strong>Sponsor:</strong> | |||||
| <%= @sponsorship.sponsor_id %> | |||||
| </p> | |||||
| <p> | |||||
| <strong>Developer:</strong> | |||||
| <%= @sponsorship.developer_id %> | |||||
| </p> | |||||
| <%= link_to 'Edit', edit_sponsorship_path(@sponsorship) %> | | |||||
| <%= link_to 'Back', sponsorships_path %> | |||||
| @@ -0,0 +1 @@ | |||||
| json.partial! "sponsorships/sponsorship", sponsorship: @sponsorship | |||||
| @@ -0,0 +1,21 @@ | |||||
| json.count @total | |||||
| json.sponsorships do | |||||
| json.array! @sponsorships do |sponsorship| | |||||
| json.id sponsorship.id | |||||
| json.start_time sponsorship.created_at.to_date | |||||
| # json.stop_time '-' | |||||
| if sponsorship.visible.zero? | |||||
| json.visible false | |||||
| else | |||||
| json.visible true | |||||
| end | |||||
| json.amount sponsorship.amount | |||||
| sponsor = sponsorship.sponsor | |||||
| json.image_url url_to_avatar(sponsor) | |||||
| json.username sponsor.full_name | |||||
| json.user_id sponsor.id | |||||
| json.login sponsor.login | |||||
| json.accumulate sponsorship.accumulate | |||||
| json.sponsor_id sponsorship.sponsor.id | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,21 @@ | |||||
| json.count @total | |||||
| json.sponsorships do | |||||
| json.array! @sponsorships do |sponsorship| | |||||
| json.id sponsorship.id | |||||
| json.start_time sponsorship.created_at.to_date | |||||
| # json.stop_time '-' | |||||
| if sponsorship.visible.zero? | |||||
| json.visible false | |||||
| else | |||||
| json.visible true | |||||
| end | |||||
| json.amount sponsorship.amount | |||||
| sponsor = sponsorship.developer | |||||
| json.image_url url_to_avatar(sponsor) | |||||
| json.username sponsor.full_name | |||||
| json.user_id sponsor.id | |||||
| json.login sponsor.login | |||||
| json.accumulate sponsorship.accumulate | |||||
| json.sponsor_id sponsorship.sponsor.id | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,11 @@ | |||||
| json.array! @stopped_sponsorships do |sponsorship| | |||||
| json.id sponsorship.id | |||||
| json.amount sponsorship.amount | |||||
| json.visible sponsorship.visible | |||||
| json.sponsor_id sponsorship.sponsor_id | |||||
| json.developer_id sponsorship.developer_id | |||||
| json.start_time sponsorship.start_time | |||||
| json.created_at sponsorship.created_at | |||||
| json.updated_at sponsorship.updated_at | |||||
| json.accumulate sponsorship.accumulate | |||||
| end | |||||
| @@ -0,0 +1,21 @@ | |||||
| json.count @total | |||||
| json.sponsorships do | |||||
| json.array! @stopped_sponsorships do |sponsorship| | |||||
| json.id sponsorship.id | |||||
| json.start_time sponsorship.start_time.to_date | |||||
| json.stop_time sponsorship.created_at.to_date | |||||
| if sponsorship.visible.zero? | |||||
| json.visible false | |||||
| else | |||||
| json.visible true | |||||
| end | |||||
| json.amount sponsorship.amount | |||||
| sponsor = sponsorship.sponsor | |||||
| json.image_url url_to_avatar(sponsor) | |||||
| json.username sponsor.full_name | |||||
| json.user_id sponsor.id | |||||
| json.login sponsor.login | |||||
| json.accumulate sponsorship.accumulate | |||||
| json.sponsor_id sponsorship.sponsor.id | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,21 @@ | |||||
| json.count @total | |||||
| json.sponsorships do | |||||
| json.array! @stopped_sponsorships do |sponsorship| | |||||
| json.id sponsorship.id | |||||
| json.start_time sponsorship.start_time.to_date | |||||
| json.stop_time sponsorship.created_at.to_date | |||||
| if sponsorship.visible.zero? | |||||
| json.visible false | |||||
| else | |||||
| json.visible true | |||||
| end | |||||
| json.amount sponsorship.amount | |||||
| sponsor = sponsorship.developer | |||||
| json.image_url url_to_avatar(sponsor) | |||||
| json.username sponsor.full_name | |||||
| json.user_id sponsor.id | |||||
| json.login sponsor.login | |||||
| json.accumulate sponsorship.accumulate | |||||
| json.sponsor_id sponsorship.sponsor.id | |||||
| end | |||||
| end | |||||
| @@ -15,6 +15,7 @@ json.phone @user.phone | |||||
| # json.email @user.mail | # json.email @user.mail | ||||
| json.profile_completed @user.profile_is_completed? | json.profile_completed @user.profile_is_completed? | ||||
| json.professional_certification @user.professional_certification | json.professional_certification @user.professional_certification | ||||
| json.sponsor_description @user.sponsor_description | |||||
| json.devops_step @user.devops_step | json.devops_step @user.devops_step | ||||
| json.ci_certification @user.ci_certification? | json.ci_certification @user.ci_certification? | ||||
| json.email @user.mail | json.email @user.mail | ||||
| @@ -15,4 +15,5 @@ json.city @user.show_location ? @user.city : nil | |||||
| json.custom_department @user.show_department ? @user.custom_department : nil | json.custom_department @user.show_department ? @user.custom_department : nil | ||||
| json.super_description @user.show_super_description ? @user.super_description : nil | json.super_description @user.show_super_description ? @user.super_description : nil | ||||
| json.show_super_description @user.show_super_description | json.show_super_description @user.show_super_description | ||||
| json.description @user.description | |||||
| json.description @user.description | |||||
| json.sponsor_description @user.sponsor_description | |||||
| @@ -0,0 +1,2 @@ | |||||
| <h1>Wallets#balance</h1> | |||||
| <p>Find me in app/views/wallets/balance.html.erb</p> | |||||
| @@ -0,0 +1 @@ | |||||
| json.balance @wallet.balance | |||||
| @@ -0,0 +1,12 @@ | |||||
| json.income do | |||||
| json.array! (0..6).each do |i| | |||||
| json.y @balance_chart_array[0][i] | |||||
| json.x @balance_chart_array[2][i].to_date | |||||
| end | |||||
| end | |||||
| json.outcome do | |||||
| json.array! (0..6).each do |i| | |||||
| json.y @balance_chart_array[1][i] | |||||
| json.x @balance_chart_array[2][i].to_date | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,25 @@ | |||||
| json.balance @wallet.balance | |||||
| json.count @total | |||||
| json.coin_changes do | |||||
| json.array! @coin_changes do |coin_change| | |||||
| from_user = if coin_change.from_wallet.nil? | |||||
| nil | |||||
| else | |||||
| coin_change.from_wallet.user | |||||
| end | |||||
| to_user = coin_change.to_wallet.user | |||||
| json.amount coin_change.amount | |||||
| if !from_user.nil? | |||||
| json.from_user from_user.full_name | |||||
| json.from_user_login from_user.login | |||||
| else | |||||
| json.from_user '系统' | |||||
| json.from_user_login '-' | |||||
| end | |||||
| json.to_user to_user.full_name | |||||
| json.to_user_login to_user.login | |||||
| json.description coin_change.description | |||||
| json.reason coin_change.reason | |||||
| json.date coin_change.created_at.to_date | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,4 @@ | |||||
| json.array! (0..6).each do |i| | |||||
| json.y @community_data_array[0][i] | |||||
| json.x @community_data_array[1][i].to_date | |||||
| end | |||||
| @@ -1,12 +1,12 @@ | |||||
| development: | |||||
| adapter: redis | |||||
| url: redis://localhost:6379 | |||||
| #development: | |||||
| # adapter: redis | |||||
| # url: redis://localhost:6379 | |||||
| test: | |||||
| adapter: redis | |||||
| url: redis://localhost:6379 | |||||
| #test: | |||||
| # adapter: redis | |||||
| # url: redis://localhost:6379 | |||||
| production: | |||||
| adapter: redis | |||||
| url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379" } %> | |||||
| channel_prefix: forgeplus_production | |||||
| #production: | |||||
| # adapter: redis | |||||
| # url: <%#= ENV.fetch("REDIS_URL") { "redis://localhost:6379" } %> | |||||
| # channel_prefix: forgeplus_production | |||||
| @@ -55,6 +55,9 @@ Rails.application.configure do | |||||
| # Suppress logger output for asset requests. | # Suppress logger output for asset requests. | ||||
| config.assets.quiet = true | config.assets.quiet = true | ||||
| # config.logger = Logger.new("#{Rails.root}/log/#{Rails.env}#{Date.today.to_s}.log", "daily") | |||||
| # config.logger.level = Logger::INFO | |||||
| # config.assets.prefix = '/dev-assets' | # config.assets.prefix = '/dev-assets' | ||||
| # Raises error for missing translations | # Raises error for missing translations | ||||
| @@ -1,3 +1,3 @@ | |||||
| redis_config = Rails.application.config_for(:redis) | redis_config = Rails.application.config_for(:redis) | ||||
| cache_url = redis_config["url"] || 'redis://localhost:6379' | cache_url = redis_config["url"] || 'redis://localhost:6379' | ||||
| $redis_cache = Redis.new(url: cache_url, db: 2) | |||||
| # $redis_cache = Redis.new(url: cache_url, db: 2) | |||||
| @@ -0,0 +1,9 @@ | |||||
| require 'multi_logger' | |||||
| formatter = Proc.new{|severity, time, progname, msg| | |||||
| formatted_severity = sprintf("%-5s",severity.to_s) | |||||
| formatted_time = time.strftime("%Y-%m-%d %H:%M:%S") | |||||
| # "[#{formatted_severity} #{formatted_time} #{$$}] #{msg.to_s.strip}\n" | |||||
| "#{msg.to_s.strip}\n" | |||||
| } | |||||
| MultiLogger.add_logger('user_trace', formatter: formatter, shift_age: 'daily') | |||||
| Rails.logger.user_trace.level = Logger::INFO | |||||
| @@ -35,6 +35,28 @@ Rails.application.routes.draw do | |||||
| resources :edu_settings | resources :edu_settings | ||||
| scope '/api' do | scope '/api' do | ||||
| get 'wallets/balance' | |||||
| get 'wallets/coin_changes' | |||||
| get 'wallets/balance_chart' | |||||
| get 'sponsorships/community_data' | |||||
| get 'wallets/community_data' | |||||
| get 'log/list', to: 'log#list' | |||||
| # post 'log/download', to: 'log#download' | |||||
| match 'log/download/:filename' => 'log#download', :constraints => { filename: /[0-z\.]+/ }, via:[:get] | |||||
| resources :sponsor_tiers, only: [:index, :show, :create, :update, :destroy] | |||||
| resources :sponsorships, only: [:index, :show, :create, :update, :destroy] do | |||||
| collection do | |||||
| get :sponsored | |||||
| get :sponsoring | |||||
| get :stopped_sponsored | |||||
| get :stopped_sponsoring | |||||
| get :stopped | |||||
| end | |||||
| end | |||||
| resources :topics, only: [:index] | resources :topics, only: [:index] | ||||
| namespace :ci do | namespace :ci do | ||||
| resources :languages, only: [:index, :show] do | resources :languages, only: [:index, :show] do | ||||
| @@ -141,9 +163,9 @@ Rails.application.routes.draw do | |||||
| delete :quit | delete :quit | ||||
| end | end | ||||
| end | end | ||||
| resources :team_projects, only: [:index, :create, :destroy] do | |||||
| collection do | |||||
| post :create_all | |||||
| resources :team_projects, only: [:index, :create, :destroy] do | |||||
| collection do | |||||
| post :create_all | |||||
| delete :destroy_all | delete :destroy_all | ||||
| end | end | ||||
| end | end | ||||
| @@ -242,6 +264,7 @@ Rails.application.routes.draw do | |||||
| get :projects | get :projects | ||||
| get :watch_users | get :watch_users | ||||
| get :fan_users | get :fan_users | ||||
| put :update_sponsor_description | |||||
| get :hovercard | get :hovercard | ||||
| put :update_image | put :update_image | ||||
| get :get_image | get :get_image | ||||
| @@ -449,11 +472,11 @@ Rails.application.routes.draw do | |||||
| end | end | ||||
| end | end | ||||
| namespace :traces do | |||||
| namespace :traces do | |||||
| resources :trace_users, only: [:create] | resources :trace_users, only: [:create] | ||||
| scope "/:owner/:repo" do | |||||
| scope "/:owner/:repo" do | |||||
| resource :projects, path: '/', only: [:index] do | resource :projects, path: '/', only: [:index] do | ||||
| member do | |||||
| member do | |||||
| post :tasks | post :tasks | ||||
| get :task_results | get :task_results | ||||
| get :reload_task | get :reload_task | ||||
| @@ -664,15 +687,15 @@ Rails.application.routes.draw do | |||||
| post :cancel | post :cancel | ||||
| end | end | ||||
| end | end | ||||
| resources :project_invite_links, only: [:index] do | |||||
| collection do | |||||
| resources :project_invite_links, only: [:index] do | |||||
| collection do | |||||
| get :current_link | get :current_link | ||||
| post :generate_link | post :generate_link | ||||
| get :show_link | get :show_link | ||||
| post :redirect_link | post :redirect_link | ||||
| end | end | ||||
| end | end | ||||
| resources :webhooks, except: [:show, :new] do | |||||
| resources :webhooks, except: [:show, :new] do | |||||
| member do | member do | ||||
| get :tasks | get :tasks | ||||
| post :test | post :test | ||||
| @@ -768,12 +791,12 @@ Rails.application.routes.draw do | |||||
| resources :project_licenses | resources :project_licenses | ||||
| resources :project_ignores | resources :project_ignores | ||||
| resources :reversed_keywords | resources :reversed_keywords | ||||
| resources :system_notifications do | |||||
| member do | |||||
| resources :system_notifications do | |||||
| member do | |||||
| get :history | get :history | ||||
| end | end | ||||
| end | end | ||||
| resources :message_templates, only: [:index, :new, :create, :edit, :update] do | |||||
| resources :message_templates, only: [:index, :new, :create, :edit, :update] do | |||||
| collection do | collection do | ||||
| get :init_data | get :init_data | ||||
| end | end | ||||
| @@ -944,7 +967,7 @@ Rails.application.routes.draw do | |||||
| resources :nps do | resources :nps do | ||||
| post :switch_change, on: :collection | post :switch_change, on: :collection | ||||
| end | end | ||||
| resources :feedbacks, only: [:index, :destroy] do | |||||
| resources :feedbacks, only: [:index, :destroy] do | |||||
| get :new_history, on: :member | get :new_history, on: :member | ||||
| post :create_history, on: :member | post :create_history, on: :member | ||||
| end | end | ||||
| @@ -0,0 +1,41 @@ | |||||
| # Use this file to easily define all of your cron jobs. | |||||
| # | |||||
| # It's helpful, but not entirely necessary to understand cron before proceeding. | |||||
| # http://en.wikipedia.org/wiki/Cron | |||||
| # Example: | |||||
| # | |||||
| # set :output, "/path/to/my/cron_log.log" | |||||
| # | |||||
| # every 2.hours do | |||||
| # command "/usr/bin/some_great_command" | |||||
| # runner "MyModel.some_method" | |||||
| # rake "some:great:rake:task" | |||||
| # end | |||||
| # | |||||
| # every 4.days do | |||||
| # runner "AnotherModel.prune_old_records" | |||||
| # end | |||||
| # Learn more: http://github.com/javan/whenever | |||||
| # | |||||
| set :environment, :development | |||||
| every '0 1 20 * *' do | |||||
| runner 'Sponsorship.monthly_payment' | |||||
| end | |||||
| every '0 2 * * *' do | |||||
| runner 'Statistic.record' | |||||
| end | |||||
| # every 1.month, at: 'January 20th 10:00am' do | |||||
| # runner 'Sponsorship.monthly_payment' | |||||
| # end | |||||
| # ####################################################### | |||||
| # * * * * * command to be executed | |||||
| # - - - - - | |||||
| # | | | | | | |||||
| # | | | | +----- day of week (0 - 6) (Sunday=0) | |||||
| # | | | +------- month (1 - 12) | |||||
| # | | +--------- day of month (1 - 31) | |||||
| # | +----------- hour (0 - 23) | |||||
| # +------------- min (0 - 59) | |||||
| # ####################################################### | |||||
| @@ -0,0 +1,8 @@ | |||||
| class AddColumnToTableUsers < ActiveRecord::Migration[5.2] | |||||
| def change | |||||
| add_column :users, :description, :string, default: "" | |||||
| add_column :users, :sponsor_certification, :integer, default: 0 | |||||
| add_column :users, :sponsor_num, :integer, default: 0 | |||||
| add_column :users, :sponsored_num, :integer, default: 0 | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,12 @@ | |||||
| class CreateSponsorships < ActiveRecord::Migration[5.2] | |||||
| def change | |||||
| create_table :sponsorships do |t| | |||||
| t.integer :amount | |||||
| t.integer :visible | |||||
| t.integer :sponsor_id | |||||
| t.integer :developer_id | |||||
| t.timestamps | |||||
| end | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,9 @@ | |||||
| class CreateSponsorTiers < ActiveRecord::Migration[5.2] | |||||
| def change | |||||
| create_table :sponsor_tiers do |t| | |||||
| t.integer :tier | |||||
| t.timestamps | |||||
| end | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,6 @@ | |||||
| class AddColumnToSponsorTiers < ActiveRecord::Migration[5.2] | |||||
| def change | |||||
| add_column :sponsor_tiers, :description, :string, default: "" | |||||
| add_column :sponsor_tiers, :user_id, :integer | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,11 @@ | |||||
| class CreateStoppedSponsorships < ActiveRecord::Migration[5.2] | |||||
| def change | |||||
| create_table :stopped_sponsorships do |t| | |||||
| t.integer :amount | |||||
| t.integer :sponsor_id | |||||
| t.integer :developer_id | |||||
| t.timestamps | |||||
| end | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,10 @@ | |||||
| class CreateWallets < ActiveRecord::Migration[5.2] | |||||
| def change | |||||
| create_table :wallets do |t| | |||||
| t.integer :balance | |||||
| t.integer :user_id | |||||
| t.timestamps | |||||
| end | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,13 @@ | |||||
| class CreateCoinChanges < ActiveRecord::Migration[5.2] | |||||
| def change | |||||
| create_table :coin_changes do |t| | |||||
| t.integer :amount | |||||
| t.string :description | |||||
| t.string :reason | |||||
| t.integer :to_wallet_id | |||||
| t.integer :from_wallet_id | |||||
| t.timestamps | |||||
| end | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,12 @@ | |||||
| class CreateWaitlists < ActiveRecord::Migration[5.2] | |||||
| def change | |||||
| create_table :waitlists do |t| | |||||
| t.string :applicant_id | |||||
| t.string :integer | |||||
| t.string :reviewer_id | |||||
| t.string :integer | |||||
| t.timestamps | |||||
| end | |||||
| end | |||||
| end | |||||