diff --git a/app/controllers/admins/competition_settings_controller.rb b/app/controllers/admins/competition_settings_controller.rb new file mode 100644 index 000000000..390ad17e8 --- /dev/null +++ b/app/controllers/admins/competition_settings_controller.rb @@ -0,0 +1,20 @@ +class Admins::CompetitionSettingsController < Admins::BaseController + def show + @competition = current_competition + end + + def update + Admins::SaveLaboratorySettingService.call(current_competition, form_params) + render_ok + end + + private + + def current_competition + @_current_competition ||= Competition.find(params[:competition_id]) + end + + def form_params + params.permit(:identifier, :name, :nav_logo, :login_logo, :tab_logo, :footer, navbar: %i[name link hidden]) + end +end \ No newline at end of file diff --git a/app/controllers/admins/competitions_controller.rb b/app/controllers/admins/competitions_controller.rb index 3d6bef819..3b9b63243 100644 --- a/app/controllers/admins/competitions_controller.rb +++ b/app/controllers/admins/competitions_controller.rb @@ -1,4 +1,6 @@ class Admins::CompetitionsController < Admins::BaseController + include CustomSortable + before_action :find_competition, except: [:index] def index params[:sort_by] = params[:sort_by].presence || 'created_on' @@ -6,10 +8,39 @@ class Admins::CompetitionsController < Admins::BaseController @competitions = custom_sort Competition.all, params[:sort_by], params[:sort_direction] @params_page = params[:page] || 1 @competitions = paginate @competitions + ids = @competitions.map(&:id) + @member_count_map = TeamMember.where(competition_id: ids).group(:competition_id).count respond_to do |format| format.js format.html end end + + def publish + @competition.update_attributes!(:published_at, Time.now) + end + + def unpublish + @competition.update_attributes!(:published_at, nil) + end + + def online_switch + if @competition.status + @competition.update_attributes!(status: false) + else + @competition.update_attributes!(status: true, online_time: Time.now) + end + end + + def enroll_list + + end + + private + + def find_competition + @competition = Competition.find_by(id: params[:id]) + end + end \ No newline at end of file diff --git a/app/controllers/weapps/base_controller.rb b/app/controllers/weapps/base_controller.rb new file mode 100644 index 000000000..fadf10fb6 --- /dev/null +++ b/app/controllers/weapps/base_controller.rb @@ -0,0 +1,34 @@ +class Weapps::BaseController < ApplicationController + + private + + def require_wechat_login! + return if session_unionid.present? + + render_error('请先进行微信授权') + end + + def weapp_session_key + Wechat::Weapp.session_key(session_openid) + end + + def set_weapp_session_key(session_key) + Wechat::Weapp.write_session_key(session_openid, session_key) + end + + def session_openid + session[:openid] + end + + def set_session_openid(openid) + session[:openid] = openid + end + + def session_unionid + session[:unionid] + end + + def set_session_unionid(unionid) + session[:unionid] = unionid + end +end \ No newline at end of file diff --git a/app/controllers/weapps/code_sessions_controller.rb b/app/controllers/weapps/code_sessions_controller.rb new file mode 100644 index 000000000..7c1978e5f --- /dev/null +++ b/app/controllers/weapps/code_sessions_controller.rb @@ -0,0 +1,24 @@ +class Weapps::CodeSessionsController < Weapps::BaseController + def create + return render_error('code不能为空') if params[:code].blank? + + result = Wechat::Weapp.jscode2session(params[:code]) + + set_session_openid(result['openid']) + set_weapp_session_key(result['session_key']) # weapp session_key写入缓存 后续解密需要 + + # 已授权,绑定过账号 + open_user = OpenUser::Wechat.find_by(uid: result['unionid']) + if open_user.present? && open_user.user + set_session_unionid(result['unionid']) + successful_authentication(open_user.user) + else + # 新用户 + user_info = Wechat::Weapp.decrypt(result['session_key'], params[:encrypted_data], params[:iv]) + + set_session_unionid(user_info['unionId']) + end + + render_ok(openid: result['openid']) + end +end \ No newline at end of file diff --git a/app/controllers/weapps/homes_controller.rb b/app/controllers/weapps/homes_controller.rb new file mode 100644 index 000000000..efb80b898 --- /dev/null +++ b/app/controllers/weapps/homes_controller.rb @@ -0,0 +1,12 @@ +class Weapps::HomesController < Weapps::BaseController + def show + # banner图 + @images = PortalImage.where(status: true).order(position: :asc) + + # 热门实训 + @shixuns = Shixun.where(homepage_show: true).includes(:tag_repertoires, :challenges).limit(4) + + # 热门实践课程 + @subjects = Subject.where(homepage_show: true).includes(:shixuns, :repertoire).limit(4) + end +end \ No newline at end of file diff --git a/app/controllers/weapps/registers_controller.rb b/app/controllers/weapps/registers_controller.rb new file mode 100644 index 000000000..0cbab7fd4 --- /dev/null +++ b/app/controllers/weapps/registers_controller.rb @@ -0,0 +1,63 @@ +class Weapps::RegistersController < Weapps::BaseController + before_action :require_wechat_login! + + def create + # 查询验证码是否正确;type只可能是1或者8 + type = phone_mail_type(params[:login].strip) + code = params[:code].strip + + if type == 1 + uid_logger("start register by phone: type is #{type}") + pre = 'p' + email = nil + phone = params[:login] + verifi_code = VerificationCode.where(phone: phone, code: code, code_type: 1).last + else + uid_logger("start register by email: type is #{type}") + pre = 'm' + email = params[:login] + phone = nil + verifi_code = VerificationCode.where(email: email, code: code, code_type: 8).last + end + uid_logger("start register: verifi_code is #{verifi_code}, code is #{code}, time is #{Time.now.to_i - verifi_code.try(:created_at).to_i}") + # check_code = (verifi_code.try(:code) == code.strip && (Time.now.to_i - verifi_code.created_at.to_i) <= 10*60) + # todo 上线前请删除万能验证码"513231" + unless code == "513231" && request.subdomain == "test-newweb" + return render_error('验证码不正确') if verifi_code.try(:code) != code.strip + return render_error('验证码已失效') if !verifi_code&.effective? + end + + login = User.generate_login(pre) + @user = User.new(admin: false, login: login, mail: email, phone: phone, type: 'User') + @user.password = params[:password] + # 现在因为是验证码,所以在注册的时候就可以激活 + @user.activate + # 必须要用save操作,密码的保存是在users中 + ActiveRecord::Base.transaction do + @user.save! + UserExtension.create!(user_id: @user.id) + # 绑定微信号 + OpenUsers::Wechat.create!(user: @user, uid: session_unionid) + + # 注册完成,手机号或邮箱想可以奖励500金币 + RewardGradeService.call( + @user, + container_id: @user.id, + container_type: pre == 'p' ? 'Phone' : 'Mail', + score: 500 + ) + end + successful_authentication(@user) + session[:user_id] = @user.id + + render_ok + end + + private + + # 1 手机类型;0 邮箱类型 + # 注意新版的login是自动名生成的 + def phone_mail_type value + value =~ /^1\d{10}$/ ? 1 : 0 + end +end \ No newline at end of file diff --git a/app/controllers/weapps/sessions_controller.rb b/app/controllers/weapps/sessions_controller.rb new file mode 100644 index 000000000..f65111399 --- /dev/null +++ b/app/controllers/weapps/sessions_controller.rb @@ -0,0 +1,24 @@ +class Weapps::SessionsController < Weapps::BaseController + before_action :require_wechat_login! + + def create + return render_error('重复登录') if current_user.present? && current_user.logged? + + user = User.try_to_login(params[:login], params[:password]) + + return render_error('错误的账号或密码') if user.blank? + return render_error('违反平台使用规范,账号已被锁定') if user.locked? + return render_error('错误的账号或密码') unless user.check_password?(params[:password].to_s) + + if user.wechat_open_user && user.wechat_open_user.uid != session_unionid + render_error('该账号已被其它微信号绑定') + return + end + + # 绑定微信号 + OpenUsers::Wechat.create!(user: user, uid: session_unionid) if user.wechat_open_user.blank? + + successful_authentication(user) + render_ok + end +end \ No newline at end of file diff --git a/app/controllers/weapps/verifies_controller.rb b/app/controllers/weapps/verifies_controller.rb new file mode 100644 index 000000000..5d8f4056e --- /dev/null +++ b/app/controllers/weapps/verifies_controller.rb @@ -0,0 +1,8 @@ +class Weapps::VerifiesController < Weapps::BaseController + before_action :require_wechat_login! + + def create + valid = Wechat::Weapp.verify?(session_openid, params[:verify_string], params[:signature]) + render_ok(valid: valid) + end +end \ No newline at end of file diff --git a/app/libs/wechat/weapp.rb b/app/libs/wechat/weapp.rb index 54f60fa2a..755c9351a 100644 --- a/app/libs/wechat/weapp.rb +++ b/app/libs/wechat/weapp.rb @@ -1,4 +1,4 @@ -class Wechat::App +class Wechat::Weapp class << self attr_accessor :appid, :secret @@ -7,5 +7,41 @@ class Wechat::App def client @_client ||= Wechat::Client.new(appid, secret) end + + def session_key(openid) + Rails.cache.read(session_key_cache_key(openid)) + end + + def write_session_key(openid, session_key) + Rails.cache.write(session_key_cache_key(openid), session_key) + end + + def verify?(openid, str, signature) + session_key = session_key(openid) + Digest::SHA1.hexdigest("#{str}#{session_key}") == signature + end + + def decrypt(session_key, encrypted_data, iv) + session_key = Base64.decode64(session_key) + encrypted_data = Base64.decode64(encrypted_data) + iv = Base64.decode64(iv) + + cipher = OpenSSL::Cipher::AES.new(128, :CBC) + cipher.decrypt + cipher.padding = 0 + cipher.key = session_key + cipher.iv = iv + data = cipher.update(encrypted_data) << cipher.final + result = JSON.parse(data[0...-data.last.ord]) + + raise Wechat::Error, '解密错误' if result.dig('watermark', 'appid') != appid + result + end + + private + + def session_key_cache_key(openid) + "weapp:#{appid}:#{openid}:session_key" + end end end \ No newline at end of file diff --git a/app/models/competition.rb b/app/models/competition.rb index 024478ad6..9055adefc 100644 --- a/app/models/competition.rb +++ b/app/models/competition.rb @@ -18,6 +18,29 @@ class Competition < ApplicationRecord after_create :create_competition_modules + def mode_type + case mode + when 1 + "课堂" + when 2 + "实训" + when 3 + "教学" + when 4 + "托管" + else + "--" + end + end + + def teacher_staff_num + teacher_staff ? "#{teacher_staff.minimum}~#{teacher_staff.maximum}" : "--" + end + + def member_staff_num + member_staff ? "#{member_staff.minimum}~#{member_staff.maximum}" : "--" + end + # 是否上架 def published? status? diff --git a/app/views/admins/competition_settings/show.html.erb b/app/views/admins/competition_settings/show.html.erb new file mode 100644 index 000000000..e69de29bb diff --git a/app/views/admins/competitions/enroll_list.html.erb b/app/views/admins/competitions/enroll_list.html.erb new file mode 100644 index 000000000..e69de29bb diff --git a/app/views/admins/competitions/index.html.erb b/app/views/admins/competitions/index.html.erb index 8fa238181..b97e26f94 100644 --- a/app/views/admins/competitions/index.html.erb +++ b/app/views/admins/competitions/index.html.erb @@ -3,5 +3,7 @@ <% end %>
序号 | +竞赛主标题 | +竞赛副标题 | +模式 | +报名人数 | +指导老师 | +参赛者 | +主题图片796*397 | +创建时间 | ++ 操作 + | + + + <% if competitions.present? %> + <% competitions.each_with_index do |competition, index| %> +
---|