Merge branch 'develop' of https://git.trustie.net/jacknudt/trustieforge into develop
This commit is contained in:
commit
fddf03d80c
2
1234567
2
1234567
|
@ -1 +1 @@
|
|||
{"access_token":"7MBMEBoE6sSC15bIHZYAZSxj47yCKlbWEVjrkUgEJxPP3K083tbhc1RIWmxGu3WoB5dAXxK_yd4l1jrcvt6YrsTcOfFGRirOHVfzrpvhsQgxOoxcdc7YljfO_dnwUtWgFTAcAIALZG","expires_in":7200,"got_token_at":1460189856}
|
||||
{"access_token":"q51KZUeA6_-CCCH-Buy1mxFmRjcrCViHgk2mHHHqEDbjuA_pgCM1IyW1DASYvpzyB06xHiarujo3rz1Ucq3GRoXdgQ7hAoFCzkL_q3Z5vczLjwAjowAVwmulYE-cAij8ATUfADAWPQ","expires_in":7200,"got_token_at":1460601163}
|
|
@ -13,7 +13,7 @@ module Mobile
|
|||
else
|
||||
case f
|
||||
when :img_url
|
||||
url_to_avatar(u)
|
||||
"/images/#{url_to_avatar(u)}"
|
||||
when :gender
|
||||
u.nil? || u.user_extensions.nil? || u.user_extensions.gender.nil? ? 0 : u.user_extensions.gender
|
||||
when :work_unit
|
||||
|
@ -24,6 +24,8 @@ module Mobile
|
|||
u.nil? || u.user_extensions.nil? ? "" : u.user_extensions.brief_introduction
|
||||
when :student_num
|
||||
u.nil? || u.user_extensions.nil? ? "" : u.user_extensions.student_id
|
||||
when :realname
|
||||
u.nil? ? "" : get_user_realname(u)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -37,7 +39,7 @@ module Mobile
|
|||
#昵称
|
||||
expose :nickname
|
||||
#真名
|
||||
expose :realname
|
||||
user_expose :realname
|
||||
#性别
|
||||
user_expose :gender
|
||||
#我的二维码
|
||||
|
|
|
@ -557,4 +557,14 @@ class AdminController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
#代码测试列表
|
||||
def code_work_tests
|
||||
@code_work_tests = StudentWorkTest.find_by_sql("select a.* ,b.id as homeworkid,d.language from student_work_tests as a , homework_commons as b ,student_works as c, homework_detail_programings as d where a.student_work_id = c.id and b.id = c.homework_common_id and c.homework_common_id = d.homework_common_id order by a.created_at desc")
|
||||
#@code_work_tests = StudentWorkTest.order('created_at desc')
|
||||
@code_work_tests = paginateHelper @code_work_tests,30
|
||||
@page = (params['page'] || 1).to_i - 1
|
||||
respond_to do |format|
|
||||
format.html
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -883,6 +883,7 @@ class CoursesController < ApplicationController
|
|||
@course_activities = course_activities.order('updated_at desc').limit(10).offset(@page * 10)
|
||||
end
|
||||
@type = params[:type]
|
||||
|
||||
respond_to do |format|
|
||||
format.js
|
||||
format.html{render :layout => 'base_courses'}
|
||||
|
@ -923,6 +924,66 @@ class CoursesController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
def search_homework_member homeworks,name
|
||||
if name == ""
|
||||
select_homework = homeworks
|
||||
else
|
||||
name = name.downcase
|
||||
select_homework = homeworks.select{ |homework|
|
||||
homework.user[:login].to_s.downcase.include?(name) || homework.user.user_extensions[:student_id].to_s.downcase.include?(name) || (homework.user[:lastname].to_s.downcase + homework.user[:firstname].to_s.downcase).include?(name)
|
||||
}
|
||||
end
|
||||
select_homework
|
||||
end
|
||||
|
||||
# 作业查重
|
||||
def code_repeat
|
||||
#代码查重新加的
|
||||
@order,@b_sort,@name,@group = params[:order] || "score",params[:sort] || "desc",params[:name] || "",params[:group]
|
||||
|
||||
@is_teacher = User.current.allowed_to?(:as_teacher,@course) || User.current.admin?
|
||||
@homework = HomeworkCommon.find params[:homework]
|
||||
#order("#{@order} #{@b_sort}"
|
||||
@student_works = search_homework_member @homework.student_works.select("student_works.*,IF(final_score is null,null,IF(final_score = 0, 0, final_score - absence_penalty - late_penalty)) as score").order("simi_value desc"),@name
|
||||
|
||||
@works_hash = {}
|
||||
|
||||
@student_works.each do |tmpwork|
|
||||
@works_hash[tmpwork.id] = tmpwork
|
||||
end
|
||||
|
||||
#respond_to do |format|
|
||||
#format.html {render :layout => 'base_courses'}
|
||||
#end
|
||||
end
|
||||
|
||||
def show_comparecode
|
||||
|
||||
src_id = params[:src_id]
|
||||
dst_id = params[:dst_id]
|
||||
|
||||
src_work = StudentWork.where("id =?", src_id).first
|
||||
|
||||
@homework = HomeworkCommon.find params[:homework_id]
|
||||
|
||||
@src_code = src_work.description
|
||||
src_user = User.where("id =?", src_work.user_id).first
|
||||
|
||||
@src_username = src_user.try(:realname) != " " ? src_user.lastname + src_user.firstname : src_user.try(:login)
|
||||
|
||||
#descriotion user name
|
||||
|
||||
dst_work = StudentWork.where("id =?", dst_id).first
|
||||
@dst_code = dst_work.description
|
||||
dst_user = User.where("id =?", dst_work.user_id).first
|
||||
|
||||
@dst_username = dst_user.try(:realname) != " " ? dst_user.lastname + dst_user.firstname : dst_user.try(:login)
|
||||
|
||||
respond_to do |format|
|
||||
format.js
|
||||
end
|
||||
end
|
||||
|
||||
#根据已有课程复制课程
|
||||
#param id:已有课程ID
|
||||
def copy_course
|
||||
|
@ -1077,7 +1138,7 @@ class CoursesController < ApplicationController
|
|||
sql_select = ""
|
||||
if groupid == 0
|
||||
sql_select = "SELECT members.*,(
|
||||
SELECT SUM(IF(student_works.final_score IS NULL,NULL,IF(student_works.final_score =0,0,student_works.final_score - student_works.absence_penalty - student_works.late_penalty)))
|
||||
SELECT SUM(IF(student_works.final_score IS NULL,NULL,IF(student_works.final_score =0,0,IF((student_works.final_score - student_works.absence_penalty - student_works.late_penalty) < 0 , 0, student_works.final_score - student_works.absence_penalty - student_works.late_penalty))))
|
||||
FROM student_works,homework_commons
|
||||
WHERE student_works.homework_common_id = homework_commons.id
|
||||
AND homework_commons.course_id = #{@course.id}
|
||||
|
@ -1089,7 +1150,7 @@ class CoursesController < ApplicationController
|
|||
WHERE members.course_id = #{@course.id} ORDER BY score #{score_sort_by}"
|
||||
else
|
||||
sql_select = "SELECT members.*,(
|
||||
SELECT SUM(IF(student_works.final_score IS NULL,NULL,IF(student_works.final_score =0,0,student_works.final_score - student_works.absence_penalty - student_works.late_penalty)))
|
||||
SELECT SUM(IF(student_works.final_score IS NULL,NULL,IF(student_works.final_score =0,0,IF((student_works.final_score - student_works.absence_penalty - student_works.late_penalty) < 0 , 0, student_works.final_score - student_works.absence_penalty - student_works.late_penalty))))
|
||||
FROM student_works,homework_commons
|
||||
WHERE student_works.homework_common_id = homework_commons.id
|
||||
AND homework_commons.course_id = #{@course.id}
|
||||
|
|
|
@ -17,9 +17,11 @@ class HomeworkCommonController < ApplicationController
|
|||
@page = params[:page] ? params[:page].to_i + 1 : 0
|
||||
@is_teacher = User.current.logged? && (User.current.admin? || User.current.allowed_to?(:as_teacher,@course))
|
||||
if @is_teacher
|
||||
@homeworks = @course.homework_commons.order("created_at desc").limit(10).offset(@page * 10)
|
||||
@homeworks = @course.homework_commons.order("updated_at desc").limit(10).offset(@page * 10)
|
||||
@homework_commons = @course.homework_commons.order("created_at desc").limit(10).offset(@page * 10)
|
||||
else
|
||||
@homeworks = @course.homework_commons.where("publish_time <= '#{Date.today}'").order("created_at desc").limit(10).offset(@page * 10)
|
||||
@homeworks = @course.homework_commons.where("publish_time <= '#{Date.today}'").order("updated_at desc").limit(10).offset(@page * 10)
|
||||
@homework_commons = @course.homework_commons.where("publish_time <= '#{Date.today}'").order("created_at desc").limit(10).offset(@page * 10)
|
||||
end
|
||||
@is_student = User.current.logged? && (User.current.admin? || (User.current.member_of_course?(@course) && !@is_teacher))
|
||||
@is_new = params[:is_new]
|
||||
|
|
|
@ -352,8 +352,13 @@ class OrganizationsController < ApplicationController
|
|||
if !params[:name].nil?
|
||||
condition = "%#{params[:name].strip}%".gsub(" ","")
|
||||
end
|
||||
if User.current.admin?
|
||||
sql = "select courses.* from courses where courses.is_public = 1 and courses.name like '#{condition}'"+
|
||||
"and courses.id not in (select distinct org_courses.course_id from org_courses where org_courses.organization_id = #{@organization.id}) and courses.is_delete=0"
|
||||
else
|
||||
sql = "select courses.* from courses inner join members on courses.id = members.course_id where members.user_id = #{User.current.id} and courses.is_public = 1 and courses.name like '#{condition}'"+
|
||||
"and courses.id not in (select distinct org_courses.course_id from org_courses where org_courses.organization_id = #{@organization.id}) and courses.is_delete=0"
|
||||
end
|
||||
#user_courses = Course.find_by_sql(sql)
|
||||
@courses = Course.find_by_sql(sql)
|
||||
# @added_course_ids = @organization.courses.map(&:id)
|
||||
|
@ -396,8 +401,13 @@ class OrganizationsController < ApplicationController
|
|||
if !params[:name].nil?
|
||||
condition = "%#{params[:name].strip}%".gsub(" ","")
|
||||
end
|
||||
if User.current.admin?
|
||||
sql = "select projects.* from projects where projects.status != 9 and projects.is_public = 1 and projects.name like '#{condition}'" +
|
||||
" and projects.id not in (select org_projects.project_id from org_projects where organization_id = #{@organization.id}) and status=1"
|
||||
else
|
||||
sql = "select projects.* from projects inner join members on projects.id = members.project_id where members.user_id = #{User.current.id} and projects.status != 9 and projects.is_public = 1 and projects.name like '#{condition}'" +
|
||||
" and projects.id not in (select org_projects.project_id from org_projects where organization_id = #{@organization.id}) and status=1"
|
||||
end
|
||||
#user_projects = Course.find_by_sql(sql)
|
||||
@projects = Course.find_by_sql(sql)
|
||||
# @added_course_ids = @organization.projects.map(&:id)
|
||||
|
|
|
@ -5,7 +5,7 @@ class StudentWorkController < ApplicationController
|
|||
include ApplicationHelper
|
||||
require 'bigdecimal'
|
||||
require "base64"
|
||||
before_filter :find_homework, :only => [:new, :index, :create, :student_work_absence_penalty, :absence_penalty_list, :evaluation_list, :program_test,:program_test_ex,:set_score_rule,:forbidden_anonymous_comment,:delete_work,:new_student_work_project,:student_work_project,:cancel_relate_project,:search_course_students]
|
||||
before_filter :find_homework, :only => [:new, :index, :create, :student_work_absence_penalty, :absence_penalty_list, :evaluation_list, :program_test,:program_test_ex,:code_repeattest,:set_score_rule,:forbidden_anonymous_comment,:delete_work,:new_student_work_project,:student_work_project,:cancel_relate_project,:search_course_students]
|
||||
before_filter :find_work, :only => [:edit, :update, :show, :destroy, :add_score, :praise_student_work,:retry_work,:revise_attachment]
|
||||
before_filter :member_of_course, :only => [:new, :create, :show, :add_score, :praise_student_work]
|
||||
before_filter :author_of_work, :only => [:edit, :update, :destroy]
|
||||
|
@ -81,6 +81,8 @@ class StudentWorkController < ApplicationController
|
|||
#根据传入的tIndex确定是第几次测试
|
||||
#之后如果觉得很卡 可以改成将结果传回JS再以参数形式传回来
|
||||
def program_test_ex
|
||||
tStarttime = Time.now
|
||||
|
||||
is_test = params[:is_test] == 'true'
|
||||
resultObj = {status: 0, results: [], error_msg: '', time: Time.now.strftime('%Y-%m-%d %T'),tseq:1,tcount:1,testid:1} #保存每测试一次返回的结果
|
||||
|
||||
|
@ -134,6 +136,16 @@ class StudentWorkController < ApplicationController
|
|||
end
|
||||
|
||||
#每次从数据库取出上次的结果加上本次的结果再存入数据库
|
||||
tEndtime = Time.now
|
||||
tUsedtime = (tEndtime.to_i-tStarttime.to_i)*1000+(tEndtime.usec - tStarttime.usec)/1000
|
||||
|
||||
if result["status"].to_i != -2
|
||||
result["results"].first['user_wait'] = tUsedtime
|
||||
end
|
||||
|
||||
if result["results"][0]["status"].to_i == 2
|
||||
result["status"] = 2
|
||||
end
|
||||
status = result["status"]
|
||||
if index == 1
|
||||
student_work_test = student_work.student_work_tests.build(status: status,
|
||||
|
@ -162,6 +174,11 @@ class StudentWorkController < ApplicationController
|
|||
resultObj[:index] = student_work.student_work_tests.count
|
||||
end
|
||||
|
||||
tEndtime = Time.now
|
||||
tUsedtime = (tEndtime.to_i-tStarttime.to_i)*1000+(tEndtime.usec - tStarttime.usec)/1000
|
||||
|
||||
logger.debug "program_test_ex user wait time = #{tUsedtime} 毫秒"
|
||||
|
||||
#渲染返回结果
|
||||
render :json => resultObj
|
||||
end
|
||||
|
@ -169,6 +186,106 @@ class StudentWorkController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
#找出该作业的所有提交作业
|
||||
def find_all_student_work_by_homeid()
|
||||
all_studentwork = StudentWork.where("homework_common_id =?", @homework.id)
|
||||
|
||||
all_studentwork
|
||||
end
|
||||
|
||||
def request_code_repeattest(src)
|
||||
url = "#{Redmine::Configuration['jplag_server']}api/realtime_test.json"
|
||||
|
||||
factor = []
|
||||
src.each do |test|
|
||||
factor << {work_id: test.id, des: test.description,created_at:test.created_at.to_i}
|
||||
end
|
||||
|
||||
solutions = {
|
||||
homeid:@homework.id,
|
||||
language:@homework.homework_detail_programing.language,
|
||||
factor: factor
|
||||
}
|
||||
uri = URI(url)
|
||||
body = solutions.to_json
|
||||
|
||||
logger.debug "send body"
|
||||
logger.debug body
|
||||
|
||||
res = Net::HTTP.new(uri.host, uri.port).start do |client|
|
||||
request = Net::HTTP::Post.new(uri.path)
|
||||
request.body = body
|
||||
request["Content-Type"] = "application/json"
|
||||
client.request(request)
|
||||
end
|
||||
|
||||
JSON.parse(res.body)
|
||||
end
|
||||
|
||||
#代码查重 status: 0完成 -2不需要查重 -1查重失败不支持该语言
|
||||
def code_repeattest
|
||||
tStarttime = Time.now
|
||||
logger.debug "code_repeattest start is #{tStarttime}}"
|
||||
resultObj = {status: -2}
|
||||
|
||||
@homework = HomeworkCommon.find params[:homework]
|
||||
|
||||
all_studentwork = find_all_student_work_by_homeid()
|
||||
|
||||
if all_studentwork == nil
|
||||
resultObj[:status] = -2
|
||||
elsif all_studentwork.count <= 1
|
||||
resultObj[:status] = -2
|
||||
else
|
||||
|
||||
#@homework.homework_detail_programing.language、id、description
|
||||
logger.debug "time1 is #{Time.now.usec} "
|
||||
result = request_code_repeattest(all_studentwork)
|
||||
logger.debug "time2 is #{Time.now.usec} "
|
||||
|
||||
resultObj[:status] = result['status'].to_i
|
||||
# resultObj[:results] = result['results']
|
||||
|
||||
#Time.now, simi_id = simiworkid , simi_value = simivalue
|
||||
if resultObj[:status] == 0
|
||||
@homework.simi_time = Time.now
|
||||
resultObj[:comparetime] = @homework.simi_time
|
||||
@homework.update_column('simi_time', @homework.simi_time)
|
||||
|
||||
logger.debug "time3 is #{Time.now.usec} "
|
||||
result['results'].each do |key,value|
|
||||
if value['simiworkid'].to_i > 0
|
||||
@student_work = StudentWork.where("id =?", key.to_i).first
|
||||
@student_work.update_column('simi_id', value['simiworkid'].to_i)
|
||||
@student_work.update_column('simi_value', value['simivalue'].to_i)
|
||||
end
|
||||
# sqlstr = "update student_works set simi_id=#{value['simiworkid']},simi_value=#{value['simivalue']} where id=#{key.to_i} "
|
||||
# dbh.execute(sqlstr)
|
||||
|
||||
end
|
||||
logger.debug "time4 is #{Time.now.usec} "
|
||||
end
|
||||
end
|
||||
tEndtime = Time.now
|
||||
logger.debug "code_repeattest end is #{tEndtime}}"
|
||||
tUsedtime = (tEndtime.to_i-tStarttime.to_i)*1000000+(tEndtime.usec - tStarttime.usec)
|
||||
logger.debug "code_repeattest userd utime is #{tUsedtime}"
|
||||
render :json => resultObj
|
||||
end
|
||||
|
||||
def last_codecomparetime
|
||||
resultObj = {status: 0}
|
||||
@homework = HomeworkCommon.find params[:homework]
|
||||
|
||||
#转换一下
|
||||
if @homework.simi_time != nil
|
||||
resultObj[:comparetime] = Time.parse(@homework.simi_time.to_s).strftime("%Y-%m-%d %H:%M")
|
||||
else
|
||||
resultObj[:comparetime] = @homework.simi_time
|
||||
end
|
||||
|
||||
render :json => resultObj
|
||||
end
|
||||
|
||||
def index
|
||||
# 作业消息状态更新
|
||||
|
@ -351,6 +468,7 @@ class StudentWorkController < ApplicationController
|
|||
render_403
|
||||
return
|
||||
end
|
||||
|
||||
@student_work_count = (search_homework_member @homework.student_works.select("student_works.*,IF(final_score is null,null,IF(final_score = 0, 0, final_score - absence_penalty - late_penalty)) as score").order("#{@order} #{@b_sort}"),@name).count
|
||||
end
|
||||
|
||||
|
@ -1152,6 +1270,7 @@ class StudentWorkController < ApplicationController
|
|||
request["Content-Type"] = "application/json"
|
||||
client.request(request)
|
||||
end
|
||||
|
||||
JSON.parse(res.body)
|
||||
end
|
||||
|
||||
|
|
|
@ -1122,13 +1122,13 @@ class UsersController < ApplicationController
|
|||
#显示更多用户课程
|
||||
def user_courses4show
|
||||
@page = params[:page].to_i + 1
|
||||
@courses = @user.courses.visible.where("is_delete =?", 0).select("courses.*,(SELECT MAX(created_at) FROM `course_activities` WHERE course_activities.course_id = courses.id) AS a").order("a desc").limit(5).offset(@page * 5)
|
||||
@courses = @user.courses.visible.where("is_delete =?", 0).select("courses.*,(SELECT MAX(updated_at) FROM `course_activities` WHERE course_activities.course_id = courses.id) AS a").order("a desc").limit(5).offset(@page * 5)
|
||||
end
|
||||
|
||||
#显示更多用户项目
|
||||
def user_projects4show
|
||||
@page = params[:page].to_i + 1
|
||||
@projects = @user.projects.visible.select("projects.*,(SELECT MAX(created_at) FROM `forge_activities` WHERE forge_activities.project_id = projects.id) AS a").order("a desc").limit(5).offset(@page * 5)
|
||||
@projects = @user.projects.visible.select("projects.*,(SELECT MAX(updated_at) FROM `forge_activities` WHERE forge_activities.project_id = projects.id) AS a").order("a desc").limit(5).offset(@page * 5)
|
||||
end
|
||||
|
||||
def user_course_activities
|
||||
|
|
|
@ -143,7 +143,7 @@ class WechatsController < ActionController::Base
|
|||
url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=#{Wechat.config.appid}&redirect_uri=#{login_wechat_url}&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect"
|
||||
article.item title: "#{n[:title]}",
|
||||
description: n[:content],
|
||||
pic_url: 'http://wechat.trustie.net/images/trustie_logo2.png',
|
||||
pic_url: 'https://www.trustie.net/images/trustie_logo2.png',
|
||||
url: url
|
||||
end
|
||||
end
|
||||
|
|
|
@ -27,6 +27,10 @@ module ApiHelper
|
|||
location
|
||||
end
|
||||
|
||||
def get_user_realname user
|
||||
name = user.lastname + user.firstname
|
||||
name.empty? || name.nil? || name == " " ? user.login : name
|
||||
end
|
||||
|
||||
def get_assigned_homeworks(homeworks, n, index)
|
||||
homeworks += homeworks
|
||||
|
|
|
@ -850,7 +850,7 @@ module CoursesHelper
|
|||
# 学生按作业总分排序,取前8个
|
||||
def hero_homework_score(course, score_sort_by)
|
||||
sql_select = "SELECT members.*,(
|
||||
SELECT SUM(IF(student_works.final_score is null,null,IF(student_works.final_score = 0, 0, student_works.final_score - student_works.absence_penalty - student_works.late_penalty)))
|
||||
SELECT SUM(IF(student_works.final_score IS NULL,NULL,IF(student_works.final_score =0,0,IF((student_works.final_score - student_works.absence_penalty - student_works.late_penalty) < 0 , 0, student_works.final_score - student_works.absence_penalty - student_works.late_penalty))))
|
||||
FROM student_works,homework_commons
|
||||
WHERE student_works.homework_common_id = homework_commons.id
|
||||
AND homework_commons.course_id = #{course.id}
|
||||
|
|
|
@ -78,48 +78,13 @@ class BlogComment < ActiveRecord::Base
|
|||
|
||||
#博客回复微信模板消息
|
||||
def blog_wechat_message
|
||||
# 发布博客
|
||||
unless self.parent_id.nil?
|
||||
uw = UserWechat.where(user_id: self.parent.author_id).first
|
||||
#unless uw.nil? && self.parent.author_id != User.current.id
|
||||
unless uw.nil?
|
||||
data = {
|
||||
touser:uw.openid,
|
||||
template_id:"A_3f5v90-zK73V9Kijm-paDkl9S-NuM8Cf-1UJi92_c",
|
||||
url:"http://www.trustie.net/",
|
||||
topcolor:"#FF0000",
|
||||
data:{
|
||||
first: {
|
||||
value:"您的博客有新回复了",
|
||||
color:"#173177"
|
||||
},
|
||||
keyword1:{
|
||||
value:self.author.try(:realname),
|
||||
color:"#173177"
|
||||
},
|
||||
keyword2:{
|
||||
value:format_time(self.created_at),
|
||||
color:"#173177"
|
||||
},
|
||||
keyword3:{
|
||||
value:self.content.html_safe,
|
||||
color:"#173177"
|
||||
},
|
||||
remark:{
|
||||
value:"具体内容请点击详情查看网站",
|
||||
color:"#173177"
|
||||
}
|
||||
}
|
||||
}
|
||||
logger.info "start send template message: #{data}"
|
||||
begin
|
||||
req = Wechat.api.template_message_send Wechat::Message.to(uw.openid).template(data)
|
||||
rescue Exception => e
|
||||
logger.error "[blog_comment] ===> #{e}"
|
||||
ws = WechatService.new
|
||||
if self.parent_id.nil?
|
||||
self.author.watcher_users.each do |watcher|
|
||||
ws.message_update_template watcher.id, "#{l(:label_new_blog_template)}", self.author.try(:realname) + " 发表了博客:" + self.title.html_safe, format_time(self.created_at)
|
||||
end
|
||||
logger.info "send over. #{req}"
|
||||
else
|
||||
ws.comment_template self.parent.author_id, "#{l(:label_blog_comment_template)}", self.author.try(:realname), format_time(self.created_at), self.content.html_safe
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class Comment < ActiveRecord::Base
|
||||
require 'net/http'
|
||||
require 'json'
|
||||
include Redmine::SafeAttributes
|
||||
include ApplicationHelper
|
||||
has_many_kindeditor_assets :assets, :dependent => :destroy
|
||||
|
@ -39,13 +41,16 @@ class Comment < ActiveRecord::Base
|
|||
after_destroy :down_course_score
|
||||
|
||||
def act_as_system_message
|
||||
ws = WechatService.new
|
||||
if self.commented.course
|
||||
if self.author_id != self.commented.author_id
|
||||
self.course_messages << CourseMessage.new(:user_id => self.commented.author_id, :course_id => self.commented.course.id, :viewed => false)
|
||||
ws.comment_template self.commented.author_id, "#{l(:label_notice_comment_template)}", self.author.try(:realname), format_time(self.created_on), self.comments.html_safe
|
||||
end
|
||||
else # 项目相关
|
||||
if self.author_id != self.commented.author_id
|
||||
self.forge_messages << ForgeMessage.new(:user_id => self.commented.author_id, :project_id => self.commented.project.id, :viewed => false)
|
||||
ws.comment_template self.commented.author_id, "#{l(:label_news_comment_template)}", self.author.try(:realname), format_time(self.created_on), self.comments.html_safe
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#老师布置的作业表
|
||||
#homework_type: 0:普通作业;1:匿评作业;2:编程作业
|
||||
class HomeworkCommon < ActiveRecord::Base
|
||||
# attr_accessible :name, :user_id, :description, :publish_time, :end_time, :homework_type, :late_penalty, :course_id
|
||||
# attr_accessible :name, :user_id, :description, :publish_time, :end_time, :homework_type, :late_penalty, :course_id,:simi_time
|
||||
require 'net/http'
|
||||
require 'json'
|
||||
include Redmine::SafeAttributes
|
||||
|
@ -59,6 +59,8 @@ class HomeworkCommon < ActiveRecord::Base
|
|||
self.course.members.each do |m|
|
||||
# if m.user_id != self.user_id
|
||||
self.course_messages << CourseMessage.new(:user_id => m.user_id, :course_id => self.course_id, :viewed => false)
|
||||
ws = WechatService.new
|
||||
ws.homework_template(m.user_id, "#{l(:label_new_homework_template)}", self.course.name, self.name.html_safe, self.end_time.to_s + " 23:59:59")
|
||||
# end
|
||||
end
|
||||
end
|
||||
|
@ -104,44 +106,8 @@ class HomeworkCommon < ActiveRecord::Base
|
|||
#修改作业后发送微信模板消息
|
||||
def wechat_message
|
||||
self.course.members.each do |member|
|
||||
uw = UserWechat.where("user_id=?", member.user_id).first
|
||||
unless uw.nil?
|
||||
data = {
|
||||
touser:uw.openid,
|
||||
template_id:"3e5Dj2GIx8MOcMyRKpTUEQnM7Tg0ASSCNc01NS9HCGI",
|
||||
url:"http://www.trustie.net/",
|
||||
topcolor:"#FF0000",
|
||||
data:{
|
||||
first: {
|
||||
value:"您的作业已被修改",
|
||||
color:"#173177"
|
||||
},
|
||||
keyword1:{
|
||||
value:self.course.name,
|
||||
color:"#173177"
|
||||
},
|
||||
keyword2:{
|
||||
value:self.name,
|
||||
color:"#173177"
|
||||
},
|
||||
keyword3:{
|
||||
value:self.end_time.to_s + "23:59:59",
|
||||
color:"#173177"
|
||||
},
|
||||
remark:{
|
||||
value:"具体内容请点击详情查看网站",
|
||||
color:"#173177"
|
||||
}
|
||||
}
|
||||
}
|
||||
logger.info "start send template message: #{data}"
|
||||
begin
|
||||
req = Wechat.api.template_message_send Wechat::Message.to(uw.openid).template(data)
|
||||
rescue Exception => e
|
||||
logger.error "[homework_common] ===> #{e}"
|
||||
end
|
||||
logger.info "send over. #{req}"
|
||||
end
|
||||
ws = WechatService.new
|
||||
ws.homework_template(member.user_id, "#{l(:label_update_homework_template)}", self.course.name, self.name.html_safe, self.end_time.to_s + " 23:59:59")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#encoding: utf-8
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
|
@ -16,6 +17,8 @@
|
|||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class Issue < ActiveRecord::Base
|
||||
require 'net/http'
|
||||
require 'json'
|
||||
include Redmine::SafeAttributes
|
||||
include Redmine::Utils::DateCalculation
|
||||
include UserScoreHelper
|
||||
|
@ -156,6 +159,8 @@ class Issue < ActiveRecord::Base
|
|||
# 指派给自己的缺陷不提示消息
|
||||
unless self.author_id == self.assigned_to_id
|
||||
self.forge_messages << ForgeMessage.new(:user_id => self.assigned_to_id, :project_id => self.project_id, :viewed => false)
|
||||
ws = WechatService.new
|
||||
ws.message_update_template self.assigned_to_id, "#{l(:label_new_issue_template)}", self.author.try(:realname) + " 给您指派了缺陷:" + self.subject.html_safe, format_time(self.created_on)
|
||||
end
|
||||
if self.tracker_id == 5
|
||||
self.project.members.each do |m|
|
||||
|
|
|
@ -239,44 +239,7 @@ class Journal < ActiveRecord::Base
|
|||
|
||||
#缺陷回复微信模板消息
|
||||
def issue_wechat_message
|
||||
uw = UserWechat.where(user_id: self.issue.author_id).first
|
||||
#unless uw.nil? && self.issue.author_id != User.current.id
|
||||
unless uw.nil?
|
||||
data = {
|
||||
touser:uw.openid,
|
||||
template_id:"A_3f5v90-zK73V9Kijm-paDkl9S-NuM8Cf-1UJi92_c",
|
||||
url:"http://www.trustie.net/",
|
||||
topcolor:"#FF0000",
|
||||
data:{
|
||||
first: {
|
||||
value:"您的缺陷有新回复了",
|
||||
color:"#173177"
|
||||
},
|
||||
keyword1:{
|
||||
value:self.user.try(:realname),
|
||||
color:"#173177"
|
||||
},
|
||||
keyword2:{
|
||||
value:format_time(self.created_on),
|
||||
color:"#173177"
|
||||
},
|
||||
keyword3:{
|
||||
value:self.notes.html_safe,
|
||||
color:"#173177"
|
||||
},
|
||||
remark:{
|
||||
value:"具体内容请点击详情查看网站",
|
||||
color:"#173177"
|
||||
}
|
||||
}
|
||||
}
|
||||
logger.info "start send template message: #{data}"
|
||||
begin
|
||||
req = Wechat.api.template_message_send Wechat::Message.to(uw.openid).template(data)
|
||||
rescue Exception => e
|
||||
logger.error "[journal] ===> #{e}"
|
||||
end
|
||||
logger.info "send over. #{req}"
|
||||
end
|
||||
ws = WechatService.new
|
||||
ws.comment_template self.issue.author_id, "#{l(:label_issue_comment_template)}", self.user.try(:realname), format_time(self.created_on), self.notes.html_safe
|
||||
end
|
||||
end
|
||||
|
|
|
@ -256,7 +256,8 @@ class JournalsForMessage < ActiveRecord::Base
|
|||
end
|
||||
end
|
||||
if self.jour_type == 'HomeworkCommon'
|
||||
journal_wechat_message '您的作业有新回复了',self.jour.user_id
|
||||
ws = WechatService.new
|
||||
ws.comment_template self.jour.user_id, "#{l(:label_homework_comment_template)}", self.user.try(:realname), format_time(self.created_on), self.notes.html_safe
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -264,12 +265,13 @@ class JournalsForMessage < ActiveRecord::Base
|
|||
# 用户留言消息通知
|
||||
def act_as_user_feedback_message
|
||||
# 主留言
|
||||
ws = WechatService.new
|
||||
if self.jour_type == 'Principal'
|
||||
receivers = []
|
||||
if self.reply_id == 0
|
||||
if self.user_id != self.jour_id # 过滤自己给自己的留言消息
|
||||
receivers << self.jour
|
||||
journal_wechat_message "您有新留言了",self.jour_id
|
||||
ws.message_update_template self.jour_id, "#{l(:label_new_journals_template)}", self.notes.html_safe, format_time(self.created_on)
|
||||
end
|
||||
else # 留言回复
|
||||
reply_to = User.find(self.reply_id)
|
||||
|
@ -279,12 +281,11 @@ class JournalsForMessage < ActiveRecord::Base
|
|||
if self.user_id != self.parent.jour_id && self.reply_id != self.parent.jour_id # 给东家发信息,如果回复的对象是东家则不发
|
||||
receivers << self.parent.jour
|
||||
end
|
||||
journal_wechat_message "您的留言有新回复了",self.reply_id
|
||||
ws.comment_template self.reply_id, "#{l(:label_journals_comment_template)}", self.user.try(:realname), format_time(self.created_on), self.notes.html_safe
|
||||
end
|
||||
receivers.each do |r|
|
||||
self.user_feedback_messages << UserFeedbackMessage.new(:user_id => r.id, :journals_for_message_id => self.id, :journals_for_message_type => "Principal", :viewed => false)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -305,48 +306,4 @@ class JournalsForMessage < ActiveRecord::Base
|
|||
down_course_score_num(self.jour.course_id, self.user_id, "HomeworkCommon")
|
||||
end
|
||||
end
|
||||
|
||||
#微信模板消息
|
||||
def journal_wechat_message type, user_id
|
||||
uw = UserWechat.where(user_id: user_id).first
|
||||
#unless uw.nil? && self.reply_id != User.current.id
|
||||
unless uw.nil?
|
||||
data = {
|
||||
touser:uw.openid,
|
||||
template_id:"A_3f5v90-zK73V9Kijm-paDkl9S-NuM8Cf-1UJi92_c",
|
||||
url:"http://www.trustie.net/",
|
||||
topcolor:"#FF0000",
|
||||
data:{
|
||||
first: {
|
||||
value:type,
|
||||
color:"#173177"
|
||||
},
|
||||
keyword1:{
|
||||
value:self.user.try(:realname),
|
||||
color:"#173177"
|
||||
},
|
||||
keyword2:{
|
||||
value:format_time(self.created_on),
|
||||
color:"#173177"
|
||||
},
|
||||
keyword3:{
|
||||
value:self.notes.html_safe,
|
||||
color:"#173177"
|
||||
},
|
||||
remark:{
|
||||
value:"具体内容请点击详情查看网站",
|
||||
color:"#173177"
|
||||
}
|
||||
}
|
||||
}
|
||||
logger.info "start send template message: #{data}"
|
||||
begin
|
||||
req = Wechat.api.template_message_send Wechat::Message.to(uw.openid).template(data)
|
||||
rescue Exception => e
|
||||
logger.error "[journal_for_message] ===> #{e}"
|
||||
end
|
||||
logger.info "send over. #{req}"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class Mailer < ActionMailer::Base
|
||||
require 'net/http'
|
||||
require 'json'
|
||||
layout 'mailer'
|
||||
helper :application
|
||||
helper :issues
|
||||
|
@ -642,9 +640,6 @@ class Mailer < ActionMailer::Base
|
|||
mail :to => recipients,
|
||||
:subject => "[ #{l(:label_user_homework)} : #{homework_common.name} #{l(:label_memo_create_succ)}]",
|
||||
:filter => true
|
||||
@homework_common.course.members.each do |member|
|
||||
mail_wechat_message member.user_id, "3e5Dj2GIx8MOcMyRKpTUEQnM7Tg0ASSCNc01NS9HCGI", "您的课程有新作业了", @homework_common.course.name, @homework_common.name, @homework_common.end_time.to_s + " 23:59:59"
|
||||
end
|
||||
end
|
||||
|
||||
# Builds a Mail::Message object used to email recipients of a news' project when a news item is added.
|
||||
|
@ -710,8 +705,6 @@ class Mailer < ActionMailer::Base
|
|||
mail :to => recipients,
|
||||
:subject => "[#{news.course.name}] #{l(:label_news)}: #{news.title}",
|
||||
:filter => true
|
||||
|
||||
mail_wechat_message news.author_id, "A_3f5v90-zK73V9Kijm-paDkl9S-NuM8Cf-1UJi92_c", "您的课程通知有新回复了", @author.try(:realname), format_time(comment.created_on), comment.comments.html_safe
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -736,13 +729,6 @@ class Mailer < ActionMailer::Base
|
|||
:cc => cc,
|
||||
:subject => "[#{message.board.project.name} - #{message.board.name} - msg#{message.root.id}] #{message.subject}",
|
||||
:filter => true
|
||||
if message.parent_id == nil
|
||||
message.project.members.each do |member|
|
||||
mail_wechat_message member.user_id, "oKzFCdk7bsIHnGbscA__N8LPQrBkUShvpjV3-kuwWDQ", "项目讨论区有新帖子发布了", message.subject, @author.try(:realname), format_time(message.created_on)
|
||||
end
|
||||
else
|
||||
mail_wechat_message message.parent.author_id, "A_3f5v90-zK73V9Kijm-paDkl9S-NuM8Cf-1UJi92_c", "您的帖子有新回复了", @author.try(:realname), format_time(message.created_on), message.content.html_safe
|
||||
end
|
||||
elsif message.course
|
||||
redmine_headers 'Course' => message.course.id,
|
||||
'Topic-Id' => (message.parent_id || message.id)
|
||||
|
@ -758,13 +744,6 @@ class Mailer < ActionMailer::Base
|
|||
:cc => cc,
|
||||
:subject => "[#{message.board.course.name} - #{message.board.name} - msg#{message.root.id}] #{message.subject}",
|
||||
:filter => true
|
||||
if message.parent_id == nil
|
||||
message.course.members.each do |member|
|
||||
mail_wechat_message member.user_id, "oKzFCdk7bsIHnGbscA__N8LPQrBkUShvpjV3-kuwWDQ", "课程问答区有新帖子发布了", message.subject, @author.try(:realname), format_time(message.created_on)
|
||||
end
|
||||
else
|
||||
mail_wechat_message message.parent.author_id, "A_3f5v90-zK73V9Kijm-paDkl9S-NuM8Cf-1UJi92_c", "您的帖子有新回复了", @author.try(:realname), format_time(message.created_on), message.content.html_safe
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1119,48 +1098,4 @@ class Mailer < ActionMailer::Base
|
|||
1.upto(len) { |i| newpass << chars[rand(chars.size-1)] }
|
||||
return newpass
|
||||
end
|
||||
|
||||
#微信模板消息
|
||||
def mail_wechat_message user_id, template_id, first, key1, key2, key3, remark="具体内容请点击详情查看网站"
|
||||
uw = UserWechat.where(user_id: user_id).first
|
||||
logger.info "mail_wechat_message #{user_id} #{uw}"
|
||||
unless uw.nil?
|
||||
data = {
|
||||
touser:uw.openid,
|
||||
template_id:template_id,
|
||||
url:"http://www.trustie.net/",
|
||||
topcolor:"#FF0000",
|
||||
data:{
|
||||
first: {
|
||||
value:first,
|
||||
color:"#173177"
|
||||
},
|
||||
keyword1:{
|
||||
value:key1,
|
||||
color:"#173177"
|
||||
},
|
||||
keyword2:{
|
||||
value:key2,
|
||||
color:"#173177"
|
||||
},
|
||||
keyword3:{
|
||||
value:key3,
|
||||
color:"#173177"
|
||||
},
|
||||
remark:{
|
||||
value:remark,
|
||||
color:"#173177"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logger.info "start send template message: #{data}"
|
||||
begin
|
||||
req = Wechat.api.template_message_send Wechat::Message.to(uw.openid).template(data)
|
||||
rescue Exception => e
|
||||
logger.error "[mailer] ===> #{e}"
|
||||
end
|
||||
logger.info "send over. #{req}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -158,7 +158,7 @@ class Member < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def student_work_score_sum
|
||||
sql_select = "SELECT (SUM(IF(student_works.final_score IS NULL,NULL,IF(student_works.final_score =0,0,student_works.final_score - student_works.absence_penalty - student_works.late_penalty)))) as score
|
||||
sql_select = "SELECT (SUM(IF(student_works.final_score IS NULL,NULL,IF(student_works.final_score =0,0,IF((student_works.final_score - student_works.absence_penalty - student_works.late_penalty) < 0 , 0, student_works.final_score - student_works.absence_penalty - student_works.late_penalty))))) AS score
|
||||
FROM student_works,homework_commons
|
||||
WHERE student_works.homework_common_id = homework_commons.id
|
||||
AND homework_commons.course_id = #{self.course_id}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#encoding: utf-8
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
|
@ -16,6 +17,8 @@
|
|||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class Message < ActiveRecord::Base
|
||||
require 'net/http'
|
||||
require 'json'
|
||||
include Redmine::SafeAttributes
|
||||
include UserScoreHelper
|
||||
include ApplicationHelper
|
||||
|
@ -257,17 +260,20 @@ class Message < ActiveRecord::Base
|
|||
# 主贴项目成员都能收到
|
||||
# 回帖:帖子的发布人收到
|
||||
def act_as_system_message
|
||||
ws = WechatService.new
|
||||
if self.course
|
||||
if self.parent_id.nil? # 主贴
|
||||
self.course.members.each do |m|
|
||||
if self.author.allowed_to?(:as_teacher, self.course) && m.user_id != self.author_id # 老师 自己的帖子不给自己发送消息
|
||||
self.course_messages << CourseMessage.new(:user_id => m.user_id, :course_id => self.board.course_id, :viewed => false)
|
||||
ws.topic_publish_template m.user_id, "#{l(:label_course_topic_template)}", self.subject, self.author.try(:realname), format_time(self.created_on)
|
||||
end
|
||||
end
|
||||
else # 回帖
|
||||
self.course.members.each do |m|
|
||||
if m.user_id == Message.find(self.parent_id).author_id && m.user_id != self.author_id # 只针对主贴回复,回复自己的帖子不发消息
|
||||
self.course_messages << CourseMessage.new(:user_id => m.user_id, :course_id => self.board.course_id, :viewed => false)
|
||||
ws.comment_template m.user_id, "#{l(:label_topic_comment_template)}", self.author.try(:realname), format_time(self.created_on), self.content.html_safe
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -276,12 +282,14 @@ class Message < ActiveRecord::Base
|
|||
self.project.members.each do |m|
|
||||
if m.user_id != self.author_id
|
||||
self.forge_messages << ForgeMessage.new(:user_id => m.user_id, :project_id => self.board.project_id, :viewed => false)
|
||||
ws.topic_publish_template m.user_id, "#{l(:label_project_topic_template)}", self.subject, self.author.try(:realname), format_time(self.created_on)
|
||||
end
|
||||
end
|
||||
else # 回帖
|
||||
self.project.members.each do |m|
|
||||
if m.user_id == Message.find(self.parent_id).author_id && m.user_id != self.author_id # 只针对主贴回复,回复自己的帖子不发消息
|
||||
self.forge_messages << ForgeMessage.new(:user_id => m.user_id, :project_id => self.board.project_id, :viewed => false)
|
||||
ws.comment_template m.user_id, "#{l(:label_topic_comment_template)}", self.author.try(:realname), format_time(self.created_on), self.content.html_safe
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#encoding: utf-8
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
|
@ -16,6 +17,8 @@
|
|||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class News < ActiveRecord::Base
|
||||
require 'net/http'
|
||||
require 'json'
|
||||
include Redmine::SafeAttributes
|
||||
belongs_to :project,:touch => true
|
||||
include ApplicationHelper
|
||||
|
@ -167,6 +170,8 @@ class News < ActiveRecord::Base
|
|||
self.course.members.each do |m|
|
||||
if m.user_id != self.author_id
|
||||
self.course_messages << CourseMessage.new(:user_id => m.user_id, :course_id => self.course_id, :viewed => false)
|
||||
ws = WechatService.new
|
||||
ws.message_update_template m.user_id, "#{l(:label_new_notice_template)}", self.author.try(:realname) + " 发布了通知:" + self.title.html_safe, format_time(self.created_on)
|
||||
end
|
||||
end
|
||||
else
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#学生提交作品表
|
||||
class StudentWork < ActiveRecord::Base
|
||||
attr_accessible :name, :description, :homework_common_id, :user_id, :final_score, :teacher_score, :student_score, :teaching_asistant_score, :project_id, :is_test
|
||||
attr_accessible :name, :description, :homework_common_id, :user_id, :final_score, :teacher_score, :student_score, :teaching_asistant_score, :project_id, :is_test, :simi_id, :simi_value
|
||||
|
||||
belongs_to :homework_common
|
||||
belongs_to :user
|
||||
|
|
|
@ -0,0 +1,114 @@
|
|||
#encoding: utf-8
|
||||
class WechatService
|
||||
|
||||
def template_data(openid, template_id, first, key1, key2, key3, remark="具体内容请点击详情查看网站")
|
||||
data = {
|
||||
touser:openid,
|
||||
template_id:template_id,
|
||||
url:"https://www.trustie.net/",
|
||||
topcolor:"#FF0000",
|
||||
data:{
|
||||
first: {
|
||||
value:first,
|
||||
color:"#173177"
|
||||
},
|
||||
keyword1:{
|
||||
value:key1,
|
||||
color:"#173177"
|
||||
},
|
||||
keyword2:{
|
||||
value:key2,
|
||||
color:"#173177"
|
||||
},
|
||||
keyword3:{
|
||||
value:key3,
|
||||
color:"#173177"
|
||||
},
|
||||
remark:{
|
||||
value:remark,
|
||||
color:"#173177"
|
||||
}
|
||||
}
|
||||
}
|
||||
data
|
||||
end
|
||||
|
||||
def homework_template(user_id, first, key1, key2, key3, remark="具体内容请点击详情查看网站")
|
||||
uw = UserWechat.where(user_id: user_id).first
|
||||
unless uw.nil?
|
||||
data = template_data uw.openid,"3e5Dj2GIx8MOcMyRKpTUEQnM7Tg0ASSCNc01NS9HCGI",first, key1, key2, key3, remark
|
||||
begin
|
||||
req = Wechat.api.template_message_send Wechat::Message.to(uw.openid).template(data)
|
||||
rescue Exception => e
|
||||
Rails.logger.error "[homework] ===> #{e}"
|
||||
end
|
||||
Rails.logger.info "send over. #{req}"
|
||||
end
|
||||
end
|
||||
|
||||
def topic_publish_template(user_id, first, key1, key2, key3, remark="具体内容请点击详情查看网站")
|
||||
uw = UserWechat.where(user_id: user_id).first
|
||||
unless uw.nil?
|
||||
data = template_data uw.openid,"oKzFCdk7bsIHnGbscA__N8LPQrBkUShvpjV3-kuwWDQ",first, key1, key2, key3, remark
|
||||
Rails.logger.info "start send template message: #{data}"
|
||||
begin
|
||||
req = Wechat.api.template_message_send Wechat::Message.to(uw.openid).template(data)
|
||||
rescue Exception => e
|
||||
Rails.logger.error "[topic_publish] ===> #{e}"
|
||||
end
|
||||
Rails.logger.info "send over. #{req}"
|
||||
end
|
||||
end
|
||||
|
||||
def comment_template(user_id, first, key1, key2, key3, remark="具体内容请点击详情查看网站")
|
||||
uw = UserWechat.where(user_id: user_id).first
|
||||
unless uw.nil?
|
||||
data = template_data uw.openid,"A_3f5v90-zK73V9Kijm-paDkl9S-NuM8Cf-1UJi92_c",first, key1, key2, key3, remark
|
||||
Rails.logger.info "start send template message: #{data}"
|
||||
begin
|
||||
req = Wechat.api.template_message_send Wechat::Message.to(uw.openid).template(data)
|
||||
rescue Exception => e
|
||||
Rails.logger.error "[comment] ===> #{e}"
|
||||
end
|
||||
Rails.logger.info "send over. #{req}"
|
||||
end
|
||||
end
|
||||
|
||||
def message_update_template(user_id, first, key1, key2, remark="具体内容请点击详情查看网站")
|
||||
uw = UserWechat.where(user_id: user_id).first
|
||||
unless uw.nil?
|
||||
data = {
|
||||
touser:uw.openid,
|
||||
template_id:"YTyNPZnQD8uZFBFq-Q6cCOWaq5LA9vL6RFlF2JuD5Cg",
|
||||
url:"https://www.trustie.net/",
|
||||
topcolor:"#FF0000",
|
||||
data:{
|
||||
first: {
|
||||
value:first,
|
||||
color:"#173177"
|
||||
},
|
||||
keyword1:{
|
||||
value:key1,
|
||||
color:"#173177"
|
||||
},
|
||||
keyword2:{
|
||||
value:key2,
|
||||
color:"#173177"
|
||||
},
|
||||
remark:{
|
||||
value:remark,
|
||||
color:"#173177"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rails.logger.info "start send template message: #{data}"
|
||||
begin
|
||||
req = Wechat.api.template_message_send Wechat::Message.to(uw.openid).template(data)
|
||||
rescue Exception => e
|
||||
Rails.logger.error "[message_update] ===> #{e}"
|
||||
end
|
||||
Rails.logger.info "send over. #{req}"
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,96 @@
|
|||
<h3>
|
||||
<%=l(:label_code_work_tests)%>
|
||||
</h3>
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="autoscroll">
|
||||
<table class="list" style="width: 100%;table-layout: fixed">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 50px;">
|
||||
作业id
|
||||
</th>
|
||||
<th style="width: 60px;">
|
||||
平均等待时间
|
||||
</th>
|
||||
<th style="width: 50px;">
|
||||
语言
|
||||
</th>
|
||||
<th style="width: 120px;">
|
||||
提交测试时间
|
||||
</th>
|
||||
<th style="width: 50px;">
|
||||
答题状态
|
||||
</th>
|
||||
<th style="width: 50px;">
|
||||
测试集数
|
||||
</th>
|
||||
<th style="width: 50px;">
|
||||
最小耗时
|
||||
</th>
|
||||
<th style="width: 50px;">
|
||||
最大耗时
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% @code_work_tests.each do |test| %>
|
||||
<tr class="<%= cycle("odd", "even") %>">
|
||||
<td style="text-align: center; " title='<%=test.homeworkid%>'>
|
||||
<%=link_to(test.homeworkid, student_work_index_path(:homework => test.homeworkid))%>
|
||||
</td>
|
||||
<td style="text-align: center;">
|
||||
<% if test.status != -2 && test.results.first['user_wait'] %>
|
||||
<% wait_time = 0 %>
|
||||
<% test.results.each do |result| wait_time = wait_time + result['user_wait'] end %>
|
||||
<%=(wait_time/test.results.count).to_s+"毫秒" %>
|
||||
<% else %>
|
||||
<%="未记录"%>
|
||||
<% end %>
|
||||
</td>
|
||||
<td align="center">
|
||||
<%=%W(C C++ Python Java).at(test.language.to_i - 1)%>
|
||||
</td>
|
||||
<td align="center">
|
||||
<%=Time.parse(test.created_at.to_s).strftime("%Y-%m-%d %H:%M:%S")%>
|
||||
</td>
|
||||
<td align="center">
|
||||
<% if test.status == 0 %>
|
||||
<%= "答题正确" %>
|
||||
<% elsif test.status == -2 %>
|
||||
<%= "编译错误" %>
|
||||
<% elsif test.status == 2 || test.results.last['status'] == 2 %>
|
||||
<%= "超时" %>
|
||||
<% else %>
|
||||
<%= "答题错误" %>
|
||||
<% end %>
|
||||
</td>
|
||||
<td class="center">
|
||||
<% if test.status != -2 %>
|
||||
<%=test.results.count%>
|
||||
<% end %>
|
||||
</td>
|
||||
<td class="center">
|
||||
<% if test.status != -2 %>
|
||||
<%test.results = test.results.sort_by {|result| result['time_used'] }%>
|
||||
<%=test.results.first['time_used'] == 0 ? "1毫秒":test.results.first['time_used'].to_s+"毫秒"%>
|
||||
<% end %>
|
||||
</td>
|
||||
<td class="center">
|
||||
<% if test.status != -2 %>
|
||||
<%=test.results.last['time_used'] == 0 ? "1毫秒":test.results.last['time_used'].to_s+"毫秒"%>
|
||||
<% end %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="pagination">
|
||||
<%= pagination_links_full @obj_pages, @obj_count, :per_page_links => false %>
|
||||
</div>
|
||||
|
||||
<% html_title(l(:label_code_work_tests)) -%>
|
|
@ -0,0 +1,101 @@
|
|||
<div class="blue-border-box">
|
||||
<div class="box-con">
|
||||
<%if @homework.simi_time != nil %>
|
||||
<h4 id = "compare-tips-1"><%="您上次查重的时间为"+Time.parse(@homework.simi_time.to_s).strftime("%Y-%m-%d %H:%M")%></h4>
|
||||
<%end%>
|
||||
<div class="box-con-a">
|
||||
<a href="javascript:void(0);" class="Blue-btn fl " onclick = "compare_code_btn(<%=homework.id%>,<%=courseid%>)">重新查重</a>
|
||||
<a href="javascript:void(0);" class="Blue-btn fl " onclick = "see_last_compare_code(<%=courseid%>,<%=homework.id%>)">查看结果</a>
|
||||
</div>
|
||||
<div class="cl"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
//请求重新查重
|
||||
function compare_code_btn(homeworkid,courseid)
|
||||
{
|
||||
hideModal($(".blue-border-box"));
|
||||
test_repeat(homeworkid,courseid);
|
||||
|
||||
}
|
||||
//查看结果
|
||||
function see_last_compare_code(courseid,homeworkid)
|
||||
{
|
||||
hideModal($(".blue-border-box"));
|
||||
var rootpath = getRootPath();
|
||||
var code_repeatpath = rootpath+"/courses/"+courseid+"/code_repeat?homework="+homeworkid;
|
||||
//新打开页面
|
||||
window.open(code_repeatpath);
|
||||
}
|
||||
|
||||
var test_repeat = function(homeworkid,courseid){
|
||||
$.post(
|
||||
'/student_work/code_repeattest',
|
||||
{homework: homeworkid},
|
||||
function(data,status){
|
||||
console.log("result = ");
|
||||
console.log(data);
|
||||
|
||||
if (data.status == 0) {
|
||||
$("#ajax-modal").html('<%= escape_javascript( render :partial => 'courses/compare_code_tips_2',:locals => {:des=>"查重完成是否立即查看结果?",:status=>1, :homework=> homework,:courseid=> courseid})%>');
|
||||
showModal('ajax-modal', '580px');
|
||||
$('#ajax-modal').siblings().remove();
|
||||
$('#ajax-modal').before("<a href='javascript:void(0)' onclick='hideModal();' style='margin-left: 560px;' class='resourceClose'></a>");
|
||||
$('#ajax-modal').parent().css("top","40%").css("left","50%");
|
||||
$('#ajax-modal').parent().addClass("resourceUploadPopup");
|
||||
$('#ajax-modal').css("padding-left","16px").css("padding-bottom","16px");
|
||||
|
||||
function closeModal(){
|
||||
hideModal($(".blue-border-box"));
|
||||
}
|
||||
}
|
||||
else if (data.status == -1){
|
||||
// confirm("对不起只支持java/c/c++的代码查重!");
|
||||
$("#ajax-modal").html('<%= escape_javascript( render :partial => 'courses/compare_code_tips_2',:locals => {:des=>"对不起目前只支持java/c/c++的代码查重!",:status=>0, :homework=> homework,:courseid=> courseid})%>');
|
||||
showModal('ajax-modal', '580px');
|
||||
$('#ajax-modal').siblings().remove();
|
||||
$('#ajax-modal').before("<a href='javascript:void(0)' onclick='hideModal();' style='margin-left: 560px;' class='resourceClose'></a>");
|
||||
$('#ajax-modal').parent().css("top","40%").css("left","50%");
|
||||
$('#ajax-modal').parent().addClass("resourceUploadPopup");
|
||||
$('#ajax-modal').css("padding-left","16px").css("padding-bottom","16px");
|
||||
|
||||
function closeModal(){
|
||||
hideModal($(".blue-border-box"));
|
||||
}
|
||||
|
||||
}
|
||||
else if (data.status == -2){
|
||||
// confirm("对不起该作业的作品过少不能查重!");
|
||||
$("#ajax-modal").html('<%= escape_javascript( render :partial => 'courses/compare_code_tips_2',:locals => {:des=>"对不起该作业的作品过少不能查重!",:status=>0, :homework=> homework,:courseid=> courseid})%>');
|
||||
showModal('ajax-modal', '580px');
|
||||
$('#ajax-modal').siblings().remove();
|
||||
$('#ajax-modal').before("<a href='javascript:void(0)' onclick='hideModal();' style='margin-left: 560px;' class='resourceClose'></a>");
|
||||
$('#ajax-modal').parent().css("top","40%").css("left","50%");
|
||||
$('#ajax-modal').parent().addClass("resourceUploadPopup");
|
||||
$('#ajax-modal').css("padding-left","16px").css("padding-bottom","16px");
|
||||
|
||||
function closeModal(){
|
||||
hideModal($(".blue-border-box"));
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
).fail(function(xhr, status){
|
||||
// confirm("对不起,服务器繁忙请稍后再试!");
|
||||
$("#ajax-modal").html('<%= escape_javascript( render :partial => 'courses/compare_code_tips_2',:locals => {:des=>"对不起,服务器繁忙请稍后再试!",:status=>0, :homework=> homework,:courseid=> courseid})%>');
|
||||
showModal('ajax-modal', '580px');
|
||||
$('#ajax-modal').siblings().remove();
|
||||
$('#ajax-modal').before("<a href='javascript:void(0)' onclick='hideModal();' style='margin-left: 560px;' class='resourceClose'></a>");
|
||||
$('#ajax-modal').parent().css("top","40%").css("left","50%");
|
||||
$('#ajax-modal').parent().addClass("resourceUploadPopup");
|
||||
$('#ajax-modal').css("padding-left","16px").css("padding-bottom","16px");
|
||||
|
||||
function closeModal(){
|
||||
hideModal($(".blue-border-box"));
|
||||
}
|
||||
return;
|
||||
});
|
||||
};
|
||||
</script>
|
|
@ -0,0 +1,22 @@
|
|||
<div class="blue-border-box">
|
||||
<div class="box-con">
|
||||
<h4><%=des%></h4>
|
||||
<div class="box-con-a">
|
||||
<a href="javascript:void(0);" class="Blue-btn " style="width:67px; margin:25px auto 0px auto;" onclick = "yes_btn(<%=status%>,<%=courseid%>,<%=homework.id%>)">确定</a>
|
||||
</div>
|
||||
<div class="cl"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
function yes_btn(status,courseid,homeworkid)
|
||||
{
|
||||
hideModal($(".blue-border-box"));
|
||||
if(status == 1) {
|
||||
var rootpath = getRootPath();
|
||||
var code_repeatpath = rootpath+"/courses/"+courseid+"/code_repeat?homework="+homeworkid;
|
||||
window.open(code_repeatpath);
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,16 @@
|
|||
|
||||
<% content_for :header_tags do %>
|
||||
<%= javascript_include_tag "/assets/codemirror/codemirror_python_ruby_c" %>
|
||||
<%= stylesheet_link_tag "/assets/codemirror/codemirror" %>
|
||||
<%= stylesheet_link_tag "/assets/codemirror/merge" %>
|
||||
<%= javascript_include_tag "https://cdnjs.cloudflare.com/ajax/libs/diff_match_patch/20121119/diff_match_patch.js"%>
|
||||
<%= javascript_include_tag "/assets/codemirror/merge" %>
|
||||
<% end %>
|
||||
|
||||
<article>
|
||||
<h3 style="float:left; width:50%; text-align:center;"><%=src_name%></h3>
|
||||
<h3 style="float:left; width:50%; text-align:center;"><%=dst_name%></h3><div class="cl"></div>
|
||||
<pre id = "program-src_1" style = "display: none" ><%= src_code if src_code%></pre>
|
||||
<pre id = "program-src_2" style = "display: none" ><%= dst_code if dst_code%></pre>
|
||||
<div class = "program-compare-code" id=program-compare-code></div>
|
||||
</article>
|
|
@ -24,7 +24,7 @@
|
|||
</span>
|
||||
<span class="c_red w70">
|
||||
<% final_score = @member_score.homework_common_score(homework_common).first%>
|
||||
<%= final_score.nil? || final_score.final_score.nil? ? "--" : format("%0.2f", final_score.final_score) %>
|
||||
<%= final_score.nil? || final_score.final_score.nil? ? "--" : format("%0.2f", final_score.final_score < 0 ? 0 : final_score.final_score) %>
|
||||
</span>
|
||||
</li>
|
||||
<% end %>
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
<div class="conbox">
|
||||
<h2 class="conbox-h2">查重结果</h2>
|
||||
<div class="chabox">
|
||||
<ul class="chabox-header">
|
||||
<li class="chabox-w-500" style = "width:413px" >全部作品</li>
|
||||
<li class="chabox-w-500" style = "width:585px" >对比作品</li>
|
||||
<div class="cl"></div>
|
||||
</ul>
|
||||
<ul class="chabox-top">
|
||||
<li class="chabox-w-151" >作品名称</li>
|
||||
<li>姓名</li>
|
||||
<li>学号 </li>
|
||||
<li class="chabox-r-line">时间 </li>
|
||||
<li class="chabox-w-151">作品名称</li>
|
||||
<li>姓名</li>
|
||||
<li>学号 </li>
|
||||
<li class="chabox-r-line">时间 </li>
|
||||
<li >相似度 </li>
|
||||
<li >对比 </li>
|
||||
</ul>
|
||||
|
||||
<%if @homework.homework_type == 2 %>
|
||||
<% @student_works.each do |student_work|%>
|
||||
<ul class="chabox-con" id = "chabox-con-<%=student_work.id%>" >
|
||||
<% student_work_name = student_work.name.nil? || student_work.name.empty? ? student_work.user.show_name + '的作品' : student_work.name%>
|
||||
|
||||
<li class="chabox-w-151" ><%=student_work_name%></li>
|
||||
<li><%=student_work.user.show_name%></li>
|
||||
<li><%= student_work.user.user_extensions.nil? ? "--" : student_work.user.user_extensions.student_id%> </li>
|
||||
<li class="chabox-r-line"><%= Time.parse(format_time(student_work.created_at)).strftime("%m-%d %H:%M")%></li>
|
||||
<% if student_work.simi_id > 0 && @works_hash[student_work.simi_id] %>
|
||||
<% simi_student_work = @works_hash[student_work.simi_id] %>
|
||||
<% simi_student_work_name = simi_student_work.name.nil? || simi_student_work.name.empty? ? simi_student_work.user.show_name + '的作品' : simi_student_work.name%>
|
||||
<li class="chabox-w-151"><%=simi_student_work_name%></li>
|
||||
<li><%=simi_student_work.user.show_name%></li>
|
||||
<li><%= simi_student_work.user.user_extensions.nil? ? "--" : simi_student_work.user.user_extensions.student_id%></li>
|
||||
<li class="chabox-r-line"><%= Time.parse(format_time(simi_student_work.created_at)).strftime("%m-%d %H:%M")%></li>
|
||||
<% if student_work.simi_value >= 90 %>
|
||||
<li style = "color:red" ><%=student_work.simi_value%>%</li>
|
||||
<% else %>
|
||||
<li ><%=student_work.simi_value%>%</li>
|
||||
<% end %>
|
||||
|
||||
<!--@works_hash[student_work.id].description -->
|
||||
<!--<li ><a href="javascript:void(0);" target="_blank" class="cha-btn" onclick = "show_code_compare()">查看</a>-->
|
||||
<li >
|
||||
<%= link_to("查看", show_comparecode_course_path(:homework_id => @homework.id,:src_id => student_work.id,:dst_id => student_work.simi_id),:class => "cha-btn",:remote => true ) %>
|
||||
</li>
|
||||
<%else%>
|
||||
<li class="chabox-w-151">无</li>
|
||||
<li>--</li>
|
||||
<li>--</li>
|
||||
<li class="chabox-r-line">--</li>
|
||||
<li >--</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<%end%>
|
||||
<%end%>
|
||||
</div>
|
||||
<div class="cl"></div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
function show_code_compare() {
|
||||
|
||||
// $("#ajax-modal").html('<%= escape_javascript( render :partial => 'courses/show_compare_code' ,:locals => {:src_code=> 1,:src_name=> 2,:dst_name=> 3, :dst_code=> 4,:language=> 5,})%>');
|
||||
// showModal('ajax-modal', '950px');
|
||||
// $('#ajax-modal').siblings().remove();
|
||||
// $('#ajax-modal').before("<a href='javascript:void(0)' onclick='closeModal();' style='margin-left: 935px;' class='resourceClose'></a>");
|
||||
// $('#ajax-modal').parent().css("top", "20%").css("left", "26.5%").css("position", "absolute");
|
||||
// $('#ajax-modal').parent().addClass("resourceUploadPopup");
|
||||
// $('#ajax-modal').css("padding-left", "16px").css("padding-bottom", "16px");
|
||||
//
|
||||
// function closeModal() {
|
||||
// hideModal($(".contrast-box"));
|
||||
// }
|
||||
}
|
||||
|
||||
</script>
|
|
@ -0,0 +1,101 @@
|
|||
$("#ajax-modal").html('<%= escape_javascript( render :partial => 'courses/show_compare_code' ,:locals => {:src_code=> @src_code,:src_name=> @src_username,:dst_name=> @dst_username, :dst_code=> @dst_code,})%>');
|
||||
showModal('ajax-modal', '1250px');
|
||||
$('#ajax-modal').siblings().remove();
|
||||
$('#ajax-modal').before("<a href='javascript:void(0)' onclick='closeModal();' style='margin-left: 1235px;' class='resourceClose'></a>");
|
||||
$('#ajax-modal').parent().css("top","20%").css("left","20%").css("position","absolute");
|
||||
//$('#ajax-modal').parent().addClass("resourceUploadPopup");
|
||||
$('#ajax-modal').css("padding-left","16px").css("padding-bottom","16px").css("padding-top","10px");
|
||||
|
||||
function closeModal(){
|
||||
hideModal($(".program-compare-code"));
|
||||
}
|
||||
|
||||
var program_name = "text/x-csrc";
|
||||
var language = <%= @homework.language.to_i %>;
|
||||
if (language == 1) {
|
||||
program_name = 'text/x-csrc';
|
||||
} else if(language==2){
|
||||
program_name = 'text/x-c++src';
|
||||
}else if(language==3){
|
||||
program_name = 'text/x-cython';
|
||||
} else if(language==4){
|
||||
program_name = 'text/x-java';
|
||||
}
|
||||
//
|
||||
//var editor_1 = CodeMirror(document.getElementById("program-code_1"), {
|
||||
// mode: {name: program_name,
|
||||
// version: 2,
|
||||
// singleLineStringErrors: false},
|
||||
// lineNumbers: true,
|
||||
// indentUnit: 2,
|
||||
// matchBrackets: true,
|
||||
// readOnly: true,
|
||||
// value: $("#program-src_1").text()
|
||||
// }
|
||||
//);
|
||||
//
|
||||
//var editor_2 = CodeMirror(document.getElementById("program-code_2"), {
|
||||
// mode: {name: program_name,
|
||||
// version: 2,
|
||||
// singleLineStringErrors: false},
|
||||
// lineNumbers: true,
|
||||
// indentUnit: 2,
|
||||
// matchBrackets: true,
|
||||
// readOnly: true,
|
||||
// value: $("#program-src_2").text()
|
||||
// }
|
||||
//);
|
||||
|
||||
var value, orig1, orig2, dv, panes = 2, highlight = true, connect = null, collapse = false;
|
||||
function initUI() {
|
||||
if (value == null) return;
|
||||
var target = document.getElementById("program-compare-code");
|
||||
target.innerHTML = "";
|
||||
dv = CodeMirror.MergeView(target, {
|
||||
value: value,
|
||||
origLeft: panes == 3 ? orig1 : null,
|
||||
orig: orig2,
|
||||
lineNumbers: true,
|
||||
mode: program_name,
|
||||
highlightDifferences: highlight,
|
||||
connect: connect,
|
||||
collapseIdentical: collapse
|
||||
});
|
||||
}
|
||||
|
||||
function toggleDifferences() {
|
||||
dv.setShowDifferences(highlight = !highlight);
|
||||
}
|
||||
|
||||
|
||||
value = $("#program-src_1").text();
|
||||
orig1 = $("#program-src_1").text();
|
||||
orig2 = $("#program-src_2").text();
|
||||
initUI();
|
||||
|
||||
|
||||
function mergeViewHeight(mergeView) {
|
||||
function editorHeight(editor) {
|
||||
if (!editor) return 0;
|
||||
return editor.getScrollInfo().height;
|
||||
}
|
||||
return Math.max(editorHeight(mergeView.leftOriginal()),
|
||||
editorHeight(mergeView.editor()),
|
||||
editorHeight(mergeView.rightOriginal()));
|
||||
}
|
||||
|
||||
function resize(mergeView) {
|
||||
var height = mergeViewHeight(mergeView);
|
||||
for(;;) {
|
||||
if (mergeView.leftOriginal())
|
||||
mergeView.leftOriginal().setSize(null, height);
|
||||
mergeView.editor().setSize(null, height);
|
||||
if (mergeView.rightOriginal())
|
||||
mergeView.rightOriginal().setSize(null, height);
|
||||
|
||||
var newHeight = mergeViewHeight(mergeView);
|
||||
if (newHeight >= height) break;
|
||||
else height = newHeight;
|
||||
}
|
||||
mergeView.wrap.style.height = height + "px";
|
||||
}
|
|
@ -39,7 +39,21 @@
|
|||
|
||||
<div class="homepageRight mt0 ml10">
|
||||
<div class="homepageRightBanner mb10">
|
||||
<div class="NewsBannerName">作业</div>
|
||||
<!--<div class="NewsBannerName">作业</div>-->
|
||||
<div id="menu_r" class="NewsBannerName" style="margin-bottom: -10px;">
|
||||
<ul class="menu_r b_w" style="padding-left: 0px; margin-top: -5px;">
|
||||
<li>
|
||||
<a href="javascript:void(0);" class="parent" style="font-size:16px; color:#4b4b4b; font-weight: normal; padding-left: 0px;">作业</a>
|
||||
<ul>
|
||||
<% @homework_commons.each_with_index do |homework_common,index |%>
|
||||
<li class="pr10">
|
||||
<%= link_to "作业#{@homework_commons.count - index}:#{homework_common.name}",student_work_index_path(:homework => homework_common.id)%>
|
||||
</li>
|
||||
<% end%>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="search_div" class="fr mr10">
|
||||
<%= render :partial => 'homework_search_form',:locals => {:course=>@course} %>
|
||||
</div>
|
||||
|
|
|
@ -236,10 +236,10 @@
|
|||
</div>
|
||||
<% if @user.projects.visible.count > 0
|
||||
project_order_ids = "(" +
|
||||
ForgeActivity.find_by_sql("SELECT p.project_id, p.created_at FROM
|
||||
(SELECT fa.project_id, MAX(fa.created_at) AS created_at FROM forge_activities fa WHERE fa.project_id IN (" + @user.projects.visible.select('projects.id').map{|p| p.id}.join(',') + ")
|
||||
ForgeActivity.find_by_sql("SELECT p.project_id, p.updated_at FROM
|
||||
(SELECT fa.project_id, MAX(fa.updated_at) AS updated_at FROM forge_activities fa WHERE fa.project_id IN (" + @user.projects.visible.select('projects.id').map{|p| p.id}.join(',') + ")
|
||||
GROUP BY fa.project_id) AS p
|
||||
ORDER BY p.created_at DESC limit 5").map {|p| p.project_id}.join(",") + ")"
|
||||
ORDER BY p.updated_at DESC limit 5").map {|p| p.project_id}.join(",") + ")"
|
||||
projects = Project.where("projects.id in #{project_order_ids}")
|
||||
else
|
||||
projects = []
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
<div class="fl">
|
||||
<%=form_tag url_for(:controller => 'organizations', :action => 'join_courses', :organization_id => organization_id),:method => 'post', :id => 'join_courses_form', :remote => true,:class=>"resourcesSearchBox" do %>
|
||||
<input type="text" name="courses" placeholder="搜索您已加入的课程的名称" class="searchCourse" />
|
||||
<div id="search_courses_result_list" class="mb8"></div>
|
||||
<div id="search_courses_result_list" class="mb8 maxHeight100" style="overflow:auto;"></div>
|
||||
<div class="courseSendSubmit">
|
||||
<a href="javascript:void(0);" onclick="org_join_courses(<%= organization_id %>);" class="sendSourceText">关联</a>
|
||||
</div>
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
<div class="fl">
|
||||
<%=form_tag url_for(:controller => 'organizations', :action => 'join_projects', :organization_id => organization_id),:method => 'post', :id => 'join_projects_form', :remote => true,:class=>"resourcesSearchBox" do %>
|
||||
<input type="text" name="projects" placeholder="搜索您已加入的项目的名称" class="searchCourse" />
|
||||
<div id="search_projects_result_list" class="mb8 maxHeight100"></div>
|
||||
<div id="search_projects_result_list" class="mb8 maxHeight100" style="overflow:auto;"></div>
|
||||
<div class="courseSendSubmit">
|
||||
<a href="javascript:void(0);" onclick="org_join_projects(<%= organization_id %>);" class="sendSourceText">关联</a>
|
||||
</div>
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
<li class="hworkPortrait mt15 mr10">
|
||||
<%= link_to(image_tag(url_to_avatar(student_work.user),:width =>"40",:height => "40"),user_activities_path(student_work.user)) %>
|
||||
</li>
|
||||
<div onclick="show_student_work('<%= student_work_path(student_work)%>');" style="cursor: pointer;" class="student_work_<%= student_work.id%>">
|
||||
<li class="hworkName mt15 mr15 <%= @homework.homework_type == 2 ? '' : 'width165'%>">
|
||||
<div class="student_work_<%= student_work.id%>">
|
||||
<li class="hworkName mt15 mr15 <%= @homework.homework_type == 2 ? '' : 'width165'%>" style="cursor: pointer;" onclick="show_student_work('<%= student_work_path(student_work)%>');">
|
||||
<% student_work_name = student_work.name.nil? || student_work.name.empty? ? student_work.user.show_name + '的作品' : student_work.name%>
|
||||
<div>
|
||||
<%= link_to student_work_name,"javascript:void(0)" ,:title => student_work_name, :class => "linkGrey f14 StudentName break_word #{@homework.homework_type == 2 ? '' : 'width165'}"%>
|
||||
|
@ -14,7 +14,7 @@
|
|||
</li>
|
||||
<li>
|
||||
<% if @homework.homework_type != 3 %>
|
||||
<ul class="mt10 fl">
|
||||
<ul class="mt10 fl" style="cursor: pointer;" onclick="show_student_work('<%= student_work_path(student_work)%>');">
|
||||
<li class="hworkStName mr10 mt16" title="<%= student_work.user.show_name%>">
|
||||
<%= student_work.user.show_name%>
|
||||
</li>
|
||||
|
@ -24,9 +24,15 @@
|
|||
</ul>
|
||||
<% elsif @homework.homework_type == 3 && @homework.homework_detail_group.base_on_project == 1 %>
|
||||
<ul class="mt10 fl">
|
||||
<% if student_work.project.is_public || User.current.member_of?(student_work.project) || User.current.admin? %>
|
||||
<li class="hworkPrName mr10 mt12" title="项目名称">
|
||||
<%= link_to( student_work.project.name, project_path(student_work.project.id))%>
|
||||
</li>
|
||||
<% else %>
|
||||
<li class="hworkPrName mr10 mt12" title="该项目是私有的">
|
||||
<%= student_work.project.name %>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% end %>
|
||||
</li>
|
||||
|
@ -57,7 +63,11 @@
|
|||
|
||||
<% if @homework.anonymous_comment == 0%>
|
||||
<li class="hworkList50 <%= score_color student_work.student_score%> student_score_info">
|
||||
<%= student_work.student_score.nil? ? "未参与" : format("%.1f",student_work.student_score)%>
|
||||
<% if student_work.student_score.nil? %>
|
||||
<span title="该作品未被匿评">未参与</span>
|
||||
<% else %>
|
||||
<%=format("%.1f",student_work.student_score) %>
|
||||
<% end %>
|
||||
<% unless student_work.student_score.nil?%>
|
||||
<span class="linkBlue">
|
||||
(<%= student_work.student_works_scores.where(:reviewer_role => 3).count%>)
|
||||
|
|
|
@ -18,9 +18,9 @@
|
|||
<%= link_to student_work_name, student_work_path(student_work),:remote => true,:title => student_work_name, :class => "linkGrey f14 StudentName break_word w230"%>
|
||||
</div>
|
||||
</li>
|
||||
<li onclick="show_student_work('<%= student_work_path(student_work)%>');" style="cursor: pointer;" class="student_work_<%= student_work.id%>">
|
||||
<li class="student_work_<%= student_work.id%>">
|
||||
<% if @homework.homework_type != 3 %>
|
||||
<ul class="mt10 fl">
|
||||
<ul class="mt10 fl" onclick="show_student_work('<%= student_work_path(student_work)%>');" style="cursor: pointer;">
|
||||
<li class="hworkStName mr10 mt16" title="<%= student_work.user.show_name%>">
|
||||
<%= student_work.user.show_name%>
|
||||
</li>
|
||||
|
@ -30,9 +30,15 @@
|
|||
</ul>
|
||||
<% elsif @homework.homework_type == 3 && @homework.homework_detail_group.base_on_project == 1 %>
|
||||
<ul class="mt10 fl">
|
||||
<% if student_work.project.is_public || User.current.member_of?(student_work.project) || User.current.admin? %>
|
||||
<li class="hworkPrName mr10 mt12" title="项目名称">
|
||||
<%= link_to( student_work.project.name, project_path(student_work.project.id))%>
|
||||
</li>
|
||||
<% else %>
|
||||
<li class="hworkPrName mr10 mt12" title="该项目是私有的">
|
||||
<%= student_work.project.name %>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% end %>
|
||||
</li>
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
|
||||
<div class="show_hwork_arrow"></div>
|
||||
<div class="showHwork">
|
||||
<ul>
|
||||
|
@ -69,16 +70,14 @@
|
|||
<span class="w60">正确输出:</span>
|
||||
|
||||
<span class="width120"><pre style="white-space: pre-wrap; margin-right: 15px;"><%=x["output"]%></pre></span>
|
||||
<% if x["status"].to_i == 2 %>
|
||||
<span class="w50">耗时:</span>
|
||||
<span class="w80"><pre><%=x["time_used"]%>毫秒</pre></span>
|
||||
<% end %>
|
||||
<span class="w80"><pre><%=x["time_used"]==0?1:x["time_used"]%>毫秒</pre></span>
|
||||
<div class="cl"></div>
|
||||
<% else %>
|
||||
|
||||
<span class="w60 c_green">测试正确!</span>
|
||||
<!-- <span class="w50"> 耗时:</span> -->
|
||||
<!-- <span class="w80"><pre><%=x["time_used"]%>微秒</pre></span> -->
|
||||
<span style="width:360px;"> </span>
|
||||
<span class="w50">耗时:</span>
|
||||
<span class="w80"><pre><%=x["time_used"]==0?1:x["time_used"]%>毫秒</pre></span>
|
||||
<div class="cl"></div>
|
||||
<% end %>
|
||||
</li>
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
<input type="text" id="course_student_name" value="<%= @name%>" placeholder="姓名、学号、邮箱" class="hworkSearchInput" onkeypress="SearchByName('<%= student_work_index_path(:homework => @homework.id)%>',event);"/>
|
||||
<a class="hworkSearchIcon" id="search_in_student_work" onclick="SearchByName_1('<%= student_work_index_path(:homework => @homework.id)%>');" href="javascript:void(0)"></a>
|
||||
</div>
|
||||
<%if @homework.homework_type == 2 %>
|
||||
<a href="javascript:void(0);" class="BlueCirBtn fr" data-course-id="<%=@course.id%>" data-homework-simi-time="<%=@homework.simi_time%>" data-homework-id="<%=@homework.id%>" id="test-program-repeat-btn" onclick = "code_repeat()">代码查重</a>
|
||||
<% end %>
|
||||
<%= select_tag(:student_work_in_group,options_for_select(course_group_list(@course),@group), {:class => "classSplit"}) unless course_group_list(@course).empty? %>
|
||||
<% end%>
|
||||
<span class="fr c_grey"> <a href="javascript:void(0);" class="linkGrey2" id="homework_info_show" style="display: none">[ 显示作业信息 ]</a> </span>
|
||||
|
@ -45,6 +48,7 @@
|
|||
<div class="cl"></div>
|
||||
<% end%>
|
||||
<script type="text/javascript">
|
||||
|
||||
$(function(){
|
||||
<% if !@is_evaluation && (!@is_teacher || params[:show_work_id].present?) %>
|
||||
<% work= params[:show_work_id].nil? ? @homework.student_works.where("user_id = ?",User.current.id).first : StudentWork.find(params[:show_work_id]) %>
|
||||
|
@ -85,4 +89,146 @@
|
|||
<% end %>
|
||||
<% end %>
|
||||
});
|
||||
//代码查重
|
||||
function code_repeat(){
|
||||
|
||||
var homework_id = <%=@homework.id%>;
|
||||
var course_id = <%=@course.id%>;
|
||||
|
||||
console.log("course_id=",course_id);
|
||||
console.log("homework_id=",homework_id);
|
||||
|
||||
if(<%= @stundet_works.count <=1 %>)
|
||||
{
|
||||
//弹框
|
||||
$("#ajax-modal").html('<%= escape_javascript( render :partial => 'courses/compare_code_tips_2',:locals => {:des=>"对不起该作业的作品过少不能查重!",:status=>0, :homework=> @homework,:courseid=> @course.id})%>');
|
||||
showModal('ajax-modal', '580px');
|
||||
$('#ajax-modal').siblings().remove();
|
||||
$('#ajax-modal').before("<a href='javascript:void(0)' onclick='hideModal();' style='margin-left: 560px;' class='resourceClose'></a>");
|
||||
$('#ajax-modal').parent().css("top","40%").css("left","50%");
|
||||
$('#ajax-modal').parent().addClass("resourceUploadPopup");
|
||||
$('#ajax-modal').css("padding-left","16px").css("padding-bottom","16px");
|
||||
|
||||
function closeModal(){
|
||||
hideModal($(".blue-border-box"));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//先请求下上次查询的时间
|
||||
$.post(
|
||||
'/student_work/last_codecomparetime',
|
||||
{homework: homework_id},
|
||||
function(data,status){
|
||||
if (data.status == 0) {
|
||||
var homework_simi_time = data.comparetime;
|
||||
|
||||
if (!homework_simi_time){
|
||||
//没进行过代码查重则直接查重
|
||||
test_repeat();
|
||||
}
|
||||
else{
|
||||
$("#ajax-modal").html('<%= escape_javascript( render :partial => 'courses/compare_code_tips_1',:locals => {:homework=> @homework,:courseid=> @course.id })%>');
|
||||
$('#compare-tips-1').html('您上次查重的时间为'+homework_simi_time);
|
||||
showModal('ajax-modal', '580px');
|
||||
$('#ajax-modal').siblings().remove();
|
||||
$('#ajax-modal').before("<a href='javascript:void(0)' onclick='hideModal();' style='margin-left: 560px;' class='resourceClose'></a>");
|
||||
$('#ajax-modal').parent().css("top","40%").css("left","50%");
|
||||
$('#ajax-modal').parent().addClass("resourceUploadPopup");
|
||||
$('#ajax-modal').css("padding-left","16px").css("padding-bottom","16px");
|
||||
console.log(homework_simi_time);
|
||||
|
||||
function closeModal(){
|
||||
hideModal($(".blue-border-box"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
).fail(function(xhr, status){
|
||||
// confirm("对不起,服务器繁忙请稍后再试!");
|
||||
$("#ajax-modal").html('<%= escape_javascript( render :partial => 'courses/compare_code_tips_2',:locals => {:des=>"对不起,服务器繁忙请稍后再试!",:status=>0, :homework=> @homework,:courseid=> @course.id})%>');
|
||||
showModal('ajax-modal', '580px');
|
||||
$('#ajax-modal').siblings().remove();
|
||||
$('#ajax-modal').before("<a href='javascript:void(0)' onclick='hideModal();' style='margin-left: 560px;' class='resourceClose'></a>");
|
||||
$('#ajax-modal').parent().css("top","40%").css("left","50%");
|
||||
$('#ajax-modal').parent().addClass("resourceUploadPopup");
|
||||
$('#ajax-modal').css("padding-left","16px").css("padding-bottom","16px");
|
||||
|
||||
function closeModal(){
|
||||
hideModal($(".blue-border-box"));
|
||||
}
|
||||
return;
|
||||
});
|
||||
|
||||
//请求查重
|
||||
var test_repeat = function(){
|
||||
$.post(
|
||||
'/student_work/code_repeattest',
|
||||
{homework: homework_id},
|
||||
function(data,status){
|
||||
console.log("result = ");
|
||||
console.log(data);
|
||||
|
||||
if (data.status == 0) {
|
||||
$("#ajax-modal").html('<%= escape_javascript( render :partial => 'courses/compare_code_tips_2',:locals => {:des=>"查重完成是否立即查看结果?",:status=>1, :homework=> @homework,:courseid=> @course.id})%>');
|
||||
showModal('ajax-modal', '580px');
|
||||
$('#ajax-modal').siblings().remove();
|
||||
$('#ajax-modal').before("<a href='javascript:void(0)' onclick='hideModal();' style='margin-left: 560px;' class='resourceClose'></a>");
|
||||
$('#ajax-modal').parent().css("top","40%").css("left","50%");
|
||||
$('#ajax-modal').parent().addClass("resourceUploadPopup");
|
||||
$('#ajax-modal').css("padding-left","16px").css("padding-bottom","16px");
|
||||
|
||||
function closeModal(){
|
||||
hideModal($(".blue-border-box"));
|
||||
}
|
||||
}
|
||||
else if (data.status == -1){
|
||||
// confirm("对不起只支持java/c/c++的代码查重!");
|
||||
$("#ajax-modal").html('<%= escape_javascript( render :partial => 'courses/compare_code_tips_2',:locals => {:des=>"对不起目前只支持java/c/c++的代码查重!",:status=>0, :homework=> @homework,:courseid=> @course.id})%>');
|
||||
showModal('ajax-modal', '580px');
|
||||
$('#ajax-modal').siblings().remove();
|
||||
$('#ajax-modal').before("<a href='javascript:void(0)' onclick='hideModal();' style='margin-left: 560px;' class='resourceClose'></a>");
|
||||
$('#ajax-modal').parent().css("top","40%").css("left","50%");
|
||||
$('#ajax-modal').parent().addClass("resourceUploadPopup");
|
||||
$('#ajax-modal').css("padding-left","16px").css("padding-bottom","16px");
|
||||
|
||||
function closeModal(){
|
||||
hideModal($(".blue-border-box"));
|
||||
}
|
||||
|
||||
}
|
||||
else if (data.status == -2){
|
||||
// confirm("对不起该作业的作品过少不能查重!");
|
||||
$("#ajax-modal").html('<%= escape_javascript( render :partial => 'courses/compare_code_tips_2',:locals => {:des=>"对不起该作业的作品过少不能查重!",:status=>0, :homework=> @homework,:courseid=> @course.id})%>');
|
||||
showModal('ajax-modal', '580px');
|
||||
$('#ajax-modal').siblings().remove();
|
||||
$('#ajax-modal').before("<a href='javascript:void(0)' onclick='hideModal();' style='margin-left: 560px;' class='resourceClose'></a>");
|
||||
$('#ajax-modal').parent().css("top","40%").css("left","50%");
|
||||
$('#ajax-modal').parent().addClass("resourceUploadPopup");
|
||||
$('#ajax-modal').css("padding-left","16px").css("padding-bottom","16px");
|
||||
|
||||
function closeModal(){
|
||||
hideModal($(".blue-border-box"));
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
).fail(function(xhr, status){
|
||||
// confirm("对不起,服务器繁忙请稍后再试!");
|
||||
$("#ajax-modal").html('<%= escape_javascript( render :partial => 'courses/compare_code_tips_2',:locals => {:des=>"对不起,服务器繁忙请稍后再试!",:status=>0, :homework=> @homework,:courseid=> @course.id})%>');
|
||||
showModal('ajax-modal', '580px');
|
||||
$('#ajax-modal').siblings().remove();
|
||||
$('#ajax-modal').before("<a href='javascript:void(0)' onclick='hideModal();' style='margin-left: 560px;' class='resourceClose'></a>");
|
||||
$('#ajax-modal').parent().css("top","40%").css("left","50%");
|
||||
$('#ajax-modal').parent().addClass("resourceUploadPopup");
|
||||
$('#ajax-modal').css("padding-left","16px").css("padding-bottom","16px");
|
||||
|
||||
function closeModal(){
|
||||
hideModal($(".blue-border-box"));
|
||||
}
|
||||
return;
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
</script>
|
|
@ -0,0 +1,2 @@
|
|||
|
||||
|
|
@ -24,6 +24,8 @@
|
|||
<%= submit_tag '',:class=>'searchIcon2',:onfocus=>"this.blur();",:style=>'border-style:none' %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="project_file_form">
|
||||
<%= render :partial => 'users/project_file_form', :locals => {:user => user, :projects => projects, :send_id => send_id, :send_ids => send_ids, :type => type} %>
|
||||
</div>
|
||||
|
|
|
@ -173,7 +173,7 @@
|
|||
</div>
|
||||
<% if !edit_mode || edit_mode && homework.homework_detail_manual.comment_status < 2 %>
|
||||
<div class="fl f14 ml10" style="margin-top: 4px;">
|
||||
<input type="checkbox" name="homework_common[anonymous_comment]" value="<%=edit_mode ? homework.anonymous_comment : 0 %>" id="anonymous_comment"/>
|
||||
<input type="checkbox" name="homework_common[anonymous_comment]" value="<%=edit_mode ? homework.anonymous_comment : 1 %>" id="anonymous_comment"/>
|
||||
<span class="f14 c_grey mr10">禁用匿评</span>
|
||||
</div>
|
||||
<% end %>
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
<%= javascript_include_tag "/assets/codemirror/codemirror_python_ruby_c" %>
|
||||
<%= javascript_include_tag 'homework','baiduTemplate' %>
|
||||
<%= stylesheet_link_tag "/assets/codemirror/codemirror" %>
|
||||
|
||||
<% end %>
|
||||
<script type="text/javascript">
|
||||
$(function(){
|
||||
|
@ -36,16 +35,17 @@
|
|||
<span class="w180"><pre style="white-space: pre-wrap; margin-right: 15px;"><!=results["result"]!> </pre></span>
|
||||
<span class="w60">正确输出:</span>
|
||||
<span class="w180"><pre style="white-space: pre-wrap; margin-right: 15px;"><!=results["output"]!></pre></span>
|
||||
<! if(results["status"]==2){!>
|
||||
<!--<! if(results["status"]==2){!>-->
|
||||
<span class="w50"> 耗时:</span>
|
||||
<span class="w80"><pre><!=results["time_used"]!>毫秒</pre></span>
|
||||
<!}!>
|
||||
<span class="w80"><pre><!=results["time_used"]==0?1:results["time_used"]!>毫秒</pre></span>
|
||||
<!--<!}!>-->
|
||||
<div class="cl"></div>
|
||||
</li>
|
||||
<!}else{!>
|
||||
<span class="w60 c_green">测试正确!</span>
|
||||
<!-- <span class="w50"> 耗时:</span> -->
|
||||
<!-- <span class="w80"><pre><!=results["time_used"]!>微秒</pre></span> -->
|
||||
<span style="width:480px;"> </span>
|
||||
<span class="w50"> 耗时:</span>
|
||||
<span class="w80"><pre ><!=results["time_used"]==0?1:results["time_used"]!>毫秒</pre></span>
|
||||
|
||||
<div class="cl"></div>
|
||||
</li>
|
||||
|
@ -146,16 +146,17 @@
|
|||
<span class="w180"><pre style="white-space: pre-wrap; margin-right: 15px;"><%=x["result"]%> </pre></span>
|
||||
<span class="w60">正确输出:</span>
|
||||
<span class="w180"><pre style="white-space: pre-wrap; margin-right: 15px;"><%= x["output"] %></pre></span>
|
||||
<% if x["status"].to_i == 2 %>
|
||||
|
||||
<span class="w50"> 耗时:</span>
|
||||
<span class="w80"><pre><%=x["time_used"]%>毫秒</pre></span>
|
||||
<% end %>
|
||||
<span class="w80"><pre><%=x["time_used"]==0?1:x["time_used"]%>毫秒</pre></span>
|
||||
|
||||
<div class="cl"></div>
|
||||
</li>
|
||||
<% else %>
|
||||
<span class="w60 c_green">测试正确!</span>
|
||||
<!-- <span class="w50"> 耗时:</span> -->
|
||||
<!-- <span class="w80"><pre><%=x["time_used"]%>微秒</pre></span> -->
|
||||
<span style="width:480px;"> </span>
|
||||
<span class="w50"> 耗时:</span>
|
||||
<span class="w80"><pre><%=x["time_used"]==0?1:x["time_used"]%>毫秒</pre></span>
|
||||
<div class="cl"></div>
|
||||
</li>
|
||||
<% end %>
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
|
||||
|
||||
<% if params[:is_observe].nil? %>
|
||||
<% if params[:send_type].present? && params[:send_type] == 'news' %>
|
||||
$("#ajax-modal").html('<%= escape_javascript( render :partial => 'users/share_news_to_project', :locals => {:projects => @projects, :user => @user, :send_id => @send_id, :send_ids => @send_ids}) %>');
|
||||
|
|
|
@ -25,16 +25,17 @@
|
|||
<span class="w180"><pre style="white-space: pre-wrap; margin-right: 15px;"><!=results["result"]!> </pre></span>
|
||||
<span class="w60">正确输出:</span>
|
||||
<span class="w180"><pre style="white-space: pre-wrap; margin-right: 15px;"><!=results["output"]!></pre></span>
|
||||
<! if(results["status"]==2){!>
|
||||
<!--<! if(results["status"]==2){!>-->
|
||||
<span class="w50"> 耗时:</span>
|
||||
<span class="w80"><pre><!=results["time_used"]!>毫秒</pre></span>
|
||||
<!}!>
|
||||
<span class="w80"><pre><!=results["time_used"]==0?1:results["time_used"]!>毫秒</pre></span>
|
||||
<!--<!}!>-->
|
||||
<div class="cl"></div>
|
||||
</li>
|
||||
<!}else{!>
|
||||
<span class="w60 c_green">测试正确!</span>
|
||||
<!-- <span class="w50"> 耗时:</span> -->
|
||||
<!-- <span class="w80"><pre><!=results["time_used"]!>微秒</pre></span> -->
|
||||
<span style="width:480px;"> </span>
|
||||
<span class="w50"> 耗时:</span>
|
||||
<span class="w80"><pre><!=results["time_used"]==0?1:results["time_used"]!>毫秒</pre></span>
|
||||
|
||||
<div class="cl"></div>
|
||||
</li>
|
||||
|
@ -113,16 +114,15 @@
|
|||
<span class="w180"><pre style="white-space: pre-wrap; margin-right: 15px;"><%=x["result"]%> </pre></span>
|
||||
<span class="w60">正确输出:</span>
|
||||
<span class="w180"><pre style="white-space: pre-wrap; margin-right: 15px;"><%=x["output"]%></pre></span>
|
||||
<% if x["status"].to_i == 2 %>
|
||||
<span class="w50"> 耗时:</span>
|
||||
<span class="w80"><pre><%=x["time_used"]%>毫秒</pre></span>
|
||||
<% end %>
|
||||
<span class="w80"><pre><%=x["time_used"]==0?1:x["time_used"] %>毫秒</pre></span>
|
||||
<div class="cl"></div>
|
||||
</li>
|
||||
<% else %>
|
||||
<span class="w60 c_green">测试正确!</span>
|
||||
<!--<span class="w50"> 耗时:</span> -->
|
||||
<!--<span class="w80"><pre><%=x["time_used"]%>微秒</pre></span> -->
|
||||
<span style="width:480px;"> </span>
|
||||
<span class="w50"> 耗时:</span>
|
||||
<span class="w80"><pre><%=x["time_used"]==0?1:x["time_used"]%>毫秒</pre></span>
|
||||
<div class="cl"></div>
|
||||
</li>
|
||||
<% end %>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<link rel="stylesheet" href="/stylesheets/weui/weui.min.css"/>
|
||||
<script type="text/javascript">
|
||||
function close(){
|
||||
WeixinJSBridge.call('closeWindow');
|
||||
window.close();
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -2124,3 +2124,29 @@ zh:
|
|||
label_resource_upload_author: 上传者
|
||||
label_resource_belongs_course: 所属课程
|
||||
label_resource_belongs_project: 所属项目
|
||||
|
||||
#微信模板消息
|
||||
label_new_homework_template: 您的课程有新作业了
|
||||
label_update_homework_template: 您的作业已被修改
|
||||
label_course_topic_template: 课程问答区有新帖子发布了
|
||||
label_topic_comment_template: 您的帖子有新回复了
|
||||
label_project_topic_template: 项目讨论区有新帖子发布了
|
||||
label_issue_comment_template: 您的缺陷有新回复了
|
||||
label_notice_comment_template: 您的课程通知有新回复了
|
||||
label_news_comment_template: 您的项目新闻有新回复了
|
||||
label_homework_comment_template: 您的作业有新回复了
|
||||
label_new_journals_template: 您有新留言了
|
||||
label_journals_comment_template: 您的留言有新回复了
|
||||
label_blog_comment_template: 您的博客有新回复了
|
||||
label_new_blog_template: 您的课程有新作业了
|
||||
label_new_issue_template: 您有新缺陷了
|
||||
label_new_notice_template: 您的课程有新通知了
|
||||
label_resource_name: 您的课程有新作业了
|
||||
label_resource_name: 您的课程有新作业了
|
||||
label_resource_name: 您的课程有新作业了
|
||||
label_resource_name: 您的课程有新作业了
|
||||
label_resource_name: 您的课程有新作业了
|
||||
label_resource_name: 您的课程有新作业了
|
||||
#edit yk
|
||||
label_code_work_tests: 代码测试列表
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ button:
|
|||
-
|
||||
type: "view"
|
||||
name: "最新动态"
|
||||
url: "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxc09454f171153c2d&redirect_uri=http://wechat.trustie.net/assets/wechat/app.html#/activities?response_type=code&scope=snsapi_base&state=123#wechat_redirect"
|
||||
url: "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxc09454f171153c2d&redirect_uri=https://www.trustie.net/assets/wechat/app.html#/activities?response_type=code&scope=snsapi_base&state=123#wechat_redirect"
|
||||
-
|
||||
type: "click"
|
||||
name: "意见返馈"
|
||||
|
@ -13,7 +13,7 @@ button:
|
|||
-
|
||||
type: "view"
|
||||
name: "进入网站"
|
||||
url: "http://www.trustie.net/"
|
||||
url: "https://www.trustie.net/"
|
||||
-
|
||||
type: "view"
|
||||
name: "使用手册"
|
||||
|
|
|
@ -283,6 +283,8 @@ RedmineApp::Application.routes.draw do
|
|||
get 'evaluation_list'
|
||||
# post 'set_program_score'
|
||||
post 'program_test_ex'
|
||||
post 'code_repeattest'
|
||||
post 'last_codecomparetime'
|
||||
post 'set_score_rule'
|
||||
end
|
||||
end
|
||||
|
@ -977,6 +979,7 @@ RedmineApp::Application.routes.draw do
|
|||
match 'admin/latest_login_users', as: :latest_login_users
|
||||
match 'admin/latest_login_teachers', as: :latest_login_teachers
|
||||
get 'admin/homework'
|
||||
get 'admin/code_work_tests'
|
||||
|
||||
resources :auth_sources do
|
||||
member do
|
||||
|
@ -997,6 +1000,7 @@ RedmineApp::Application.routes.draw do
|
|||
get 'search_member', :action => 'search_member'
|
||||
get 'file', :action => 'file', :as => 'file'
|
||||
get 'feedback', :action => 'feedback', :as => 'course_feedback'
|
||||
get 'code_repeat', :action => 'code_repeat', :as => 'code_repeat'
|
||||
get 'member', :controller => 'courses', :action => 'member', :as => 'member'
|
||||
get 'export_course_member_excel',:controller => 'courses',:action => 'export_course_member_excel'
|
||||
get 'member_score', :to => 'courses#member_score'
|
||||
|
@ -1023,10 +1027,10 @@ RedmineApp::Application.routes.draw do
|
|||
get 'syllabus'
|
||||
get 'search_public_orgs_not_in_course'
|
||||
get "homework_search"
|
||||
get "show_comparecode"
|
||||
end
|
||||
collection do
|
||||
match 'join_private_courses', :via => [:get, :post]
|
||||
|
||||
end
|
||||
|
||||
match '/member', :to => 'courses#member', :as => 'member', :via => :get
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
class AddSimiIdToStudentWorks < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :student_works, :simi_id, :integer, :default => false
|
||||
add_column :student_works, :simi_value, :integer, :default => false
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
class AddSimiTimeToHomeworkCommons < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :homework_commons, :simi_time, :datetime
|
||||
end
|
||||
end
|
|
@ -395,6 +395,7 @@ Redmine::MenuManager.map :admin_menu do |menu|
|
|||
menu.push :course_resource_list, {:controller => 'admin', :action => 'course_resource_list'}, :caption => :label_course_resource_list
|
||||
menu.push :project_resource_list, {:controller => 'admin', :action => 'project_resource_list'}, :caption => :label_project_resource_list
|
||||
menu.push :homework, {:controller => 'admin', :action => 'homework'}, :caption => :label_user_homework
|
||||
menu.push :code_work_tests, {:controller => 'admin', :action => 'code_work_tests'}, :caption => :label_code_work_tests
|
||||
|
||||
end
|
||||
#Modified by young
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
.CodeMirror-merge {
|
||||
position: relative;
|
||||
border: 1px solid #ddd;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
.CodeMirror-merge, .CodeMirror-merge .CodeMirror {
|
||||
height: 350px;
|
||||
}
|
||||
|
||||
.CodeMirror-merge-2pane .CodeMirror-merge-pane { width: 47%; }
|
||||
.CodeMirror-merge-2pane .CodeMirror-merge-gap { width: 6%; }
|
||||
.CodeMirror-merge-3pane .CodeMirror-merge-pane { width: 31%; }
|
||||
.CodeMirror-merge-3pane .CodeMirror-merge-gap { width: 3.5%; }
|
||||
|
||||
.CodeMirror-merge-pane {
|
||||
display: inline-block;
|
||||
white-space: normal;
|
||||
vertical-align: top;
|
||||
}
|
||||
.CodeMirror-merge-pane-rightmost {
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.CodeMirror-merge-gap {
|
||||
z-index: 2;
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
border-left: 1px solid #ddd;
|
||||
border-right: 1px solid #ddd;
|
||||
position: relative;
|
||||
background: #f8f8f8;
|
||||
}
|
||||
|
||||
.CodeMirror-merge-scrolllock-wrap {
|
||||
position: absolute;
|
||||
bottom: 0; left: 50%;
|
||||
}
|
||||
.CodeMirror-merge-scrolllock {
|
||||
position: relative;
|
||||
left: -50%;
|
||||
cursor: pointer;
|
||||
color: #555;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.CodeMirror-merge-copybuttons-left, .CodeMirror-merge-copybuttons-right {
|
||||
position: absolute;
|
||||
left: 0; top: 0;
|
||||
right: 0; bottom: 0;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.CodeMirror-merge-copy {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
color: #44c;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.CodeMirror-merge-copy-reverse {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
color: #44c;
|
||||
}
|
||||
|
||||
.CodeMirror-merge-copybuttons-left .CodeMirror-merge-copy { left: 2px; }
|
||||
.CodeMirror-merge-copybuttons-right .CodeMirror-merge-copy { right: 2px; }
|
||||
|
||||
.CodeMirror-merge-r-inserted, .CodeMirror-merge-l-inserted {
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAACCAYAAACddGYaAAAAGUlEQVQI12MwuCXy3+CWyH8GBgYGJgYkAABZbAQ9ELXurwAAAABJRU5ErkJggg==);
|
||||
background-position: bottom left;
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
|
||||
.CodeMirror-merge-r-deleted, .CodeMirror-merge-l-deleted {
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAACCAYAAACddGYaAAAAGUlEQVQI12M4Kyb2/6yY2H8GBgYGJgYkAABURgPz6Ks7wQAAAABJRU5ErkJggg==);
|
||||
background-position: bottom left;
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
|
||||
.CodeMirror-merge-r-chunk { background: #ffffe0; }
|
||||
.CodeMirror-merge-r-chunk-start { border-top: 1px solid #ee8; }
|
||||
.CodeMirror-merge-r-chunk-end { border-bottom: 1px solid #ee8; }
|
||||
.CodeMirror-merge-r-connect { fill: #ffffe0; stroke: #ee8; stroke-width: 1px; }
|
||||
|
||||
.CodeMirror-merge-l-chunk { background: #eef; }
|
||||
.CodeMirror-merge-l-chunk-start { border-top: 1px solid #88e; }
|
||||
.CodeMirror-merge-l-chunk-end { border-bottom: 1px solid #88e; }
|
||||
.CodeMirror-merge-l-connect { fill: #eef; stroke: #88e; stroke-width: 1px; }
|
||||
|
||||
.CodeMirror-merge-l-chunk.CodeMirror-merge-r-chunk { background: #dfd; }
|
||||
.CodeMirror-merge-l-chunk-start.CodeMirror-merge-r-chunk-start { border-top: 1px solid #4e4; }
|
||||
.CodeMirror-merge-l-chunk-end.CodeMirror-merge-r-chunk-end { border-bottom: 1px solid #4e4; }
|
||||
|
||||
.CodeMirror-merge-collapsed-widget:before {
|
||||
content: "(...)";
|
||||
}
|
||||
.CodeMirror-merge-collapsed-widget {
|
||||
cursor: pointer;
|
||||
color: #88b;
|
||||
background: #eef;
|
||||
border: 1px solid #ddf;
|
||||
font-size: 90%;
|
||||
padding: 0 3px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.CodeMirror-merge-collapsed-line .CodeMirror-gutter-elt { display: none; }
|
|
@ -0,0 +1,774 @@
|
|||
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
||||
// Distributed under an MIT license: http://codemirror.net/LICENSE
|
||||
|
||||
// declare global: diff_match_patch, DIFF_INSERT, DIFF_DELETE, DIFF_EQUAL
|
||||
|
||||
(function(mod) {
|
||||
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
||||
mod(require("../../lib/codemirror")); // Note non-packaged dependency diff_match_patch
|
||||
else if (typeof define == "function" && define.amd) // AMD
|
||||
define(["../../lib/codemirror", "diff_match_patch"], mod);
|
||||
else // Plain browser env
|
||||
mod(CodeMirror);
|
||||
})(function(CodeMirror) {
|
||||
"use strict";
|
||||
var Pos = CodeMirror.Pos;
|
||||
var svgNS = "http://www.w3.org/2000/svg";
|
||||
|
||||
function DiffView(mv, type) {
|
||||
this.mv = mv;
|
||||
this.type = type;
|
||||
this.classes = type == "left"
|
||||
? {chunk: "CodeMirror-merge-l-chunk",
|
||||
start: "CodeMirror-merge-l-chunk-start",
|
||||
end: "CodeMirror-merge-l-chunk-end",
|
||||
insert: "CodeMirror-merge-l-inserted",
|
||||
del: "CodeMirror-merge-l-deleted",
|
||||
connect: "CodeMirror-merge-l-connect"}
|
||||
: {chunk: "CodeMirror-merge-r-chunk",
|
||||
start: "CodeMirror-merge-r-chunk-start",
|
||||
end: "CodeMirror-merge-r-chunk-end",
|
||||
insert: "CodeMirror-merge-r-inserted",
|
||||
del: "CodeMirror-merge-r-deleted",
|
||||
connect: "CodeMirror-merge-r-connect"};
|
||||
}
|
||||
|
||||
DiffView.prototype = {
|
||||
constructor: DiffView,
|
||||
init: function(pane, orig, options) {
|
||||
this.edit = this.mv.edit;
|
||||
(this.edit.state.diffViews || (this.edit.state.diffViews = [])).push(this);
|
||||
this.orig = CodeMirror(pane, copyObj({value: orig, readOnly: !this.mv.options.allowEditingOriginals}, copyObj(options)));
|
||||
this.orig.state.diffViews = [this];
|
||||
|
||||
this.diff = getDiff(asString(orig), asString(options.value));
|
||||
this.chunks = getChunks(this.diff);
|
||||
this.diffOutOfDate = this.dealigned = false;
|
||||
|
||||
this.showDifferences = options.showDifferences !== false;
|
||||
this.forceUpdate = registerUpdate(this);
|
||||
setScrollLock(this, true, false);
|
||||
registerScroll(this);
|
||||
},
|
||||
setShowDifferences: function(val) {
|
||||
val = val !== false;
|
||||
if (val != this.showDifferences) {
|
||||
this.showDifferences = val;
|
||||
this.forceUpdate("full");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function ensureDiff(dv) {
|
||||
if (dv.diffOutOfDate) {
|
||||
dv.diff = getDiff(dv.orig.getValue(), dv.edit.getValue());
|
||||
dv.chunks = getChunks(dv.diff);
|
||||
dv.diffOutOfDate = false;
|
||||
CodeMirror.signal(dv.edit, "updateDiff", dv.diff);
|
||||
}
|
||||
}
|
||||
|
||||
var updating = false;
|
||||
function registerUpdate(dv) {
|
||||
var edit = {from: 0, to: 0, marked: []};
|
||||
var orig = {from: 0, to: 0, marked: []};
|
||||
var debounceChange, updatingFast = false;
|
||||
function update(mode) {
|
||||
updating = true;
|
||||
updatingFast = false;
|
||||
if (mode == "full") {
|
||||
if (dv.svg) clear(dv.svg);
|
||||
if (dv.copyButtons) clear(dv.copyButtons);
|
||||
clearMarks(dv.edit, edit.marked, dv.classes);
|
||||
clearMarks(dv.orig, orig.marked, dv.classes);
|
||||
edit.from = edit.to = orig.from = orig.to = 0;
|
||||
}
|
||||
ensureDiff(dv);
|
||||
if (dv.showDifferences) {
|
||||
updateMarks(dv.edit, dv.diff, edit, DIFF_INSERT, dv.classes);
|
||||
updateMarks(dv.orig, dv.diff, orig, DIFF_DELETE, dv.classes);
|
||||
}
|
||||
makeConnections(dv);
|
||||
|
||||
if (dv.mv.options.connect == "align")
|
||||
alignChunks(dv);
|
||||
updating = false;
|
||||
}
|
||||
function setDealign(fast) {
|
||||
if (updating) return;
|
||||
dv.dealigned = true;
|
||||
set(fast);
|
||||
}
|
||||
function set(fast) {
|
||||
if (updating || updatingFast) return;
|
||||
clearTimeout(debounceChange);
|
||||
if (fast === true) updatingFast = true;
|
||||
debounceChange = setTimeout(update, fast === true ? 20 : 250);
|
||||
}
|
||||
function change(_cm, change) {
|
||||
if (!dv.diffOutOfDate) {
|
||||
dv.diffOutOfDate = true;
|
||||
edit.from = edit.to = orig.from = orig.to = 0;
|
||||
}
|
||||
// Update faster when a line was added/removed
|
||||
setDealign(change.text.length - 1 != change.to.line - change.from.line);
|
||||
}
|
||||
dv.edit.on("change", change);
|
||||
dv.orig.on("change", change);
|
||||
dv.edit.on("markerAdded", setDealign);
|
||||
dv.edit.on("markerCleared", setDealign);
|
||||
dv.orig.on("markerAdded", setDealign);
|
||||
dv.orig.on("markerCleared", setDealign);
|
||||
dv.edit.on("viewportChange", function() { set(false); });
|
||||
dv.orig.on("viewportChange", function() { set(false); });
|
||||
update();
|
||||
return update;
|
||||
}
|
||||
|
||||
function registerScroll(dv) {
|
||||
dv.edit.on("scroll", function() {
|
||||
syncScroll(dv, DIFF_INSERT) && makeConnections(dv);
|
||||
});
|
||||
dv.orig.on("scroll", function() {
|
||||
syncScroll(dv, DIFF_DELETE) && makeConnections(dv);
|
||||
});
|
||||
}
|
||||
|
||||
function syncScroll(dv, type) {
|
||||
// Change handler will do a refresh after a timeout when diff is out of date
|
||||
if (dv.diffOutOfDate) return false;
|
||||
if (!dv.lockScroll) return true;
|
||||
var editor, other, now = +new Date;
|
||||
if (type == DIFF_INSERT) { editor = dv.edit; other = dv.orig; }
|
||||
else { editor = dv.orig; other = dv.edit; }
|
||||
// Don't take action if the position of this editor was recently set
|
||||
// (to prevent feedback loops)
|
||||
if (editor.state.scrollSetBy == dv && (editor.state.scrollSetAt || 0) + 50 > now) return false;
|
||||
|
||||
var sInfo = editor.getScrollInfo();
|
||||
if (dv.mv.options.connect == "align") {
|
||||
targetPos = sInfo.top;
|
||||
} else {
|
||||
var halfScreen = .5 * sInfo.clientHeight, midY = sInfo.top + halfScreen;
|
||||
var mid = editor.lineAtHeight(midY, "local");
|
||||
var around = chunkBoundariesAround(dv.chunks, mid, type == DIFF_INSERT);
|
||||
var off = getOffsets(editor, type == DIFF_INSERT ? around.edit : around.orig);
|
||||
var offOther = getOffsets(other, type == DIFF_INSERT ? around.orig : around.edit);
|
||||
var ratio = (midY - off.top) / (off.bot - off.top);
|
||||
var targetPos = (offOther.top - halfScreen) + ratio * (offOther.bot - offOther.top);
|
||||
|
||||
var botDist, mix;
|
||||
// Some careful tweaking to make sure no space is left out of view
|
||||
// when scrolling to top or bottom.
|
||||
if (targetPos > sInfo.top && (mix = sInfo.top / halfScreen) < 1) {
|
||||
targetPos = targetPos * mix + sInfo.top * (1 - mix);
|
||||
} else if ((botDist = sInfo.height - sInfo.clientHeight - sInfo.top) < halfScreen) {
|
||||
var otherInfo = other.getScrollInfo();
|
||||
var botDistOther = otherInfo.height - otherInfo.clientHeight - targetPos;
|
||||
if (botDistOther > botDist && (mix = botDist / halfScreen) < 1)
|
||||
targetPos = targetPos * mix + (otherInfo.height - otherInfo.clientHeight - botDist) * (1 - mix);
|
||||
}
|
||||
}
|
||||
|
||||
other.scrollTo(sInfo.left, targetPos);
|
||||
other.state.scrollSetAt = now;
|
||||
other.state.scrollSetBy = dv;
|
||||
return true;
|
||||
}
|
||||
|
||||
function getOffsets(editor, around) {
|
||||
var bot = around.after;
|
||||
if (bot == null) bot = editor.lastLine() + 1;
|
||||
return {top: editor.heightAtLine(around.before || 0, "local"),
|
||||
bot: editor.heightAtLine(bot, "local")};
|
||||
}
|
||||
|
||||
function setScrollLock(dv, val, action) {
|
||||
dv.lockScroll = val;
|
||||
if (val && action != false) syncScroll(dv, DIFF_INSERT) && makeConnections(dv);
|
||||
dv.lockButton.innerHTML = val ? "\u21db\u21da" : "\u21db \u21da";
|
||||
}
|
||||
|
||||
// Updating the marks for editor content
|
||||
|
||||
function clearMarks(editor, arr, classes) {
|
||||
for (var i = 0; i < arr.length; ++i) {
|
||||
var mark = arr[i];
|
||||
if (mark instanceof CodeMirror.TextMarker) {
|
||||
mark.clear();
|
||||
} else if (mark.parent) {
|
||||
editor.removeLineClass(mark, "background", classes.chunk);
|
||||
editor.removeLineClass(mark, "background", classes.start);
|
||||
editor.removeLineClass(mark, "background", classes.end);
|
||||
}
|
||||
}
|
||||
arr.length = 0;
|
||||
}
|
||||
|
||||
// FIXME maybe add a margin around viewport to prevent too many updates
|
||||
function updateMarks(editor, diff, state, type, classes) {
|
||||
var vp = editor.getViewport();
|
||||
editor.operation(function() {
|
||||
if (state.from == state.to || vp.from - state.to > 20 || state.from - vp.to > 20) {
|
||||
clearMarks(editor, state.marked, classes);
|
||||
markChanges(editor, diff, type, state.marked, vp.from, vp.to, classes);
|
||||
state.from = vp.from; state.to = vp.to;
|
||||
} else {
|
||||
if (vp.from < state.from) {
|
||||
markChanges(editor, diff, type, state.marked, vp.from, state.from, classes);
|
||||
state.from = vp.from;
|
||||
}
|
||||
if (vp.to > state.to) {
|
||||
markChanges(editor, diff, type, state.marked, state.to, vp.to, classes);
|
||||
state.to = vp.to;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function markChanges(editor, diff, type, marks, from, to, classes) {
|
||||
var pos = Pos(0, 0);
|
||||
var top = Pos(from, 0), bot = editor.clipPos(Pos(to - 1));
|
||||
var cls = type == DIFF_DELETE ? classes.del : classes.insert;
|
||||
function markChunk(start, end) {
|
||||
var bfrom = Math.max(from, start), bto = Math.min(to, end);
|
||||
for (var i = bfrom; i < bto; ++i) {
|
||||
var line = editor.addLineClass(i, "background", classes.chunk);
|
||||
if (i == start) editor.addLineClass(line, "background", classes.start);
|
||||
if (i == end - 1) editor.addLineClass(line, "background", classes.end);
|
||||
marks.push(line);
|
||||
}
|
||||
// When the chunk is empty, make sure a horizontal line shows up
|
||||
if (start == end && bfrom == end && bto == end) {
|
||||
if (bfrom)
|
||||
marks.push(editor.addLineClass(bfrom - 1, "background", classes.end));
|
||||
else
|
||||
marks.push(editor.addLineClass(bfrom, "background", classes.start));
|
||||
}
|
||||
}
|
||||
|
||||
var chunkStart = 0;
|
||||
for (var i = 0; i < diff.length; ++i) {
|
||||
var part = diff[i], tp = part[0], str = part[1];
|
||||
if (tp == DIFF_EQUAL) {
|
||||
var cleanFrom = pos.line + (startOfLineClean(diff, i) ? 0 : 1);
|
||||
moveOver(pos, str);
|
||||
var cleanTo = pos.line + (endOfLineClean(diff, i) ? 1 : 0);
|
||||
if (cleanTo > cleanFrom) {
|
||||
if (i) markChunk(chunkStart, cleanFrom);
|
||||
chunkStart = cleanTo;
|
||||
}
|
||||
} else {
|
||||
if (tp == type) {
|
||||
var end = moveOver(pos, str, true);
|
||||
var a = posMax(top, pos), b = posMin(bot, end);
|
||||
if (!posEq(a, b))
|
||||
marks.push(editor.markText(a, b, {className: cls}));
|
||||
pos = end;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (chunkStart <= pos.line) markChunk(chunkStart, pos.line + 1);
|
||||
}
|
||||
|
||||
// Updating the gap between editor and original
|
||||
|
||||
function makeConnections(dv) {
|
||||
if (!dv.showDifferences) return;
|
||||
|
||||
if (dv.svg) {
|
||||
clear(dv.svg);
|
||||
var w = dv.gap.offsetWidth;
|
||||
attrs(dv.svg, "width", w, "height", dv.gap.offsetHeight);
|
||||
}
|
||||
if (dv.copyButtons) clear(dv.copyButtons);
|
||||
|
||||
var vpEdit = dv.edit.getViewport(), vpOrig = dv.orig.getViewport();
|
||||
var sTopEdit = dv.edit.getScrollInfo().top, sTopOrig = dv.orig.getScrollInfo().top;
|
||||
for (var i = 0; i < dv.chunks.length; i++) {
|
||||
var ch = dv.chunks[i];
|
||||
if (ch.editFrom <= vpEdit.to && ch.editTo >= vpEdit.from &&
|
||||
ch.origFrom <= vpOrig.to && ch.origTo >= vpOrig.from)
|
||||
drawConnectorsForChunk(dv, ch, sTopOrig, sTopEdit, w);
|
||||
}
|
||||
}
|
||||
|
||||
function getMatchingOrigLine(editLine, chunks) {
|
||||
var editStart = 0, origStart = 0;
|
||||
for (var i = 0; i < chunks.length; i++) {
|
||||
var chunk = chunks[i];
|
||||
if (chunk.editTo > editLine && chunk.editFrom <= editLine) return null;
|
||||
if (chunk.editFrom > editLine) break;
|
||||
editStart = chunk.editTo;
|
||||
origStart = chunk.origTo;
|
||||
}
|
||||
return origStart + (editLine - editStart);
|
||||
}
|
||||
|
||||
function findAlignedLines(dv, other) {
|
||||
var linesToAlign = [];
|
||||
for (var i = 0; i < dv.chunks.length; i++) {
|
||||
var chunk = dv.chunks[i];
|
||||
linesToAlign.push([chunk.origTo, chunk.editTo, other ? getMatchingOrigLine(chunk.editTo, other.chunks) : null]);
|
||||
}
|
||||
if (other) {
|
||||
for (var i = 0; i < other.chunks.length; i++) {
|
||||
var chunk = other.chunks[i];
|
||||
for (var j = 0; j < linesToAlign.length; j++) {
|
||||
var align = linesToAlign[j];
|
||||
if (align[1] == chunk.editTo) {
|
||||
j = -1;
|
||||
break;
|
||||
} else if (align[1] > chunk.editTo) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j > -1)
|
||||
linesToAlign.splice(j - 1, 0, [getMatchingOrigLine(chunk.editTo, dv.chunks), chunk.editTo, chunk.origTo]);
|
||||
}
|
||||
}
|
||||
return linesToAlign;
|
||||
}
|
||||
|
||||
function alignChunks(dv, force) {
|
||||
if (!dv.dealigned && !force) return;
|
||||
if (!dv.orig.curOp) return dv.orig.operation(function() {
|
||||
alignChunks(dv, force);
|
||||
});
|
||||
|
||||
dv.dealigned = false;
|
||||
var other = dv.mv.left == dv ? dv.mv.right : dv.mv.left;
|
||||
if (other) {
|
||||
ensureDiff(other);
|
||||
other.dealigned = false;
|
||||
}
|
||||
var linesToAlign = findAlignedLines(dv, other);
|
||||
|
||||
// Clear old aligners
|
||||
var aligners = dv.mv.aligners;
|
||||
for (var i = 0; i < aligners.length; i++)
|
||||
aligners[i].clear();
|
||||
aligners.length = 0;
|
||||
|
||||
var cm = [dv.orig, dv.edit], scroll = [];
|
||||
if (other) cm.push(other.orig);
|
||||
for (var i = 0; i < cm.length; i++)
|
||||
scroll.push(cm[i].getScrollInfo().top);
|
||||
|
||||
for (var ln = 0; ln < linesToAlign.length; ln++)
|
||||
alignLines(cm, linesToAlign[ln], aligners);
|
||||
|
||||
for (var i = 0; i < cm.length; i++)
|
||||
cm[i].scrollTo(null, scroll[i]);
|
||||
}
|
||||
|
||||
function alignLines(cm, lines, aligners) {
|
||||
var maxOffset = 0, offset = [];
|
||||
for (var i = 0; i < cm.length; i++) if (lines[i] != null) {
|
||||
var off = cm[i].heightAtLine(lines[i], "local");
|
||||
offset[i] = off;
|
||||
maxOffset = Math.max(maxOffset, off);
|
||||
}
|
||||
for (var i = 0; i < cm.length; i++) if (lines[i] != null) {
|
||||
var diff = maxOffset - offset[i];
|
||||
if (diff > 1)
|
||||
aligners.push(padAbove(cm[i], lines[i], diff));
|
||||
}
|
||||
}
|
||||
|
||||
function padAbove(cm, line, size) {
|
||||
var above = true;
|
||||
if (line > cm.lastLine()) {
|
||||
line--;
|
||||
above = false;
|
||||
}
|
||||
var elt = document.createElement("div");
|
||||
elt.className = "CodeMirror-merge-spacer";
|
||||
elt.style.height = size + "px"; elt.style.minWidth = "1px";
|
||||
return cm.addLineWidget(line, elt, {height: size, above: above});
|
||||
}
|
||||
|
||||
function drawConnectorsForChunk(dv, chunk, sTopOrig, sTopEdit, w) {
|
||||
var flip = dv.type == "left";
|
||||
var top = dv.orig.heightAtLine(chunk.origFrom, "local") - sTopOrig;
|
||||
if (dv.svg) {
|
||||
var topLpx = top;
|
||||
var topRpx = dv.edit.heightAtLine(chunk.editFrom, "local") - sTopEdit;
|
||||
if (flip) { var tmp = topLpx; topLpx = topRpx; topRpx = tmp; }
|
||||
var botLpx = dv.orig.heightAtLine(chunk.origTo, "local") - sTopOrig;
|
||||
var botRpx = dv.edit.heightAtLine(chunk.editTo, "local") - sTopEdit;
|
||||
if (flip) { var tmp = botLpx; botLpx = botRpx; botRpx = tmp; }
|
||||
var curveTop = " C " + w/2 + " " + topRpx + " " + w/2 + " " + topLpx + " " + (w + 2) + " " + topLpx;
|
||||
var curveBot = " C " + w/2 + " " + botLpx + " " + w/2 + " " + botRpx + " -1 " + botRpx;
|
||||
attrs(dv.svg.appendChild(document.createElementNS(svgNS, "path")),
|
||||
"d", "M -1 " + topRpx + curveTop + " L " + (w + 2) + " " + botLpx + curveBot + " z",
|
||||
"class", dv.classes.connect);
|
||||
}
|
||||
if (dv.copyButtons) {
|
||||
var copy = dv.copyButtons.appendChild(elt("div", dv.type == "left" ? "\u21dd" : "\u21dc",
|
||||
"CodeMirror-merge-copy"));
|
||||
var editOriginals = dv.mv.options.allowEditingOriginals;
|
||||
copy.title = editOriginals ? "Push to left" : "Revert chunk";
|
||||
copy.chunk = chunk;
|
||||
copy.style.top = top + "px";
|
||||
|
||||
if (editOriginals) {
|
||||
var topReverse = dv.orig.heightAtLine(chunk.editFrom, "local") - sTopEdit;
|
||||
var copyReverse = dv.copyButtons.appendChild(elt("div", dv.type == "right" ? "\u21dd" : "\u21dc",
|
||||
"CodeMirror-merge-copy-reverse"));
|
||||
copyReverse.title = "Push to right";
|
||||
copyReverse.chunk = {editFrom: chunk.origFrom, editTo: chunk.origTo,
|
||||
origFrom: chunk.editFrom, origTo: chunk.editTo};
|
||||
copyReverse.style.top = topReverse + "px";
|
||||
dv.type == "right" ? copyReverse.style.left = "2px" : copyReverse.style.right = "2px";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function copyChunk(dv, to, from, chunk) {
|
||||
if (dv.diffOutOfDate) return;
|
||||
var editStart = chunk.editTo > to.lastLine() ? Pos(chunk.editFrom - 1) : Pos(chunk.editFrom, 0)
|
||||
var origStart = chunk.origTo > from.lastLine() ? Pos(chunk.origFrom - 1) : Pos(chunk.origFrom, 0)
|
||||
to.replaceRange(from.getRange(origStart, Pos(chunk.origTo, 0)), editStart, Pos(chunk.editTo, 0))
|
||||
}
|
||||
|
||||
// Merge view, containing 0, 1, or 2 diff views.
|
||||
|
||||
var MergeView = CodeMirror.MergeView = function(node, options) {
|
||||
if (!(this instanceof MergeView)) return new MergeView(node, options);
|
||||
|
||||
this.options = options;
|
||||
var origLeft = options.origLeft, origRight = options.origRight == null ? options.orig : options.origRight;
|
||||
|
||||
var hasLeft = origLeft != null, hasRight = origRight != null;
|
||||
var panes = 1 + (hasLeft ? 1 : 0) + (hasRight ? 1 : 0);
|
||||
var wrap = [], left = this.left = null, right = this.right = null;
|
||||
var self = this;
|
||||
|
||||
if (hasLeft) {
|
||||
left = this.left = new DiffView(this, "left");
|
||||
var leftPane = elt("div", null, "CodeMirror-merge-pane");
|
||||
wrap.push(leftPane);
|
||||
wrap.push(buildGap(left));
|
||||
}
|
||||
|
||||
var editPane = elt("div", null, "CodeMirror-merge-pane");
|
||||
wrap.push(editPane);
|
||||
|
||||
if (hasRight) {
|
||||
right = this.right = new DiffView(this, "right");
|
||||
wrap.push(buildGap(right));
|
||||
var rightPane = elt("div", null, "CodeMirror-merge-pane");
|
||||
wrap.push(rightPane);
|
||||
}
|
||||
|
||||
(hasRight ? rightPane : editPane).className += " CodeMirror-merge-pane-rightmost";
|
||||
|
||||
wrap.push(elt("div", null, null, "height: 0; clear: both;"));
|
||||
|
||||
var wrapElt = this.wrap = node.appendChild(elt("div", wrap, "CodeMirror-merge CodeMirror-merge-" + panes + "pane"));
|
||||
this.edit = CodeMirror(editPane, copyObj(options));
|
||||
|
||||
if (left) left.init(leftPane, origLeft, options);
|
||||
if (right) right.init(rightPane, origRight, options);
|
||||
|
||||
if (options.collapseIdentical)
|
||||
this.editor().operation(function() {
|
||||
collapseIdenticalStretches(self, options.collapseIdentical);
|
||||
});
|
||||
if (options.connect == "align") {
|
||||
this.aligners = [];
|
||||
alignChunks(this.left || this.right, true);
|
||||
}
|
||||
|
||||
var onResize = function() {
|
||||
if (left) makeConnections(left);
|
||||
if (right) makeConnections(right);
|
||||
};
|
||||
CodeMirror.on(window, "resize", onResize);
|
||||
var resizeInterval = setInterval(function() {
|
||||
for (var p = wrapElt.parentNode; p && p != document.body; p = p.parentNode) {}
|
||||
if (!p) { clearInterval(resizeInterval); CodeMirror.off(window, "resize", onResize); }
|
||||
}, 5000);
|
||||
};
|
||||
|
||||
function buildGap(dv) {
|
||||
var lock = dv.lockButton = elt("div", null, "CodeMirror-merge-scrolllock");
|
||||
lock.title = "Toggle locked scrolling";
|
||||
var lockWrap = elt("div", [lock], "CodeMirror-merge-scrolllock-wrap");
|
||||
CodeMirror.on(lock, "click", function() { setScrollLock(dv, !dv.lockScroll); });
|
||||
var gapElts = [lockWrap];
|
||||
//去掉复制功能 yuanke20160408
|
||||
// if (dv.mv.options.revertButtons !== false) {
|
||||
// dv.copyButtons = elt("div", null, "CodeMirror-merge-copybuttons-" + dv.type);
|
||||
// CodeMirror.on(dv.copyButtons, "click", function(e) {
|
||||
// var node = e.target || e.srcElement;
|
||||
// if (!node.chunk) return;
|
||||
// if (node.className == "CodeMirror-merge-copy-reverse") {
|
||||
// copyChunk(dv, dv.orig, dv.edit, node.chunk);
|
||||
// return;
|
||||
// }
|
||||
// copyChunk(dv, dv.edit, dv.orig, node.chunk);
|
||||
// });
|
||||
// gapElts.unshift(dv.copyButtons);
|
||||
// }
|
||||
if (dv.mv.options.connect != "align") {
|
||||
var svg = document.createElementNS && document.createElementNS(svgNS, "svg");
|
||||
if (svg && !svg.createSVGRect) svg = null;
|
||||
dv.svg = svg;
|
||||
if (svg) gapElts.push(svg);
|
||||
}
|
||||
|
||||
return dv.gap = elt("div", gapElts, "CodeMirror-merge-gap");
|
||||
}
|
||||
|
||||
MergeView.prototype = {
|
||||
constuctor: MergeView,
|
||||
editor: function() { return this.edit; },
|
||||
rightOriginal: function() { return this.right && this.right.orig; },
|
||||
leftOriginal: function() { return this.left && this.left.orig; },
|
||||
setShowDifferences: function(val) {
|
||||
if (this.right) this.right.setShowDifferences(val);
|
||||
if (this.left) this.left.setShowDifferences(val);
|
||||
},
|
||||
rightChunks: function() {
|
||||
if (this.right) { ensureDiff(this.right); return this.right.chunks; }
|
||||
},
|
||||
leftChunks: function() {
|
||||
if (this.left) { ensureDiff(this.left); return this.left.chunks; }
|
||||
}
|
||||
};
|
||||
|
||||
function asString(obj) {
|
||||
if (typeof obj == "string") return obj;
|
||||
else return obj.getValue();
|
||||
}
|
||||
|
||||
// Operations on diffs
|
||||
|
||||
var dmp = new diff_match_patch();
|
||||
function getDiff(a, b) {
|
||||
var diff = dmp.diff_main(a, b);
|
||||
dmp.diff_cleanupSemantic(diff);
|
||||
// The library sometimes leaves in empty parts, which confuse the algorithm
|
||||
for (var i = 0; i < diff.length; ++i) {
|
||||
var part = diff[i];
|
||||
if (!part[1]) {
|
||||
diff.splice(i--, 1);
|
||||
} else if (i && diff[i - 1][0] == part[0]) {
|
||||
diff.splice(i--, 1);
|
||||
diff[i][1] += part[1];
|
||||
}
|
||||
}
|
||||
return diff;
|
||||
}
|
||||
|
||||
function getChunks(diff) {
|
||||
var chunks = [];
|
||||
var startEdit = 0, startOrig = 0;
|
||||
var edit = Pos(0, 0), orig = Pos(0, 0);
|
||||
for (var i = 0; i < diff.length; ++i) {
|
||||
var part = diff[i], tp = part[0];
|
||||
if (tp == DIFF_EQUAL) {
|
||||
var startOff = startOfLineClean(diff, i) ? 0 : 1;
|
||||
var cleanFromEdit = edit.line + startOff, cleanFromOrig = orig.line + startOff;
|
||||
moveOver(edit, part[1], null, orig);
|
||||
var endOff = endOfLineClean(diff, i) ? 1 : 0;
|
||||
var cleanToEdit = edit.line + endOff, cleanToOrig = orig.line + endOff;
|
||||
if (cleanToEdit > cleanFromEdit) {
|
||||
if (i) chunks.push({origFrom: startOrig, origTo: cleanFromOrig,
|
||||
editFrom: startEdit, editTo: cleanFromEdit});
|
||||
startEdit = cleanToEdit; startOrig = cleanToOrig;
|
||||
}
|
||||
} else {
|
||||
moveOver(tp == DIFF_INSERT ? edit : orig, part[1]);
|
||||
}
|
||||
}
|
||||
if (startEdit <= edit.line || startOrig <= orig.line)
|
||||
chunks.push({origFrom: startOrig, origTo: orig.line + 1,
|
||||
editFrom: startEdit, editTo: edit.line + 1});
|
||||
return chunks;
|
||||
}
|
||||
|
||||
function endOfLineClean(diff, i) {
|
||||
if (i == diff.length - 1) return true;
|
||||
var next = diff[i + 1][1];
|
||||
if (next.length == 1 || next.charCodeAt(0) != 10) return false;
|
||||
if (i == diff.length - 2) return true;
|
||||
next = diff[i + 2][1];
|
||||
return next.length > 1 && next.charCodeAt(0) == 10;
|
||||
}
|
||||
|
||||
function startOfLineClean(diff, i) {
|
||||
if (i == 0) return true;
|
||||
var last = diff[i - 1][1];
|
||||
if (last.charCodeAt(last.length - 1) != 10) return false;
|
||||
if (i == 1) return true;
|
||||
last = diff[i - 2][1];
|
||||
return last.charCodeAt(last.length - 1) == 10;
|
||||
}
|
||||
|
||||
function chunkBoundariesAround(chunks, n, nInEdit) {
|
||||
var beforeE, afterE, beforeO, afterO;
|
||||
for (var i = 0; i < chunks.length; i++) {
|
||||
var chunk = chunks[i];
|
||||
var fromLocal = nInEdit ? chunk.editFrom : chunk.origFrom;
|
||||
var toLocal = nInEdit ? chunk.editTo : chunk.origTo;
|
||||
if (afterE == null) {
|
||||
if (fromLocal > n) { afterE = chunk.editFrom; afterO = chunk.origFrom; }
|
||||
else if (toLocal > n) { afterE = chunk.editTo; afterO = chunk.origTo; }
|
||||
}
|
||||
if (toLocal <= n) { beforeE = chunk.editTo; beforeO = chunk.origTo; }
|
||||
else if (fromLocal <= n) { beforeE = chunk.editFrom; beforeO = chunk.origFrom; }
|
||||
}
|
||||
return {edit: {before: beforeE, after: afterE}, orig: {before: beforeO, after: afterO}};
|
||||
}
|
||||
|
||||
function collapseSingle(cm, from, to) {
|
||||
cm.addLineClass(from, "wrap", "CodeMirror-merge-collapsed-line");
|
||||
var widget = document.createElement("span");
|
||||
widget.className = "CodeMirror-merge-collapsed-widget";
|
||||
widget.title = "Identical text collapsed. Click to expand.";
|
||||
var mark = cm.markText(Pos(from, 0), Pos(to - 1), {
|
||||
inclusiveLeft: true,
|
||||
inclusiveRight: true,
|
||||
replacedWith: widget,
|
||||
clearOnEnter: true
|
||||
});
|
||||
function clear() {
|
||||
mark.clear();
|
||||
cm.removeLineClass(from, "wrap", "CodeMirror-merge-collapsed-line");
|
||||
}
|
||||
CodeMirror.on(widget, "click", clear);
|
||||
return {mark: mark, clear: clear};
|
||||
}
|
||||
|
||||
function collapseStretch(size, editors) {
|
||||
var marks = [];
|
||||
function clear() {
|
||||
for (var i = 0; i < marks.length; i++) marks[i].clear();
|
||||
}
|
||||
for (var i = 0; i < editors.length; i++) {
|
||||
var editor = editors[i];
|
||||
var mark = collapseSingle(editor.cm, editor.line, editor.line + size);
|
||||
marks.push(mark);
|
||||
mark.mark.on("clear", clear);
|
||||
}
|
||||
return marks[0].mark;
|
||||
}
|
||||
|
||||
function unclearNearChunks(dv, margin, off, clear) {
|
||||
for (var i = 0; i < dv.chunks.length; i++) {
|
||||
var chunk = dv.chunks[i];
|
||||
for (var l = chunk.editFrom - margin; l < chunk.editTo + margin; l++) {
|
||||
var pos = l + off;
|
||||
if (pos >= 0 && pos < clear.length) clear[pos] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function collapseIdenticalStretches(mv, margin) {
|
||||
if (typeof margin != "number") margin = 2;
|
||||
var clear = [], edit = mv.editor(), off = edit.firstLine();
|
||||
for (var l = off, e = edit.lastLine(); l <= e; l++) clear.push(true);
|
||||
if (mv.left) unclearNearChunks(mv.left, margin, off, clear);
|
||||
if (mv.right) unclearNearChunks(mv.right, margin, off, clear);
|
||||
|
||||
for (var i = 0; i < clear.length; i++) {
|
||||
if (clear[i]) {
|
||||
var line = i + off;
|
||||
for (var size = 1; i < clear.length - 1 && clear[i + 1]; i++, size++) {}
|
||||
if (size > margin) {
|
||||
var editors = [{line: line, cm: edit}];
|
||||
if (mv.left) editors.push({line: getMatchingOrigLine(line, mv.left.chunks), cm: mv.left.orig});
|
||||
if (mv.right) editors.push({line: getMatchingOrigLine(line, mv.right.chunks), cm: mv.right.orig});
|
||||
var mark = collapseStretch(size, editors);
|
||||
if (mv.options.onCollapse) mv.options.onCollapse(mv, line, size, mark);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// General utilities
|
||||
|
||||
function elt(tag, content, className, style) {
|
||||
var e = document.createElement(tag);
|
||||
if (className) e.className = className;
|
||||
if (style) e.style.cssText = style;
|
||||
if (typeof content == "string") e.appendChild(document.createTextNode(content));
|
||||
else if (content) for (var i = 0; i < content.length; ++i) e.appendChild(content[i]);
|
||||
return e;
|
||||
}
|
||||
|
||||
function clear(node) {
|
||||
for (var count = node.childNodes.length; count > 0; --count)
|
||||
node.removeChild(node.firstChild);
|
||||
}
|
||||
|
||||
function attrs(elt) {
|
||||
for (var i = 1; i < arguments.length; i += 2)
|
||||
elt.setAttribute(arguments[i], arguments[i+1]);
|
||||
}
|
||||
|
||||
function copyObj(obj, target) {
|
||||
if (!target) target = {};
|
||||
for (var prop in obj) if (obj.hasOwnProperty(prop)) target[prop] = obj[prop];
|
||||
return target;
|
||||
}
|
||||
|
||||
function moveOver(pos, str, copy, other) {
|
||||
var out = copy ? Pos(pos.line, pos.ch) : pos, at = 0;
|
||||
for (;;) {
|
||||
var nl = str.indexOf("\n", at);
|
||||
if (nl == -1) break;
|
||||
++out.line;
|
||||
if (other) ++other.line;
|
||||
at = nl + 1;
|
||||
}
|
||||
out.ch = (at ? 0 : out.ch) + (str.length - at);
|
||||
if (other) other.ch = (at ? 0 : other.ch) + (str.length - at);
|
||||
return out;
|
||||
}
|
||||
|
||||
function posMin(a, b) { return (a.line - b.line || a.ch - b.ch) < 0 ? a : b; }
|
||||
function posMax(a, b) { return (a.line - b.line || a.ch - b.ch) > 0 ? a : b; }
|
||||
function posEq(a, b) { return a.line == b.line && a.ch == b.ch; }
|
||||
|
||||
function findPrevDiff(chunks, start, isOrig) {
|
||||
for (var i = chunks.length - 1; i >= 0; i--) {
|
||||
var chunk = chunks[i];
|
||||
var to = (isOrig ? chunk.origTo : chunk.editTo) - 1;
|
||||
if (to < start) return to;
|
||||
}
|
||||
}
|
||||
|
||||
function findNextDiff(chunks, start, isOrig) {
|
||||
for (var i = 0; i < chunks.length; i++) {
|
||||
var chunk = chunks[i];
|
||||
var from = (isOrig ? chunk.origFrom : chunk.editFrom);
|
||||
if (from > start) return from;
|
||||
}
|
||||
}
|
||||
|
||||
function goNearbyDiff(cm, dir) {
|
||||
var found = null, views = cm.state.diffViews, line = cm.getCursor().line;
|
||||
if (views) for (var i = 0; i < views.length; i++) {
|
||||
var dv = views[i], isOrig = cm == dv.orig;
|
||||
ensureDiff(dv);
|
||||
var pos = dir < 0 ? findPrevDiff(dv.chunks, line, isOrig) : findNextDiff(dv.chunks, line, isOrig);
|
||||
if (pos != null && (found == null || (dir < 0 ? pos > found : pos < found)))
|
||||
found = pos;
|
||||
}
|
||||
if (found != null)
|
||||
cm.setCursor(found, 0);
|
||||
else
|
||||
return CodeMirror.Pass;
|
||||
}
|
||||
|
||||
CodeMirror.commands.goNextDiff = function(cm) {
|
||||
return goNearbyDiff(cm, 1);
|
||||
};
|
||||
CodeMirror.commands.goPrevDiff = function(cm) {
|
||||
return goNearbyDiff(cm, -1);
|
||||
};
|
||||
});
|
|
@ -9,7 +9,11 @@
|
|||
<div class="post-main">
|
||||
<div class="post-avatar fl"><img ng-src="{{replaceUrl(act.author.img_url)}}" width="45" height="45" class="border-radius" /></div>
|
||||
<div class="post-title hidden mb5"><span class="c-grey3 f15 fb">{{act.subject|safeHtml}}</span></div>
|
||||
<div class="post-title hidden"><a herf="javascript:void(0);" class="mr10">{{act.author.realname}}</a>to<a herf="javascript:void(0);" class="ml10">{{act.course_project_name}} | {{act.activity_type_name}}</a></div>
|
||||
<div class="post-title hidden">
|
||||
<a herf="javascript:void(0);" class="mr10">
|
||||
<span ng-if="act.author.realname != ' '">{{act.author.realname}}</span>
|
||||
<span ng-if="act.author.realname == ' '">{{act.author.nickname}}</span>
|
||||
</a>to<a herf="javascript:void(0);" class="ml10">{{act.course_project_name}} | {{act.activity_type_name}}</a></div>
|
||||
<div class="cl"></div>
|
||||
<div class="post-content c-grey2 mt10">
|
||||
<div class="post-all-content" ng-bind-html="act.description|safeHtml"></div>
|
||||
|
|
|
@ -3,12 +3,11 @@
|
|||
<div class="post-container">
|
||||
<div class="post-wrapper">
|
||||
<div class="post-main">
|
||||
<div class="post-avatar fl"><img ng-src="{{blog.user.img_url}}" width="45" height="45" class="border-radius" /></div>
|
||||
<div class="post-title hidden mb5"><span class="c-grey3 f15 fb">{{blog.title}}</span></div>
|
||||
<div class="post-title hidden"><a herf="javascript:void(0);" class="mr10">{{blog.user.realname}}</a>发表博客</div>
|
||||
<div class="post-title mb5"><span class="c-grey3 f15 fb">{{blog.title}}</span></div>
|
||||
<div class="post-title"><a herf="javascript:void(0);" class="mr10">{{blog.user.realname}}</a>发表博客</div>
|
||||
<div class="cl"></div>
|
||||
<div class="post-content" style="height:auto;">
|
||||
<div class="post-all-content c-grey2 mt10" ng-bind-html="blog.content|safeHtml"></div>
|
||||
<div class="post-all-content c-grey3 mt10" ng-bind-html="blog.content|safeHtml"></div>
|
||||
</div>
|
||||
<div class="cl"></div>
|
||||
<span class="c-grey f13 mt10 fl">{{blog.created_at}}</span>
|
||||
|
@ -36,7 +35,9 @@
|
|||
<div class="post-input-wrap">
|
||||
<div class="post-reply-row">
|
||||
<!--<div class="post-reply-avatar fl"><img src="images/post-avatar.jpg" width="30" height="30" /></div>-->
|
||||
<div class="post-input-container">
|
||||
<input type="text" class="post-reply-input" id="postInput" ng-model="formData.comment" />
|
||||
</div>
|
||||
<button ng-click="addBlogReply(formData)" class="post-reply-submit fr mt10">回复</button>
|
||||
<div class="cl"></div>
|
||||
</div>
|
||||
|
|
|
@ -3,11 +3,16 @@
|
|||
<div class="post-container">
|
||||
<div class="post-wrapper">
|
||||
<div class="post-main">
|
||||
<div class="post-avatar fl"><img ng-src="{{discussion.user.img_url}}" width="45" height="45" class="border-radius" /></div>
|
||||
<div class="post-title hidden mb5"><span class="c-grey3 f15 fb">{{discussion.subject}}</span></div>
|
||||
<div class="post-title hidden"><a herf="javascript:void(0);" class="mr10">{{discussion.user.realname}}</a>to<a herf="javascript:void(0);" class="ml10">{{discussion.course_project_name}} | 课程问答区</a></div>
|
||||
<div class="cl"></div>
|
||||
<div class="post-content c-grey2 mt10" style="height:auto;">
|
||||
<div class="post-title mb5"><span class="c-grey3 f15 fb">{{discussion.subject}}</span></div>
|
||||
<table class="post-detail-info"><tr>
|
||||
<td class="text-nowrap v-top">发布者:</td>
|
||||
<td>{{discussion.user.realname}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-nowrap v-top">来 源:</td>
|
||||
<td>{{discussion.course_project_name}} | 课程问答区</td>
|
||||
</tr></table>
|
||||
<div class="post-content c-grey3 mt10" style="height:auto;">
|
||||
<div class="post-all-content" ng-bind-html="discussion.content|safeHtml"></div>
|
||||
</div>
|
||||
<div class="cl"></div>
|
||||
|
@ -36,7 +41,9 @@
|
|||
<div class="post-input-wrap">
|
||||
<div class="post-reply-row">
|
||||
<!--<div class="post-reply-avatar fl"><img src="images/post-avatar.jpg" width="30" height="30" /></div>-->
|
||||
<div class="post-input-container">
|
||||
<input type="text" class="post-reply-input" id="postInput" ng-model="formData.comment" />
|
||||
</div>
|
||||
<button ng-click="addDiscussionReply(formData)" class="post-reply-submit fr mt10">回复</button>
|
||||
<div class="cl"></div>
|
||||
</div>
|
||||
|
|
|
@ -3,11 +3,16 @@
|
|||
<div class="post-container">
|
||||
<div class="post-wrapper">
|
||||
<div class="post-main">
|
||||
<div class="post-avatar fl"><img ng-src="{{news.author.img_url}}" width="45" height="45" class="border-radius" /></div>
|
||||
<div class="post-title hidden mb5"><span class="c-grey3 f15 fb">{{news.title}}</span></div>
|
||||
<div class="post-title hidden"><a herf="javascript:void(0);" class="mr10">{{news.author.realname}}</a>to<a herf="javascript:void(0);" class="ml10">{{news.course_name}} | 课程通知</a></div>
|
||||
<div class="cl"></div>
|
||||
<div class="post-content c-grey2 mt10" style="height:auto;">
|
||||
<div class="post-title mb5"><span class="c-grey3 f15 fb">{{news.title}}</span></div>
|
||||
<table class="post-detail-info"><tr>
|
||||
<td class="text-nowrap v-top">发布者:</td>
|
||||
<td>{{news.author.realname}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-nowrap v-top">来 源:</td>
|
||||
<td>{{news.course_name}} | 课程通知</td>
|
||||
</tr></table>
|
||||
<div class="post-content c-grey3 mt10" style="height:auto;">
|
||||
<div class="post-all-content" ng-bind-html="news.description|safeHtml"></div>
|
||||
</div>
|
||||
<div class="cl"></div>
|
||||
|
@ -36,7 +41,9 @@
|
|||
<div class="post-input-wrap">
|
||||
<div class="post-reply-row">
|
||||
<!--<div class="post-reply-avatar fl"><img src="images/post-avatar.jpg" width="30" height="30" /></div>-->
|
||||
<div class="post-input-container">
|
||||
<input type="text" class="post-reply-input" id="postInput" ng-model="formData.comment" />
|
||||
</div>
|
||||
<button ng-click="addNoticeReply(formData)" class="post-reply-submit fr mt10">回复</button>
|
||||
<div class="cl"></div>
|
||||
</div>
|
||||
|
|
|
@ -3,14 +3,23 @@
|
|||
<div class="post-container">
|
||||
<div class="post-wrapper">
|
||||
<div class="post-main">
|
||||
<div class="post-avatar fl"><img ng-src="{{homework.author.img_url}}" width="45" height="45" class="border-radius" /></div>
|
||||
<div class="post-title hidden mb5"><span class="c-grey3 f15 fb">{{homework.name}}</span></div>
|
||||
<div class="post-title hidden"><a herf="javascript:void(0);" class="mr10">{{homework.author.realname}}</a>to<a herf="javascript:void(0);" class="ml10">{{homework.course_name}} | 课程作业</a></div>
|
||||
<div class="cl"></div>
|
||||
<div class="post-content c-grey2 mt10" style="height:auto;">
|
||||
<div class="post-all-content" ng-bind-html="homework.description|safeHtml"></div>
|
||||
<span class="mr15">迟交扣分:{{homework.late_penalty}}分</span> 匿评开启时间:{{homework.evaluation_start}}<br />
|
||||
<span class="mr15">缺评扣分:{{homework.absence_penalty}}分/作品</span> 匿评关闭时间:{{homework.evaluation_end}}
|
||||
<div class="post-title mb5"><span class="c-grey3 f15 fb">{{homework.name}}</span></div>
|
||||
<table class="post-detail-info"><tr>
|
||||
<td class="text-nowrap v-top">发布者:</td>
|
||||
<td>
|
||||
<span ng-if="homework.author.realname != ' '">{{homework.author.realname}}</span>
|
||||
<span ng-if="homework.author.realname == ' '">{{homework.author.nickname}}</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-nowrap v-top">来 源:</td>
|
||||
<td>{{homework.course_name}} | 课程作业</td>
|
||||
</tr></table>
|
||||
<div class="post-content c-grey3 mt10" style="height:auto;">
|
||||
<div class="post-all-content mb10" ng-bind-html="homework.description|safeHtml"></div>
|
||||
<span class="c-grey">迟交扣分:{{homework.late_penalty}}分<br/>
|
||||
缺评扣分:{{homework.absence_penalty}}分/作品<br />
|
||||
匿评开启时间:{{homework.evaluation_start}}<br />
|
||||
匿评关闭时间:{{homework.evaluation_end}}</span>
|
||||
</div>
|
||||
<div class="cl"></div>
|
||||
<span class="c-grey f13 mt10 fl">{{homework.publish_time}}</span>
|
||||
|
@ -38,7 +47,9 @@
|
|||
<div class="post-input-wrap">
|
||||
<div class="post-reply-row">
|
||||
<!--<div class="post-reply-avatar fl"><img src="images/post-avatar.jpg" width="30" height="30" /></div>-->
|
||||
<div class="post-input-container">
|
||||
<input type="text" class="post-reply-input" id="postInput" ng-model="formData.comment" />
|
||||
</div>
|
||||
<button ng-click="addHomeworkReply(formData)" value="回复" class="post-reply-submit fr mt10">回复</button>
|
||||
<div class="cl"></div>
|
||||
</div>
|
||||
|
|
|
@ -3,14 +3,21 @@
|
|||
<div class="post-container">
|
||||
<div class="post-wrapper">
|
||||
<div class="post-main">
|
||||
<div class="post-avatar fl"><img ng-src="{{issue.author.img_url}}" width="45" height="45" class="border-radius" /></div>
|
||||
<div class="post-title hidden mb5"><span class="c-grey3 f15 fb">{{issue.subject}}</span></div>
|
||||
<div class="post-title hidden"><a herf="javascript:void(0);" class="mr10">{{issue.author.realname}}</a>to<span class="ml10">{{issue.project_name}} | 项目缺陷</span></div>
|
||||
<div class="cl"></div>
|
||||
<div class="post-title mb5"><span class="c-grey3 f15 fb">{{issue.subject}}</span></div>
|
||||
<table class="post-detail-info"><tr>
|
||||
<td class="text-nowrap v-top">发布者:</td>
|
||||
<td>{{issue.author.realname}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-nowrap v-top">来 源:</td>
|
||||
<td>{{issue.project_name}} | 项目缺陷</td>
|
||||
</tr></table>
|
||||
<div class="post-content" style="height:auto;">
|
||||
<div class="post-all-content c-grey2 mt10" ng-bind-html="issue.description|safeHtml"></div>
|
||||
<span class="mr15">状态:{{issue.issue_status}}</span> <span class="mr15">优先级:{{issue.issue_priority}}</span> <br />
|
||||
<span class="mr15">指派给:{{issue.issue_assigned_to}}</span> <span class="mr15">完成度:{{issue.done_ratio}}%</span>
|
||||
<div class="post-all-content c-grey3 mt10 mb10" ng-bind-html="issue.description|safeHtml"></div>
|
||||
<span class="c-grey">状 态:{{issue.issue_status}}<br>
|
||||
优先级:{{issue.issue_priority}}<br />
|
||||
指派给:{{issue.issue_assigned_to}}<br />
|
||||
完成度:{{issue.done_ratio}}%</span>
|
||||
</div>
|
||||
<div class="cl"></div>
|
||||
<span class="c-grey f13 mt10 fl">{{issue.created_on}}</span>
|
||||
|
@ -38,7 +45,9 @@
|
|||
<div class="post-input-wrap">
|
||||
<div class="post-reply-row">
|
||||
<!--<div class="post-reply-avatar fl"><img src="images/post-avatar.jpg" width="30" height="30" /></div>-->
|
||||
<div class="post-input-container">
|
||||
<input type="text" class="post-reply-input" id="postInput" ng-model="formData.comment" />
|
||||
</div>
|
||||
<button ng-click="addIssueReply(formData)" class="post-reply-submit fr mt10">回复</button>
|
||||
<div class="cl"></div>
|
||||
</div>
|
||||
|
|
|
@ -2,9 +2,8 @@
|
|||
<div class="post-container">
|
||||
<div class="post-wrapper">
|
||||
<div class="post-main">
|
||||
<div class="post-avatar fl"><img ng-src="{{message.user.img_url}}" width="45" height="45" class="border-radius" /></div>
|
||||
<div class="post-title mb5 hidden"><a herf="javascript:void(0);" class="mr10">{{message.user.realname}}</a><span style="vertical-align:top;">给您留言了</span><br /></div>
|
||||
<div class="post-title hidden">{{message.created_on}}</div>
|
||||
<div class="post-title mb5"><a herf="javascript:void(0);" class="mr10">{{message.user.realname}}</a><span style="vertical-align:top;">给您留言了</span><br /></div>
|
||||
<div class="post-title">{{message.created_on}}</div>
|
||||
<div class="cl"></div>
|
||||
<div class="post-content c-grey2 mt10" style="height:auto;">
|
||||
<div class="post-all-content" ng-bind-html="message.notes|safeHtml"></div>
|
||||
|
@ -34,7 +33,9 @@
|
|||
<div class="post-input-wrap">
|
||||
<div class="post-reply-row">
|
||||
<!--<div class="post-reply-avatar fl"><img src="images/post-avatar.jpg" width="30" height="30" /></div>-->
|
||||
<div class="post-input-container">
|
||||
<input type="text" class="post-reply-input" id="postInput" ng-model="formData.comment" />
|
||||
</div>
|
||||
<button ng-click="addJournalReply(formData)" class="post-reply-submit fr mt10">回复</button>
|
||||
<div class="cl"></div>
|
||||
</div>
|
||||
|
|
|
@ -3,11 +3,16 @@
|
|||
<div class="post-container">
|
||||
<div class="post-wrapper">
|
||||
<div class="post-main">
|
||||
<div class="post-avatar fl"><img ng-src="{{discussion.user.img_url}}" width="45" height="45" class="border-radius" /></div>
|
||||
<div class="post-title hidden mb5"><span class="c-grey3 f15 fb">{{discussion.subject}}</span></div>
|
||||
<div class="post-title hidden"><a herf="javascript:void(0);" class="mr10">{{discussion.user.realname}}</a>to<a herf="javascript:void(0);" class="ml10">{{discussion.course_project_name}} | 项目讨论区</a></div>
|
||||
<div class="cl"></div>
|
||||
<div class="post-content c-grey2 mt10" style="height:auto;">
|
||||
<div class="post-title mb5"><span class="c-grey3 f15 fb">{{discussion.subject}}</span></div>
|
||||
<table class="post-detail-info"><tr>
|
||||
<td class="text-nowrap v-top">发布者:</td>
|
||||
<td>{{discussion.user.realname}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-nowrap v-top">来 源:</td>
|
||||
<td>{{discussion.course_project_name}} | 项目讨论区</td>
|
||||
</tr></table>
|
||||
<div class="post-content c-grey3 mt10" style="height:auto;">
|
||||
<div class="post-all-content" ng-bind-html="discussion.content|safeHtml"></div>
|
||||
</div>
|
||||
<div class="cl"></div>
|
||||
|
@ -36,7 +41,9 @@
|
|||
<div class="post-input-wrap">
|
||||
<div class="post-reply-row">
|
||||
<!--<div class="post-reply-avatar fl"><img src="images/post-avatar.jpg" width="30" height="30" /></div>-->
|
||||
<div class="post-input-container">
|
||||
<input type="text" class="post-reply-input" id="postInput" ng-model="formData.comment" />
|
||||
</div>
|
||||
<button ng-click="addDiscussionReply(formData)" class="post-reply-submit fr mt10">回复</button>
|
||||
<div class="cl"></div>
|
||||
</div>
|
||||
|
|
|
@ -1432,4 +1432,3 @@ function submit_course_feedback() {
|
|||
function show_more_tool(){
|
||||
$('#navContentCourse').css('display', 'block');
|
||||
}
|
||||
|
||||
|
|
|
@ -98,11 +98,10 @@ $(function(){
|
|||
if(status == 'timeout'){
|
||||
alert("您的答案超时了, 请检查代码是否存在死循环的错误.");
|
||||
} else {
|
||||
alert("测试失败,服务器出错.");
|
||||
alert("对不起,服务器繁忙请稍后再试!");
|
||||
}
|
||||
return;
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
test_post(1, 0);
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
var app = angular.module('wechat', ['ngRoute','ngCookies']);
|
||||
var apiUrl = 'http://wechat.trustie.net/api/v1/';
|
||||
var apiUrl = '/api/v1/';
|
||||
var debug = false; //调试标志,如果在本地请置为true
|
||||
|
||||
if(debug===true){
|
||||
apiUrl = 'http://localhost:3000/api/v1/';
|
||||
apiUrl = 'https://www.trustie.net/api/v1/';
|
||||
}
|
||||
|
||||
app.factory('auth', function($http,$routeParams, $cookies, $q){
|
||||
var _openid = '';
|
||||
|
||||
if(debug===true){
|
||||
_openid = "3";
|
||||
_openid = "1";
|
||||
}
|
||||
|
||||
var getOpenId = function() {
|
||||
|
@ -63,7 +63,7 @@ app.factory('rms', function(){
|
|||
|
||||
app.controller('ActivityController',function($scope, $http, auth, rms, common){
|
||||
$scope.replaceUrl = function(url){
|
||||
return "http://www.trustie.net/" + url;
|
||||
return url;
|
||||
};
|
||||
|
||||
console.log("ActivityController load");
|
||||
|
|
|
@ -2848,3 +2848,26 @@ img.school_avatar {
|
|||
|
||||
.admin_message_warn{font-size: 12px;color: red;}
|
||||
a.btn_message_free{ background:#15BCCF; display:block; text-align:center; color:#fff; padding:3px 0; width:60px; margin-bottom:10px;margin-left: 58px;}
|
||||
|
||||
/*20160401袁可------------------ 查重结果样式*/
|
||||
.conbox{ width:1000px; margin:0 auto; border:1px solid #f0f0f0; background:#fff;}
|
||||
.conbox-h2{ font-size:16px; padding:10px 0; padding-left:25px;}
|
||||
.chabox{ width:1000px;}
|
||||
.chabox ul li{ float:left; width:87px; text-align:center; display:block;white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
|
||||
.chabox ul li.chabox-w-151{ width:151px; display:block;white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
|
||||
.chabox ul li.chabox-r-line{ border-right:1px solid #D1D1D1;}
|
||||
.chabox-top{ width:1000px; }
|
||||
.chabox-top li{ font-size:14px; font-weight:bold; line-height:40px; height:40px; background:#E4E4E4; color:#000;}
|
||||
.chabox-con li{font-size:12px; line-height:35px; height:35px; color:#000; border-bottom:1px solid #DFDFDF;}
|
||||
a.cha-btn{ display:block; width:50px; height:20px; line-height:20px; margin:0 auto; border:1px solid #269ac9; color:#269ac9;-webkit-border-radius: 3px;border-radius:3px; margin-top:8px;}
|
||||
a:hover.cha-btn{ background:#269ac9; color:#fff;}
|
||||
.chabox-header li{ font-size:14px; font-weight:bold; line-height:40px; height:40px; border-top:1px solid #E4E4E4; border-right:1px solid #E4E4E4; color:#000;}
|
||||
.chabox ul li.chabox-w-500{ width:499px;}
|
||||
|
||||
.contrast-box{ width:1200px;box-shadow: 0 0 5px #6B6B6B; background:#fff; margin:0 auto; }
|
||||
.contrast-con{ width:599px; border-right:1px solid #D1D1D1; float:left;}
|
||||
.contrast-con h3{font-size:14px; font-weight:bold; line-height:40px; height:40px; background:#E4E4E4; color:#000; text-align:center; display:block;white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
|
||||
.contrast-txt{ padding:10px;}
|
||||
.showCodeC{ width:580px; float:left;}
|
||||
|
||||
.resourceClose {background:url(images/resource_icon_list.png) 0px -40px no-repeat; width:20px; height:20px; display:inline-block; position: absolute; z-index: 1000;}
|
|
@ -1293,3 +1293,14 @@ a.contributor_course{float: right; color: #888; font-size: 12px; font-weight: no
|
|||
|
||||
/*20160310分班样式*/
|
||||
.select-class-option {width:125px;}
|
||||
|
||||
/* 弹框 */
|
||||
a.Blue-btn{ display:block; margin-right:15px;width:65px; height:22px; background-color:#ffffff; line-height:24px; vertical-align:middle; text-align:center; border:1px solid #3598db; color:#3598db; -moz-border-radius:5px; -webkit-border-radius:5px; border-radius:5px;}
|
||||
a:hover.Blue-btn{ background:#3598db; color:#fff;}
|
||||
.fl{ float:left;}
|
||||
.fr{ float:right;}
|
||||
.blue-border-box{ width:500px; padding:20px; margin:0 auto; background:#fff;}
|
||||
.box-con h4{ font-size:14px; font-weight: bold; width:450px; text-align:center;}
|
||||
.box-con{ width:450px; margin:0 auto; text-align:center;}
|
||||
.box-con-a{ width:170px; margin:0 auto; margin-top:10px;}
|
||||
/*--------------------------------------*/
|
||||
|
|
|
@ -226,7 +226,7 @@ a.c_green{ color:#28be6c;}
|
|||
.c_dblue{ color:#09658c;}
|
||||
.b_blue{background:#64bdd9;}
|
||||
.b_green{background:#28be6c;}
|
||||
.b_w{ background:#fff;}
|
||||
.b_w{ background:#fff !important;}
|
||||
|
||||
/*add by Tim*/
|
||||
.fontGrey {color:#cecece;}
|
||||
|
|
|
@ -33,6 +33,8 @@ a.underline {text-decoration:underline;}
|
|||
.hidden {overflow:hidden; white-space:nowrap; text-overflow:ellipsis;}
|
||||
.inline-block {display:inline-block;}
|
||||
.undis {display:none;}
|
||||
.text-nowrap {white-space:nowrap;}
|
||||
.v-top {vertical-align:top;}
|
||||
|
||||
/*动态样式*/
|
||||
.post-container {width:100%;}
|
||||
|
@ -40,6 +42,7 @@ a.underline {text-decoration:underline;}
|
|||
.post-main {padding:10px; color:#9a9a9a;}
|
||||
.post-avatar {width:45px; height:45px; margin-right:10px;}
|
||||
.post-title {font-size:13px; text-align:left;}
|
||||
.post-detail-info {font-size:13px; text-align:left; color:#9a9a9a;}
|
||||
.fl {float:left;}
|
||||
.fr {float:right;}
|
||||
.cl {clear:both; overflow:hidden;}
|
||||
|
@ -59,5 +62,6 @@ a.underline {text-decoration:underline;}
|
|||
.post-reply-content {font-size:13px; text-align:left; word-break:break-all; word-wrap:break-word; overflow:hidden;}
|
||||
.post-reply-date {font-size:13px;}
|
||||
.post-reply-trigger {font-size:13px;}
|
||||
.post-reply-input {width:100%; height:28px; line-height:28px; border:1px solid #e6e6e6; outline:none; border-radius:3px;}
|
||||
.post-input-container {padding-right:2px;}
|
||||
.post-reply-input {width:100%; height:28px; line-height:28px; border:1px solid #e6e6e6; outline:none; padding:0; margin:0; border-radius:3px;}
|
||||
.post-reply-submit {font-size:13px; padding:3px 8px; color:#fff; background-color:#269ac9; outline:none; border:none; display:inline-block;}
|
Loading…
Reference in New Issue