Merge remote-tracking branch 'origin/develop' into dev_hjm

dev_hjm
hjm 6 years ago
commit 6786b6ee10

6
.gitignore vendored

@ -45,4 +45,8 @@ config/oneapm.yml
/public/react-mobile7/build/.project
/public/npm-debug.log
/vendor
/workspace/*
/workspace/*
.ruby-gemset
.rvmrc

@ -9,8 +9,8 @@ module Mobile
desc "ecloud接口测试"
get 'list' do
EcloudService.new.list
post 'list' do
EcloudService.new.list(params)
end
end

@ -0,0 +1,3 @@
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/

@ -0,0 +1,3 @@
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/

@ -0,0 +1,3 @@
// Place all the styles related to the ecloud controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/

@ -0,0 +1,3 @@
// Place all the styles related to the oauth controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/

@ -436,7 +436,15 @@ class AccountController < ApplicationController
# 注册完/绑定邮箱 后完善资料
def user_info
@user = User.current
#是否是Oschina过来的
@is_ecoder_user = @user.ecoder_user_id.to_i>0
#是否没设置过密码
@is_set_password = @user.hashed_password.present?
if request.get?
# 如果是登录的请求进来,则需要判断登录名是否合法
if (@user.login =~ /(^(?=.*?[a-zA-Z]).*$)/).nil? || !(@user.login =~ /[@#\$%\^&\*\.]+/).nil?
@login_error = true
@ -454,6 +462,22 @@ class AccountController < ApplicationController
apply_user.update_all(:status => 2) unless apply_user.blank?
end
if @is_ecoder_user && !@is_set_password
@user.password = params[:new_password]
@user.password_confirmation = params[:new_password_confirmation]
if @user.password.size<8
@password_len_error = true
render :user_info and return
end
if @user.password != @user.password_confirmation
@password_match_error = true
render :user_info and return
end
end
@user.lastname = params[:lastname]
@user.firstname = ""
@user.show_realname = params[:hide_realname] ? 0 : 1
@ -525,6 +549,7 @@ class AccountController < ApplicationController
return
else
@user.login = lg
logger.info "save user: #{@user.errors}"
end
end
end
@ -652,12 +677,16 @@ class AccountController < ApplicationController
req = Hash.new(false)
req[:valid] = false
type = params[:type].to_i
if type == 1 || type == 2 || type == 4 || type == 6 || params[:phone] =~ /^1\d{10}$/
code = VerificationCode.where(:phone => params[:phone], :code => params[:code], :code_type => (params[:type].to_i != 1 && params[:type].to_i != 2 && params[:type].to_i != 4) ? 2 : params[:type].to_i ).last
if Redmine::Configuration['gitlab_address'].include?("test") && params[:code] == "134790"
req[:valid] = true
else
code = VerificationCode.where(:email => params[:phone], :code => params[:code], :code_type => params[:type].to_i).last
if type == 1 || type == 2 || type == 4 || type == 6 || params[:phone] =~ /^1\d{10}$/
code = VerificationCode.where(:phone => params[:phone], :code => params[:code], :code_type => (params[:type].to_i != 1 && params[:type].to_i != 2 && params[:type].to_i != 4) ? 2 : params[:type].to_i ).last
else
code = VerificationCode.where(:email => params[:phone], :code => params[:code], :code_type => params[:type].to_i).last
end
req[:valid] = !code.nil? && (Time.now.to_i - code.created_at.to_i) <= 10*60
end
req[:valid] = !code.nil? && (Time.now.to_i - code.created_at.to_i) <= 10*60
render :json => req
end

@ -65,6 +65,25 @@ class ApplicationController < ActionController::Base
include Redmine::MenuManager::MenuController
helper Redmine::MenuManager::MenuHelper
def ecloud_auth ucloud_user_id
euser = EcloudUser.where("id =? and opttype not in(3, 5)", ucloud_user_id).first
if euser.present? # 开通过业务
#
else
false
end
end
def ec_public_auth major_school
unless User.current.admin? || major_school.template_major || major_school.school.users.where(:id => User.current.id).count > 0 ||
major_school.ec_major_school_users.where(:user_id => User.current.id).count > 0 ||
EcCourseUser.where(:user_id => User.current.id, :ec_course_id => EcCourse.where(:ec_year_id => major_school.ec_years.pluck(:id)).pluck(:id)).count > 0
render_403
else
true
end
end
def user_agent
logger.info "HTTP_USER_AGENT #{request.env["HTTP_USER_AGENT"]}"
end
@ -274,6 +293,7 @@ class ApplicationController < ActionController::Base
true
end
def require_admin
return unless require_login
if !User.current.admin?

@ -2,6 +2,7 @@
class EcCourseAchievementMethodsController < ApplicationController
before_filter :find_target, :only => [:edit_course_target, :create_evaluation_methods]
skip_before_filter :verify_authenticity_token, :only => [:create_evaluation_methods, :sync_course_data]
before_filter :find_ec_course, :only => [:index]
include ApplicationHelper
@ -59,11 +60,9 @@ class EcCourseAchievementMethodsController < ApplicationController
###############################################################
def index
achievement_list = []
# 具体工程课程
ec_course = EcCourse.find params[:ec_course_id]
# 课程的所有目标
targets = ec_course.ec_course_targets
targets = @ec_course.ec_course_targets
targets.each do |target|
evaluate_data = []
# 评价环节
@ -95,7 +94,7 @@ class EcCourseAchievementMethodsController < ApplicationController
end
achievement_list << {target_id: target.id, target_evaluate_data: evaluate_data}
end
render :json => {achievement_list: achievement_list}
render :json => {achievement_list: achievement_list, is_manager: @is_manager}
end
@ -306,4 +305,13 @@ class EcCourseAchievementMethodsController < ApplicationController
@target = EcCourseTarget.find params[:ec_course_target_id]
end
def find_ec_course
@ec_course = EcCourse.find(params[:ec_course_id])
@year = @ec_course.ec_year
@ec_major_school = @year.ec_major_school
@template_major = User.current.admin? || @ec_major_school.school.ec_school_users.pluck(:user_id).include?(User.current.id) ||
@ec_major_school.ec_major_school_users.pluck(:user_id).include?(User.current.id)
@is_manager = @template_major || @ec_course.ec_course_users.pluck(:user_id).include?(User.current.id)
end
end

@ -2,6 +2,8 @@
class EcCourseSupportsController < ApplicationController
before_filter :find_year, :except => [:edit_require_vs_course, :destroy_require_vs_course]
skip_before_filter :verify_authenticity_token, :only => [:create, :edit_require_vs_course, :destroy_require_vs_course]
before_filter :require_login
before_filter :ec_auth, :except => [:edit_require_vs_course, :destroy_require_vs_course]
###############################################################################
# 毕业要求vs课程体系
@ -47,6 +49,8 @@ class EcCourseSupportsController < ApplicationController
course_support_data = []
max_support_count = 0
subitems_count = 0
major_school = @year.ec_major_school
is_manager = User.current.admin? || major_school.school.ec_school_users.pluck(:user_id).include?(User.current.id) || major_school.ec_major_school_users.pluck(:user_id).include?(User.current.id)
ec_graduation_requirements.each_with_index do |gr, i|
logger.info("#############index:#{i}#####_ec_gradiation_reqiorements: #{gr.id}")
subitems_count += gr.ec_graduation_subitems.count
@ -60,7 +64,12 @@ class EcCourseSupportsController < ApplicationController
course_data << { name: name, top_relation: cs.top_relation, weigths: cs.weigths}
end
gs.ec_course_supports.count > max_support_count && max_support_count = gs.ec_course_supports.count
course_support_data << {sequence_num: sequence_num, ec_graduation_subitem_id: gs.id, course_data: course_data, num_total: gs.ec_course_supports.count, weights_total: weigths_sum}
course_support_data << {sequence_num: sequence_num,
sequence_title: gs.content,
ec_graduation_subitem_id: gs.id,
course_data: course_data,
num_total: gs.ec_course_supports.count,
weights_total: weigths_sum}
end
end
render :json => {ec_year_id: @year.id,
@ -69,7 +78,8 @@ class EcCourseSupportsController < ApplicationController
subitems_url: "#{graduation_requirement_ec_major_school_ec_year_path(@year, :ec_major_school_id => @year.ec_major_school_id)}",
course_count: @year.ec_courses.count,
course_url: "#{ec_course_setting_ec_major_school_ec_year_path(@year, :ec_major_school_id => @year.ec_major_school_id)}",
max_support_count: max_support_count}
max_support_count: max_support_count,
is_manager: is_manager}
end
# 毕业要求vs课程体系 详情页面
@ -208,4 +218,9 @@ class EcCourseSupportsController < ApplicationController
def find_year
@year = EcYear.find(params[:ec_year_id])
end
# 职业认证的权限判断
def ec_auth
ec_public_auth @year.ec_major_school
end
end

@ -3,6 +3,8 @@ class EcCoursesController < ApplicationController
layout 'base_ec'
before_filter :find_ec_course, :except => [:create, :get_calculation_data, :sync_all_course_data]
before_filter :find_year, :only => [:create, :get_calculation_data]
before_filter :require_login
before_filter :ec_auth, :except => [:sync_all_course_data]
skip_before_filter :verify_authenticity_token, :only => [:crud_targets, :crud_score_level, :sync_all_course_data, :search_courses,
:correlation_course, :delete_course]
@ -77,7 +79,8 @@ class EcCoursesController < ApplicationController
end
calculation_data << {first_level: first_level, first_leval_data: first_leval_data}
end
render :json => {calculation_data: calculation_data, calculation_value: @year.calculation_value, course_ids: course_ids.uniq}
render :json => {calculation_data: calculation_data, calculation_value: @year.calculation_value, course_ids: course_ids.uniq,
is_manager: @template_major}
end
# 课程目标配置
@ -100,6 +103,12 @@ class EcCoursesController < ApplicationController
end
end
def ec_course_support_setting_data
course_targets = @ec_course.ec_course_targets.includes(:ec_graduation_subitems)
json_data = target_list_data(course_targets)
render :json => json_data
end
# 课程目标配置的更新操作()
# /ec_courses/1/crud_targets
def crud_targets
@ -414,6 +423,8 @@ class EcCoursesController < ApplicationController
def score_level
respond_to do |format|
format.html{
Rails.logger.info("1111111111111111111template_major: #{@template_major}")
Rails.logger.info("1111111111111111111is_manager: #{@is_manager}")
render "/common/index", :layout => false
}
format.json{
@ -429,11 +440,27 @@ class EcCoursesController < ApplicationController
{score: 70, level: ""},
{score: 60, level: ""}]
end
render :json => {levels: ls}
render :json => {levels: ls, is_manager: @is_manager}
}
end
end
def score_level_data
levels = @ec_course.ec_score_levels
ls = []
if levels.present?
levels.each do |l|
ls << {score: l.score, level: l.level}
end
else
ls = [{score: 90, level: ""},
{score: 80, level: ""},
{score: 70, level: ""},
{score: 60, level: ""}]
end
render :json => {levels: ls, is_manager: @is_manager}
end
def crud_score_level
levels = params[:levels]
render :json => {status: -1, message: "参数不能为空"} if levels.blank?
@ -574,6 +601,11 @@ class EcCoursesController < ApplicationController
#@is_manager = @template_major || @ec_course.ec_course_users.pluck(:user_id).include?(User.current.id)
end
# 职业认证的权限判断
def ec_auth
ec_public_auth @ec_major_school
end
def target_list_data course_targets
targets = []
course_targets.each do |ct|
@ -595,6 +627,10 @@ class EcCoursesController < ApplicationController
end
end
Rails.logger.info("111111111111111user_id: #{User.current.try(:id)}")
Rails.logger.info("template_major: #{@template_major}")
Rails.logger.info("is_manager: #{@is_manager}")
return {ec_year_id: @ec_course.ec_year_id, ec_course_id: @ec_course.id, course_targets: targets,
requirements: requirements, is_manager: @is_manager}
end
@ -630,7 +666,7 @@ class EcCoursesController < ApplicationController
# 遍历学生成绩统计数据
student_scores.each do |sc|
sub_ecss = EcCourseStudentScore.where(:ec_course_id => @ec_course.id, :ec_year_student_id => sc.ec_year_student_id).first
sub_score = base_score == 0 ? 0 : ((sc.try(:score).to_f/base_score) * percentage).round(3)
sub_score = base_score == 0 || sc.try(:score).nil? ? 0 : ((sc.try(:score).to_f/base_score) * percentage).round(3)
if sub_ecss
ess_target = sub_ecss.ec_student_score_targets.where(:ec_course_target_id => target.id,

@ -2,7 +2,10 @@
class EcMajorSchoolsController < ApplicationController
layout "base_ec"
before_filter :require_login
before_filter :find_major_school, :except => [:get_navigation_data]
before_filter :ec_auth, :except => [:get_navigation_data]
def show
@years = @major_school.ec_years
@ -125,7 +128,8 @@ class EcMajorSchoolsController < ApplicationController
evaluation_methods_url: evaluation_methods_url,
competition_calculation_info_url: competition_calculation_info_url,
score_level_setting_url: score_level_setting_url,
example_major: example_major
example_major: example_major,
allow_visit: User.current.admin? || (User.current.ec_school.present? && User.current.ec_school == major.school.id)
}
end
@ -181,4 +185,9 @@ class EcMajorSchoolsController < ApplicationController
# 管理员权限
@major_manager = User.current.admin? || @major_school.school.ec_school_users.pluck(:user_id).include?(User.current.id) || @major_school.ec_major_school_users.pluck(:user_id).include?(User.current.id)
end
# 职业认证的权限判断
def ec_auth
ec_public_auth @major_school
end
end

@ -3,6 +3,9 @@ class EcYearsController < ApplicationController
layout "base_ec"
before_filter :find_major_and_year, except: [:create]
before_filter :require_login
before_filter :ec_auth, except: [:create]
#before_filter :find_year, only: [:set_calculation_value]
skip_before_filter :verify_authenticity_token, :only => [:import_students, :set_calculation_value, :destroy_students]
require 'simple_xlsx_reader'
@ -54,37 +57,38 @@ class EcYearsController < ApplicationController
format.html {
render "/common/index", :layout => false
}
format.json {
template_file = EcTemplate.find_by_name "学生列表导入模板"
if template_file.present?
file = template_file.attachments.first
template_url = "/attachments/download/#{file.id}/#{file.filename}"
else
template_url = "javascript:void(0);"
end
students = @year.ec_year_students
show_name = @year.ec_year_students.where(:name => nil).count == 0
end
end
page = params[:page] || 1
total_student = students.count
total_page = (total_student / 50.0).ceil
students = paginateHelper students, 50
def student_lists_data
template_file = EcTemplate.find_by_name "学生列表导入模板"
if template_file.present?
file = template_file.attachments.first
template_url = "/attachments/download/#{file.id}/#{file.filename}"
else
template_url = "javascript:void(0);"
end
ec_students = []
students.each_with_index do |student, index|
student = {index: (50*(page.to_i - 1) + index + 1),
student_name: student.name,
student_id: student.student_id}
ec_students << student
end
students = @year.ec_year_students
show_name = @year.ec_year_students.where(:name => nil).count == 0
import_url = "/ec_major_schools/#{@ec_major_school.id}/academic_years/#{@year.id}/import_students"
page = params[:page] || 1
total_student = students.count
total_page = (total_student / 50.0).ceil
students = paginateHelper students, 50
render :json => {template_url: template_url, ec_students: ec_students, total_page: total_page, import_url: import_url,
show_name: show_name, :total_student => total_student}
}
ec_students = []
students.each_with_index do |student, index|
student = {index: (50*(page.to_i - 1) + index + 1),
student_name: student.name,
student_id: student.student_id}
ec_students << student
end
import_url = "/ec_major_schools/#{@ec_major_school.id}/academic_years/#{@year.id}/import_students"
render :json => {template_url: template_url, ec_students: ec_students, total_page: total_page, import_url: import_url,
show_name: show_name, :total_student => total_student, :is_manager => @template_major}
end
# DELETE: /ec_major_schools/:major_id/academic_years/:year_id/destroy_students
@ -346,6 +350,11 @@ class EcYearsController < ApplicationController
@template_major = User.current.admin? || @ec_major_school.school.ec_school_users.pluck(:user_id).include?(User.current.id) || @ec_major_school.ec_major_school_users.pluck(:user_id).include?(User.current.id)
end
# 职业认证的权限判断
def ec_auth
ec_public_auth @ec_major_school
end
def find_year
@year = EcYear.find(params[:id])
end
@ -387,6 +396,14 @@ class EcYearsController < ApplicationController
new_egs.save!
# 记录新旧对应关系,为之后的中间表做记录
egs_record << [pre_egs.id, new_egs.id]
prev_ersvss = EcRequireSubVsStandard.where(:ec_graduation_subitem_id => pre_egs.id)
prev_ersvss.each do |prev_ersvs|
new_ersvss = EcRequireSubVsStandard.new
new_ersvss.attributes = prev_ersvs.attributes.dup.except("id", "ec_graduation_subitem_id")
new_ersvss.ec_graduation_subitem_id = new_egs.id
new_ersvss.save!
end
end
end
@ -397,12 +414,30 @@ class EcYearsController < ApplicationController
new_eto.attributes = pre_eto.attributes.dup.except("id", "ec_year_id")
new_eto.ec_year_id = ec_year.id
new_eto.save!
# 复制 "培养目标分项"
pre_eto.ec_training_subitems.try(:each) do |pre_ets|
new_ets = EcTrainingSubitem.new
new_ets.attributes = pre_ets.attributes.dup.except("id", "ec_training_objective_id")
new_ets.ec_training_objective_id = new_eto.id
new_ets.save!
# 复制 "毕业要去 vs 培养目标"
pre_ervsos = EcRequirementVsObjective.where(:ec_training_objective_id => pre_ets.id)
pre_ervsos.each do |ervso|
new_ervso = EcRequirementVsObjective.new
new_ervso.attributes = ervso.attributes.dup.except("id", "ec_training_objective_id", "ec_graduation_requirement_id")
new_ervso.ec_training_objective_id = new_ets.id
new_egr_id = -1
egr_record.each do |egr_id|
if egr_id[0] == ervso.ec_graduation_requirement_id
new_egr_id = egr_id[1]
end
end
raise("找不对应的毕业要求") if new_egr_id == -1
new_ervso.ec_graduation_requirement_id = new_egr_id
new_ervso.save!
end
end
end

@ -0,0 +1,370 @@
#encoding=utf-8
# 云启训练场EduCoder个人版 产品编码appId 9200108
# 产品名称 计费类型 套餐编码
# 云启训练场EduCoder个人版 固定包月 9200108001
# 固定包月 9200108002
# 固定包月 9200108003
# ---------------------------------------------------
# 产品名称 计费类型 套餐编码
# 云启训练场EduCoder院校版 包月+按license 9200109001
# 包月+按license 9200109002
# 云启训练场EduCoder院校版 产品编码appId 9200109
require 'net/http'
require 'digest'
class EcloudController < ApplicationController
skip_before_filter :verify_authenticity_token
before_filter :check_sign, only: [:ps_new, :ps_update, :bs_new, :bs_update]
before_filter :save_para
before_filter :user_setup
# before_filter :require_login, only: [:authorize]
skip_before_filter :verify_authenticity_token, only: [:ps_new, :ps_update, :bs_new, :bs_update, :ecloud_login_callback]
def index
render file: 'public/react-oschina/build/index.html', :layout => false
end
def trustie_login
end
CLIENT_ID = '1022'
CLIENT_SECRET = '2112037a-6d7a-432b-9081-feb1153d8668'
ROOT_URl = 'http://localhost:3000'
SERVER_URL = "https://221.176.54.92:9081/restful/services/"
## 签名
def sign(timestamp)
Digest::MD5.hexdigest("client_id=#{CLIENT_ID}client_key=#{CLIENT_SECRET}timestamp=#{timestamp}").upcase
end
# 企业/个人业务开通
# applyno 申请单号,唯一
# ecordercode 唯一标志一个企业的订购关系
# params['opttype']操作类型。0开通1变更2试用转商用4再次开通
# 业务列表opttype: 0新增1注销2修改
# serviceparas: 但是由于企业版是按成员收费的所以serviceparas里面会传成员数个人版是包月计费的serviceparas不会传成员数
def bs_new
ActiveRecord::Base.transaction do
begin
if params['opttype'] == 0 # 开通企业/个人业务
ecloud = Ecloud.create!(eloud_params)
create_service(params['services'], ecloud.try(:id))
create_product_params(params['productparas'], ecloud.try(:id)) if params['productparas'].present?
# 为管理员添加一条记录
# 开通的时候都是用户的opttype也是0
# 如果管理员已经存在,则不用重复开通
euser = EcloudUser.where(id: params['userid'], custid: params['custid']).first
unless euser
EcloudUser.create!(custid: params['custid'], opttype: params['opttype'], userid: params['userid'],
username: params['username'], useralias: params['useralias'],
mobile: params['mobile'], email: params['email'], begintime: params['begintime'],
endtime: params['endtime'])
end
elsif params['opttype'] == 2 # 试用转商用 # 变更企业/个人业务
# 业务列表:注销业务(注销试用的套餐),另一个业务项的操作代码是:新增业务(开通商用的套餐)
# 需要通过产品服务编号和业务编码来区分哪个产品
ecloud = Ecloud.where(custid: params['custid'], custcode: params['custcode'], productcode: params['productcode'], trial: true).first
# 注销试用的套餐
## 需要注销的套餐; 试用转商用是不会有批量操作的所以可以使用first
des_service = params['services'].select{|s| s['opttype'] == 1}.first
esd = EcloudService.where(ecloud_id: ecloud.try(:id), code: des_service['code']).first
ecloud.update_attribute(:trial, params['trial'])
esd.update_attributes!(opttype: des_service['opttype'], begintime: des_service['begintime'], endtime: des_service['endtime'])
# 试用转商用是不会有批量操作的
# 新增业务
add_service = params['services'].select{|s| s['opttype'] == 0}
create_service(add_service, ecloud.try(:id))
#
elsif params['opttype'] == 1 # 业务变更
ecloud = Ecloud.where(custid: params['custid'], custcode: params['custcode'], productcode: params['productcode']).first
# 套餐变更
# 新增业务
add_service = params['services'].select{|s| s['opttype'] == 0}
create_service(add_service, ecloud.try(:id)) if add_service.present?
# 如果有注销业务,注销业务
des_services = params['services'].select{|s| s['opttype'] == 1}
if des_services.present?
des_services.each do |ds|
esd = EcloudService.where(ecloud_id: ecloud.try(:id), code: ds['code']).first
esd.update_attributes!(opttype: ds['opttype'], begintime: ds['begintime'], endtime: ds['endtime'])
end
end
# 变更业务
edt_services = params['services'].select{|s| s['opttype'] == 2}
if edt_services.present?
edt_services.each do |es|
ese = EcloudService.where(ecloud_id: ecloud.try(:id), code: es['code']).first
ese.update_attributes!(opttype: es['opttype'], begintime: es['begintime'], endtime: es['endtime'])
create_serviceparas es['serviceparas'].first, ese.id
end
end
# ecloud = Ecloud.where(bossorderid: params['bossorderid']).first
# ecloud.update_attributes!(eloud_params)
# ecloud.ecloud_productparas.destroy
# ecloud.ecloud_services.destroy
#
# ecloud_id = ecloud.try(:id)
elsif params['opttype'] == 4 # 再次重复开通
ecloud = Ecloud.where(custid: params['custid'], custcode: params['custcode'], productcode: params['productcode']).first
create_service(params['services'], ecloud.try(:id))
create_product_params(params['productparas'], ecloud.try(:id)) if params['productparas'].present?
end
#
# # 非试用情况下,为管理员单独创建一条账号,企业账号
# unless params['trial']
# EcloudUser.create!(ecloud_id: ecloud.try(:id), opttype: params['opttype'], userid: params['userid'],
# username: params['username'], useralias: params['useralias'],
# mobile: params['mobile'], email: params['email'])
# end
render :json => {result: true, errmsg: ""}
rescue Exception => e
logger.error(e.message)
render :json => {code: 500, msg: "#{e.message}"}
raise ActiveRecord::Rollback
end
end
end
# 企业/个人业务变更、注销
# 处理业务平台退订、暂停(欠费暂停,信控暂停等)、暂停后恢复应用业务
# 这个接口是不会新增业务的
# 试用退订的时候bossorderid传空字符
def bs_update
ActiveRecord::Base.transaction do
begin
case params['opttype']
when 0 # 退订
opttype = 6
when 1 # 暂停
opttype = 7
when 2 # 恢复
opttype = 8
end
if params['bossorderid'].present?
ecloud = Ecloud.where(bossorderid: params['bossorderid']).first
ecloud.update_attribute(:opttype, opttype)
else
# 试用退订
params['services'].each do |service|
ecloud_id = EcloudService.where(code: service['packagecode']).first.try(:ecloud_id)
Ecloud.find(ecloud_id).update_attribute(:opttype, opttype)
end
end
render :json => {result: true, errmsg: ""}
rescue Exception => e
logger.error(e.message)
render :json => {code: 500, msg: "#{e.message}"}
raise ActiveRecord::Rollback
end
end
end
# 用户业务开通与变更接口
# 授权statu为1取消授权status为0
# user['opttype']: 操作类型0开通1变更3: 取消授权4暂停5恢复
def ps_new
ActiveRecord::Base.transaction do
begin
user_params = params['users']
user_params.each do |user_param|
if user_param['opttype'] == 0 # 开通
EcloudUser.create!(custid: params['custid'], opttype: user_param['opttype'], userid: user_param['userid'],
username: user_param['username'], useralias: user_param['useralias'],
mobile: user_param['mobile'], email: user_param['email'], begintime: user_param['begintime'].to_s,
endtime: user_param['endtime'].to_s)
elsif user_param['opttype'] == 1 # 变更
ecloud_user = EcloudUser.where(custid: params['custid'], userid: user_param['userid']).first
ecloud_user.update_attributes!(opttype: user_param['opttype'], username: user_param['username'],
useralias: user_param['useralias'], mobile: user_param['mobile'], email: user_param['email'],
begintime: user_param['begintime'].to_s, endtime: user_param['endtime'].to_s)
end
end
render :json => {success: true, errmsg: ""}
# end
rescue Exception => e
logger.error(e.message)
render :json => {code: 500, msg: "#{e.message}"}
raise ActiveRecord::Rollback
end
end
end
# 用户业务状态变更
# user['opttype']: 操作类型0开通1变更3: 取消授权4暂停5恢复
def ps_update
begin
user_params = params['users']
user_params.each do |user_param|
case user_param['opttype']
when 0 # 取消授权
opttype = 3
when 1 # 暂停
opttype = 4
when 2 # 恢复
opttype = 5
end
ecloud_user = EcloudUser.where(custid: params['custid'], userid: user_param['userid']).first
ecloud_user.update_attributes!(opttype: opttype, operatime: params['operatime'], effecttime: params['effecttime'])
end
render :json => {success: true, errmsg: ""}
rescue Exception => e
logger.error(e.message)
render :json => {code: 500, msg: "#{e.message}"}
end
end
def ecloud_login_callback
unless params["test"] == 'true'
#获取code
logger.info "oauth2 login_callback: #{params}"
raise "没有code" unless params[:code]
url = "#{SERVER_URL}/oauth2/authorization?grant_type=authorization_code" +
"&client_id=#{CLIENT_ID}&scope=&redirect_uri=&code=#{params[:code]}"
res = post(url)
logger.info "oauth2 authorization resp: #{res}"
# {"access_token":"ae673b2d-88b4-46cc-aa74-0b031f24b76f","expires":6,"refresh_token":"7380cc67-a59c-4c21-9000-70e12a58d175","username":"15111030087@QW_er","uid":2147}
body = decode(res)
raise '登录失败' unless body["access_token"]
#获取此用户信息
res = get("#{SERVER_URL}/user/info?access_token=#{body['access_token']}&userid=#{body['uid']}")
logger.info "oauth2 get user info: #{res}"
# {"userid":2147,"custid":2104,"custcode":"E0002018042810010054","custtype":2,"status":2,"username":"15111030087@QW_er","useralias":"15111030087","isadmin":true,"entprise":"04**004","departments":"","departmentnames":"","mobile":"15365386520","email":"15111030087@139.com"}
else
res = '{"userid":2147,"custid":2104,"custcode":"E0002018042810010054","custtype":2,"status":2,"username":"15111030087@QW_er","useralias":"15111030087","isadmin":true,"entprise":"04**004","departments":"","departmentnames":"","mobile":"15365386520","email":"15111030087@139.com"}'
end
# 同步用户
info = decode(res)
user = User.find_by_ecoder_user_id(info["userid"])
unless user
#新建用户
user = User.create_with_ecoder!(info)
end
self.logged_user = user
user = UserExtensions.where(:user_id => User.current.id).first
if user.gender.nil? || user.school_id.nil? || User.current.lastname.nil?
redirect_to my_account_path
elsif user.identity == 3 && user.school_id.nil?
redirect_to my_account_path
else
redirect_to User.current
end
end
private
def get(url)
uri = URI(url)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = url.start_with?('https')
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Get.new(uri.request_uri)
request['Content-Type'] = 'application/json'
request['Accept'] = 'application/json'
response = http.request(request)
response.body
end
def post(url)
uri = URI(url)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = url.start_with?('https')
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Post.new(uri.request_uri)
request['Content-Type'] = 'application/json'
request['Accept'] = 'application/json'
response = http.request(request)
response.body
end
def decode(s)
begin
obj = ActiveSupport::JSON.decode(s)
rescue ActiveSupport::JSON.parse_error
logger.error("Attempted to decode invalid JSON: #{s}")
end
end
private
def eloud_params
return {applyno: params['applyno'], ecordercode: params['ecordercode'], opttype: params['opttype'],
trial: params['trial'], bossorderid: params['bossorderid'], custid: params['custid'], custtype: params['custtype'],
custcode: params['custcode'], registersource: params['registersource'], custname: params['custname'],
userid: params['userid'], username: params['username'], useralias: params['useralias'], mobile: params['mobile'],
email: params['email'], productcode: params['productcode'], begintime: params['begintime'],
endtime: params['endtime']}
end
# 新增套餐
def create_service services, ecloud_id
services.each do |service|
ese = EcloudService.create!(opttype: service['opttype'], code: service['code'], begintime: service['begintime'],
endtime: service['endtime'], ecloud_id: ecloud_id)
if service['serviceparas'].present?
create_serviceparas(service['serviceparas'].first, ese.id)
end
end
end
def create_serviceparas params_serviceparas, ese_id
if params_serviceparas.present?
EcloudServieceServicepara.create(key: params_serviceparas['key'], value: params_serviceparas['value'], ecloud_service_id: ese_id)
end
end
def create_product_params params, ecloud_id
params.each do |p|
EcloudProductpara.create(key: p['key'], value: p['value'], ecloud_id: ecloud_id)
end
end
def check_sign
sign = sign(params['timestamp'])
if sign != params['sign']
render :json => {code: 501, msg: "sign的值错误"}
return
end
end
def save_para
EcloudLog.create(url: request.url, para_value: params, applyno: params['applyno'], custid: params['custid'],
custcode: params['custcode'], userid: params['userid'], username: params['username'])
end
end

@ -1,5 +1,7 @@
class EcsController < ApplicationController
before_filter :require_login
before_filter :find_school, :except => [:get_navigation_url]
before_filter :school_manager, :except => [:department, :get_navigation_url]
layout 'base_ec'
def department
@ -10,26 +12,30 @@ class EcsController < ApplicationController
@major_schools = @school.ec_major_schools.where(:template_major => false)
unless @is_school_manager
ec_major_school_ids = EcMajorSchoolUser.where(:user_id => User.current.id).pluck(:ec_major_school_id)
ec_course_major_ids = EcYear.where(:id => EcCourseUser.where(:user_id => User.current.id).pluck(:ec_year_id)).pluck(:ec_major_school_id)
ec_course_major_ids = EcYear.where(:id => EcCourse.where(:id => EcCourseUser.where(:user_id => User.current.id).pluck(:ec_course_id)).pluck(:ec_year_id)).pluck(:ec_major_school_id)
@major_schools = @major_schools.where(:id => (ec_major_school_ids + ec_course_major_ids).uniq)
end
@major_count = @major_schools.count
if params[:search].present?
major_ids = EcMajor.where("name like '%#{params[:search]}%' or code like '%#{params[:search]}%'").pluck(:id)
@major_schools = @major_schools.where(:ec_major_id => major_ids)
end
if @major_count == 0
render_403
else
if params[:search].present?
major_ids = EcMajor.where("name like '%#{params[:search]}%' or code like '%#{params[:search]}%'").pluck(:id)
@major_schools = @major_schools.where(:ec_major_id => major_ids)
end
@obj_count = @major_schools.count
@limit = 10
@is_remote = true
@obj_pages = Paginator.new @obj_count, @limit, params['page'] || 1
@offset ||= @obj_pages.offset
@major_schools = paginateHelper @major_schools, @limit
respond_to do |format|
format.js
format.html
@obj_count = @major_schools.count
@limit = 10
@is_remote = true
@obj_pages = Paginator.new @obj_count, @limit, params['page'] || 1
@offset ||= @obj_pages.offset
@major_schools = paginateHelper @major_schools, @limit
respond_to do |format|
format.js
format.html
end
end
end
@ -62,4 +68,10 @@ class EcsController < ApplicationController
def find_school
@school = School.find(params[:school_id])
end
def school_manager
unless User.current.admin? || @school.users.where(:id => User.current.id).count > 0
render_403
end
end
end

@ -219,10 +219,10 @@ class GamesController < ApplicationController
@had_passed_testsests_public_count = had_test.blank? ? 0 : had_test.select{|had_test| had_test.result == true && had_test.is_public == true}.count
@mirror_name = @myshixun.mirror_name
@final_score = ((@shixun.status <= 1) ? 0 : @game.final_score.to_i)
if @myshixun.shixun.status <= 1 || (@game.final_score != 0 && @game.answer_open?)
if @myshixun.shixun.status <= 1 || (@game.final_score != 0 && @game.answer_open > 0)
@gold = 0
else
if @game.answer_open? && @game.final_score ==0
if @game.answer_open > 0 && @game.final_score ==0
@gold = -@game_challenge.score.to_i
else
@gold = @game.final_score.to_i

@ -671,6 +671,7 @@ class HomeworkCommonController < ApplicationController
def destroy
if @homework.destroy
StudentWork.where(:homework_common_id => @homework.id).destroy_all
#更新CourseHomeworkStatistics中每个学生的未交作品数、已交作品数、迟交作品数
# hw_count = @course.homework_commons.includes(:homework_detail_manual).where("homework_detail_manuals.comment_status > 0").count
# homework_ids = @course.homework_commons.empty? ? "(-1)" : "(" + @course.homework_commons.map{|hw| hw.id}.join(",") + ")"
@ -1347,7 +1348,7 @@ class HomeworkCommonController < ApplicationController
def find_homework
@homework = HomeworkCommon.find params[:id]
@homework_detail_manual = @homework.homework_detail_manual
@homework_detail_programing = @homework.homework_detail_programing
# @homework_detail_programing = @homework.homework_detail_programing
@homework_detail_group = @homework.homework_detail_group
@course = @homework.course
rescue

@ -1796,7 +1796,7 @@ end
@school_id = params[:school_id]
if params[:school_id] && params[:school_id] != ''
@courses = Course.joins("join users u on courses.tea_id = u.id").joins("join user_extensions ue on u.id = ue.user_id").where("ue.school_id = #{params[:school_id]}")
@courses = @courses.joins("join user_extensions ue on courses.tea_id = ue.user_id").where("ue.school_id = #{params[:school_id]}")
end
if params[:homepage_show]
@ -1819,7 +1819,7 @@ end
user_id = User.where("concat(lastname, firstname) like '%#{@search}%'")
@courses = @courses.joins("join users u on courses.tea_id = u.id").where("concat(u.lastname, u.firstname) like '%#{@search}%'")
end
else
elsif "dep_name" == @keyword
school = School.where("name like '%#{@search}%'").map(&:id)
@courses = @courses.where(:school_id => school)
# @courses= @courses.where("name like '%#{@search}%'")

@ -141,6 +141,10 @@ class MyController < ApplicationController
# Edit user's account
def account
@user = params[:user_id].nil? ? User.current : User.find(params[:user_id])
ue = @user.user_extensions
if @user.lastname.blank? || ue.try(:identity).nil? || (ue.try(:identity) == 1 && ue.try(:student_id).blank?) || (ue.try(:identity) != 1 && ue.try(:technical_title).blank?) || ue.try(:gender).blank? || ue.try(:school_id).blank?
redirect_to user_info_path
@ -152,7 +156,8 @@ class MyController < ApplicationController
applied_message = AppliedMessage.where(:id => params[:applied_message_id]).first
applied_message.update_attribute(:viewed, true)
end
# @user = User.current
# 认证
@trail_authentication = ApplyAction.where(:user_id => User.current.id, :container_type => "TrialAuthorization").order("created_at desc").first
if @trail_authentication && (@trail_authentication.status == 1 || @trail_authentication.status == 2) && !@trail_authentication.noticed

@ -510,7 +510,7 @@ class MyshixunsController < ApplicationController
challenge.path.split("").each do |path|
game_passed_code(game.id, path, myshixun.try(:gpid), 1)
end
if !game.answer_open && (challenge.shixun.try(:status) > 1) # 如果没有查看答案,则获得该关卡得分
if game.answer_open == 0 && (challenge.shixun.try(:status) > 1) # 如果没有查看答案,则获得该关卡得分
reward_grade(game.user, game.id, 'Game', challenge.score)
reward_experience(game.user, game.id, 'Game', challenge.score)
game.update_attributes!(:final_score => challenge.score)

@ -0,0 +1,167 @@
#encoding: utf-8
class OauthController < ApplicationController
require
include ApplicationHelper
before_filter :user_setup
before_filter :require_login, only: [:authorize]
skip_before_filter :verify_authenticity_token, only: [:token]
def index
render 'oauth/index', layout: false
end
# 客户端申请认证的URI包含以下参数
#
# response_type表示授权类型必选项此处的值固定为”code”
# client_id表示客户端的ID必选项
# redirect_uri表示重定向URI可选项
# scope表示申请的权限范围可选项
# state表示客户端的当前状态可以指定任意值最好是随机字符串认证服务器会原封不动地返回这个值可防止CSRF攻击
#
# 这个页显示授权页如果授权成功返回redirect_uri+code
#
#
# 服务器回应客户端的URI包含以下参数
#
# code表示授权码必选项。该码的有效期应该很短通常设为10分钟客户端只能使用该码一次 否则会被授权服务器拒绝。该码与客户端ID和重定向URI是一一对应关系。
# state如果客户端的请求中包含这个参数认证服务器的回应也必须一模一样包含这个参数。
def authorize
begin
#参数检查
raise "response_type只能为code" unless params["response_type"] == "code"
raise "client_id为必传项" unless params["client_id"].present?
raise "redirect_uri为必传项" unless params["redirect_uri"].present?
config = OauthConfig.where(client_id: params["client_id"], redirect_uri: params["redirect_uri"]).first
raise "client_id或redirect_uri不正确" unless config
@data = params
if params[:gen_code]
## 检查通过生成code
oauth = Oauth.create!(client_id: config.client_id,
client_secret: config.client_secret,
redirect_uri: config.redirect_uri,
user_id: User.current.id
)
code = oauth.gen_code
redirect_to params["redirect_uri"] + "?code=#{code}&state=#{params[:state]}"
else
render 'oauth/authorize', :layout => 'forge'
end
rescue => e
logger.error e
render :text => e.message
end
end
def test_callback
# 申请 token
#
client_id = "88d893c5a345313e7b8c6fcf23d3d024ee08d5e41ce120c3448b6eea77d8de30"
client_secret = "e9240cc5fc913741db5aea93f2986a8ea0631bb67f7c00e41e491b95d9619e64"
redirect_uri = "http://localhost:3000/oauth/cb"
url = "http://127.0.0.1:3000/oauth/token?grant_type=authorization_code&code=#{params['code']}&redirect_uri=#{redirect_uri}&client_id=#{client_id}&client_secret=#{client_secret}"
render text: url
end
# 客户端向认证服务器申请令牌的HTTP请求包含以下参数
#
# grant_type表示使用的授权模式必选项此处的值固定为”authorization_code”。
# code表示上一步获得的授权码必选项。
# redirect_uri表示重定向URI必选项且必须与A步骤中的该参数值保持一致。
# client_id表示客户端ID必选项。
# client_secret: 表示客户端密钥,必选项。
#
#
# 认证服务器核对了授权码和”重定向URI”确认无误后向客户端发送访问令牌access token和更新令牌refresh token
#
# 认证服务器发送的HTTP回复包含以下内容
#
# access_token表示访问令牌必选项。
# token_type表示令牌类型该值大小写不敏感必选项可以是bearer类型或mac类型。
# expires_in表示过期时间单位为秒。如果省略该参数必须其他方式设置过期时间。
# refresh_token表示更新令牌用来获取下一次的访问令牌可选项。
# scope表示权限范围如果与客户端申请的范围一致此项可省略。
def token
begin
res = {}
if params[:grant_type] == 'authorization_code'
raise "code必传" unless params["code"]
raise "client_id必传" unless params["client_id"]
raise "client_secret必传" unless params["client_secret"]
raise "code错误或已超时" unless Oauth.code_valid?(params["code"])
oauth = Oauth.auth_code(params["code"], params["client_id"], params["client_secret"])
raise "认证不通过" unless oauth
## 生成 token
#
oauth.gen_token
oauth.reload
res = {
access_token: oauth.access_token,
token_type: 'bearer',
expires_in: oauth.token_expires_in,
refresh_token: oauth.refresh_token
}
end
render json: res.to_json
rescue => e
logger.error e
render text: e.message
end
end
def get_userinfo
user = Oauth.auth(params["access_token"])
user_info = {}
if user
user_info = {
token: user.id,
login: user.login,
avatar_url: "https://openi.org.cn/images/" + url_to_avatar(user),
name: user.show_name,
email: user.mail,
allow: (user.login == "guange"||user.phone=='15607313899') ? 1 : 0
}
end
render json: user_info.to_json
end
private
def require_login
require "base64"
if !User.current.logged?
redirect_to '/login?back_url64=' + Base64.urlsafe_encode64(request.original_url)
end
end
include Trustie::Http
end

@ -508,7 +508,7 @@ class StudentWorkController < ApplicationController
end
@tab = params[:tab].nil? ? 1 : params[:tab].to_i
if User.current.member_of_course?(@homework.course) && params[:order].nil? && params[:sort].nil? && params[:name].nil? && params[:group].nil? && params[:page].nil?
if (User.current.member_of_course?(@homework.course) || User.current.admin?) && params[:order].nil? && params[:sort].nil? && params[:name].nil? && params[:group].nil? && params[:page].nil?
if !@course.is_end && @homework.homework_type == 4 && @homework.homework_detail_manual.comment_status > 0 && (@homework.end_time > Time.now || (@homework.end_time <= Time.now && @homework.allow_late))
update_shixun_work_status @homework
end

@ -2592,6 +2592,7 @@ class UsersController < ApplicationController
def user_info
end
# 连续签到六天则每天累加10个金币

@ -33,6 +33,28 @@ module ApplicationHelper
extend Forwardable
def_delegators :wiki_helper, :wikitoolbar_for, :heads_for_wiki_formatter
# 课堂相关controller
def course_controller
["courses", "homework_common", "student_work", "exercise", "poll", "boards", "messages", "graduation_topics", "graduation_tasks",
"graduation_works", "files"]
end
# 实训课程相关controller
def subjects_controller
["subjects", "stages"]
end
# 实训路径相关controller
def shixuns_controller
["shixuns", "challenges", "myshixuns", "games"]
end
# 工程认证相关controller
def ecs_controller
["ecs", "ec_courses", "ec_course_evaluations", "ec_course_supports", "ec_course_targets", "ec_graduation_requirements",
"ec_major_schools", "ec_majors", "ec_years"]
end
def exercise_bank_json_data exercises
exercises.map do |exercise|
exercise_path = exercise_bank_path(exercise)
@ -2968,7 +2990,7 @@ module ApplicationHelper
title << ("关于我们")
end
elsif params[:controller] == "courses" && params[:action] == "index"
title << ("课堂")
title << ("翻转课堂")
elsif params[:controller] == "competitions" && params[:action] == "index"
title << ("竞赛")
elsif @competition
@ -2976,11 +2998,11 @@ module ApplicationHelper
elsif @contest
title << (@contest.name.nil? ? "创新源于实践" : @contest.name)
elsif @shixun
title << (@shixun.name.nil? ? "精选实训" : @shixun.name)
title << (@shixun.name.nil? ? "开发社区" : @shixun.name)
elsif @my_shixun
title << ("我的实训")
elsif params[:controller] == "shixuns" && params[:action] == "index"
title << ("精选实训")
title << ("开发社区")
elsif @subject
title << (@subject.name.nil? ? "实训课程" : @subject.name)
elsif params[:controller] == "subjects" && params[:action] == "index"
@ -4318,7 +4340,7 @@ module ApplicationHelper
candown = (attachment.is_public == 1 || attachment.is_public == true)
end
else
if attachment.container_type == "MarkDown" || attachment.container_type == "Shixun" || attachment.container_type == "Memo" || attachment.container_type == "Career" || attachment.container_type == "Exercise" || attachment.container_type == "ExerciseBank"
if attachment.container_type == "MarkDown" || attachment.container_type.nil? || attachment.container_type == 'Subject' || attachment.container_type == "Shixun" || attachment.container_type == "Memo" || attachment.container_type == "Career" || attachment.container_type == "Exercise" || attachment.container_type == "ExerciseBank"
candown = true
end
end
@ -6793,7 +6815,9 @@ def update_myshixun_work_score myshixun
end
work.update_time = Time.now
work.final_score = final_score
# 为迁移的数据做特殊处理, 若分数小于当前通关分数则不更新
work.final_score = final_score if work.final_score.nil? || final_score > work.final_score
score = work.final_score + work.eff_score - work.late_penalty
work.work_score = format("%.2f",(score < 0 ? 0 : score).to_f) unless work.ultimate_score
#logger.info("#############work_score: #{score}")

@ -0,0 +1,2 @@
module EcloudHelper
end

@ -0,0 +1,2 @@
module OauthHelper
end

@ -15,6 +15,8 @@ module SubjectsHelper
'<span class="fr color-grey-9">已发布</span>'
when 3
'<span class="fr color-grey-9">已关闭</span>'
else
""
end
else
if shixun_status != 2
@ -23,6 +25,8 @@ module SubjectsHelper
'<span class="fr color-grey-c">暂未公开</span>'
when 3
'<span class="fr color-grey-9">已关闭</span>'
else
""
end
else
""

@ -0,0 +1,11 @@
#encoding=utf-8
class Ecloud < ActiveRecord::Base
attr_accessible :applyno, :begintime, :bossorderid, :custcode, :custid, :custname, :custtype, :ecordercode, :endtime,
:mobile, :opttype, :productcode, :registersource, :string, :trial, :useralias, :userid, :username, :email,
:effecttime, :operatime
has_many :ecloud_services, :dependent => :destroy # 业务列表
has_many :ecloud_productparas, :dependent => :destroy # 开通参数列表
has_one :ecloud_user
end

@ -0,0 +1,3 @@
class EcloudLog < ActiveRecord::Base
end

@ -0,0 +1,4 @@
class EcloudProductpara < ActiveRecord::Base
attr_accessible :key, :value, :ecloud_id
belongs_to :ecloud
end

@ -0,0 +1,5 @@
class EcloudService < ActiveRecord::Base
attr_accessible :begintime, :code, :endtime, :opttype, :ecloud_id, :packagecode, :bossorderid
belongs_to :ecloud
has_many :ecloud_serviece_serviceparas
end

@ -0,0 +1,4 @@
class EcloudServieceServicepara < ActiveRecord::Base
attr_accessible :key, :value, :ecloud_service_id
belongs_to :ecloud_service
end

@ -0,0 +1,3 @@
class EcloudUser < ActiveRecord::Base
has_many :ecloud_user_paras
end

@ -0,0 +1,3 @@
class EcloudUserPara < ActiveRecord::Base
belongs_to :ecloud_user
end

@ -0,0 +1,4 @@
class EcloudUser < ActiveRecord::Base
# opttype: # user['opttype']: 操作类型0开通1变更3: 取消授权4暂停5恢复
attr_accessible :begintime, :email, :endtime, :mobile, :opttype, :paras, :useralias, :userid, :username, :custid
end

@ -15,7 +15,7 @@ class HomeworkCommon < ActiveRecord::Base
belongs_to :homework_bank
has_many :homework_group_settings, :dependent => :destroy
has_one :homework_detail_manual, :dependent => :destroy
has_one :homework_detail_programing, :dependent => :destroy
# has_one :homework_detail_programing, :dependent => :destroy
has_one :homework_detail_group, :dependent => :destroy
has_one :homework_commons_shixuns, :dependent => :destroy
has_many :homework_challenge_settings, :dependent => :destroy
@ -24,21 +24,21 @@ class HomeworkCommon < ActiveRecord::Base
has_many :homework_review_results, :dependent => :destroy # 学生的查重情况
belongs_to :course_homework_category
has_many :student_work_projects, :dependent => :destroy
has_many :homework_tests, :dependent => :destroy
has_many :homework_samples, :dependent => :destroy
has_many :student_works, :dependent => :destroy, :conditions => "student_works.is_test=0 and student_works.is_delete != 1"
has_many :student_work_projects
# has_many :homework_tests, :dependent => :destroy
# has_many :homework_samples, :dependent => :destroy
has_many :student_works, :conditions => "student_works.is_test=0 and student_works.is_delete != 1"
has_many :student_works_evaluation_distributions, :through => :student_works #一个作业的分配的匿评列表
has_many :journals_for_messages, :as => :jour, :dependent => :destroy
has_many :apply_homeworks, :dependent => :destroy
has_many :apply_homeworks
has_many :praise_tread, as: :praise_tread_object, dependent: :destroy
has_one :praise_tread_cache, as: :object, dependent: :destroy
has_many :acts, :class_name => 'Activity', :as => :act, :dependent => :destroy #用户活动
# has_many :acts, :class_name => 'Activity', :as => :act, :dependent => :destroy #用户活动
has_and_belongs_to_many :shixuns
# 课程动态
has_many :course_acts, :class_name => 'CourseActivity',:as =>:course_act ,:dependent => :destroy
# 课程消息
has_many :course_messages, :class_name =>'CourseMessage', :as => :course_message, :dependent => :destroy
# has_many :course_messages, :class_name =>'CourseMessage', :as => :course_message, :dependent => :destroy
has_many :tidings, as: :container, dependent: :destroy
acts_as_attachable
acts_as_event :title => Proc.new {|o| "#{l(:label_course_homework)} ##{o.id}: #{o.name}" },
@ -48,7 +48,7 @@ class HomeworkCommon < ActiveRecord::Base
# after_create :act_as_activity
after_update :update_activity
after_save :act_as_course_activity
after_destroy :delete_kindeditor_assets
# after_destroy :delete_kindeditor_assets
before_destroy :update_homework_bank_quotes
#删除时更新题库中的引用数
@ -188,9 +188,9 @@ class HomeworkCommon < ActiveRecord::Base
# end
end
def is_program_homework?
self.homework_type == 2 && self.homework_detail_programing
end
# def is_program_homework?
# self.homework_type == 2 && self.homework_detail_programing
# end
def is_group_homework?
self.homework_type == 3 && self.homework_detail_group
@ -225,6 +225,6 @@ class HomeworkCommon < ActiveRecord::Base
end
end
delegate :language_name, :language, :to => :homework_detail_programing
# delegate :language_name, :language, :to => :homework_detail_programing
end

@ -64,7 +64,7 @@ class Myshixun < ActiveRecord::Base
time = 0
self.games.each do |game|
if game.status == 2
time += (game.end_time.to_i - game.open_time.to_i) > 0 ? (game.end_time.to_i - game.open_time.to_i) : 0
time += game.cost_time.to_i
end
end
time

@ -0,0 +1,53 @@
require 'base64'
class Oauth < ActiveRecord::Base
attr_accessible :client_id, :client_secret, :redirect_uri, :access_token,
:refresh_token, :token_created_at,:token_expires_in, :user_id
belongs_to :user
def gen_code
code = Base64.urlsafe_encode64 Digest::MD5.hexdigest "#{Time.now}-#{Random.new_seed}"
update_column(:code, code)
code
end
def gen_token
access_token = Digest::MD5.hexdigest "#{Time.now}-#{Random.new_seed}"
refresh_token = Digest::MD5.hexdigest "#{Random.new_seed}-#{Time.now}-#{Random.new_seed}"
self.update_attributes(access_token: access_token,
refresh_token: refresh_token,
token_created_at: Time.now.to_i,
token_expires_in: Time.now.to_i + 24*60*60,
)
end
def self.code_valid?(code)
# 1. 是否存在
oauth = Oauth.where(code: code).order("ID desc").first
return false unless oauth
# 2. 是否超过10分钟
return false if Time.now.to_i - oauth.created_at.to_i > 10*60
# 3. 是否有使用过
return false if oauth.access_token.present?
return true
end
def self.auth_code(code, client_id, client_secret)
Oauth.where(code: code, client_id: client_id, client_secret: client_secret).order('id desc').first
end
def self.auth(access_token)
oauth = self.find_by_access_token(access_token)
return nil unless oauth
oauth.user
end
end

@ -0,0 +1,3 @@
class OauthConfig < ActiveRecord::Base
attr_accessible :client_id, :client_secret, :redirect_uri, :scope
end

@ -13,9 +13,9 @@ class StudentWork < ActiveRecord::Base
has_many :student_works_scores, :dependent => :destroy
has_many :challenge_work_scores, :dependent => :destroy
belongs_to :project
has_many :student_work_tests, order: 'id desc'
# has_many :student_work_tests, order: 'id desc'
# course's message
has_many :course_messages, :class_name =>'CourseMessage', :as => :course_message, :dependent => :destroy
# has_many :course_messages, :class_name =>'CourseMessage', :as => :course_message, :dependent => :destroy
has_many :attachments, :dependent => :destroy
has_many :tidings, as: :container, dependent: :destroy
belongs_to :myshixun
@ -24,7 +24,7 @@ class StudentWork < ActiveRecord::Base
scope :all_commit, lambda{where("work_status != 0")}
before_destroy :delete_praise
before_save :set_program_score, :set_src
before_save :set_program_score
after_save :update_avg_sum_score
# after_create :act_as_message
@ -34,25 +34,26 @@ class StudentWork < ActiveRecord::Base
PraiseTread.where("praise_tread_object_id = #{self.id} AND praise_tread_object_type = 'StudentWork'").destroy_all
end
def last_test
student_work_tests.order('id desc').first
end
# def last_test
# student_work_tests.order('id desc').first
# end
private
def set_program_score
if self.homework_common.is_program_homework? #编程作业,学生提交作品后计算系统得分
#根据最后一次测试计算得分
unless last_test
self.system_score = 0
else
self.system_score = last_test.test_score self.homework_common.homework_tests.size
end
end
# if self.homework_common.is_program_homework? #编程作业,学生提交作品后计算系统得分
# #根据最后一次测试计算得分
# unless last_test
# self.system_score = 0
# else
# self.system_score = last_test.test_score self.homework_common.homework_tests.size
# end
# end
set_final_score self.homework_common,self
end
def set_src
self.description = last_test.src if last_test
end
# def set_src
# self.description = last_test.src if last_test
# end
#成绩计算
def set_final_score homework,student_work
@ -217,8 +218,8 @@ class StudentWork < ActiveRecord::Base
# status == 0 : delay
def act_as_message
if self.work_status != 0 && self.created_at > self.homework_common.end_time
self.course_messages << CourseMessage.new(:user_id => self.user_id, :course_id => self.homework_common.course_id, :viewed => false, :status => false)
end
# if self.work_status != 0 && self.created_at > self.homework_common.end_time
# self.course_messages << CourseMessage.new(:user_id => self.user_id, :course_id => self.homework_common.course_id, :viewed => false, :status => false)
# end
end
end

@ -245,6 +245,8 @@ class User < Principal
has_many :ec_major_schools, :through => :ec_major_school_users
has_many :ec_major_school_users, :dependent => :destroy
has_many :ec_course_users
#####
scope :logged, lambda { where("#{User.table_name}.status <> #{STATUS_ANONYMOUS}") }
@ -344,6 +346,21 @@ class User < Principal
end
end
}
# 工程认证的学校
def ec_school
school_id = self.ec_school_users.pluck(:school_id).first ||
self.ec_major_schools.pluck(:school_id).first ||
(self.ec_course_users.first && self.ec_course_users.first.try(:ec_course).try(:ec_year).try(:ec_major_school).try(:school_id))
end
# 工程认证的权限
def ec_school_auth school_id
# self.ec_school_users.where(:school_id => school_id).count > 0 ||
# self.ec_major_schools.where(:school_id => school_id).count > 0 ||
#
end
def challenge_tags
games = self.games.where(:id => self.experiences.map(&:container_id), :status => 2)
challenge_tags = ChallengeTag.where(:challenge_id => games.map(&:challenge_id)).where("name != ''")
@ -1675,6 +1692,36 @@ class User < Principal
end
end
def self.create_with_ecoder!(info)
user = User.new
user.admin = false
user.login = "ecoder_" + info["mobile"]
user.phone = info["mobile"]
unless User.find_by_mail(info["email"])
user.mail = info["email"]
end
user.nickname = info["username"]
user.activate
user.last_login_on = Time.now
user.ecoder_user_id = info["userid"]
user.save!(:validate => false)
UserStatus.create!(:user_id => user.id, :changsets_count => 0, :watchers_count => 0)
ue = user.user_extensions ||= UserExtensions.new
ue.user_id = user.id
ue.save!
user
end
end
class AnonymousUser < User

@ -1,6 +1,7 @@
class EcloudService
def list
return {status: 0, message: "test"}
def list params
return {status: 0, message: "test", code: params[:code], params: params}
end
end

@ -43,7 +43,7 @@ class GamesService
# 高性能取上一关、下一关
prev_game = Game.prev_identifier(shixun.id, game.myshixun_id, game_challenge.position)
next_game = if current_user.is_certification_teacher || shixun_manager(shixun, current_user) || game.status == 2
next_game = if current_user.is_certification_teacher || shixun_manager(shixun, current_user) || game.status || shixun.task_pass
Game.next_game(shixun.id, game.myshixun_id, game_challenge.position).try(:identifier)
end
@ -88,15 +88,28 @@ class GamesService
# tpm_script_modified = (shixun.reset_time > myshixun.reset_time ? true : false) # 新结构脚本是实时传送的,所以不会影响
# 区分评测过未评测过,未评测过按需求取数据
if max_query_index > 0
qurey_test_sets = TestSet.find_by_sql("SELECT o.actual_output, o.out_put, o.result, o.test_set_position, o.query_index,t.is_public,t.input, t.output, g.id as game_id, c.id as challenge_id FROM outputs o,games g ,challenges c,test_sets t where
g.id=#{game.id} and o.query_index=#{max_query_index} and g.id = o.game_id and c.id= g.challenge_id and t.challenge_id = c.id and t.position =o.test_set_position order by o.query_index
")
else
qurey_test_sets = TestSet.find_by_sql("SELECT t.is_public,t.input, t.output,t.position FROM games g ,challenges c,test_sets t where
g.id=#{game.id} and c.id= g.challenge_id and t.challenge_id = c.id
")
end
sql =
if max_query_index > 0
"SELECT
b.actual_output, b.out_put, b.result, a.is_public, a.input, a.output
FROM
(SELECT position, input, output, challenge_id, is_public FROM test_sets where challenge_id=#{game_challenge.id}) a
LEFT JOIN
(SELECT
result, test_set_position, g.challenge_id, o.actual_output, o.out_put
FROM
outputs o left join games g on g.id=o.game_id
WHERE
game_id=#{game.id} and query_index = #{max_query_index}
) b
ON
b.challenge_id = a.challenge_id and b.test_set_position = a.position"
else
"SELECT t.is_public, t.input, t.output, t.position
FROM games g ,challenges c,test_sets t
WHERE g.id=#{game.id} and c.id= g.challenge_id and t.challenge_id = c.id"
end
qurey_test_sets = TestSet.find_by_sql(sql)
# 测试集统计及处理
unless qurey_test_sets.blank?
@ -233,7 +246,7 @@ class GamesService
is_teacher = (current_user.user_extensions.identity == 0)
is_certification_teacher = current_user.is_certification_teacher
# 这几种情况可以直接查看答案的:实训未发布;当前用户为实训管理员;已经查看过答案;平台认证的老师;
if (@shixun.status < 2 || shixun_manager(@shixun, current_user) || @game.answer_open || is_certification_teacher)
if (@shixun.status < 2 || shixun_manager(@shixun, current_user) || @game.answer_open == 1 || is_certification_teacher)
Rails.logger.info("answer#{params[:identifier]}#### user is #{current_user.id}, status is #{@shixun.status}, manager is #{shixun_manager(@shixun, current_user)}, open #{@game.answer_open}, cer #{is_certification_teacher}")
if challenge.st == 0
result = challenge.try(:answer)
@ -258,7 +271,7 @@ class GamesService
challenge_score = challenge.try(:score)
final_score = @game.final_score
if current_user.grade.to_i - challenge_score > 0
unless @game.answer_open # 如果这是第一次查看答案
if @game.answer_open == 0 # 如果这是第一次查看答案
if challenge.st == 0
final_score = final_score - challenge_score
# 积分消耗情况记录
@ -697,7 +710,7 @@ class GamesService
if had_passed && !game.had_passed?
game.update_attributes(:status => 2, :end_time => Time.now)
# TPM实训已发布并且没有查看答案
if shixun.is_published? && !game.answer_open
if shixun.is_published? && game.answer_open == 0
# 查看答案的时候处理final_scor和扣分记录
experience = score
reward_grade(myshixun.owner, game.id, 'Game', score)
@ -796,7 +809,7 @@ class GamesService
if game_status == 2 # 通关
if shixun.status > 1
score = game.final_score # 查看答案的时候有对最终获得金币进行处理
experience = game.answer_open ? 0 : game_challenge.score.to_i
experience = game.answer_open > 0 ? 0 : game_challenge.score.to_i
else
score = 0
experience = 0
@ -930,7 +943,8 @@ class GamesService
end
#end
myshixun_job = Base64.urlsafe_encode64("myshixun_#{myshixun.id}")
StudentWork.where(:myshixun_id => myshixun.id).update_all(:myshixun_id => nil, :work_status => 0)
StudentWork.where(:myshixun_id => myshixun.id).update_all(:myshixun_id => 0, :work_status => 0, :work_score => nil, :final_score => nil,
:cost_time => 0, :update_time => nil, :compelete_status => 0, :commit_time => nil)
# myshixun.destroy
myshixun.delete
# 主从复制出现脏读的情况

@ -39,6 +39,20 @@
</li>
<% end %>
<% if @is_ecoder_user && !@is_set_password %>
<li class="clearfix">
<label class="second-label fl"><span class="color-orange">* </span>密码:</label>
<input name="new_password" type="password" class="winput-240-40 fl" placeholder="请输入密码">
<p class="notice color-orange fl"><span id="new_password_hint" class="none"><i class="fa fa-exclamation-circle mt7 mr5 fl"></i>密码最小长度为8位</span></p>
</li>
<li class="clearfix">
<label class="second-label fl"><span class="color-orange">* </span>重复密码:</label>
<input name="new_password_confirmation" type="password" class="winput-240-40 fl" placeholder="请输入密码">
<p class="notice color-orange fl"><span id="new_password_confirmation_hint" class="none"><i class="fa fa-exclamation-circle mt7 mr5 fl"></i>两次密码不匹配</span></p>
</li>
<% end %>
<li class="<%= @user.show_realname ? 'none' : '' %> clearfix" id="nickname_li">
<label class="second-label fl"><span class="color-orange">* </span>昵称:</label>
<input type="text" id="nickname" name="nickname" maxlength="20" value="<%= @user.nickname %>" class="winput-240-40 fl" placeholder="填写昵称">

@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"><meta name="theme-color" content="#000000"><meta name="renderer" content="webkit"/><meta name="force-rendering" content="webkit"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><link rel="manifest" href="/manifest.json"><link rel="shortcut icon" href="/favicon.ico"><title>Educoder</title><script type="text/javascript">window.__isR=!0</script><link rel="stylesheet" href="/react/build/css/css_min_all.css"><link rel="stylesheet" href="/assets/iconfont/iconfont.css"><link href="/react/build/./static/css/main.3274c43b.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="md_div" style="display:none"></div><div id="root" class="page -layout-v -fit"></div><div id="picture_display" style="display:none"></div><script type="text/javascript" src="/react/build/js/js_min_all.js"></script><script type="text/javascript" src="/assets/kindeditor/kindeditor.js"></script><script type="text/javascript" src="/react/build/js/create_kindeditor.js"></script><script type="text/javascript" src="/javascripts/educoder/edu_application.js"></script><script type="text/javascript" src="/react/build/./static/js/main.9f01900e.js"></script></body></html>
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"><meta name="theme-color" content="#000000"><meta name="renderer" content="webkit"/><meta name="force-rendering" content="webkit"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><link rel="manifest" href="/manifest.json"><link rel="shortcut icon" href="/favicon.ico"><title>Educoder</title><script type="text/javascript">window.__isR=!0</script><link rel="stylesheet" href="/react/build/css/css_min_all.css"><link rel="stylesheet" href="/assets/iconfont/iconfont.css"><link href="/react/build/./static/css/main.80b6ec5e.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="md_div" style="display:none"></div><div id="root" class="page -layout-v -fit"></div><div id="picture_display" style="display:none"></div><script type="text/javascript" src="/react/build/js/js_min_all.js"></script><script type="text/javascript" src="/assets/kindeditor/kindeditor.js"></script><script type="text/javascript" src="/react/build/js/create_kindeditor.js"></script><script type="text/javascript" src="/javascripts/educoder/edu_application.js"></script><script type="text/javascript" src="/react/build/./static/js/main.b4ee5e8a.js"></script></body></html>

@ -26,7 +26,7 @@
<% end %>
</li>
<% end %>
<% else %>
<% elsif @template_major %>
<form id="form_data_for_requirements">
<div class="clearfix ml30 mr30 pt20 pb20 bor-top-greyE" id="requirementNew">
<p class="df mb20"><input type="hidden" name="year_id" value="<%= @year.id %>">

@ -49,13 +49,13 @@
<!--</span>-->
</span>
<span class="column-2 fr edu-txt-center">
<% if @major_manager && !@major_school.template_major %>
<% if @major_manager && !@major_school.template_major || User.current.admin? %>
<a href="javascript:void(0);" onclick="delete_confirm_box_3('<%= ec_major_school_ec_year_path(year, :ec_major_school_id => @major_school) %>','您确定要删除吗?')" class="mr15 color-grey-c">删除</a>
<% end %>
<%#= link_to '删除', ec_major_school_ec_year_path(year, :ec_major_school_id => @major_school), method: :delete, :class => "mr15 color-grey-c", data: { confirm: '您确定要删除吗' } %>
<% if @major_manager || @major_school.template_major %>
<a href="javascript:void(0)" data-tip-down="导出本学年所有数据" class="mr15 color-blue">导出</a>
<% end %>
<%# if @major_manager || @major_school.template_major %>
<!--<a href="javascript:void(0)" data-tip-down="导出本学年所有数据" class="mr15 color-blue">导出</a>-->
<%# end %>
<%= link_to @btn_text, training_objectives_ec_major_school_ec_year_path(year, :ec_major_school_id => @major_school) %>
</span>

@ -46,13 +46,16 @@
</label>
</span>
<span class="column-11 edu-txt-center">
<label class="color-red-dd">
<% if course.ec_course_targets.count == 0 %>
--
<% else %>
<%= course.complete_target_count == course.ec_course_targets.count ? "达成" : "未达成" %>
--
<% else %>
<% if course.complete_target_count == course.ec_course_targets.count %>
<label class="color-green">达成</label>
<% else %>
<label class="color-red-dd">未达成</label>
<% end %>
<%#= course.complete_target_count == course.ec_course_targets.count ? "达成" : "未达成" %>
<% end %>
</label>
</span>
<span class="column-10 fl edu-txt-left">
<% if course_manager || @template_major %>
@ -83,7 +86,7 @@
</span>
<% end %>
<span class="column-5 fr">
<% if course_manager || @template_major %>
<% if @template_major %>
<a href="javascript:void(0)" onclick="delete_confirm_box_2('<%= ec_course_path(course) %>','是否确定删除当前课程?');" class="color-grey-c mr15 DelCorrelationCourse">删除</a>
<% end %>
<% redirect_url = course_targets == 0 ? ec_course_support_setting_ec_course_path(course) : (

@ -13,7 +13,7 @@
</li>
<% end %>
</ul>
<% elsif @ec_training_objective.present? %>
<% elsif @ec_training_objective.present? && @template_major && @sub_training_objectives.count == 0 %>
<form id="edit_training_subitems">
<ul class="edu-back-white padding10-30" id="SubentryNewPanel">
<li class="df mb10">

@ -12,7 +12,7 @@
<a href="javascript:void(0)" class="defalutCancelbtn mr20 fr" onclick="CancelEditBtn();">取消</a>
</p>
</div>
<% else %>
<% elsif @template_major %>
<div class="clearfix" id="targetEdit">
<textarea class="winput-100-130 mb10" id="training_obejctive"></textarea>
<p class="clearfix">

@ -9,7 +9,7 @@
<li class="clearfix">
<span class="column-No">0</span>
<span class="column-2">000000</span>
<span class="column-3 task-hide"><a href="javascript:void(0)"><%= @template_major.name %>(示例)</a></span>
<span class="column-3 task-hide"><a href="<%= ec_major_school_path(@template_major) %>"><%= @template_major.name %>(示例)</a></span>
<span class="column-5">
<a href="<%= ec_major_school_path(@template_major) %>" class="color-blue" target="_blank"><%= User.current.admin? ? "配置" : "查看" %></a>
</span>
@ -19,7 +19,7 @@
<li class="clearfix" id="major_list_<%= major_school.id %>">
<span class="column-No major_index"><%= index + 1 %></span>
<span class="column-2"><%= major_school.code %></span>
<span class="column-3 task-hide"><a href="javascript:void(0)"><%= major_school.name %></a></span>
<span class="column-3 task-hide"><a href="<%= ec_major_school_path(major_school) %>"><%= major_school.name %></a></span>
<span class="column-4">
<% if major_manager %>
<a href="javascript:void(0)" data-major-id="<%= major_school.id %>" class="color-blue mr5 mt-3 fl addMajorManager"><i class="iconfont icon-tianjiafangda"></i></a>
@ -29,7 +29,7 @@
</p>
</span>
<span class="column-5">
<% if major_manager %>
<% if @is_school_manager %>
<a href="javascript:void(0)" class="mr15 color-grey-c" onclick="delete_confirm_box_2('<%= ec_major_school_path(major_school) %>','是否确认删除')">删除</a>
<% end %>
<a href="<%= ec_major_school_path(major_school) %>" class="color-blue"><%= major_manager ? "配置" : "查看" %></a>

@ -2,8 +2,11 @@
<%= link_to image_tag("/images/educoder/headNavLogo.png", alt:"高校智能化教学与实训平台", class:"logoimg"), home_path %>
<div class="head-nav pr">
<ul id="header-nav">
<li class="pr<%= params[:action] == "index" && params[:controller] == "shixuns" ? " active" : "" %>"><%= link_to "精选实训", shixuns_path %><img src="/images/educoder/hot-h.png" class="nav-img" /></li>
<li class="<%= params[:action] == "index" && params[:controller] == "subjects" ? " active" : "" %>"><%= link_to "实训课程", subjects_path %></li>
<li class="<%= subjects_controller.include?(params[:controller]) ? " active" : "" %>"><%= link_to "实训课程", subjects_path %></li>
<li class="<%= course_controller.include?(params[:controller]) ? " active" : "" %>"><%= link_to "翻转课堂", courses_path %></li>
<!-- 精选实训 -->
<li class="pr<%= shixuns_controller.include?(params[:controller]) ? " active" : "" %>"><%= link_to "开发社区", shixuns_path %><img src="/images/educoder/hot-h.png" class="nav-img" /></li>
<% careers = Career.published.order("created_at asc") %>
<% if careers.present? %>
<li class="fl edu-menu-panel headIcon careershover <%= params[:action] == "index" && params[:controller] == "careers" ? " active" : "" %>" style="cursor: auto;">
@ -15,12 +18,12 @@
</ul>
</li>
<% end %>
<li class="<%= params[:action] == "index" && params[:controller] == "courses" ? " active" : "" %>"><%= link_to "课堂", courses_path %></li>
<li class="<%= params[:action] == "index" && params[:controller] == "competitions" ? " active" : "" %>"><%= link_to "竞赛", competitions_path %></li>
<li class="<%= params[:action] == "index" && params[:controller] == "forums" ? " active" : "" %>"><%= link_to "问答", forums_path %></li>
<% ec_user = EcSchoolUser.where(:user_id => User.current.id).first %>
<% if ec_user %>
<li class="<%= params[:controller] == "ecs" ? " active" : "" %>" id="ec_banner"><%= link_to "认证", department_ecs_path(:school_id => ec_user.school_id) %></li>
<li class="<%= params[:controller] == "competitions" ? " active" : "" %>"><%= link_to "竞赛", competitions_path %></li>
<li class="<%= params[:controller] == "forums" ? " active" : "" %>"><%= link_to "问答", forums_path %></li>
<% if User.current.ec_school.present? %>
<li class="<%= ecs_controller.include?(params[:controller]) ? " active" : "" %>" id="ec_banner">
<%= link_to "认证", department_ecs_path(:school_id => User.current.ec_school) %>
</li>
<% end %>
</ul>
<div class="posi-search" id="posi-search" style="display: none">

@ -3,11 +3,13 @@
<div class="head-nav pr">
<ul id="header-nav">
<li class="active" style="display: none"><%= link_to "首页", home_path %></li>
<li><%= link_to "实训课程", subjects_path %></li>
<li><%= link_to "翻转课堂", courses_path %></li>
<li class="pr">
<%= link_to "精选实训", shixuns_path %>
<%= link_to "开发社区", shixuns_path %>
<img src="/images/educoder/hot-h.png" class="nav-img" />
</li>
<li><%= link_to "实训课程", subjects_path %></li>
<% careers = Career.published.order("created_at asc") %>
<% if careers.present? %>
<li class="fl edu-menu-panel headIcon careershover" style="cursor: auto;">
@ -19,7 +21,6 @@
</ul>
</li>
<% end %>
<li><%= link_to "课堂", courses_path %></li>
<li><%= link_to "竞赛", competitions_path %></li>
<li><%= link_to "问答", forums_path %></li>
<!--<li><%#= link_to "活动竞赛", competitions_path %></li>-->
@ -90,22 +91,19 @@
document.getElementById('nHeader').style.left=sl+'px';
}
$(function () {
<% if params[:action] == "index" %>
var $header = $("#header-nav").children("li");
<% case params[:controller] %>
<% when "welcome" %>
<% if params[:controller] == "welcome" %>
$("#header-nav").children("li").eq(0).addClass("active");
<% when "shixuns" %>
<% elsif subjects_controller.include?(params[:controller]) %>
$("#header-nav").children("li").eq(1).addClass("active");
<% when "subjects" %>
<% elsif course_controller.include?(params[:controller]) %>
$("#header-nav").children("li").eq(2).addClass("active");
<% when "courses" %>
$header.length == 7 ? $header.eq(4).addClass("active") : $header.eq(3).addClass("active");
<% when "competitions" %>
<% elsif shixuns_controller.include?(params[:controller]) %>
$header.length == 7 ? $header.eq(2).addClass("active") : $header.eq(3).addClass("active");
<% elsif params[:controller] == "competitions" %>
$header.length == 7 ? $header.eq(5).addClass("active") : $header.eq(4).addClass("active");
<% when "forums" %>
<% elsif params[:controller] == "forums" %>
$header.length == 7 ? $header.eq(6).addClass("active") : $header.eq(5).addClass("active");
<% end %>
<% end %>
})
</script>

@ -12,7 +12,7 @@
option = {
grid: {
left: '3%',
right: '7%',
right: '9%',
bottom: '3%',
containLabel: true
},

@ -55,7 +55,7 @@
<tr>
<td>第<%= index + 1 %>关</td>
<td class="<%= game.status == 2 && game.end_time > @homework.end_time ? 'color-red' : '' %>"><%= game.status == 2 ? format_time(game.end_time) : '- -' %></td>
<td><%= game.status == 2 ? game_spend_time(game.end_time.to_i - game.open_time.to_i) : '- -' %></td>
<td><%= game.consumes_time %></td>
<td><%= game.status == 2 ? (game.final_score < 0 ? 0 : cha.score) : '- -' %></td>
</tr>
<% end %>

@ -78,7 +78,7 @@
placeholder: "请在此输入实训课程的简介",
imageUpload : true,
imageFormats : ["jpg", "jpeg", "gif", "png", "bmp", "webp", "JPG", "JPEG", "GIF", "PNG", "BMP", "WEBP"],
imageUploadURL : "<%= upload_with_markdown_path(:container_id => @subject.id, :container_type => @subject.class) %>" //url
imageUploadURL : "<%= upload_with_markdown_path(:container_id => @subject.id, :container_type => 'MarkDown') %>" //url
});
md_elocalStorage(shixun_editormd, "subject_desc_<%= User.current.id %>", "desc");
/* --------------------------------- 学习须知 -------------------------------------- */
@ -106,7 +106,7 @@
placeholder: "请在此输入实训课程的学习须知",
imageUpload : true,
imageFormats : ["jpg", "jpeg", "gif", "png", "bmp", "webp", "JPG", "JPEG", "GIF", "PNG", "BMP", "WEBP"],
imageUploadURL : "<%= upload_with_markdown_path(:container_id => @subject.id, :container_type => @subject.class) %>" //url
imageUploadURL : "<%= upload_with_markdown_path(:container_id => @subject.id, :container_type => 'MarkDown') %>" //url
});
md_elocalStorage(shixun_propaedeutics, "subject_notes_<%= User.current.id %>", "notes");

@ -25,8 +25,10 @@
<% else %>
<div style="text-align: center;padding: 100px 0px;">
<p class="font-16 mb20">没有实训数据可以选择</p>
<p>
<a href="javascript:void(0)" onclick="newshixuns(<%= User.current.mail.blank? %>)" class = "white-btn orange-btn">立即新建</a>
<a href="javascript:void(0)" onclick="newshixuns(<%= User.current.mail.blank? %>)" class = "white-btn orange-btn">立即新建</a>
<div class="clearfix edu-txt-center">
<a href="javascript:void(0);" class="task-btn pop_close mr60 pathhidnmodel" onclick="hideModal();">取消</a>
</div>
</div>
<% end %>

@ -70,22 +70,7 @@
</div>
<% end %>
<script>
/* -------------- 简介Md -------------------- */
var shixunPro = editormd.markdownToHTML("shixuns_propaedeutics", {
htmlDecode: "style,script,iframe", // you can filter tags decode
taskList: true,
tex: true, // 默认不解析
flowChart: true, // 默认不解析
sequenceDiagram: true // 默认不解析
});
/* -------------- 简介Md -------------------- */
var shixunPro = editormd.markdownToHTML("subject_learning_notes", {
htmlDecode: "style,script,iframe", // you can filter tags decode
taskList: true,
tex: true, // 默认不解析
flowChart: true, // 默认不解析
sequenceDiagram: true // 默认不解析
});
var flag = true;
$(function() {

@ -109,6 +109,23 @@
<% end %>
</div>
<script>
/* -------------- 简介Md -------------------- */
var shixunPro = editormd.markdownToHTML("shixuns_propaedeutics", {
htmlDecode: "style,script,iframe", // you can filter tags decode
taskList: true,
tex: true, // 默认不解析
flowChart: true, // 默认不解析
sequenceDiagram: true // 默认不解析
});
/* -------------- 课程须知MD -------------------- */
var shixunPro = editormd.markdownToHTML("subject_learning_notes", {
htmlDecode: "style,script,iframe", // you can filter tags decode
taskList: true,
tex: true, // 默认不解析
flowChart: true, // 默认不解析
sequenceDiagram: true // 默认不解析
});
//点击新建阶段
$(".click_add").click(function(){
if($("#new_stage_form").length == 1){

@ -51,23 +51,12 @@
</div>
</div>
</div>
<!--精选实训-->
<div class="clearfix pt20 educontent pr pb20">
<div class="edu-txt-center">
<p class="color-dark edu-txt-center font-24" style="line-height: 30px">精选实训</p>
<p class="color-grey-cd font-12">SELECTED TRAINING</p>
</div>
<a href="<%= shixuns_path %>" class="moreitem">更多<i class="fa fa-angle-right ml5"></i></a>
<div class="square-list clearfix">
<%= render :partial => "shixuns/shixun_item", :locals => {:shixuns => @shixuns} %>
</div>
</div>
<!--实训路径-->
<div class="clearfix pt20 educontent pr pb20 mb60">
<div class="edu-txt-center">
<p class="color-dark edu-txt-center font-24" style="line-height: 30px">实训课程</p>
<p class="color-grey-cd font-12">TRAINING PATH</p>
<p class="color-grey-cd font-12">TRAINING COURSE</p>
</div>
<a href="<%= subjects_path() %>" class="moreitem">更多<i class="fa fa-angle-right ml5"></i></a>
<div class="square-list clearfix">
@ -77,6 +66,20 @@
<!--<a href="https://www.educoder.net/paths/4" target="_blank"><img src="/images/educoder/guagngao.png" width="100%"/></a>-->
</div>
<!--精选实训 改为 开发社区-->
<div class="clearfix pt20 educontent pr pb20">
<div class="edu-txt-center">
<p class="color-dark edu-txt-center font-24" style="line-height: 30px">开发社区</p>
<p class="color-grey-cd font-12">DEVELOPMENT COMMUNITY</p>
</div>
<a href="<%= shixuns_path %>" class="moreitem">更多<i class="fa fa-angle-right ml5"></i></a>
<div class="square-list clearfix">
<%= render :partial => "shixuns/shixun_item", :locals => {:shixuns => @shixuns} %>
</div>
</div>
<!--导师排行榜-->
<div class="pt60 pb60 mb30 mentor-ranking">
<div class="educontent">

@ -25,7 +25,21 @@
# 所有的 act: :act 变成 :act => :act
# Example: :via => :get ====> :via => :get
RedmineApp::Application.routes.draw do
RedmineApp::Application.routes.draw do ## oauth相关
match 'oauth', to: 'oauth#index'
match 'oauth/authorize', to: 'oauth#authorize', :via => [:get, :post]
match 'oauth/token', to: 'oauth#token', :via => :post
match 'oauth/cb', to: 'oauth#test_callback', :via => :get
match 'oauth/userinfo', to: 'oauth#get_userinfo', :via => :get
get 'ecloud/ecloud_login', to: 'ecloud#ecloud_login_callback'
post 'ecloud/bs_new', to: 'ecloud#bs_new'
post 'ecloud/bs_update', to: 'ecloud#bs_update'
post 'ecloud/ps_new', to: 'ecloud#ps_new'
post 'ecloud/ps_update', to: 'ecloud#ps_update'
resources :ec_course_evaluations do
member do
match 'import_score', :via => [:post]
@ -54,6 +68,7 @@ RedmineApp::Application.routes.draw do
post 'add_manager'
delete 'delete_manager'
get "ec_course_support_setting"
get "ec_course_support_setting_data"
get "ec_course_reach_setting"
get "evaluation_methods"
match "search_courses", :via => [:get, :post]
@ -67,6 +82,7 @@ RedmineApp::Application.routes.draw do
post 'crud_targets'
post 'crud_score_level'
get 'score_level'
get 'score_level_data'
end
collection do
get 'get_calculation_data'
@ -129,6 +145,7 @@ RedmineApp::Application.routes.draw do
resources :ec_years, :path => "academic_years" do
member do
get 'student_lists'
get 'student_lists_data'
match 'import_students', :via => [:post]
get 'training_objectives'
get 'graduation_requirement'

@ -1,5 +1,5 @@
class AddForbidCopyToShixun < ActiveRecord::Migration
def change
add_column :shixuns, :forbid_copy, :boolean, :default => 0
# add_column :shixuns, :forbid_copy, :boolean, :default => 0
end
end

@ -0,0 +1,44 @@
class CreateOauths < ActiveRecord::Migration
def change
create_table :oauths do |t|
t.string :client_id
t.string :client_secret
t.string :code
t.string :redirect_uri
t.string :scope
t.string :access_token
t.string :refresh_token
t.integer :token_created_at
t.integer :token_expires_in #过期时间
t.timestamps
end
add_column :oauths, :user_id, :integer, default: 0
add_index :oauths, :user_id
create_table :oauth_configs do |t|
t.string :client_id
t.string :client_secret
t.string :redirect_uri
t.string :scope
t.timestamps
end
OauthConfig.create(
client_id: '88d893c5a345313e7b8c6fcf23d3d024ee08d5e41ce120c3448b6eea77d8de30',
client_secret: 'e9240cc5fc913741db5aea93f2986a8ea0631bb67f7c00e41e491b95d9619e64',
redirect_uri: 'http://localhost:3000/oschina/login_cb',
scope: ''
)
end
end

@ -0,0 +1,40 @@
class AddPassedScoreForUsers < ActiveRecord::Migration
def up
games = Game.where("final_score = 0 and status = 2 and answer_open = 0 and created_at > '2019-03-09 00:00:00'").includes(:challenge)
puts "game_count: #{games.count}"
games.find_each do |game|
puts "#{game.id}"
challenge = game.challenge
# 选择题和实践题的分数
score = challenge.choose_score
user = game.user
game.update_column(:final_score, score)
# 奖励金币和提供记录
grade = Grade.where(:user_id => user.id, :container_id => game.id, :container_type => "Game").first
if grade.nil?
Grade.create!(:user_id => user.id,
:container_id => game.id,
:container_type => "Game",
:score => score,
:created_at => game.end_time || Time.now,
:updated_at => game.end_time || Time.now)
user.update_column(:grade, (score + user.grade.to_i))
end
# 经验奖励
experience = Experience.where(:user_id => user.id, :container_id => game.id, :container_type => "Game").first
if experience.nil?
Experience.create!(:user_id => user.id,
:container_id => game.id,
:container_type => "Game",
:score => score,
:created_at => game.end_time || Time.now,
:updated_at => game.end_time || Time.now)
user.update_column(:experience, (score + user.experience.to_i))
end
end
end
def down
end
end

@ -0,0 +1,30 @@
class CreateEcloudusers < ActiveRecord::Migration
def change
create_table :ecloudusers do |t|
t.string :applyno
t.string :ecordercoder
t.string :string
t.integer :opttype
t.boolean :trial
t.string :bossorderid
t.integer :custid
t.string :custcod
t.string :string
t.integer :custtype
t.integer :registersource
t.string :custname
t.integer :userid
t.string :username
t.string :useralias
t.string :moblile
t.string :email
t.string :productcode
t.datetime :begintime
t.datetime :endtime
t.string :productparas
t.string :services
t.timestamps
end
end
end

@ -0,0 +1,18 @@
class CreateEcloudUser < ActiveRecord::Migration
def change
create_table :ecloud_users do |t|
t.integer :opttype
t.integer :userid
t.string :username
t.string :useralias
t.string :mobile
t.string :email
t.string :begintime
t.string :endtime
t.string :paras
t.integer :custid
t.timestamps
end
end
end

@ -0,0 +1,25 @@
class CreateEclouds < ActiveRecord::Migration
def change
create_table :eclouds do |t|
t.string :applyno
t.string :ecordercode
t.integer :opttype
t.boolean :trial
t.string :bossorderid
t.integer :custid
t.string :custcode
t.integer :registersource
t.integer :custtype
t.string :custname
t.integer :userid
t.string :username
t.string :useralias
t.string :mobile
t.string :productcode
t.string :begintime
t.string :endtime
t.timestamps
end
end
end

@ -0,0 +1,13 @@
class CreateEcloudServices < ActiveRecord::Migration
def change
create_table :ecloud_services do |t|
t.integer :opttype
t.string :code
t.string :begintime
t.string :endtime
t.integer :ecloud_id
t.timestamps
end
end
end

@ -0,0 +1,5 @@
class AddIndexToEcloud < ActiveRecord::Migration
def change
add_index :eclouds, [:ecordercode, :custcode], :unique => true, :name => 'ecorder_cust_code'
end
end

@ -0,0 +1,5 @@
class AddEmailToEcloud < ActiveRecord::Migration
def change
add_column :eclouds, :email, :string
end
end

@ -0,0 +1,6 @@
class AddPackagecodeToEcloudServices < ActiveRecord::Migration
def change
add_column :ecloud_services, :packagecode, :string
add_column :ecloud_services, :bossorderid, :string
end
end

@ -0,0 +1,6 @@
class AddOperatimeToEcloud < ActiveRecord::Migration
def change
add_column :eclouds, :operatime, :string
add_column :eclouds, :effecttime, :string
end
end

@ -0,0 +1,39 @@
class AddScoreForPassGames < ActiveRecord::Migration
def up
games = Game.where("final_score = 0 and status = 2 and answer_open = 0 and end_time > '2019-03-08 00:00:00'").includes(:challenge)
puts "game_count: #{games.count}"
games.find_each do |game|
puts "#{game.id}"
challenge = game.challenge
# 选择题和实践题的分数
score = challenge.choose_score
user = game.user
game.update_column(:final_score, score)
# 奖励金币和提供记录
grade = Grade.where(:user_id => user.id, :container_id => game.id, :container_type => "Game").first
if grade.nil?
Grade.create!(:user_id => user.id,
:container_id => game.id,
:container_type => "Game",
:score => score,
:created_at => game.end_time,
:updated_at => game.end_time)
user.update_column(:grade, (score + user.grade.to_i))
end
# 经验奖励
experience = Experience.where(:user_id => user.id, :container_id => game.id, :container_type => "Game").first
if experience.nil?
Experience.create!(:user_id => user.id,
:container_id => game.id,
:container_type => "Game",
:score => score,
:created_at => game.end_time,
:updated_at => game.end_time)
user.update_column(:experience, (score + user.experience.to_i))
end
end
end
def down
end
end

@ -0,0 +1,5 @@
class RemoveIndexFromEcloud < ActiveRecord::Migration
def change
remove_index :eclouds, :name => 'ecorder_cust_code'
end
end

@ -0,0 +1,5 @@
class AddEcloudIdToEcloudUser < ActiveRecord::Migration
def change
add_column :ecloud_users, :ecloud_id, :integer
end
end

@ -0,0 +1,5 @@
class AddStatusToEcloudUser < ActiveRecord::Migration
def change
add_column :ecloud_users, :status, :integer, :limit => 1
end
end

@ -0,0 +1,11 @@
class CreateEcloudProductpara < ActiveRecord::Migration
def change
create_table :ecloud_productparas do |t|
t.string :key
t.string :value
t.integer :ecloud_id
t.timestamps
end
end
end

@ -0,0 +1,11 @@
class CreateEcloudServieceServicepara < ActiveRecord::Migration
def change
create_table :ecloud_serviece_serviceparas do |t|
t.string :key
t.string :value
t.integer :ecloud_service_id
t.timestamps
end
end
end

@ -0,0 +1,6 @@
class AddEcoderUserIdToUsers < ActiveRecord::Migration
def change
add_column :users, :ecoder_user_id, :integer, default: 0
add_index :users, :ecoder_user_id
end
end

@ -0,0 +1,13 @@
class CreateEcloudLogs < ActiveRecord::Migration
def change
create_table :ecloud_logs do |t|
t.string :url
t.string :applyno
t.integer :custid
t.string :custcode
t.string :para_value
t.timestamps
end
end
end

@ -0,0 +1,16 @@
class ChangeClo < ActiveRecord::Migration
def up
change_column :eclouds, :begintime, :bigint, :limit => 20
change_column :eclouds, :endtime, :bigint, :limit => 20
change_column :eclouds, :operatime, :bigint, :limit => 20
change_column :eclouds, :effecttime, :bigint, :limit => 20
change_column :ecloud_services, :endtime, :bigint, :limit => 20
change_column :ecloud_services, :begintime, :bigint, :limit => 20
change_column :ecloud_users, :begintime, :bigint, :limit => 20
change_column :ecloud_users, :endtime, :bigint, :limit => 20
change_column :ecloud_logs, :para_value, :longtext
end
def down
end
end

@ -0,0 +1,8 @@
class AddIndexToHomework < ActiveRecord::Migration
def change
add_index :homework_detail_manuals, :homework_common_id
add_index :homework_commons_shixuns, :homework_common_id
add_index :student_works_evaluation_distributions, :student_work_id
add_index :tidings, :container_id
end
end

@ -0,0 +1,5 @@
class AddProductcodeToUcloudService < ActiveRecord::Migration
def change
add_column :ecloud_services, :productcode, :string
end
end

@ -0,0 +1,6 @@
class AddUseridToEcloudLog < ActiveRecord::Migration
def change
add_column :ecloud_logs, :userid, :integer
add_column :ecloud_logs, :username, :string
end
end

@ -0,0 +1,11 @@
class CreateEcloudUserParas < ActiveRecord::Migration
def change
create_table :ecloud_user_paras do |t|
t.string :key
t.string :value
t.integer :ecloud_user_id
t.timestamps
end
end
end

@ -0,0 +1,6 @@
class AddOperatimeToEcloudUsers < ActiveRecord::Migration
def change
add_column :ecloud_users, :operatime, :bigint
add_column :ecloud_users, :effecttime, :bigint
end
end

@ -0,0 +1,99 @@
# encoding: utf-8
class CreateShixunStudentWorks < ActiveRecord::Migration
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)
def down_generate_identifier type
if type == "game"
code = DCODES.sample(12).join
return down_generate_identifier(type) if Game.where(identifier: code).present?
elsif type == "myshixun"
code = DCODES.sample(10).join
return down_generate_identifier(type) if Myshixun.where(identifier: code).present?
end
code
end
def up
works = StudentWork.where("myshixun_id != 0 and myshixun_id not in (select id from myshixuns) and (work_score is null or work_score = 0)")
works.update_all(:myshixun_id => 0, :work_status => 0, :work_score => nil, :final_score => nil,
:cost_time => 0, :update_time => nil, :compelete_status => 0, :commit_time => nil)
shixun_works = StudentWork.where("myshixun_id != 0 and myshixun_id not in (select id from myshixuns) and work_score > 0")
shixun_works.each do |work|
shixun = work.homework_common.try(:homework_commons_shixuns).try(:shixun)
user = work.user
begin
ActiveRecord::Base.transaction do
if shixun.present? && user.present?
myshixun = Myshixun.where(:user_id => user.id, :shixun_id => shixun.id).first
if myshixun.blank?
# 创建新的myshixun和games
# fork版本库如果用户没有同步则先同步用户
g = Gitlab.client
if user.gid.nil?
s = Trustie::Gitlab::Sync.new
s.sync_user(user)
end
gshixun = g.fork(shixun.gpid, user.gid)
shixun_tomcat = Redmine::Configuration['shixun_tomcat']
code = down_generate_identifier("myshixun")
# 一般通过默认分支是否存在来判断一个项目是否fork成功
if gshixun.try(:id).present?
commit_id = g.commits(shixun.gpid).first.try(:id)
# educoder 加入到myshixun中
myshixun_admin_gid = User.where(:login => "educoder").first.try(:gid)
g.add_team_member(gshixun.id, myshixun_admin_gid, 40) # 40代表角色master
myshixun = Myshixun.create!(:shixun_id => shixun.id, :user_id => user.id, :identifier => code,
:modify_time => shixun.modify_time, :reset_time => shixun.reset_time,
:onclick_time => Time.now, :gpid => gshixun.id,
:git_url => gshixun.try(:path_with_namespace), :commit_id => commit_id)
url = "#{Redmine::Configuration['gitlab_address_ip']}/#{g.project(shixun.try(:gpid)).try(:path_with_namespace)}.git"
rep_url = Base64.urlsafe_encode64(url) # 注意educoder为默认给实训创建版本库的用户如果换成别的用户名字要相应的修改
uri = "#{shixun_tomcat}/bridge/game/openGameInstance"
params = {tpiID: "#{myshixun.id}", tpmGitURL:rep_url, tpiRepoName: gshixun.try(:name)}
logger.info("openGameInstance params is #{params}")
uri = URI.parse(URI.encode(uri.strip))
res = Net::HTTP.post_form(uri, params).body
res = JSON.parse(res)
if (res && res['code'].to_i != 0)
raise("实训云平台繁忙繁忙等级83")
end
# 其它创建关卡等操作
challenges = shixun.challenges
# 之所以增加user_id是为了方便统计查询性能
challenges.each_with_index do |challenge, index|
status = (index == 0 ? 0 : 3)
code = down_generate_identifier("game")
Game.create!(:challenge_id => challenge.id, :myshixun_id => myshixun.id, :status => status, :user_id => myshixun.user_id,
:open_time => Time.now, :identifier => code, :modify_time => challenge.modify_time)
end
end
work_score = work.final_score
work.homework_common.homework_challenge_settings.each do |setting|
if work_score > 1
games = myshixun.games.where(:challenge_id => setting.challenge_id).first
games.update_attributes(:status => 2, :end_time => Time.now, :final_score => setting.challenge.score)
work_score -= setting.score
end
end
work.update_column("myshixun_id", myshixun.id)
else
work.update_attributes(:myshixun_id => 0, :work_status => 0)
end
end
end
rescue Exception => e
puts ("###failed to exec shixun: current task id is #{e}")
# g.delete_project(gshixun.id) if gshixun.try(:id).present?
raise ActiveRecord::Rollback
end
end
end
def down
end
end

@ -0,0 +1,46 @@
#coding=utf-8
require 'net/http'
require 'uri'
module Trustie
module Http
def get(url)
uri = URI(url)
res = Net::HTTP.start(uri.host, uri.port, use_ssl: url.start_with?('https')) do |http|
req = Net::HTTP::Get.new(uri)
#req['Content-Type'] = 'application/json'
# The body needs to be a JSON string, use whatever you know to parse Hash to JSON
#req.body = {a: 1}.to_json
http.request(req)
end
res.body
end
def post(url, data=nil)
uri = URI(url)
res = Net::HTTP.start(uri.host, uri.port, use_ssl: url.start_with?('https')) do |http|
req = Net::HTTP::Post.new(uri)
#req['Content-Type'] = 'application/json'
# The body needs to be a JSON string, use whatever you know to parse Hash to JSON
req.body = data if data
http.request(req)
end
res.body
end
def decode(s)
begin
obj = ActiveSupport::JSON.decode(s)
rescue ActiveSupport::JSON.parse_error
logger.error("Attempted to decode invalid JSON: #{s}")
end
end
end
end

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 293 KiB

@ -152,7 +152,7 @@ function changeDepValue(value, data) {
// 基本资料页面提交表单时,判断身份与单位是否合法
function my_account_form_submit() {
if ($("#nickname").val().trim() == '') {
if ($("#nickname").val().trim() === "") {
$("#nickname").focus();
$("#nickname_hint").show();
e.stopImmediatePropagation();
@ -161,6 +161,8 @@ function my_account_form_submit() {
$("#nickname_hint").hide();
}
//姓名不能为空
if ($("#lastname").val().trim() == '') {
$("#lastname").focus();

File diff suppressed because it is too large Load Diff

@ -1,88 +1,88 @@
{
"./static/js/0.d15cdb8c.chunk.js": "./static/js/0.d15cdb8c.chunk.js",
"./static/js/0.d15cdb8c.chunk.js.map": "./static/js/0.d15cdb8c.chunk.js.map",
"./static/js/1.b37de40f.chunk.js": "./static/js/1.b37de40f.chunk.js",
"./static/js/1.b37de40f.chunk.js.map": "./static/js/1.b37de40f.chunk.js.map",
"./static/js/10.0b59b6d9.chunk.js": "./static/js/10.0b59b6d9.chunk.js",
"./static/js/10.0b59b6d9.chunk.js.map": "./static/js/10.0b59b6d9.chunk.js.map",
"./static/js/11.03d0c22e.chunk.js": "./static/js/11.03d0c22e.chunk.js",
"./static/js/11.03d0c22e.chunk.js.map": "./static/js/11.03d0c22e.chunk.js.map",
"./static/js/12.33ef9274.chunk.js": "./static/js/12.33ef9274.chunk.js",
"./static/js/12.33ef9274.chunk.js.map": "./static/js/12.33ef9274.chunk.js.map",
"./static/js/13.84649bc7.chunk.js": "./static/js/13.84649bc7.chunk.js",
"./static/js/13.84649bc7.chunk.js.map": "./static/js/13.84649bc7.chunk.js.map",
"./static/js/14.57622e23.chunk.js": "./static/js/14.57622e23.chunk.js",
"./static/js/14.57622e23.chunk.js.map": "./static/js/14.57622e23.chunk.js.map",
"./static/js/15.cd2747c4.chunk.js": "./static/js/15.cd2747c4.chunk.js",
"./static/js/15.cd2747c4.chunk.js.map": "./static/js/15.cd2747c4.chunk.js.map",
"./static/js/16.e8e3aa00.chunk.js": "./static/js/16.e8e3aa00.chunk.js",
"./static/js/16.e8e3aa00.chunk.js.map": "./static/js/16.e8e3aa00.chunk.js.map",
"./static/js/17.db50ac9a.chunk.js": "./static/js/17.db50ac9a.chunk.js",
"./static/js/17.db50ac9a.chunk.js.map": "./static/js/17.db50ac9a.chunk.js.map",
"./static/js/18.e8b5b490.chunk.js": "./static/js/18.e8b5b490.chunk.js",
"./static/js/18.e8b5b490.chunk.js.map": "./static/js/18.e8b5b490.chunk.js.map",
"./static/js/19.5f9a9263.chunk.js": "./static/js/19.5f9a9263.chunk.js",
"./static/js/19.5f9a9263.chunk.js.map": "./static/js/19.5f9a9263.chunk.js.map",
"./static/js/2.48f59130.chunk.js": "./static/js/2.48f59130.chunk.js",
"./static/js/2.48f59130.chunk.js.map": "./static/js/2.48f59130.chunk.js.map",
"./static/js/20.6efcbe58.chunk.js": "./static/js/20.6efcbe58.chunk.js",
"./static/js/20.6efcbe58.chunk.js.map": "./static/js/20.6efcbe58.chunk.js.map",
"./static/js/21.6e5a22af.chunk.js": "./static/js/21.6e5a22af.chunk.js",
"./static/js/21.6e5a22af.chunk.js.map": "./static/js/21.6e5a22af.chunk.js.map",
"./static/js/22.7c073e45.chunk.js": "./static/js/22.7c073e45.chunk.js",
"./static/js/22.7c073e45.chunk.js.map": "./static/js/22.7c073e45.chunk.js.map",
"./static/js/23.0abe5b59.chunk.js": "./static/js/23.0abe5b59.chunk.js",
"./static/js/23.0abe5b59.chunk.js.map": "./static/js/23.0abe5b59.chunk.js.map",
"./static/js/24.e1553222.chunk.js": "./static/js/24.e1553222.chunk.js",
"./static/js/24.e1553222.chunk.js.map": "./static/js/24.e1553222.chunk.js.map",
"./static/js/25.7f05ced8.chunk.js": "./static/js/25.7f05ced8.chunk.js",
"./static/js/25.7f05ced8.chunk.js.map": "./static/js/25.7f05ced8.chunk.js.map",
"./static/js/26.00916fb9.chunk.js": "./static/js/26.00916fb9.chunk.js",
"./static/js/26.00916fb9.chunk.js.map": "./static/js/26.00916fb9.chunk.js.map",
"./static/js/27.85a886e8.chunk.js": "./static/js/27.85a886e8.chunk.js",
"./static/js/27.85a886e8.chunk.js.map": "./static/js/27.85a886e8.chunk.js.map",
"./static/js/28.db5cbded.chunk.js": "./static/js/28.db5cbded.chunk.js",
"./static/js/28.db5cbded.chunk.js.map": "./static/js/28.db5cbded.chunk.js.map",
"./static/js/29.95e5a009.chunk.js": "./static/js/29.95e5a009.chunk.js",
"./static/js/29.95e5a009.chunk.js.map": "./static/js/29.95e5a009.chunk.js.map",
"./static/js/3.a357162e.chunk.js": "./static/js/3.a357162e.chunk.js",
"./static/js/3.a357162e.chunk.js.map": "./static/js/3.a357162e.chunk.js.map",
"./static/js/30.3482c43d.chunk.js": "./static/js/30.3482c43d.chunk.js",
"./static/js/30.3482c43d.chunk.js.map": "./static/js/30.3482c43d.chunk.js.map",
"./static/js/31.3edb9173.chunk.js": "./static/js/31.3edb9173.chunk.js",
"./static/js/31.3edb9173.chunk.js.map": "./static/js/31.3edb9173.chunk.js.map",
"./static/js/32.23fc5ec4.chunk.js": "./static/js/32.23fc5ec4.chunk.js",
"./static/js/32.23fc5ec4.chunk.js.map": "./static/js/32.23fc5ec4.chunk.js.map",
"./static/js/4.a72da972.chunk.js": "./static/js/4.a72da972.chunk.js",
"./static/js/4.a72da972.chunk.js.map": "./static/js/4.a72da972.chunk.js.map",
"./static/js/5.1853fe23.chunk.js": "./static/js/5.1853fe23.chunk.js",
"./static/js/5.1853fe23.chunk.js.map": "./static/js/5.1853fe23.chunk.js.map",
"./static/js/6.070d1eab.chunk.js": "./static/js/6.070d1eab.chunk.js",
"./static/js/6.070d1eab.chunk.js.map": "./static/js/6.070d1eab.chunk.js.map",
"./static/js/7.1ad7321f.chunk.js": "./static/js/7.1ad7321f.chunk.js",
"./static/js/7.1ad7321f.chunk.js.map": "./static/js/7.1ad7321f.chunk.js.map",
"./static/js/8.d5642b7b.chunk.js": "./static/js/8.d5642b7b.chunk.js",
"./static/js/8.d5642b7b.chunk.js.map": "./static/js/8.d5642b7b.chunk.js.map",
"./static/js/9.c6b81c3d.chunk.js": "./static/js/9.c6b81c3d.chunk.js",
"./static/js/9.c6b81c3d.chunk.js.map": "./static/js/9.c6b81c3d.chunk.js.map",
"main.css": "./static/css/main.3274c43b.css",
"main.css.map": "./static/css/main.3274c43b.css.map",
"main.js": "./static/js/main.9f01900e.js",
"main.js.map": "./static/js/main.9f01900e.js.map",
"static/media/ERASBD.ttf": "static/media/ERASBD.d5213044.ttf",
"static/media/background1.png": "static/media/background1.a34df396.png",
"static/media/background2.png": "static/media/background2.22ee659e.png",
"static/media/courses.jpg": "static/media/courses.7b27495b.jpg",
"static/media/group.png": "static/media/group.2f91e9cd.png",
"static/media/introduceback.jpg": "static/media/introduceback.3d75d3db.jpg",
"static/media/logo.svg": "static/media/logo.5d5d9eef.svg",
"static/media/match_ad.jpg": "static/media/match_ad.4e957369.jpg",
"static/media/message.svg": "static/media/message.c4f86b97.svg",
"static/media/messagegrey.svg": "static/media/messagegrey.31dd74f4.svg",
"static/media/nodata.png": "static/media/nodata.cde5b659.png",
"static/media/passall.png": "static/media/passall.46817e26.png",
"static/media/passpart.png": "static/media/passpart.4aaf3e6b.png",
"static/media/rc-tree.png": "static/media/rc-tree.776c7fe6.png",
"static/media/search.svg": "static/media/search.0e1dcc19.svg",
"static/media/vedio.png": "static/media/vedio.6a98b4f1.png"
"./static/js/0.f26528b1.chunk.js": "./static/js/0.f26528b1.chunk.js",
"./static/js/0.f26528b1.chunk.js.map": "./static/js/0.f26528b1.chunk.js.map",
"./static/js/1.cc33d6fc.chunk.js": "./static/js/1.cc33d6fc.chunk.js",
"./static/js/1.cc33d6fc.chunk.js.map": "./static/js/1.cc33d6fc.chunk.js.map",
"./static/js/10.943803f2.chunk.js": "./static/js/10.943803f2.chunk.js",
"./static/js/10.943803f2.chunk.js.map": "./static/js/10.943803f2.chunk.js.map",
"./static/js/11.c1a78f08.chunk.js": "./static/js/11.c1a78f08.chunk.js",
"./static/js/11.c1a78f08.chunk.js.map": "./static/js/11.c1a78f08.chunk.js.map",
"./static/js/12.fd69873b.chunk.js": "./static/js/12.fd69873b.chunk.js",
"./static/js/12.fd69873b.chunk.js.map": "./static/js/12.fd69873b.chunk.js.map",
"./static/js/13.d7c70bf4.chunk.js": "./static/js/13.d7c70bf4.chunk.js",
"./static/js/13.d7c70bf4.chunk.js.map": "./static/js/13.d7c70bf4.chunk.js.map",
"./static/js/14.af9b2fb8.chunk.js": "./static/js/14.af9b2fb8.chunk.js",
"./static/js/14.af9b2fb8.chunk.js.map": "./static/js/14.af9b2fb8.chunk.js.map",
"./static/js/15.05fc7db4.chunk.js": "./static/js/15.05fc7db4.chunk.js",
"./static/js/15.05fc7db4.chunk.js.map": "./static/js/15.05fc7db4.chunk.js.map",
"./static/js/16.efbbac6a.chunk.js": "./static/js/16.efbbac6a.chunk.js",
"./static/js/16.efbbac6a.chunk.js.map": "./static/js/16.efbbac6a.chunk.js.map",
"./static/js/17.17bd092d.chunk.js": "./static/js/17.17bd092d.chunk.js",
"./static/js/17.17bd092d.chunk.js.map": "./static/js/17.17bd092d.chunk.js.map",
"./static/js/18.24d189e1.chunk.js": "./static/js/18.24d189e1.chunk.js",
"./static/js/18.24d189e1.chunk.js.map": "./static/js/18.24d189e1.chunk.js.map",
"./static/js/19.cadd2a48.chunk.js": "./static/js/19.cadd2a48.chunk.js",
"./static/js/19.cadd2a48.chunk.js.map": "./static/js/19.cadd2a48.chunk.js.map",
"./static/js/2.9a1bdcfa.chunk.js": "./static/js/2.9a1bdcfa.chunk.js",
"./static/js/2.9a1bdcfa.chunk.js.map": "./static/js/2.9a1bdcfa.chunk.js.map",
"./static/js/20.5086cbe2.chunk.js": "./static/js/20.5086cbe2.chunk.js",
"./static/js/20.5086cbe2.chunk.js.map": "./static/js/20.5086cbe2.chunk.js.map",
"./static/js/21.d3d939d5.chunk.js": "./static/js/21.d3d939d5.chunk.js",
"./static/js/21.d3d939d5.chunk.js.map": "./static/js/21.d3d939d5.chunk.js.map",
"./static/js/22.234575f5.chunk.js": "./static/js/22.234575f5.chunk.js",
"./static/js/22.234575f5.chunk.js.map": "./static/js/22.234575f5.chunk.js.map",
"./static/js/23.67ab77f0.chunk.js": "./static/js/23.67ab77f0.chunk.js",
"./static/js/23.67ab77f0.chunk.js.map": "./static/js/23.67ab77f0.chunk.js.map",
"./static/js/24.27d7be07.chunk.js": "./static/js/24.27d7be07.chunk.js",
"./static/js/24.27d7be07.chunk.js.map": "./static/js/24.27d7be07.chunk.js.map",
"./static/js/25.c8a915ae.chunk.js": "./static/js/25.c8a915ae.chunk.js",
"./static/js/25.c8a915ae.chunk.js.map": "./static/js/25.c8a915ae.chunk.js.map",
"./static/js/26.488c5233.chunk.js": "./static/js/26.488c5233.chunk.js",
"./static/js/26.488c5233.chunk.js.map": "./static/js/26.488c5233.chunk.js.map",
"./static/js/27.ba45f1d3.chunk.js": "./static/js/27.ba45f1d3.chunk.js",
"./static/js/27.ba45f1d3.chunk.js.map": "./static/js/27.ba45f1d3.chunk.js.map",
"./static/js/28.8071de5d.chunk.js": "./static/js/28.8071de5d.chunk.js",
"./static/js/28.8071de5d.chunk.js.map": "./static/js/28.8071de5d.chunk.js.map",
"./static/js/29.67275bf0.chunk.js": "./static/js/29.67275bf0.chunk.js",
"./static/js/29.67275bf0.chunk.js.map": "./static/js/29.67275bf0.chunk.js.map",
"./static/js/3.935bae8c.chunk.js": "./static/js/3.935bae8c.chunk.js",
"./static/js/3.935bae8c.chunk.js.map": "./static/js/3.935bae8c.chunk.js.map",
"./static/js/30.4964944f.chunk.js": "./static/js/30.4964944f.chunk.js",
"./static/js/30.4964944f.chunk.js.map": "./static/js/30.4964944f.chunk.js.map",
"./static/js/31.5a1072f1.chunk.js": "./static/js/31.5a1072f1.chunk.js",
"./static/js/31.5a1072f1.chunk.js.map": "./static/js/31.5a1072f1.chunk.js.map",
"./static/js/32.2ff1fc95.chunk.js": "./static/js/32.2ff1fc95.chunk.js",
"./static/js/32.2ff1fc95.chunk.js.map": "./static/js/32.2ff1fc95.chunk.js.map",
"./static/js/4.017bf48d.chunk.js": "./static/js/4.017bf48d.chunk.js",
"./static/js/4.017bf48d.chunk.js.map": "./static/js/4.017bf48d.chunk.js.map",
"./static/js/5.27b42764.chunk.js": "./static/js/5.27b42764.chunk.js",
"./static/js/5.27b42764.chunk.js.map": "./static/js/5.27b42764.chunk.js.map",
"./static/js/6.1d80a66b.chunk.js": "./static/js/6.1d80a66b.chunk.js",
"./static/js/6.1d80a66b.chunk.js.map": "./static/js/6.1d80a66b.chunk.js.map",
"./static/js/7.03d1beb1.chunk.js": "./static/js/7.03d1beb1.chunk.js",
"./static/js/7.03d1beb1.chunk.js.map": "./static/js/7.03d1beb1.chunk.js.map",
"./static/js/8.ea688812.chunk.js": "./static/js/8.ea688812.chunk.js",
"./static/js/8.ea688812.chunk.js.map": "./static/js/8.ea688812.chunk.js.map",
"./static/js/9.2971266e.chunk.js": "./static/js/9.2971266e.chunk.js",
"./static/js/9.2971266e.chunk.js.map": "./static/js/9.2971266e.chunk.js.map",
"main.css": "./static/css/main.80b6ec5e.css",
"main.css.map": "./static/css/main.80b6ec5e.css.map",
"main.js": "./static/js/main.b4ee5e8a.js",
"main.js.map": "./static/js/main.b4ee5e8a.js.map",
"static\\media\\ERASBD.ttf": "static/media/ERASBD.d5213044.ttf",
"static\\media\\background1.png": "static/media/background1.a34df396.png",
"static\\media\\background2.png": "static/media/background2.22ee659e.png",
"static\\media\\courses.jpg": "static/media/courses.7b27495b.jpg",
"static\\media\\group.png": "static/media/group.2f91e9cd.png",
"static\\media\\introduceback.jpg": "static/media/introduceback.3d75d3db.jpg",
"static\\media\\logo.svg": "static/media/logo.ee7cd8ed.svg",
"static\\media\\match_ad.jpg": "static/media/match_ad.4e957369.jpg",
"static\\media\\message.svg": "static/media/message.a7af2a8f.svg",
"static\\media\\messagegrey.svg": "static/media/messagegrey.8c1dff55.svg",
"static\\media\\nodata.png": "static/media/nodata.cde5b659.png",
"static\\media\\passall.png": "static/media/passall.46817e26.png",
"static\\media\\passpart.png": "static/media/passpart.4aaf3e6b.png",
"static\\media\\rc-tree.png": "static/media/rc-tree.776c7fe6.png",
"static\\media\\search.svg": "static/media/search.0e1dcc19.svg",
"static\\media\\vedio.png": "static/media/vedio.6a98b4f1.png"
}

@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"><meta name="theme-color" content="#000000"><meta name="renderer" content="webkit"/><meta name="force-rendering" content="webkit"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><link rel="manifest" href="/manifest.json"><link rel="shortcut icon" href="/favicon.ico"><title>Educoder</title><script type="text/javascript">window.__isR=!0</script><link rel="stylesheet" href="/css/css_min_all.css"><link rel="stylesheet" href="http://testbdweb.educoder.net/assets/iconfont/iconfont.css"><link href="/react/build/./static/css/main.3274c43b.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="md_div" style="display:none"></div><div id="root" class="page -layout-v -fit"></div><div id="picture_display" style="display:none"></div><script type="text/javascript" src="/js/js_min_all.js"></script><script type="text/javascript" src="http://testbdweb.educoder.net/assets/kindeditor/kindeditor.js"></script><script type="text/javascript" src="/js/create_kindeditor.js"></script><script type="text/javascript" src="http://testbdweb.educoder.net/javascripts/educoder/edu_application.js"></script><script type="text/javascript" src="/react/build/./static/js/main.9f01900e.js"></script></body></html>
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"><meta name="theme-color" content="#000000"><meta name="renderer" content="webkit"/><meta name="force-rendering" content="webkit"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><link rel="manifest" href="/manifest.json"><link rel="shortcut icon" href="/favicon.ico"><title>Educoder</title><script type="text/javascript">window.__isR=!0</script><link rel="stylesheet" href="/css/css_min_all.css"><link rel="stylesheet" href="http://testbdweb.educoder.net/assets/iconfont/iconfont.css"><link href="/react/build/./static/css/main.80b6ec5e.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="md_div" style="display:none"></div><div id="root" class="page -layout-v -fit"></div><div id="picture_display" style="display:none"></div><script type="text/javascript" src="/js/js_min_all.js"></script><script type="text/javascript" src="http://testbdweb.educoder.net/assets/kindeditor/kindeditor.js"></script><script type="text/javascript" src="/js/create_kindeditor.js"></script><script type="text/javascript" src="http://testbdweb.educoder.net/javascripts/educoder/edu_application.js"></script><script type="text/javascript" src="/react/build/./static/js/main.b4ee5e8a.js"></script></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save