mirror of
https://gitlink.org.cn/Gitlink/forgeplus.git
synced 2026-05-03 03:40:49 +08:00
init project
This commit is contained in:
277
app/controllers/accounts_controller.rb
Normal file
277
app/controllers/accounts_controller.rb
Normal file
@@ -0,0 +1,277 @@
|
||||
class AccountsController < ApplicationController
|
||||
|
||||
#skip_before_action :check_account, :only => [:logout]
|
||||
|
||||
def index
|
||||
render json: session
|
||||
end
|
||||
|
||||
# 其他平台同步注册的用户
|
||||
def remote_register
|
||||
username = params[:username]&.gsub(/\s+/, "")
|
||||
email = params[:email]&.gsub(/\s+/, "")
|
||||
password = params[:password]
|
||||
platform = (params[:platform] || 'forge')&.gsub(/\s+/, "")
|
||||
|
||||
@user = User.new(admin: false, login: username, mail: email, type: "User")
|
||||
@user.password = password
|
||||
@user.platform = platform
|
||||
@user.activate
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
interactor = Gitea::RegisterInteractor.call({username: username, email: email, password: password})
|
||||
if interactor.success?
|
||||
gitea_user = interactor.result
|
||||
result = Gitea::User::GenerateTokenService.new(username, password).call
|
||||
@user.gitea_token = result['sha1']
|
||||
@user.gitea_uid = gitea_user['id']
|
||||
if @user.save!
|
||||
render_ok({user: {id: @user.id, token: @user.gitea_token}})
|
||||
end
|
||||
else
|
||||
render_error(interactor.error)
|
||||
end
|
||||
end
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
tip_exception(-1, e.message)
|
||||
end
|
||||
|
||||
# 用户注册
|
||||
# 注意:用户注册需要兼顾本地版,本地版是不需要验证码及激活码以及使用授权的,注册完成即可使用
|
||||
# params[:login] 邮箱或者手机号
|
||||
# params[:code] 验证码
|
||||
# code_type 1:注册手机验证码 8:邮箱注册验证码
|
||||
def register
|
||||
begin
|
||||
# 查询验证码是否正确;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 normal_status(-2, "验证码不正确") if verifi_code.try(:code) != code.strip
|
||||
return normal_status(-2, "验证码已失效") if !verifi_code&.effective?
|
||||
end
|
||||
|
||||
return normal_status(-1, "8~16位密码,支持字母数字和符号") unless params[:password] =~ CustomRegexp::PASSWORD
|
||||
|
||||
code = generate_identifier User, 8, pre
|
||||
login = pre + code
|
||||
@user = User.new(admin: false, login: login, mail: email, phone: phone, type: "User")
|
||||
@user.password = params[:password]
|
||||
# 现在因为是验证码,所以在注册的时候就可以激活
|
||||
@user.activate
|
||||
# 必须要用save操作,密码的保存是在users中
|
||||
if @user.save!
|
||||
# todo user_extension
|
||||
UserExtension.create!(user_id: @user.id)
|
||||
# 注册完成,手机号或邮箱想可以奖励500金币
|
||||
# RewardGradeService.call(
|
||||
# @user,
|
||||
# container_id: @user.id,
|
||||
# container_type: pre == 'p' ? 'Phone' : 'Mail',
|
||||
# score: 500
|
||||
# )
|
||||
# 注册时,记录是否是引流用户
|
||||
ip = request.remote_ip
|
||||
ua = UserAgent.find_by_ip(ip)
|
||||
ua.update_column(:agent_type, UserAgent::USER_REGISTER) if ua
|
||||
successful_authentication(@user)
|
||||
# session[:user_id] = @user.id
|
||||
normal_status("注册成功")
|
||||
end
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
tip_exception(-1, e.message)
|
||||
end
|
||||
end
|
||||
|
||||
# 用户登录
|
||||
def login
|
||||
@user = User.try_to_login(params[:login], params[:password])
|
||||
|
||||
return normal_status(-2, "错误的账号或密码") if @user.blank?
|
||||
# user is already in local database
|
||||
return normal_status(-2, "违反平台使用规范,账号已被锁定") if @user.locked?
|
||||
|
||||
login_control = LimitForbidControl::UserLogin.new(@user)
|
||||
return normal_status(-2, "登录密码出错已达上限,账号已被锁定, 请#{login_control.forbid_expires/60}分钟后重新登录或找回密码") if login_control.forbid?
|
||||
|
||||
password_ok = @user.check_password?(params[:password].to_s)
|
||||
unless password_ok
|
||||
if login_control.remain_times-1 == 0
|
||||
normal_status(-2, "登录密码出错已达上限,账号已被锁定, 请#{login_control.forbid_expires/60}分钟后重新登录或找回密码")
|
||||
else
|
||||
normal_status(-2, "你已经输错密码#{login_control.error_times+1}次,还剩余#{login_control.remain_times-1}次机会")
|
||||
end
|
||||
login_control.increment!
|
||||
return
|
||||
end
|
||||
|
||||
successful_authentication(@user)
|
||||
login_control.clear # 重置每日密码错误次数
|
||||
|
||||
# session[:user_id] = @user.id
|
||||
end
|
||||
|
||||
# 忘记密码
|
||||
def reset_password
|
||||
begin
|
||||
code = params[:code]
|
||||
login_type = phone_mail_type(params[:login].strip)
|
||||
# 获取验证码
|
||||
if login_type == 1
|
||||
phone = params[:login]
|
||||
verifi_code = VerificationCode.where(phone: phone, code: code, code_type: 2).last
|
||||
user = User.find_by_phone(phone)
|
||||
else
|
||||
email = params[:login]
|
||||
verifi_code = VerificationCode.where(email: email, code: code, code_type: 3).last
|
||||
user = User.find_by_mail(email) #这里有问题,应该是为email,而不是mail 6.13-hs
|
||||
end
|
||||
return normal_status(-2, "验证码不正确") if verifi_code.try(:code) != code.strip
|
||||
return normal_status(-2, "验证码已失效") if !verifi_code&.effective?
|
||||
return normal_status(-1, "8~16位密码,支持字母数字和符号") unless params[:new_password] =~ CustomRegexp::PASSWORD
|
||||
|
||||
user.password, user.password_confirmation = params[:new_password], params[:new_password_confirmation]
|
||||
ActiveRecord::Base.transaction do
|
||||
user.save!
|
||||
LimitForbidControl::UserLogin.new(user).clear
|
||||
end
|
||||
sucess_status
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
tip_exception(e.message)
|
||||
end
|
||||
end
|
||||
|
||||
def successful_authentication(user)
|
||||
uid_logger("Successful authentication start: '#{user.login}' from #{request.remote_ip} at #{Time.now.utc}")
|
||||
# Valid user
|
||||
self.logged_user = user
|
||||
# generate a key and set cookie if autologin
|
||||
|
||||
set_autologin_cookie(user)
|
||||
UserAction.create(:action_id => user.try(:id), :action_type => "Login", :user_id => user.try(:id), :ip => request.remote_ip)
|
||||
user.update_column(:last_login_on, Time.now)
|
||||
session[:"#{default_yun_session}"] = user.id
|
||||
# 注册完成后有一天的试用申请(先去掉)
|
||||
# UserDayCertification.create(user_id: user.id, status: 1)
|
||||
end
|
||||
|
||||
# def set_autologin_cookie(user)
|
||||
# token = Token.get_or_create_permanent_login_token(user, "autologin")
|
||||
# cookie_options = {
|
||||
# :value => token.value,
|
||||
# :expires => 1.month.from_now,
|
||||
# :path => '/',
|
||||
# :secure => false,
|
||||
# :httponly => true
|
||||
# }
|
||||
# if edu_setting('cookie_domain').present?
|
||||
# cookie_options = cookie_options.merge(domain: edu_setting('cookie_domain'))
|
||||
# end
|
||||
# cookies[autologin_cookie_name] = cookie_options
|
||||
# logger.info("cookies is #{cookies}")
|
||||
# end
|
||||
|
||||
def logout
|
||||
UserAction.create(action_id: User.current.id, action_type: "Logout", user_id: User.current.id, :ip => request.remote_ip)
|
||||
logout_user
|
||||
render :json => {status: 1, message: "退出成功!"}
|
||||
end
|
||||
|
||||
# 检验邮箱是否已被注册及邮箱或者手机号是否合法
|
||||
# 参数type为事件类型 1:注册;2:忘记密码;3:绑定
|
||||
def valid_email_and_phone
|
||||
check_mail_and_phone_valid(params[:login], params[:type])
|
||||
end
|
||||
|
||||
# 发送验证码
|
||||
# params[:login] 手机号或者邮箱号
|
||||
# params[:type]为事件通知类型 1:用户注册注册 2:忘记密码 3: 绑定手机 4: 绑定邮箱, 5: 验收手机号有效 # 如果有新的继续后面加
|
||||
# 发送验证码:send_type 1:注册手机验证码 2:找回密码手机验证码 3:找回密码邮箱验证码 4:绑定手机 5:绑定邮箱
|
||||
# 6:手机验证码登录 7:邮箱验证码登录 8:邮箱注册验证码 9: 验收手机号有效
|
||||
def get_verification_code
|
||||
code = %W(0 1 2 3 4 5 6 7 8 9)
|
||||
value = params[:login]
|
||||
type = params[:type].strip.to_i
|
||||
login_type = phone_mail_type(value)
|
||||
send_type = verify_type(login_type, type)
|
||||
verification_code = code.sample(6).join
|
||||
|
||||
sign = Digest::MD5.hexdigest("#{OPENKEY}#{value}")
|
||||
tip_exception(501, "请求不合理") if sign != params[:smscode]
|
||||
|
||||
logger.info("########get_verification_code: login_type: #{login_type}, send_type:#{send_type}, ")
|
||||
|
||||
# 记录验证码
|
||||
check_verification_code(verification_code, send_type, value)
|
||||
sucess_status
|
||||
end
|
||||
|
||||
# 1 手机类型;0 邮箱类型
|
||||
# 注意新版的login是自动名生成的
|
||||
def phone_mail_type value
|
||||
value =~ /^1\d{10}$/ ? 1 : 0
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# type 事件类型 1:用户注册 2:忘记密码 3: 绑定手机 4: 绑定邮箱, 5: 验证手机号是否有效 # 如果有新的继续后面加
|
||||
# login_type 1:手机类型 2:邮箱类型
|
||||
def verify_type login_type, type
|
||||
case type
|
||||
when 1
|
||||
login_type == 1 ? 1 : 8
|
||||
when 2
|
||||
login_type == 1 ? 2 : 3
|
||||
when 3
|
||||
login_type == 1 ? 4 : tip_exception('请填写正确的手机号')
|
||||
when 4
|
||||
login_type == 1 ? tip_exception('请填写正确的邮箱') : 5
|
||||
when 5
|
||||
login_type == 1 ? 9 : tip_exception('请填写正确的手机号')
|
||||
end
|
||||
end
|
||||
|
||||
def generate_login(login)
|
||||
type = phone_mail_type(login.strip)
|
||||
|
||||
if type == 1
|
||||
uid_logger("start register by phone: type is #{type}")
|
||||
pre = 'p'
|
||||
email = nil
|
||||
phone = login
|
||||
else
|
||||
uid_logger("start register by email: type is #{type}")
|
||||
pre = 'm'
|
||||
email = login
|
||||
phone = nil
|
||||
end
|
||||
code = generate_identifier User, 8, pre
|
||||
|
||||
{ login: pre + code, email: email, phone: phone }
|
||||
end
|
||||
|
||||
def user_params
|
||||
params.require(:user).permit(:login, :email, :phone)
|
||||
end
|
||||
|
||||
end
|
||||
18
app/controllers/admins/abouts_controller.rb
Normal file
18
app/controllers/admins/abouts_controller.rb
Normal file
@@ -0,0 +1,18 @@
|
||||
class Admins::AboutsController < Admins::BaseController
|
||||
def edit
|
||||
current_doc
|
||||
end
|
||||
|
||||
def update
|
||||
current_doc.update!(about_us: params[:about_us])
|
||||
|
||||
flash[:success] = '保存成功'
|
||||
redirect_to edit_admins_about_path
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_doc
|
||||
@doc ||= Help.first || Help.create
|
||||
end
|
||||
end
|
||||
18
app/controllers/admins/agreements_controller.rb
Normal file
18
app/controllers/admins/agreements_controller.rb
Normal file
@@ -0,0 +1,18 @@
|
||||
class Admins::AgreementsController < Admins::BaseController
|
||||
def edit
|
||||
current_doc
|
||||
end
|
||||
|
||||
def update
|
||||
current_doc.update!(agreement: params[:agreement])
|
||||
|
||||
flash[:success] = '保存成功'
|
||||
redirect_to edit_admins_agreement_path
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_doc
|
||||
@doc ||= Help.first || Help.create
|
||||
end
|
||||
end
|
||||
58
app/controllers/admins/auth_schools_controller.rb
Normal file
58
app/controllers/admins/auth_schools_controller.rb
Normal file
@@ -0,0 +1,58 @@
|
||||
class Admins::AuthSchoolsController < Admins::BaseController
|
||||
|
||||
def index
|
||||
schools = School.where(ec_auth: 1).includes(:users).order("updated_at desc")
|
||||
@params_page = params[:page] || 1
|
||||
@schools = paginate schools
|
||||
end
|
||||
|
||||
def destroy
|
||||
ActiveRecord::Base.transaction do
|
||||
school = School.where(id: params[:id]).first
|
||||
school.destroy
|
||||
render_success_js
|
||||
end
|
||||
end
|
||||
|
||||
# 工程认证单位列表搜索学校
|
||||
def search_school
|
||||
@schools = School.where("ec_auth != 1 and name like '%#{params[:name]}%'").limit(10)
|
||||
end
|
||||
|
||||
# 添加认证学校
|
||||
def add_school
|
||||
all_schools = School.all
|
||||
all_schools.where(id: params[:school_id]).update_all(ec_auth: 1)
|
||||
schools = all_schools.where(ec_auth: 1).order("updated_at desc")
|
||||
@params_page = params[:page] || 1
|
||||
@schools = paginate schools
|
||||
end
|
||||
|
||||
# 搜索用户
|
||||
def search_manager
|
||||
school = School.find_by(id: params[:school_id])
|
||||
user_ids = school&.ec_school_users&.pluck(:user_id)
|
||||
@users = User.where.not(id: user_ids).where("concat(lastname, firstname) like ?", "%#{params[:name].strip.to_s}%").limit(10)
|
||||
end
|
||||
|
||||
# 添加认证学校管理员
|
||||
def add_manager
|
||||
ActiveRecord::Base.transaction do
|
||||
user_ids = params[:user_id]
|
||||
@school_id = params[:school_id]
|
||||
user_ids.each do |id|
|
||||
EcSchoolUser.create(user_id: id, school_id: @school_id)
|
||||
end
|
||||
@school_users = User.where(id: user_ids)
|
||||
end
|
||||
end
|
||||
|
||||
# 删除学校管理员
|
||||
def remove_manager
|
||||
ActiveRecord::Base.transaction do
|
||||
manager = EcSchoolUser.where(school_id: params[:school_id], user_id: params[:user_id]).first
|
||||
manager&.destroy
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
45
app/controllers/admins/base_controller.rb
Normal file
45
app/controllers/admins/base_controller.rb
Normal file
@@ -0,0 +1,45 @@
|
||||
class Admins::BaseController < ApplicationController
|
||||
include Base::PaginateHelper
|
||||
include Admins::RenderHelper
|
||||
include Base::ErrorRescueHandler
|
||||
|
||||
layout 'admin'
|
||||
|
||||
skip_before_action :verify_authenticity_token
|
||||
before_action :require_login, :require_admin!
|
||||
|
||||
after_action :rebind_event_if_ajax_render_partial
|
||||
skip_before_action :check_sign
|
||||
|
||||
private
|
||||
|
||||
def require_login
|
||||
return if User.current.logged?
|
||||
|
||||
redirect_to "/login?back_url=#{CGI::escape(request.fullpath)}"
|
||||
end
|
||||
|
||||
def require_admin!
|
||||
return if current_user.blank? || !current_user.logged?
|
||||
return if current_user.admin_or_business?
|
||||
|
||||
render_forbidden
|
||||
end
|
||||
|
||||
# 触发after ajax render partial hooks,执行一些因为局部刷新后失效的绑定事件
|
||||
def rebind_event_if_ajax_render_partial
|
||||
return if request.format.symbol != :js
|
||||
return if response.content_type != 'text/javascript'
|
||||
|
||||
path = Rails.root.join('app/views/admins/shared/after_render_js_hook.js.erb')
|
||||
return unless File.exists?(path)
|
||||
|
||||
append_js = ERB.new(File.open(path).read).result
|
||||
response.body += append_js
|
||||
end
|
||||
|
||||
# 重写此方法,防止影响超级管理员端云上实验室功能,因为那里重写了:current_laboratory方法
|
||||
def setup_laboratory
|
||||
Laboratory.current = Laboratory.find_by_subdomain(request.subdomain) || Laboratory.find(1)
|
||||
end
|
||||
end
|
||||
86
app/controllers/admins/carousels_controller.rb
Normal file
86
app/controllers/admins/carousels_controller.rb
Normal file
@@ -0,0 +1,86 @@
|
||||
class Admins::CarouselsController < Admins::BaseController
|
||||
before_action :convert_file!, only: [:create]
|
||||
|
||||
helper_method :current_laboratory
|
||||
|
||||
def index
|
||||
@images = current_laboratory.portal_images.order(position: :asc)
|
||||
end
|
||||
|
||||
def create
|
||||
position = current_laboratory.portal_images.count + 1
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
image = current_laboratory.portal_images.create!(create_params.merge(position: position))
|
||||
|
||||
file_path = Util::FileManage.disk_filename('PortalImage', image.id)
|
||||
File.delete(file_path) if File.exist?(file_path) # 删除之前的文件
|
||||
Util.write_file(@file, file_path)
|
||||
end
|
||||
|
||||
flash[:success] = '保存成功'
|
||||
redirect_to admins_laboratory_carousels_path(current_laboratory)
|
||||
end
|
||||
|
||||
def update
|
||||
current_image.update!(update_params)
|
||||
render_ok
|
||||
end
|
||||
|
||||
def destroy
|
||||
ActiveRecord::Base.transaction do
|
||||
current_image.destroy!
|
||||
# 前移
|
||||
current_laboratory.portal_images.where('position > ?', current_image.position)
|
||||
.update_all('position = position - 1')
|
||||
|
||||
file_path = Util::FileManage.disk_filename('PortalImage', current_image.id)
|
||||
File.delete(file_path) if File.exist?(file_path)
|
||||
end
|
||||
render_delete_success
|
||||
end
|
||||
|
||||
def drag
|
||||
move = current_laboratory.portal_images.find_by(id: params[:move_id])
|
||||
after = current_laboratory.portal_images.find_by(id: params[:after_id])
|
||||
|
||||
Admins::DragPortalImageService.call(current_laboratory, move, after)
|
||||
render_ok
|
||||
rescue Admins::DragPortalImageService::Error => e
|
||||
render_error(e.message)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_laboratory
|
||||
@_current_laboratory ||= Laboratory.find(params[:laboratory_id])
|
||||
end
|
||||
|
||||
def current_image
|
||||
@_current_image ||= current_laboratory.portal_images.find(params[:id])
|
||||
end
|
||||
|
||||
def create_params
|
||||
params.require(:portal_image).permit(:name, :link)
|
||||
end
|
||||
|
||||
def update_params
|
||||
params.permit(:name, :link, :status)
|
||||
end
|
||||
|
||||
def convert_file!
|
||||
max_size = 10 * 1024 * 1024 # 10M
|
||||
file = params.dig('portal_image', 'image')
|
||||
if file.class == ActionDispatch::Http::UploadedFile
|
||||
@file = file
|
||||
render_error('请上传文件') if @file.size.zero?
|
||||
render_error('文件大小超过限制') if @file.size > max_size
|
||||
else
|
||||
file = file.to_s.strip
|
||||
return render_error('请上传正确的图片') if file.blank?
|
||||
@file = Util.convert_base64_image(file, max_size: max_size)
|
||||
end
|
||||
rescue Base64ImageConverter::Error => ex
|
||||
render_error(ex.message)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,11 @@
|
||||
class Admins::ChooseMirrorRepositoriesController < Admins::BaseController
|
||||
def new
|
||||
@mirror = MirrorRepository.find(params[:mirror_id])
|
||||
@new_mirror = MirrorOperationRecord.where(mirror_repository_id: @mirror.id, status: 1, user_id: -1).first
|
||||
end
|
||||
|
||||
def create
|
||||
mirror = MirrorRepository.find(params[:mirror_id])
|
||||
Admins::ChooseMirrorService.call(mirror, current_user, params[:mirror_number])
|
||||
end
|
||||
end
|
||||
28
app/controllers/admins/contact_us_controller.rb
Normal file
28
app/controllers/admins/contact_us_controller.rb
Normal file
@@ -0,0 +1,28 @@
|
||||
class Admins::ContactUsController < Admins::BaseController
|
||||
def edit
|
||||
@cooperations = Cooperation.all.group(:user_type)
|
||||
@help = Help.first
|
||||
end
|
||||
|
||||
def update
|
||||
cooperation = Cooperation.find(params[:id])
|
||||
cooperation.update!(update_cooperation_params)
|
||||
|
||||
flash[:success] = '保存成功'
|
||||
redirect_to edit_admins_contact_us_path
|
||||
end
|
||||
|
||||
def update_address
|
||||
help = Help.first || Help.create
|
||||
help.update!(status: params.dig('help', 'status'))
|
||||
|
||||
flash[:success] = '保存成功'
|
||||
redirect_to edit_admins_contact_us_path
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def update_cooperation_params
|
||||
params.require(:cooperation).permit(:name, :qq, :mail)
|
||||
end
|
||||
end
|
||||
84
app/controllers/admins/cooperatives_controller.rb
Normal file
84
app/controllers/admins/cooperatives_controller.rb
Normal file
@@ -0,0 +1,84 @@
|
||||
class Admins::CooperativesController < Admins::BaseController
|
||||
before_action :convert_file!, only: [:create]
|
||||
|
||||
def index
|
||||
@data = { 'alliance_coop' => [], 'com_coop' => [], 'edu_coop' => [] }
|
||||
@data = @data.merge CooImg.all.group_by(&:img_type)
|
||||
end
|
||||
|
||||
def create
|
||||
position = CooImg.where(img_type: create_params[:img_type]).count + 1
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
coo = CooImg.create!(create_params.merge(position: position))
|
||||
|
||||
file_path = Util::FileManage.disk_filename('CooImg', coo.id)
|
||||
File.delete(file_path) if File.exist?(file_path) # 删除之前的文件
|
||||
Util.write_file(@file, file_path)
|
||||
|
||||
coo.update!(url_states: Util::FileManage.disk_file_url('CooImg', coo.id))
|
||||
end
|
||||
|
||||
flash[:success] = '保存成功'
|
||||
redirect_to admins_cooperatives_path
|
||||
end
|
||||
|
||||
def update
|
||||
current_coo.update!(src_states: params[:url])
|
||||
render_ok
|
||||
end
|
||||
|
||||
def destroy
|
||||
ActiveRecord::Base.transaction do
|
||||
current_coo.destroy!
|
||||
# 前移
|
||||
CooImg.where(img_type: current_coo.img_type).where('position > ?', current_coo.position)
|
||||
.update_all('position = position - 1')
|
||||
|
||||
file_path = Util::FileManage.disk_filename('CooImg', current_coo.id)
|
||||
File.delete(file_path) if File.exist?(file_path)
|
||||
end
|
||||
render_delete_success
|
||||
end
|
||||
|
||||
def drag
|
||||
move = CooImg.find_by(id: params[:move_id])
|
||||
after = CooImg.find_by(id: params[:after_id])
|
||||
|
||||
Admins::DragCooperativeService.call(move, after)
|
||||
render_ok
|
||||
rescue Admins::DragCooperativeService::Error => e
|
||||
render_error(e.message)
|
||||
end
|
||||
|
||||
def replace_image_url
|
||||
current_coo.update!(url_states: Util::FileManage.disk_file_url('CooImg', current_coo.id))
|
||||
render_ok
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_coo
|
||||
@_current_coo ||= CooImg.find(params[:id])
|
||||
end
|
||||
|
||||
def create_params
|
||||
params.require(:coo_img).permit(:img_type, :src_states)
|
||||
end
|
||||
|
||||
def convert_file!
|
||||
max_size = 10 * 1024 * 1024 # 10M
|
||||
file = params.dig('coo_img', 'image')
|
||||
if file.class == ActionDispatch::Http::UploadedFile
|
||||
@file = file
|
||||
render_error('请上传文件') if @file.size.zero?
|
||||
render_error('文件大小超过限制') if @file.size > max_size
|
||||
else
|
||||
file = file.to_s.strip
|
||||
return render_error('请上传正确的图片') if file.blank?
|
||||
@file = Util.convert_base64_image(file, max_size: max_size)
|
||||
end
|
||||
rescue Base64ImageConverter::Error => ex
|
||||
render_error(ex.message)
|
||||
end
|
||||
end
|
||||
35
app/controllers/admins/course_lists_controller.rb
Normal file
35
app/controllers/admins/course_lists_controller.rb
Normal file
@@ -0,0 +1,35 @@
|
||||
class Admins::CourseListsController < Admins::BaseController
|
||||
|
||||
def index
|
||||
course_lists = Admins::CourseListQuery.call(params)
|
||||
@course_lists = paginate course_lists.preload(:courses, :user)
|
||||
@params_page = params[:page] || 1
|
||||
respond_to do |format|
|
||||
format.js
|
||||
format.html
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
CourseList.find(params[:id]).destroy!
|
||||
|
||||
render_delete_success
|
||||
end
|
||||
|
||||
def merge
|
||||
origin_course_list = CourseList.find_by!(id: params[:origin_course_list_id])
|
||||
o_courselist = CourseList.find_by(name: params[:course_list_name])
|
||||
if o_courselist
|
||||
origin_course_list.courses.each do |course|
|
||||
course.update!(name: course.name.sub(origin_course_list.name, params[:course_list_name]), course_list_id: o_courselist.id)
|
||||
end
|
||||
origin_course_list.destroy
|
||||
else
|
||||
origin_course_list.courses.each do |course|
|
||||
course.update!(name: course.name.sub(origin_course_list.name, params[:course_list_name]))
|
||||
end
|
||||
origin_course_list.update!(name: params[:course_list_name])
|
||||
end
|
||||
render_ok
|
||||
end
|
||||
end
|
||||
47
app/controllers/admins/courses_controller.rb
Normal file
47
app/controllers/admins/courses_controller.rb
Normal file
@@ -0,0 +1,47 @@
|
||||
class Admins::CoursesController < Admins::BaseController
|
||||
before_action :find_course, except: [:index]
|
||||
|
||||
def index
|
||||
default_sort('created_at', 'desc')
|
||||
|
||||
courses = Admins::CourseQuery.call(params)
|
||||
@ended_courses = courses.where(is_end: 1).size
|
||||
@processed_courses = courses.where(is_end: 0).size
|
||||
@courses = paginate courses.includes(:school, :students, :attachments, :homework_commons, teacher: :user_extension)
|
||||
|
||||
respond_to do |format|
|
||||
format.js
|
||||
format.html
|
||||
format.xlsx do
|
||||
@courses = courses.includes(:school, :students, :attachments, :homework_commons, :course_acts, teacher: :user_extension)
|
||||
filename = "课堂列表_#{Time.current.strftime('%Y%m%d%H%M%S')}.xlsx"
|
||||
render xlsx: 'index', filename: filename
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
if @course.is_delete == 0
|
||||
@course.delete!
|
||||
Tiding.create!(user_id: current_user.id, trigger_user_id: current_user.id, container_id: @course.id,
|
||||
container_type: 'DeleteCourse', tiding_type: 'System', belong_container: @course, extra: @course.name)
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
unless @course.update_attributes!(setting_params)
|
||||
redirect_to admins_courses_path
|
||||
flash[:danger] = "更新失败"
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_course
|
||||
@course = Course.find_by!(id: params[:id])
|
||||
end
|
||||
|
||||
def setting_params
|
||||
params.permit(:homepage_show, :email_notify)
|
||||
end
|
||||
end
|
||||
39
app/controllers/admins/customers_controller.rb
Normal file
39
app/controllers/admins/customers_controller.rb
Normal file
@@ -0,0 +1,39 @@
|
||||
class Admins::CustomersController < Admins::BaseController
|
||||
# skip_before_action :check_sign
|
||||
helper_method :current_partner
|
||||
|
||||
def index
|
||||
default_sort('created_at', 'desc')
|
||||
|
||||
customers = Admins::CustomerQuery.call(params.merge(partner_id: current_partner.id))
|
||||
@customers = paginate(customers.preload(:school))
|
||||
end
|
||||
|
||||
def create
|
||||
params[:school_ids] = Array.wrap(params[:school_ids])
|
||||
school_ids = School.where(id: params[:school_ids]).pluck(:id)
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
school_ids.each do |school_id|
|
||||
next if current_partner.customers.exists?(school_id)
|
||||
|
||||
customer = Customer.create!(school_id: school_id)
|
||||
current_partner.partner_customers.create!(customer: customer)
|
||||
end
|
||||
end
|
||||
|
||||
render_ok
|
||||
end
|
||||
|
||||
def destroy
|
||||
current_partner.customers.find(params[:id]).destroy!
|
||||
|
||||
render_delete_success
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_partner
|
||||
@_current_partner ||= Partner.find(params[:partner_id])
|
||||
end
|
||||
end
|
||||
37
app/controllers/admins/daily_school_statistics_controller.rb
Normal file
37
app/controllers/admins/daily_school_statistics_controller.rb
Normal file
@@ -0,0 +1,37 @@
|
||||
class Admins::DailySchoolStatisticsController < Admins::BaseController
|
||||
def index
|
||||
params[:sort_by] = params[:sort_by].presence || :teacher_count
|
||||
params[:sort_direction] = params[:sort_direction].presence || :desc
|
||||
|
||||
total_count, statistics = Admins::SchoolDailyStatisticService.call(params)
|
||||
|
||||
@statistics = paginate statistics, total_count: total_count
|
||||
@params_page = params[:page] || 1
|
||||
|
||||
respond_to do |format|
|
||||
format.html { load_statistic_total }
|
||||
format.js
|
||||
end
|
||||
end
|
||||
|
||||
def export
|
||||
params[:per_page] = 10000
|
||||
_count, @schools = Admins::SchoolDailyStatisticService.call(params)
|
||||
|
||||
filename = ['学校统计总表', params[:keyword], Time.zone.now.strftime('%Y%m%d%H%M%S')].join('-') << '.xlsx'
|
||||
render xlsx: 'export', filename: filename
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_statistic_total
|
||||
@teacher_total = User.joins(:user_extension).where(user_extensions: { identity: :teacher }).count
|
||||
@student_total = User.joins(:user_extension).where(user_extensions: { identity: :student }).count
|
||||
@course_total = Course.count
|
||||
@active_course_total = Course.where(is_end: false).count
|
||||
@shixun_homework_total = HomeworkCommon.where(homework_type: 4).count
|
||||
@other_homework_total = HomeworkCommon.where(homework_type: [1, 3]).count
|
||||
@shixun_total = Shixun.count
|
||||
@shixun_evaluate_total = SchoolReport.sum(:shixun_evaluate_count)
|
||||
end
|
||||
end
|
||||
51
app/controllers/admins/dashboards_controller.rb
Normal file
51
app/controllers/admins/dashboards_controller.rb
Normal file
@@ -0,0 +1,51 @@
|
||||
class Admins::DashboardsController < Admins::BaseController
|
||||
def index
|
||||
@active_user_count = User.where(last_login_on: today).count
|
||||
@weekly_active_user_count = User.where(last_login_on: current_week).count
|
||||
@month_active_user_count = User.where(last_login_on: current_month).count
|
||||
|
||||
@new_user_count = User.where(created_on: current_month).count
|
||||
end
|
||||
|
||||
def month_active_user
|
||||
count = UserExtension.where(created_at: current_month).group(:identity).count
|
||||
|
||||
data = [
|
||||
{ value: count['teacher'].to_i, name: '老师' },
|
||||
{ value: count['student'].to_i, name: '学生' },
|
||||
{ value: count['professional'].to_i, name: '专业人士' },
|
||||
{ value: count[nil].to_i, name: '未选职业' },
|
||||
]
|
||||
|
||||
render_ok(data: data)
|
||||
end
|
||||
|
||||
def evaluate
|
||||
names = []
|
||||
data = []
|
||||
|
||||
1.upto(7) do |i|
|
||||
date = i.days.ago
|
||||
names.unshift(date.strftime('%Y-%m-%d'))
|
||||
|
||||
count = Output.where(created_at: date.beginning_of_day..date.end_of_day).count
|
||||
data.unshift(count)
|
||||
end
|
||||
|
||||
render_ok(names: names, data: data)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def today
|
||||
Time.now.beginning_of_day..Time.now.end_of_day
|
||||
end
|
||||
|
||||
def current_week
|
||||
7.days.ago.beginning_of_day..Time.now.end_of_day
|
||||
end
|
||||
|
||||
def current_month
|
||||
30.days.ago.beginning_of_day..Time.now.end_of_day
|
||||
end
|
||||
end
|
||||
106
app/controllers/admins/department_applies_controller.rb
Normal file
106
app/controllers/admins/department_applies_controller.rb
Normal file
@@ -0,0 +1,106 @@
|
||||
class Admins::DepartmentAppliesController < Admins::BaseController
|
||||
|
||||
before_action :get_apply,only:[:agree,:destroy]
|
||||
|
||||
def index
|
||||
params[:status] ||= 0
|
||||
params[:sort_by] = params[:sort_by].presence || 'created_at'
|
||||
params[:sort_direction] = params[:sort_direction].presence || 'desc'
|
||||
applies = Admins::DepartmentApplyQuery.call(params)
|
||||
@depart_applies = paginate applies.preload(:school,user: :user_extension)
|
||||
end
|
||||
|
||||
def agree
|
||||
ActiveRecord::Base.transaction do
|
||||
@depart_apply.update_attribute("status",1)
|
||||
@depart_apply&.applied_messages&.update_all(status:1)
|
||||
@depart_apply&.department&.update_attribute("is_auth",1)
|
||||
@depart_apply&.user&.user_extension&.update_attribute("department_id",@depart_apply.department_id)
|
||||
render_success_js
|
||||
end
|
||||
end
|
||||
|
||||
def merge
|
||||
apply_id = params[:origin_department_id]
|
||||
apply_add =ApplyAddDepartment.find(apply_id)
|
||||
origin_id = apply_add&.department_id
|
||||
new_id = params[:department_id]
|
||||
|
||||
return render_error('请选择其它部门') if origin_id.to_s == new_id.to_s
|
||||
|
||||
origin_department = apply_add&.department
|
||||
to_department = Department.find(new_id)
|
||||
|
||||
return render_error('部门所属单位不相同') if origin_department&.school_id != to_department&.school_id
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
applied_message = AppliedMessage.where(applied_id: origin_id, applied_type: "ApplyAddDepartment")
|
||||
|
||||
applied_message.update_all(:status => 4)
|
||||
apply_add.update_attribute(:status, 2)
|
||||
apply_add.tidings.update_all(:status => 1)
|
||||
|
||||
extra = to_department&.name + "(#{apply_add&.department&.school&.try(:name)})"
|
||||
tiding_params = {
|
||||
user_id: apply_add.user_id,
|
||||
trigger_user_id: 0,
|
||||
container_id: apply_add.id,
|
||||
container_type: 'ApplyAddDepartment',
|
||||
belong_container_id: apply_add&.department&.school_id,
|
||||
belong_container_type: "School",
|
||||
tiding_type: "System",
|
||||
status: 3,
|
||||
extra: extra
|
||||
}
|
||||
Tiding.create(tiding_params)
|
||||
|
||||
origin_department.apply_add_departments.delete_all
|
||||
|
||||
origin_department.user_extensions.update_all(department_id: new_id)
|
||||
|
||||
if to_department.identifier.blank? && origin_department.identifier.present?
|
||||
to_department.update!(identifier: origin_department.identifier)
|
||||
end
|
||||
|
||||
origin_department.destroy!
|
||||
apply_add.destroy!
|
||||
end
|
||||
render_ok
|
||||
end
|
||||
|
||||
def destroy
|
||||
ActiveRecord::Base.transaction do
|
||||
@depart_apply.update_attribute("status",3)
|
||||
@depart_apply&.applied_messages&.update_all(status:3)
|
||||
|
||||
if params[:tip] == 'unapplied' #未审批时候删除
|
||||
user_extens = UserExtension.where(department_id: @depart_apply.department_id)
|
||||
user_extens.update_all(department_id:nil)
|
||||
User.where(id: user_extens.pluck(:user_id)).update_all(profile_completed:false)
|
||||
|
||||
tiding_params = {
|
||||
user_id: @depart_apply.user_id,
|
||||
trigger_user_id: 0,
|
||||
container_id: @depart_apply.id,
|
||||
container_type: 'ApplyAddDepartment',
|
||||
belong_container_id: @depart_apply&.department&.school_id,
|
||||
belong_container_type: "School",
|
||||
tiding_type: "System",
|
||||
status: 2,
|
||||
extra: params[:reason]
|
||||
}
|
||||
Tiding.create(tiding_params)
|
||||
end
|
||||
|
||||
@depart_apply&.department&.destroy
|
||||
@depart_apply.destroy
|
||||
render_success_js
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_apply
|
||||
@depart_apply = ApplyAddDepartment.find_by(id:params[:id])
|
||||
end
|
||||
end
|
||||
20
app/controllers/admins/department_members_controller.rb
Normal file
20
app/controllers/admins/department_members_controller.rb
Normal file
@@ -0,0 +1,20 @@
|
||||
class Admins::DepartmentMembersController < Admins::BaseController
|
||||
|
||||
helper_method :current_department
|
||||
|
||||
def create
|
||||
Admins::AddDepartmentMemberService.call(current_department, params)
|
||||
current_department.reload
|
||||
end
|
||||
|
||||
def destroy
|
||||
@member = current_department.department_members.find_by(user_id: params[:user_id])
|
||||
@member.destroy! if @member.present?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_department
|
||||
@_current_department ||= Department.find(params[:department_id])
|
||||
end
|
||||
end
|
||||
95
app/controllers/admins/departments_controller.rb
Normal file
95
app/controllers/admins/departments_controller.rb
Normal file
@@ -0,0 +1,95 @@
|
||||
class Admins::DepartmentsController < Admins::BaseController
|
||||
|
||||
helper_method :current_department
|
||||
|
||||
def index
|
||||
params[:sort_by] ||= 'created_at'
|
||||
params[:sort_direction] ||= 'desc'
|
||||
|
||||
departments = Admins::DepartmentQuery.call(params)
|
||||
|
||||
@departments = paginate departments.preload(:school, :member_users)
|
||||
|
||||
department_ids = @departments.map(&:id)
|
||||
@users_count = UserExtension.where(department_id: department_ids).group(:department_id).count
|
||||
@professional_auth_count = UserExtension.where(department_id: department_ids)
|
||||
.joins(:user).where(users: { professional_certification: true })
|
||||
.group(:department_id).count
|
||||
end
|
||||
|
||||
def create
|
||||
department_name = params[:department_name].to_s.strip
|
||||
school = School.find(params[:school_id])
|
||||
|
||||
return render_error('部门名称重复') if school.departments.exists?(name: department_name)
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
department = school.departments.create!(name: department_name, is_auth: 1)
|
||||
ApplyAddDepartment.create!(school_id: school.id, status: 1, name: department.name,
|
||||
department_id: department.id, user_id: current_user.id)
|
||||
end
|
||||
|
||||
render_ok
|
||||
end
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def update
|
||||
identifier = update_params.delete(:identifier).presence
|
||||
if identifier && Department.where.not(id: current_department.id).exists?(identifier: identifier)
|
||||
return render_error('统计链接重复', type: :notify)
|
||||
end
|
||||
|
||||
current_department.update!(update_params.merge(identifier: identifier))
|
||||
end
|
||||
|
||||
def destroy
|
||||
ActiveRecord::Base.transaction do
|
||||
current_department.apply_add_departments.update_all(status: 2)
|
||||
|
||||
user_ids = current_department.user_extensions.pluck(:user_id)
|
||||
if user_ids.present?
|
||||
DeleteDepartmentNotifyJob.perform_later(current_department.id, 0, user_ids)
|
||||
current_department.soft_delete!
|
||||
else
|
||||
current_department.destroy!
|
||||
end
|
||||
end
|
||||
|
||||
render_delete_success
|
||||
end
|
||||
|
||||
def merge
|
||||
return render_error('请选择其它部门') if params[:origin_department_id].to_s == params[:department_id].to_s
|
||||
|
||||
origin_department = Department.find(params[:origin_department_id])
|
||||
to_department = Department.find(params[:department_id])
|
||||
|
||||
return render_error('部门所属单位不相同') if origin_department.school_id != to_department.school_id
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
origin_department.apply_add_departments.delete_all
|
||||
|
||||
origin_department.user_extensions.update_all(department_id: to_department.id)
|
||||
|
||||
if to_department.identifier.blank? && origin_department.identifier.present?
|
||||
to_department.update!(identifier: origin_department.identifier)
|
||||
end
|
||||
|
||||
origin_department.destroy!
|
||||
end
|
||||
|
||||
render_ok
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_department
|
||||
@_current_department ||= Department.find(params[:id])
|
||||
end
|
||||
|
||||
def update_params
|
||||
params.require(:department).permit(:name, :identifier, :host_count)
|
||||
end
|
||||
end
|
||||
77
app/controllers/admins/disciplines_controller.rb
Normal file
77
app/controllers/admins/disciplines_controller.rb
Normal file
@@ -0,0 +1,77 @@
|
||||
class Admins::DisciplinesController < Admins::BaseController
|
||||
|
||||
def index
|
||||
@disciplines = Discipline.all
|
||||
end
|
||||
|
||||
def create
|
||||
name = params[:name].to_s.strip
|
||||
return render_error('名称重复') if Discipline.where(name: name).exists?
|
||||
Discipline.create!(name: name, position: Discipline.all.pluck(:position).max + 1)
|
||||
render_ok
|
||||
end
|
||||
|
||||
def edit
|
||||
@discipline = current_discipline
|
||||
end
|
||||
|
||||
def update
|
||||
begin
|
||||
if params[:discipline] && params[:discipline][:name]
|
||||
name = params[:discipline][:name].to_s.strip
|
||||
current_discipline.update_attributes!(name: name)
|
||||
else
|
||||
ActiveRecord::Base.transaction do
|
||||
current_discipline.update_attributes!(setting_params)
|
||||
current_discipline.sub_disciplines.each do |sub|
|
||||
sub.tag_disciplines.each do |tag|
|
||||
tag.update_attributes!(setting_params)
|
||||
end
|
||||
sub.update_attributes!(setting_params)
|
||||
end
|
||||
end
|
||||
end
|
||||
rescue Exception => e
|
||||
@message = e.message
|
||||
end
|
||||
@disciplines = Discipline.all
|
||||
end
|
||||
|
||||
def destroy
|
||||
@discipline_id = params[:id]
|
||||
ActiveRecord::Base.transaction do
|
||||
Discipline.where("position > #{current_discipline.position}").update_all("position=position-1")
|
||||
current_discipline.destroy!
|
||||
end
|
||||
end
|
||||
|
||||
def adjust_position
|
||||
max_position = Discipline.all.pluck(:position).max
|
||||
opr = params[:opr] || "down"
|
||||
if (params[:opr] == "up" && current_discipline.position == 1) || (params[:opr] == "down" && current_discipline.position == max_position)
|
||||
@message = "超出范围"
|
||||
else
|
||||
ActiveRecord::Base.transaction do
|
||||
if opr == "up"
|
||||
Discipline.find_by("position = #{current_discipline.position - 1}")&.update!(position: current_discipline.position)
|
||||
current_discipline.update!(position: current_discipline.position - 1)
|
||||
else
|
||||
Discipline.find_by("position = #{current_discipline.position + 1}")&.update!(position: current_discipline.position)
|
||||
current_discipline.update!(position: current_discipline.position + 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
@disciplines = Discipline.all
|
||||
rescue Exception => e
|
||||
@message = e.message
|
||||
end
|
||||
|
||||
private
|
||||
def current_discipline
|
||||
@_current_discipline = Discipline.find params[:id]
|
||||
end
|
||||
|
||||
def setting_params
|
||||
params.permit(:shixun, :subject, :question)
|
||||
end
|
||||
end
|
||||
41
app/controllers/admins/ec_templates_controller.rb
Normal file
41
app/controllers/admins/ec_templates_controller.rb
Normal file
@@ -0,0 +1,41 @@
|
||||
class Admins::EcTemplatesController < Admins::BaseController
|
||||
|
||||
def index
|
||||
@params_page = params[:page] || 1
|
||||
templates = EcTemplate.where(nil).includes(:attachments).order("updated_at desc")
|
||||
@templates = paginate templates
|
||||
end
|
||||
|
||||
def create_template
|
||||
ActiveRecord::Base.transaction do
|
||||
if params[:template_id] == "-1"
|
||||
ec_template = EcTemplate.new(name: params[:name])
|
||||
ec_template.save
|
||||
else
|
||||
ec_template = EcTemplate.find_by(id: params[:template_id])
|
||||
end
|
||||
|
||||
if params[:attachment_id] != "-1"
|
||||
attachment_id = params[:attachment_id]
|
||||
attachment_tem = Attachment.find_by(id: attachment_id)
|
||||
|
||||
unless attachment_tem.container_id.present? && attachment_tem.container_id == ec_template&.id
|
||||
attachment_tem.update_attributes(container_id: ec_template&.id, container_type: "EcTemplate")
|
||||
end
|
||||
end
|
||||
|
||||
@params_page = params[:page] || 1
|
||||
templates = EcTemplate.where(nil).includes(:attachments).order("updated_at desc")
|
||||
@templates = paginate templates
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
ActiveRecord::Base.transaction do
|
||||
template = EcTemplate.find_by(id: params[:id])
|
||||
template.destroy
|
||||
render_success_js
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,30 @@
|
||||
class Admins::ExaminationAuthenticationsController < Admins::BaseController
|
||||
def index
|
||||
params[:status] ||= 'pending'
|
||||
params[:sort_direction] = params[:status] == 'pending' ? 'asc' : 'desc'
|
||||
|
||||
applies = Admins::ApplyItemBankQuery.call(params.merge(type: "ExaminationBank"))
|
||||
|
||||
@applies = paginate applies.preload(user: { user_extension: [:school, :department] })
|
||||
end
|
||||
|
||||
def agree
|
||||
ActiveRecord::Base.transaction do
|
||||
exam = ExaminationBank.find current_apply.container_id
|
||||
current_apply.update!(status: 1)
|
||||
exam.update!(public: 1)
|
||||
end
|
||||
render_success_js
|
||||
end
|
||||
|
||||
def refuse
|
||||
current_apply.update!(status: 2)
|
||||
render_success_js
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_apply
|
||||
@_current_apply ||= ApplyAction.find(params[:id])
|
||||
end
|
||||
end
|
||||
51
app/controllers/admins/files_controller.rb
Normal file
51
app/controllers/admins/files_controller.rb
Normal file
@@ -0,0 +1,51 @@
|
||||
class Admins::FilesController < Admins::BaseController
|
||||
before_action :convert_file!, only: [:create]
|
||||
|
||||
def create
|
||||
File.delete(file_path) if File.exist?(file_path) # 删除之前的文件
|
||||
|
||||
Util.write_file(@file, file_path)
|
||||
|
||||
render_ok(
|
||||
source_id: params[:source_id],
|
||||
source_type: params[:source_type].to_s,
|
||||
suffix: params[:suffix].presence,
|
||||
url: file_url
|
||||
)
|
||||
rescue StandardError => ex
|
||||
logger_error(ex)
|
||||
render_error('上传失败')
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def convert_file!
|
||||
max_size = 10 * 1024 * 1024 # 10M
|
||||
if params[:file].class == ActionDispatch::Http::UploadedFile
|
||||
@file = params[:file]
|
||||
render_error('请上传文件') if @file.size.zero?
|
||||
render_error('文件大小超过限制') if @file.size > max_size
|
||||
else
|
||||
file = params[:file].to_s.strip
|
||||
return render_error('请上传正确的图片') if file.blank?
|
||||
@file = Util.convert_base64_image(file, max_size: max_size)
|
||||
end
|
||||
rescue Base64ImageConverter::Error => ex
|
||||
render_error(ex.message)
|
||||
end
|
||||
|
||||
def file_path
|
||||
@_file_path ||= begin
|
||||
case params[:source_type].to_s
|
||||
when 'Shixun' then
|
||||
Util::FileManage.disk_filename('Shixun', params[:source_id], params[:suffix].presence)
|
||||
else
|
||||
Util::FileManage.disk_filename(params[:source_type].to_s, params[:source_id].to_s, params[:suffix].presence)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def file_url
|
||||
Util::FileManage.disk_file_url(params[:source_type].to_s, params[:source_id].to_s, params[:suffix].presence)
|
||||
end
|
||||
end
|
||||
33
app/controllers/admins/graduation_standards_controller.rb
Normal file
33
app/controllers/admins/graduation_standards_controller.rb
Normal file
@@ -0,0 +1,33 @@
|
||||
class Admins::GraduationStandardsController < Admins::BaseController
|
||||
|
||||
def index
|
||||
standards = EcGraduationStandard.all.order("updated_at desc")
|
||||
@params_page = params[:page] || 1
|
||||
@standards = paginate standards
|
||||
end
|
||||
|
||||
def create_standard
|
||||
ActiveRecord::Base.transaction do
|
||||
if params[:graduation_id] == "-1"
|
||||
content = params[:content]
|
||||
EcGraduationStandard.create(:content => content)
|
||||
else
|
||||
graduation = EcGraduationStandard.find_by(id: params[:graduation_id])
|
||||
graduation.update_attribute(:content, params[:content])
|
||||
end
|
||||
|
||||
standards = EcGraduationStandard.all.order("updated_at desc")
|
||||
@params_page = params[:page] || 1
|
||||
@standards = paginate standards
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
ActiveRecord::Base.transaction do
|
||||
@graduation = EcGraduationStandard.find_by(id: params[:id])
|
||||
@graduation.destroy
|
||||
render_success_js
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
18
app/controllers/admins/help_centers_controller.rb
Normal file
18
app/controllers/admins/help_centers_controller.rb
Normal file
@@ -0,0 +1,18 @@
|
||||
class Admins::HelpCentersController < Admins::BaseController
|
||||
def edit
|
||||
current_doc
|
||||
end
|
||||
|
||||
def update
|
||||
current_doc.update!(help_center: params[:help_center])
|
||||
|
||||
flash[:success] = '保存成功'
|
||||
redirect_to edit_admins_help_center_path
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_doc
|
||||
@doc ||= Help.first || Help.create
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,45 @@
|
||||
class Admins::IdentityAuthenticationsController < Admins::BaseController
|
||||
def index
|
||||
params[:status] ||= 'pending'
|
||||
params[:sort_direction] = params[:status] == 'pending' ? 'asc' : 'desc'
|
||||
|
||||
applies = Admins::ApplyUserAuthenticationQuery.call(params.merge(type: 1))
|
||||
|
||||
@applies = paginate applies.preload(user: { user_extension: [:school, :department] })
|
||||
end
|
||||
|
||||
def agree
|
||||
Admins::IdentityAuths::AgreeApplyService.call(current_apply)
|
||||
render_success_js
|
||||
end
|
||||
|
||||
def refuse
|
||||
Admins::IdentityAuths::RefuseApplyService.call(current_apply, params)
|
||||
|
||||
render_success_js
|
||||
end
|
||||
|
||||
def batch_agree
|
||||
ApplyUserAuthentication.real_name_auth.where(id: params[:ids]).each do |apply|
|
||||
begin
|
||||
Admins::IdentityAuths::AgreeApplyService.call(apply)
|
||||
rescue => e
|
||||
Util.logger_error(e)
|
||||
end
|
||||
end
|
||||
|
||||
render_ok
|
||||
end
|
||||
|
||||
def revoke
|
||||
Admins::IdentityAuths::RevokeApplyService.call(current_apply)
|
||||
|
||||
render_success_js
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_apply
|
||||
@_current_apply ||= ApplyUserAuthentication.real_name_auth.find(params[:id])
|
||||
end
|
||||
end
|
||||
10
app/controllers/admins/import_course_members_controller.rb
Normal file
10
app/controllers/admins/import_course_members_controller.rb
Normal file
@@ -0,0 +1,10 @@
|
||||
class Admins::ImportCourseMembersController < Admins::BaseController
|
||||
def create
|
||||
return render_error('请上传正确的文件') if params[:file].blank? || !params[:file].is_a?(ActionDispatch::Http::UploadedFile)
|
||||
|
||||
result = Admins::ImportCourseMemberService.call(params[:file].to_io)
|
||||
render_ok(result)
|
||||
rescue Admins::ImportCourseMemberService::Error => ex
|
||||
render_error(ex)
|
||||
end
|
||||
end
|
||||
10
app/controllers/admins/import_disciplines_controller.rb
Normal file
10
app/controllers/admins/import_disciplines_controller.rb
Normal file
@@ -0,0 +1,10 @@
|
||||
class Admins::ImportDisciplinesController < Admins::BaseController
|
||||
def create
|
||||
return render_error('请上传正确的文件') if params[:file].blank? || !params[:file].is_a?(ActionDispatch::Http::UploadedFile)
|
||||
|
||||
result = Admins::ImportDisciplineService.call(params[:file].to_io)
|
||||
render_ok(result)
|
||||
rescue Admins::ImportDisciplineService::Error => ex
|
||||
render_error(ex)
|
||||
end
|
||||
end
|
||||
10
app/controllers/admins/import_users_controller.rb
Normal file
10
app/controllers/admins/import_users_controller.rb
Normal file
@@ -0,0 +1,10 @@
|
||||
class Admins::ImportUsersController < Admins::BaseController
|
||||
def create
|
||||
return render_error('请上传正确的文件') if params[:file].blank? || !params[:file].is_a?(ActionDispatch::Http::UploadedFile)
|
||||
|
||||
result = Admins::ImportUserService.call(params[:file].to_io)
|
||||
render_ok(result)
|
||||
rescue Admins::ImportUserService::Error => ex
|
||||
render_error(ex)
|
||||
end
|
||||
end
|
||||
34
app/controllers/admins/item_authentications_controller.rb
Normal file
34
app/controllers/admins/item_authentications_controller.rb
Normal file
@@ -0,0 +1,34 @@
|
||||
class Admins::ItemAuthenticationsController < Admins::BaseController
|
||||
def index
|
||||
params[:status] ||= 'pending'
|
||||
params[:sort_direction] = params[:status] == 'pending' ? 'asc' : 'desc'
|
||||
|
||||
applies = Admins::ApplyItemBankQuery.call(params.merge(type: "ItemBank"))
|
||||
|
||||
@applies = paginate applies.preload(user: { user_extension: [:school, :department] })
|
||||
end
|
||||
|
||||
def show
|
||||
@item = ItemBank.find current_apply.container_id
|
||||
end
|
||||
|
||||
def agree
|
||||
ActiveRecord::Base.transaction do
|
||||
item = ItemBank.find current_apply.container_id
|
||||
current_apply.update!(status: 1)
|
||||
item.update!(public: 1)
|
||||
end
|
||||
render_success_js
|
||||
end
|
||||
|
||||
def refuse
|
||||
current_apply.update!(status: 2)
|
||||
render_success_js
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_apply
|
||||
@_current_apply ||= ApplyAction.find(params[:id])
|
||||
end
|
||||
end
|
||||
85
app/controllers/admins/laboratories_controller.rb
Normal file
85
app/controllers/admins/laboratories_controller.rb
Normal file
@@ -0,0 +1,85 @@
|
||||
class Admins::LaboratoriesController < Admins::BaseController
|
||||
def index
|
||||
default_sort('id', 'desc')
|
||||
|
||||
laboratories = Admins::LaboratoryQuery.call(params)
|
||||
@laboratories = paginate laboratories.preload(:school, :laboratory_users)
|
||||
end
|
||||
|
||||
def create
|
||||
Admins::CreateLaboratoryService.call(create_params)
|
||||
render_ok
|
||||
rescue Admins::CreateLaboratoryService::Error => ex
|
||||
render_error(ex.message)
|
||||
end
|
||||
|
||||
def destroy
|
||||
current_laboratory.destroy!
|
||||
|
||||
render_delete_success
|
||||
end
|
||||
|
||||
def shixuns_for_select
|
||||
except_shixun_ids = current_laboratory.laboratory_shixuns.pluck(:shixun_id)
|
||||
|
||||
shixuns = Shixun.where.not(id: except_shixun_ids)
|
||||
|
||||
keyword = params[:keyword].to_s.strip
|
||||
if keyword.present?
|
||||
like_sql = 'shixuns.name LIKE :keyword OR CONCAT(users.lastname, users.firstname) LIKE :keyword '\
|
||||
'OR mirror_repositories.name LIKE :keyword'
|
||||
shixuns = shixuns.joins(:user, :mirror_repositories).where(like_sql, keyword: "%#{keyword}%")
|
||||
end
|
||||
|
||||
@count = shixuns.count
|
||||
@shixuns = paginate(shixuns.includes(:user))
|
||||
end
|
||||
|
||||
def subjects_for_select
|
||||
except_subject_ids = current_laboratory.laboratory_subjects.pluck(:subject_id)
|
||||
|
||||
subjects = Subject.where.not(id: except_subject_ids)
|
||||
|
||||
keyword = params[:keyword].to_s.strip
|
||||
if keyword.present?
|
||||
like_sql = 'subjects.name LIKE :keyword OR CONCAT(users.lastname, users.firstname) LIKE :keyword'
|
||||
subjects = subjects.joins(:user).where(like_sql, keyword: "%#{keyword}%")
|
||||
end
|
||||
|
||||
@count = subjects.count
|
||||
@subjects = paginate(subjects.includes(:user))
|
||||
end
|
||||
|
||||
def synchronize_user
|
||||
school = current_laboratory.school
|
||||
users = User.joins(:user_extension).where(user_extensions: {school_id: school.id})
|
||||
users.update_all(laboratory_id: current_laboratory.id)
|
||||
end
|
||||
|
||||
def update_sync_course
|
||||
current_laboratory.update!(sync_course: !current_laboratory.sync_course)
|
||||
@laboratory = current_laboratory
|
||||
end
|
||||
|
||||
def update
|
||||
@laboratory = current_laboratory
|
||||
unless @laboratory.update_attributes!(setting_params)
|
||||
redirect_to admins_laboratories_path
|
||||
flash[:danger] = "更新失败"
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_laboratory
|
||||
@_current_laboratory ||= Laboratory.find(params[:id])
|
||||
end
|
||||
|
||||
def create_params
|
||||
params.permit(:school_id)
|
||||
end
|
||||
|
||||
def setting_params
|
||||
params.permit(:sync_course, :sync_subject, :sync_shixun)
|
||||
end
|
||||
end
|
||||
23
app/controllers/admins/laboratory_settings_controller.rb
Normal file
23
app/controllers/admins/laboratory_settings_controller.rb
Normal file
@@ -0,0 +1,23 @@
|
||||
class Admins::LaboratorySettingsController < Admins::BaseController
|
||||
def show
|
||||
@laboratory = current_laboratory
|
||||
end
|
||||
|
||||
def update
|
||||
Admins::SaveLaboratorySettingService.call(current_laboratory, form_params)
|
||||
render_ok
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_laboratory
|
||||
@_current_laboratory ||= Laboratory.find(params[:laboratory_id])
|
||||
end
|
||||
|
||||
def form_params
|
||||
params.permit(:identifier, :name,
|
||||
:nav_logo, :login_logo, :tab_logo, :oj_banner,
|
||||
:subject_banner, :course_banner, :competition_banner, :moop_cases_banner,
|
||||
:footer, navbar: %i[name link hidden])
|
||||
end
|
||||
end
|
||||
48
app/controllers/admins/laboratory_shixuns_controller.rb
Normal file
48
app/controllers/admins/laboratory_shixuns_controller.rb
Normal file
@@ -0,0 +1,48 @@
|
||||
class Admins::LaboratoryShixunsController < Admins::BaseController
|
||||
helper_method :current_laboratory, :current_laboratory_shixun
|
||||
|
||||
def index
|
||||
laboratory_shixuns = Admins::LaboratoryShixunQuery.call(current_laboratory, params)
|
||||
@laboratory_shixuns = paginate laboratory_shixuns.includes(shixun: %i[tag_repertoires user])
|
||||
end
|
||||
|
||||
def create
|
||||
shixun_ids = Array.wrap(params[:shixun_ids])
|
||||
shixun_ids = Shixun.where(id: shixun_ids).pluck(:id)
|
||||
exist_shixun_id = current_laboratory.laboratory_shixuns.where(shixun_id: shixun_ids).pluck(:shixun_id)
|
||||
|
||||
LaboratoryShixun.bulk_insert(*%i[shixun_id laboratory_id created_at updated_at]) do |worker|
|
||||
(shixun_ids - exist_shixun_id).each do |shixun_id|
|
||||
worker.add(shixun_id: shixun_id, laboratory_id: current_laboratory.id)
|
||||
end
|
||||
end
|
||||
render_ok
|
||||
end
|
||||
|
||||
def destroy
|
||||
return render_js_error('不能删除自建实训', type: :notify) if current_laboratory_shixun.ownership?
|
||||
current_laboratory_shixun.destroy!
|
||||
|
||||
render_delete_success
|
||||
end
|
||||
|
||||
def homepage
|
||||
current_laboratory_shixun.update!(homepage: true)
|
||||
render_ok
|
||||
end
|
||||
|
||||
def cancel_homepage
|
||||
current_laboratory_shixun.update!(homepage: false)
|
||||
render_ok
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_laboratory
|
||||
@_current_laboratory ||= Laboratory.find(params[:laboratory_id])
|
||||
end
|
||||
|
||||
def current_laboratory_shixun
|
||||
@_current_laboratory_shixun ||= current_laboratory.laboratory_shixuns.find(params[:id])
|
||||
end
|
||||
end
|
||||
51
app/controllers/admins/laboratory_subjects_controller.rb
Normal file
51
app/controllers/admins/laboratory_subjects_controller.rb
Normal file
@@ -0,0 +1,51 @@
|
||||
class Admins::LaboratorySubjectsController < Admins::BaseController
|
||||
helper_method :current_laboratory, :current_laboratory_subject
|
||||
|
||||
def index
|
||||
laboratory_subjects = Admins::LaboratorySubjectQuery.call(current_laboratory, params)
|
||||
|
||||
includes_tables = { subject: [:repertoire, :subject_level_system, user: {user_extension: :school}] }
|
||||
@laboratory_subjects = paginate(laboratory_subjects.includes(includes_tables))
|
||||
end
|
||||
|
||||
def create
|
||||
subject = Subject.find(params[:subject_id])
|
||||
Subjects::CopySubjectService.call(subject, current_user, current_laboratory)
|
||||
render_ok
|
||||
end
|
||||
|
||||
def destroy
|
||||
return render_js_error('不能删除自建课程', type: :notify) if current_laboratory_subject.ownership?
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
current_subject = current_laboratory_subject.subject
|
||||
# 实训软删除,并解除与子站的关联
|
||||
current_laboratory.laboratory_shixuns.where(shixun_id: current_subject.shixuns).destroy_all
|
||||
current_subject.shixuns.update_all(status: -1)
|
||||
current_subject.destroy!
|
||||
|
||||
render_delete_success
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def homepage
|
||||
current_laboratory_subject.update!(homepage: true)
|
||||
render_ok
|
||||
end
|
||||
|
||||
def cancel_homepage
|
||||
current_laboratory_subject.update!(homepage: false)
|
||||
render_ok
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_laboratory
|
||||
@_current_laboratory ||= Laboratory.find(params[:laboratory_id])
|
||||
end
|
||||
|
||||
def current_laboratory_subject
|
||||
@_current_laboratory_subject ||= current_laboratory.laboratory_subjects.find(params[:id])
|
||||
end
|
||||
end
|
||||
19
app/controllers/admins/laboratory_users_controller.rb
Normal file
19
app/controllers/admins/laboratory_users_controller.rb
Normal file
@@ -0,0 +1,19 @@
|
||||
class Admins::LaboratoryUsersController < Admins::BaseController
|
||||
helper_method :current_laboratory
|
||||
|
||||
def create
|
||||
Admins::AddLaboratoryUserService.call(current_laboratory, params.permit(user_ids: []))
|
||||
current_laboratory.reload
|
||||
end
|
||||
|
||||
def destroy
|
||||
@laboratory_user = current_laboratory.laboratory_users.find_by(user_id: params[:user_id])
|
||||
@laboratory_user.destroy! if @laboratory_user.present?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_laboratory
|
||||
@_current_laboratory ||= Laboratory.find(params[:laboratory_id])
|
||||
end
|
||||
end
|
||||
25
app/controllers/admins/library_applies_controller.rb
Normal file
25
app/controllers/admins/library_applies_controller.rb
Normal file
@@ -0,0 +1,25 @@
|
||||
class Admins::LibraryAppliesController < Admins::BaseController
|
||||
def index
|
||||
params[:status] ||= 'pending'
|
||||
applies = Admins::LibraryApplyQuery.call(params)
|
||||
|
||||
@library_applies = paginate applies.preload(library: :user)
|
||||
end
|
||||
|
||||
def agree
|
||||
Libraries::AgreeApplyService.new(current_library_apply, current_user).call
|
||||
render_success_js
|
||||
end
|
||||
|
||||
def refuse
|
||||
Libraries::RefuseApplyService.new(current_library_apply, current_user, reason: params[:reason]).call
|
||||
|
||||
render_success_js
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_library_apply
|
||||
@_current_library_apply ||= LibraryApply.find(params[:id])
|
||||
end
|
||||
end
|
||||
8
app/controllers/admins/major_informations_controller.rb
Normal file
8
app/controllers/admins/major_informations_controller.rb
Normal file
@@ -0,0 +1,8 @@
|
||||
class Admins::MajorInformationsController < Admins::BaseController
|
||||
|
||||
def index
|
||||
disciplines = EcDiscipline.includes(ec_discipline_firsts: {ec_majors: :schools}).order("ec_disciplines.code asc")
|
||||
@disciplines = paginate disciplines
|
||||
end
|
||||
|
||||
end
|
||||
96
app/controllers/admins/mirror_repositories_controller.rb
Normal file
96
app/controllers/admins/mirror_repositories_controller.rb
Normal file
@@ -0,0 +1,96 @@
|
||||
class Admins::MirrorRepositoriesController < Admins::BaseController
|
||||
before_action :check_shixun_mirrors!, only: [:index]
|
||||
|
||||
def index
|
||||
mirrors = MirrorRepository.all
|
||||
mirrors = mirrors.reorder(status: :desc, main_type: :desc, type_name: :asc)
|
||||
|
||||
@mirrors = paginate mirrors.includes(:mirror_scripts)
|
||||
@error_mirror_names = MirrorRepository.where(status: 5).pluck(:name)
|
||||
end
|
||||
|
||||
def new
|
||||
@mirror = MirrorRepository.new
|
||||
end
|
||||
|
||||
def create
|
||||
@mirror = MirrorRepository.new
|
||||
Admins::SaveMirrorRepositoryService.call(@mirror, current_user, form_params)
|
||||
|
||||
flash[:success] = '保存成功'
|
||||
redirect_to edit_admins_mirror_repository_path(@mirror)
|
||||
rescue ActiveRecord::RecordInvalid
|
||||
flash.now[:danger] = '保存失败'
|
||||
render 'new'
|
||||
rescue Admins::SaveMirrorRepositoryService::Error => ex
|
||||
flash.now[:danger] = ex.message
|
||||
render 'new'
|
||||
end
|
||||
|
||||
def edit
|
||||
@mirror = current_mirror
|
||||
end
|
||||
|
||||
def update
|
||||
@mirror = current_mirror
|
||||
|
||||
Admins::SaveMirrorRepositoryService.call(current_mirror, current_user, form_params)
|
||||
|
||||
flash[:success] = '保存成功'
|
||||
redirect_to edit_admins_mirror_repository_path(current_mirror)
|
||||
rescue ActiveRecord::RecordInvalid
|
||||
flash.now[:danger] = '保存失败'
|
||||
render 'edit'
|
||||
rescue Admins::SaveMirrorRepositoryService::Error => ex
|
||||
flash.now[:danger] = ex.message
|
||||
render 'edit'
|
||||
end
|
||||
|
||||
def destroy
|
||||
return render_js_error('该状态下不允许删除') unless current_mirror.deletable?
|
||||
|
||||
current_mirror.destroy!
|
||||
|
||||
render_delete_success
|
||||
end
|
||||
|
||||
def for_select
|
||||
mirrors = MirrorRepository.all
|
||||
|
||||
keyword = params[:keyword].to_s.strip
|
||||
mirrors = mirrors.where('name LIKE ?', "%#{keyword}%") if keyword.present?
|
||||
|
||||
@mirrors = paginate mirrors
|
||||
|
||||
render_ok(count: @mirrors.total_count, mirrors: @mirrors.as_json(only: %i[id name]))
|
||||
end
|
||||
|
||||
def merge
|
||||
origin_mirror = MirrorRepository.find(params[:mirror_id])
|
||||
mirror = MirrorRepository.find(params[:new_mirror_id])
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
origin_mirror.update!(name: mirror.name, mirrorID: mirror.mirrorID)
|
||||
mirror.destroy!
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_mirror
|
||||
@_current_mirror ||= MirrorRepository.find(params[:id])
|
||||
end
|
||||
|
||||
def form_params
|
||||
columns = %i[type_name main_type time_limit resource_limit cpu_limit memory_limit description status]
|
||||
params.require(:mirror_repository).permit(*columns)
|
||||
end
|
||||
|
||||
def check_shixun_mirrors!
|
||||
return unless request.format.html?
|
||||
|
||||
Admins::CheckShixunMirrorsService.call
|
||||
rescue Admins::CheckShixunMirrorsService::Error => e
|
||||
internal_server_error(e.message)
|
||||
end
|
||||
end
|
||||
59
app/controllers/admins/mirror_scripts_controller.rb
Normal file
59
app/controllers/admins/mirror_scripts_controller.rb
Normal file
@@ -0,0 +1,59 @@
|
||||
class Admins::MirrorScriptsController < Admins::BaseController
|
||||
helper_method :current_mirror
|
||||
|
||||
def index
|
||||
scripts = current_mirror.mirror_scripts.order(updated_at: :desc)
|
||||
@scripts = paginate scripts
|
||||
end
|
||||
|
||||
def new
|
||||
@script = current_mirror.mirror_scripts.new
|
||||
end
|
||||
|
||||
def create
|
||||
@script = current_mirror.mirror_scripts.new(form_params)
|
||||
|
||||
if @script.save
|
||||
flash[:success] = '保存成功'
|
||||
redirect_to edit_admins_mirror_repository_mirror_script_path(current_mirror, @script)
|
||||
else
|
||||
flash[:danger] = '保存失败'
|
||||
render 'new'
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
@script = current_script
|
||||
end
|
||||
|
||||
def update
|
||||
@script = current_script
|
||||
|
||||
if @script.update(form_params)
|
||||
flash[:success] = '保存成功'
|
||||
redirect_to edit_admins_mirror_repository_mirror_script_path(current_mirror, @script)
|
||||
else
|
||||
flash[:danger] = '保存失败'
|
||||
render 'edit'
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
current_script.destroy!
|
||||
render_delete_success
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_script
|
||||
@_current_script ||= current_mirror.mirror_scripts.find(params[:id])
|
||||
end
|
||||
|
||||
def current_mirror
|
||||
@_current_mirror ||= MirrorRepository.find(params[:mirror_repository_id])
|
||||
end
|
||||
|
||||
def form_params
|
||||
params.require(:mirror_script).permit(:script_type, :description, :script)
|
||||
end
|
||||
end
|
||||
29
app/controllers/admins/partners_controller.rb
Normal file
29
app/controllers/admins/partners_controller.rb
Normal file
@@ -0,0 +1,29 @@
|
||||
class Admins::PartnersController < Admins::BaseController
|
||||
def index
|
||||
default_sort('created_at', 'desc')
|
||||
|
||||
partners = Admins::PartnerQuery.call(params)
|
||||
@partners = paginate(partners.preload(:school))
|
||||
end
|
||||
|
||||
def create
|
||||
params[:school_ids] = Array.wrap(params[:school_ids])
|
||||
|
||||
school_ids = School.where(id: params[:school_ids]).pluck(:id)
|
||||
exist_school_ids = Partner.where(school_id: school_ids).pluck(:school_id)
|
||||
|
||||
Partner.bulk_insert(*%i[school_id created_at updated_at]) do |worker|
|
||||
(school_ids - exist_school_ids).each do |school_id|
|
||||
worker.add(school_id: school_id)
|
||||
end
|
||||
end
|
||||
|
||||
render_ok
|
||||
end
|
||||
|
||||
def destroy
|
||||
Partner.find(params[:id]).destroy!
|
||||
|
||||
render_delete_success
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,44 @@
|
||||
class Admins::ProfessionalAuthenticationsController < Admins::BaseController
|
||||
def index
|
||||
params[:status] ||= 'pending'
|
||||
params[:sort_direction] = params[:status] == 'pending' ? 'asc' : 'desc'
|
||||
|
||||
applies = Admins::ApplyUserAuthenticationQuery.call(params.merge(type: 2))
|
||||
|
||||
@applies = paginate applies.preload(user: { user_extension: [:school, :department] })
|
||||
end
|
||||
|
||||
def agree
|
||||
Admins::ProfessionalAuths::AgreeApplyService.call(current_apply)
|
||||
render_success_js
|
||||
end
|
||||
|
||||
def refuse
|
||||
Admins::ProfessionalAuths::RefuseApplyService.call(current_apply, params)
|
||||
|
||||
render_success_js
|
||||
end
|
||||
|
||||
def batch_agree
|
||||
ApplyUserAuthentication.professional_auth.where(id: params[:ids]).each do |apply|
|
||||
begin
|
||||
Admins::ProfessionalAuths::AgreeApplyService.call(apply)
|
||||
rescue => e
|
||||
Util.logger_error(e)
|
||||
end
|
||||
end
|
||||
|
||||
render_ok
|
||||
end
|
||||
|
||||
def revoke
|
||||
Admins::ProfessionalAuths::RevokeApplyService.call(current_apply)
|
||||
render_success_js
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_apply
|
||||
@_current_apply ||= ApplyUserAuthentication.professional_auth.find(params[:id])
|
||||
end
|
||||
end
|
||||
37
app/controllers/admins/project_package_applies_controller.rb
Normal file
37
app/controllers/admins/project_package_applies_controller.rb
Normal file
@@ -0,0 +1,37 @@
|
||||
class Admins::ProjectPackageAppliesController < Admins::BaseController
|
||||
before_action :current_apply,only: [:agree,:refuse]
|
||||
|
||||
def index
|
||||
params[:status] ||= 'pending'
|
||||
status = params[:status]
|
||||
if status == 'all'
|
||||
status = %w(agreed refused)
|
||||
end
|
||||
package_applies = ProjectPackageApply.where(status: status)
|
||||
keyword = params[:keyword].to_s.strip || ""
|
||||
if keyword.present?
|
||||
package_applies = package_applies.joins(:project_package).where("project_packages.title like ?","%#{keyword}%")
|
||||
end
|
||||
@package_applies = paginate package_applies.includes(project_package: { creator: :user_extension })
|
||||
end
|
||||
|
||||
def agree
|
||||
ProjectPackages::AgreeApplyService.new(current_apply).call
|
||||
render_success_js
|
||||
rescue ProjectPackages::AgreeApplyService::Error => e
|
||||
render json: { status: -1, message: e.message }
|
||||
end
|
||||
|
||||
def refuse
|
||||
ProjectPackages::RefuseApplyService.new(current_apply, reason: params[:reason]).call
|
||||
render_success_js
|
||||
rescue ProjectPackages::RefuseApplyService::Error => e
|
||||
render json: { status: -1, message: e.message }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_apply
|
||||
@_current_apply ||= ProjectPackageApply.find(params[:id])
|
||||
end
|
||||
end
|
||||
70
app/controllers/admins/project_statistics_controller.rb
Normal file
70
app/controllers/admins/project_statistics_controller.rb
Normal file
@@ -0,0 +1,70 @@
|
||||
class Admins::ProjectStatisticsController < Admins::BaseController
|
||||
|
||||
|
||||
def index
|
||||
projects = Project.project_statics_select.all
|
||||
by_time = params[:time]
|
||||
project_type = params[:project_type]
|
||||
is_private = params[:is_private]
|
||||
project_category_id = params[:project_category_id]
|
||||
project_language_id = params[:project_language_id]
|
||||
license_id = params[:license_id]
|
||||
|
||||
projects = projects.where(project_type: project_type) if project_type.present?
|
||||
projects = projects.where(is_private: is_private) if is_private.present?
|
||||
projects = projects.where(project_category_id: project_category_id) if project_category_id.present?
|
||||
projects = projects.where(project_language_id: project_language_id) if project_language_id.present?
|
||||
projects = projects.where(license_id: license_id) if license_id.present?
|
||||
|
||||
if by_time.present?
|
||||
case by_time.to_s
|
||||
when "week"
|
||||
projects = projects.group_by_week(:created_on).size
|
||||
when "month"
|
||||
projects = projects.group_by_month(:created_on).size
|
||||
when "quarter"
|
||||
projects = projects.group_by_month(:created_on).size
|
||||
when "year"
|
||||
projects = projects.group_by_year(:created_on).size
|
||||
else
|
||||
projects = projects.group_by_day(:created_on).size
|
||||
end
|
||||
end
|
||||
@projects = projects
|
||||
end
|
||||
|
||||
def visits_static
|
||||
projects = Project.project_statics_select.all
|
||||
by_time = params[:time]
|
||||
project_type = params[:project_type]
|
||||
is_private = params[:is_private]
|
||||
project_category_id = params[:project_category_id]
|
||||
project_language_id = params[:project_language_id]
|
||||
license_id = params[:license_id]
|
||||
|
||||
projects = projects.where(project_type: project_type) if project_type.present?
|
||||
projects = projects.where(is_private: is_private) if is_private.present?
|
||||
projects = projects.where(project_category_id: project_category_id) if project_category_id.present?
|
||||
projects = projects.where(project_language_id: project_language_id) if project_language_id.present?
|
||||
projects = projects.where(license_id: license_id) if license_id.present?
|
||||
|
||||
if by_time.present?
|
||||
case by_time.to_s
|
||||
when "week"
|
||||
projects = projects.group_by_week(:created_on).size
|
||||
when "month"
|
||||
projects = projects.group_by_month(:created_on).size
|
||||
when "quarter"
|
||||
projects = projects.group_by_month(:created_on).size
|
||||
when "year"
|
||||
projects = projects.group_by_year(:created_on).size
|
||||
else
|
||||
projects = projects.group_by_day(:created_on).size
|
||||
end
|
||||
end
|
||||
@projects = projects
|
||||
end
|
||||
|
||||
|
||||
|
||||
end
|
||||
25
app/controllers/admins/projects_controller.rb
Normal file
25
app/controllers/admins/projects_controller.rb
Normal file
@@ -0,0 +1,25 @@
|
||||
class Admins::ProjectsController < Admins::BaseController
|
||||
|
||||
def index
|
||||
default_sort('created_at', 'desc')
|
||||
|
||||
search = params[:search].to_s.strip
|
||||
projects = Project.where("name like ?", "%#{search}%")
|
||||
@projects = paginate projects.includes(:owner, :members, :issues, :versions, :attachments, :project_score)
|
||||
end
|
||||
|
||||
def destroy
|
||||
project = Project.find_by!(id: params[:id])
|
||||
ActiveRecord::Base.transaction do
|
||||
g = Gitlab.client
|
||||
g.delete_project(project.gpid)
|
||||
# 删除Trustie版本库记录
|
||||
repoisitory = Repository.where(project_id: project.id, type: "Repository::Gitlab").first
|
||||
repoisitory.destroy!
|
||||
Tiding.where(container_id: project.id, container_type: ["JoinProject", "DealProject", "ReporterJoinProject", "ManagerJoinProject"]).destroy_all
|
||||
project.destroy!
|
||||
render_delete_success
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
36
app/controllers/admins/repertoires_controller.rb
Normal file
36
app/controllers/admins/repertoires_controller.rb
Normal file
@@ -0,0 +1,36 @@
|
||||
class Admins::RepertoiresController < Admins::BaseController
|
||||
|
||||
def index
|
||||
@repertoires = Repertoire.all
|
||||
end
|
||||
|
||||
def edit
|
||||
@repertoire = current_repertoire
|
||||
end
|
||||
|
||||
def update
|
||||
Rails.logger.info("#################--------")
|
||||
if params[:repertoire] && params[:repertoire][:name].present?
|
||||
name = params[:repertoire][:name].to_s.strip
|
||||
current_repertoire.update_attributes!(name: name)
|
||||
end
|
||||
@repertoires = Repertoire.all
|
||||
end
|
||||
|
||||
def create
|
||||
name = params[:name].to_s.strip
|
||||
return render_error('名称重复') if Repertoire.where(name: name).exists?
|
||||
Repertoire.create!(name: name)
|
||||
render_ok
|
||||
end
|
||||
|
||||
def destroy
|
||||
@repertoire_id = params[:id]
|
||||
current_repertoire.destroy!
|
||||
end
|
||||
|
||||
private
|
||||
def current_repertoire
|
||||
@_current_repertoire = Repertoire.find params[:id]
|
||||
end
|
||||
end
|
||||
35
app/controllers/admins/salesman_channels_controller.rb
Normal file
35
app/controllers/admins/salesman_channels_controller.rb
Normal file
@@ -0,0 +1,35 @@
|
||||
class Admins::SalesmanChannelsController < Admins::BaseController
|
||||
before_action :set_salesman
|
||||
|
||||
def index
|
||||
@channels = @salesman.salesman_channels
|
||||
if params[:keyword].present?
|
||||
@channels = @channels.joins(:school).where("schools.name like ?", "%#{params[:keyword]}%")
|
||||
end
|
||||
@start_time = params[:start_date]
|
||||
@end_time = params[:end_date].blank? ? Time.now : params[:end_date]
|
||||
end
|
||||
|
||||
def batch_add
|
||||
channel_ids = @salesman.salesman_channels.pluck(:school_id)
|
||||
school_ids = params[:school_ids] - channel_ids
|
||||
school_ids.each do |school_id|
|
||||
school = School.find_by(id: school_id)
|
||||
next if school.blank? || @salesman.salesman_channels.where(school_id: school.id).exists?
|
||||
@salesman.salesman_channels.create!(school_id: school.id)
|
||||
end
|
||||
render_ok
|
||||
rescue Exception => ex
|
||||
render_error(ex.message)
|
||||
end
|
||||
|
||||
def destroy
|
||||
@salesman.salesman_channels.find_by!(id: params[:id]).destroy
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_salesman
|
||||
@salesman = Salesman.find params[:salesman_id]
|
||||
end
|
||||
end
|
||||
28
app/controllers/admins/salesman_customers_controller.rb
Normal file
28
app/controllers/admins/salesman_customers_controller.rb
Normal file
@@ -0,0 +1,28 @@
|
||||
class Admins::SalesmanCustomersController < Admins::BaseController
|
||||
before_action :set_salesman
|
||||
|
||||
def index
|
||||
@customers = @salesman.salesman_customers.includes(:user, :school)
|
||||
end
|
||||
|
||||
def batch_add
|
||||
customer_ids = @salesman.salesman_customers.pluck(:user_id)
|
||||
user_ids = params[:user_ids] - customer_ids
|
||||
user_ids.each do |user_id|
|
||||
user = UserExtension.find_by(user_id: user_id)
|
||||
next if user.blank? || @salesman.salesman_customers.where(user_id: user.user_id).exists?
|
||||
@salesman.salesman_customers.create!(user_id: user.user_id, school_id: user.school_id)
|
||||
end
|
||||
render_ok
|
||||
end
|
||||
|
||||
def destroy
|
||||
@salesman.salesman_customers.find_by!(id: params[:id]).destroy
|
||||
end
|
||||
|
||||
private
|
||||
def set_salesman
|
||||
@salesman = Salesman.find params[:salesman_id]
|
||||
end
|
||||
|
||||
end
|
||||
29
app/controllers/admins/salesmans_controller.rb
Normal file
29
app/controllers/admins/salesmans_controller.rb
Normal file
@@ -0,0 +1,29 @@
|
||||
class Admins::SalesmansController < Admins::BaseController
|
||||
before_action :set_salesman, except: [:index, :batch_add]
|
||||
|
||||
def index
|
||||
@salesmans = Salesman.all
|
||||
end
|
||||
|
||||
def destroy
|
||||
@salesman.destroy!
|
||||
end
|
||||
|
||||
# 批量增加销售人员
|
||||
def batch_add
|
||||
salesman_user_ids = Salesman.where(id: params[:user_ids]).pluck(:user_id)
|
||||
user_ids = params[:user_ids] - salesman_user_ids
|
||||
user_ids.each do |user_id|
|
||||
user = User.find_by(id: user_id)
|
||||
next if user.blank?
|
||||
Salesman.create!(user_id: user.id, name: user.real_name)
|
||||
end
|
||||
render_ok
|
||||
end
|
||||
|
||||
private
|
||||
def set_salesman
|
||||
@salesman = Salesman.find params[:id]
|
||||
end
|
||||
|
||||
end
|
||||
50
app/controllers/admins/school_statistics_controller.rb
Normal file
50
app/controllers/admins/school_statistics_controller.rb
Normal file
@@ -0,0 +1,50 @@
|
||||
class Admins::SchoolStatisticsController < Admins::BaseController
|
||||
before_action :contrast_column_select_options, only: [:contrast]
|
||||
|
||||
def index
|
||||
params[:data_type] ||= 'grow'
|
||||
params[:sort_by] = params[:sort_by].presence || :teacher_increase_count
|
||||
params[:sort_direction] = params[:sort_direction].presence || :desc
|
||||
|
||||
service = Admins::StatisticSchoolDataGrowService.new(params)
|
||||
@grow_summary = service.grow_summary
|
||||
|
||||
total_count, statistics = service.call
|
||||
@params_page = params[:page] || 1
|
||||
|
||||
@statistics = paginate statistics, total_count: total_count
|
||||
end
|
||||
|
||||
def contrast
|
||||
params[:contrast_column] = params[:contrast_column].presence || :teacher_increase_count
|
||||
params[:sort_direction] ||= :desc
|
||||
params[:sort_by] = :percentage
|
||||
|
||||
# 无对比日期时直接返回无数据页面
|
||||
if useless_contrast_date_parameter?
|
||||
@total_count = 0
|
||||
@statistics = paginate([])
|
||||
return
|
||||
end
|
||||
|
||||
total_count, statistics = Admins::StatisticSchoolContrastDataService.call(params)
|
||||
|
||||
@statistics = paginate statistics, total_count: total_count
|
||||
rescue Admins::StatisticSchoolContrastDataService::ParameterError
|
||||
render_unprocessable_entity('参数错误')
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def useless_contrast_date_parameter?
|
||||
params[:begin_date].blank? && params[:end_date].blank? &&
|
||||
params[:other_begin_date].blank? &¶ms[:other_end_date].blank?
|
||||
end
|
||||
|
||||
def contrast_column_select_options
|
||||
@select_options =
|
||||
Admins::StatisticSchoolContrastDataService::CONTRAST_COLUMN_LIST.map do |column|
|
||||
[I18n.t("school_daily_report.#{column}"), column]
|
||||
end
|
||||
end
|
||||
end
|
||||
30
app/controllers/admins/schools_controller.rb
Normal file
30
app/controllers/admins/schools_controller.rb
Normal file
@@ -0,0 +1,30 @@
|
||||
class Admins::SchoolsController < Admins::BaseController
|
||||
def index
|
||||
params[:sort_by] ||= 'created_at'
|
||||
params[:sort_direction] ||= 'desc'
|
||||
|
||||
schools = Admins::SchoolQuery.call(params)
|
||||
@total_count = schools.map(&:id).count
|
||||
@schools = paginate schools
|
||||
|
||||
school_ids = @schools.map(&:id)
|
||||
@department_count = Department.where(school_id: school_ids).group(:school_id).count
|
||||
end
|
||||
|
||||
def destroy
|
||||
users = User.joins(:user_extension).where(user_extensions: { school_id: current_school.id })
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
users.update_all(profile_completed: false)
|
||||
current_school.destroy!
|
||||
end
|
||||
|
||||
render_delete_success
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_school
|
||||
@_current_school ||= School.find(params[:id])
|
||||
end
|
||||
end
|
||||
84
app/controllers/admins/sub_disciplines_controller.rb
Normal file
84
app/controllers/admins/sub_disciplines_controller.rb
Normal file
@@ -0,0 +1,84 @@
|
||||
class Admins::SubDisciplinesController < Admins::BaseController
|
||||
|
||||
def index
|
||||
@discipline = current_discipline
|
||||
@sub_disciplines = current_discipline.sub_disciplines
|
||||
end
|
||||
|
||||
def create
|
||||
name = params[:name].to_s.strip
|
||||
return render_error('名称不能为空') if name.blank?
|
||||
return render_error('名称重复') if current_discipline.sub_disciplines.where(name: name).exists?
|
||||
SubDiscipline.create!(name: name, discipline_id: current_discipline.id, position: current_discipline.sub_disciplines.pluck(:position).max + 1)
|
||||
render_ok
|
||||
end
|
||||
|
||||
def edit
|
||||
@sub_discipline = current_sub_discipline
|
||||
end
|
||||
|
||||
def update
|
||||
begin
|
||||
if params[:sub_discipline] && params[:sub_discipline][:name]
|
||||
name = params[:sub_discipline][:name].to_s.strip
|
||||
current_sub_discipline.update_attributes!(name: name)
|
||||
else
|
||||
ActiveRecord::Base.transaction do
|
||||
current_sub_discipline.update_attributes!(setting_params)
|
||||
current_sub_discipline.tag_disciplines.each do |tag|
|
||||
tag.update_attributes!(setting_params)
|
||||
end
|
||||
end
|
||||
end
|
||||
rescue Exception => e
|
||||
@message = e.message
|
||||
end
|
||||
@sub_disciplines = current_sub_discipline.discipline&.sub_disciplines
|
||||
end
|
||||
|
||||
def destroy
|
||||
@sub_discipline_id = params[:id]
|
||||
ActiveRecord::Base.transaction do
|
||||
discipline = current_sub_discipline.discipline
|
||||
discipline.sub_disciplines.where("position > #{current_sub_discipline.position}").update_all("position=position-1")
|
||||
current_sub_discipline.destroy!
|
||||
end
|
||||
end
|
||||
|
||||
def adjust_position
|
||||
discipline = current_sub_discipline.discipline
|
||||
max_position = discipline.sub_disciplines.pluck(:position).max
|
||||
opr = params[:opr] || "down"
|
||||
if (params[:opr] == "up" && current_sub_discipline.position == 1) || (params[:opr] == "down" && current_sub_discipline.position == max_position)
|
||||
@message = "超出范围"
|
||||
else
|
||||
ActiveRecord::Base.transaction do
|
||||
if opr == "up"
|
||||
discipline.sub_disciplines.find_by("position = #{current_sub_discipline.position - 1}")&.update!(position: current_sub_discipline.position)
|
||||
current_sub_discipline.update!(position: current_sub_discipline.position - 1)
|
||||
else
|
||||
discipline.sub_disciplines.find_by("position = #{current_sub_discipline.position + 1}")&.update!(position: current_sub_discipline.position)
|
||||
current_sub_discipline.update!(position: current_sub_discipline.position + 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
@sub_disciplines = discipline&.sub_disciplines
|
||||
rescue Exception => e
|
||||
@message = e.message
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
def current_sub_discipline
|
||||
@_current_sub_discipline = SubDiscipline.find params[:id]
|
||||
end
|
||||
|
||||
def current_discipline
|
||||
@_current_discipline = Discipline.find params[:discipline_id]
|
||||
end
|
||||
|
||||
def setting_params
|
||||
params.permit(:shixun, :subject, :question)
|
||||
end
|
||||
end
|
||||
45
app/controllers/admins/sub_repertoires_controller.rb
Normal file
45
app/controllers/admins/sub_repertoires_controller.rb
Normal file
@@ -0,0 +1,45 @@
|
||||
class Admins::SubRepertoiresController < Admins::BaseController
|
||||
|
||||
def index
|
||||
@repertoire = current_repertoire
|
||||
@sub_repertoires = current_repertoire.sub_repertoires
|
||||
end
|
||||
|
||||
def create
|
||||
name = params[:name].to_s.strip
|
||||
return render_error('名称重复') if current_repertoire.sub_repertoires.where(name: name).exists?
|
||||
SubRepertoire.create!(name: name, repertoire_id: current_repertoire.id)
|
||||
render_ok
|
||||
end
|
||||
|
||||
def edit
|
||||
@sub_repertoire = current_sub_repertoire
|
||||
end
|
||||
|
||||
def update
|
||||
if params[:sub_repertoire] && params[:sub_repertoire][:name].present?
|
||||
name = params[:sub_repertoire][:name].to_s.strip
|
||||
current_sub_repertoire.update_attributes!(name: name)
|
||||
end
|
||||
@sub_repertoires = current_sub_repertoire.repertoire&.sub_repertoires
|
||||
end
|
||||
|
||||
def destroy
|
||||
@sub_repertoire_id = params[:id]
|
||||
current_sub_repertoire.destroy!
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_sub_repertoire
|
||||
@_current_sub_repertoire = SubRepertoire.find params[:id]
|
||||
end
|
||||
|
||||
def current_repertoire
|
||||
@_current_repertoire = Repertoire.find params[:repertoire_id]
|
||||
end
|
||||
|
||||
def setting_params
|
||||
params.permit(:shixun, :subject, :question)
|
||||
end
|
||||
end
|
||||
49
app/controllers/admins/subject_authorizations_controller.rb
Normal file
49
app/controllers/admins/subject_authorizations_controller.rb
Normal file
@@ -0,0 +1,49 @@
|
||||
class Admins::SubjectAuthorizationsController < Admins::BaseController
|
||||
def index
|
||||
params[:status] ||= 'pending'
|
||||
|
||||
applies = ApplyAction.where(container_type: 'ApplySubject')
|
||||
|
||||
status =
|
||||
case params[:status]
|
||||
when 'pending' then 0
|
||||
when 'processed' then [1, 2]
|
||||
when 'agreed' then 1
|
||||
when 'refused' then 2
|
||||
else 0
|
||||
end
|
||||
applies = applies.where(status: status) if status.present?
|
||||
|
||||
# 关键字模糊查询
|
||||
keyword = params[:keyword].to_s.strip
|
||||
if keyword.present?
|
||||
applies = applies.joins('JOIN subjects ON subjects.id = apply_actions.container_id')
|
||||
.where('subjects.name LIKE :keyword', keyword: "%#{keyword}%")
|
||||
end
|
||||
|
||||
applies = applies.order(updated_at: :desc)
|
||||
|
||||
@applies = paginate applies.includes(user: :user_extension)
|
||||
|
||||
subject_ids = @applies.map(&:container_id)
|
||||
@subject_map = Subject.where(id: subject_ids).each_with_object({}) { |s, h| h[s.id] = s }
|
||||
@challenge_count_map = Challenge.joins(shixun: :stage_shixuns).where(st: 0, stage_shixuns: { subject_id: subject_ids}).group('subject_id').count
|
||||
end
|
||||
|
||||
def agree
|
||||
Admins::SubjectAuths::AgreeApplyService.call(current_apply, current_user)
|
||||
render_success_js
|
||||
end
|
||||
|
||||
def refuse
|
||||
Admins::SubjectAuths::RefuseApplyService.call(current_apply, current_user, params)
|
||||
|
||||
render_success_js
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_apply
|
||||
@_current_apply ||= ApplyAction.where(container_type: 'ApplySubject').find(params[:id])
|
||||
end
|
||||
end
|
||||
34
app/controllers/admins/subject_settings_controller.rb
Normal file
34
app/controllers/admins/subject_settings_controller.rb
Normal file
@@ -0,0 +1,34 @@
|
||||
class Admins::SubjectSettingsController < Admins::BaseController
|
||||
def index
|
||||
default_sort('created_at', 'desc')
|
||||
|
||||
subjects = Admins::SubjectQuery.call(params)
|
||||
@sub_disciplines = SubDiscipline.where(subject: 1).pluck(:name,:id)
|
||||
@subjects = paginate subjects.includes(:repertoire, :subject_level_system, :sub_disciplines)
|
||||
end
|
||||
|
||||
def update
|
||||
sub_discipline_ids = params[:sub_disciplines] || []
|
||||
sub_ids = sub_discipline_ids.reject(&:blank?).map(&:to_i)
|
||||
old_sub_ids = current_subject.sub_discipline_containers.pluck(:sub_discipline_id)
|
||||
new_ids = sub_ids - old_sub_ids
|
||||
delete_ids = old_sub_ids - sub_ids
|
||||
sub_params = new_ids.map{|sub| {sub_discipline_id: sub}}
|
||||
ActiveRecord::Base.transaction do
|
||||
current_subject.sub_discipline_containers.where(sub_discipline_id: delete_ids).destroy_all
|
||||
current_subject.sub_discipline_containers.create!(sub_params)
|
||||
end
|
||||
end
|
||||
|
||||
def update_mobile_show
|
||||
subject = Subject.find(params[:subject_id])
|
||||
subject.update_attributes(:show_mobile => params[:show_mobile])
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_subject
|
||||
@_current_subject ||= Subject.find(params[:id])
|
||||
end
|
||||
|
||||
end
|
||||
71
app/controllers/admins/subjects_controller.rb
Normal file
71
app/controllers/admins/subjects_controller.rb
Normal file
@@ -0,0 +1,71 @@
|
||||
class Admins::SubjectsController < Admins::BaseController
|
||||
def index
|
||||
default_sort('created_at', 'desc')
|
||||
|
||||
subjects = Admins::SubjectQuery.call(params)
|
||||
@subjects = paginate subjects.includes(user: { user_extension: :school })
|
||||
end
|
||||
|
||||
def edit
|
||||
@subject = current_subject
|
||||
end
|
||||
|
||||
def update
|
||||
current_subject.update!(update_params)
|
||||
|
||||
flash[:success] = '保存成功'
|
||||
redirect_to admins_subject_settings_path
|
||||
end
|
||||
|
||||
def destroy
|
||||
current_subject.destroy!
|
||||
|
||||
render_delete_success
|
||||
end
|
||||
|
||||
# 隐藏
|
||||
def hide
|
||||
current_subject.update!(hidden: true)
|
||||
render_ok
|
||||
end
|
||||
|
||||
# 展示
|
||||
def cancel_hide
|
||||
current_subject.update!(hidden: false)
|
||||
render_ok
|
||||
end
|
||||
|
||||
# 设为主页展示
|
||||
def homepage_show
|
||||
current_subject.update!(homepage_show: true)
|
||||
render_ok
|
||||
end
|
||||
|
||||
# 取消主页展示
|
||||
def cancel_homepage_show
|
||||
current_subject.update!(homepage_show: false)
|
||||
render_ok
|
||||
end
|
||||
|
||||
# 设为金课
|
||||
def excellent
|
||||
current_subject.update!(excellent: true, public: 2)
|
||||
render_ok
|
||||
end
|
||||
|
||||
# 取消金课
|
||||
def cancel_excellent
|
||||
current_subject.update!(excellent: false)
|
||||
render_ok
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_subject
|
||||
@_current_subject ||= Subject.find(params[:id])
|
||||
end
|
||||
|
||||
def update_params
|
||||
params.require(:subject).permit(:repertoire_id, :subject_level_system_id, :student_count)
|
||||
end
|
||||
end
|
||||
79
app/controllers/admins/tag_disciplines_controller.rb
Normal file
79
app/controllers/admins/tag_disciplines_controller.rb
Normal file
@@ -0,0 +1,79 @@
|
||||
class Admins::TagDisciplinesController < Admins::BaseController
|
||||
|
||||
def index
|
||||
@sub_discipline = current_sub_discipline
|
||||
@tag_disciplines = current_sub_discipline.tag_disciplines
|
||||
end
|
||||
|
||||
def create
|
||||
name = params[:name].to_s.strip
|
||||
return render_error('名称重复') if current_sub_discipline.tag_disciplines.where(name: name).exists?
|
||||
TagDiscipline.create!(name: name, sub_discipline_id: current_sub_discipline.id, user_id: current_user.id,
|
||||
position: current_sub_discipline.tag_disciplines.pluck(:position).max + 1)
|
||||
render_ok
|
||||
end
|
||||
|
||||
def edit
|
||||
@tag_discipline = current_tag_discipline
|
||||
end
|
||||
|
||||
def update
|
||||
begin
|
||||
if params[:tag_discipline] && params[:tag_discipline][:name]
|
||||
name = params[:tag_discipline][:name].to_s.strip
|
||||
current_tag_discipline.update_attributes!(name: name)
|
||||
else
|
||||
current_tag_discipline.update_attributes!(setting_params)
|
||||
end
|
||||
rescue Exception => e
|
||||
@message = e.message
|
||||
end
|
||||
@tag_disciplines = current_tag_discipline.sub_discipline&.tag_disciplines
|
||||
end
|
||||
|
||||
def destroy
|
||||
@tag_discipline_id = params[:id]
|
||||
ActiveRecord::Base.transaction do
|
||||
sub_discipline = current_tag_discipline.sub_discipline
|
||||
sub_discipline.tag_disciplines.where("position > #{current_tag_discipline.position}").update_all("position=position-1")
|
||||
current_tag_discipline.destroy!
|
||||
end
|
||||
end
|
||||
|
||||
def adjust_position
|
||||
sub_discipline = current_tag_discipline.sub_discipline
|
||||
max_position = sub_discipline.tag_disciplines.pluck(:position).max
|
||||
opr = params[:opr] || "down"
|
||||
if (params[:opr] == "up" && current_tag_discipline.position == 1) || (params[:opr] == "down" && current_tag_discipline.position == max_position)
|
||||
@message = "超出范围"
|
||||
else
|
||||
ActiveRecord::Base.transaction do
|
||||
if opr == "up"
|
||||
sub_discipline.tag_disciplines.find_by("position = #{current_tag_discipline.position - 1}")&.update!(position: current_tag_discipline.position)
|
||||
current_tag_discipline.update!(position: current_tag_discipline.position - 1)
|
||||
else
|
||||
sub_discipline.tag_disciplines.find_by("position = #{current_tag_discipline.position + 1}")&.update!(position: current_tag_discipline.position)
|
||||
current_tag_discipline.update!(position: current_tag_discipline.position + 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
@tag_disciplines = sub_discipline&.tag_disciplines
|
||||
rescue Exception => e
|
||||
@message = e.message
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
def current_sub_discipline
|
||||
@_current_sub_discipline = SubDiscipline.find params[:sub_discipline_id]
|
||||
end
|
||||
|
||||
def current_tag_discipline
|
||||
@_current_tag_discipline = TagDiscipline.find params[:id]
|
||||
end
|
||||
|
||||
def setting_params
|
||||
params.permit(:shixun, :subject, :question)
|
||||
end
|
||||
end
|
||||
43
app/controllers/admins/tag_repertoires_controller.rb
Normal file
43
app/controllers/admins/tag_repertoires_controller.rb
Normal file
@@ -0,0 +1,43 @@
|
||||
class Admins::TagRepertoiresController < Admins::BaseController
|
||||
|
||||
def index
|
||||
@sub_repertoire = current_sub_repertoire
|
||||
@tag_repertoires = current_sub_repertoire.tag_repertoires
|
||||
end
|
||||
|
||||
def create
|
||||
name = params[:name].to_s.strip
|
||||
return render_error('名称重复') if current_sub_repertoire.tag_repertoires.where(name: name).exists?
|
||||
TagRepertoire.create!(name: name, sub_repertoire_id: current_sub_repertoire.id)
|
||||
render_ok
|
||||
end
|
||||
|
||||
def edit
|
||||
@tag_repertoire = current_tag_repertoire
|
||||
end
|
||||
|
||||
def update
|
||||
if params[:tag_repertoire] && params[:tag_repertoire][:name].present?
|
||||
name = params[:tag_repertoire][:name].to_s.strip
|
||||
current_tag_repertoire.update_attributes!(name: name)
|
||||
end
|
||||
@tag_repertoires = current_tag_repertoire.sub_repertoire&.tag_repertoires
|
||||
end
|
||||
|
||||
def destroy
|
||||
@tag_repertoire_id = params[:id]
|
||||
current_tag_repertoire.destroy!
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_sub_repertoire
|
||||
@_current_sub_repertoire = SubRepertoire.find params[:sub_repertoire_id]
|
||||
end
|
||||
|
||||
def current_tag_repertoire
|
||||
@_current_tag_repertoire = TagRepertoire.find params[:id]
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
122
app/controllers/admins/unit_applies_controller.rb
Normal file
122
app/controllers/admins/unit_applies_controller.rb
Normal file
@@ -0,0 +1,122 @@
|
||||
class Admins::UnitAppliesController < Admins::BaseController
|
||||
before_action :get_apply,only: [:agree,:destroy,:edit,:update]
|
||||
|
||||
def index
|
||||
params[:sort_by] ||= 'created_at'
|
||||
params[:sort_direction] ||= 'desc'
|
||||
unit_applies = Admins::UnitApplyQuery.call(params)
|
||||
@unit_applies = paginate unit_applies.preload(:school, :user)
|
||||
end
|
||||
|
||||
def agree
|
||||
ActiveRecord::Base.transaction do
|
||||
begin
|
||||
@unit_apply.update_attribute("status",1)
|
||||
@unit_apply&.applied_messages&.update_all(status:1)
|
||||
@unit_apply&.school&.update_attribute("province",@unit_apply.province)
|
||||
|
||||
# #申请信息的创建
|
||||
apply_message_params = {
|
||||
user_id: @unit_apply&.user_id,
|
||||
status: 1,
|
||||
viewed: 0,
|
||||
applied_id: @unit_apply.school_id,
|
||||
applied_type: "ApplyAddSchools",
|
||||
name: @unit_apply.name,
|
||||
}
|
||||
AppliedMessage.new(apply_message_params).save(validate: false)
|
||||
|
||||
Tiding.where(user_id: 1, trigger_user_id: @unit_apply.user_id, container_id: @unit_apply.id,
|
||||
container_type: 'ApplyAddSchools', status: 0, tiding_type: "Apply").update_all(status: 1)
|
||||
#消息的创建
|
||||
tiding_params = {
|
||||
user_id: @unit_apply.user_id,
|
||||
trigger_user_id: 0,
|
||||
container_id: @unit_apply.id,
|
||||
container_type: 'ApplyAddSchools',
|
||||
belong_container_id: @unit_apply.school_id,
|
||||
belong_container_type: "School",
|
||||
tiding_type: "System",
|
||||
status: 1
|
||||
}
|
||||
Tiding.create(tiding_params)
|
||||
render_success_js
|
||||
rescue Exception => e
|
||||
Rails.logger.info("############_________________#########{e}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
Admins::DeleteUnitApplyService.call(@unit_apply, params)
|
||||
render_success_js
|
||||
end
|
||||
|
||||
def edit
|
||||
@all_schools = School.where.not(id: @unit_apply.school_id).pluck("name","id")
|
||||
|
||||
end
|
||||
|
||||
def update
|
||||
school = School.find_by(id: params[:school_id])
|
||||
ActiveRecord::Base.transaction do
|
||||
@unit_apply&.applied_messages&.update_all(status:4)
|
||||
Tiding.where(user_id: 1, trigger_user_id: @unit_apply.user_id, container_id: @unit_apply.id,
|
||||
container_type: 'ApplyAddSchools', status: 0, tiding_type: "Apply").update_all(status: 1)
|
||||
|
||||
#消息的创建
|
||||
tiding_params = {
|
||||
user_id: @unit_apply.user_id,
|
||||
trigger_user_id: 0,
|
||||
container_id: @unit_apply.id,
|
||||
container_type: 'ApplyAddSchools',
|
||||
belong_container_id: params[:school_id],
|
||||
belong_container_type: "School",
|
||||
tiding_type: "System",
|
||||
status: 3,
|
||||
extra: school.try(:name).to_s
|
||||
}
|
||||
Tiding.create(tiding_params)
|
||||
|
||||
UserExtension.where(school_id: @unit_apply.school_id).update_all(school_id: params[:school_id].to_i)
|
||||
ApplyAddDepartment.where(:school_id => @unit_apply.school_id).update_all(school_id: params[:school_id].to_i)
|
||||
|
||||
# 判断重复
|
||||
before_apply_departments = Department.where(school_id: @unit_apply.school_id)
|
||||
before_apply_departments.each do |department|
|
||||
after_dep = Department.where(school_id: params[:school_id].to_i, name: department.name)&.first
|
||||
if after_dep.present?
|
||||
UserExtension.where(school_id: @unit_apply.school_id, department_id: department.id).update_all(department_id: after_dep.id)
|
||||
department.destroy
|
||||
department.apply_add_departments.destroy_all
|
||||
else
|
||||
department.apply_add_departments.update_all(school_id: school.id)
|
||||
department.update_attribute(:school_id, school.id)
|
||||
end
|
||||
end
|
||||
|
||||
@unit_apply&.school&.destroy
|
||||
apply_params = {
|
||||
status: 2,
|
||||
name: school&.name.to_s,
|
||||
school_id: params[:school_id],
|
||||
province: params[:province],
|
||||
city: params[:city],
|
||||
address: params[:address]
|
||||
}
|
||||
@unit_apply.update_attributes(apply_params)
|
||||
# render_success_js
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_apply
|
||||
@unit_apply = ApplyAddSchool.find_by(id:params[:id])
|
||||
end
|
||||
|
||||
def disk_auth_filename(source_type, source_id, type)
|
||||
File.join(storage_path, "#{source_type}", "#{source_id}#{type}")
|
||||
end
|
||||
end
|
||||
|
||||
19
app/controllers/admins/user_statistics_controller.rb
Normal file
19
app/controllers/admins/user_statistics_controller.rb
Normal file
@@ -0,0 +1,19 @@
|
||||
class Admins::UserStatisticsController < Admins::BaseController
|
||||
def index
|
||||
default_sort('finish_shixun_count', 'desc')
|
||||
|
||||
total_count, users = Admins::UserStatisticQuery.call(params)
|
||||
|
||||
@users = paginate users, total_count: total_count
|
||||
end
|
||||
|
||||
def export
|
||||
default_sort('finish_shixun_count', 'desc')
|
||||
|
||||
params[:per_page] = 10000
|
||||
_count, @users = Admins::UserStatisticQuery.call(params)
|
||||
|
||||
filename = ['用户实训情况', Time.zone.now.strftime('%Y%m%d%H%M%S')].join('-') << '.xlsx'
|
||||
render xlsx: 'export', filename: filename
|
||||
end
|
||||
end
|
||||
68
app/controllers/admins/users_controller.rb
Normal file
68
app/controllers/admins/users_controller.rb
Normal file
@@ -0,0 +1,68 @@
|
||||
class Admins::UsersController < Admins::BaseController
|
||||
def index
|
||||
params[:sort_by] = params[:sort_by].presence || 'created_on'
|
||||
params[:sort_direction] = params[:sort_direction].presence || 'desc'
|
||||
|
||||
users = Admins::UserQuery.call(params)
|
||||
@users = paginate users.includes(user_extension: :school)
|
||||
end
|
||||
|
||||
def edit
|
||||
@user = User.find(params[:id])
|
||||
end
|
||||
|
||||
def update
|
||||
@user = User.find(params[:id])
|
||||
|
||||
Admins::UpdateUserService.call(@user, update_params)
|
||||
flash[:success] = '保存成功'
|
||||
redirect_to edit_admins_user_path(@user)
|
||||
rescue ActiveRecord::RecordInvalid
|
||||
flash.now[:danger] = '保存失败'
|
||||
render 'edit'
|
||||
rescue Admins::UpdateUserService::Error => ex
|
||||
flash.now[:danger] = ex.message
|
||||
render 'edit'
|
||||
end
|
||||
|
||||
def destroy
|
||||
User.find(params[:id]).destroy!
|
||||
|
||||
render_delete_success
|
||||
end
|
||||
|
||||
def lock
|
||||
User.find(params[:id]).lock!
|
||||
|
||||
render_ok
|
||||
end
|
||||
|
||||
def unlock
|
||||
User.find(params[:id]).activate!
|
||||
|
||||
render_ok
|
||||
end
|
||||
|
||||
def reward_grade
|
||||
user = User.find(params[:user_id])
|
||||
return render_unprocessable_entity('金币数量必须大于0') if params[:grade].to_i <= 0
|
||||
|
||||
RewardGradeService.call(user, container_id: user.id, container_type: 'Feedback', score: params[:grade].to_i, not_unique: true)
|
||||
|
||||
render_ok(grade: user.grade)
|
||||
end
|
||||
|
||||
def reset_login_times
|
||||
User.find(params[:id]).reset_login_times!
|
||||
|
||||
render_ok
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def update_params
|
||||
params.require(:user).permit(%i[lastname nickname gender identity technical_title student_id is_shixun_marker
|
||||
mail phone location location_city school_id department_id admin business is_test
|
||||
password professional_certification authentication])
|
||||
end
|
||||
end
|
||||
41
app/controllers/admins/video_applies_controller.rb
Normal file
41
app/controllers/admins/video_applies_controller.rb
Normal file
@@ -0,0 +1,41 @@
|
||||
class Admins::VideoAppliesController < Admins::BaseController
|
||||
|
||||
def index
|
||||
params[:status] ||= 'pending'
|
||||
status = params[:status]
|
||||
if status == 'all'
|
||||
status = %w(agreed refused)
|
||||
end
|
||||
|
||||
applies = VideoApply.where(status: status).order('video_applies.updated_at desc')
|
||||
|
||||
search = params[:keyword].to_s.strip
|
||||
if search.present?
|
||||
applies = applies.joins(:video)
|
||||
.where('videos.title like :search', search: "%#{search}%")
|
||||
end
|
||||
|
||||
@video_applies = paginate applies.includes(video: { user: :user_extension })
|
||||
end
|
||||
|
||||
def agree
|
||||
Videos::AgreeApplyService.new(current_video_apply, current_user).call
|
||||
render_success_js
|
||||
rescue Videos::AgreeApplyService::Error => e
|
||||
render json: { status: -1, message: e.message }
|
||||
end
|
||||
|
||||
def refuse
|
||||
Videos::RefuseApplyService.new(current_video_apply, current_user, reason: params[:reason]).call
|
||||
render_success_js
|
||||
rescue Videos::RefuseApplyService::Error => e
|
||||
render json: { status: -1, message: e.message }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_video_apply
|
||||
@_current_video_apply ||= VideoApply.find(params[:id])
|
||||
end
|
||||
end
|
||||
|
||||
79
app/controllers/admins/weapp_adverts_controller.rb
Normal file
79
app/controllers/admins/weapp_adverts_controller.rb
Normal file
@@ -0,0 +1,79 @@
|
||||
class Admins::WeappAdvertsController < Admins::BaseController
|
||||
before_action :convert_file!, only: [:create]
|
||||
def index
|
||||
@adverts = WeappSettings::Advert.all
|
||||
end
|
||||
|
||||
def create
|
||||
position = WeappSettings::Advert.count + 1
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
advert = WeappSettings::Advert.create!(create_params.merge(position: position))
|
||||
|
||||
file_path = Util::FileManage.source_disk_filename(advert)
|
||||
File.delete(file_path) if File.exist?(file_path) # 删除之前的文件
|
||||
Util.write_file(@file, file_path)
|
||||
end
|
||||
|
||||
flash[:success] = '保存成功'
|
||||
redirect_to admins_weapp_adverts_path
|
||||
end
|
||||
|
||||
def update
|
||||
current_advert.update!(update_params)
|
||||
render_ok
|
||||
end
|
||||
|
||||
def destroy
|
||||
ActiveRecord::Base.transaction do
|
||||
current_advert.destroy!
|
||||
# 前移
|
||||
WeappSettings::Advert.where('position > ?', current_advert.position)
|
||||
.update_all('position = position - 1')
|
||||
|
||||
file_path = Util::FileManage.source_disk_filename(current_advert)
|
||||
File.delete(file_path) if File.exist?(file_path)
|
||||
end
|
||||
render_delete_success
|
||||
end
|
||||
|
||||
def drag
|
||||
move = WeappSettings::Advert.find_by(id: params[:move_id])
|
||||
after = WeappSettings::Advert.find_by(id: params[:after_id])
|
||||
|
||||
Admins::DragWeappAdvertService.call(move, after)
|
||||
render_ok
|
||||
rescue ApplicationService::Error => e
|
||||
render_error(e.message)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_advert
|
||||
@_current_advert ||= WeappSettings::Advert.find(params[:id])
|
||||
end
|
||||
|
||||
def create_params
|
||||
params.require(:weapp_settings_advert).permit(:link)
|
||||
end
|
||||
|
||||
def update_params
|
||||
params.permit(:link, :online)
|
||||
end
|
||||
|
||||
def convert_file!
|
||||
max_size = 10 * 1024 * 1024 # 10M
|
||||
file = params.dig('weapp_settings_advert', 'image')
|
||||
if file.class == ActionDispatch::Http::UploadedFile
|
||||
@file = file
|
||||
render_error('请上传文件') if @file.size.zero?
|
||||
render_error('文件大小超过限制') if @file.size > max_size
|
||||
else
|
||||
file = file.to_s.strip
|
||||
return render_error('请上传正确的图片') if file.blank?
|
||||
@file = Util.convert_base64_image(file, max_size: max_size)
|
||||
end
|
||||
rescue Base64ImageConverter::Error => ex
|
||||
render_error(ex.message)
|
||||
end
|
||||
end
|
||||
80
app/controllers/admins/weapp_carousels_controller.rb
Normal file
80
app/controllers/admins/weapp_carousels_controller.rb
Normal file
@@ -0,0 +1,80 @@
|
||||
class Admins::WeappCarouselsController < Admins::BaseController
|
||||
before_action :convert_file!, only: [:create]
|
||||
|
||||
def index
|
||||
@carousels = WeappSettings::Carousel.all
|
||||
end
|
||||
|
||||
def create
|
||||
position = WeappSettings::Carousel.count + 1
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
carousel = WeappSettings::Carousel.create!(create_params.merge(position: position))
|
||||
|
||||
file_path = Util::FileManage.source_disk_filename(carousel)
|
||||
File.delete(file_path) if File.exist?(file_path) # 删除之前的文件
|
||||
Util.write_file(@file, file_path)
|
||||
end
|
||||
|
||||
flash[:success] = '保存成功'
|
||||
redirect_to admins_weapp_carousels_path
|
||||
end
|
||||
|
||||
def update
|
||||
current_carousel.update!(update_params)
|
||||
render_ok
|
||||
end
|
||||
|
||||
def destroy
|
||||
ActiveRecord::Base.transaction do
|
||||
current_carousel.destroy!
|
||||
# 前移
|
||||
WeappSettings::Carousel.where('position > ?', current_carousel.position)
|
||||
.update_all('position = position - 1')
|
||||
|
||||
file_path = Util::FileManage.source_disk_filename(current_carousel)
|
||||
File.delete(file_path) if File.exist?(file_path)
|
||||
end
|
||||
render_delete_success
|
||||
end
|
||||
|
||||
def drag
|
||||
move = WeappSettings::Carousel.find_by(id: params[:move_id])
|
||||
after = WeappSettings::Carousel.find_by(id: params[:after_id])
|
||||
|
||||
Admins::DragWeappCarouselService.call(move, after)
|
||||
render_ok
|
||||
rescue ApplicationService::Error => e
|
||||
render_error(e.message)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_carousel
|
||||
@_current_carousel ||= WeappSettings::Carousel.find(params[:id])
|
||||
end
|
||||
|
||||
def create_params
|
||||
params.require(:weapp_settings_carousel).permit(:link)
|
||||
end
|
||||
|
||||
def update_params
|
||||
params.permit(:link, :online)
|
||||
end
|
||||
|
||||
def convert_file!
|
||||
max_size = 10 * 1024 * 1024 # 10M
|
||||
file = params.dig('weapp_settings_carousel', 'image')
|
||||
if file.class == ActionDispatch::Http::UploadedFile
|
||||
@file = file
|
||||
render_error('请上传文件') if @file.size.zero?
|
||||
render_error('文件大小超过限制') if @file.size > max_size
|
||||
else
|
||||
file = file.to_s.strip
|
||||
return render_error('请上传正确的图片') if file.blank?
|
||||
@file = Util.convert_base64_image(file, max_size: max_size)
|
||||
end
|
||||
rescue Base64ImageConverter::Error => ex
|
||||
render_error(ex.message)
|
||||
end
|
||||
end
|
||||
772
app/controllers/application_controller.rb
Normal file
772
app/controllers/application_controller.rb
Normal file
@@ -0,0 +1,772 @@
|
||||
require 'oauth2'
|
||||
|
||||
class ApplicationController < ActionController::Base
|
||||
include CodeExample
|
||||
include RenderExpand
|
||||
include RenderHelper
|
||||
include ControllerRescueHandler
|
||||
include LaboratoryHelper
|
||||
include GitHelper
|
||||
include LoggerHelper
|
||||
include LoginHelper
|
||||
|
||||
protect_from_forgery prepend: true, unless: -> { request.format.json? }
|
||||
|
||||
before_action :check_sign
|
||||
before_action :user_setup
|
||||
#before_action :check_account
|
||||
|
||||
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 = "79e33abd4b6588941ab7622aed1e67e8"
|
||||
|
||||
helper_method :current_user
|
||||
|
||||
# 所有请求必须合法签名
|
||||
def check_sign
|
||||
if !Rails.env.development?
|
||||
Rails.logger.info("66666 #{params}")
|
||||
# suffix = request.url.split(".").last.split("?").first
|
||||
# suffix_arr = ["xls", "xlsx", "pdf", "zip"] # excel文件先注释
|
||||
# unless suffix_arr.include?(suffix)
|
||||
if params[:client_key].present?
|
||||
randomcode = params[:randomcode]
|
||||
# tip_exception(501, "请求不合理") unless (Time.now.to_i - randomcode.to_i).between?(0,5)
|
||||
|
||||
sign = Digest::MD5.hexdigest("#{OPENKEY}#{randomcode}")
|
||||
Rails.logger.info("2222 #{sign}")
|
||||
tip_exception(501, "请求不合理") if sign != params[:client_key]
|
||||
else
|
||||
tip_exception(501, "请求不合理")
|
||||
end
|
||||
# end
|
||||
end
|
||||
end
|
||||
|
||||
# 全局配置参数
|
||||
# 返回name对应的value
|
||||
def edu_setting(name)
|
||||
EduSetting.get(name)
|
||||
end
|
||||
|
||||
# 平台身份权限判断(学生用户无权限)
|
||||
def identity_auth
|
||||
ue = current_user.user_extension
|
||||
tip_exception(403, "..") unless current_user.admin_or_business? || ue.teacher? || ue.professional?
|
||||
end
|
||||
|
||||
# 平台已认证身份判断(已认证的老师和专业人士)
|
||||
def certi_identity_auth
|
||||
ue = current_user.user_extension
|
||||
tip_exception(403, "..") unless current_user.admin_or_business? ||
|
||||
(current_user.professional_certification && (ue.teacher? || ue.professional?))
|
||||
end
|
||||
|
||||
def shixun_marker
|
||||
unless current_user.is_shixun_marker? || current_user.admin_or_business?
|
||||
tip_exception(403, "..")
|
||||
end
|
||||
end
|
||||
|
||||
# 实训的访问权限
|
||||
def shixun_access_allowed
|
||||
if !current_user.shixun_permission(@shixun)
|
||||
tip_exception(403, "..")
|
||||
end
|
||||
end
|
||||
|
||||
def admin_or_business?
|
||||
User.current.admin? || User.current.business?
|
||||
end
|
||||
|
||||
# 访问课堂时没权限直接弹加入课堂的弹框 :409
|
||||
def user_course_identity
|
||||
@user_course_identity = current_user.course_identity(@course)
|
||||
if @user_course_identity > Course::STUDENT && @course.is_public == 0
|
||||
tip_exception(401, "..") unless User.current.logged?
|
||||
check_account
|
||||
tip_exception(@course.excellent ? 410 : 409, "您没有权限进入")
|
||||
end
|
||||
if @user_course_identity > Course::CREATOR && @user_course_identity <= Course::STUDENT && @course.tea_id != current_user.id
|
||||
# 实名认证和职业认证的身份判断
|
||||
tip_exception(411, "你的实名认证和职业认证审核未通过") if @course.authentication &&
|
||||
@course.professional_certification && (!current_user.authentication && !current_user.professional_certification)
|
||||
tip_exception(411, "你的实名认证审核未通过") if @course.authentication && !current_user.authentication
|
||||
tip_exception(411, "你的职业认证审核未通过") if @course.professional_certification && !current_user.professional_certification
|
||||
end
|
||||
uid_logger("###############user_course_identity:#{@user_course_identity}")
|
||||
end
|
||||
|
||||
# 题库的访问权限
|
||||
def bank_visit_auth
|
||||
tip_exception(-2,"未通过职业认证") if current_user.is_teacher? && !current_user.certification_teacher? && !current_user.admin_or_business? && @bank.user_id != current_user.id && @bank.is_public
|
||||
tip_exception(403, "无权限") unless @bank.user_id == current_user.id || current_user.admin_or_business? ||
|
||||
(current_user.certification_teacher? && @bank.is_public)
|
||||
end
|
||||
|
||||
|
||||
# 判断用户的邮箱或者手机是否可用
|
||||
# params[:type] 1: 注册;2:忘记密码;3:绑定
|
||||
def check_mail_and_phone_valid login, type
|
||||
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}$/ ||
|
||||
login =~ /^[a-zA-Z0-9]+([._\\]*[a-zA-Z0-9])$/
|
||||
tip_exception(-2, "请输入正确的手机号或邮箱")
|
||||
end
|
||||
# 考虑到安全参数问题,多一次查询,去掉Union
|
||||
user = User.where(phone: login).first || User.where(mail: login).first
|
||||
if type.to_i == 1 && !user.nil?
|
||||
tip_exception(-2, "该手机号码或邮箱已被注册")
|
||||
elsif type.to_i == 2 && user.nil?
|
||||
tip_exception(-2, "该手机号码或邮箱未注册")
|
||||
elsif type.to_i == 3 && user.present?
|
||||
tip_exception(-2, "该手机号码或邮箱已绑定")
|
||||
end
|
||||
sucess_status
|
||||
end
|
||||
|
||||
# 发送及记录激活码
|
||||
# 发送验证码:type 1:注册手机验证码 2:找回密码手机验证码 3:找回密码邮箱验证码 4:绑定手机 5:绑定邮箱
|
||||
# 6:手机验证码登录 7:邮箱验证码登录 8:邮箱注册验证码 9:验证手机号有效
|
||||
def check_verification_code(code, send_type, value)
|
||||
case send_type
|
||||
when 1, 2, 4, 9
|
||||
# 手机类型的发送
|
||||
sigle_para = {phone: value}
|
||||
status = Educoder::Sms.send(mobile: value, code: code)
|
||||
tip_exception(-2, code_msg(status)) if status != 0
|
||||
when 8, 3, 5
|
||||
# 邮箱类型的发送
|
||||
sigle_para = {email: value}
|
||||
# 60s内不能重复发送
|
||||
send_email_limit_cache_key = "send_email_60_second_limit:#{value}"
|
||||
tip_exception(-1, '请勿频繁操作') if Rails.cache.exist?(send_email_limit_cache_key)
|
||||
|
||||
# 短时间内不能大量发送
|
||||
send_email_control = LimitForbidControl::SendEmailCode.new(value)
|
||||
tip_exception(-1, '邮件发送太频繁,请稍后再试') if send_email_control.forbid?
|
||||
begin
|
||||
UserMailer.register_email(value, code).deliver_now
|
||||
|
||||
Rails.cache.write(send_email_limit_cache_key, 1, expires_in: 1.minute)
|
||||
send_email_control.increment!
|
||||
# Mailer.run.email_register(code, value)
|
||||
rescue Exception => e
|
||||
logger_error(e)
|
||||
tip_exception(-2,"邮件发送失败,请稍后重试")
|
||||
end
|
||||
end
|
||||
ver_params = {code_type: send_type, code: code}.merge(sigle_para)
|
||||
VerificationCode.create!(ver_params)
|
||||
end
|
||||
|
||||
def code_msg status
|
||||
case status
|
||||
when 0
|
||||
"验证码已经发送到您的手机,请注意查收"
|
||||
when 8
|
||||
"同一手机号30秒内重复提交相同的内容"
|
||||
when 9
|
||||
"同一手机号5分钟内重复提交相同的内容超过3次"
|
||||
when 22
|
||||
"1小时内同一手机号发送次数超过限制"
|
||||
when 33
|
||||
"验证码发送次数超过频率"
|
||||
when 43
|
||||
"一天内同一手机号发送次数超过限制"
|
||||
when 53
|
||||
"手机号接收超过频率限制"
|
||||
end
|
||||
end
|
||||
|
||||
def find_course
|
||||
return normal_status(2, '缺少course_id参数!') if params[:course_id].blank?
|
||||
@course = Course.find(params[:course_id])
|
||||
tip_exception(404, "") if @course.is_delete == 1 && !current_user.admin_or_business?
|
||||
rescue Exception => e
|
||||
tip_exception(e.message)
|
||||
end
|
||||
|
||||
def course_manager
|
||||
return normal_status(403, '只有课堂管理员才有权限') if @user_course_identity > Course::CREATOR
|
||||
end
|
||||
|
||||
def find_board
|
||||
return normal_status(2, "缺少board_id参数") if params[:board_id].blank?
|
||||
@board = Board.find(params[:board_id])
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
tip_exception(e.message)
|
||||
end
|
||||
|
||||
def validate_type(object_type)
|
||||
normal_status(2, "参数") if params.has_key?(:sort_type) && !SORT_TYPE.include?(params[:sort_type].strip)
|
||||
end
|
||||
|
||||
def set_pagination
|
||||
@page = params[:page] || 1
|
||||
@page_size = params[:page_size] || 15
|
||||
end
|
||||
|
||||
# 课堂教师权限
|
||||
def teacher_allowed
|
||||
logger.info("#####identity: #{current_user.course_identity(@course)}")
|
||||
unless current_user.course_identity(@course) < Course::STUDENT
|
||||
normal_status(403, "")
|
||||
end
|
||||
end
|
||||
|
||||
# 课堂教师、课堂管理员、超级管理员的权限(不包含助教)
|
||||
def teacher_or_admin_allowed
|
||||
unless current_user.course_identity(@course) < Course::ASSISTANT_PROFESSOR
|
||||
normal_status(403, "")
|
||||
end
|
||||
end
|
||||
|
||||
def require_admin
|
||||
normal_status(403, "") unless User.current.admin?
|
||||
end
|
||||
|
||||
def require_business
|
||||
normal_status(403, "") unless admin_or_business?
|
||||
end
|
||||
|
||||
# 前端会捕捉401,弹登录弹框
|
||||
# 未授权的捕捉407,弹试用申请弹框
|
||||
def require_login
|
||||
#6.13 -hs
|
||||
tip_exception(401, "请登录后再操作") unless User.current.logged?
|
||||
end
|
||||
|
||||
# 异常提醒
|
||||
def tip_exception(status = -1, message)
|
||||
raise Educoder::TipException.new(status, message)
|
||||
end
|
||||
|
||||
def missing_template
|
||||
tip_exception(404, "...")
|
||||
end
|
||||
|
||||
# 弹框提醒
|
||||
def tip_show_exception(status = -2, message)
|
||||
raise Educoder::TipException.new(status, message)
|
||||
end
|
||||
|
||||
def normal_status(status = 0, message)
|
||||
case status
|
||||
when 403
|
||||
message = "您没有权限进行该操作"
|
||||
when 404
|
||||
message = "您访问的页面不存在或已被删除"
|
||||
end
|
||||
render :json => { status: status, message: message }
|
||||
end
|
||||
|
||||
# 资料是否完善
|
||||
def check_account
|
||||
if !current_user.profile_completed?
|
||||
#info_url = '/account/profile'
|
||||
tip_exception(402, nil)
|
||||
end
|
||||
end
|
||||
|
||||
# 系统全局认证(暂时隐藏试用申请的判断)
|
||||
def check_auth
|
||||
# day_cer = UserDayCertification.find_by(user_id: current_user.id)
|
||||
# # 如果注册超过24小时则需要完善资料及授权
|
||||
# if (Time.now.to_i - day_cer.try(:created_at).to_i) > 86400
|
||||
# if !current_user.profile_completed?
|
||||
# info_url = '/account/profile'
|
||||
# tip_exception(402, info_url)
|
||||
# elsif current_user.certification != 1
|
||||
# if current_user.apply_actions.exists?(container_type: 'TrialAuthorization', status: 0)
|
||||
# tip_exception(408, "您的试用申请正在审核中,请耐心等待")
|
||||
# end
|
||||
# tip_exception(407, "系统未授权")
|
||||
# end
|
||||
# end
|
||||
|
||||
|
||||
# if current_user.certification != 1 && current_user.apply_actions.exists?(container_type: 'TrialAuthorization', status: 0)
|
||||
# tip_exception(408, "您的试用申请正在审核中,请耐心等待")
|
||||
# elsif (Time.now.to_i - day_cer.try(:created_at).to_i) < 86400
|
||||
# if !current_user.profile_completed?
|
||||
# info_url = '/account/profile'
|
||||
# tip_exception(402, info_url)
|
||||
# elsif current_user.certification != 1
|
||||
# day_cer = UserDayCertification.find_by(user_id: current_user.id)
|
||||
# tip_exception(407, "系统未授权") unless (Time.now.to_i - day_cer.try(:created_at).to_i) < 86400
|
||||
# end
|
||||
# end
|
||||
end
|
||||
|
||||
def user_setup
|
||||
# # reacct静态资源加载不需要走这一步
|
||||
#return if params[:controller] == "main"
|
||||
# Find the current user
|
||||
#Rails.logger.info("current_laboratory is #{current_laboratory} domain is #{request.subdomain}")
|
||||
User.current = find_current_user
|
||||
uid_logger("user_setup: " + (User.current.logged? ? "#{User.current.try(:login)} (id=#{User.current.try(:id)})" : "anonymous"))
|
||||
|
||||
# 开放课程通过链接访问的用户
|
||||
if !User.current.logged? && !params[:chinaoocTimestamp].blank? && !params[:websiteName].blank? && !params[:chinaoocKey].blank?
|
||||
content = "#{OPENKEY}#{params[:websiteName]}#{params[:chinaoocTimestamp]}"
|
||||
|
||||
if Digest::MD5.hexdigest(content) == params[:chinaoocKey]
|
||||
user = open_class_user
|
||||
if user
|
||||
start_user_session(user)
|
||||
set_autologin_cookie(user)
|
||||
end
|
||||
User.current = user
|
||||
end
|
||||
end
|
||||
|
||||
# if !User.current.logged? && Rails.env.development?
|
||||
# User.current = User.find 1
|
||||
# end
|
||||
|
||||
|
||||
# 测试版前端需求
|
||||
logger.info("subdomain:#{request.subdomain}")
|
||||
if request.subdomain != "www"
|
||||
if params[:debug] == 'teacher' #todo 为了测试,记得讲debug删除
|
||||
User.current = User.find 81403
|
||||
elsif params[:debug] == 'student'
|
||||
User.current = User.find 8686
|
||||
elsif params[:debug] == 'admin'
|
||||
User.current = User.find 1
|
||||
end
|
||||
end
|
||||
# User.current = User.find 81403
|
||||
end
|
||||
|
||||
# Returns the current user or nil if no user is logged in
|
||||
# and starts a session if needed
|
||||
def find_current_user
|
||||
uid_logger("user setup start: session[:user_id] is #{session[:user_id]}")
|
||||
uid_logger("0000000000000user setup start: default_yun_session is #{default_yun_session}, session[:current_user_id] is #{session[:"#{default_yun_session}"]}")
|
||||
current_domain_session = session[:"#{default_yun_session}"]
|
||||
if current_domain_session
|
||||
# existing session
|
||||
User.current = (User.active.find(current_domain_session) rescue nil)
|
||||
elsif autologin_user = try_to_autologin
|
||||
autologin_user
|
||||
elsif params[:format] == 'atom' && params[:key] && request.get? && accept_rss_auth?
|
||||
# RSS key authentication does not start a session
|
||||
User.find_by_rss_key(params[:key])
|
||||
end
|
||||
end
|
||||
|
||||
def try_to_autologin
|
||||
if cookies[autologin_cookie_name]
|
||||
# auto-login feature starts a new session
|
||||
user = nil
|
||||
Rails.logger.info("111111111111111111#{default_yun_session}, session is #{session[:"#{default_yun_session}"]} ")
|
||||
user = User.try_to_autologin(cookies[autologin_cookie_name]) if session[:"#{default_yun_session}"]
|
||||
start_user_session(user) if user
|
||||
user
|
||||
end
|
||||
end
|
||||
|
||||
def api_request?
|
||||
%w(xml json).include? params[:format]
|
||||
end
|
||||
|
||||
def current_user
|
||||
User.current
|
||||
end
|
||||
|
||||
## 默认输出json
|
||||
def render_json
|
||||
respond_to do |format|
|
||||
format.json
|
||||
end
|
||||
end
|
||||
|
||||
## 输出错误信息
|
||||
def error_status(message = nil)
|
||||
@status = -1
|
||||
@message = message
|
||||
end
|
||||
|
||||
# 实训等对应的仓库地址
|
||||
def repo_ip_url(repo_path)
|
||||
"#{edu_setting('git_address_ip')}/#{repo_path}"
|
||||
end
|
||||
|
||||
def repo_url(repo_path)
|
||||
"#{edu_setting('git_address_domain')}/#{repo_path}"
|
||||
end
|
||||
|
||||
# 通关后,把最后一次成功的代码存到数据库
|
||||
# type 0 创始内容, 1 最新内容
|
||||
# def game_passed_code(path, myshixun, game_id)
|
||||
# # 如果代码窗口是隐藏的,则不用保存代码
|
||||
# return if myshixun.shixun.hide_code || myshixun.shixun.vnc
|
||||
# file_content = git_fle_content myshixun.repo_path, path
|
||||
# #unless file_content.present?
|
||||
# # raise("获取文件代码异常")
|
||||
# #end
|
||||
# logger.info("#######game_id:#{game_id}, file_content:#{file_content}")
|
||||
# game_code = GameCode.where(:game_id => game_id, :path => path).first
|
||||
# if game_code.nil?
|
||||
# GameCode.create!(:game_id => game_id, :new_code => file_content, :path => path)
|
||||
# else
|
||||
# game_code.update_attributes!(:new_code => file_content)
|
||||
# end
|
||||
# end
|
||||
|
||||
# Post请求
|
||||
def uri_post(uri, params)
|
||||
begin
|
||||
uid_logger_dubug("--uri_exec: params is #{params}, url is #{uri}")
|
||||
uri = URI.parse(URI.encode(uri.strip))
|
||||
res = Net::HTTP.post_form(uri, params).body
|
||||
uid_logger_dubug("--uri_exec: .....res is #{res}")
|
||||
JSON.parse(res)
|
||||
rescue Exception => e
|
||||
uid_logger_error("--uri_exec: exception #{e.message}")
|
||||
raise Educoder::TipException.new("实训平台繁忙(繁忙等级:84)")
|
||||
end
|
||||
end
|
||||
|
||||
# 处理返回非0就报错的请求
|
||||
def interface_post(uri, params, status, message)
|
||||
begin
|
||||
uid_logger_dubug("--uri_exec: params is #{params}, url is #{uri}")
|
||||
uri = URI.parse(URI.encode(uri.strip))
|
||||
res = Net::HTTP.post_form(uri, params).body
|
||||
uid_logger_dubug("--uri_exec: .....res is #{res}")
|
||||
res = JSON.parse(res)
|
||||
if (res && res['code'] != 0)
|
||||
tip_exception(status, message)
|
||||
else
|
||||
res
|
||||
end
|
||||
rescue Exception => e
|
||||
uid_logger("--uri_exec: exception #{e.message}")
|
||||
raise Educoder::TipException.new(message)
|
||||
end
|
||||
end
|
||||
|
||||
# json格式请求
|
||||
def interface_json_post(uri, params, status, message)
|
||||
begin
|
||||
uid_logger_dubug("--uri_exec: params is #{params}, url is #{uri}")
|
||||
uri = URI.parse(URI.encode(uri.strip))
|
||||
res = Net::HTTP.start(uri.host, uri.port) do |http|
|
||||
req = Net::HTTP::Post.new(uri)
|
||||
req['Content-Type'] = 'application/json'
|
||||
req.body = params.to_json
|
||||
http.request(req)
|
||||
end
|
||||
uid_logger_dubug("--uri_exec: .....res is #{res.body}")
|
||||
res = JSON.parse(res.body)
|
||||
if (res && res['code'] != 0)
|
||||
tip_exception(status, message)
|
||||
else
|
||||
res
|
||||
end
|
||||
rescue Exception => e
|
||||
uid_logger("--uri_exec: exception #{e.message}")
|
||||
raise Educoder::TipException.new("服务器繁忙")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# 适用与已经用url_safe编码后,回调字符串形式
|
||||
def tran_base64_decode64(str)
|
||||
s_size = str.size % 4
|
||||
if s_size != 0
|
||||
str += "=" * (4 - s_size)
|
||||
end
|
||||
if str.blank?
|
||||
str
|
||||
else
|
||||
Base64.decode64(str.tr("-_", "+/")).force_encoding("utf-8")
|
||||
end
|
||||
end
|
||||
|
||||
def sucess_status(message = 'success')
|
||||
render :json => { status: 1, message: message }
|
||||
end
|
||||
|
||||
# 随机生成字符
|
||||
def generate_identifier(container, num, pre='')
|
||||
code = DCODES.sample(num).join
|
||||
if container == User
|
||||
while container.exists?(login: pre+code) do
|
||||
code = DCODES.sample(num).join
|
||||
end
|
||||
else
|
||||
while container.exists?(identifier: code) do
|
||||
code = DCODES.sample(num).join
|
||||
end
|
||||
end
|
||||
code
|
||||
end
|
||||
|
||||
|
||||
# 实训主类别列表,自带描述
|
||||
def shixun_main_type
|
||||
list = []
|
||||
mirrors = MirrorRepository.select([:id, :type_name, :description, :name]).published_main_mirror
|
||||
mirrors.try(:each) do |mirror|
|
||||
list << {id: mirror.id, type_name: mirror.type_name, description: mirror.try(:description), mirror_name: mirror.name}
|
||||
end
|
||||
list
|
||||
end
|
||||
|
||||
# 小类别列表
|
||||
def shixun_small_type
|
||||
list = []
|
||||
mirrors = MirrorRepository.select([:id, :type_name, :description, :name]).published_small_mirror
|
||||
mirrors.try(:each) do |mirror|
|
||||
list << {id: mirror.id, type_name: mirror.type_name, description: mirror.description, mirror_name: mirror.name}
|
||||
end
|
||||
list
|
||||
end
|
||||
|
||||
def container_limit(mirror_repositories)
|
||||
container = []
|
||||
mirror_repositories.each do |mr|
|
||||
if mr.name.present?
|
||||
container << {:image => mr.name, :cpuLimit => mr.cpu_limit, :memoryLimit => "#{mr.memory_limit}M", :type => mr.try(:main_type) == "1" ? "main" : "sub"}
|
||||
end
|
||||
end
|
||||
container.to_json
|
||||
end
|
||||
|
||||
# 实训中间层pod配置
|
||||
def shixun_container_limit shixun
|
||||
container = []
|
||||
shixun.shixun_service_configs.each do |config|
|
||||
mirror = config.mirror_repository
|
||||
if mirror.name.present?
|
||||
# 资源限制没有就传默认值。
|
||||
cpu_limit = config.cpu_limit.presence || 1
|
||||
cpu_request = config.lower_cpu_limit.presence || 0.1
|
||||
memory_limit = config.memory_limit.presence || 1024
|
||||
request_limit = config.request_limit.presence || 10
|
||||
resource_limit = config.resource_limit.presence || 10000
|
||||
container << {:image => mirror.name,
|
||||
:cpuLimit => cpu_limit,
|
||||
:cpuRequest => cpu_request,
|
||||
:memoryLimit => "#{memory_limit}M",
|
||||
:memoryRequest => "#{request_limit}M",
|
||||
:resourceLimit => "#{resource_limit}K",
|
||||
:type => mirror.try(:main_type) == "1" ? "main" : "sub"}
|
||||
end
|
||||
end
|
||||
container.to_json
|
||||
end
|
||||
|
||||
# 毕设任务列表的赛选
|
||||
def course_work(task, **option)
|
||||
logger.info("#############{option}")
|
||||
course = task.course
|
||||
work_list = task.graduation_works.includes(user: [:user_extension])
|
||||
# 教师评阅搜索 0: 未评, 1 已评
|
||||
if option[:teacher_comment]
|
||||
graduation_work_ids = GraduationWorkScore.where(graduation_work_id: work_list.map(&:id)).pluck(:graduation_work_id)
|
||||
if option[:teacher_comment].zero?
|
||||
work_list = work_list.where.not(id: graduation_work_ids)
|
||||
elsif option[:teacher_comment] == 1
|
||||
work_list = work_list.where(id: graduation_work_ids).where.not(work_status: 0)
|
||||
end
|
||||
end
|
||||
|
||||
# 作品状态 0: 未提交, 1 按时提交, 2 延迟提交
|
||||
if option[:task_status]
|
||||
work_list = work_list.where(work_status: option[:task_status])
|
||||
end
|
||||
|
||||
# 分班情况
|
||||
if option[:course_group]
|
||||
group_user_ids = course.course_members.where(course_group_id: option[:course_group]).pluck(:user_id)
|
||||
# 有分组只可能是老师身份查看列表
|
||||
work_list = work_list.where(user_id: group_user_ids)
|
||||
end
|
||||
|
||||
# 只看我的交叉评阅
|
||||
if option[:cross_comment]
|
||||
graduation_work_id = task.graduation_work_comment_assignations.where(:user_id => current_user.id)
|
||||
.pluck(:graduation_work_id).uniq if task.graduation_work_comment_assignations
|
||||
work_list = work_list.where(id: graduation_work_id)
|
||||
end
|
||||
|
||||
# 输入姓名和学号搜索
|
||||
# TODO user_extension 如果修改 请调整
|
||||
if option[:search]
|
||||
work_list = work_list.joins(user: :user_extension).where("concat(lastname, firstname) like ?
|
||||
or student_id like ?", "%#{option[:search]}%", "%#{option[:search]}%")
|
||||
end
|
||||
|
||||
# 排序
|
||||
rorder = option[:order] || "updated_at"
|
||||
b_order = option[:b_order] || "desc"
|
||||
if rorder == "created_at" || rorder == "work_score"
|
||||
work_list = work_list.order("graduation_works.#{rorder} #{b_order}")
|
||||
elsif rorder == "student_id"
|
||||
work_list = work_list.joins(user: :user_extension).order("user_extensions.#{rorder} #{b_order}")
|
||||
end
|
||||
work_list
|
||||
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
|
||||
def filename_for_content_disposition(name)
|
||||
request.env['HTTP_USER_AGENT'] =~ %r{MSIE|Trident|Edge} ? ERB::Util.url_encode(name) : name
|
||||
end
|
||||
|
||||
def format_time(time)
|
||||
time.blank? ? '' : time.strftime("%Y-%m-%d %H:%M")
|
||||
end
|
||||
|
||||
# 获取Oauth Client
|
||||
def get_client(site)
|
||||
client_id = Rails.configuration.educoder['client_id']
|
||||
client_secret = Rails.configuration.educoder['client_secret']
|
||||
|
||||
OAuth2::Client.new(client_id, client_secret, site: site)
|
||||
end
|
||||
|
||||
def paginate(relation)
|
||||
limit = params[:limit] || params[:per_page]
|
||||
limit = (limit.to_i.zero? || limit.to_i > 20) ? 20 : limit.to_i
|
||||
page = params[:page].to_i.zero? ? 1 : params[:page].to_i
|
||||
offset = (page - 1) * limit
|
||||
|
||||
if relation.is_a?(Array)
|
||||
relation[offset, limit]
|
||||
else
|
||||
relation.limit(limit).offset(offset)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
def strf_time(time)
|
||||
time.blank? ? '' : time.strftime("%Y-%m-%d %H:%M:%S")
|
||||
end
|
||||
|
||||
def strf_date(date)
|
||||
date.blank? ? '' : date.to_date.strftime("%Y-%m-%d")
|
||||
end
|
||||
|
||||
def logger_error(error)
|
||||
Rails.logger.error(error.message)
|
||||
error.backtrace.each { |msg| Rails.logger.error(msg) }
|
||||
end
|
||||
|
||||
def find_user
|
||||
@user = User.find_by_login params[:login]
|
||||
render_not_found("未找到’#{params[:login]}’相关的用户") unless @user
|
||||
end
|
||||
|
||||
def find_user_with_id
|
||||
@user = User.find_by_id params[:user_id]
|
||||
render_not_found("未找到’#{params[:login]}’相关的用户") unless @user
|
||||
end
|
||||
|
||||
def find_repository
|
||||
@repo = @user.repositories.find_by_identifier params[:repo_identifier]
|
||||
render_not_found("未找到’#{params[:repo_identifier]}’相关的项目") unless @repo
|
||||
end
|
||||
|
||||
def find_project
|
||||
project_id = params[:project_id] ? params[:project_id] : params[:id]
|
||||
project = Project.where(identifier: project_id)
|
||||
if project.exists?
|
||||
@project = project.first
|
||||
else
|
||||
@project = Project.find project_id
|
||||
end
|
||||
|
||||
render_not_found("未找到’#{project}’相关的项目") unless @project
|
||||
end
|
||||
|
||||
def find_project_with_identifier
|
||||
@project = Project.find_by_identifier! params[:id]
|
||||
render_not_found("未找到’#{params[:id]}’相关的项目") unless @project
|
||||
end
|
||||
|
||||
def find_project_with_id
|
||||
@project = Project.find(params[:project_id] || params[:id])
|
||||
rescue Exception => e
|
||||
logger_error(e.message)
|
||||
tip_exception(e.message)
|
||||
end
|
||||
|
||||
def render_response(interactor)
|
||||
interactor.success? ? render_ok : render_error(interactor.error)
|
||||
end
|
||||
|
||||
private
|
||||
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)
|
||||
uid_logger("Tip show status is #{exception.status}, message is #{exception.message}")
|
||||
render json: exception.tip_json
|
||||
end
|
||||
|
||||
def render_parameter_missing
|
||||
render json: { status: -1, message: '参数缺失' }
|
||||
end
|
||||
|
||||
def set_export_cookies
|
||||
cookies[:fileDownload] = true
|
||||
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
|
||||
keyword = params[:keyword].to_s.strip
|
||||
return if keyword.blank? || keyword.size <= 1
|
||||
return unless HotSearchKeyword.available?
|
||||
|
||||
HotSearchKeyword.add(keyword)
|
||||
end
|
||||
|
||||
end
|
||||
240
app/controllers/attachments_controller.rb
Normal file
240
app/controllers/attachments_controller.rb
Normal file
@@ -0,0 +1,240 @@
|
||||
#coding=utf-8
|
||||
#
|
||||
# 文件上传
|
||||
class AttachmentsController < ApplicationController
|
||||
before_action :require_login, :check_auth, except: [:show]
|
||||
before_action :find_file, only: %i[show destroy]
|
||||
before_action :attachment_candown, only: [:show]
|
||||
skip_before_action :check_sign, only: [:show, :create]
|
||||
|
||||
include ApplicationHelper
|
||||
|
||||
def show
|
||||
# 1. 优先跳到cdn
|
||||
# 2. 如果没有cdn,send_file
|
||||
if @file.cloud_url.present?
|
||||
update_downloads(@file)
|
||||
redirect_to @file.cloud_url and return
|
||||
end
|
||||
|
||||
type_attachment = params[:disposition] || "attachment"
|
||||
if type_attachment == "inline"
|
||||
send_file absolute_path(local_path(@file)),filename: @file.title, disposition: 'inline',type: 'application/pdf'
|
||||
elsif type_attachment == "MP4"
|
||||
send_file_with_range absolute_path(local_path(@file)), disposition: 'inline', type: "video/mp4", range: true
|
||||
else
|
||||
send_file(absolute_path(local_path(@file)), filename: @file.title,stream:false, type: @file.content_type.presence || 'application/octet-stream')
|
||||
end
|
||||
update_downloads(@file)
|
||||
end
|
||||
|
||||
def create
|
||||
# 1. 本地存储
|
||||
# 2. 上传到云
|
||||
begin
|
||||
upload_file = params["file"] || params["#{params[:file_param_name]}"] # 这里的file_param_name是为了方便其他插件名称
|
||||
uid_logger("#########################file_params####{params["#{params[:file_param_name]}"]}")
|
||||
raise "未上传文件" unless upload_file
|
||||
|
||||
folder = edu_setting('attachment_folder')
|
||||
raise "存储目录未定义" unless folder.present?
|
||||
|
||||
month_folder = current_month_folder
|
||||
save_path = File.join(folder, month_folder)
|
||||
|
||||
ext = file_ext(upload_file.original_filename)
|
||||
|
||||
local_path, digest = file_save_to_local(save_path, upload_file.tempfile, ext)
|
||||
|
||||
content_type = upload_file.content_type.presence || 'application/octet-stream'
|
||||
|
||||
# remote_path = file_save_to_ucloud(local_path[folder.size, local_path.size], local_path, content_type)
|
||||
remote_path = nil # TODO 暂时本地上传,待域名配置后方可上传至云端
|
||||
|
||||
logger.info "local_path: #{local_path}"
|
||||
logger.info "remote_path: #{remote_path}"
|
||||
|
||||
|
||||
disk_filename = local_path[save_path.size + 1, local_path.size]
|
||||
#存数据库
|
||||
#
|
||||
@attachment = Attachment.where(disk_filename: disk_filename,
|
||||
author_id: current_user.id,
|
||||
cloud_url: remote_path).first
|
||||
if @attachment.blank?
|
||||
@attachment = Attachment.new
|
||||
@attachment.filename = upload_file.original_filename
|
||||
@attachment.disk_filename = local_path[save_path.size + 1, local_path.size]
|
||||
@attachment.filesize = upload_file.tempfile.size
|
||||
@attachment.content_type = content_type
|
||||
@attachment.digest = digest
|
||||
@attachment.author_id = current_user.id
|
||||
@attachment.disk_directory = month_folder
|
||||
@attachment.cloud_url = remote_path
|
||||
@attachment.save!
|
||||
else
|
||||
logger.info "文件已存在,id = #{@attachment.id}, filename = #{@attachment.filename}"
|
||||
end
|
||||
|
||||
render_json
|
||||
rescue => e
|
||||
uid_logger_error(e.message)
|
||||
tip_exception(e.message)
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
begin
|
||||
@file_path = absolute_path(local_path(@file))
|
||||
#return normal_status(403, "") unless @file.author == current_user
|
||||
@file.destroy!
|
||||
|
||||
delete_file(@file_path)
|
||||
normal_status("删除成功")
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
tip_exception(e.message)
|
||||
raise ActiveRecord::Rollback
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def find_file
|
||||
@file =
|
||||
if params[:type] == 'history'
|
||||
AttachmentHistory.find params[:id]
|
||||
else
|
||||
Attachment.find params[:id]
|
||||
end
|
||||
end
|
||||
|
||||
def delete_file(file_path)
|
||||
File.delete(file_path) if File.exist?(file_path)
|
||||
end
|
||||
|
||||
def current_month_folder
|
||||
date = Time.now
|
||||
"#{date.year}/#{date.month.to_s.rjust(2, '0')}"
|
||||
end
|
||||
|
||||
def file_ext(file_name)
|
||||
ext = ''
|
||||
exts = file_name.split(".")
|
||||
if exts.size > 1
|
||||
ext = ".#{exts.last}"
|
||||
end
|
||||
ext
|
||||
end
|
||||
|
||||
def file_save_to_local(save_path, temp_file, ext)
|
||||
unless Dir.exists?(save_path)
|
||||
FileUtils.mkdir_p(save_path) ##不成功这里会抛异常
|
||||
end
|
||||
|
||||
digest = md5_file(temp_file)
|
||||
digest = "#{digest}_#{(Time.now.to_f * 1000).to_i}"
|
||||
local_file_path = File.join(save_path, digest) + ext
|
||||
save_temp_file(temp_file, local_file_path)
|
||||
|
||||
[local_file_path, digest]
|
||||
end
|
||||
|
||||
def save_temp_file(temp_file, save_file_path)
|
||||
File.open(save_file_path, 'wb') do |f|
|
||||
temp_file.rewind
|
||||
while (buffer = temp_file.read(8192))
|
||||
f.write(buffer)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def md5_file(temp_file)
|
||||
md5 = Digest::MD5.new
|
||||
temp_file.rewind
|
||||
while (buffer = temp_file.read(8192))
|
||||
md5.update(buffer)
|
||||
end
|
||||
md5.hexdigest
|
||||
end
|
||||
|
||||
def file_save_to_ucloud(path, file, content_type)
|
||||
ufile = Educoder::Ufile.new(
|
||||
ucloud_public_key: edu_setting('public_key'),
|
||||
ucloud_private_key: edu_setting('private_key'),
|
||||
ucloud_public_read: true,
|
||||
ucloud_public_bucket: edu_setting('public_bucket'),
|
||||
ucloud_public_bucket_host: edu_setting('public_bucket_host'),
|
||||
ucloud_public_cdn_host: edu_setting('public_cdn_host'),
|
||||
)
|
||||
File.open(file) do |f|
|
||||
ufile.put(path, f, 'Content-Type' => content_type)
|
||||
end
|
||||
edu_setting('public_cdn_host') + "/" + path
|
||||
end
|
||||
|
||||
def attachment_candown
|
||||
unless current_user.admin? || current_user.business?
|
||||
candown = true
|
||||
unless params[:type] == 'history'
|
||||
if @file.container && current_user.logged?
|
||||
# 课堂资源、作业、毕设相关资源的权限判断
|
||||
if @file.container.is_a?(Course)
|
||||
course = @file.container
|
||||
candown = current_user.member_of_course?(course) || (course.is_public? && @file.publiced?)
|
||||
elsif @file.container.is_a?(HomeworkCommon) || @file.container.is_a?(GraduationTask) || @file.container.is_a?(GraduationTopic)
|
||||
course = @file.container&.course
|
||||
candown = current_user.member_of_course?(course)
|
||||
elsif @file.container.is_a?(StudentWork)
|
||||
course = @file.container&.homework_common&.course
|
||||
candown = current_user.member_of_course?(course)
|
||||
elsif @file.container.is_a?(StudentWorksScore)
|
||||
course = @file.container&.student_work&.homework_common&.course
|
||||
candown = current_user.member_of_course?(course)
|
||||
elsif @file.container.is_a?(GraduationWork)
|
||||
course = @file.container&.graduation_task&.course
|
||||
candown = current_user.member_of_course?(course)
|
||||
elsif @file.container.is_a?(GraduationWorkScore)
|
||||
course = @file.container&.graduation_work&.graduation_task&.course
|
||||
candown = current_user.member_of_course?(course)
|
||||
elsif @file.container.is_a?(Issue)
|
||||
course = @file.container.project
|
||||
candown = course.member?(current_user)
|
||||
elsif @file.container.is_a?(Journal)
|
||||
course = @file.container.issue.project
|
||||
candown = course.member?(current_user)
|
||||
end
|
||||
tip_exception(403, "您没有权限进入") if course.present? && !candown
|
||||
tip_exception(403, "您没有权限进入") if @file.container.is_a?(ApplyUserAuthentication)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def send_file_with_range(path, options = {})
|
||||
logger.info("########request.headers: #{request.headers}")
|
||||
logger.info("########request.headers: #{File.exist?(path)}")
|
||||
|
||||
if File.exist?(path)
|
||||
size = File.size(path)
|
||||
logger.info("########request.headers: #{request.headers}")
|
||||
if !request.headers["Range"]
|
||||
status_code = 200 # 200 OK
|
||||
offset = 0
|
||||
length = File.size(path)
|
||||
else
|
||||
status_code = 206 # 206 Partial Content
|
||||
bytes = Rack::Utils.byte_ranges(request.headers, size)[0]
|
||||
offset = bytes.begin
|
||||
length = bytes.end - bytes.begin
|
||||
end
|
||||
response.header["Accept-Ranges"] = "bytes"
|
||||
response.header["Content-Range"] = "bytes #{bytes.begin}-#{bytes.end}/#{size}" if bytes
|
||||
response.header["status"] = status_code
|
||||
|
||||
send_data IO.binread(path, length, offset), options
|
||||
else
|
||||
raise ActionController::MissingFile, "Cannot read file #{path}."
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
23
app/controllers/bidding_users_controller.rb
Normal file
23
app/controllers/bidding_users_controller.rb
Normal file
@@ -0,0 +1,23 @@
|
||||
class BiddingUsersController < ApplicationController
|
||||
before_action :require_login, :check_auth
|
||||
|
||||
def create
|
||||
ProjectPackages::BiddingService.call(current_package, current_user)
|
||||
render_ok
|
||||
rescue ProjectPackages::BiddingService::Error => ex
|
||||
render_error(ex.message)
|
||||
end
|
||||
|
||||
def win
|
||||
ProjectPackages::WinBiddingService.call(current_package, current_user, params)
|
||||
render_ok
|
||||
rescue ProjectPackages::WinBiddingService::Error => ex
|
||||
render_error(ex.message)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_package
|
||||
@_current_package ||= ProjectPackage.find(params[:project_package_id])
|
||||
end
|
||||
end
|
||||
44
app/controllers/bind_users_controller.rb
Normal file
44
app/controllers/bind_users_controller.rb
Normal file
@@ -0,0 +1,44 @@
|
||||
class BindUsersController < ApplicationController
|
||||
# before_action :require_login
|
||||
|
||||
def create
|
||||
# user = CreateBindUserService.call(create_params)
|
||||
#
|
||||
if params[:type] == "qq"
|
||||
begin
|
||||
user = CreateBindUserService.call(current_user, create_params)
|
||||
successful_authentication(user) if user.id != current_user.id
|
||||
|
||||
render_ok
|
||||
rescue ApplicationService::Error => ex
|
||||
render_error(ex.message)
|
||||
end
|
||||
else
|
||||
begin
|
||||
tip_exception '系统错误' if session[:unionid].blank?
|
||||
|
||||
bind_user = User.try_to_login(params[:username], params[:password])
|
||||
tip_exception '用户名或者密码错误' if bind_user.blank?
|
||||
tip_exception '用户名或者密码错误' unless bind_user.check_password?(params[:password].to_s)
|
||||
tip_exception '该账号已被绑定,请更换其他账号进行绑定' if bind_user.bind_open_user?(params[:type].to_s)
|
||||
|
||||
OpenUsers::Wechat.create!(user: bind_user, uid: session[:unionid])
|
||||
successful_authentication(bind_user)
|
||||
|
||||
render_ok
|
||||
rescue Exception => e
|
||||
render_error(e.message)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def new_user
|
||||
current_user
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def create_params
|
||||
params.permit(:username, :password, :type, :not_bind)
|
||||
end
|
||||
end
|
||||
12
app/controllers/blob_controller.rb
Normal file
12
app/controllers/blob_controller.rb
Normal file
@@ -0,0 +1,12 @@
|
||||
class BlobController < ApplicationController
|
||||
def new
|
||||
commit unless @repository.empty?
|
||||
end
|
||||
|
||||
def create
|
||||
create_commit(Files::CreateService, success_path: after_create_path,
|
||||
failure_view: :new,
|
||||
failure_path: namespace_project_new_blob_path(@project.namespace, @project, @ref))
|
||||
end
|
||||
|
||||
end
|
||||
5
app/controllers/callbacks/base_controller.rb
Normal file
5
app/controllers/callbacks/base_controller.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
class Callbacks::BaseController < ActionController::Base
|
||||
include RenderHelper
|
||||
|
||||
skip_before_action :verify_authenticity_token
|
||||
end
|
||||
342
app/controllers/challenges_controller.rb
Normal file
342
app/controllers/challenges_controller.rb
Normal file
@@ -0,0 +1,342 @@
|
||||
class ChallengesController < ApplicationController
|
||||
before_action :require_login, :check_auth, except: [:index]
|
||||
before_action :find_shixun, only: [:new, :create, :index]
|
||||
skip_before_action :verify_authenticity_token, only: [:create, :update, :create_choose_question, :crud_answer]
|
||||
before_action :find_challenge, only: [:edit, :show, :update, :create_choose_question, :index_down, :index_up,
|
||||
:edit_choose_question, :show_choose_question, :destroy_challenge_choose,
|
||||
:update_choose_question, :destroy, :crud_answer, :answer]
|
||||
# 关卡更新和操作的权限控制
|
||||
before_action :update_allowed, except: [:index]
|
||||
# 关卡访问的权限控制
|
||||
before_action :shixun_access_allowed, only: [:index]
|
||||
|
||||
include ShixunsHelper
|
||||
include ChallengesHelper
|
||||
|
||||
|
||||
|
||||
|
||||
# 新建实践题
|
||||
def new
|
||||
@position = @shixun.challenges.count + 1
|
||||
@st = params[:st].to_i
|
||||
@task_pass_default = PlatformSample.find_by(samples_type: "taskPass").try(:contents)
|
||||
end
|
||||
|
||||
# params
|
||||
# challenge:{"subject": "标题", "task_pass": "过关任务",
|
||||
# "diffculty": "关卡难度", "score": "关卡分数", "st": "关卡类型"} 关卡相关信息
|
||||
# challenge_tag: 关卡标签
|
||||
#
|
||||
def create
|
||||
ActiveRecord::Base.transaction do
|
||||
begin
|
||||
@challenge = Challenge.new(challenge_params)
|
||||
@challenge.position = @shixun.challenges.count + 1
|
||||
@challenge.shixun_id = @shixun.id
|
||||
@challenge.user_id = current_user.id
|
||||
@challenge.modify_time = Time.now
|
||||
@challenge.save!
|
||||
|
||||
# 实训是否需要重置, 非实践任务创建第一个阶段调用, 避免不包含实践任务的实训进行模拟实战报错 todo: 新建实训需要重置TPI
|
||||
# shixun_modify_status_without_publish(@shixun, 1) if @challenge.position != 1
|
||||
|
||||
tags = params[:challenge_tag]
|
||||
if tags.present?
|
||||
tags.each do |tag|
|
||||
# TODO 创建tag的时候为什么一直报challenge choose必须存在??
|
||||
ChallengeTag.create!(name: tag, challenge_id: @challenge.id)
|
||||
end
|
||||
end
|
||||
rescue Exception => e
|
||||
uid_logger_error("create challenge failed #{e}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# 创建选择题
|
||||
def create_choose_question
|
||||
ActiveRecord::Base.transaction do
|
||||
begin
|
||||
@challenge_choose = ChallengeChoose.new(chooce_params)
|
||||
@challenge_choose.position = @challenge.challenge_chooses.count + 1
|
||||
@challenge_choose.category = @challenge_choose.standard_answer.length == 1 ? 1 : 2
|
||||
@challenge_choose.challenge_id = @challenge.id
|
||||
|
||||
if @challenge_choose.save!
|
||||
# 创建选项
|
||||
params[:question][:cnt].each_with_index do |test, index|
|
||||
answer = params[:choice][:answer][index]
|
||||
ChallengeQuestion.create(:option_name => test,
|
||||
:challenge_choose_id => @challenge_choose.id,
|
||||
:position => index, :right_key => answer)
|
||||
end
|
||||
# 创建单选多选的技能标签
|
||||
if params[:challenge_tag].present?
|
||||
params[:challenge_tag].each do |tag|
|
||||
ChallengeTag.create(:name => tag, :challenge_choose_id => @challenge_choose.id, :challenge_id => @challenge.id)
|
||||
end
|
||||
end
|
||||
@challenge.update_column(:score, @challenge.challenge_chooses.sum(:score))
|
||||
end
|
||||
rescue Exception => e
|
||||
raise ActiveRecord::Rollback
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# 选择题详情页面
|
||||
def show_choose_question
|
||||
@challenge_choose = ChallengeChoose.find params[:choose_id]
|
||||
|
||||
end
|
||||
|
||||
# 选择题更新页面
|
||||
def update_choose_question
|
||||
@challenge_choose = ChallengeChoose.find(params[:choose_id])
|
||||
ActiveRecord::Base.transaction do
|
||||
if params[:standard_answer] != @challenge_choose.standard_answer
|
||||
@challenge.update_column(:modify_time, Time.now)
|
||||
end
|
||||
@challenge_choose.update_attributes(chooce_params)
|
||||
@challenge.update_column(:score, @challenge.challenge_chooses.sum(:score))
|
||||
# 单选多选题的更新
|
||||
category = @challenge_choose.standard_answer.length > 1 ? 2 : 1
|
||||
@challenge_choose.update_column(:category, category)
|
||||
begin
|
||||
@challenge_choose.challenge_questions.delete_all
|
||||
params[:question][:cnt].each_with_index do |test, index|
|
||||
answer = params[:choice][:answer][index]
|
||||
ChallengeQuestion.create(:option_name => test, :challenge_choose_id => @challenge_choose.id, :position => index, :right_key => answer)
|
||||
end
|
||||
@challenge_choose.challenge_tags.delete_all unless @challenge_choose.challenge_tags.blank?
|
||||
if params[:challenge_tag].present?
|
||||
params[:challenge_tag].each do |tag|
|
||||
ChallengeTag.create(:name => tag, :challenge_choose_id => @challenge_choose.id, :challenge_id => @challenge.id)
|
||||
end
|
||||
end
|
||||
@challenge_choose = ChallengeChoose.find params[:choose_id]
|
||||
rescue Exception => e
|
||||
raise ActiveRecord::Rollback
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# 选择题的编辑
|
||||
def edit_choose_question
|
||||
@challenge_choose = ChallengeChoose.find params[:choose_id]
|
||||
end
|
||||
|
||||
def destroy_challenge_choose
|
||||
ActiveRecord::Base.transaction do
|
||||
@challenge_choose = ChallengeChoose.where(:id => params[:choose_id]).first
|
||||
pos = @challenge_choose.position
|
||||
@challenge.challenge_chooses.where("position > ?", pos).update_all("position = position - 1")
|
||||
@challenge_choose.destroy
|
||||
@status = 1
|
||||
# 发起重置请求 TODO: 重置实训需要后续做
|
||||
# shixun_modify_status_without_publish(@shixun, 1)
|
||||
end
|
||||
end
|
||||
|
||||
# 编辑模式
|
||||
# tab 0,nil 过关任务, 1 评测设置, 2 参考答案
|
||||
def edit
|
||||
@tab = params[:tab].to_i
|
||||
@power = @shixun.status == 0
|
||||
challenge_num = Challenge.where(:shixun_id => @shixun).count
|
||||
@position = @challenge.position
|
||||
@chooses = @challenge.challenge_chooses
|
||||
if @position < challenge_num
|
||||
@next_challenge = Challenge.where(:shixun_id => @shixun, :position => @position + 1).first
|
||||
end
|
||||
@prev_challenge = Challenge.where(:shixun_id => @shixun, :position => @position - 1).first if @position - 1 > 0
|
||||
end
|
||||
|
||||
def index
|
||||
uid_logger("identifier: #{params}")
|
||||
|
||||
@challenges = @shixun.challenges.fields_for_list
|
||||
|
||||
@editable = @shixun.status == 0 # before_action:有判断权限,如果没发布,则肯定是管理人员
|
||||
@user = current_user
|
||||
@shixun.increment!(:visits)
|
||||
end
|
||||
|
||||
|
||||
|
||||
def show
|
||||
@tab = params[:tab].nil? ? 1 : params[:tab].to_i
|
||||
challenge_num = @shixun.challenges_count
|
||||
@power = @shixun.status == 0 # 之前验证走过了是不是管理员,因此这里只用判断是否发布
|
||||
@position = @challenge.position
|
||||
if @position < challenge_num
|
||||
@next_challenge = Challenge.where(:shixun_id => @shixun, :position => @position + 1).first
|
||||
end
|
||||
@prev_challenge = Challenge.where(:shixun_id => @shixun, :position => @position - 1).first if @position - 1 > 0
|
||||
end
|
||||
|
||||
# tab 0:过关任务的更新; 1:评测设置的更新; 2:表示参考答案的更新;
|
||||
def update
|
||||
begin
|
||||
ActiveRecord::Base.transaction do
|
||||
tab = params[:tab].to_i
|
||||
@challenge.update_attributes!(challenge_params)
|
||||
if tab == 0 && @challenge.st == 0
|
||||
@challenge.challenge_tags.delete_all
|
||||
if params[:challenge_tag].present?
|
||||
params[:challenge_tag].each do |input|
|
||||
ChallengeTag.create!(:name => input, :challenge_id => @challenge.id)
|
||||
end
|
||||
end
|
||||
elsif tab == 1
|
||||
path = @challenge.path
|
||||
exec_path = @challenge.exec_path
|
||||
test_set = @challenge.test_sets
|
||||
sets_output = test_set.map(&:output)
|
||||
sets_input = test_set.map(&:input)
|
||||
sets_open = test_set.map(&:is_public)
|
||||
set_score = test_set.map(&:score)
|
||||
set_match_rule = test_set.map(&:match_rule)
|
||||
params_hidden = params[:test_set].map{|set| set[:hidden].to_i == 0}
|
||||
params_output = params[:test_set].map{|set| set[:output] }
|
||||
params_input = params[:test_set].map{|set| set[:input] }
|
||||
params_score = params[:test_set].map{|set| set[:score]}
|
||||
params_test_set = params[:test_set].map{|set| set[:match_rule]}
|
||||
# 测试集变化则需要更新(输入、 输出、 是否隐藏)
|
||||
if sets_output != params_output || sets_open != params_hidden || sets_input != params_input ||
|
||||
set_score != params_score || params_test_set != set_match_rule
|
||||
test_set.delete_all unless test_set.blank?
|
||||
params[:test_set].each_with_index do |set, index|
|
||||
# last: 末尾匹配, full: 全完匹配
|
||||
logger.info("set: #{set}; match_rule : #{set[:match_rule]}")
|
||||
match_rule = set[:match_rule] == 'last' ? 'last' : 'full'
|
||||
TestSet.create!(:challenge_id => @challenge.id,
|
||||
:input => "#{set[:input]}",
|
||||
:output => "#{set[:output]}",
|
||||
:is_public => params_hidden[index],
|
||||
:score => set[:score],
|
||||
:match_rule => "#{match_rule}",
|
||||
:position => (index + 1))
|
||||
end
|
||||
@challenge.update_column(:modify_time, Time.now)
|
||||
# 测试集的
|
||||
@shixun.myshixuns.update_all(:system_tip => 0)
|
||||
end
|
||||
if params[:challenge][:show_type].to_i == -1
|
||||
@challenge.update_attributes(picture_path: nil, web_route: nil, expect_picture_path: nil, original_picture_path: nil)
|
||||
end
|
||||
# 关卡评测执行文件如果被修改,需要修改脚本内容
|
||||
logger.info("############shixun_publiced:#{@shixun.public == 0}")
|
||||
if @shixun.public == 0
|
||||
script = modify_shixun_script @shixun, @shixun.evaluate_script
|
||||
@shixun.shixun_info.update_column(:evaluate_script, script)
|
||||
end
|
||||
# TODO:
|
||||
# if path != params[:challenge][:path]
|
||||
# shixun_modify_status_without_publish(@shixun, 1)
|
||||
# end
|
||||
#Attachment.attach_files(@challenge, params[:attachments])
|
||||
end
|
||||
|
||||
end
|
||||
rescue Exception => e
|
||||
logger.error("##update_challenges: ##{e.message}")
|
||||
tip_exception("#{e.message}")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# 参考答案的'增,删,改'
|
||||
# POST: /shixuns/:id/challenges/:id/crud_answer
|
||||
# {'challenge_answer': [
|
||||
# {'name': 'name', contents: 'contents', score: 10},
|
||||
# {...},
|
||||
# {...}, ...]
|
||||
#}
|
||||
def crud_answer
|
||||
if @challenge.challenge_answers && params[:challenge_answer].blank?
|
||||
@challenge.challenge_answers.destroy_all
|
||||
else
|
||||
raise '参考答案不能为空' if params[:challenge_answer].empty?
|
||||
raise '占比之和必须为100%' if params[:challenge_answer].map{|a| a[:score]}.sum != 100
|
||||
ActiveRecord::Base.transaction do
|
||||
@challenge.challenge_answers.destroy_all if @challenge.challenge_answers
|
||||
params[:challenge_answer].each_with_index do |answer, index|
|
||||
# 内容为空不保存
|
||||
next if answer[:contents].blank?
|
||||
ChallengeAnswer.create!(name: answer[:name], contents: answer[:contents],
|
||||
level: index+1, score: answer[:score], challenge_id: @challenge.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# 查看参考答案接口
|
||||
def answer
|
||||
@answers = @challenge.challenge_answers
|
||||
end
|
||||
|
||||
def index_down
|
||||
next_challenge = @challenge.next_challenge
|
||||
position = @challenge.position
|
||||
@challenge.update_attribute(:position, (position + 1))
|
||||
next_challenge.update_attribute(:position, next_challenge.position - 1)
|
||||
# 关卡位置被修改,需要修改脚本
|
||||
script = modify_shixun_script @shixun, @shixun.evaluate_script
|
||||
@shixun.shixun_info.update_column(:evaluate_script, script)
|
||||
end
|
||||
|
||||
def index_up
|
||||
position = @challenge.position
|
||||
last_challenge = @challenge.last_challenge
|
||||
@challenge.update_attribute(:position, (position - 1))
|
||||
last_challenge.update_attribute(:position, last_challenge.position + 1)
|
||||
# 关卡位置被修改,需要修改脚本
|
||||
script = modify_shixun_script @shixun, @shixun.evaluate_script
|
||||
@shixun.shixun_info.update_column(:evaluate_script, script)
|
||||
end
|
||||
|
||||
def destroy
|
||||
next_challenges = @shixun.challenges.where("position > #{@challenge.position}")
|
||||
next_challenges.update_all("position = position - 1")
|
||||
# Todo: 实训修改后,关卡需要重置
|
||||
# shixun_modify_status_without_publish(@shixun, 1)
|
||||
@challenge.destroy
|
||||
# 关卡位置被删除,需要修改脚本
|
||||
script = modify_shixun_script @shixun, @shixun.evaluate_script
|
||||
@shixun.shixun_info.update_column(:evaluate_script, script)
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
def find_shixun
|
||||
@shixun = Shixun.find_by_identifier(params[:shixun_identifier])
|
||||
end
|
||||
|
||||
# 通用接口
|
||||
def find_challenge
|
||||
@challenge = Challenge.find params[:id]
|
||||
@shixun = Shixun.find_by!(identifier: params[:shixun_identifier])
|
||||
end
|
||||
|
||||
def challenge_params
|
||||
tip_exception("评测时间不能超过300秒") if params[:challenge][:exec_time].to_i > 300
|
||||
params.require(:challenge).permit(:subject, :task_pass, :difficulty, :score, :st, :modify_time, :test_set_average,
|
||||
:path, :exec_path, :show_type, :original_picture_path, :test_set_score,
|
||||
:expect_picture_path, :picture_path, :web_route, :answer, :exec_time)
|
||||
end
|
||||
|
||||
def chooce_params
|
||||
params.require(:challenge_choose).permit(:subject, :answer,
|
||||
:standard_answer, :score, :difficult)
|
||||
end
|
||||
|
||||
def update_allowed
|
||||
unless current_user.manager_of_shixun?(@shixun)
|
||||
raise Educoder::TipException.new(403, "..")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
75
app/controllers/comments_controller.rb
Normal file
75
app/controllers/comments_controller.rb
Normal file
@@ -0,0 +1,75 @@
|
||||
class CommentsController < ApplicationController
|
||||
before_action :find_hack
|
||||
before_action :require_login
|
||||
|
||||
|
||||
# 评论
|
||||
def create
|
||||
begin
|
||||
@discuss = @hack.discusses.new(comment_params) # 管理员回复的能够显示
|
||||
@discuss.hidden = false
|
||||
@discuss.user_id = current_user.id
|
||||
@discuss.save!
|
||||
rescue Exception => e
|
||||
uid_logger_error("create discuss failed : #{e.message}")
|
||||
render_error("评论异常")
|
||||
end
|
||||
end
|
||||
|
||||
# 回复
|
||||
def reply
|
||||
begin
|
||||
@discuss = @hack.discusses.new(reply_params)
|
||||
@discuss.hidden = false
|
||||
@discuss.user_id = current_user.id
|
||||
@discuss.root_id = params[:comments][:parent_id]
|
||||
@discuss.save!
|
||||
rescue Exception => e
|
||||
uid_logger_error("reply discuss failed : #{e.message}")
|
||||
render_error("回复评论异常")
|
||||
end
|
||||
end
|
||||
|
||||
# 列表
|
||||
def index
|
||||
discusses =
|
||||
if current_user.admin_or_business?
|
||||
@hack.discusses.where(root_id: nil)
|
||||
else
|
||||
@hack.discusses.where(root_id: nil, hidden: false)
|
||||
end
|
||||
@discusses_count = discusses.count
|
||||
@discusses= paginate discusses
|
||||
end
|
||||
|
||||
# 删除
|
||||
def destroy
|
||||
@hack.discusses.find_by(id: params[:id]).destroy
|
||||
render_ok
|
||||
end
|
||||
|
||||
# 隐藏、取消隐藏
|
||||
def hidden
|
||||
if current_user.admin_or_business?
|
||||
@discuss = @hack.discusses.where(id: params[:id]).first
|
||||
@discuss.update_attribute(:hidden, params[:hidden].to_i == 1)
|
||||
sucess_status
|
||||
else
|
||||
Educoder::TipException(403, "..")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
def find_hack
|
||||
@hack = Hack.find_by_identifier(params[:hack_identifier])
|
||||
end
|
||||
|
||||
def comment_params
|
||||
params.require(:comments).permit(:content)
|
||||
end
|
||||
|
||||
def reply_params
|
||||
params.require(:comments).permit(:content, :parent_id)
|
||||
end
|
||||
end
|
||||
76
app/controllers/commons_controller.rb
Normal file
76
app/controllers/commons_controller.rb
Normal file
@@ -0,0 +1,76 @@
|
||||
class CommonsController < ApplicationController
|
||||
OBJECT_TYPE = %W[message journals_for_message]
|
||||
|
||||
before_action :require_login, :check_auth
|
||||
before_action :validate_object_type
|
||||
before_action :find_object
|
||||
before_action :validate_power
|
||||
|
||||
def delete
|
||||
begin
|
||||
@object.destroy!
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
tip_exception(e.message)
|
||||
raise ActiveRecord::Rollback
|
||||
end
|
||||
end
|
||||
|
||||
def hidden
|
||||
action(true)
|
||||
end
|
||||
|
||||
def unhidden
|
||||
action(false)
|
||||
end
|
||||
|
||||
private
|
||||
def find_object
|
||||
begin
|
||||
@object = params[:object_type].strip.classify.constantize.find params[:object_id]
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
tip_exception(e.message)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
def validate_object_type
|
||||
return normal_status(2, "缺少object_id参数") if params[:object_id].blank?
|
||||
return normal_status(2, "缺少object_type参数") if params[:object_type].blank?
|
||||
return normal_status(2, "object_type参数格式错误") unless OBJECT_TYPE.include? params[:object_type].strip
|
||||
end
|
||||
|
||||
def validate_power
|
||||
code =
|
||||
case params[:object_type].strip
|
||||
when 'message'
|
||||
if current_user.course_identity(@object.board.course) >= Course::STUDENT && @object.author != current_user
|
||||
403
|
||||
else
|
||||
200
|
||||
end
|
||||
when 'journals_for_message'
|
||||
course = @object&.jour_type.to_s == "StudentWorksScore" ? @object.jour&.student_work&.homework_common&.course : @object.jour&.course
|
||||
if current_user.course_identity(course) >= Course::STUDENT && @object.user != current_user
|
||||
403
|
||||
else
|
||||
200
|
||||
end
|
||||
else
|
||||
current_user.admin_or_business? ? 200 : 403
|
||||
end
|
||||
return normal_status(code, "你没有权限操作!") if code == 403
|
||||
end
|
||||
|
||||
def action(flag)
|
||||
begin
|
||||
@object.has_attribute?(:is_hidden) ? @object.update_attributes(:is_hidden => flag )
|
||||
: @object.update_attributes(:hidden => flag )
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
tip_exception(e.message)
|
||||
raise ActiveRecord::Rollback
|
||||
end
|
||||
end
|
||||
end
|
||||
38
app/controllers/compose_projects_controller.rb
Normal file
38
app/controllers/compose_projects_controller.rb
Normal file
@@ -0,0 +1,38 @@
|
||||
class ComposeProjectsController < ApplicationController
|
||||
#未做完
|
||||
before_action :require_login
|
||||
before_action :set_compose
|
||||
|
||||
def create
|
||||
project_ids = params[:project_ids]
|
||||
ComposeProject.transaction do
|
||||
project_ids.each do |p|
|
||||
project = Project.select(:id, :user_id).find(p)
|
||||
unless project.blank? || ComposeProject.exists?(user_id: project.user_id, project_id: p, compose_id: @compose.id)
|
||||
ComposeProject.create!(user_id: project.user_id, project_id: p, compose_id: @compose.id, position: p)
|
||||
end
|
||||
end
|
||||
end
|
||||
normal_status(0, "添加成功")
|
||||
end
|
||||
|
||||
def destroy
|
||||
project_ids = params[:project_ids]
|
||||
if ComposeProject.where(project_id: project_ids, compose_id: @compose.id).delete_all
|
||||
normal_status(0, "项目删除成功")
|
||||
else
|
||||
normal_status(-1, "项目删除失败")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
def set_compose
|
||||
@compose = Compose.find(params[:compose_id])
|
||||
unless @compose.present?
|
||||
normal_status(-1, "组织不存在")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
99
app/controllers/composes_controller.rb
Normal file
99
app/controllers/composes_controller.rb
Normal file
@@ -0,0 +1,99 @@
|
||||
class ComposesController < ApplicationController
|
||||
before_action :require_login, except: [:index]
|
||||
before_action :find_compose, except: [:index, :new,:create]
|
||||
|
||||
def index
|
||||
@order_type = params[:order] || "created_at"
|
||||
@search_name = params[:search]
|
||||
composes = Compose.compose_includes
|
||||
if @search_name.present?
|
||||
composes = composes.where("title like ?", "%#{@search_name}%")
|
||||
end
|
||||
composes = composes.order("#{@order_type} desc")
|
||||
@page = params[:page] || 1
|
||||
@limit = params[:limit] || 15
|
||||
@composes_size = composes.size
|
||||
@composes = composes.page(@page).per(@limit)
|
||||
end
|
||||
|
||||
def new
|
||||
|
||||
end
|
||||
|
||||
def create
|
||||
ActiveRecord::Base.transaction do
|
||||
begin
|
||||
@compose = Compose.new(compose_params.merge(user_id: current_user.id))
|
||||
if @compose.save
|
||||
ComposeUser.create!(user_id: current_user.id, compose_id: @compose.id, is_manager: 1)
|
||||
normal_status(0,"组织创建成功")
|
||||
else
|
||||
error_messages = @compose.errors.messages[:title][0]
|
||||
normal_status(-1,"组织创建失败:#{error_messages}")
|
||||
end
|
||||
rescue Exception => e
|
||||
tip_exception("#{e}")
|
||||
raise ActiveRecord::Rollback
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
|
||||
end
|
||||
|
||||
def update
|
||||
if @compose.update_attributes(compose_params)
|
||||
normal_status(0,"组织更新成功")
|
||||
else
|
||||
error_messages = @compose.errors.messages[:title][0]
|
||||
normal_status(-1,"组织更新失败:#{error_messages}")
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
if @compose.destroy
|
||||
normal_status(0,"组织删除成功")
|
||||
else
|
||||
normal_status(-1,"组织删除失败,请稍后重试")
|
||||
end
|
||||
end
|
||||
|
||||
def show
|
||||
compose_projects_ids = @compose&.compose_projects&.pluck(:project_id)
|
||||
search = params[:search]
|
||||
if compose_projects_ids.size > 0
|
||||
compose_projects = Project.where(id: compose_projects_ids)
|
||||
|
||||
if search.present?
|
||||
compose_projects = compose_projects.where("name like ? ", "%#{search.to_s.strip}%")
|
||||
end
|
||||
else
|
||||
compose_projects = []
|
||||
end
|
||||
|
||||
@compose_projects_size = compose_projects.size
|
||||
|
||||
if @compose_projects_size > 0
|
||||
@page = params[:page] || 1
|
||||
@limit = params[:limit] || 15
|
||||
@compose_projects = compose_projects.page(@page).per(@limit)
|
||||
else
|
||||
@compose_projects = compose_projects
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def compose_params
|
||||
params.require(:compose).permit(:user_id, :title, :description, :show_mode, :compose_mode, :compose_users_count, :compose_projects_count)
|
||||
end
|
||||
|
||||
def find_compose
|
||||
@compose = Compose.find(params[:compose_id])
|
||||
unless @compose.present?
|
||||
normal_status(-1, "组织不存在")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
0
app/controllers/concerns/.keep
Normal file
0
app/controllers/concerns/.keep
Normal file
18
app/controllers/concerns/admins/render_helper.rb
Normal file
18
app/controllers/concerns/admins/render_helper.rb
Normal file
@@ -0,0 +1,18 @@
|
||||
module Admins::RenderHelper
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
include Base::RenderHelper
|
||||
|
||||
def render_delete_success
|
||||
render_js_template 'admins/shared/delete'
|
||||
end
|
||||
alias_method :render_success_js, :render_delete_success
|
||||
|
||||
def render_js_error(message, type: :alert)
|
||||
if type == :notify
|
||||
render js: "$.notify({ message: '#{message}' },{ type: 'danger', delay: 5000 });"
|
||||
else
|
||||
render_js_template 'admins/shared/error', locals: { message: message }
|
||||
end
|
||||
end
|
||||
end
|
||||
25
app/controllers/concerns/base/error_rescue_handler.rb
Normal file
25
app/controllers/concerns/base/error_rescue_handler.rb
Normal file
@@ -0,0 +1,25 @@
|
||||
module Base::ErrorRescueHandler
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
rescue_from Exception do |e|
|
||||
raise e if Rails.env.development?
|
||||
|
||||
Util.logger_error e
|
||||
internal_server_error
|
||||
end
|
||||
|
||||
rescue_from ActionView::MissingTemplate, ActiveRecord::RecordNotFound, with: :render_not_found
|
||||
rescue_from ActionController::ParameterMissing do
|
||||
render_unprocessable_entity('参数缺失')
|
||||
end
|
||||
# form validation error
|
||||
rescue_from ActiveModel::ValidationError do |ex|
|
||||
render_unprocessable_entity(ex.model.errors.full_messages.join(','))
|
||||
end
|
||||
rescue_from ActiveRecord::RecordInvalid do |ex|
|
||||
ex.backtrace.each { |msg| Rails.logger.error(msg) }
|
||||
render_unprocessable_entity(ex.record.errors.full_messages.join(','))
|
||||
end
|
||||
end
|
||||
end
|
||||
29
app/controllers/concerns/base/paginate_helper.rb
Normal file
29
app/controllers/concerns/base/paginate_helper.rb
Normal file
@@ -0,0 +1,29 @@
|
||||
module Base::PaginateHelper
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
def default_sort(sort_by, direction)
|
||||
params[:sort_by] = params[:sort_by].presence || sort_by
|
||||
params[:sort_direction] = params[:sort_direction].presence || direction
|
||||
end
|
||||
|
||||
def offset
|
||||
(page - 1) * per_page
|
||||
end
|
||||
|
||||
def page
|
||||
params[:page].to_i <= 0 ? 1 : params[:page].to_i
|
||||
end
|
||||
|
||||
def per_page
|
||||
params[:per_page].to_i <= 0 || params[:per_page].to_i > 100 ? 20 : params[:per_page].to_i
|
||||
end
|
||||
alias_method :limit, :per_page
|
||||
|
||||
def paginate(relations, total_count: nil)
|
||||
if relations.is_a?(Array)
|
||||
Kaminari.paginate_array(relations, limit: limit, offset: offset, total_count: total_count)
|
||||
else
|
||||
relations.page(page).per(per_page)
|
||||
end
|
||||
end
|
||||
end
|
||||
38
app/controllers/concerns/base/render_helper.rb
Normal file
38
app/controllers/concerns/base/render_helper.rb
Normal file
@@ -0,0 +1,38 @@
|
||||
module Base::RenderHelper
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
def render_by_format(hash)
|
||||
format = request.format.symbol
|
||||
hash.key?(format) ? hash[format].call : hash[:html].call
|
||||
end
|
||||
|
||||
def render_forbidden
|
||||
render_by_format(html: -> { current_user&.business? ? render('shared/403') : redirect_to('/403') },
|
||||
js: -> { render_js_error(I18n.t('error.forbidden'), type: :notify) },
|
||||
json: -> { render status: 403, json: { messages: I18n.t('error.forbidden') } } )
|
||||
end
|
||||
|
||||
def render_not_found
|
||||
render_by_format(html: -> { render 'shared/404' },
|
||||
js: -> { render_js_error('资源未找到') },
|
||||
json: -> { render status: 404, json: { message: '资源未找到' } })
|
||||
end
|
||||
|
||||
def render_unprocessable_entity(message, type: :alert)
|
||||
render_by_format(html: -> { render 'shared/422' },
|
||||
js: -> { render_js_error(message, type: type) },
|
||||
json: -> { render status: 422, json: { message: message } })
|
||||
end
|
||||
alias_method :render_error, :render_unprocessable_entity
|
||||
|
||||
def internal_server_error(message = '系统错误')
|
||||
@message = message
|
||||
render_by_format(html: -> { render 'shared/500' },
|
||||
js: -> { render_js_error(message) },
|
||||
json: -> { render status: 500, json: { message: message } })
|
||||
end
|
||||
|
||||
def render_js_template(template, **opts)
|
||||
render({ template: template, formats: :js }.merge(opts))
|
||||
end
|
||||
end
|
||||
137
app/controllers/concerns/code_example.rb
Normal file
137
app/controllers/concerns/code_example.rb
Normal file
@@ -0,0 +1,137 @@
|
||||
module CodeExample
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
#老师C语言的标准代码
|
||||
def c_stantard_code_teacher
|
||||
"// 老师您好!这是一个C语言的样例程序
|
||||
// 程序功能:输入两个整数,输出两者之和
|
||||
// 测试集合:老师可以给出多组测试集,例如:
|
||||
// 输入1和2,输出3
|
||||
// 输入3和4,输出7
|
||||
// ... ...
|
||||
// 系统将根据您给出的测试集对学生代码进行自动评分
|
||||
|
||||
// 特别提醒:程序采用命令行传参方式,输入通过argv传入
|
||||
// 否则您的作业标准代码将不能通过测试
|
||||
|
||||
#include <stdio.h> //引用必须头文件
|
||||
int main(int argc, char** argv) {
|
||||
int a = atoi(argv[1]); //将第一个输入转成整型
|
||||
int b = atoi(argv[2]); //将第二个输入转换为整型
|
||||
|
||||
printf(\"%d\",a+b); //输出a+b
|
||||
return 0;
|
||||
}".html_safe
|
||||
end
|
||||
|
||||
#老师C++语言的标准代码
|
||||
def c_stantard_code_teacher_
|
||||
"// 老师您好!这是一个C++语言的样例程序
|
||||
// 程序功能:输入两个整数,输出两者之和
|
||||
// 测试集合:老师可以给出多组测试集,例如:
|
||||
// 输入1和2,输出3
|
||||
// 输入3和4,输出7
|
||||
// ... ...
|
||||
// 系统将根据您给出的测试集对学生代码进行自动评分
|
||||
|
||||
// 特别提醒:程序采用命令行传参方式,输入通过argv传入
|
||||
// 否则您的作业标准代码将不能通过测试
|
||||
|
||||
#include <iostream> //引用必须头文件
|
||||
#include <cstdlib>
|
||||
using namespace std;
|
||||
int main(int argc, char** argv){
|
||||
int a = atoi(argv[1]); //将第一个输入转成整型
|
||||
int b = atoi(argv[2]); //将第二个输入转换为整型
|
||||
cout<<a+b; //输出a+b
|
||||
return 0;
|
||||
}".html_safe
|
||||
end
|
||||
|
||||
#学生C语言的标准代码
|
||||
def c_stantard_code_student
|
||||
"// 同学好!这是一个C语言的样例程序
|
||||
// 程序功能:输入两个整数,输出两者之和
|
||||
// 测试集合:老师可以给出多组测试集,例如:
|
||||
// 输入1和2,输出3
|
||||
// 输入3和4,输出7
|
||||
// ... ...
|
||||
// 系统将根据您给出的测试集对学生代码进行自动评分
|
||||
|
||||
// 特别提醒:程序采用命令行传参方式,输入通过argv传入
|
||||
// 否则您的作业标准代码将不能通过测试
|
||||
|
||||
#include <stdio.h> //引用必须头文件
|
||||
int main(int argc, char** argv) {
|
||||
int a = atoi(argv[1]); //将第一个输入转成整型
|
||||
int b = atoi(argv[2]); //将第二个输入转换为整型
|
||||
|
||||
printf(\"%d\",a+b); //输出a+b
|
||||
return 0;
|
||||
}".html_safe
|
||||
end
|
||||
|
||||
#学生C++语言的标准代码
|
||||
def c_stantard_code_student_
|
||||
"// 同学好!这是一个C++语言的样例程序
|
||||
// 程序功能:输入两个整数,输出两者之和
|
||||
// 测试集合:老师可以给出多组测试集,例如:
|
||||
// 输入1和2,输出3
|
||||
// 输入3和4,输出7
|
||||
// ... ...
|
||||
// 系统将根据您给出的测试集对学生代码进行自动评分
|
||||
|
||||
// 特别提醒:程序采用命令行传参方式,输入通过argv传入
|
||||
// 否则您的作业标准代码将不能通过测试
|
||||
|
||||
#include <iostream> //引用必须头文件
|
||||
#include <cstdlib>
|
||||
using namespace std;
|
||||
int main(int argc, char** argv){
|
||||
int a = atoi(argv[1]); //将第一个输入转成整型
|
||||
int b = atoi(argv[2]); //将第二个输入转换为整型
|
||||
cout<<a+b; //输出a+b
|
||||
return 0;
|
||||
}".html_safe
|
||||
end
|
||||
|
||||
def compile_command
|
||||
"compile(){
|
||||
# 编译命令
|
||||
compileCommand=\"COMPILECOMMAND\"
|
||||
# 取当前关卡的编译文件
|
||||
challengeProgramName=${challengeProgramNames[$1 - 1]}
|
||||
# 获取编译结果(此处编译无输出则说明编译通过,否则输出编译错误信息,请按实训实际情况调整)
|
||||
compileResult=$($compileCommand $challengeProgramName 2>&1 | base64)
|
||||
if [ -z \"$compileResult\" ]; then
|
||||
compileResult=$(echo -n \"compile successfully\" | base64)
|
||||
fi
|
||||
|
||||
}
|
||||
compile $1"
|
||||
end
|
||||
|
||||
def execute_command
|
||||
"execute(){
|
||||
#执行命令
|
||||
executeCommand=\"EXECUTECOMMAND\"
|
||||
#执行文件名
|
||||
sourceClassName=${sourceClassNames[$1 - 1]}
|
||||
challengeStage=$1
|
||||
|
||||
output=''
|
||||
i=0
|
||||
while [[ i -lt ${#ins[*]} ]]; do
|
||||
#执行,并拼接执行结果
|
||||
result=$(echo \"${ins[$i]}\" | base64 -d | $executeCommand $sourceClassName 2>&1 | base64)
|
||||
#拼接输出结果
|
||||
output=$output\\\"$result\\\",
|
||||
let i++
|
||||
done
|
||||
output=\"[${output%?}]\"
|
||||
}
|
||||
|
||||
execute $1
|
||||
"
|
||||
end
|
||||
end
|
||||
40
app/controllers/concerns/controller_rescue_handler.rb
Normal file
40
app/controllers/concerns/controller_rescue_handler.rb
Normal file
@@ -0,0 +1,40 @@
|
||||
module ControllerRescueHandler
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
rescue_from Exception do |e|
|
||||
Util.logger_error e
|
||||
render json: {status: -1, message: e.message}
|
||||
end
|
||||
rescue_from ActiveRecord::StatementInvalid do |e|
|
||||
Util.logger_error e
|
||||
render json: {status: -1, message: "接口数据异常"}
|
||||
end
|
||||
rescue_from NoMethodError do |e|
|
||||
Util.logger_error e
|
||||
render json: {status: -1, message: "接口方法异常"}
|
||||
end
|
||||
|
||||
rescue_from ActionController::UnknownFormat do |e|
|
||||
render json: {status: -1, message: "接口调用非JSON格式"}
|
||||
end
|
||||
# rescue_from ActionView::MissingTemplate, with: :object_not_found
|
||||
# rescue_from ActiveRecord::RecordNotFound, with: :object_not_found
|
||||
rescue_from Educoder::TipException, with: :tip_show
|
||||
rescue_from ::ActionView::MissingTemplate, with: :missing_template
|
||||
rescue_from ActiveRecord::RecordNotFound, with: :object_not_found
|
||||
rescue_from ActionController::ParameterMissing, with: :render_parameter_missing
|
||||
|
||||
# form validation error
|
||||
rescue_from ActiveModel::ValidationError do |ex|
|
||||
render_error(ex.model.errors.full_messages.join(','))
|
||||
end
|
||||
rescue_from ActiveRecord::RecordInvalid do |ex|
|
||||
render_error(ex.record.errors.full_messages.join(','))
|
||||
end
|
||||
# rescue_from RuntimeError do |ex|
|
||||
# Util.logger_error "#######ex:#{ex}"
|
||||
# render_error(ex.message)
|
||||
# end
|
||||
end
|
||||
end
|
||||
16
app/controllers/concerns/cooperative/render_helper.rb
Normal file
16
app/controllers/concerns/cooperative/render_helper.rb
Normal file
@@ -0,0 +1,16 @@
|
||||
module Cooperative::RenderHelper
|
||||
include Base::RenderHelper
|
||||
|
||||
def render_delete_success
|
||||
render_js_template 'cooperative/shared/delete'
|
||||
end
|
||||
alias_method :render_success_js, :render_delete_success
|
||||
|
||||
def render_js_error(message, type: :alert)
|
||||
if type == :notify
|
||||
render js: "$.notify({ message: '#{message}' },{ type: 'danger', delay: 5000 });"
|
||||
else
|
||||
render_js_template 'cooperative/shared/error', locals: { message: message }
|
||||
end
|
||||
end
|
||||
end
|
||||
59
app/controllers/concerns/git_common.rb
Normal file
59
app/controllers/concerns/git_common.rb
Normal file
@@ -0,0 +1,59 @@
|
||||
module GitCommon
|
||||
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
|
||||
end
|
||||
|
||||
|
||||
# ------------------------
|
||||
# 版本库目录结构
|
||||
def repository
|
||||
begin
|
||||
@repo_url = repo_url @repo_path
|
||||
@trees = GitService.file_tree(repo_path: @repo_path, path: @path)
|
||||
logger.info("#11@@#@#@#@111#@@@@###{@trees}")
|
||||
|
||||
# TPI(学员实训)不需要获取最近的一次提交
|
||||
if params[:controller] != "myshixuns" && @trees
|
||||
logger.info("#@@#@#@#@#@@@@###{@trees.try(:count)}")
|
||||
@latest_commit = [GitService.commits(repo_path: @repo_path).first]
|
||||
Rails.logger.info("########## #{@latest_commit}")
|
||||
end
|
||||
rescue Exception => e
|
||||
logger.error(e.message)
|
||||
end
|
||||
end
|
||||
|
||||
def file_content
|
||||
@content = git_fle_content @repo_path, @path
|
||||
end
|
||||
|
||||
# 版本库提交记录
|
||||
# Redo: commit接口需要按倒叙排列
|
||||
def commits
|
||||
begin
|
||||
@commits = GitService.commits(repo_path: @repo_path)
|
||||
logger.info("git first commit is #{@commits.try(:first)}")
|
||||
raise Educoder::TipException.new("请先创建版本库") if @commits.nil?
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
raise Educoder::TipException.new("提交记录异常")
|
||||
end
|
||||
end
|
||||
|
||||
# 为版本库添加文件
|
||||
def add_file
|
||||
@path, message, content = params[:path].strip, params[:message], params[:content]
|
||||
author_name, author_email = current_user.real_name, current_user.git_mail
|
||||
Rails.logger.info(" good repo_name is #{@repo_path}")
|
||||
@content = GitService.update_file(repo_path: @repo_path,
|
||||
file_path: @path,
|
||||
message: message.force_encoding('UTF-8'),
|
||||
content: content.force_encoding('UTF-8'),
|
||||
author_name: author_name,
|
||||
author_email: author_email)
|
||||
end
|
||||
|
||||
end
|
||||
80
app/controllers/concerns/git_helper.rb
Normal file
80
app/controllers/concerns/git_helper.rb
Normal file
@@ -0,0 +1,80 @@
|
||||
module GitHelper
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
# 版本库目录空间
|
||||
def repo_namespace(user_login, shixun_identifier)
|
||||
"#{user_login}/#{shixun_identifier}.git"
|
||||
end
|
||||
|
||||
# 版本库文件内容,带转码
|
||||
def git_fle_content(repo_path, path)
|
||||
begin
|
||||
Rails.logger.info("git file content: repo_path is #{repo_path}, path is #{path}")
|
||||
|
||||
content = GitService.file_content(repo_path: repo_path, path: path)
|
||||
|
||||
Rails.logger.info("git file content: content is #{content}")
|
||||
decode_content = nil
|
||||
if content.present?
|
||||
content = content["content"] #6.24 -hs 这个为新增,因为当实训题里含有选择题时,这里会报错,undefined method `[]' for nil:NilClass
|
||||
|
||||
content = Base64.decode64(content)
|
||||
cd = CharDet.detect(content)
|
||||
Rails.logger.info "encoding: #{cd['encoding']} confidence: #{cd['confidence']}"
|
||||
# 字符编码问题,GB18030编码识别率不行
|
||||
decode_content =
|
||||
if cd["encoding"] == 'GB18030' && cd['confidence'] > 0.8
|
||||
content.encode('UTF-8', 'GBK', {:invalid => :replace, :undef => :replace, :replace => ' '})
|
||||
else
|
||||
content.force_encoding('UTF-8')
|
||||
end
|
||||
end
|
||||
|
||||
decode_content
|
||||
|
||||
rescue Exception => e
|
||||
Rails.logger.error(e.message)
|
||||
raise Educoder::TipException.new("文档内容获取异常")
|
||||
end
|
||||
end
|
||||
|
||||
# 更新文件代码
|
||||
# content: 文件内容;message:提交描述
|
||||
def update_file_content(content, repo_path, path, mail, username, message)
|
||||
#content = Base64.encode64(content)
|
||||
GitService.update_file(repo_path: repo_path, file_path: path, message: message,
|
||||
content: content, author_name: username, author_email: mail)
|
||||
end
|
||||
|
||||
def update_file_base64_content(content, repo_path, path, mail, username, message)
|
||||
content = Base64.encode64(content)
|
||||
GitService.update_file_base64(repo_path: repo_path, file_path: path, message: message,
|
||||
content: content, author_name: username, author_email: mail)
|
||||
end
|
||||
|
||||
# 添加目录
|
||||
def git_add_folder(folder_path, author_name, author_email, message)
|
||||
GitService.add_tree(file_path: folder_path, message: message, author_name: author_name, author_email: author_email)
|
||||
end
|
||||
|
||||
# 删除文件
|
||||
def git_delete_file(file_path, author_name, author_email, message)
|
||||
GitService.delete_file(file_path: file_path, message: message, author_name: author_name, author_email: author_email)
|
||||
end
|
||||
|
||||
# 版本库Fork功能
|
||||
def project_fork(container, original_rep_path, username)
|
||||
raise Educoder::TipException.new("fork源路径为空,fork失败!") if original_rep_path.blank?
|
||||
# 将要生成的仓库名字
|
||||
new_repo_name = "#{username.try(:strip)}/#{container.try(:identifier)}#{ Time.now.strftime("%Y%m%d%H%M%S")}"
|
||||
# uid_logger("start fork container: repo_name is #{new_repo_name}")
|
||||
GitService.fork_repository(repo_path: original_rep_path, fork_repository_path: (new_repo_name + ".git"))
|
||||
container.update_attributes!(:repo_name => new_repo_name)
|
||||
end
|
||||
|
||||
#实训题的关卡url初始化
|
||||
def challenge_path(path)
|
||||
cha_path = path.present? ? path.split(";") : []
|
||||
cha_path.reject(&:blank?)[0].try(:strip)
|
||||
end
|
||||
end
|
||||
32
app/controllers/concerns/laboratory_helper.rb
Normal file
32
app/controllers/concerns/laboratory_helper.rb
Normal file
@@ -0,0 +1,32 @@
|
||||
module LaboratoryHelper
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
before_action :setup_laboratory
|
||||
|
||||
helper_method :current_laboratory
|
||||
helper_method :default_setting
|
||||
helper_method :default_yun_session
|
||||
end
|
||||
|
||||
def current_laboratory
|
||||
@_current_laboratory ||= (Laboratory.find_by_subdomain(request.subdomain) || Laboratory.find(1))
|
||||
end
|
||||
|
||||
def default_laboratory
|
||||
@_default_laboratory ||= Laboratory.find(1)
|
||||
end
|
||||
|
||||
def default_setting
|
||||
@_default_setting ||= LaboratorySetting.find_by(laboratory_id: 1)
|
||||
end
|
||||
|
||||
def setup_laboratory
|
||||
Laboratory.current = current_laboratory
|
||||
end
|
||||
|
||||
def default_yun_session
|
||||
laboratory ||= (Laboratory.find_by_subdomain(request.subdomain) || Laboratory.find(1))
|
||||
@_default_yun_session = "#{laboratory.try(:identifier).split('.').first}_user_id"
|
||||
end
|
||||
end
|
||||
22
app/controllers/concerns/logger_helper.rb
Normal file
22
app/controllers/concerns/logger_helper.rb
Normal file
@@ -0,0 +1,22 @@
|
||||
module LoggerHelper
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
extend LoggerHelper
|
||||
|
||||
|
||||
# 以用户id开始的日志定义
|
||||
def uid_logger(message)
|
||||
Rails.logger.info("##:#{current_user.try(:id)} --#{message}")
|
||||
end
|
||||
|
||||
# debug日志
|
||||
def uid_logger_dubug(message)
|
||||
Rails.logger.info("##dubug-#{current_user.try(:id)} --#{message}")
|
||||
|
||||
end
|
||||
|
||||
# 以用户id开始的日志定义
|
||||
def uid_logger_error(message)
|
||||
Rails.logger.error("##:#{current_user.try(:id)} --#{message}")
|
||||
end
|
||||
end
|
||||
85
app/controllers/concerns/login_helper.rb
Normal file
85
app/controllers/concerns/login_helper.rb
Normal file
@@ -0,0 +1,85 @@
|
||||
module LoginHelper
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
def edu_setting(name)
|
||||
EduSetting.get(name)
|
||||
end
|
||||
|
||||
def autologin_cookie_name
|
||||
edu_setting('autologin_cookie_name').presence || 'autologin'
|
||||
end
|
||||
|
||||
def set_autologin_cookie(user)
|
||||
token = Token.get_or_create_permanent_login_token(user, "autologin")
|
||||
cookie_options = {
|
||||
:value => token.value,
|
||||
:expires => 1.month.from_now,
|
||||
:path => '/',
|
||||
:secure => false,
|
||||
:httponly => false
|
||||
}
|
||||
if edu_setting('cookie_domain').present?
|
||||
cookie_options = cookie_options.merge(domain: edu_setting('cookie_domain'))
|
||||
end
|
||||
cookies[autologin_cookie_name] = cookie_options
|
||||
Rails.logger.info("cookies is #{cookies}")
|
||||
end
|
||||
|
||||
def successful_authentication(user)
|
||||
Rails.logger.info("id: #{user&.id} Successful authentication start: '#{user.login}' from #{request.remote_ip} at #{Time.now.utc}")
|
||||
# Valid user
|
||||
self.logged_user = user
|
||||
session[:"#{default_yun_session}"] = user.id
|
||||
# generate a key and set cookie if autologin
|
||||
set_autologin_cookie(user)
|
||||
|
||||
UserAction.create(action_id: user&.id, action_type: 'Login', user_id: user&.id, ip: request.remote_ip)
|
||||
user.update_column(:last_login_on, Time.now)
|
||||
# 注册完成后有一天的试用申请(先去掉)
|
||||
# UserDayCertification.create(user_id: user.id, status: 1)
|
||||
end
|
||||
|
||||
def logout_user
|
||||
if User.current.logged?
|
||||
if autologin = cookies.delete(autologin_cookie_name)
|
||||
User.current.delete_autologin_token(autologin)
|
||||
end
|
||||
User.current.delete_session_token(session[:tk])
|
||||
self.logged_user = nil
|
||||
end
|
||||
# 云上实验室退出清理当前session
|
||||
laboratory ||= (Laboratory.find_by_subdomain(request.subdomain) || Laboratory.find(1))
|
||||
default_yun_session = "#{laboratory.try(:identifier).split('.').first}_user_id"
|
||||
# end
|
||||
session[:"#{default_yun_session}"] = nil
|
||||
end
|
||||
|
||||
# Sets the logged in user
|
||||
def logged_user=(user)
|
||||
# reset_session
|
||||
if user && user.is_a?(User)
|
||||
User.current = user
|
||||
start_user_session(user)
|
||||
else
|
||||
User.current = User.anonymous
|
||||
end
|
||||
end
|
||||
|
||||
def start_user_session(user)
|
||||
# re_subdomain = "#{request.subdomain.split('.').first}_user_id"
|
||||
# session[:"#{request.subdomain}_user_id"] = user.id
|
||||
# Rails.logger.info("domain_user_id session is: 3333332222111#{session[:"#{request.subdomain}_user_id"]}")
|
||||
# Rails.logger.info("user_id session is: 3333332222111#{session[:"#{request.subdomain}_user_id"]}")
|
||||
#
|
||||
# # if current_laboratory.main_site?
|
||||
# # session[:user_id] = user.id
|
||||
# # else
|
||||
# # session[:"#{request.subdomain}_user_id"] = user.id
|
||||
# # end
|
||||
|
||||
# session[:user_id] = user.id
|
||||
session[:"#{default_yun_session}"] = user.id
|
||||
session[:ctime] = Time.now.utc.to_i
|
||||
session[:atime] = Time.now.utc.to_i
|
||||
end
|
||||
end
|
||||
12
app/controllers/concerns/operate_project_ability_able.rb
Normal file
12
app/controllers/concerns/operate_project_ability_able.rb
Normal file
@@ -0,0 +1,12 @@
|
||||
module OperateProjectAbilityAble
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
end
|
||||
|
||||
def authorizate_user_can_edit_project!
|
||||
return if current_user.project_manager? @project || current_user.admin?
|
||||
render_forbidden('你没有权限操作.')
|
||||
end
|
||||
|
||||
end
|
||||
12
app/controllers/concerns/paginate_helper.rb
Normal file
12
app/controllers/concerns/paginate_helper.rb
Normal file
@@ -0,0 +1,12 @@
|
||||
module PaginateHelper
|
||||
def paginate(objs, **opts)
|
||||
page = params[:page].to_i <= 0 ? 1 : params[:page].to_i
|
||||
per_page = params[:per_page].to_i > 0 && params[:per_page].to_i < 50 ? params[:per_page].to_i : opts[:per_page] || 20
|
||||
|
||||
if objs.is_a?(Array)
|
||||
Kaminari.paginate_array(objs).page(page).per(per_page)
|
||||
else
|
||||
objs.page(page).per(per_page)
|
||||
end
|
||||
end
|
||||
end
|
||||
40
app/controllers/concerns/render_expand.rb
Normal file
40
app/controllers/concerns/render_expand.rb
Normal file
@@ -0,0 +1,40 @@
|
||||
module RenderExpand
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
ActionController.add_renderer :pdf do |template, options|
|
||||
file = File.open(Rails.root.join('app/templates', template << '.html.erb'))
|
||||
html = ERB.new(file.read).result(binding)
|
||||
kit = PDFKit.new(html)
|
||||
|
||||
base_css = %w(app/templates/shared/main.css)
|
||||
base_css.each { |css| kit.stylesheets << Rails.root.join(css) }
|
||||
|
||||
Array.wrap(options.delete(:stylesheets)).each do |path|
|
||||
kit.stylesheets << Rails.root.join('app/templates', path)
|
||||
end
|
||||
|
||||
send_data kit.to_pdf, filename: options[:filename], disposition: options[:disposition] || 'attachment', type: 'application/pdf'
|
||||
end
|
||||
|
||||
|
||||
ActionController.add_renderer :exam_pdf do |template, options|
|
||||
file = File.open(Rails.root.join('app/templates', template << '.html.erb'))
|
||||
html = ERB.new(file.read).result(binding)
|
||||
kit = PDFKit.new(html)
|
||||
|
||||
# PDFKit初始化后再添加样式文件到stylesheets,会出现在页面的<!DOCTYPE>定义不起作用,文档模式为默认为BackCompat,从而导致katex不起作用
|
||||
# 而测试发现通过配置添加css样式文件不会有影响
|
||||
PDFKit.configure do |config|
|
||||
config.default_options = {
|
||||
:"user-style-sheet" => Rails.root.join('app/templates', options[:stylesheets])
|
||||
}
|
||||
end
|
||||
|
||||
send_data kit.to_pdf, filename: options[:filename], disposition: options[:disposition] || 'attachment', type: 'application/pdf'
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
end
|
||||
31
app/controllers/concerns/render_helper.rb
Normal file
31
app/controllers/concerns/render_helper.rb
Normal file
@@ -0,0 +1,31 @@
|
||||
module RenderHelper
|
||||
def render_ok(data = {})
|
||||
render json: { status: 0, message: 'success' }.merge(data)
|
||||
end
|
||||
|
||||
def render_error(message = '')
|
||||
render json: { status: -1, message: message }
|
||||
end
|
||||
|
||||
def render_not_acceptable(message = '请求已拒绝')
|
||||
render json: { status: 406, message: message }
|
||||
end
|
||||
|
||||
def render_not_found(message = I18n.t('error.record_not_found'))
|
||||
render json: { status: 404, message: message }
|
||||
# render status: 404, json: { errors: errors }
|
||||
end
|
||||
|
||||
def render_forbidden(message = I18n.t('error.forbidden'))
|
||||
render json: { status: 403, message: message }
|
||||
# render status: 403, json: { errors: errors }
|
||||
end
|
||||
|
||||
def render_unauthorized(message = I18n.t('error.unauthorized'))
|
||||
render json: { status: 401, message: message }
|
||||
end
|
||||
|
||||
def render_result(status=1, message='success')
|
||||
render json: { status: status, message: message }
|
||||
end
|
||||
end
|
||||
37
app/controllers/contents_controller.rb
Normal file
37
app/controllers/contents_controller.rb
Normal file
@@ -0,0 +1,37 @@
|
||||
class ContentsController < ApplicationController
|
||||
before_action :find_user, :find_repository
|
||||
before_action :require_login, only: %i[create update_file delete_file]
|
||||
|
||||
def create
|
||||
interactor = Gitea::CreateFileInteractor.call(current_user, content_params)
|
||||
if interactor.success?
|
||||
@file = interactor.result
|
||||
else
|
||||
render_error(interactor.error)
|
||||
end
|
||||
end
|
||||
|
||||
def update_file
|
||||
interactor = Gitea::UpdateFileInteractor.call(current_user, params)
|
||||
if interactor.success?
|
||||
@file = interactor.result
|
||||
else
|
||||
render_error(interactor.error)
|
||||
end
|
||||
end
|
||||
|
||||
def delete_file
|
||||
interactor = Gitea::DeleteFileInteractor.call(current_user, params)
|
||||
if interactor.success?
|
||||
@file = interactor.result
|
||||
else
|
||||
render_error(interactor.error)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def content_params
|
||||
params.permit(:login, :repo_identifier, :filepath, :branch, :content, :message, :new_branch)
|
||||
end
|
||||
|
||||
end
|
||||
73
app/controllers/course_groups_controller.rb
Normal file
73
app/controllers/course_groups_controller.rb
Normal file
@@ -0,0 +1,73 @@
|
||||
class CourseGroupsController < ApplicationController
|
||||
before_action :require_login, :check_auth
|
||||
before_action :set_group, except: [:create]
|
||||
before_action :find_course, only: [:create]
|
||||
before_action :teacher_allowed, except: [:set_invite_code_halt]
|
||||
|
||||
def create
|
||||
tip_exception("分班名称不能为空") if params[:name].blank?
|
||||
if @course.course_groups.where(name: params[:name]).count > 0
|
||||
normal_status(-1, "已存在同名分班")
|
||||
else
|
||||
course_group = @course.course_groups.create!(name: params[:name], position: @course.course_groups.count + 1)
|
||||
render :json => {group_id: course_group.id, status: 0, message: "创建成功"}
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
ActiveRecord::Base.transaction do
|
||||
begin
|
||||
@course.course_groups.where("position > #{@group.position}").update_all("position = position - 1")
|
||||
# 将该分班的学生转到未分班
|
||||
@group.course_members.update_all(course_group_id: 0)
|
||||
@group.destroy
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
tip_exception("删除分班失败")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# 分班重命名
|
||||
def rename_group
|
||||
tip_exception("名称不能为空") if params[:name].blank?
|
||||
if @course.course_groups.where(name: params[:name]).count > 0
|
||||
normal_status(-1, "已存在同名分班")
|
||||
else
|
||||
@group.update_attributes(name: params[:name].strip)
|
||||
normal_status(0, "更新成功")
|
||||
end
|
||||
end
|
||||
|
||||
# 分班的拖动
|
||||
def move_category
|
||||
tip_exception("移动失败") if params[:position].blank?
|
||||
unless params[:position].to_i == @group.position
|
||||
if params[:position].to_i < @group.position
|
||||
@course.course_groups.where("position < #{@group.position} and position >= ?", params[:position]).update_all("position = position + 1")
|
||||
else
|
||||
@course.course_groups.where("position > #{@group.position} and position <= ?", params[:position]).update_all("position = position - 1")
|
||||
end
|
||||
@group.update_attributes(position: params[:position])
|
||||
normal_status(0, "移动成功")
|
||||
else
|
||||
normal_status(-1, "位置没有变化")
|
||||
end
|
||||
end
|
||||
|
||||
# 邀请码停用/启用
|
||||
def set_invite_code_halt
|
||||
teacher = @course.teachers.find_by(user_id: current_user.id)
|
||||
tip_exception(403, "无权限") unless current_user.admin_or_business? ||
|
||||
(teacher.present? && (teacher.teacher_course_groups.pluck(:course_group_id).include?(@group.id) || teacher.teacher_course_groups.size == 0))
|
||||
@group.update!(invite_code_halt: !@group.invite_code_halt)
|
||||
normal_status(0, "成功")
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_group
|
||||
@group = CourseGroup.find_by!(id: params[:id])
|
||||
@course = @group.course
|
||||
end
|
||||
end
|
||||
68
app/controllers/course_modules_controller.rb
Normal file
68
app/controllers/course_modules_controller.rb
Normal file
@@ -0,0 +1,68 @@
|
||||
class CourseModulesController < ApplicationController
|
||||
before_action :require_login, :check_auth
|
||||
before_action :set_module, except: [:unhidden_modules]
|
||||
before_action :find_course, only: [:unhidden_modules]
|
||||
before_action :teacher_or_admin_allowed, except: [:add_second_category]
|
||||
before_action :teacher_allowed, only: [:add_second_category]
|
||||
|
||||
# 模块置顶
|
||||
def sticky_module
|
||||
# position为1则不做处理,否则该模块的position置为1,position小于当前模块的position加1
|
||||
unless @course_module.position == 1
|
||||
@course.course_modules.where("position < #{@course_module.position}").update_all("position = position + 1")
|
||||
@course_module.update_attributes(position: 1)
|
||||
end
|
||||
normal_status(0, "置顶成功")
|
||||
end
|
||||
|
||||
# 模块隐藏
|
||||
def hidden_module
|
||||
tip_exception("请至少保留一个课堂模块") if @course.none_hidden_course_modules.where.not(id: @course_module.id).size == 0
|
||||
@course_module.update_attributes(hidden: 1)
|
||||
normal_status(0, "更新成功")
|
||||
end
|
||||
|
||||
# 模块重命名
|
||||
def rename_module
|
||||
name = params[:name].strip
|
||||
tip_exception("名称不能为空") if name.blank?
|
||||
tip_exception("已存在同名模块") if @course.course_modules.exists?(module_name: name)
|
||||
@course_module.update_attributes(module_name: name)
|
||||
|
||||
case @course_module.module_type
|
||||
when 'board'
|
||||
@course.course_board.update_columns(name: name)
|
||||
end
|
||||
normal_status(0, "更新成功")
|
||||
end
|
||||
|
||||
# 模块的显示
|
||||
def unhidden_modules
|
||||
tip_exception("请选择要显示的模块") if params[:module_ids].blank?
|
||||
@course.course_modules.where(id: params[:module_ids]).update_all(hidden: 0)
|
||||
normal_status(0, "更新成功")
|
||||
end
|
||||
|
||||
# 添加二级目录
|
||||
def add_second_category
|
||||
tip_exception("子目录名称不能为空") if params[:name].blank?
|
||||
tip_exception("已存在同名子目录") if @course_module.course_second_categories.exists?(name: params[:name].strip)
|
||||
ActiveRecord::Base.transaction do
|
||||
begin
|
||||
category = @course_module.course_second_categories.create!(name: params[:name].strip, category_type: @course_module.module_type,
|
||||
course_id: @course.id, position: @course_module.course_second_categories.count + 1)
|
||||
render :json => {category_id: category.id, status: 0, message: "添加成功"}
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
tip_exception("添加子目录失败")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_module
|
||||
@course_module = CourseModule.find_by!(id: params[:id])
|
||||
@course = @course_module.course
|
||||
end
|
||||
end
|
||||
60
app/controllers/course_second_categories_controller.rb
Normal file
60
app/controllers/course_second_categories_controller.rb
Normal file
@@ -0,0 +1,60 @@
|
||||
class CourseSecondCategoriesController < ApplicationController
|
||||
before_action :require_login, :check_auth
|
||||
before_action :set_category
|
||||
before_action :teacher_allowed
|
||||
|
||||
# 目录重命名
|
||||
def rename_category
|
||||
tip_exception("毕设子目录不能重命名") if @category.category_type == "graduation"
|
||||
tip_exception("名称不能为空") if params[:name].blank?
|
||||
tip_exception("已存在同名子目录") if @course_module.course_second_categories.exists?(name: params[:name].strip)
|
||||
@category.update_attributes!(name: params[:name].strip)
|
||||
normal_status(0, "更新成功")
|
||||
end
|
||||
|
||||
# 子目录的拖动
|
||||
def move_category
|
||||
tip_exception("移动失败") if params[:position].blank?
|
||||
unless params[:position].to_i == @category.position
|
||||
if params[:position].to_i < @category.position
|
||||
@course_module.course_second_categories.where("position < #{@category.position} and position >= ?", params[:position]).update_all("position = position + 1")
|
||||
else
|
||||
@course_module.course_second_categories.where("position > #{@category.position} and position <= ?", params[:position]).update_all("position = position - 1")
|
||||
end
|
||||
@category.update!(position: params[:position])
|
||||
normal_status(0, "移动成功")
|
||||
else
|
||||
normal_status(-1, "位置没有变化")
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
tip_exception("毕设子目录不能删除") if @category.category_type == "graduation"
|
||||
ActiveRecord::Base.transaction do
|
||||
begin
|
||||
@course_module.course_second_categories.where("position > #{@category.position}").update_all("position = position - 1")
|
||||
# 更新相应对象的子目录id
|
||||
if @course_module.module_type == "shixun_homework"
|
||||
@category.homework_commons.update_all(course_second_category_id: 0)
|
||||
@right_url = "/courses/#{@course.id}/shixun_homeworks/#{@course_module.id}"
|
||||
elsif @course_module.module_type == "attachment"
|
||||
Attachment.where(course_second_category_id: @category.id).update_all(course_second_category_id: 0)
|
||||
@right_url = "/courses/#{@course.id}/files/#{@course_module.id}"
|
||||
end
|
||||
|
||||
@category.destroy
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
tip_exception("删除子目录失败")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_category
|
||||
@category = CourseSecondCategory.find_by!(id: params[:id])
|
||||
@course_module = @category.course_module
|
||||
@course = @course_module.try(:course)
|
||||
end
|
||||
end
|
||||
1675
app/controllers/courses_controller.rb
Normal file
1675
app/controllers/courses_controller.rb
Normal file
File diff suppressed because it is too large
Load Diff
13
app/controllers/departments_controller.rb
Normal file
13
app/controllers/departments_controller.rb
Normal file
@@ -0,0 +1,13 @@
|
||||
class DepartmentsController < ApplicationController
|
||||
skip_before_action :check_sign
|
||||
|
||||
def for_option
|
||||
render_ok(departments: current_school.departments.without_deleted.select(:id, :name).as_json)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_school
|
||||
@_current_school ||= School.find(params[:id])
|
||||
end
|
||||
end
|
||||
6
app/controllers/disciplines_controller.rb
Normal file
6
app/controllers/disciplines_controller.rb
Normal file
@@ -0,0 +1,6 @@
|
||||
class DisciplinesController < ApplicationController
|
||||
|
||||
def index
|
||||
|
||||
end
|
||||
end
|
||||
29
app/controllers/edu_datas_controller.rb
Normal file
29
app/controllers/edu_datas_controller.rb
Normal file
@@ -0,0 +1,29 @@
|
||||
class EduDatasController < ApplicationController
|
||||
before_action :find_game
|
||||
skip_before_action :user_setup
|
||||
skip_before_action :setup_laboratory
|
||||
# layout :false
|
||||
include GitHelper
|
||||
|
||||
# params[:game_id]
|
||||
def game
|
||||
@shixun = @challenge.shixun
|
||||
@shixun_env = @shixun.mirror_name
|
||||
@shixun_tags = @challenge.challenge_tags.map(&:name)
|
||||
end
|
||||
|
||||
def code_lines
|
||||
path = @challenge.path
|
||||
myshixun = @game.myshixun
|
||||
# content = git_fle_content(myshixun.repo_path, path) || ""
|
||||
@content = {"content":"#coding=utf-8\n\n#请在此处添加代码完成输出“Hello Python”,注意要区分大小写!\n###### Begin ######\n\n\n\n###### End ######\n\n"}
|
||||
@content[:content].include?("Begin")
|
||||
end
|
||||
|
||||
private
|
||||
def find_game
|
||||
game_id = params[:game_id]
|
||||
@game = Game.find(game_id)
|
||||
@challenge = @game.challenge
|
||||
end
|
||||
end
|
||||
75
app/controllers/edu_settings_controller.rb
Normal file
75
app/controllers/edu_settings_controller.rb
Normal file
@@ -0,0 +1,75 @@
|
||||
class EduSettingsController < ApplicationController
|
||||
before_action :require_admin
|
||||
before_action :set_edu_setting, only: [:show, :edit, :update, :destroy]
|
||||
skip_before_action :check_sign
|
||||
# GET /edu_settings
|
||||
# GET /edu_settings.json
|
||||
def index
|
||||
@edu_settings = EduSetting.all
|
||||
end
|
||||
|
||||
# GET /edu_settings/1
|
||||
# GET /edu_settings/1.json
|
||||
def show
|
||||
end
|
||||
|
||||
# GET /edu_settings/new
|
||||
def new
|
||||
@edu_setting = EduSetting.new
|
||||
end
|
||||
|
||||
# GET /edu_settings/1/edit
|
||||
def edit
|
||||
end
|
||||
|
||||
# POST /edu_settings
|
||||
# POST /edu_settings.json
|
||||
def create
|
||||
@edu_setting = EduSetting.new(edu_setting_params)
|
||||
|
||||
respond_to do |format|
|
||||
if @edu_setting.save
|
||||
format.html { redirect_to @edu_setting, notice: 'Edu setting was successfully created.' }
|
||||
format.json { render :show, status: :created, location: @edu_setting }
|
||||
else
|
||||
format.html { render :new }
|
||||
format.json { render json: @edu_setting.errors, status: :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# PATCH/PUT /edu_settings/1
|
||||
# PATCH/PUT /edu_settings/1.json
|
||||
def update
|
||||
respond_to do |format|
|
||||
if @edu_setting.update(edu_setting_params)
|
||||
format.html { redirect_to @edu_setting, notice: 'Edu setting was successfully updated.' }
|
||||
format.json { render :show, status: :ok, location: @edu_setting }
|
||||
else
|
||||
format.html { render :edit }
|
||||
format.json { render json: @edu_setting.errors, status: :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# DELETE /edu_settings/1
|
||||
# DELETE /edu_settings/1.json
|
||||
def destroy
|
||||
@edu_setting.destroy
|
||||
respond_to do |format|
|
||||
format.html { redirect_to edu_settings_url, notice: 'Edu setting was successfully destroyed.' }
|
||||
format.json { head :no_content }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
# Use callbacks to share common setup or constraints between actions.
|
||||
def set_edu_setting
|
||||
@edu_setting = EduSetting.find(params[:id])
|
||||
end
|
||||
|
||||
# Never trust parameters from the scary internet, only allow the white list through.
|
||||
def edu_setting_params
|
||||
params.require(:edu_setting).permit(:name, :value)
|
||||
end
|
||||
end
|
||||
92
app/controllers/examination_banks_controller.rb
Normal file
92
app/controllers/examination_banks_controller.rb
Normal file
@@ -0,0 +1,92 @@
|
||||
class ExaminationBanksController < ApplicationController
|
||||
include PaginateHelper
|
||||
before_action :require_login
|
||||
before_action :certi_identity_auth, only: [:create, :edit, :update, :destroy, :set_public, :revoke_item]
|
||||
before_action :find_exam, except: [:index, :create]
|
||||
before_action :edit_auth, only: [:update, :destroy, :set_public, :revoke_item]
|
||||
before_action :identity_auth, only: [:index]
|
||||
|
||||
def index
|
||||
exams = ExaminationBankQuery.call(params)
|
||||
@exams_count = exams.size
|
||||
@exams = paginate exams.includes(:user, :examination_items)
|
||||
end
|
||||
|
||||
def show
|
||||
@items = @exam.examination_items
|
||||
@single_questions = @items.where(item_type: "SINGLE")
|
||||
@multiple_questions = @items.where(item_type: "MULTIPLE")
|
||||
@judgement_questions = @items.where(item_type: "JUDGMENT")
|
||||
@program_questions = @items.where(item_type: "PROGRAM")
|
||||
end
|
||||
|
||||
def create
|
||||
ActiveRecord::Base.transaction do
|
||||
exam = ExaminationBank.new(user: current_user)
|
||||
# 保存试卷基础信息
|
||||
exam = ExaminationBanks::SaveExaminationBankService.call(exam, form_params)
|
||||
|
||||
# 将试题篮中的试题发送到试卷,试卷的题目与试题独立
|
||||
current_user.item_baskets.includes(:item_bank).each do |basket|
|
||||
item = basket.item_bank
|
||||
if item.present?
|
||||
new_item = ExaminationItem.new
|
||||
new_item.new_item(item, exam, basket.score, basket.position)
|
||||
end
|
||||
end
|
||||
|
||||
current_user.item_baskets.destroy_all
|
||||
end
|
||||
render_ok
|
||||
rescue ApplicationService::Error => ex
|
||||
render_error(ex.message)
|
||||
end
|
||||
|
||||
def edit; end
|
||||
|
||||
def update
|
||||
ExaminationBanks::SaveExaminationBankService.call(@exam, form_params)
|
||||
render_ok
|
||||
rescue ApplicationService::Error => ex
|
||||
render_error(ex.message)
|
||||
end
|
||||
|
||||
def destroy
|
||||
ActiveRecord::Base.transaction do
|
||||
ApplyAction.where(container_type: "ExaminationBank", container_id: @exam.id).destroy_all
|
||||
@exam.destroy!
|
||||
render_ok
|
||||
end
|
||||
end
|
||||
|
||||
def set_public
|
||||
tip_exception(-1, "该试卷已公开") if @exam.public?
|
||||
tip_exception(-1, "请勿重复提交申请") if ApplyAction.where(container_id: @exam.id, container_type: "ExaminationBank", status: 0).exists?
|
||||
ApplyAction.create!(container_id: @exam.id, container_type: "ExaminationBank", user_id: current_user.id)
|
||||
# @exam.update_attributes!(public: 1)
|
||||
render_ok
|
||||
end
|
||||
|
||||
def revoke_item
|
||||
item = @exam.examination_items.find_by!(item_bank_id: params[:item_id])
|
||||
ActiveRecord::Base.transaction do
|
||||
@exam.examination_items.where(item_type: item.item_type).where("position > #{item.position}").update_all("position = position -1")
|
||||
item.destroy!
|
||||
end
|
||||
render_ok
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def form_params
|
||||
params.permit(:discipline_id, :sub_discipline_id, :difficulty, :name, :duration, tag_discipline_id: [])
|
||||
end
|
||||
|
||||
def find_exam
|
||||
@exam = ExaminationBank.find_by!(id: params[:id])
|
||||
end
|
||||
|
||||
def edit_auth
|
||||
current_user.admin_or_business? || @exam.user == current_user
|
||||
end
|
||||
end
|
||||
108
app/controllers/examination_intelligent_settings_controller.rb
Normal file
108
app/controllers/examination_intelligent_settings_controller.rb
Normal file
@@ -0,0 +1,108 @@
|
||||
class ExaminationIntelligentSettingsController < ApplicationController
|
||||
before_action :require_login
|
||||
before_action :certi_identity_auth, only: [:create, :optinal_items, :save_exam, :exchange_one_item, :exchange_items]
|
||||
before_action :find_exam, only: [:exchange_one_item, :exchange_items, :save_exam]
|
||||
|
||||
def optinal_items
|
||||
sub_discipline_id = params[:sub_discipline_id]
|
||||
tag_discipline_id = params[:tag_discipline_id]
|
||||
difficulty = params[:difficulty]
|
||||
source = params[:source]
|
||||
|
||||
items = OptionalItemQuery.call(sub_discipline_id, tag_discipline_id, difficulty, source)
|
||||
@single_question_count = items.select{ |item| item.item_type == "SINGLE" }.size
|
||||
@multiple_question_count = items.select{ |item| item.item_type == "MULTIPLE" }.size
|
||||
@judgement_question_count = items.select{ |item| item.item_type == "JUDGMENT" }.size
|
||||
@program_question_count = items.select{ |item| item.item_type == "PROGRAM" }.size
|
||||
end
|
||||
|
||||
def create
|
||||
ActiveRecord::Base.transaction do
|
||||
exam = ExaminationIntelligentSetting.new(user: current_user)
|
||||
# 保存试卷基础信息
|
||||
exam = ExaminationIntelligentSettings::SaveSettingService.call(exam, form_params)
|
||||
render_ok({exam_setting_id: exam.id})
|
||||
end
|
||||
rescue ApplicationService::Error => ex
|
||||
render_error(ex.message)
|
||||
end
|
||||
|
||||
def save_exam
|
||||
new_exam = ExaminationBank.new(user: current_user)
|
||||
# 保存试卷基础信息
|
||||
ExaminationIntelligentSettings::SaveExaminationService.call(new_exam, save_params, @exam)
|
||||
render_ok
|
||||
rescue ApplicationService::Error => ex
|
||||
render_error(ex.message)
|
||||
end
|
||||
|
||||
def exchange_one_item
|
||||
item = @exam.item_baskets.find_by!(item_bank_id: params[:item_id])
|
||||
exam_type_setting = @exam.examination_type_settings.find_by!(item_type: item.item_type)
|
||||
|
||||
# 获取可选的题
|
||||
items = OptionalItemQuery.call(@exam.sub_discipline_id, @exam.tag_discipline_containers.pluck(:tag_discipline_id), @exam.difficulty, @exam.public)
|
||||
|
||||
# 可选题中去掉已组卷的试题
|
||||
type_items = items.select{ |t_item| t_item.item_type == item.item_type }
|
||||
optional_item_ids = (type_items.pluck(:id) - @exam.item_baskets.where(item_type: item.item_type).pluck(:item_bank_id)).uniq
|
||||
|
||||
# 如果可选的题数等于0则提示无可换的题
|
||||
tip_exception("无可换的题") if optional_item_ids.size == 0
|
||||
|
||||
new_item = ItemBank.find optional_item_ids.sample(1).first
|
||||
ActiveRecord::Base.transaction do
|
||||
@exam.item_baskets << ItemBasket.new(item_bank_id: new_item.id, position: item.position, score: item.score, item_type: new_item.item_type)
|
||||
item.destroy!
|
||||
end
|
||||
render_ok
|
||||
end
|
||||
|
||||
def exchange_items
|
||||
exam_type_setting = @exam.examination_type_settings.find_by!(item_type: params[:item_type])
|
||||
choosed_items = @exam.item_baskets.where(item_type: params[:item_type])
|
||||
|
||||
# 获取可选的题
|
||||
items = OptionalItemQuery.call(@exam.sub_discipline_id, @exam.tag_discipline_containers.pluck(:tag_discipline_id), @exam.difficulty, @exam.public)
|
||||
type_items = items.select{ |t_item| t_item.item_type == params[:item_type] }
|
||||
|
||||
# 可选题中去掉已组卷的试题
|
||||
choosed_item_ids = choosed_items.pluck(:item_bank_id)
|
||||
optional_item_ids = (type_items.pluck(:id) - choosed_item_ids).uniq
|
||||
|
||||
# 如果可选的题数等于0则提示无可换的题
|
||||
tip_exception("无可换的题") if optional_item_ids.size == 0
|
||||
|
||||
# 如果可选题数小于设置的题数(n),则在原来的选题中随机选n个,确保换题时能选到新的题
|
||||
if optional_item_ids.size < exam_type_setting.count
|
||||
absence_count = exam_type_setting.count - optional_item_ids.size
|
||||
optional_item_ids = optional_item_ids + choosed_item_ids.sample(absence_count)
|
||||
end
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
# 取试题分数
|
||||
score = choosed_items.first&.score || (params[:item_type] == "PROGRAM" ? 10 : 5)
|
||||
choosed_items.destroy_all
|
||||
optional_item_ids.sample(exam_type_setting.count).each_with_index do |item_id, index|
|
||||
new_item = ItemBank.find item_id
|
||||
@exam.item_baskets << ItemBasket.new(item_bank_id: new_item.id, position: index+1, score: score, item_type: new_item.item_type)
|
||||
end
|
||||
end
|
||||
render_ok
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_exam
|
||||
@exam = ExaminationIntelligentSetting.find_by!(id: params[:id])
|
||||
tip_exception(403,"无权限编辑") unless current_user.admin_or_business? || @exam.user_id == current_user.id
|
||||
end
|
||||
|
||||
def form_params
|
||||
params.permit(:discipline_id, :sub_discipline_id, :difficulty, :source, tag_discipline_id: [], question_settings: %i[item_type count])
|
||||
end
|
||||
|
||||
def save_params
|
||||
params.permit(:name, :duration)
|
||||
end
|
||||
end
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user