Merge branch 'develop' into cxt_course

cxt_course
cxt 9 years ago
commit 239f4e67eb

@ -1 +1 @@
{"access_token":"oEEf8ZKAB8Y2G0o_xnTPkPJHKKk8iHkLC-f5ptvQ2nCMj9IpC86ivLD2-p38GfOkuG-HuQp3pWZqhs3NJXUMdPLWsr5k67hPZYuqg4ozLccx0xdLswapj0mn8ovZhK1tKIKiAFAOMO","expires_in":7200,"got_token_at":1467012449}
{"access_token":"b_Pc60Dd5eyg_ut3cHbsjQO9EJJdj2Qj5F99o9LH9ltKSme7_FZ3Of22lWLL-K2V0siWzv-bd9PO0Dn-L1PBvIy9LhXa0qPVaFl6vTtZHR2kA8qjo1ps2ancya0t7KmzURGbAFAAXM","expires_in":7200,"got_token_at":1467976842}

5
.gitignore vendored

@ -6,8 +6,7 @@
/config/database.yml
/config/configuration.yml
/config/additional_environment.rb
/config/menu.yml
/config/wechat.yml
/files/*
/log/*
@ -35,3 +34,5 @@ vendor/cache
1234567
public/javascripts/wechat/node_modules/
.ruby-version
.access_token
tmux*.log

@ -5,8 +5,8 @@ unless RUBY_PLATFORM =~ /w32/
gem 'iconv'
if RUBY_PLATFORM =~ /darwin/
gem "rmagick", "= 2.15.4" ## osx must be this version
else
gem "rmagick", "= 2.13.1" ## centos yum install ImageMagick-devel
elsif RUBY_PLATFORM =~ /linux/
#gem "rmagick", "= 2.13.1" ## centos yum install ImageMagick-devel
end
gem 'certified'
gem 'net-ssh', '2.9.1'
@ -57,7 +57,7 @@ group :development do
gem 'grape-swagger'
gem 'better_errors', '~> 1.1.0'
# gem "query_reviewer"
# gem 'rack-mini-profiler', '~> 0.9.3'
gem 'rack-mini-profiler', '~> 0.9.3'
if RUBY_PLATFORM =~ /w32/
gem 'win32console'
end

@ -0,0 +1,114 @@
source 'https://ruby.taobao.org/'
unless RUBY_PLATFORM =~ /w32/
# unix-like only
gem 'iconv'
gem "rmagick", ">= 2.0.0"
gem 'certified'
end
gem 'net-ssh', '2.9.1'
gem 'jenkins_api_client'
gem 'nokogiri'
gem 'wechat',path: 'lib/wechat'
gem 'grack', path:'lib/grack'
gem 'gitlab', path: 'lib/gitlab-cli'
gem 'rest-client'
gem "mysql2", "= 0.3.18"
gem 'redis-rails'
gem 'rubyzip'
gem 'delayed_job_active_record'#, :group => :production
gem 'daemons'
gem 'grape', '~> 0.9.0'
gem 'grape-entity'
gem 'rack-cors', :require => 'rack/cors'
gem 'seems_rateable', '~> 1.0.13'
gem 'rails', '~> 3.2'
gem "jquery-rails", "~> 2.0.2"
gem "i18n", "~> 0.6.0"
gem 'coderay', '~> 1.1.0'
gem "fastercsv", "~> 1.5.0", :platforms => [:mri_18, :mingw_18, :jruby]
gem "builder", "3.0.0"
gem 'acts-as-taggable-on', '2.4.1'
gem 'spreadsheet'
gem 'ruby-ole'
gem 'rails_kindeditor',path:'lib/rails_kindeditor'
gem 'binding_of_caller'
gem 'chinese_pinyin'
# gem 'sunspot_rails', '~> 1.3.3'
# gem 'sunspot_solr'
# gem 'sunspot'
# gem 'progress_bar'
gem 'ansi'
gem 'kaminari'
gem 'elasticsearch-model'
gem 'elasticsearch-rails'
### profile
#gem 'oneapm_rpm'
group :development do
gem 'grape-swagger'
gem 'better_errors', '~> 1.1.0'
# gem "query_reviewer"
# gem 'rack-mini-profiler', '~> 0.9.3'
if RUBY_PLATFORM =~ /w32/
gem 'win32console'
end
end
group :development, :test do
unless RUBY_PLATFORM =~ /w32/
gem 'pry-rails'
if RUBY_VERSION >= '2.0.0'
gem 'pry-byebug'
end
gem 'pry-stack_explorer'
if RUBY_PLATFORM =~ /darwin/
gem 'puma'
end
end
gem 'rspec-rails', '~> 3.0'
gem 'factory_girl_rails'
end
# Gems used only for assets and not required
# in production environments by default.
group :assets do
gem 'sass-rails', '~> 3.2.3'
gem 'coffee-rails', '~> 3.2.1'
# See https://github.com/sstephenson/execjs#readme for more supported runtimes
# gem 'therubyracer', :platforms => :ruby
gem 'uglifier', '>= 1.0.3'
end
# Optional gem for LDAP authentication
group :ldap do
gem "net-ldap", "~> 0.3.1"
end
# Optional gem for OpenID authentication
group :openid do
gem "ruby-openid", "~> 2.1.4", :require => "openid"
gem "rack-openid"
end
database_file = File.join(File.dirname(__FILE__), "config/database.yml")
if File.exist?(database_file)
else
warn("Please configure your config/database.yml first")
end
# Load plugins' Gemfiles
Dir.glob File.expand_path("../plugins/*/Gemfile", __FILE__) do |file|
puts "Loading #{file} ..." if $DEBUG # `ruby -d` or `bundle -v`
instance_eval File.read(file)
end

@ -19,6 +19,7 @@ module Mobile
require_relative 'apis/new_comment'
require_relative 'apis/praise'
require_relative 'apis/resources'
require_relative 'apis/syllabuses'
class API < Grape::API
version 'v1', using: :path
@ -73,6 +74,7 @@ module Mobile
mount Apis::NewComment
mount Apis::Praise
mount Apis::Resources
mount Apis::Syllabuses
add_swagger_documentation ({api_version: 'v1', base_path: '/api'}) if Rails.env.development?

@ -10,30 +10,44 @@ module Mobile
params do
requires :page, type: Integer
requires :token, type: String
requires :container_type, type: String
end
post do
authenticate!
user = current_user
container_type = params[:container_type] ? params[:container_type] : "All"
if container_type == "All" || container_type == "Project"
shield_project_ids = ShieldActivity.select("shield_id").where("container_type='User' and container_id=#{user.id} and shield_type='Project'").map(&:shield_id)
shield_course_ids = ShieldActivity.select("shield_id").where("container_type='User' and container_id=#{user.id} and shield_type='Course'").map(&:shield_id)
page = params[:page] ? params[:page] : 0
user_project_ids = (user.projects.where("status = 1").map{|project| project.id}-shield_project_ids).empty? ? "(-1)" : "(" + (user.projects.where("status = 1").map{|project| project.id}-shield_project_ids).join(",") + ")"
project_types = "('Message','Issue','Project')"
end
if container_type == "All" || container_type == "Course"
shield_course_ids = ShieldActivity.select("shield_id").where("container_type='User' and container_id=#{user.id} and shield_type='Course'").map(&:shield_id)
user_course_ids = (user.courses.where("is_delete = 0").map{|course| course.id}-shield_course_ids).empty? ? "(-1)" : "(" + (user.courses.where("is_delete = 0").map{|course| course.id}-shield_course_ids).join(",") + ")"
course_types = "('Message','News','HomeworkCommon','Poll','Course')"
project_types = "('Message','Issue','Project')"
end
page = params[:page] ? params[:page] : 0
principal_types = "JournalsForMessage"
watched_user_ids = User.watched_by(user.id).count == 0 ? " " : ("," + User.watched_by(user.id).map{|u| u.id.to_s }.join(','))
user_ids = "(" + user.id.to_s + watched_user_ids + ")"
watched_user_blog_ids = Blog.select("id").where("author_id in #{user_ids}").count == 0 ? " " :Blog.select("id").where("author_id in #{user_ids}").map { |blog| blog.id}.join(",")
blog_ids = "(" + watched_user_blog_ids + ")"
if container_type == "Course"
activities = UserActivity.where("(container_type = 'Course' and container_id in #{user_course_ids} and act_type in #{course_types})").order('updated_at desc')
elsif container_type == "Project"
activities = UserActivity.where("(container_type = 'Project' and container_id in #{user_project_ids} and act_type in #{project_types})").order('updated_at desc')
else
activities = UserActivity.where("(container_type = 'Project' and container_id in #{user_project_ids} and act_type in #{project_types})" +
"or (container_type = 'Course' and container_id in #{user_course_ids} and act_type in #{course_types}) "+
"or (container_type = 'Principal' and act_type= '#{principal_types}' and container_id = #{user.id}) " +
"or (container_type = 'Blog' and act_type= 'BlogComment' and container_id in #{blog_ids})").order('updated_at desc')
end
all_count = activities.count
activities = activities.limit(10).offset(page * 10)
count = activities.count
@ -42,6 +56,7 @@ module Mobile
present :count, count
present :page, page
present :status, 0
present :container_type, container_type
end
end
end

@ -7,7 +7,7 @@ module Mobile
desc "get special topic"
get ':id' do
user = UserWechat.find_by_openid(params[:openid]).user
user = current_user
blog = BlogComment.find params[:id]
present :data, blog, with: Mobile::Entities::BlogComment,user: user
present :status, 0

@ -107,7 +107,7 @@ module Mobile
status = cs.join_course({role: "10", openid: params[:openid], invite_code: params[:invite_code]}, current_user)
{
status: status[:state],
messsge:CoursesService::JoinCourseError.message(status[:state])
message:CoursesService::JoinCourseError.message(status[:state])
}
end
@ -396,6 +396,23 @@ module Mobile
present :status,0
end
desc '删除课程'
params do
requires :token, type: String
end
post ':course_id/del' do
authenticate!
c = Course.find(params[:course_id])
# if c.members.count > 1
# {status: -1, message: '已经有成员加入,不能删除'}
# else
c.delete!
present :status,0
# end
end
end
end
end

@ -46,9 +46,25 @@ module Mobile
end
desc '发送资源'
params do
requires :token, type: String
requires :course_ids, type: Array[Integer]
requires :send_id, type: Integer
end
post 'send' do
authenticate!
rs = ResourcesService.new
ori, flag, save_message = rs.send_resource_to_course(current_user,params)
if flag
present :status, 0
else
{status: -1, message: save_message.first}
end
end
end
end
end

@ -0,0 +1,103 @@
#coding=utf-8
module Mobile
module Apis
class Syllabuses < Grape::API
resources :syllabuses do
desc "获取大纲列表"
params do
requires :token, type: String
end
get do
authenticate!
cs = SyllabusesService.new
courses = cs.user_syllabus(current_user)
present :data, courses, with: Mobile::Entities::Syllabus
present :status, 0
end
desc "获取某个大纲"
params do
requires :token, type: String
end
get ':id' do
authenticate!
ss = SyllabusesService.new
sy = ::Syllabus.find(params[:id])
sy.courses = sy.courses.not_deleted
sy = ss.judge_can_setting(sy,current_user)
present :data, sy, with: Mobile::Entities::Syllabus
present :status, 0
end
desc "获取新建大纲的权限"
params do
requires :token, type: String
end
post 'auth' do
authenticate!
auth = 0
if (current_user.user_extensions && current_user.user_extensions.identity == 0 && current_user.allowed_to?(:add_course, nil, :global => true))
auth = 1
end
present :auth, auth
end
desc "新建大纲"
params do
requires :token, type: String
requires :title, type: String, desc: '大纲标题'
requires :courses, type: Array[String], desc: '课程名'
end
post do
authenticate!
ss = SyllabusesService.new
sy = ss.create(current_user, params[:title],
params[:courses].map{|c| {name: c} })
if sy.new_record?
{status:-1, message: '创建大纲失败' }
else
present :data, sy, with: Mobile::Entities::Syllabus
present :status, 0
end
end
desc '编辑大纲'
params do
requires :token, type: String
requires :title, type: String, desc: '大纲标题'
# requires :add_courses, type: Array[String], desc: '课程名'
# requires :modify_courses, type: Array[Integer,String], desc: '课程名'
end
post ':id/edit' do
authenticate!
ss = SyllabusesService.new
#修改课程大纲
status = ss.edit(current_user, params)
if status == -1
{status:status, message: '修改课程信息失败' }
else
present :status, status
end
end
end
end
end
end

@ -53,10 +53,20 @@ module Mobile
requires :password, type: String, desc: 'password'
end
post do
openid = session[:wechat_openid]
logger.debug "openid ============== #{openid}"
raise "无法获取到openid,请在微信中打开本页面" unless openid
us = UsersService.new
user = us.register params.merge(:password_confirmation => params[:password],
:should_confirmation_password => true)
raise "该邮箱已经被注册过了" if user.new_record?
raise user.errors.full_messages.first if user.new_record?
UserWechat.create!(
openid: openid,
user: user
)
present :data, user, with: Mobile::Entities::User
present :status, 0

@ -15,6 +15,8 @@ module Mobile
#f.img_url if f.respond_to?(:img_url)
elsif field == :created_at || field == :updated_at
(format_time(c[field]) if (c.is_a?(Hash) && c.key?(field))) || (format_time(c.send(field)) if c.respond_to?(field))
elsif field == :member_count
::Course===c ? c.members.count : 0
else
(c[field] if (c.is_a?(Hash) && c.key?(field))) || (c.send(field) if c.respond_to?(field))
end
@ -49,6 +51,8 @@ module Mobile
course_expose :qrcode
course_expose :updated_at
course_expose :course_student_num
course_expose :member_count
course_expose :can_setting
expose :teacher, using: Mobile::Entities::User do |c, opt|
if c.is_a? ::Course
c.teacher

@ -0,0 +1,13 @@
module Mobile
module Entities
class Syllabus < Grape::Entity
include ApplicationHelper
expose :title
expose :id
expose :can_setting
expose :courses, using: Mobile::Entities::Course
end
end
end

@ -116,6 +116,9 @@ class BlogCommentsController < ApplicationController
#回复
def reply
if params[:homepage]
@in_user_homepage = true
end
if params[:in_user_center]
@in_user_center = true
end

@ -1090,7 +1090,7 @@ class CoursesController < ApplicationController
#删除课程
#删除课程只是将课程的is_deleted状态改为falseis_deleted为false状态的课程只有管理员可以看到
def destroy
@course.update_attributes(:is_delete => true)
@course.delete!
@course = nil
redirect_to user_url(User.current)
end

@ -27,6 +27,7 @@ class HomeworkCommonController < ApplicationController
#@homeworks = @course.homework_commons.where("publish_time <= '#{Date.today}'").order("created_at desc").limit(10).offset(@page * 10)
@homework_commons = @course.homework_commons.where("name like '%#{search}%' and publish_time <= '#{Date.today}'").order("created_at desc")
end
#update_homework_time @homework_commons
@is_student = User.current.logged? && (User.current.admin? || (User.current.member_of_course?(@course) && !@is_teacher))
@is_new = params[:is_new]
@ -409,8 +410,8 @@ class HomeworkCommonController < ApplicationController
def update_homework_time homeworks
unless homeworks.nil?
homeworks.each do |h|
if h.homework_type == 3
student_works = h.student_work_projects.where("is_leader = 1")
if h.homework_type == 3 && h.homework_detail_group.base_on_project == 1
student_works = h.student_work_projects.where("is_leader = 1 && project_id != -1")
time = h.updated_at
unless student_works.nil?
student_works.each do |s|
@ -418,7 +419,7 @@ class HomeworkCommonController < ApplicationController
unless project.nil? && project.gpid.nil?
project_time=project.updated_on
project_time=ForgeActivity.where("project_id=?",project.id).last.updated_at if ForgeActivity.where("project_id=?",project.id).last
if format_time(time) < format_time(project_time)
if time.strftime('%Y-%m-%d %H:%M:%S') < project_time.strftime('%Y-%m-%d %H:%M:%S')
time = project_time
end
begin
@ -428,21 +429,30 @@ class HomeworkCommonController < ApplicationController
changesets = g.commits(project.gpid, :ref_name => default_branch)
changesets_latest_coimmit = changesets[0]
unless changesets[0].blank?
if format_time(time) < format_time(changesets_latest_coimmit.created_at)
if time.strftime('%Y-%m-%d %H:%M:%S') <changesets_latest_coimmit.created_at.strftime('%Y-%m-%d %H:%M:%S')
time = changesets_latest_coimmit.created_at
end
end
rescue
logger.error("############## ==> update homework project time")
end
end
end
end
puts h.updated_at
puts time
s_time = time
if format_time(time) > format_time(h.updated_at)
if time.strftime('%Y-%m-%d %H:%M:%S') > h.updated_at.strftime('%Y-%m-%d %H:%M:%S')
h.update_column('updated_at', s_time)
course_activity = CourseActivity.where("course_act_type=? and course_act_id =?", 'HomeworkCommon', h.id).first
if course_activity && (time.strftime('%Y-%m-%d %H:%M:%S') > course_activity.updated_at.strftime('%Y-%m-%d %H:%M:%S'))
course_activity.update_column('updated_at', s_time)
end
user_activity = UserActivity.where("act_type=? and act_id =?", 'HomeworkCommon', h.id).first
if user_activity && (time.strftime('%Y-%m-%d %H:%M:%S') > user_activity.updated_at.strftime('%Y-%m-%d %H:%M:%S'))
user_activity.update_column('updated_at', s_time)
end
org_activity = OrgActivity.where("org_act_type=? and org_act_id =?", 'HomeworkCommon', h.id).first
if org_activity && (time.strftime('%Y-%m-%d %H:%M:%S') > org_activity.updated_at.strftime('%Y-%m-%d %H:%M:%S'))
org_activity.update_column('updated_at', s_time)
end
end
end
end

@ -26,14 +26,25 @@ class QualityAnalysisController < ApplicationController
job_name = "#{user_name}-#{rep_id}"
sonar_name = "#{user_name}:#{rep_id}"
# 考虑到历史数据有些用户创建类job但是build失败,即sonar没有结果这个时候需要把job删除,并且删掉quality_analyses表数据
# 如果不要这句则需要迁移数据
@sonar_address = Redmine::Configuration['sonar_address']
projects_date = open(@sonar_address + "/api/projects/index").read
arr = JSON.parse(projects_date).map {|m| m["nm"]} # eg: ["Hjqreturn:cc_rep", "Hjqreturn:putong", "Hjqreturn:sonar_rep2", "shitou:sonar_rep"]
quality_an = QualityAnalysis.where(:sonar_name => sonar_name).first
if @client.job.exists?(job_name) && QualityAnalysis.where(:sonar_name => sonar_name).select{|qa| arr.include?(qa.sonar_name)}.blank?
logger.info("88888888888888888888")
aa = @client.job.delete("#{job_name}")
quality_an.delete unless quality_an.blank?
end
# Checks if the given job exists in Jenkins.
unless @client.job.exists?(job_name)
@g = Gitlab.client
branch = params[:branch]
language = swith_language_type(params[:language])
path = params[:path].blank? ? "./" : params[:path]
qa = QualityAnalysis.where(:project_id => @project.id, :author_login => user_name).first
version = qa.nil? ? 1 : qa.sonar_version + 1
# qa = QualityAnalysis.where(:project_id => @project.id, :author_login => user_name).first
version = quality_an.nil? ? 1 : quality_an.sonar_version + 1
properties = "sonar.projectKey=#{sonar_name}
sonar.projectName=#{sonar_name}
sonar.projectVersion=#{version}
@ -60,37 +71,64 @@ class QualityAnalysisController < ApplicationController
# 判断调用sonar分析是否成功
# 等待启动时间处理, 最长时间为30分钟
for i in 0..60 do
sleep(60)
for i in 0..360 do
sleep(5)
@current_build_status = @client.job.get_current_build_status("#{job_name}")
if (@current_build_status != "not_run" || @current_build_status != "running")
if (@current_build_status == "success" || @current_build_status == "failure")
break
if i == 60
if i == 360
@build_console_result = false
break
end
end
end
@console_build = @client.job.get_console_output("#{job_name}", build_num = 0, start = 0, mode = 'text')
# sonar 缓冲,取数据
sleep(5)
# 获取sonar output结果
console_build = @client.job.get_console_output("#{job_name}", build_num = 0, start = 0, mode = 'text')["output"]
logger.info("@current_build_status is ==> #{@current_build_status}")
logger.info("@console_build is ==> #{@console_build}")
d = @client.job.delete("#{job_name}") if jenkins_job == '200' && code != '201'
logger.error("delete result ==> #{code}")
if qa.blank? && @current_build_status == "success"
# 两种情况需要删除job
# 1/创建成功但是build失败则删除job
# 2/creat和build成功调用sonar启动失败则删除job
# 错误信息存储需存到Trustie数据库否则一旦job删除则无法获取这些信息
if jenkins_job == '200' && code != '201'
@client.job.delete("#{job_name}")
else
if @current_build_status == "failure"
reg_console = /Exception:.*?\r/.match(console_build)
output = reg_console[0].gsub("\r", "") unless reg_console.nil?
se = SonarError.where(:jenkins_job_name => job_name).first
se.nil? ? SonarError.create(:project_id => @project.id, :jenkins_job_name => job_name, :output => output) : se.update_column(:output, output)
@client.job.delete("#{job_name}")
elsif @current_build_status == "success"
if quality_an.blank?
QualityAnalysis.create(:project_id => @project.id, :author_login => user_name, :rep_identifier => identifier,
:sonar_version => version, :path => path, :branch => branch, :language => language, :sonar_name => "#{user_name}:#{rep_id}")
else
qa.update_attribute(:sonar_version, version)
end
end
end
end
rescue => e
puts e
end
respond_to do |format|
if @current_build_status == "success"
format.html{redirect_to project_quality_analysis_path(:project_id => @project.id, :resource_id => sonar_name, :branch => branch, :current_build_status => @current_build_status, :job_name => job_name)}
# format.js{redirect_to project_quality_analysis_path(:project_id => @project.id, :resource_id => sonar_name, :branch => branch)}
elsif @current_build_status == "failure"
format.html{redirect_to error_list_project_quality_analysi_path(:project_id => @project.id, :job_name => job_name)}
end
end
end
def error_list
@error_list = SonarError.where(:jenkins_job_name => params[:job_name]).first
respond_to do |format|
format.html
end
end
@ -145,7 +183,7 @@ class QualityAnalysisController < ApplicationController
get_current_build_status = @client.job.get_current_build_status("Hjqreturn-1280")
logger.error("Failed to update job: ==> #{jenkins_job}") unless jenkins_job == '200'
# 数据更新到Trustie数据
# 数据更新到Trustie数据
if jenkins_job == '200'
logger.info("quality_ananlysis will be updated: ==> #{jenkins_job}")
@quality_analysis.path = path
@ -168,27 +206,34 @@ class QualityAnalysisController < ApplicationController
@branch = params[:branch]
@resource_id = params[:resource_id]
@sonar_address = Redmine::Configuration['sonar_address']
@jenkins_address = Redmine::Configuration['jenkins_address']
if params[:resource_id].nil?
@name_flag = true
projects_date = open(@sonar_address + "/api/projects/index").read
arr = JSON.parse(projects_date).map {|m| m["nm"]} # eg: ["Hjqreturn:cc_rep", "Hjqreturn:putong", "Hjqreturn:sonar_rep2", "shitou:sonar_rep"]
@quality_analyses = QualityAnalysis.where(:project_id => @project.id).select{|qa| arr.include?(qa.sonar_name)}
else
filter = "sqale_rating,function_complexity,duplicated_lines_density,comment_lines_density,sqale_index,lines,files,functions,classes,directories,blocker_violations,critical_violations,major_violations,minor_violations,info_violations,violations"
complexity_date = open(@sonar_address + "/api/resources/index?resource=#{@resource_id}&depth=0&metrics=#{filter}").read
@complexity =JSON.parse(complexity_date).first
# 按名称转换成hash键值对
@ha = {}
@complexity["msr"].each do |com|
key = com["key"]
if key == "sqale_index"
value = com["frmt_val"]
else
if params[:current_build_status] == "failure"
job_name = params[:job_name]
@console_build = @client.job.get_console_output("#{job_name}", build_num = 0, start = 0, mode = 'text')["output"]
value = com["val"].to_i
end
complexity_date = open(@sonar_address + "/api/resources/index?resource=#{@resource_id}&depth=0&metrics=sqale_rating,function_complexity,duplicated_lines_density,comment_lines_density,sqale_index,lines,file_line,files,functions,classes,directories").read
@complexity =JSON.parse(complexity_date).first
@ha.store(key,value)
end
issue_date = open(@sonar_address + "/api/resources/index?resource=#{@resource_id}&depth=0&metrics=blocker_violations,critical_violations,major_violations,minor_violations,info_violations,violations").read
@sonar_issues = JSON.parse(issue_date).first
end
rescue => e
puts e
end
end
# Find project of id params[:project_id]

@ -38,7 +38,9 @@ class RepositoriesController < ApplicationController
before_filter :find_changeset, :only => [:revision, :add_related_issue, :remove_related_issue]
before_filter :authorize , :except => [:newrepo,:newcreate,:fork, :to_gitlab, :forked, :commit_diff, :project_archive, :quality_analysis]
# 链接gitlab
before_filter :connect_gitlab, :only => [:quality_analysis]
before_filter :connect_gitlab, :only => [:quality_analysis, :show]
# 版本库新增权限
before_filter :show_rep, :only => [:show]
accept_rss_auth :revisions
# hidden repositories filter // 隐藏代码过滤器
before_filter :check_hidden_repo, :only => [:show, :stats, :revisions, :revision, :diff ]
@ -361,44 +363,42 @@ update
def show
## TODO: the below will move to filter, done.
if !User.current.member_of?(@project) && @project.hidden_repo
render_403
return
end
# 获取版本库目录结构
@entries = @repository.entries(@path, @rev)
@changeset = @repository.find_changeset_by_name(@rev)
if request.xhr?
@entries ? render(:partial => 'dir_list_content') : render(:nothing => true)
else
g = Gitlab.client
@changesets = g.commits(@project.gpid, :ref_name => @rev)
g_project = g.project(@project.gpid)
@changesets = @g.commits(@project.gpid, :ref_name => @rev)
# 最近一次提交
@changesets_latest_coimmit = @changesets[0]
g_project = @g.project(@project.gpid)
# 总的提交数
@changesets_all_count = @project.gpid.nil? ? 0 : commit_count(@project, @rev)
@changesets_all_count = @g.user_static(@project.gpid, :rev => @rev).count
# 获取默认分支
@g_default_branch = g_project.default_branch.nil? ? "master" : g_project.default_branch
# 访问该页面的是会后则刷新
if @project.project_score.nil?
# 访问版本庫后更新project_score表数据changeset_num为提交总数
project_score = @project.project_score
if project_score.nil?
ProjectScore.create(:project_id => @project.id, :score => false)
else
project_score.update_column(:changeset_num, @changesets_all_count)
end
# 刷新改页面的时候,更新统计数
if @changesets_all_count != @project.project_score.changeset_num && @changesets_all_count != 0
update_commits_count(@project, @changesets_all_count)
end
# 最近一次提交
@changesets_latest_coimmit = @changesets[0]
unless @changesets[0].blank?
update_commits_date(@project, @changesets_latest_coimmit)
end
@creator = User.where("id =?", @project.user_id).first.try(:login)
# @properties = @repository.properties(@path, @rev)
# @repositories = @project.repositories
# project_path_cut = RepositoriesHelper::PROJECT_PATH_CUT
# ip = RepositoriesHelper::REPO_IP_ADDRESS
# unless @changesets_latest_coimmit.blank?
# update_commits_date(@project, @changesets_latest_coimmit)
# end
@creator = @project.owner.to_s
gitlab_address = Redmine::Configuration['gitlab_address']
# REDO:需优化,仅测试用
@zip_path = Gitlab.endpoint.to_s + "/projects/" + @project.gpid.to_s + "/repository/archive?&private_token=" + Gitlab.private_token
# 获取版本库路径主要分为两种一种随Gitlab类型另一种为Git类型Git类型为无用数据最终需要删掉这种类型。
if @repository.type.to_s == "Repository::Gitlab"
@repos_url = gitlab_address.to_s+"/"+@project.owner.to_s+"/"+@repository.identifier+"."+"git"
@repos_url = gitlab_address.to_s+"/" + @creator + "/" + @repository.identifier+"."+"git"
else
@repos_url = "http://"+@repository.login.to_s+"_"+@repository.identifier.to_s+"@"+ip.to_s + @repository.url.slice(project_path_cut, @repository.url.length).to_s
end
@ -653,10 +653,21 @@ update
# 链接gitlab
def connect_gitlab
begin
@g = Gitlab.client
unless @project.gpid.nil?
@g_project = @g.project(@project.gpid)
end
rescue => e
logger.error("failed to connect gitlab ==> #{e}")
end
end
def show_rep
if !User.current.member_of?(@project) && @project.hidden_repo
render_403
return
end
end
def find_repository

@ -155,47 +155,51 @@ class SchoolController < ApplicationController
def apply_add_school
data = {result:0,name:params[:name],school_id:0}
#0 成功 1参数错误 2名称已存在
#0 成功 1参数错误 2名称已存在 3.失败
data[:result] = 0
#检验参数
if params[:name] == "" || params[:province] == "" || params[:city] == "" || params[:address] == ""
data[:result] = 1
else
school_id = School.find_by_sql("select id from schools where name='#{params[:name]}'").first
if school_id
school = School.where("name = '#{params[:name]}'").first
if school
data[:result] = 2
else
school = School.new
school.name = params[:name].strip
school.pinyin = Pinyin.t(params[:name].strip, splitter: '')
school.save
#status 0未处理 1通过 2拒绝
applyschool = ApplyAddSchools.new
applyschool.school_id = school.id
#用belongs_to 可以一起存数据库
applyschool.school = school
applyschool.name = school.name
applyschool.province = params[:province]
applyschool.city = params[:city]
applyschool.address = params[:address]
applyschool.remarks = params[:remarks]
applyschool.save
if applyschool.save
data[:school_id] = school.id
else
data[:result] = 3
end
end
end
render :json =>data
end
def search_repeat_schoolname
status = 0
status = 0 #没有重复的
name = params[:name]
if name
school_id = School.find_by_sql("select id from schools where name='#{name}'").first
school = School.where("name = '#{name}'").first
if school_id
status = 1
if school
status = 1 #有重复的
end
end

@ -803,6 +803,9 @@ class StudentWorkController < ApplicationController
@new_score.comment = params[:new_form][:user_message] if params[:new_form] && params[:new_form][:user_message] && params[:new_form][:user_message] != ""
@new_score.user_id = User.current.id
@new_score.student_work_id = @work.id
if @is_teacher && @work.work_status == 0
@work.update_column('work_status', 1)
end
if User.current.admin?
@new_score.reviewer_role = 1
else
@ -813,7 +816,6 @@ class StudentWorkController < ApplicationController
if @is_teacher
@is_new = true
@is_last_a = false
@work.update_column('work_status', 1)
else
@is_new = false
end
@ -1229,7 +1231,7 @@ class StudentWorkController < ApplicationController
sheet1[count_row,3] = homework.user.user_extensions.student_id
sheet1[count_row,4] = homework.user.mail
sheet1[count_row,5] = homework.name
sheet1[count_row,6] = strip_html homework.description
sheet1[count_row,6] = strip_html homework.description if !homework.description.nil?
sheet1[count_row,7] = homework.teacher_score.nil? ? l(:label_without_score) : homework.teacher_score.round(2)
sheet1[count_row,8] = homework.teaching_asistant_score.nil? ? l(:label_without_score) : homework.teaching_asistant_score.round(2)
if @homework.anonymous_comment ==0

@ -1046,11 +1046,21 @@ class UsersController < ApplicationController
homework_detail_group.save if homework_detail_group
if homework.homework_type != 3
unless homework.course.nil?
students = homework.course.student
if !homework.course.nil? && !students.empty?
name = homework.name
homework.course.student.each do |student|
StudentWork.create(:name => "#{name}的作品提交", :homework_common_id => homework.id, :user_id => student.student_id)
name_str = name + "的作品提交"
str = ""
students.each do |student|
if str != ""
str += ","
end
str += "('#{name_str}',#{homework.id},#{student.student_id}, '#{format_time(Time.now)}', '#{format_time(Time.now)}')"
end
#('#{name}的作品提交',#{homework.id},#{student.student_id}, '#{format_time(Time.now)}', '#{format_time(Time.now)}')
sql = "insert into student_works (name, homework_common_id,user_id, created_at, updated_at) values" + str
#StudentWork.create(:name => "#{name}的作品提交", :homework_common_id => homework.id, :user_id => student.student_id)
ActiveRecord::Base.connection.execute sql
end
end
@ -2012,44 +2022,8 @@ class UsersController < ApplicationController
def add_exist_file_to_course
@flag = true
if params[:send_id].present?
send_id = params[:send_id]
@ori = Attachment.find_by_id(send_id)
course_ids = params[:course_ids]
if course_ids.nil?
@flag = false
end
unless course_ids.nil?
course_ids.each do |id|
next if @ori.blank?
@exist = false
Course.find(id).attachments.each do |att| #如果课程中包含该资源
if att.id == @ori.id || (!att.copy_from.nil? && !@ori.copy_from.nil? && att.copy_from == @ori.copy_from) || att.copy_from == @ori.id || att.id == @ori.copy_from
att.created_on = Time.now
att.save
@exist = true
break
end
end
next if @exist
attach_copied_obj = @ori.copy
attach_copied_obj.tag_list.add(@ori.tag_list) # tag关联
attach_copied_obj.container = Course.find(id)
attach_copied_obj.created_on = Time.now
attach_copied_obj.author_id = User.current.id
attach_copied_obj.is_public = 0
attach_copied_obj.copy_from = @ori.copy_from.nil? ? @ori.id : @ori.copy_from #发送要添加copy_from
if attach_copied_obj.attachtype == nil
attach_copied_obj.attachtype = 4
end
if attach_copied_obj.save
# 更新引用次数
quotes = @ori.quotes.to_i + 1
@ori.update_attribute(:quotes, quotes) unless @ori.nil?
@ori.forwards << Forward.new(:to_type => attach_copied_obj.class.name, :to_id => attach_copied_obj.id,:created_at => Time.now)
end
@save_message = attach_copied_obj.errors.full_messages
end
end
rs = ResourcesService.new
@ori, @flag, @save_message = rs.send_resource_to_course(params)
elsif params[:send_ids].present?
send_ids = params[:send_ids].split(",")
course_ids = params[:course_ids]

@ -8,7 +8,11 @@ class WechatsController < ActionController::Base
# default text responder when no other match
on :text do |request, content|
#邀请码
if join_request(request)
sendBindClass(request, {invite_code: content})
else
request.reply.text '您的意见已收到,感谢您的反馈!'
end
end
# When receive 'help', will trigger this responder
@ -142,6 +146,11 @@ class WechatsController < ActionController::Base
end
end
def join_request(request)
openid = request[:FromUserName]
wl = WechatLog.where("openid = '#{openid}' and request_raw like '%\"Event\":\"click\"%'").order('id desc').first
wl && JSON(wl.request_raw)["EventKey"] == 'JOIN_CLASS'
end
def sendBindClass(request, params)
begin

@ -2631,7 +2631,7 @@ module ApplicationHelper
def homework_anonymous_comment (homework, is_in_course, user_activity_id = -1, course_activity = -1)
if homework.homework_detail_manual.comment_status == 0 ||Time.parse(homework.end_time.to_s).strftime("%Y-%m-%d") >= Time.now.strftime("%Y-%m-%d")
link = link_to "启动匿评","javascript:void(0)", :class => "postOptionLink", :title => "作业截止日期之前不可以启动匿评"
elsif homework.student_works.count >= 2 && homework.homework_detail_manual#作业份数大于2
elsif homework.student_works.has_committed.count >= 2 && homework.homework_detail_manual#作业份数大于2
case homework.homework_detail_manual.comment_status
when 1
link = link_to '启动匿评', Setting.protocol + "://" + Setting.host_name + "/homework_common/" + homework.id.to_s + "/alert_anonymous_comment?is_in_course=" + is_in_course.to_s + "&user_activity_id=" + user_activity_id.to_s + "&course_activity=" + course_activity.to_s, id: "#{homework.id}_start_anonymous_comment", remote: true, disable_with: '加载中...',:class => 'postOptionLink'
@ -2681,8 +2681,8 @@ module ApplicationHelper
#根据传入作业确定显示为编辑作品还是新建作品,或者显示作品数量
def user_for_homework_common homework,is_teacher
if User.current.member_of_course?(homework.course)
count = homework.student_works.has_committed.count
if User.current.member_of_course?(homework.course)
if is_teacher #老师显示作品数量
link_to "作品(#{count})", student_work_index_url_in_org(homework.id), :class => "c_blue"
else #学生显示提交作品、修改作品等按钮
@ -3282,7 +3282,7 @@ end
def strip_html(text,len=0,endss="...")
ss = ""
if text.length>0
if !text.nil? && text.length>0
ss=text.gsub(/<\/?.*?>/, '').strip
ss = ss.gsub(/&nbsp;/, ' ')

@ -388,6 +388,21 @@ module UsersHelper
return result
end
#获取指定用户的课程大纲
def user_syllabus(user)
results = []
courses = user_courses_list(user)
other = Syllabus.new(title: '未命名课程')
courses.each do |c|
other << c unless c.syllabus
end
user.syllabuses.to_a << other
end
#获取用户参与的公开的课程列表
def user_public_course_list user
membership = user.coursememberships.all#@user.coursememberships.all(:conditions => Course.visible_condition(User.current))

@ -1,3 +1,4 @@
class ApplyAddSchools < ActiveRecord::Base
attr_accessible :address, :city, :name, :province, :remarks, :school_id, :status
belongs_to :school
end

@ -4,6 +4,8 @@ require 'elasticsearch/model'
class Course < ActiveRecord::Base
include Redmine::SafeAttributes
include CoursesHelper
STATUS_ACTIVE = 1
STATUS_CLOSED = 5
STATUS_ARCHIVED = 9
@ -22,7 +24,7 @@ class Course < ActiveRecord::Base
end
end
attr_accessible :code, :extra, :name, :state, :tea_id, :time , :location, :state, :term, :password,:is_public,:description,:class_period, :open_student, :enterprise_name, :is_delete
attr_accessible :code, :extra, :name, :state, :tea_id, :time , :location, :state, :term, :password,:is_public,:description,:class_period, :open_student, :enterprise_name, :is_delete, :syllabus_id
#belongs_to :project, :class_name => 'Course', :foreign_key => :extra, primary_key: :identifier
belongs_to :teacher, :class_name => 'User', :foreign_key => :tea_id # 定义一个方法teacher该方法通过tea_id来调用User表
belongs_to :school, :class_name => 'School', :foreign_key => :school_id #定义一个方法school该方法通过school_id来调用School表
@ -69,8 +71,10 @@ class Course < ActiveRecord::Base
validates_presence_of :term,:name
validates_format_of :class_period, :with =>/^[1-9]\d*$/
validates_format_of :name,:with =>/^[^ ]+[a-zA-Z0-9_\u4e00-\u9fa5\s\S]+$/
validates_format_of :time, :with => /^\d{4}$/
validates_format_of :name,:with =>/^[^ ]+[a-zA-Z0-9_\u4e00-\u9fa5\s\S]*$/
validates_length_of :description, :maximum => 10000
before_save :self_validate
# 公开课程变成私有课程,所有资源都变成私有
after_update :update_files_public,:update_course_ealasticsearch_index
@ -169,6 +173,10 @@ class Course < ActiveRecord::Base
)
end
def delete!
update_attribute(:is_delete, true)
end
def visible?(user=User.current)
user.allowed_to?(:view_course, self)
end
@ -296,6 +304,13 @@ class Course < ActiveRecord::Base
end
end
def update_default_value
self.time = Time.now.year unless time
self.term = cur_course_term unless term
self.class_period = 10 unless class_period
end
# 创建课程讨论区
def create_board_sync
@board = self.boards.build
@ -480,7 +495,7 @@ class Course < ActiveRecord::Base
def generate_qrcode
ticket = self.qrcode
if !ticket || ticket.size < 10
response = Wechat.api.qrcode_create_scene(invite_code)
response = Wechat.api.qrcode_create_scene(invite_code, 2592000)
logger.debug "response = #{response}"
self.qrcode = response['ticket']
save! && reload

@ -0,0 +1,3 @@
class SonarError < ActiveRecord::Base
attr_accessible :jenkins_job_name, :output, :project_id
end

@ -9,8 +9,10 @@ class Syllabus < ActiveRecord::Base
belongs_to :user
has_many :courses
has_many :journals_for_messages, :as => :jour, :dependent => :destroy
attr_accessible :user_id, :description, :title, :eng_name, :syllabus_type, :credit, :hours, :theory_hours, :practice_hours, :applicable_major, :pre_course
safe_attributes 'title', 'description', 'eng_name', 'syllabus_type', 'credit', 'hours', 'theory_hours', 'practice_hours', 'credit', 'applicable_major', 'pre_course'
attr_accessible :description, :user_id, :title, :eng_name, :syllabus_type, :credit, :hours, :theory_hours, :practice_hours, :applicable_major, :pre_course
safe_attributes 'title','user', 'description', 'eng_name', 'syllabus_type', 'credit', 'hours', 'theory_hours', 'practice_hours', 'credit', 'applicable_major', 'pre_course'
validates :title, :user_id, presence: true
scope :like, lambda {|arg|
if arg.blank?

@ -0,0 +1,4 @@
#coding=utf-8
#
class WechatLog < ActiveRecord::Base
end

@ -44,6 +44,8 @@ class CoursesService
}
end
#搜索课程
def search_course params,current_user
courses_all = Course.all_course
@ -324,9 +326,9 @@ class CoursesService
define_error [
0, '加入成功',
1, '密码错误',
2, '班级已过期 请联系班级管理员重启班级。',
3, '您已经加入了班级',
4, '您加入的班级不存在',
2, '课程已过期 请联系课程管理员重启课程。',
3, '您已经加入了课程',
4, '您的邀请码不正确',
5, '您还未登录',
6, '申请成功,请等待审核完毕',
7, '您已经发送过申请了,请耐心等待',

@ -0,0 +1,53 @@
#coding=utf-8
class ResourcesService
#发送资源到课程
def send_resource_to_course user,params
send_id = params[:send_id]
@ori = Attachment.find_by_id(send_id)
course_ids = params[:course_ids]
@flag = false
unless course_ids.nil?
course_ids.each do |id|
next if @ori.blank?
@exist = false
Course.find(id).attachments.each do |att| #如果课程中包含该资源
if att.id == @ori.id || (!att.copy_from.nil? && !@ori.copy_from.nil? && att.copy_from == @ori.copy_from) || att.copy_from == @ori.id || att.id == @ori.copy_from
att.created_on = Time.now
att.save
@exist = true
@flag = true
break
end
end
next if @exist
attach_copied_obj = @ori.copy
attach_copied_obj.tag_list.add(@ori.tag_list) # tag关联
attach_copied_obj.container = Course.find(id)
attach_copied_obj.created_on = Time.now
attach_copied_obj.author_id = user.id
attach_copied_obj.is_public = 0
attach_copied_obj.copy_from = @ori.copy_from.nil? ? @ori.id : @ori.copy_from #发送要添加copy_from
if attach_copied_obj.attachtype == nil
attach_copied_obj.attachtype = 4
end
if attach_copied_obj.save
# 更新引用次数
quotes = @ori.quotes.to_i + 1
@ori.update_attribute(:quotes, quotes) unless @ori.nil?
@ori.forwards << Forward.new(:to_type => attach_copied_obj.class.name, :to_id => attach_copied_obj.id,:created_at => Time.now)
@flag = true
else
@flag = false
@save_message = attach_copied_obj.errors.full_messages
break
end
end
end
[@ori, @flag, @save_message]
end
end

@ -0,0 +1,143 @@
#coding=utf-8
class SyllabusesService
include ApplicationHelper
include CoursesHelper
def judge_can_setting(sy,user)
sy[:can_setting] = sy[:user_id] == user.id ? true : false
sy[:can_setting] = false if sy[:id].nil?
sy.courses.each do |c|
c[:can_setting] = false
member = c.members.where("user_id=#{user.id} and course_id=#{c.id}")[0]
roleName = member.roles[0].name if member
if roleName && (roleName == "TeachingAsistant" || roleName == "Teacher" )
c[:can_setting] = true
end
if c.tea_id == user.id
c[:can_setting] = true
end
end
sy
end
#获取指定用户的课程大纲
def user_syllabus(user)
courses = CoursesService.new.user_courses_list(user)
other = Syllabus.new(title: '未命名课程',user_id: user.id)
courses.each do |c|
other.courses << c[:course] unless c[:course].syllabus
end
# user.syllabuses.each do |syllabus|
# syllabus.courses = syllabus.courses.not_deleted
# end
#
# user.syllabuses.to_a << other
courses = user.courses.not_deleted
syllabus_ids = courses.empty? ? '(-1)' : "(" + courses.map{|course| !course.syllabus_id.nil? && course.syllabus_id}.join(",") + ")"
syllabuses = Syllabus.where("id in #{syllabus_ids} or user_id = #{user.id}").order("updated_at desc")
syllabuses.each do |syllabus|
syllabus.courses = courses.where("syllabus_id = #{syllabus.id}").select("courses.*,(SELECT MAX(updated_at) FROM `course_activities` WHERE course_activities.course_id = courses.id) AS updatetime").order("time desc")
end
syllabuses.to_a << other
#管理权限 can_setting
syllabuses.each do |s|
s = judge_can_setting(s,user)
end
syllabuses
end
def after_create_course(course, user)
#unless User.current.admin?
r = Role.givable.find_by_id(Setting.new_project_user_role_id.to_i) || Role.givable.first
m = Member.new(:user => user, :roles => [r])
m.project_id = -1
course_info = CourseInfos.new(:user_id => user.id, :course_id => course.id)
#user_grades = UserGrade.create(:user_id => User.current.id, :course_id => @course.id)
course.members << m
course.course_infos << course_info
end
#创建大纲
# params {title: '大纲名称', [{course}, {course}]}
def create(user, title, courses = [])
sy = Syllabus.new(title: title, user_id: user.id)
ActiveRecord::Base.transaction() do
sy.save!
courses.each do |course|
if ::Course === course
course.syllabus_id = sy.id
course.save!
elsif Hash === course
c = ::Course.new(course)
c.tea_id = user.id
c.syllabus_id = sy.id
c.update_default_value
c.is_public = 0
c.save!
after_create_course(c, user)
end
end
end
sy[:can_setting] = true
sy
end
#修改课程大纲的名称、班级名称、新增班级
def edit(user, option)
courses = []
status = -1
syllabus_id = option[:id]
sy = Syllabus.where("id=?",option[:id]).first
if sy && sy.user_id == user.id
syllabus_title = option[:title]
sy.title = syllabus_title
sy.save!
#修改班级名称
modify_courses = option[:modify_courses]
modify_courses.each do |c|
course = Course.where("id=?",c.id).first
if course && course.tea_id == user.id
course.name = c.name
!course.save
end
end
#新增班级
add_courses = option[:add_courses]
add_courses.each do |c|
course = Course.new()
course.name = c
course.tea_id = user.id
course.syllabus_id = sy.id
course.update_default_value
course.is_public = 0
course.save!
after_create_course(course, user)
end
status = 0
end
status
end
end

@ -319,4 +319,8 @@ class UsersService
my_jours_arr
end
end

@ -0,0 +1,3 @@
<span>
<a title="<%= course.name %>" id="rename_course_name_<%= course.id %>" ondblclick="rename_course_name($(this),'<%=course.name %>','<%=course.id %>');"><%= course.name %></a>
</span>

@ -68,10 +68,8 @@
</td>
<td class="center">
</td>
<td style="white-space: nowrap;overflow: hidden;text-overflow: ellipsis;" class="name" title='<%=course.name%>'>
<span>
<a title="<%=course.name %>" id="rename_course_name_<%=course.id %>" ondblclick="rename_course_name($(this),'<%=course.name %>','<%=course.id %>');"><%= course.name%></a>
</span>
<td style="white-space: nowrap;overflow: hidden;text-overflow: ellipsis;" class="name" title='<%=course.name%>' id="syllabus_course_name_<%=course.id %>">
<%= render :partial => 'admin/rename_course_name', :locals => {:course => course} %>
</td>
<td align="center">
<%= link_to(course.try(:teacher).try(:realname).truncate(6, omission: '...'), user_path(course.teacher)) %>

@ -1 +1 @@
$("#rename_course_name_<%=@course.id %>").html("<%=@course.name %>");
$("#syllabus_course_name_<%=@course.id %>").html("<%=escape_javascript(render :partial => 'admin/rename_course_name', :locals => {:course => @course}) %>");

@ -1,4 +1,7 @@
<% if @in_user_center%>
<% if @in_user_homepage %>
<% homepage = BlogComment.find(@user.blog.homepage_id) %>
$("#user_activity_<%= @user_activity_id%>").replaceWith("<%= escape_javascript(render :partial => 'blogs/homepage', :locals => {:activity => homepage, :user_activity_id => homepage.id}) %>");
<% elsif @in_user_center%>
$("#user_activity_<%= @user_activity_id%>").replaceWith("<%= escape_javascript(render :partial => 'users/user_blog', :locals => {:activity => @article,:user_activity_id =>@user_activity_id}) %>");
// init_activity_KindEditor_data(<%#= @user_activity_id%>,"","87%", 'UserActivity');
<% else%>

@ -48,4 +48,53 @@
</div>
<div class="cl"></div>
</div>
<% count=activity.children.count %>
<div class="homepagePostReply">
<%= render :partial => 'users/reply_banner', :locals => {:count => count, :activity => activity, :user_activity_id => user_activity_id} %>
<% comments = activity.children.reorder("created_on desc").limit(3) %>
<% if count > 0 %>
<div class="" id="reply_div_<%= user_activity_id %>">
<%= render :partial => 'users/all_replies', :locals => {:comments => comments}%>
</div>
<% end %>
<% if activity.locked == false && User.current.logged?%>
<div class="homepagePostReplyContainer borderBottomNone minHeight48">
<div class="homepagePostReplyPortrait mr15 imageFuzzy" id="reply_image_<%= user_activity_id%>"><%= link_to image_tag(url_to_avatar(User.current), :width => "33", :height => "33"), user_path(activity.author_id), :alt => "用户头像" %></div>
<div class="homepagePostReplyInputContainer mb10">
<% if User.current.logged? %>
<div nhname='new_message_<%= user_activity_id%>' style="display:none;">
<%= form_for('new_form',:url => {:controller => 'blog_comments', :action => 'reply', :user_id=>activity.author_id,:blog_id=>activity.blog_id,:id=>activity.id,:homepage=>1},:method => "post", :remote => true) do |f|%>
<input type="hidden" name="quote[quote]" value="">
<input type="hidden" name="in_user_center" value="true">
<input type="hidden" name="blog_comment[sticky]" value="0">
<input type="hidden" name="blog_comment[locked]" value="0">
<input type="hidden" name="blog_comment[title]" value="RE:<%= activity.title%>">
<input type="hidden" name="user_activity_id" value="<%=user_activity_id%>">
<div nhname='toolbar_container_<%= user_activity_id%>'></div>
<textarea placeholder="有问题或有建议,请直接给我留言吧!" style="display: none" nhname='new_message_textarea_<%= user_activity_id%>' name="blog_comment[content]"></textarea>
<a id="new_message_submit_btn_<%= user_activity_id%>" href="javascript:void(0)" onclick="this.style.display='none'" class="blue_n_btn fr" style="display:none;margin-top:6px;">发送</a>
<div class="cl"></div>
<p nhname='contentmsg_<%= user_activity_id%>'></p>
<% end%>
</div>
<% else %>
<%= render :partial => "users/show_unlogged" %>
<% end %>
<div class="cl"></div>
</div>
<div class="cl"></div>
</div>
<% end %>
</div>
</div>
<script>
function expand_reply_input(id) {
$(id).toggle();
}
$(function() {
sd_create_editor_from_data(<%= user_activity_id %>, null, "100%", "<%= activity.class.to_s %>");
});
</script>

@ -27,7 +27,7 @@
<span class="f14 fl">邀请码:</span>
<span class="f14 fontBlue2 fl"><%=@course.generate_invite_code %></span>
<% unless is_teacher %>
<div id="join_in_course_header" class="fl ml35"><%= join_in_course_header(@course, User.current) %></div>
<div id="join_in_course_header" class="fl ml30"><%= join_in_course_header(@course, User.current) %></div>
<% end %>
</div>

@ -1,4 +1,4 @@
<span style="word-break: normal; word-wrap: normal;"><%=@syllabus.title %></span>
<span style="word-break: normal; word-wrap: break-word;"><%=@syllabus.title %></span>
<% if User.current == syllabus.user %>
<%= link_to image_tag("../images/signature_edit.png",width:"12px", height: "12px"), "javascript:void(0);",:id => "syllabus_edit_title_png", :class => "none", :onclick => "show_edit_title();"%>

@ -120,193 +120,6 @@
});
}
function showcity(province, cityField) {
$("#provincenotice").hide();
switch (province) {
case "北京" :
var cityOptions = new Array(
"东城", "西城", "朝阳", "丰台", "石景山", "海淀", "门头沟",
"房山", "通州", "顺义", "昌平", "大兴", "平谷", "怀柔", "密云", "延庆");
break;
case "上海" :
var cityOptions = new Array(
"崇明", "黄浦", "卢湾", "徐汇", "长宁", "静安", "普陀", "闸北", "虹口", "杨浦", "闵行",
"宝山", "嘉定", "浦东", "金山", "松江", "青浦", "南汇", "奉贤");
break;
case "广东" :
var cityOptions = new Array(
"广州", "深圳", "珠海", "东莞", "中山", "佛山", "惠州", "河源", "潮州", "江门", "揭阳", "茂名",
"梅州", "清远", "汕头", "汕尾", "韶关", "顺德", "阳江", "云浮", "湛江", "肇庆");
break;
case "江苏" :
var cityOptions = new Array(
"南京", "常熟", "常州", "海门", "淮安", "江都", "江阴", "昆山", "连云港", "南通",
"启东", "沭阳", "宿迁", "苏州", "太仓", "泰州", "同里", "无锡", "徐州", "盐城",
"扬州", "宜兴", "仪征", "张家港", "镇江", "周庄");
break;
case "重庆" :
var cityOptions = new Array(
"万州", "涪陵", "渝中", "大渡口", "江北", "沙坪坝", "九龙坡", "南岸", "北碚", "万盛",
"双挢", "渝北", "巴南", "黔江", "长寿", "綦江", "潼南", "铜梁", "大足", "荣昌", "壁山",
"梁平", "城口", "丰都", "垫江", "武隆", "忠县", "开县", "云阳", "奉节", "巫山", "巫溪",
"石柱", "秀山", "酉阳", "彭水", "江津", "合川", "永川", "南川");
break;
case "安徽" :
var cityOptions = new Array(
"合肥", "安庆", "蚌埠", "亳州", "巢湖", "滁州", "阜阳", "贵池", "淮北", "淮化", "淮南",
"黄山", "九华山", "六安", "马鞍山", "宿州", "铜陵", "屯溪", "芜湖", "宣城");
break;
case "福建" :
var cityOptions = new Array(
"福州", "厦门", "泉州", "漳州", "龙岩", "南平", "宁德", "莆田", "三明");
break;
case "甘肃" :
var cityOptions = new Array(
"兰州", "白银", "定西", "敦煌", "甘南", "金昌", "酒泉", "临夏", "平凉", "天水",
"武都", "武威", "西峰", "张掖");
break;
case "广西" :
var cityOptions = new Array(
"南宁", "百色", "北海", "桂林", "防城港", "贵港", "河池", "贺州", "柳州", "钦州", "梧州", "玉林");
break;
case "贵州" :
var cityOptions = new Array(
"贵阳", "安顺", "毕节", "都匀", "凯里", "六盘水", "铜仁", "兴义", "玉屏", "遵义");
break;
case "海南" :
var cityOptions = new Array(
"海口", "儋县", "陵水", "琼海", "三亚", "通什", "万宁");
break;
case "河北" :
var cityOptions = new Array(
"石家庄", "保定", "北戴河", "沧州", "承德", "丰润", "邯郸", "衡水", "廊坊", "南戴河", "秦皇岛",
"唐山", "新城", "邢台", "张家口");
break;
case "黑龙江" :
var cityOptions = new Array(
"哈尔滨", "北安", "大庆", "大兴安岭", "鹤岗", "黑河", "佳木斯", "鸡西", "牡丹江", "齐齐哈尔",
"七台河", "双鸭山", "绥化", "伊春");
break;
case "河南" :
var cityOptions = new Array(
"郑州", "安阳", "鹤壁", "潢川", "焦作", "济源", "开封", "漯河", "洛阳", "南阳", "平顶山",
"濮阳", "三门峡", "商丘", "新乡", "信阳", "许昌", "周口", "驻马店");
break;
case "香港" :
var cityOptions = new Array(
"香港", "九龙", "新界");
break;
case "湖北" :
var cityOptions = new Array(
"武汉", "恩施", "鄂州", "黄冈", "黄石", "荆门", "荆州", "潜江", "十堰", "随州", "武穴",
"仙桃", "咸宁", "襄阳", "襄樊", "孝感", "宜昌");
break;
case "湖南" :
var cityOptions = new Array(
"长沙", "常德", "郴州", "衡阳", "怀化", "吉首", "娄底", "邵阳", "湘潭", "益阳", "岳阳",
"永州", "张家界", "株洲");
break;
case "江西" :
var cityOptions = new Array(
"南昌", "抚州", "赣州", "吉安", "景德镇", "井冈山", "九江", "庐山", "萍乡",
"上饶", "新余", "宜春", "鹰潭");
break;
case "吉林" :
var cityOptions = new Array(
"长春", "吉林", "白城", "白山", "珲春", "辽源", "梅河", "四平", "松原", "通化", "延吉");
break;
case "辽宁" :
var cityOptions = new Array(
"沈阳", "鞍山", "本溪", "朝阳", "大连", "丹东", "抚顺", "阜新", "葫芦岛", "锦州",
"辽阳", "盘锦", "铁岭", "营口");
break;
case "澳门" :
var cityOptions = new Array("澳门");
break;
case "内蒙古" :
var cityOptions = new Array(
"呼和浩特", "阿拉善盟", "包头", "赤峰", "东胜", "海拉尔", "集宁", "临河", "通辽", "乌海",
"乌兰浩特", "锡林浩特");
break;
case "宁夏" :
var cityOptions = new Array(
"银川", "固源", "石嘴山", "吴忠");
break;
case "青海" :
var cityOptions = new Array(
"西宁", "德令哈", "格尔木", "共和", "海东", "海晏", "玛沁", "同仁", "玉树");
break;
case "山东" :
var cityOptions = new Array(
"济南", "滨州", "兖州", "德州", "东营", "菏泽", "济宁", "莱芜", "聊城", "临沂",
"蓬莱", "青岛", "曲阜", "日照", "泰安", "潍坊", "威海", "烟台", "枣庄", "淄博");
break;
case "山西" :
var cityOptions = new Array(
"太原", "长治", "大同", "候马", "晋城", "离石", "临汾", "宁武", "朔州", "忻州",
"阳泉", "榆次", "运城");
break;
case "陕西" :
var cityOptions = new Array(
"西安", "安康", "宝鸡", "汉中", "渭南", "商州", "绥德", "铜川", "咸阳", "延安", "榆林");
break;
case "四川" :
var cityOptions = new Array(
"成都", "巴中", "达川", "德阳", "都江堰", "峨眉山", "涪陵", "广安", "广元", "九寨沟",
"康定", "乐山", "泸州", "马尔康", "绵阳", "眉山", "南充", "内江", "攀枝花", "遂宁",
"汶川", "西昌", "雅安", "宜宾", "自贡", "资阳");
break;
case "台湾" :
var cityOptions = new Array(
"台北", "基隆", "台南", "台中", "高雄", "屏东", "南投", "云林", "新竹", "彰化", "苗栗",
"嘉义", "花莲", "桃园", "宜兰", "台东", "金门", "马祖", "澎湖");
break;
case "天津" :
var cityOptions = new Array(
"天津", "和平", "东丽", "河东", "西青", "河西", "津南", "南开", "北辰", "河北", "武清", "红挢",
"塘沽", "汉沽", "大港", "宁河", "静海", "宝坻", "蓟县");
break;
case "新疆" :
var cityOptions = new Array(
"乌鲁木齐", "阿克苏", "阿勒泰", "阿图什", "博乐", "昌吉", "东山", "哈密", "和田", "喀什",
"克拉玛依", "库车", "库尔勒", "奎屯", "石河子", "塔城", "吐鲁番", "伊宁");
break;
case "西藏" :
var cityOptions = new Array(
"拉萨", "阿里", "昌都", "林芝", "那曲", "日喀则", "山南");
break;
case "云南" :
var cityOptions = new Array(
"昆明", "大理", "保山", "楚雄", "大理", "东川", "个旧", "景洪", "开远", "临沧", "丽江",
"六库", "潞西", "曲靖", "思茅", "文山", "西双版纳", "玉溪", "中甸", "昭通");
break;
case "浙江" :
var cityOptions = new Array(
"杭州", "安吉", "慈溪", "定海", "奉化", "海盐", "黄岩", "湖州", "嘉兴", "金华", "临安",
"临海", "丽水", "宁波", "瓯海", "平湖", "千岛湖", "衢州", "江山", "瑞安", "绍兴", "嵊州",
"台州", "温岭", "温州", "余姚", "舟山");
break;
case "海外" :
var cityOptions = new Array(
"美国", "日本", "英国", "法国", "德国", "其他");
break;
default:
var cityOptions = new Array("");
break;
}
cityField.options.length = 0;
for (var i = 0; i < cityOptions.length; i++) {
cityField.options[i] = new Option(cityOptions[i], cityOptions[i]);
/*
if (cityField.options[i].value==city)
{
//alert("here put City ok!");
document.oblogform["city"].selectedIndex = i;
}*/
}
}
function ifNameRepeat(){
//名称不能为空也不能重复

@ -249,191 +249,6 @@
<% end %>
<script type="text/javascript">
function showcity(province, cityField) {
switch (province) {
case "北京" :
var cityOptions = new Array(
"东城", "西城", "朝阳", "丰台", "石景山", "海淀", "门头沟",
"房山", "通州", "顺义", "昌平", "大兴", "平谷", "怀柔", "密云", "延庆");
break;
case "上海" :
var cityOptions = new Array(
"崇明", "黄浦", "卢湾", "徐汇", "长宁", "静安", "普陀", "闸北", "虹口", "杨浦", "闵行",
"宝山", "嘉定", "浦东", "金山", "松江", "青浦", "南汇", "奉贤");
break;
case "广东" :
var cityOptions = new Array(
"广州", "深圳", "珠海", "东莞", "中山", "佛山", "惠州", "河源", "潮州", "江门", "揭阳", "茂名",
"梅州", "清远", "汕头", "汕尾", "韶关", "顺德", "阳江", "云浮", "湛江", "肇庆");
break;
case "江苏" :
var cityOptions = new Array(
"南京", "常熟", "常州", "海门", "淮安", "江都", "江阴", "昆山", "连云港", "南通",
"启东", "沭阳", "宿迁", "苏州", "太仓", "泰州", "同里", "无锡", "徐州", "盐城",
"扬州", "宜兴", "仪征", "张家港", "镇江", "周庄");
break;
case "重庆" :
var cityOptions = new Array(
"万州", "涪陵", "渝中", "大渡口", "江北", "沙坪坝", "九龙坡", "南岸", "北碚", "万盛",
"双挢", "渝北", "巴南", "黔江", "长寿", "綦江", "潼南", "铜梁", "大足", "荣昌", "壁山",
"梁平", "城口", "丰都", "垫江", "武隆", "忠县", "开县", "云阳", "奉节", "巫山", "巫溪",
"石柱", "秀山", "酉阳", "彭水", "江津", "合川", "永川", "南川");
break;
case "安徽" :
var cityOptions = new Array(
"合肥", "安庆", "蚌埠", "亳州", "巢湖", "滁州", "阜阳", "贵池", "淮北", "淮化", "淮南",
"黄山", "九华山", "六安", "马鞍山", "宿州", "铜陵", "屯溪", "芜湖", "宣城");
break;
case "福建" :
var cityOptions = new Array(
"福州", "厦门", "泉州", "漳州", "龙岩", "南平", "宁德", "莆田", "三明");
break;
case "甘肃" :
var cityOptions = new Array(
"兰州", "白银", "定西", "敦煌", "甘南", "金昌", "酒泉", "临夏", "平凉", "天水",
"武都", "武威", "西峰", "张掖");
break;
case "广西" :
var cityOptions = new Array(
"南宁", "百色", "北海", "桂林", "防城港", "贵港", "河池", "贺州", "柳州", "钦州", "梧州", "玉林");
break;
case "贵州" :
var cityOptions = new Array(
"贵阳", "安顺", "毕节", "都匀", "凯里", "六盘水", "铜仁", "兴义", "玉屏", "遵义");
break;
case "海南" :
var cityOptions = new Array(
"海口", "儋县", "陵水", "琼海", "三亚", "通什", "万宁");
break;
case "河北" :
var cityOptions = new Array(
"石家庄", "保定", "北戴河", "沧州", "承德", "丰润", "邯郸", "衡水", "廊坊", "南戴河", "秦皇岛",
"唐山", "新城", "邢台", "张家口");
break;
case "黑龙江" :
var cityOptions = new Array(
"哈尔滨", "北安", "大庆", "大兴安岭", "鹤岗", "黑河", "佳木斯", "鸡西", "牡丹江", "齐齐哈尔",
"七台河", "双鸭山", "绥化", "伊春");
break;
case "河南" :
var cityOptions = new Array(
"郑州", "安阳", "鹤壁", "潢川", "焦作", "济源", "开封", "漯河", "洛阳", "南阳", "平顶山",
"濮阳", "三门峡", "商丘", "新乡", "信阳", "许昌", "周口", "驻马店");
break;
case "香港" :
var cityOptions = new Array(
"香港", "九龙", "新界");
break;
case "湖北" :
var cityOptions = new Array(
"武汉", "恩施", "鄂州", "黄冈", "黄石", "荆门", "荆州", "潜江", "十堰", "随州", "武穴",
"仙桃", "咸宁", "襄阳", "襄樊", "孝感", "宜昌");
break;
case "湖南" :
var cityOptions = new Array(
"长沙", "常德", "郴州", "衡阳", "怀化", "吉首", "娄底", "邵阳", "湘潭", "益阳", "岳阳",
"永州", "张家界", "株洲");
break;
case "江西" :
var cityOptions = new Array(
"南昌", "抚州", "赣州", "吉安", "景德镇", "井冈山", "九江", "庐山", "萍乡",
"上饶", "新余", "宜春", "鹰潭");
break;
case "吉林" :
var cityOptions = new Array(
"长春", "吉林", "白城", "白山", "珲春", "辽源", "梅河", "四平", "松原", "通化", "延吉");
break;
case "辽宁" :
var cityOptions = new Array(
"沈阳", "鞍山", "本溪", "朝阳", "大连", "丹东", "抚顺", "阜新", "葫芦岛", "锦州",
"辽阳", "盘锦", "铁岭", "营口");
break;
case "澳门" :
var cityOptions = new Array("澳门");
break;
case "内蒙古" :
var cityOptions = new Array(
"呼和浩特", "阿拉善盟", "包头", "赤峰", "东胜", "海拉尔", "集宁", "临河", "通辽", "乌海",
"乌兰浩特", "锡林浩特");
break;
case "宁夏" :
var cityOptions = new Array(
"银川", "固源", "石嘴山", "吴忠");
break;
case "青海" :
var cityOptions = new Array(
"西宁", "德令哈", "格尔木", "共和", "海东", "海晏", "玛沁", "同仁", "玉树");
break;
case "山东" :
var cityOptions = new Array(
"济南", "滨州", "兖州", "德州", "东营", "菏泽", "济宁", "莱芜", "聊城", "临沂",
"蓬莱", "青岛", "曲阜", "日照", "泰安", "潍坊", "威海", "烟台", "枣庄", "淄博");
break;
case "山西" :
var cityOptions = new Array(
"太原", "长治", "大同", "候马", "晋城", "离石", "临汾", "宁武", "朔州", "忻州",
"阳泉", "榆次", "运城");
break;
case "陕西" :
var cityOptions = new Array(
"西安", "安康", "宝鸡", "汉中", "渭南", "商州", "绥德", "铜川", "咸阳", "延安", "榆林");
break;
case "四川" :
var cityOptions = new Array(
"成都", "巴中", "达川", "德阳", "都江堰", "峨眉山", "涪陵", "广安", "广元", "九寨沟",
"康定", "乐山", "泸州", "马尔康", "绵阳", "眉山", "南充", "内江", "攀枝花", "遂宁",
"汶川", "西昌", "雅安", "宜宾", "自贡", "资阳");
break;
case "台湾" :
var cityOptions = new Array(
"台北", "基隆", "台南", "台中", "高雄", "屏东", "南投", "云林", "新竹", "彰化", "苗栗",
"嘉义", "花莲", "桃园", "宜兰", "台东", "金门", "马祖", "澎湖");
break;
case "天津" :
var cityOptions = new Array(
"天津", "和平", "东丽", "河东", "西青", "河西", "津南", "南开", "北辰", "河北", "武清", "红挢",
"塘沽", "汉沽", "大港", "宁河", "静海", "宝坻", "蓟县");
break;
case "新疆" :
var cityOptions = new Array(
"乌鲁木齐", "阿克苏", "阿勒泰", "阿图什", "博乐", "昌吉", "东山", "哈密", "和田", "喀什",
"克拉玛依", "库车", "库尔勒", "奎屯", "石河子", "塔城", "吐鲁番", "伊宁");
break;
case "西藏" :
var cityOptions = new Array(
"拉萨", "阿里", "昌都", "林芝", "那曲", "日喀则", "山南");
break;
case "云南" :
var cityOptions = new Array(
"昆明", "大理", "保山", "楚雄", "大理", "东川", "个旧", "景洪", "开远", "临沧", "丽江",
"六库", "潞西", "曲靖", "思茅", "文山", "西双版纳", "玉溪", "中甸", "昭通");
break;
case "浙江" :
var cityOptions = new Array(
"杭州", "安吉", "慈溪", "定海", "奉化", "海盐", "黄岩", "湖州", "嘉兴", "金华", "临安",
"临海", "丽水", "宁波", "瓯海", "平湖", "千岛湖", "衢州", "江山", "瑞安", "绍兴", "嵊州",
"台州", "温岭", "温州", "余姚", "舟山");
break;
case "海外" :
var cityOptions = new Array(
"美国", "日本", "英国", "法国", "德国", "其他");
break;
default:
var cityOptions = new Array("");
break;
}
cityField.options.length = 0;
for (var i = 0; i < cityOptions.length; i++) {
cityField.options[i] = new Option(cityOptions[i], cityOptions[i]);
/*
if (cityField.options[i].value==city)
{
//alert("here put City ok!");
document.oblogform["city"].selectedIndex = i;
}*/
}
}
function showtechnical_title(val){
$("*[nhname='tag']").each(function(){
$("*[nh_required='1']",$(this)).attr("required",false);

@ -46,7 +46,7 @@
</div>
</div>
<% end %>
<% if act.org_act_type == 'OrgDocumentComment' %>
<% if act.org_act_type == 'OrgDocumentComment' && act.org_act.organization.home_id != act.org_act.id %>
<%= render :partial => 'show_org_document', :locals => {:document => act.org_act, :act => act, :flag => 2, :org_subfield_id => params[:org_subfield_id]} %>
<% end %>
<% end %>

@ -40,7 +40,7 @@
<li class=" mb5 ml80">
<label >公开&nbsp;&nbsp;</label>
<input id="project_is_public" name="project[is_public]" type="checkbox" value="1" checked="checked">
<span class="c_grey">(打钩为公开,不打钩则不公开,若不公开,仅项目成员可见该项目。)</span>
<span class="c_grey">(打钩为公开项目,不打钩为私有项目;私有项目仅项目成员可见。)</span>
<div class="cl"></div>
</li>
<li>

@ -94,7 +94,7 @@
},
series: [{
name: '代码质量',
data: [<%= @complexity["msr"][9].nil? ? 0 : @complexity["msr"][9]["val"] %>]
data: [<%= @ha["sqale_rating"].nil? ? 0 : @ha["sqale_rating"] %>]
// tooltip: {
// valueSuffix: ' km/h'
// }
@ -209,7 +209,7 @@
},
series: [{
name: '复杂度',
data: [<%= @complexity["msr"][6].nil? ? 0 : @complexity["msr"][6]["val"] %>]
data: [<%= @ha["function_complexity"].nil? ? 0 : @ha["function_complexity"] %>]
// tooltip: {
// valueSuffix: ' km/h'
// }
@ -329,7 +329,7 @@
},
series: [{
name: '重复率',
data: [<%= @complexity["msr"][7].nil? ? 0 : @complexity["msr"][7]["val"] %>]
data: [<%= @ha["duplicated_lines_density"].nil? ? 0 : @ha["duplicated_lines_density"] %>]
// tooltip: {
// valueSuffix: ' km/h'
// }
@ -454,7 +454,7 @@
},
series: [{
name: '质量等级',
data: [<%= @complexity["msr"][5].nil? ? 0 : @complexity["msr"][5]["val"] %>]
data: [<%= @ha["comment_lines_density"].nil? ? 0 : @ha["comment_lines_density"] %>]
// tooltip: {
// valueSuffix: ' km/h'
// }

@ -6,86 +6,124 @@
<div class="cl"></div>
<div class="tac f20 fb mt35 mb30">项目代码质量分析报告</div>
<div class="analysis-tag-wrap f16"> <span class="analysis-tag fl mr15"></span> <span class="fb fl">概要信息</span></div>
<% if @complexity["msr"].count > 3 %>
<%= render :partial => "hightchars" %>
<div class="analysis-block mt10 mb40 f14">
<div class="flex mb10">
<div class="analysis-genral">
<p id="container_sqale_rating" style="max-width:200px;min-height:200px;width:200px; margin:0 auto;"></p>
<p class="fontGrey3">质量等级</p>
<p class="fontBlue2 pr"><%= @complexity["msr"][9].nil? ? "A" : @complexity["msr"][9]["frmt_val"] %>
<span class="f10 c_white analysis-genral-icon <%=@complexity["msr"][9].nil? ? "" : sqale_rating_status(@complexity["msr"][9]["val"].to_i)[1] %> borderRadius"><%= @complexity["msr"][9].blank? ? "很好" : sqale_rating_status(@complexity["msr"][9]["val"].to_i)[0] %></span></p>
<p class="fontBlue2 pr"><%= @ha["sqale_rating"] %>
<span class="f10 c_white analysis-genral-icon <%= sqale_rating_status(@ha["sqale_rating"].to_i)[1] %> borderRadius">
<%= @ha["sqale_rating"].nil? ? "很好" : sqale_rating_status(@ha["sqale_rating"].to_i)[0] %>
</span>
</p>
</div>
<div class="analysis-genral" >
<p id="container_function_complexity" style="max-width:200px;min-height:200px;width:200px; margin:0 auto;"></p>
<p class="fontGrey3">复杂度</p>
<p class="fontBlue2 pr"><%= @complexity["msr"][6].nil? ? 0 : @complexity["msr"][6]["val"] %>
<span class="f10 c_white analysis-genral-icon <%= @complexity["msr"][6].nil? ? "" : complexity_status(@complexity["msr"][6]["val"].to_i)[1] %> borderRadius"><%= @complexity["msr"][6].nil? ? 0 : complexity_status(@complexity["msr"][6]["val"].to_i)[0] %></span></p>
<p class="fontBlue2 pr"><%= @ha["function_complexity"].nil? ? 0 : @ha["function_complexity"] %>
<span class="f10 c_white analysis-genral-icon <%= complexity_status(@ha["function_complexity"].to_i)[1] %> borderRadius">
<%= @ha["function_complexity"].nil? ? "良好" : complexity_status(@ha["function_complexity"].to_i)[0] %>
</span>
</p>
</div>
</div>
<div class="flex">
<div class="analysis-genral">
<p id="container_duplicated_lines_density" style="max-width:200px;min-height:200px;width:200px; margin:0 auto;"></p>
<p class="fontGrey3">代码重复度</p>
<p class="fontBlue2 pr"><%= @complexity["msr"][7].nil? ? 0 : @complexity["msr"][7]["frmt_val"] %>
<span class="f10 c_white analysis-genral-icon <%= @complexity["msr"][7].nil? ? "" : duplicated_lines_density_status(@complexity["msr"][7]["val"].to_i)[1] %> borderRadius"><%= @complexity["msr"][7].nil? ? 0 : duplicated_lines_density_status(@complexity["msr"][7]["val"].to_i)[0] %></span></p>
<p class="fontBlue2 pr"><%= @ha["duplicated_lines_density"].nil? ? 0 : @ha["duplicated_lines_density"] %>
<span class="f10 c_white analysis-genral-icon <%= duplicated_lines_density_status(@ha["duplicated_lines_density"].to_i)[1] %> borderRadius">
<%= @ha["duplicated_lines_density"].nil? ? 0 : duplicated_lines_density_status(@ha["duplicated_lines_density"].to_i)[0] %>
</span>
</p>
</div>
<div class="analysis-genral">
<p id="container_comment_lines_density" style="max-width:200px;min-height:200px;width:200px; margin:0 auto;"></p>
<p class="fontGrey3">注释率</p>
<p class="fontBlue2 pr"><%= @complexity["msr"][5].nil? ? 0 : @complexity["msr"][5]["frmt_val"] %>
<span class="f10 c_white analysis-genral-icon <%= @complexity["msr"][5].nil? ? "" : comment_lines_density_status(@complexity["msr"][5]["val"].to_i)[1] %> borderRadius"><%= @complexity["msr"][5].nil? ? 0 : comment_lines_density_status(@complexity["msr"][5]["val"].to_i)[0] %></span></p>
<p class="fontBlue2 pr"><%= @ha["comment_lines_density"].nil? ? 0 : @ha["comment_lines_density"] %>
<span class="f10 c_white analysis-genral-icon <%= comment_lines_density_status(@ha["comment_lines_density"].to_i)[1] %> borderRadius">
<%= @ha["comment_lines_density"].nil? ? 0 : comment_lines_density_status(@ha["comment_lines_density"].to_i)[0] %>
</span>
</p>
</div>
</div>
</div>
<% end %>
<div class="analysis-tag-wrap f16"> <span class="analysis-tag fl mr15"></span> <span class="fb fl mr10">质量等级</span><span class="mr10 fontGrey2"><span class="c_red f18" style="margin-top:-5px; display:inline-block;"><%=@complexity["msr"][9].nil? ? 0 : score_sqale_rating(@complexity["msr"][9]["val"].to_i) %></span>/5分</span>
<span class="fontGrey2">可定性评价为:<span class="c_red">质量<%=@complexity["msr"][9].nil? ? "很好" : sqale_rating_status(@complexity["msr"][9]["val"])[0] %></span></span></div>
<div class="analysis-tag-wrap f16">
<span class="analysis-tag fl mr15"></span>
<span class="fb fl mr10">质量等级</span>
<span class="mr10 fontGrey2"><span class="c_red f18" style="margin-top:-5px; display:inline-block;"><%= @ha["sqale_rating"].nil? ? 0 : score_sqale_rating(@ha["sqale_rating"].to_i) %></span>/5分</span>
<span class="fontGrey2">可定性评价为:<span class="c_red">质量<%= @ha["sqale_rating"].nil? ? "很好" : sqale_rating_status(@ha["sqale_rating"].to_i)[0] %></span></span></div>
<div class="analysis-block mt10 mb40 f14">
<div><span class="fontGrey3 mr30">技术债务</span><span class="w70 pInline"><%=@complexity["msr"][8].nil? ? 0 : @complexity["msr"][8]["frmt_val"] %></span>
<div><span class="fontGrey3 mr30">技术债务</span>
<span class="w70 pInline">
<% if @ha["sqale_index"].to_i == 0 %>
0
<% else %>
<%= /[0-9]*/.match(@ha["sqale_index"])[0] %>天
<%= / [0-9]*/.match(@ha["sqale_index"]).nil? ? 0 : / [0-9]*/.match(@ha["sqale_index"]) %>小时
<% end %>
</span>
<span class="fontGrey2"><a class="linkBlue2" target="_blank" href="<%= @sonar_address %>/drilldown/measures/<%= @resource_id %>?metric=sqale_index">查看详情</a></span></div>
<div><span class="fontGrey3 mr30 fl">质量问题</span>
<span class="fontBlue2 w70 pInline"><a class="fontBlue2 w70 pInline" target="_blank" href="<%= @sonar_address %>/component_issues?id=<%= @resource_id %>#resolved=false"><%=@sonar_issues["msr"][0].nil? ? 0 : @sonar_issues["msr"][0]["frmt_val"] %></a></span><span class="fontGrey2">&nbsp;问题分类如下:</span></div>
<span class="fontBlue2 w70 pInline">
<a class="fontBlue2 w70 pInline" target="_blank" href="<%= @sonar_address %>/component_issues?id=<%= @resource_id %>#resolved=false">
<%= @ha["violations"].nil? ? 0 : @ha["violations"] %>
</a>
</span><span class="fontGrey2">&nbsp;问题分类如下:</span></div>
<div class="ml90 mt15">
<div class="mb10"><span class="analysis-block-icon mr5"></span><span class="fontGrey3 mr45">阻断</span>
<a target="_blank" href="<%= @sonar_address %>/component_issues?id=<%= @resource_id %>#resolved=false|severities=BLOCKER" class="fontBlue2 w70 pInline"><%= @sonar_issues["msr"][1].nil? ? 0 : @sonar_issues["msr"][1]["frmt_val"] %></a>
<span class="quality-percentage"><span class="quality-percentage-rate" style="width:<%=@sonar_issues["msr"][1].nil? ? 0 : statistics_result_percentage(@sonar_issues["msr"][1]["frmt_val"].to_i, 1000) %>%;"></span></span></div>
<a target="_blank" href="<%= @sonar_address %>/component_issues?id=<%= @resource_id %>#resolved=false|severities=BLOCKER" class="fontBlue2 w70 pInline">
<%= @ha["blocker_violations"].nil? ? 0 : @ha["blocker_violations"] %>
</a>
<span class="quality-percentage"><span class="quality-percentage-rate" style="width:<%=@ha["blocker_violations"].nil? ? 0 : statistics_result_percentage(@ha["blocker_violations"].to_i, 3000) %>%;"></span></span></div>
<div class="mb10"><span class="analysis-serious-icon mr5"></span><span class="fontGrey3 mr45">严重</span>
<a target="_blank" href="<%= @sonar_address %>/component_issues?id=<%= @resource_id %>#resolved=false|severities=CRITICAL" class="fontBlue2 w70 pInline"><%= @sonar_issues["msr"][2].nil? ? 0 : @sonar_issues["msr"][2]["frmt_val"] %></a>
<span class="quality-percentage"><span class="quality-percentage-rate" style="width:<%=@sonar_issues["msr"][2].nil? ? 0 : statistics_result_percentage(@sonar_issues["msr"][2]["frmt_val"].to_i, 1000) %>%;"></span></span></div>
<a target="_blank" href="<%= @sonar_address %>/component_issues?id=<%= @resource_id %>#resolved=false|severities=CRITICAL" class="fontBlue2 w70 pInline">
<%= @ha["critical_violations"].nil? ? 0 : @ha["critical_violations"] %>
</a>
<span class="quality-percentage"><span class="quality-percentage-rate" style="width:<%= @ha["critical_violations"].nil? ? 0 : statistics_result_percentage(@ha["critical_violations"].to_i, 3000) %>%;"></span></span></div>
<div class="mb10"><span class="analysis-main-icon mr5"></span><span class="fontGrey3 mr45">主要</span>
<a target="_blank" href="<%= @sonar_address %>/component_issues?id=<%= @resource_id %>#resolved=false|severities=MAJOR" class="fontBlue2 w70 pInline"><%= @sonar_issues["msr"][3].nil? ? 0 : @sonar_issues["msr"][3]["frmt_val"] %></a>
<span class="quality-percentage"><span class="quality-percentage-rate" style="width:<%=@sonar_issues["msr"][3].nil? ? 0 : statistics_result_percentage(@sonar_issues["msr"][3]["frmt_val"].to_i, 1000) %>%;"></span></span></div>
<a target="_blank" href="<%= @sonar_address %>/component_issues?id=<%= @resource_id %>#resolved=false|severities=MAJOR" class="fontBlue2 w70 pInline">
<%= @ha["major_violations"].nil? ? 0 : @ha["major_violations"] %>
</a>
<span class="quality-percentage"><span class="quality-percentage-rate" style="width:<%= @ha["major_violations"].nil? ? 0 : statistics_result_percentage(@ha["major_violations"].to_i, 3000) %>%;"></span></span></div>
<div class="mb10"><span class="analysis-secondary-icon mr5"></span><span class="fontGrey3 mr45">次要</span>
<a target="_blank" href="<%= @sonar_address %>/component_issues?id=<%= @resource_id %>#resolved=false|severities=MINOR" class="fontBlue2 w70 pInline"><%=@sonar_issues["msr"][4].nil? ? 0 : @sonar_issues["msr"][4]["frmt_val"] %></a>
<span class="quality-percentage"><span class="quality-percentage-rate" style="width:<%=@sonar_issues["msr"][4].nil? ? 0 : statistics_result_percentage(@sonar_issues["msr"][4]["frmt_val"].to_i, 1000) %>%;"></span></span></div>
<a target="_blank" href="<%= @sonar_address %>/component_issues?id=<%= @resource_id %>#resolved=false|severities=MINOR" class="fontBlue2 w70 pInline">
<%= @ha["minor_violations"].nil? ? 0 : @ha["minor_violations"] %>
</a>
<span class="quality-percentage"><span class="quality-percentage-rate" style="width:<%= @ha["minor_violations"].nil? ? 0 : statistics_result_percentage(@ha["minor_violations"].to_i, 3000) %>%;"></span></span></div>
<div><span class="analysis-info-icon mr5"></span><span class="fontGrey3 mr45">信息</span>
<a target="_blank" href="<%= @sonar_address %>/component_issues?id=<%= @resource_id %>#resolved=false|severities=INFO" class="fontBlue2 w70 pInline"><%=@sonar_issues["msr"][5].nil? ? 0 : @sonar_issues["msr"][5]["frmt_val"] %></a>
<span class="quality-percentage"><span class="quality-percentage-rate" style="width:<%=@sonar_issues["msr"][5].nil? ? 0 : statistics_result_percentage(@sonar_issues["msr"][5]["frmt_val"].to_i, 200) %>%;"></span></span></div>
<a target="_blank" href="<%= @sonar_address %>/component_issues?id=<%= @resource_id %>#resolved=false|severities=INFO" class="fontBlue2 w70 pInline">
<%= @ha["info_violations"].nil? ? 0 : @ha["info_violations"] %>
</a>
<span class="quality-percentage"><span class="quality-percentage-rate" style="width:<%= @ha["info_violations"].nil? ? 0 : statistics_result_percentage(@ha["info_violations"].to_i, 3000) %>%;"></span></span></div>
</div>
</div>
<div class="analysis-tag-wrap f16"> <span class="analysis-tag fl mr15"></span> <span class="fb fl mr10">代码规模</span><span class="fontGrey2">可定性评价为:<span class="c_red"><%=@complexity["msr"][0].nil? ? 0 : lines_scale(@complexity["msr"][0]["frmt_val"].to_i) %></span></span></div>
<div class="analysis-tag-wrap f16">
<span class="analysis-tag fl mr15"></span>
<span class="fb fl mr10">代码规模</span><span class="fontGrey2">可定性评价为:<span class="c_red"><%= @ha["lines"].nil? ? 0 : lines_scale(@ha["lines"].to_i) %></span></span></div>
<div class="analysis-block mt10 mb40 flex f14">
<div class="analysis-genral">
<p class="fontGrey3">代码行数</p>
<p class="fontBlue2"><%= @complexity["msr"][0].nil? ? 0 : @complexity["msr"][0]["frmt_val"] %></p>
<p class="fontBlue2"><%= @ha["lines"].nil? ? 0 : @ha["lines"] %></p>
</div>
<div class="analysis-genral">
<p class="fontGrey3">文件</p>
<p class="fontBlue2"><%= @complexity["msr"][2].nil? ? 0 : @complexity["msr"][2]["frmt_val"] %></p>
<p class="fontBlue2"><%= @ha["lines"].nil? ? 0 : @ha["lines"] %></p>
</div>
<div class="analysis-genral">
<p class="fontGrey3">目录</p>
<p class="fontBlue2"><%= @complexity["msr"][3].nil? ? 0 : @complexity["msr"][3]["frmt_val"] %></p>
<p class="fontBlue2"><%= @ha["directories"].nil? ? 0 : @ha["directories"] %></p>
</div>
<div class="analysis-genral">
<p class="fontGrey3">类</p>
<p class="fontBlue2"><%= @complexity["msr"][1].nil? ? 0 : @complexity["msr"][1]["frmt_val"] %></p>
<p class="fontBlue2"><%= @ha["classes"].nil? ? 0 : @ha["classes"] %></p>
</div>
<div class="analysis-genral">
<p class="fontGrey3">方法</p>
<p class="fontBlue2"><%=@complexity["msr"][4].nil? ? 0 : @complexity["msr"][4]["frmt_val"] %></p>
<p class="fontBlue2"><%=@ha["functions"].nil? ? 0 : @ha["functions"] %></p>
</div>
</div>
<!--<div class="analysis-tag-wrap f16"> <span class="analysis-tag fl mr15"></span> <span class="fb fl">贡献统计</span></div>-->

@ -1,9 +1,11 @@
<% if @current_build_status == "success" %>
<%= render :partial => "show", :locals => {:branch => params[:branch]} %>
<div class="project_r_h">
<h2 class="project_h2" style="width:180px;">质量分析</h2>
</div>
<div>
<div class="c_red">本次分析失败,原因如下:</div>
<% if @build_console_result == false %>
分析超时
<% else %>
<% if @build_console_result %>
运行结果超时
<% else %>
<%= render :partial => "console_output" %>
<% end %>
<%= h @sonar_error.to_json %>
<% end %>
</div>

@ -0,0 +1,11 @@
<div class="project_r_h">
<h2 class="project_h2" style="width:180px;">质量分析</h2>
</div>
<div>
<div class="c_red">本次分析失败,原因如下:</div>
<% if @build_console_result == false %>
分析超时
<% else %>
<%= h @error_list.output %>
<% end %>
</div>

@ -20,17 +20,10 @@
:depth => (depth + 1),
:parent_id => tr_id)) %>');">&nbsp;</span>
<% end %>
<!--<a class="<%#= (entry.is_dir? ? 'icon icon-folder' : "icon icon-file #{Redmine::MimeType.css_class_of(ent_name)}") %>">-->
<!--<%#= h(ent_name) %>-->
<!--</a>-->
<%#= h(ent_name), :class => "(entry.is_dir? ? 'icon icon-folder' : "icon icon-file #{Redmine::MimeType.css_class_of(ent_name)}")%>
<%= link_to h(ent_name),
{:action => (entry.is_dir? ? 'show' : 'entry'), :id => @project, :repository_id => @repository.identifier_param, :path => to_path_param(ent_path), :rev => @rev},
:class => (entry.is_dir? ? 'icon icon-folder' : "icon icon-file #{Redmine::MimeType.css_class_of(ent_name)}")%>
</td>
<!--<td class="size"><%#= (entry.size ? number_to_human_size(entry.size) : "?") unless entry.is_dir? %></td>-->
<!--<td class="size"><%#= (entry.size ? number_to_human_size(entry.size) : "?") unless entry.is_dir? %></td>-->
<%# if @repository.report_last_commit %>
<div id="children_tree">
<td class="tree-comments c_grey hidden">
<div class="hidden" title="<%= (latest_changes.message) if latest_changes && latest_changes.message %>">
@ -46,10 +39,8 @@
<div class="hidden" title="<%= format_time(latest_changes.time) %>">
<%# 为了转换UTC时间时差8小时 %>
<%= distance_of_time_in_words(latest_changes.time, Time.now + 8.hours) if latest_changes && latest_changes.time %>
<%#= latest_changes.time if latest_changes && latest_changes.time %>
</div>
</td>
</div>
<%# end %>
</tr>
<% end %>

@ -21,9 +21,9 @@
<%= select_tag :branch, options_for_select(@repository.branches, @rev), :id => 'branch' %>
<% end -%>
<% if !@repository.tags.nil? && @repository.tags.length > 0 -%>
<%= select_tag :tag, options_for_select([''] + @repository.tags, @rev), :id => 'tag', :style=>" display:none" %>
<% end -%>
<%# if !@repository.tags.nil? && @repository.tags.length > 0 -%>
<%#= select_tag :tag, options_for_select([''] + @repository.tags, @rev), :id => 'tag', :style=>" display:none" %>
<%# end -%>
<% if @repository.supports_all_revisions? %>
<%= hidden_field_tag 'rev', @rev, :size => 8 %>

@ -15,7 +15,7 @@
<%= select_tag :language, options_for_select(["java","python","ruby","c++","c#","c"]), :id => 'branch', :class => "analysis-option-box" %>
</div>
</div>
<div class="courseSendSubmit mr15"><a href="javascript:void(0);" class="sendSourceText" onclick="$('#ajax-indicator').text('正在分析中…………(大概需要30分钟请耐心等待)').show();$('#quality_analyses_form').submit();hideModal()">提交</a></div>
<div class="courseSendSubmit mr15"><a href="javascript:void(0);" class="sendSourceText" onclick="$('#ajax-indicator').css('opacity','0.8').text('正在分析中…………(大概需要30分钟请耐心等待)').show();$('#quality_analyses_form').submit();hideModal()">提交</a></div>
<div class="courseSendCancel"><a href="javascript:void(0);" class="sendSourceText" onclick="hideModal()">取消</a></div>
<div class="cl"></div>
</div>

@ -1,17 +1,11 @@
<%= call_hook(:view_repositories_show_contextual, {:repository => @repository, :project => @project}) %>
<%#= call_hook(:view_repositories_show_contextual, {:repository => @repository, :project => @project}) %>
<div class="project_r_h">
<div class="fl"><h2 class="project_h2_repository"><%= render :partial => 'breadcrumbs', :locals => {:path => @path, :kind => 'dir', :revision => @rev} %></h2></div>
<% unless @entries.nil? %>
<a href="<%= @zip_path %>" class="btn_zipdown fr" onclick="">ZIP下载</a>
<%# if is_project_manager?(User.current, @project.id) && QualityAnalysis.where(:project_id => @project.id).first.nil? %>
<%# if User.current.member_of?(@project) %>
<% if quality_analysis(User.current.try(:login), @repository.id).nil? && User.current.member_of?(@project) && @project.is_public? %>
<%= link_to "质量分析", quality_analysis_path(:id => @project.id, :repository_id => @repository.identifier, :rev => @rev, :default_branch => @g_default_branch ), :remote => true, :class => "btn_zipdown fr" %>
<% end %>
<%# end %>
<%# else %>
<%#= link_to "质量分析", project_quality_analysis_path(:project_id => @project.id, :resource_id => @proje), :class => "btn_zipdown fr" %>
<%# end %>
<% end %>
</div>
<div class="repository_con" style="line-height:1.9;">
@ -28,24 +22,24 @@
<% else %>
版本库地址:<%= h @repository.url %>
<% end %>
<!-- added by bai -->
<div class="cl"></div>
</div>
<% else %>
<%= render :partial => 'navigation' %>
<div class="fl c_grey02 mt5 mr5">克隆网址:</div>
<textarea id="copy_rep_content" class="cloneUrl mt5 fl" type="input" ><%= @repository.type.to_s=="Repository::Gitlab" ? @repos_url.to_s.lstrip : @repository.url %></textarea>
<textarea id="copy_rep_content" class="cloneUrl mt5 fl" type="input" ><%= @repos_url.to_s.lstrip %></textarea>
<a href="javascript:void(0);" class="clone_btn mt5" onclick="jsCopy()"><span class="vl_copy" title="点击复制版本库地址"></span></a>
<div class="fl mt5 ml15">
<%=link_to "代码统计", stats_repository_project_path(:id => @project.id, :repository_id => @repository.identifier, :rev => @rev, :creator => @creator, :default_branch => @g_default_branch ), :class => "fl vl_zip" %>
</div>
<%# 针对公开项目:用户必须创建了项目,否则用户无法同步 %>
<% if User.current.id != @project.user_id %>
<div class="fr mt5"><%= link_to "<span class='vl_fork'></span>".html_safe+"Fork", {:controller => 'repositories', :action => 'forked'}, :class=>"vl_btn", :target => "_blank", :confirm=>"平台将为您创建一个新的同名项目和版本库,请问是否继续?" %>
<span href="javascript:void(0);" class="vl_btn_2 fb"><%= @project.forked_count.to_i %></span>
</div>
<% end %>
<div class="cl"></div>
<div class="recordBanner mt10">
<% if @changesets && !@changesets.empty? %>
<% if !user_commit_rep(@changesets_latest_coimmit.author_email).nil? %>
@ -71,24 +65,14 @@
</div>
<% end %>
<!--contextual end-->
<% if !@entries.nil? && authorize_for('repositories', 'browse') %>
<%# 数据统计 %>
<%#= render :partial => 'summary' %>
<%# end %>
<%= render :partial => 'dir_list' %>
<% end %>
<%#= render_properties(@properties) %>
<!-- 代码修订 -->
<%#= render_properties(@properties) %>
<a href="https://<%=Setting.host_name %>/forums/1/memos/1232" >如何提交代码</a>
</div>
<% content_for :header_tags do %>
<%= stylesheet_link_tag "scm" %>
<% end %>
<%# content_for :header_tags do %>
<%#= stylesheet_link_tag "scm" %>
<%# end %>
<% html_title(l(:label_repository)) -%>

@ -26,7 +26,7 @@
<li >
<span class="tit_fb ">编程代码:</span>
<div class="showHworkP break_word"><pre id="work-src_<%= work.id%>" style="display: none;"><%= work.description if work.description%></pre><div class="fontGrey2 font_cus" id="work-code_<%= work.id%>">
<div class="showHworkP break_word"><pre id="work-src_<%= work.id%>" style="display: none;"><%= work.description ? work.description : "该作品尚未提交相关内容。"%></pre><div class="fontGrey2 font_cus" id="work-code_<%= work.id%>">
</div>
</div>
<div class="cl"></div>

@ -195,8 +195,13 @@
<% sort_projects = project_sort_update projects %>
<div class="mt10 relatePWrap" id="relatePWrap_<%=user_activity_id %>">
<div class="mr5 fontGrey2">
<% first_pro = project_sort_first(projects).first %>
#&nbsp;<%=time_from_now first_pro.updated_at %><%= link_to User.find(first_pro.user_id).show_name, user_activities_path(first_pro.user_id), :class => "newsBlue ml5 mr5"%>更新了项目,最近更新:
<%# first_pro = sort_projects.first %>
<% first_pro = Project.find sort_projects.first.project_id %>
<% commit_time = first_pro.project_score.commit_time %>
<% one_time = first_pro.updated_on %>
<% one_forge_time=ForgeActivity.where("project_id=?",first_pro.id).last.updated_at if ForgeActivity.where("project_id=?",first_pro.id).last %>
<% one_time= one_time > one_forge_time ? one_time : one_forge_time %>
#&nbsp;<%=time_from_now !commit_time.nil? && format_time(commit_time) > format_time(one_time) ? commit_time : one_time %><%= link_to User.find(first_pro.user_id).show_name, user_activities_path(first_pro.user_id), :class => "newsBlue ml5 mr5"%>更新了项目,最近更新:
</div>
<div class="cl"></div>
<% sort_projects.each_with_index do |pro, i| %>
@ -219,7 +224,8 @@
<% end %>
<% com_time = project.project_score.commit_time %>
<% time=project.updated_on %>
<% time=ForgeActivity.where("project_id=?",project.id).last.updated_at if ForgeActivity.where("project_id=?",project.id).last %>
<% forge_time=ForgeActivity.where("project_id=?",project.id).last.updated_at if ForgeActivity.where("project_id=?",project.id).last %>
<% time= time > forge_time ? time : forge_time %>
<p class="mh18"><span class="captainName" title="<%=(User.find project.user_id).show_name %>"><%=(User.find project.user_id).show_name %></span><span style="vertical-align: top;">(组长)</span></p>
<p class="mh18"><%=time_from_now !com_time.nil? && format_time(com_time) > format_time(time) ? com_time : time %>&nbsp;&nbsp;<%= project.project_score.changeset_num %>提交</p>
<div class="relatePInfo" id="relatePInfo_<%=project.id %>_<%=activity.id %>">

@ -93,8 +93,10 @@
<%# cache (act) do %>
<% case user_activity.act_type.to_s %>
<% when 'BlogComment' %>
<% if !(act.blog.homepage_id and act.id == act.blog.homepage_id) %>
<%= render :partial => 'user_blog', :locals => {:activity => act,:user_activity_id =>user_activity.id} %>
<% end %>
<% end %>
<%# end %>
<% end %>

@ -206,8 +206,12 @@
<% sort_projects = project_sort_update projects %>
<div class="mt10 relatePWrap" id="relatePWrap_<%=homework_common.id %>">
<div class="mr5 fontGrey2">
<% first_pro = project_sort_first(projects).first %>
#&nbsp;<%=time_from_now first_pro.updated_at %><%= link_to User.find(first_pro.user_id).show_name, user_activities_path(first_pro.user_id), :class => "newsBlue ml5 mr5"%>更新了项目,最近更新:
<% first_pro = Project.find sort_projects.first.project_id %>
<% commit_time = first_pro.project_score.commit_time %>
<% one_time = first_pro.updated_on %>
<% one_forge_time=ForgeActivity.where("project_id=?",first_pro.id).last.updated_at if ForgeActivity.where("project_id=?",first_pro.id).last %>
<% one_time= one_time > one_forge_time ? one_time : one_forge_time %>
#&nbsp;<%=time_from_now !commit_time.nil? && format_time(commit_time) > format_time(one_time) ? commit_time : one_time %><%= link_to User.find(first_pro.user_id).show_name, user_activities_path(first_pro.user_id), :class => "newsBlue ml5 mr5"%>更新了项目,最近更新:
</div>
<div class="cl"></div>
<% sort_projects.each_with_index do |pro, i| %>
@ -230,7 +234,8 @@
<% end %>
<% com_time = project.project_score.commit_time %>
<% time=project.updated_on %>
<% time=ForgeActivity.where("project_id=?",project.id).last.updated_at if ForgeActivity.where("project_id=?",project.id).last %>
<% forge_time=ForgeActivity.where("project_id=?",project.id).last.updated_at if ForgeActivity.where("project_id=?",project.id).last %>
<% time= time > forge_time ? time : forge_time %>
<p class="mh18"><span class="captainName" title="<%=(User.find project.user_id).show_name %>"><%=(User.find project.user_id).show_name %></span><span style="vertical-align: top;">(组长)</span></p>
<p class="mh18"><%=time_from_now !com_time.nil? && format_time(com_time) > format_time(time) ? com_time : time %>&nbsp;&nbsp;<%= project.project_score.changeset_num %>提交</p>
<div class="relatePInfo" id="relatePInfo_<%=project.id %>_<%=homework_common.id %>">

@ -28,7 +28,7 @@
<script src="https://dn-demotest.qbox.me/angular.all.min.js"></script>
<!-- <script src="/javascripts/wechat/build/angular.all.min.js"></script> -->
<script src="/javascripts/wechat/build/app.min.js"></script>
<script src="/javascripts/wechat/build/app.min.js?version=20160709-0920"></script>
<!-- <script src="/javascripts/wechat/app.js"></script> -->
<!-- <script src="/javascripts/wechat/others/factory.js"></script> -->
<!-- <script src="/javascripts/wechat/others/filter.js"></script> -->
@ -41,6 +41,7 @@
<!-- <script src="/javascripts/wechat/controllers/login.js"></script> -->
<!-- <script src="/javascripts/wechat/controllers/activity.js"></script> -->
<!-- <script src="/javascripts/wechat/controllers/new_class.js"></script> -->
<!-- <script src="/javascripts/wechat/controllers/edit_class.js"></script> -->
<!-- <script src="/javascripts/wechat/controllers/blog.js"></script> -->
<!-- <script src="/javascripts/wechat/controllers/course_notice.js"></script> -->
<!-- <script src="/javascripts/wechat/controllers/discussion.js"></script> -->
@ -50,6 +51,7 @@
<!-- <script src="/javascripts/wechat/controllers/class.js"></script> -->
<!-- <script src="/javascripts/wechat/controllers/class_list.js"></script> -->
<!-- <script src="/javascripts/wechat/controllers/myresource.js"></script> -->
<!-- <script src="/javascripts/wechat/controllers/send_class_list.js"></script> -->
<!-- <script src="/javascripts/wechat/others/routes.js"></script> -->
</body>

@ -2,7 +2,7 @@ button:
-
type: "view"
name: "我的动态"
url: "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx8e1ab05163a28e37&redirect_uri=http://www.trustie.net/wechat/user_activities&response_type=code&scope=snsapi_base&state=123#wechat_redirect"
url: "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx8e1ab05163a28e37&redirect_uri=https://www.trustie.net/wechat/user_activities&response_type=code&scope=snsapi_base&state=123#wechat_redirect"
-
name: "我的课程"
sub_button:

@ -0,0 +1,32 @@
button:
-
type: "view"
name: "我的动态"
url: "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx8e1ab05163a28e37&redirect_uri=http://www.trustie.net/wechat/user_activities&response_type=code&scope=snsapi_base&state=activities#wechat_redirect"
-
name: "我的课程"
sub_button:
-
type: "view"
name: "课程"
url: "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx8e1ab05163a28e37&redirect_uri=http://www.trustie.net/wechat/user_activities&response_type=code&scope=snsapi_base&state=class_list#wechat_redirect"
-
type: "view"
name: "资源"
url: "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx8e1ab05163a28e37&redirect_uri=http://www.trustie.net/wechat/user_activities&response_type=code&scope=snsapi_base&state=myresource#wechat_redirect"
-
name: "更多"
sub_button:
-
type: "click"
name: "加入班级"
key: "JOIN_CLASS"
-
type: "click"
name: "反馈"
key: "FEEDBACK"
-
type: "view"
name: "历史推文"
url: "http://mp.weixin.qq.com/mp/getmasssendmsg?__biz=MzIwOTM2NDkxMA==#wechat_webview_type=1&wechat_redirect"

@ -0,0 +1,35 @@
button:
-
type: "view"
name: "我的动态"
url: "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxc09454f171153c2d&redirect_uri=http://test.forge.trustie.net/wechat/user_activities&response_type=code&scope=snsapi_b
ase&state=activities#wechat_redirect"
-
name: "我的课程"
sub_button:
-
type: "view"
name: "课程"
url: "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxc09454f171153c2d&redirect_uri=http://test.forge.trustie.net/wechat/user_activities&response_type=code&scope=snsapi
_base&state=class_list#wechat_redirect"
-
type: "view"
name: "资源"
url: "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxc09454f171153c2d&redirect_uri=http://test.forge.trustie.net/wechat/user_activities&response_type=code&scope=snsapi
_base&state=myresource#wechat_redirect"
-
name: "更多"
sub_button:
-
type: "click"
name: "加入班级"
key: "JOIN_CLASS"
-
type: "click"
name: "反馈"
key: "FEEDBACK"
-
type: "view"
name: "历史推文"
url: "http://mp.weixin.qq.com/mp/getmasssendmsg?__biz=MzIwOTM2NDkxMA==#wechat_webview_type=1&wechat_redirect"

@ -797,6 +797,7 @@ RedmineApp::Application.routes.draw do
match 'update_jenkins_job'
match 'edit'
match 'create'
get 'error_list'
end
end
# resources :files, :only => [:index, :new, :create] do

@ -2,20 +2,24 @@ default: &default
# corpid: "corpid"
# corpsecret: "corpsecret"
# agentid: 1
# Or if using public account, only need above two line
# guange test
#
#- # guange test
#appid: "wxf694495398c7d470"
#secret: "743e038392f1d89540e95f8f7645849a"
#production
appid: "wx8e1ab05163a28e37"
secret: "beb4d3bc4b32b3557811680835357841"
#test
#appid: "wxc09454f171153c2d"
#secret: "dff5b606e34dcafe24163ec82c2715f8"
token: "123456"
access_token: ".access_token"
access_token: "1234567"
encrypt_mode: false # if true must fill encoding_aes_key
encoding_aes_key: "QGfP13YP4BbQGkkrlYuxpn4ZIDXpBJww4fxl8CObvNw"
jsapi_ticket: "tmp/wechat_jsapi_ticket"
jsapi_ticket: "C:/Users/[user_name]/wechat_jsapi_ticket"
#template
binding_succ_notice: "jjpDrgFErnmkrE9tf2M3o0t31ZrJ7mr0YtuE_wyLaMc"

@ -0,0 +1,33 @@
default: &default
# corpid: "corpid"
# corpsecret: "corpsecret"
# agentid: 1
# Or if using public account, only need above two line
# guange test
#appid: "wxf694495398c7d470"
#secret: "743e038392f1d89540e95f8f7645849a"
appid: "wx8e1ab05163a28e37"
secret: "beb4d3bc4b32b3557811680835357841"
token: "123456"
access_token: ".access_token"
encrypt_mode: false # if true must fill encoding_aes_key
encoding_aes_key: "QGfP13YP4BbQGkkrlYuxpn4ZIDXpBJww4fxl8CObvNw"
jsapi_ticket: "tmp/wechat_jsapi_ticket"
#template
binding_succ_notice: "jjpDrgFErnmkrE9tf2M3o0t31ZrJ7mr0YtuE_wyLaMc"
journal_notice: "uC1zAw4F2q6HTA3Pcj8VUO6wKKKiYFwnPJB4iXxpdoM"
homework_message_notice: "tCf7teCVqc2vl2LZ_hppIdWmpg8yLcrI8XifxYePjps"
class_notice: "MQ_mFupbXP-9jWbeHT3C5xqNBvPo8EIlNv4ULakSpJA"
production:
<<: *default
development:
<<: *default
test:
<<: *default

@ -0,0 +1,11 @@
class CreateSonarErrors < ActiveRecord::Migration
def change
create_table :sonar_errors do |t|
t.integer :project_id
t.string :jenkins_job_name
t.text :output
t.timestamps
end
end
end

@ -0,0 +1,8 @@
class RenewQrcode < ActiveRecord::Migration
def up
Course.update_all(:qrcode => '')
end
def down
end
end

@ -0,0 +1,5 @@
class AddIndexOpenidToWechatLogs < ActiveRecord::Migration
def change
add_index(:wechat_logs, :openid)
end
end

@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20160708005533) do
ActiveRecord::Schema.define(:version => 20160709015740) do
create_table "activities", :force => true do |t|
t.integer "act_id", :null => false
@ -562,9 +562,9 @@ ActiveRecord::Schema.define(:version => 20160708005533) do
t.integer "excellent_option", :default => 0
t.integer "is_copy", :default => 0
t.integer "visits", :default => 0
t.integer "syllabus_id"
t.string "invite_code"
t.string "qrcode"
t.integer "syllabus_id"
end
add_index "courses", ["invite_code"], :name => "index_courses_on_invite_code", :unique => true
@ -1137,23 +1137,6 @@ ActiveRecord::Schema.define(:version => 20160708005533) do
t.integer "viewed_count", :default => 0
end
create_table "mess", :id => false, :force => true do |t|
t.string "课程名"
t.integer "课程ID", :default => 0, :null => false
t.string "教师姓", :default => "", :null => false
t.string "教师名", :limit => 30, :default => "", :null => false
t.string "主贴名", :default => "", :null => false
t.integer "主贴或回帖ID", :default => 0, :null => false
t.integer "回帖对应主贴ID"
t.integer "帖子点赞数"
t.integer "主贴回复数", :default => 0, :null => false
t.text "主贴或回帖内容"
t.datetime "发帖时间", :null => false
t.integer "发帖或回帖用户ID", :default => 0, :null => false
t.string "发帖或回帖用户姓", :default => "", :null => false
t.string "发帖或回帖用户名", :limit => 30, :default => "", :null => false
end
create_table "message_alls", :force => true do |t|
t.integer "user_id"
t.integer "message_id"
@ -1755,6 +1738,14 @@ ActiveRecord::Schema.define(:version => 20160708005533) do
t.integer "project_id"
end
create_table "sonar_errors", :force => true do |t|
t.integer "project_id"
t.string "jenkins_job_name"
t.text "output"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "ssos", :force => true do |t|
t.integer "user_id"
t.string "openid"
@ -2195,6 +2186,8 @@ ActiveRecord::Schema.define(:version => 20160708005533) do
t.datetime "created_at", :null => false
end
add_index "wechat_logs", ["openid"], :name => "index_wechat_logs_on_openid"
create_table "wiki_content_versions", :force => true do |t|
t.integer "wiki_content_id", :null => false
t.integer "page_id", :null => false

@ -75,6 +75,17 @@ class Gitlab::Client
end
alias_method :repo_commits, :commits_total_count
# Gets total project commits.
#
# @example
# @param [Integer] project The ID of a project.
# @param [Hash] options A customizable set of options.
# @option options [String] :rev The branch or tag name of a project repository.
# @return [Hash<Gitlab::ObjectifiedHash>]
def user_static(project, options={})
get("/projects/#{project}/repository/user_static", :query => options)
end
# Gets a specific commit identified by the commit hash or name of a branch or tag.
#
# @example

@ -2,7 +2,11 @@
namespace :update_homework do
desc "update homework project time"
def update_homework_time homeworks
task :update_homework => :environment do
year = Time.now.year
courses = Course.where("time > ? and is_delete = 0", (year.to_i - 2))
course_ids = courses.nil? ? '(-1)' : '(' + courses.map{|c| c.id}.join(',') + ')'
homeworks = HomeworkCommon.where("course_id in #{course_ids} and homework_type = 3")
unless homeworks.nil?
homeworks.each do |h|
if h.homework_type == 3
@ -28,38 +32,34 @@ namespace :update_homework do
time = changesets_latest_coimmit.created_at
end
end
rescue
rescue Exception => e
puts e
end
end
end
end
s_time = time
puts "latest time is =========================> #{time}"
if time.strftime('%Y-%m-%d %H:%M:%S') > h.updated_at.strftime('%Y-%m-%d %H:%M:%S')
h.update_column('updated_at', s_time)
course_activity = CourseActivity.where("course_act_type=? and course_act_id =?", 'HomeworkCommon', h.id).first
if course_activity && (time.strftime('%Y-%m-%d %H:%M:%S') > course_activity.updated_at.strftime('%Y-%m-%d %H:%M:%S'))
course_activity.update_column('updated_at', s_time)
puts "user_activity time is =========================> #{course_activity}"
end
user_activity = UserActivity.where("act_type=? and act_id =?", 'HomeworkCommon', h.id).first
if user_activity && (time.strftime('%Y-%m-%d %H:%M:%S') > user_activity.updated_at.strftime('%Y-%m-%d %H:%M:%S'))
user_activity.update_column('updated_at', s_time)
puts "user_activity time is =========================> #{user_activity}"
end
org_activity = OrgActivity.where("org_act_type=? and org_act_id =?", 'HomeworkCommon', h.id).first
if org_activity && (time.strftime('%Y-%m-%d %H:%M:%S') > org_activity.updated_at.strftime('%Y-%m-%d %H:%M:%S'))
org_activity.update_column('updated_at', s_time)
puts "org_activity time is =========================> #{org_activity}"
end
end
end
end
end
end
task :update_homework => :environment do
year = Time.now.year
courses = Course.where("time > ? and is_delete = 0", (year.to_i - 2))
course_ids = courses.nil? ? '(-1)' : '(' + courses.map{|c| c.id}.join(',') + ')'
homeworks = HomeworkCommon.where("course_id in #{course_ids} and homework_type = 3")
unless homeworks.nil?
update_homework_time homeworks
end
end
end

@ -2,43 +2,56 @@
<!-- 模板1开始可以使用scripttype设置为text/html来存放模板片段并且用id标示 -->
<div loading-spinner></div>
<div class="class-detail-name">我的动态</div>
<!--<div class="tab-wrap">-->
<!--<a id="class_tab_1" href="javascript:void(0);" class="weixin-tab class-tab-active" ng-click="HoverLi(1)">所有动态<span id="tab_arrow_1" class="tab-active-arrow"></span></a>-->
<!--<a id="class_tab_2" href="javascript:void(0);" class="weixin-tab" ng-click="HoverLi(2)">课程动态<span id="tab_arrow_2" class="tab-active-arrow undis"></span></a>-->
<!--<a id="class_tab_3" href="javascript:void(0);" class="weixin-tab" ng-click="HoverLi(3)">项目动态<span id="tab_arrow_3" class="tab-active-arrow undis"></span></a>-->
<!--</div>-->
<div class="tab-wrap">
<a ng-click="tab($index+1)" ng-repeat="menu in menus" id="class_tab_1" href="javascript:void(0);" ng-class="['weixin-tab', {'class-tab-active': currentTab == $index+1}]">{{menu}}</a>
</div>
<div ng-class="{'undis': currentTab!=1}">
<div ng-repeat="act in activities">
<div ng-if="act.container_type=='Course' ">
<div ng-if="act.act_type=='HomeworkCommon'">
<div class="post-container">
<div class="post-wrapper">
<div class="post-main">
<div class="mb5" dataID = "{{act.act_id}}" ng-click="goDetail('homework',act.act_id, act.id)" id="act_{{act.id}}">
<div class="post-avatar fl"><img ng-src="{{replaceUrl(act.author.img_url)}}" width="40" height="40" class="border-radius" /></div>
<div class="post-title hidden mb5">
<a herf="javascript:void(0);">
<div dataID = "{{act.act_id}}" ng-click="goDetail('homework',act.act_id, act.id)" id="act_{{act.id}}">
<div class="post-avatar fl mr10"><img ng-src="{{replaceUrl(act.author.img_url)}}" width="30" height="30" class="border-radius img-circle" /></div>
<div class="post-dynamic-author hidden fl">
<span ng-if="act.author.realname != ' '">{{act.author.realname}}</span>
<span ng-if="act.author.realname == ' '">{{act.author.nickname}}</span>
</a></div>
<div class="post-title hidden">
<a herf="javascript:void(0);" class="f12 c-grey2">{{act.course_project_name}}</a></div>
<img ng-if="act.author.gender == '0'" src="images/wechat/male.png" width="14" class="ml5" />
<img ng-if="act.author.gender != '0'" src="images/wechat/female.png" width="14" class="ml5" />
</div>
<div class="post-dynamic-time fr f13">{{act.latest_update}}</div>
<div class="cl"></div>
<div class="post-title mt5 mb5 hidden"><span class="c-grey3 f15 fb">{{act.subject|safeHtml}}</span></div>
<div class="post-content c-grey3">
<div class="post-dynamic-title c-grey3 hidden mt12 fb">【作业】{{act.subject|safeHtml}}</div>
<div class="post-content c-grey3 mt10 mb10">
<div class="post-all-content" ng-bind-html="act.description|safeHtml"></div>
<span class="mr15 f13 c-grey2">迟交扣分:{{act.homework_common_detail.late_penalty}}分</span> <span ng-if="!act.homework_common_detail.anonymous_comment" class="f13 c-grey2">匿评开启时间:{{act.homework_common_detail.evaluation_start}}</span><br />
<span ng-if="!act.homework_common_detail.anonymous_comment" class="mr15 f13 c-grey2">缺评扣分:{{act.homework_common_detail.absence_penalty}}分/作品</span> <span ng-if="!act.homework_common_detail.anonymous_comment" class="f13 c-grey2">匿评关闭时间:{{act.homework_common_detail.evaluation_end}}</span>
</div>
<!--<a herf="javascript:void(0);" class="c-grey2 f13 fr mt5 mb10 post-more mr20 undis" text-auto-height>点击展开</a>-->
<div class="cl"></div>
</div>
<div class="post-op-banner">
<span ng-if="act.homework_common_detail.homework_type == 1" class="c-grey f12 fl mr15">普通作业</span>
<span ng-if="act.homework_common_detail.homework_type == 2" class="c-grey f12 fl mr15">编程作业</span>
<span ng-if="act.homework_common_detail.homework_type == 3" class="c-grey f12 fl mr15">分组作业</span>
<span class="c-grey f12 fl">{{act.latest_update}}</span>
<a ng-if="!act.reply_count" ng-click="goDetail('homework',act.act_id, act.id)" class="c-grey2 fr f12"><img src="/images/wechat/w_reply.png" height="15" class="mr5 mt3" /><span style="vertical-align:top;">回复</span></a>
<a ng-if="act.reply_count" ng-click="goDetail('homework',act.act_id, act.id)" class="c-grey2 fr f12"><img src="/images/wechat/w_reply.png" height="15" class="mr5 mt3" /><span style="vertical-align:top;">{{act.reply_count}}</span></a>
<div class="c-grey fr f12 mr25" ng-if="!act.praise_count" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" height="15" class="mr5 mt3" /><span class="num-block"></span></div>
<div class="c-grey fr f12 mr25" ng-if="act.praise_count && !act.has_praise" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" height="15" class="mr5 mt3" /><span class="num-block">{{act.praise_count}}</span></div>
<div class="c-grey fr f12 mr25" ng-if="act.has_praise" ng-click="decreasePraise(act);"><img src="/images/wechat/w_praised.png" height="15" class="mr5 mt3" /><span class="num-block">{{act.praise_count}}</span></div>
<div class="cl"></div>
<div class="post-dynamic-from hidden fl c-grey3">来源: <span class="c-blue">{{act.course_project_name}}</span></div>
<div class="fr f13">
<div ng-if="!act.praise_count" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span></span></div>
<div ng-if="act.praise_count && !act.has_praise" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span>{{act.praise_count}}</span></div>
<div ng-if="act.has_praise" ng-click="decreasePraise(act);"><img src="/images/wechat/w_praised.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span>{{act.praise_count}}</span></div>
</div>
<div class="fr mr25 f13">
<a ng-if="!act.reply_count" ng-click="goDetail('homework',act.act_id, act.id)"><img src="/images/wechat/w_reply.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span style="vertical-align:top;">回复</span></a>
<a ng-if="act.reply_count" ng-click="goDetail('homework',act.act_id, act.id)"><img src="/images/wechat/w_reply.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span style="vertical-align:top;">{{act.reply_count}}</span></a>
</div>
<div class="cl"></div>
</div>
</div>
</div>
@ -48,28 +61,33 @@
<div class="post-container">
<div class="post-wrapper">
<div class="post-main">
<div class="mb5" dataID = "{{act.act_id}}" ng-click="goDetail('course_notice',act.act_id, act.id)" id="act_{{act.id}}">
<div class="post-avatar fl"><img ng-src="{{replaceUrl(act.author.img_url)}}" width="40" height="40" class="border-radius" /></div>
<div class="post-title hidden mb5"><a herf="javascript:void(0);">{{act.author.realname}}</a></div>
<div class="post-title hidden"><a herf="javascript:void(0);" class="f13 c-grey2">{{act.course_project_name}}</a></div>
<div dataID = "{{act.act_id}}" ng-click="goDetail('course_notice',act.act_id, act.id)" id="act_{{act.id}}">
<div class="post-avatar fl mr10"><img ng-src="{{replaceUrl(act.author.img_url)}}" width="30" height="30" class="border-radius img-circle" /></div>
<div class="post-dynamic-author hidden fl">
<span ng-if="act.author.realname != ' '">{{act.author.realname}}</span>
<span ng-if="act.author.realname == ' '">{{act.author.nickname}}</span>
<img ng-if="act.author.gender == '0'" src="images/wechat/male.png" width="14" class="ml5" />
<img ng-if="act.author.gender != '0'" src="images/wechat/female.png" width="14" class="ml5" />
</div>
<div class="post-dynamic-time fr f13">{{act.latest_update}}</div>
<div class="cl"></div>
<div class="post-title hidden mt5 mb5"><span class="c-grey3 f15 fb">{{act.subject|safeHtml}}</span></div>
<div class="post-content c-grey3">
<div class="post-dynamic-title c-grey3 hidden mt12 fb">【通知】{{act.subject|safeHtml}}</div>
<div class="post-content c-grey3 mt10 mb10">
<div class="post-all-content" ng-bind-html="act.description|safeHtml"></div>
</div>
<!--<a herf="javascript:void(0);" class="c-grey2 f13 fr mt5 mb10 post-more mr20 undis" text-auto-height>点击展开</a>-->
<div class="cl"></div>
</div>
<div class="post-op-banner">
<span class="c-grey f12 fl mr15">{{act.activity_type_name}}</span>
<span class="c-grey f12 fl">{{act.latest_update}}</span>
<a ng-if="!act.reply_count" ng-click="goDetail('course_notice',act.act_id, act.id)" class="c-grey2 fr f12"><img src="/images/wechat/w_reply.png" height="15" class="mr5 mt3" /><span style="vertical-align:top;">回复</span></a>
<a ng-if="act.reply_count" ng-click="goDetail('course_notice',act.act_id, act.id)" class="c-grey2 fr f12"><img src="/images/wechat/w_reply.png" height="15" class="mr5 mt3" /><span style="vertical-align:top;">{{act.reply_count}}</span></a>
<div class="c-grey fr f12 mr25" ng-if="!act.praise_count" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" height="15" class="mr5 mt3" /><span class="num-block"></span></div>
<div class="c-grey fr f12 mr25" ng-if="act.praise_count && !act.has_praise" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" height="15" class="mr5 mt3" /><span class="num-block">{{act.praise_count}}</span></div>
<div class="c-grey fr f12 mr25" ng-if="act.has_praise" ng-click="decreasePraise(act);"><img src="/images/wechat/w_praised.png" height="15" class="mr5 mt3" /><span class="num-block">{{act.praise_count}}</span></div>
<div class="cl"></div>
<div class="post-dynamic-from hidden fl c-grey3">来源: <span class="c-blue">{{act.course_project_name}}</span></div>
<div class="fr f13">
<div ng-if="!act.praise_count" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span></span></div>
<div ng-if="act.praise_count && !act.has_praise" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span>{{act.praise_count}}</span></div>
<div ng-if="act.has_praise" ng-click="decreasePraise(act);"><img src="/images/wechat/w_praised.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span>{{act.praise_count}}</span></div>
</div>
<div class="fr mr25 f13">
<a ng-if="!act.reply_count" ng-click="goDetail('course_notice',act.act_id, act.id)"><img src="/images/wechat/w_reply.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span style="vertical-align:top;">回复</span></a>
<a ng-if="act.reply_count" ng-click="goDetail('course_notice',act.act_id, act.id)"><img src="/images/wechat/w_reply.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span style="vertical-align:top;">{{act.reply_count}}</span></a>
</div>
<div class="cl"></div>
</div>
</div>
</div>
@ -79,28 +97,34 @@
<div class="post-container">
<div class="post-wrapper">
<div class="post-main">
<div class="mb5" dataID = "{{act.act_id}}" ng-click="goDetail('course_discussion',act.act_id, act.id)" id="act_{{act.id}}">
<div class="post-avatar fl"><img ng-src="{{replaceUrl(act.author.img_url)}}" width="40" height="40" class="border-radius" /></div>
<div class="post-title hidden mb5"><a herf="javascript:void(0);" class="mr10">{{act.author.realname}}</a></div>
<div class="post-title hidden"><a herf="javascript:void(0);" class="f12 c-grey2">{{act.course_project_name}}</a></div>
<div dataID = "{{act.act_id}}" ng-click="goDetail('course_discussion',act.act_id, act.id)" id="act_{{act.id}}">
<div class="post-avatar fl mr10"><img ng-src="{{replaceUrl(act.author.img_url)}}" width="30" height="30" class="border-radius img-circle" /></div>
<div class="post-dynamic-author hidden fl">
<span ng-if="act.author.realname != ' '">{{act.author.realname}}</span>
<span ng-if="act.author.realname == ' '">{{act.author.nickname}}</span>
<img ng-if="act.author.gender == '0'" src="images/wechat/male.png" width="14" class="ml5" />
<img ng-if="act.author.gender != '0'" src="images/wechat/female.png" width="14" class="ml5" />
</div>
<div class="post-dynamic-time fr f13">{{act.latest_update}}</div>
<div class="cl"></div>
<div class="post-title hidden mt5 mb5"><span class="c-grey3 f15 fb">{{act.subject|safeHtml}}</span></div>
<div class="post-content c-grey3">
<div class="post-dynamic-title c-grey3 hidden mt12 fb">【帖子】{{act.subject|safeHtml}}</div>
<div class="post-content c-grey3 mt10 mb10">
<div class="post-all-content" ng-bind-html="act.description|safeHtml"></div>
</div>
<!--<a herf="javascript:void(0);" class="c-grey2 f13 fr mt5 mb10 post-more mr20 undis" text-auto-height>点击展开</a>-->
<div class="cl"></div>
</div>
<div class="post-op-banner">
<span class="c-grey f12 fl mr15">{{act.activity_type_name}}</span>
<span class="c-grey f12 fl">{{act.latest_update}}</span>
<a ng-if="!act.reply_count" ng-click="goDetail('course_discussion',act.act_id, act.id)" class="c-grey2 fr f12"><img src="/images/wechat/w_reply.png" height="15" class="mr5 mt3" /><span style="vertical-align:top;">回复</span></a>
<a ng-if="act.reply_count" ng-click="goDetail('course_discussion',act.act_id, act.id)" class="c-grey2 fr f12"><img src="/images/wechat/w_reply.png" height="15" class="mr5 mt3" /><span style="vertical-align:top;">{{act.reply_count}}</span></a>
<div class="c-grey fr f12 mr25" ng-if="!act.praise_count" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" height="15" class="mr5 mt3" /><span class="num-block"></span></div>
<div class="c-grey fr f12 mr25" ng-if="act.praise_count && !act.has_praise" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" height="15" class="mr5 mt3" /><span class="num-block">{{act.praise_count}}</span></div>
<div class="c-grey fr f12 mr25" ng-if="act.has_praise" ng-click="decreasePraise(act);"><img src="/images/wechat/w_praised.png" height="15" class="mr5 mt3" /><span class="num-block">{{act.praise_count}}</span></div>
<div class="cl"></div>
<div class="post-dynamic-from hidden fl c-grey3">来源: <span class="c-blue">{{act.course_project_name}}</span></div>
<div class="fr f13">
<div ng-if="!act.praise_count" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span></span></div>
<div ng-if="act.praise_count && !act.has_praise" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span>{{act.praise_count}}</span></div>
<div ng-if="act.has_praise" ng-click="decreasePraise(act);"><img src="/images/wechat/w_praised.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span>{{act.praise_count}}</span></div>
</div>
<div class="fr mr25 f13">
<a ng-if="!act.reply_count" ng-click="goDetail('course_discussion',act.act_id, act.id)"><img src="/images/wechat/w_reply.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span style="vertical-align:top;">回复</span></a>
<a ng-if="act.reply_count" ng-click="goDetail('course_discussion',act.act_id, act.id)"><img src="/images/wechat/w_reply.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span style="vertical-align:top;">{{act.reply_count}}</span></a>
</div>
<div class="cl"></div>
</div>
</div>
</div>
@ -111,8 +135,8 @@
<div class="post-container">
<div class="post-wrapper">
<div class="post-main">
<div class="post-avatar fl"><img ng-src="{{replaceUrl(act.author.img_url)}}" width="40" height="40" class="border-radius" /></div>
<div class="post-title hidden mb5"><span class="c-grey3 f13 fb mr10">{{act.author.realname}}</span>创建了<span class="c-grey3 f13 fb ml10">{{act.course_project_name}} | 课程</span></div>
<div class="post-avatar fl mr10"><img ng-src="{{replaceUrl(act.author.img_url)}}" width="30" height="30" class="border-radius img-circle" /></div>
<div class="post-title hidden mb5"><span class="c-grey3 f13 fb mr10">{{act.author.realname}}</span>创建了<span class="c-grey3 f13 fb ml10">{{act.course_project_name}} | 班级</span></div>
<div class="post-title hidden"><span class="mr10">{{act.latest_update}}</span></div>
<div class="cl"></div>
</div>
@ -126,30 +150,35 @@
<div class="post-container">
<div class="post-wrapper">
<div class="post-main">
<div class="mb5" dataID = "{{act.act_id}}" ng-click="goDetail('issues',act.act_id, act.id)" id="act_{{act.id}}">
<div class="post-avatar fl"><img ng-src="{{replaceUrl(act.author.img_url)}}" width="40" height="40" class="border-radius" /></div>
<div class="post-title hidden mb5"><a herf="javascript:void(0);">{{act.author.realname}}</a></div>
<div class="post-title hidden"><a herf="javascript:void(0);" class="f12 c-grey2">{{act.course_project_name}}</a></div>
<div dataID = "{{act.act_id}}" ng-click="goDetail('issues',act.act_id, act.id)" id="act_{{act.id}}">
<div class="post-avatar fl mr10"><img ng-src="{{replaceUrl(act.author.img_url)}}" width="30" height="30" class="border-radius img-circle" /></div>
<div class="post-dynamic-author hidden fl">
<span ng-if="act.author.realname != ' '">{{act.author.realname}}</span>
<span ng-if="act.author.realname == ' '">{{act.author.nickname}}</span>
<img ng-if="act.author.gender == '0'" src="images/wechat/male.png" width="14" class="ml5" />
<img ng-if="act.author.gender != '0'" src="images/wechat/female.png" width="14" class="ml5" />
</div>
<div class="post-dynamic-time fr f13">{{act.latest_update}}</div>
<div class="cl"></div>
<div class="post-title hidden mt5 mb5"><span class="c-grey3 f15 fb">{{act.subject|safeHtml}}</span></div>
<div class="post-content c-grey3">
<div class="post-dynamic-title c-grey3 hidden mt12 fb">【帖子】{{act.subject|safeHtml}}</div>
<div class="post-content c-grey3 mt10 mb10">
<div class="post-all-content" ng-bind-html="act.description|safeHtml"></div>
<span class="mr15 f13 c-grey2">状态:{{act.issue_detail.issue_status}}</span> <span class="mr15 f13 c-grey2">优先级:{{act.issue_detail.issue_priority}}</span> <br />
<span class="mr15 f13 c-grey2">指派给:{{act.issue_detail.issue_assigned_to}}</span> <span class="mr15 f13 c-grey2">完成度:{{act.issue_detail.done_ratio}}%</span>
</div>
<!--<a herf="javascript:void(0);" class="c-grey2 f13 fr mt5 mb10 post-more mr20 undis" text-auto-height>点击展开</a>-->
<div class="cl"></div>
</div>
<div class="post-op-banner">
<span class="c-grey f12 fl mr15">{{act.activity_type_name}}</span>
<span class="c-grey f12 fl">{{act.latest_update}}</span>
<a ng-if="!act.reply_count" ng-click="goDetail('issues',act.act_id, act.id)" class="c-grey2 fr f12"><img src="/images/wechat/w_reply.png" height="15" class="mr5 mt3" /><span style="vertical-align:top;">回复</span></a>
<a ng-if="act.reply_count" ng-click="goDetail('issues',act.act_id, act.id)" class="c-grey2 fr f12"><img src="/images/wechat/w_reply.png" height="15" class="mr5 mt3" /><span style="vertical-align:top;">{{act.reply_count}}</span></a>
<div class="c-grey fr f12 mr25" ng-if="!act.praise_count" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" height="15" class="mr5 mt3" /><span class="num-block"></span></div>
<div class="c-grey fr f12 mr25" ng-if="act.praise_count && !act.has_praise" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" height="15" class="mr5 mt3" /><span class="num-block">{{act.praise_count}}</span></div>
<div class="c-grey fr f12 mr25" ng-if="act.has_praise" ng-click="decreasePraise(act);"><img src="/images/wechat/w_praised.png" height="15" class="mr5 mt3" /><span class="num-block">{{act.praise_count}}</span></div>
<div class="cl"></div>
<div class="post-dynamic-from hidden fl c-grey3">来源: <span class="c-blue">{{act.course_project_name}}</span></div>
<div class="fr f13">
<div ng-if="!act.praise_count" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span></span></div>
<div ng-if="act.praise_count && !act.has_praise" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span>{{act.praise_count}}</span></div>
<div ng-if="act.has_praise" ng-click="decreasePraise(act);"><img src="/images/wechat/w_praised.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span>{{act.praise_count}}</span></div>
</div>
<div class="fr mr25 f13">
<a ng-if="!act.reply_count" ng-click="goDetail('issues',act.act_id, act.id)"><img src="/images/wechat/w_reply.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span style="vertical-align:top;">回复</span></a>
<a ng-if="act.reply_count" ng-click="goDetail('issues',act.act_id, act.id)"><img src="/images/wechat/w_reply.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span style="vertical-align:top;">{{act.reply_count}}</span></a>
</div>
<div class="cl"></div>
</div>
</div>
</div>
@ -160,28 +189,33 @@
<div class="post-container">
<div class="post-wrapper">
<div class="post-main">
<div class="mb5" dataID = "{{act.act_id}}" ng-click="goDetail('project_discussion',act.act_id, act.id)" id="act_{{act.id}}">
<div class="post-avatar fl"><img ng-src="{{replaceUrl(act.author.img_url)}}" width="40" height="40" class="border-radius" /></div>
<div class="post-title hidden mb5"><a herf="javascript:void(0);">{{act.author.realname}}</a></div>
<div class="post-title hidden"><a herf="javascript:void(0);" class="f12 c-grey2">{{act.course_project_name}}</a></div>
<div dataID = "{{act.act_id}}" ng-click="goDetail('project_discussion',act.act_id, act.id)" id="act_{{act.id}}">
<div class="post-avatar fl mr10"><img ng-src="{{replaceUrl(act.author.img_url)}}" width="30" height="30" class="border-radius img-circle" /></div>
<div class="post-dynamic-author hidden fl">
<span ng-if="act.author.realname != ' '">{{act.author.realname}}</span>
<span ng-if="act.author.realname == ' '">{{act.author.nickname}}</span>
<img ng-if="act.author.gender == '0'" src="images/wechat/male.png" width="14" class="ml5" />
<img ng-if="act.author.gender != '0'" src="images/wechat/female.png" width="14" class="ml5" />
</div>
<div class="post-dynamic-time fr f13">{{act.latest_update}}</div>
<div class="cl"></div>
<div class="post-title hidden mt5 mb5"><span class="c-grey3 f15 fb">{{act.subject|safeHtml}}</span></div>
<div class="post-content c-grey3">
<div class="post-dynamic-title c-grey3 hidden mt12 fb">【帖子】{{act.subject|safeHtml}}</div>
<div class="post-content c-grey3 mt10 mb10">
<div class="post-all-content" ng-bind-html="act.description|safeHtml"></div>
</div>
<!--<a herf="javascript:void(0);" class="c-grey2 f13 fr mt5 mb10 post-more mr20 undis" text-auto-height>点击展开</a>-->
<div class="cl"></div>
</div>
<div class="post-op-banner">
<span class="c-grey f12 fl mr15">{{act.activity_type_name}}</span>
<span class="c-grey f12 fl">{{act.latest_update}}</span>
<a ng-if="!act.reply_count" ng-click="goDetail('project_discussion',act.act_id, act.id)" class="c-grey2 fr f12"><img src="/images/wechat/w_reply.png" height="15" class="mr5 mt3" /><span style="vertical-align:top;">回复</span></a>
<a ng-if="act.reply_count" ng-click="goDetail('project_discussion',act.act_id, act.id)" class="c-grey2 fr f12"><img src="/images/wechat/w_reply.png" height="15" class="mr5 mt3" /><span style="vertical-align:top;">{{act.reply_count}}</span></a>
<div class="c-grey fr f12 mr25" ng-if="!act.praise_count" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" height="15" class="mr5 mt3" /><span class="num-block"></span></div>
<div class="c-grey fr f12 mr25" ng-if="act.praise_count && !act.has_praise" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" height="15" class="mr5 mt3" /><span class="num-block">{{act.praise_count}}</span></div>
<div class="c-grey fr f12 mr25" ng-if="act.has_praise" ng-click="decreasePraise(act);"><img src="/images/wechat/w_praised.png" height="15" class="mr5 mt3" /><span class="num-block">{{act.praise_count}}</span></div>
<div class="cl"></div>
<div class="post-dynamic-from hidden fl c-grey3">来源: <span class="c-blue">{{act.course_project_name}}</span></div>
<div class="fr f13">
<div ng-if="!act.praise_count" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span></span></div>
<div ng-if="act.praise_count && !act.has_praise" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span>{{act.praise_count}}</span></div>
<div ng-if="act.has_praise" ng-click="decreasePraise(act);"><img src="/images/wechat/w_praised.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span>{{act.praise_count}}</span></div>
</div>
<div class="fr mr25 f13">
<a ng-if="!act.reply_count" ng-click="goDetail('project_discussion',act.act_id, act.id)"><img src="/images/wechat/w_reply.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span style="vertical-align:top;">回复</span></a>
<a ng-if="act.reply_count" ng-click="goDetail('project_discussion',act.act_id, act.id)"><img src="/images/wechat/w_reply.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span style="vertical-align:top;">{{act.reply_count}}</span></a>
</div>
<div class="cl"></div>
</div>
</div>
</div>
@ -191,7 +225,7 @@
<div class="post-container">
<div class="post-wrapper">
<div class="post-main">
<div class="post-avatar fl"><img ng-src="{{replaceUrl(act.author.img_url)}}" width="40" height="40" class="border-radius" /></div>
<div class="post-avatar fl mr10"><img ng-src="{{replaceUrl(act.author.img_url)}}" width="30" height="30" class="border-radius img-circle" /></div>
<div class="post-title hidden mb5"><span class="c-grey3 f13 fb mr10">{{act.author.realname}}</span>创建了<span class="c-grey3 f13 fb ml10">{{act.course_project_name}} | 项目</span></div>
<div class="post-title hidden"><span class="mr10">{{act.latest_update}}</span></div>
<div class="cl"></div>
@ -206,68 +240,313 @@
<div class="post-container">
<div class="post-wrapper">
<div class="post-main">
<div class="mb5" dataID = "{{act.act_id}}" ng-click="goDetail('journal_for_message',act.act_id, act.id)" id="act_{{act.id}}">
<div class="post-avatar fl"><img ng-src="{{replaceUrl(act.author.img_url)}}" width="40" height="40" class="border-radius" /></div>
<div class="post-title mb5 hidden"><a herf="javascript:void(0);" class="mr10">{{act.author.realname}}</a></div>
<div class="post-title hidden"><span class="f12 c-grey">留言</span></div>
<div dataID = "{{act.act_id}}" ng-click="goDetail('journal_for_message',act.act_id, act.id)" id="act_{{act.id}}">
<div class="post-avatar fl mr10"><img ng-src="{{replaceUrl(act.author.img_url)}}" width="30" height="30" class="border-radius img-circle" /></div>
<div class="post-dynamic-author hidden fl">
<span ng-if="act.author.realname != ' '">{{act.author.realname}}</span>
<span ng-if="act.author.realname == ' '">{{act.author.nickname}}</span>
<img ng-if="act.author.gender == '0'" src="images/wechat/male.png" width="14" class="ml5" />
<img ng-if="act.author.gender != '0'" src="images/wechat/female.png" width="14" class="ml5" />
</div>
<div class="post-dynamic-time fr f13">{{act.latest_update}}</div>
<div class="cl"></div>
<div class="post-content c-grey3 mt10 mb10">
<div class="post-all-content" ng-bind-html="act.description|safeHtml"></div>
</div>
<!--<a herf="javascript:void(0);" class="c-grey2 f13 fr mt5 mb10 post-more mr20 undis" text-auto-height>点击展开</a>-->
<div class="cl"></div>
</div>
<div class="post-dynamic-from hidden fl c-grey3">来源: <span class="c-blue">留言</span></div>
<div class="fr f13">
<div ng-if="!act.praise_count" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span></span></div>
<div ng-if="act.praise_count && !act.has_praise" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span>{{act.praise_count}}</span></div>
<div ng-if="act.has_praise" ng-click="decreasePraise(act);"><img src="/images/wechat/w_praised.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span>{{act.praise_count}}</span></div>
</div>
<div class="fr mr25 f13">
<a ng-if="!act.reply_count" ng-click="goDetail('journal_for_message',act.act_id, act.id)"><img src="/images/wechat/w_reply.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span style="vertical-align:top;">回复</span></a>
<a ng-if="act.reply_count" ng-click="goDetail('journal_for_message',act.act_id, act.id)"><img src="/images/wechat/w_reply.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span style="vertical-align:top;">{{act.reply_count}}</span></a>
</div>
<div class="cl"></div>
</div>
</div>
</div>
</div>
</div>
<div ng-if="act.act_type=='BlogComment' ">
<div class="post-container">
<div class="post-wrapper">
<div class="post-main">
<div dataID = "{{act.act_id}}" ng-click="goDetail('blog_comment',act.act_id, act.id)" id="act_{{act.id}}">
<div class="post-avatar fl mr10"><img ng-src="{{replaceUrl(act.author.img_url)}}" width="30" height="30" class="border-radius img-circle" /></div>
<div class="post-dynamic-author hidden fl">
<span ng-if="act.author.realname != ' '">{{act.author.realname}}</span>
<span ng-if="act.author.realname == ' '">{{act.author.nickname}}</span>
<img ng-if="act.author.gender == '0'" src="images/wechat/male.png" width="14" class="ml5" />
<img ng-if="act.author.gender != '0'" src="images/wechat/female.png" width="14" class="ml5" />
</div>
<div class="post-dynamic-time fr f13">{{act.latest_update}}</div>
<div class="cl"></div>
<div class="post-content c-grey3 mt5 mb5">
<div class="post-dynamic-title c-grey3 hidden mt12 fb">【博客】{{act.subject|safeHtml}}</div>
<div class="post-content c-grey3 mt10 mb10">
<div class="post-all-content" ng-bind-html="act.description|safeHtml"></div>
</div>
<!--<a herf="javascript:void(0);" class="c-grey2 f13 fr mt5 mb10 post-more mr20 undis" text-auto-height>点击展开</a>-->
<div class="cl"></div>
</div>
<div class="post-op-banner">
<span class="c-grey f12 fl">{{act.latest_update}}</span>
<a ng-if="!act.reply_count" ng-click="goDetail('journal_for_message',act.act_id, act.id)" class="c-grey2 fr f12"><img src="/images/wechat/w_reply.png" height="15" class="mr5 mt3" /><span style="vertical-align:top;">回复</span></a>
<a ng-if="act.reply_count" ng-click="goDetail('journal_for_message',act.act_id, act.id)" class="c-grey2 fr f12"><img src="/images/wechat/w_reply.png" height="15" class="mr5 mt3" /><span style="vertical-align:top;">{{act.reply_count}}</span></a>
<div class="c-grey fr f12 mr25" ng-if="!act.praise_count" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" height="15" class="mr5 mt3" /><span class="num-block"></span></div>
<div class="c-grey fr f12 mr25" ng-if="act.praise_count && !act.has_praise" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" height="15" class="mr5 mt3" /><span class="num-block">{{act.praise_count}}</span></div>
<div class="c-grey fr f12 mr25" ng-if="act.has_praise" ng-click="decreasePraise(act);"><img src="/images/wechat/w_praised.png" height="15" class="mr5 mt3" /><span class="num-block">{{act.praise_count}}</span></div>
<div class="post-dynamic-from hidden fl c-grey3">来源: <span class="c-blue">博客</span></div>
<div class="fr f13">
<div ng-if="!act.praise_count" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span></span></div>
<div ng-if="act.praise_count && !act.has_praise" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span>{{act.praise_count}}</span></div>
<div ng-if="act.has_praise" ng-click="decreasePraise(act);"><img src="/images/wechat/w_praised.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span>{{act.praise_count}}</span></div>
</div>
<div class="fr mr25 f13">
<a ng-if="!act.reply_count" ng-click="goDetail('blog_comment',act.act_id, act.id)"><img src="/images/wechat/w_reply.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span style="vertical-align:top;">回复</span></a>
<a ng-if="act.reply_count" ng-click="goDetail('blog_comment',act.act_id, act.id)"><img src="/images/wechat/w_reply.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span style="vertical-align:top;">{{act.reply_count}}</span></a>
</div>
<div class="cl"></div>
</div>
</div>
</div>
</div>
</div>
<div ng-if="has_more">
<div id="more_activities" class="more-events mt10" ng-click="loadActData(1,page+1);">更多</div>
</div>
</div>
<div ng-if="act.act_type=='BlogComment'">
<div ng-class="{'undis': currentTab!=2}">
<div ng-repeat="act in course_activities">
<div ng-if="act.container_type=='Course' ">
<div ng-if="act.act_type=='HomeworkCommon'">
<div class="post-container">
<div class="post-wrapper">
<div class="post-main">
<div dataID = "{{act.act_id}}" ng-click="goDetail('homework',act.act_id, act.id)" id="act_{{act.id}}">
<div class="post-avatar fl mr10"><img ng-src="{{replaceUrl(act.author.img_url)}}" width="30" height="30" class="border-radius img-circle" /></div>
<div class="post-dynamic-author hidden fl">
<span ng-if="act.author.realname != ' '">{{act.author.realname}}</span>
<span ng-if="act.author.realname == ' '">{{act.author.nickname}}</span>
<img ng-if="act.author.gender == '0'" src="images/wechat/male.png" width="14" class="ml5" />
<img ng-if="act.author.gender != '0'" src="images/wechat/female.png" width="14" class="ml5" />
</div>
<div class="post-dynamic-time fr f13">{{act.latest_update}}</div>
<div class="cl"></div>
<div class="post-dynamic-title c-grey3 hidden mt12 fb">【作业】{{act.subject|safeHtml}}</div>
<div class="post-content c-grey3 mt10 mb10">
<div class="post-all-content" ng-bind-html="act.description|safeHtml"></div>
<span class="mr15 f13 c-grey2">迟交扣分:{{act.homework_common_detail.late_penalty}}分</span> <span ng-if="!act.homework_common_detail.anonymous_comment" class="f13 c-grey2">匿评开启时间:{{act.homework_common_detail.evaluation_start}}</span><br />
<span ng-if="!act.homework_common_detail.anonymous_comment" class="mr15 f13 c-grey2">缺评扣分:{{act.homework_common_detail.absence_penalty}}分/作品</span> <span ng-if="!act.homework_common_detail.anonymous_comment" class="f13 c-grey2">匿评关闭时间:{{act.homework_common_detail.evaluation_end}}</span>
</div>
<div class="cl"></div>
</div>
<div class="post-dynamic-from hidden fl c-grey3">来源: <span class="c-blue">{{act.course_project_name}}</span></div>
<div class="fr f13">
<div ng-if="!act.praise_count" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span></span></div>
<div ng-if="act.praise_count && !act.has_praise" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span>{{act.praise_count}}</span></div>
<div ng-if="act.has_praise" ng-click="decreasePraise(act);"><img src="/images/wechat/w_praised.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span>{{act.praise_count}}</span></div>
</div>
<div class="fr mr25 f13">
<a ng-if="!act.reply_count" ng-click="goDetail('homework',act.act_id, act.id)"><img src="/images/wechat/w_reply.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span style="vertical-align:top;">回复</span></a>
<a ng-if="act.reply_count" ng-click="goDetail('homework',act.act_id, act.id)"><img src="/images/wechat/w_reply.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span style="vertical-align:top;">{{act.reply_count}}</span></a>
</div>
<div class="cl"></div>
</div>
</div>
</div>
</div>
<div ng-if="act.act_type=='News'">
<div class="post-container">
<div class="post-wrapper">
<div class="post-main">
<div dataID = "{{act.act_id}}" ng-click="goDetail('course_notice',act.act_id, act.id)" id="act_{{act.id}}">
<div class="post-avatar fl mr10"><img ng-src="{{replaceUrl(act.author.img_url)}}" width="30" height="30" class="border-radius img-circle" /></div>
<div class="post-dynamic-author hidden fl">
<span ng-if="act.author.realname != ' '">{{act.author.realname}}</span>
<span ng-if="act.author.realname == ' '">{{act.author.nickname}}</span>
<img ng-if="act.author.gender == '0'" src="images/wechat/male.png" width="14" class="ml5" />
<img ng-if="act.author.gender != '0'" src="images/wechat/female.png" width="14" class="ml5" />
</div>
<div class="post-dynamic-time fr f13">{{act.latest_update}}</div>
<div class="cl"></div>
<div class="post-dynamic-title c-grey3 hidden mt12 fb">【通知】{{act.subject|safeHtml}}</div>
<div class="post-content c-grey3 mt10 mb10">
<div class="post-all-content" ng-bind-html="act.description|safeHtml"></div>
</div>
<div class="cl"></div>
</div>
<div class="post-dynamic-from hidden fl c-grey3">来源: <span class="c-blue">{{act.course_project_name}}</span></div>
<div class="fr f13">
<div ng-if="!act.praise_count" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span></span></div>
<div ng-if="act.praise_count && !act.has_praise" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span>{{act.praise_count}}</span></div>
<div ng-if="act.has_praise" ng-click="decreasePraise(act);"><img src="/images/wechat/w_praised.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span>{{act.praise_count}}</span></div>
</div>
<div class="fr mr25 f13">
<a ng-if="!act.reply_count" ng-click="goDetail('course_notice',act.act_id, act.id)"><img src="/images/wechat/w_reply.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span style="vertical-align:top;">回复</span></a>
<a ng-if="act.reply_count" ng-click="goDetail('course_notice',act.act_id, act.id)"><img src="/images/wechat/w_reply.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span style="vertical-align:top;">{{act.reply_count}}</span></a>
</div>
<div class="cl"></div>
</div>
</div>
</div>
</div>
<div ng-if="act.act_type=='Message'">
<div class="post-container">
<div class="post-wrapper">
<div class="post-main">
<div class="mb5" dataID = "{{act.act_id}}" ng-click="goDetail('blog_comment',act.act_id, act.id)" id="act_{{act.id}}">
<div class="post-avatar fl"><img ng-src="{{replaceUrl(act.author.img_url)}}" width="40" height="40" class="border-radius" /></div>
<div class="post-title hidden mb5"><a herf="javascript:void(0);">{{act.author.realname}}</a></div>
<div class="post-title hidden"><span class="f12 c-grey">博客</span></div>
<div dataID = "{{act.act_id}}" ng-click="goDetail('course_discussion',act.act_id, act.id)" id="act_{{act.id}}">
<div class="post-avatar fl mr10"><img ng-src="{{replaceUrl(act.author.img_url)}}" width="30" height="30" class="border-radius img-circle" /></div>
<div class="post-dynamic-author hidden fl">
<span ng-if="act.author.realname != ' '">{{act.author.realname}}</span>
<span ng-if="act.author.realname == ' '">{{act.author.nickname}}</span>
<img ng-if="act.author.gender == '0'" src="images/wechat/male.png" width="14" class="ml5" />
<img ng-if="act.author.gender != '0'" src="images/wechat/female.png" width="14" class="ml5" />
</div>
<div class="post-dynamic-time fr f13">{{act.latest_update}}</div>
<div class="cl"></div>
<div class="post-title hidden mt5 mb5"><span class="c-grey3 f15 fb">{{act.subject|safeHtml}}</span></div>
<div class="post-content c-grey3">
<div class="post-dynamic-title c-grey3 hidden mt12 fb">【帖子】{{act.subject|safeHtml}}</div>
<div class="post-content c-grey3 mt10 mb10">
<div class="post-all-content" ng-bind-html="act.description|safeHtml"></div>
</div>
<!--<a herf="javascript:void(0);" class="c-grey2 f13 fr mt5 mb10 post-more mr20 undis" text-auto-height>点击展开</a>-->
<div class="cl"></div>
</div>
<div class="post-op-banner">
<span class="c-grey f12 fl">{{act.latest_update}}</span>
<a ng-if="!act.reply_count" ng-click="goDetail('blog_comment',act.act_id, act.id)" class="c-grey2 fr f12"><img src="/images/wechat/w_reply.png" height="15" class="mr5 mt3" /><span style="vertical-align:top;">回复</span></a>
<a ng-if="act.reply_count" ng-click="goDetail('blog_comment',act.act_id, act.id)" class="c-grey2 fr f12"><img src="/images/wechat/w_reply.png" height="15" class="mr5 mt3" /><span style="vertical-align:top;">{{act.reply_count}}</span></a>
<div class="c-grey fr f12 mr25" ng-if="!act.praise_count" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" height="15" class="mr5 mt3" /><span class="num-block"></span></div>
<div class="c-grey fr f12 mr25" ng-if="act.praise_count && !act.has_praise" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" height="15" class="mr5 mt3" /><span class="num-block">{{act.praise_count}}</span></div>
<div class="c-grey fr f12 mr25" ng-if="act.has_praise" ng-click="decreasePraise(act);"><img src="/images/wechat/w_praised.png" height="15" class="mr5 mt3" /><span class="num-block">{{act.praise_count}}</span></div>
<div class="post-dynamic-from hidden fl c-grey3">来源: <span class="c-blue">{{act.course_project_name}}</span></div>
<div class="fr f13">
<div ng-if="!act.praise_count" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span></span></div>
<div ng-if="act.praise_count && !act.has_praise" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span>{{act.praise_count}}</span></div>
<div ng-if="act.has_praise" ng-click="decreasePraise(act);"><img src="/images/wechat/w_praised.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span>{{act.praise_count}}</span></div>
</div>
<div class="fr mr25 f13">
<a ng-if="!act.reply_count" ng-click="goDetail('course_discussion',act.act_id, act.id)"><img src="/images/wechat/w_reply.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span style="vertical-align:top;">回复</span></a>
<a ng-if="act.reply_count" ng-click="goDetail('course_discussion',act.act_id, act.id)"><img src="/images/wechat/w_reply.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span style="vertical-align:top;">{{act.reply_count}}</span></a>
</div>
<div class="cl"></div>
</div>
</div>
</div>
</div>
<div ng-if="act.act_type=='Course'">
<div class="post-container">
<div class="post-wrapper">
<div class="post-main">
<div class="post-avatar fl mr10"><img ng-src="{{replaceUrl(act.author.img_url)}}" width="30" height="30" class="border-radius img-circle" /></div>
<div class="post-title hidden mb5"><span class="c-grey3 f13 fb mr10">{{act.author.realname}}</span>创建了<span class="c-grey3 f13 fb ml10">{{act.course_project_name}} | 课程</span></div>
<div class="post-title hidden"><span class="mr10">{{act.latest_update}}</span></div>
<div class="cl"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<div ng-if="course_has_more">
<div id="more_course_activities" class="more-events mt10" ng-click="loadActData(2,course_page+1);">更多</div>
</div>
</div>
<div ng-class="{'undis': currentTab!=3}">
<div ng-repeat="act in project_activities">
<div ng-if="act.container_type=='Project' ">
<div ng-if="act.act_type=='Issue'">
<div class="post-container">
<div class="post-wrapper">
<div class="post-main">
<div dataID = "{{act.act_id}}" ng-click="goDetail('issues',act.act_id, act.id)" id="act_{{act.id}}">
<div class="post-avatar fl mr10"><img ng-src="{{replaceUrl(act.author.img_url)}}" width="30" height="30" class="border-radius img-circle" /></div>
<div class="post-dynamic-author hidden fl">
<span ng-if="act.author.realname != ' '">{{act.author.realname}}</span>
<span ng-if="act.author.realname == ' '">{{act.author.nickname}}</span>
<img ng-if="act.author.gender == '0'" src="images/wechat/male.png" width="14" class="ml5" />
<img ng-if="act.author.gender != '0'" src="images/wechat/female.png" width="14" class="ml5" />
</div>
<div class="post-dynamic-time fr f13">{{act.latest_update}}</div>
<div class="cl"></div>
<div class="post-dynamic-title c-grey3 hidden mt12 fb">【帖子】{{act.subject|safeHtml}}</div>
<div class="post-content c-grey3 mt10 mb10">
<div class="post-all-content" ng-bind-html="act.description|safeHtml"></div>
<span class="mr15 f13 c-grey2">状态:{{act.issue_detail.issue_status}}</span> <span class="mr15 f13 c-grey2">优先级:{{act.issue_detail.issue_priority}}</span> <br />
<span class="mr15 f13 c-grey2">指派给:{{act.issue_detail.issue_assigned_to}}</span> <span class="mr15 f13 c-grey2">完成度:{{act.issue_detail.done_ratio}}%</span>
</div>
<div class="cl"></div>
</div>
<div class="post-dynamic-from hidden fl c-grey3">来源: <span class="c-blue">{{act.course_project_name}}</span></div>
<div class="fr f13">
<div ng-if="!act.praise_count" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span></span></div>
<div ng-if="act.praise_count && !act.has_praise" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span>{{act.praise_count}}</span></div>
<div ng-if="act.has_praise" ng-click="decreasePraise(act);"><img src="/images/wechat/w_praised.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span>{{act.praise_count}}</span></div>
</div>
<div class="fr mr25 f13">
<a ng-if="!act.reply_count" ng-click="goDetail('issues',act.act_id, act.id)"><img src="/images/wechat/w_reply.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span style="vertical-align:top;">回复</span></a>
<a ng-if="act.reply_count" ng-click="goDetail('issues',act.act_id, act.id)"><img src="/images/wechat/w_reply.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span style="vertical-align:top;">{{act.reply_count}}</span></a>
</div>
<div class="cl"></div>
</div>
</div>
</div>
</div>
<div ng-if="act.act_type=='Message'">
<div class="post-container">
<div class="post-wrapper">
<div class="post-main">
<div dataID = "{{act.act_id}}" ng-click="goDetail('project_discussion',act.act_id, act.id)" id="act_{{act.id}}">
<div class="post-avatar fl mr10"><img ng-src="{{replaceUrl(act.author.img_url)}}" width="30" height="30" class="border-radius img-circle" /></div>
<div class="post-dynamic-author hidden fl">
<span ng-if="act.author.realname != ' '">{{act.author.realname}}</span>
<span ng-if="act.author.realname == ' '">{{act.author.nickname}}</span>
<img ng-if="act.author.gender == '0'" src="images/wechat/male.png" width="14" class="ml5" />
<img ng-if="act.author.gender != '0'" src="images/wechat/female.png" width="14" class="ml5" />
</div>
<div class="post-dynamic-time fr f13">{{act.latest_update}}</div>
<div class="cl"></div>
<div class="post-dynamic-title c-grey3 hidden mt12 fb">【帖子】{{act.subject|safeHtml}}</div>
<div class="post-content c-grey3 mt10 mb10">
<div class="post-all-content" ng-bind-html="act.description|safeHtml"></div>
</div>
<div class="cl"></div>
</div>
<div class="post-dynamic-from hidden fl c-grey3">来源: <span class="c-blue">{{act.course_project_name}}</span></div>
<div class="fr f13">
<div ng-if="!act.praise_count" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span></span></div>
<div ng-if="act.praise_count && !act.has_praise" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span>{{act.praise_count}}</span></div>
<div ng-if="act.has_praise" ng-click="decreasePraise(act);"><img src="/images/wechat/w_praised.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span>{{act.praise_count}}</span></div>
</div>
<div class="fr mr25 f13">
<a ng-if="!act.reply_count" ng-click="goDetail('project_discussion',act.act_id, act.id)"><img src="/images/wechat/w_reply.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span style="vertical-align:top;">回复</span></a>
<a ng-if="act.reply_count" ng-click="goDetail('project_discussion',act.act_id, act.id)"><img src="/images/wechat/w_reply.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span style="vertical-align:top;">{{act.reply_count}}</span></a>
</div>
<div class="cl"></div>
</div>
</div>
</div>
</div>
<div ng-if="has_more">
<div id="more_activities" class="more-events mt10" ng-click="loadActData(page+1);">更多</div>
<div ng-if="act.act_type=='Project'">
<div class="post-container">
<div class="post-wrapper">
<div class="post-main">
<div class="post-avatar fl mr10"><img ng-src="{{replaceUrl(act.author.img_url)}}" width="30" height="30" class="border-radius img-circle" /></div>
<div class="post-title hidden mb5"><span class="c-grey3 f13 fb mr10">{{act.author.realname}}</span>创建了<span class="c-grey3 f13 fb ml10">{{act.course_project_name}} | 项目</span></div>
<div class="post-title hidden"><span class="mr10">{{act.latest_update}}</span></div>
<div class="cl"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<div ng-if="project_has_more">
<div id="more_project_activities" class="more-events mt10" ng-click="loadActData(3,project_page+1);">更多</div>
</div>
</div>
<my-alert message="alertService.message" title="alertService.title" visible="alertService.visible"></my-alert>
</div>

@ -3,47 +3,64 @@
<div loading-spinner></div>
<div ng-if="blog.act_type == 'BlogComment'">
<div class="post-container">
<div class="post-wrapper">
<div class="post-wrapper" style="margin-top:0;">
<div class="post-main">
<div class="post-title mb5"><span class="c-grey3 f15 fb">{{blog.title}}</span><img ng-if="blog.locked" src="/images/locked.png" style="display:inline-block;" /></div>
<div class="post-title"><a herf="javascript:void(0);" class="mr10">{{blog.user.realname}}</a>发表博客</div>
<div class="post-avatar fl mr10"><img ng-src="{{blog.user.img_url}}" width="30" height="30" class="border-radius img-circle" /></div>
<div class="post-dynamic-author hidden fl">
{{blog.user.realname}}
<img ng-if="blog.user.gender == '0'" src="images/wechat/male.png" width="14" class="ml5" />
<img ng-if="blog.user.gender != '0'" src="images/wechat/female.png" width="14" class="ml5" />
</div>
<div class="cl"></div>
<div class="post-dynamic-title c-grey3 mt12 fb">{{blog.title}}<img ng-if="blog.locked" src="/images/locked.png" style="display:inline-block;" /></div>
<div class="c-grey4 f13 mt10"><span class="mr10">博客</span><span>{{blog.created_at}}</span></div>
<div class="f13 c-grey3 mt10 text-control" ng-bind-html="blog.content|safeHtml"></div>
<div class="cl"></div>
<span class="c-grey f13 mt10 fl">{{blog.created_at}}</span>
<div class="cl"></div>
<div class="fr f13">
<div ng-if="!blog.praise_count" ng-click="addPraise(blog);"><img src="/images/wechat/w_praise.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span></span></div>
<div ng-if="blog.praise_count && !blog.has_praise" ng-click="addPraise(blog);"><img src="/images/wechat/w_praise.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span>{{blog.praise_count}}</span></div>
<div ng-if="blog.has_praise" ng-click="decreasePraise(blog);"><img src="/images/wechat/w_praised.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span>{{blog.praise_count}}</span></div>
</div>
<div class="post-interactive border-bottom">
<div class="post-interactive-reply c-grey">回复 <span class="reply-num">({{blog.comment_count}})</span></div>
<div class="post-interactive-column c-grey" ng-if="blog.has_praise" ng-click="decreasePraise(blog);">已赞 ({{blog.praise_count}})</div>
<div class="post-interactive-column c-grey" ng-if="!blog.has_praise" ng-click="addPraise(blog);">赞 ({{blog.praise_count}})</div>
<div class="fr mr25 f13">
<a ng-if="!blog.comment_count"><img src="/images/wechat/w_reply.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span style="vertical-align:top;">回复</span></a>
<a ng-if="blog.comment_count"><img src="/images/wechat/w_reply.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span style="vertical-align:top;">{{blog.comment_count}}</span></a>
</div>
<div class="cl"></div>
</div>
<div id="all_blog_reply">
<div class="post-reply-wrap border-bottom" ng-repeat="journal in blog.blog_comment_children">
<div ng-if="blog.blog_comment_children == ''" style="border-top:1px solid #ccc;"></div>
<div class="post-reply-wrap" ng-repeat="journal in blog.blog_comment_children">
<div class="post-reply-row">
<div class="post-reply-avatar fl"><img ng-src="{{journal.user.img_url}}" width="45" height="45" class="border-radius" /></div>
<div class="ml55">
<div class="post-reply-user hidden">{{journal.user.realname}}</div>
<div class="post-reply-content c-grey2 mb10" ng-bind-html="journal.content|safeHtml"></div>
<div class="post-reply-date fl">{{journal.lasted_comment}}</div>
<div class="post-reply-trigger fr undis">回复</div>
<div class="post-avatar fl mr10"><img ng-src="{{journal.user.img_url}}" width="30" height="30" class="border-radius img-circle" /></div>
<div class="post-dynamic-author hidden fl">
{{journal.user.realname}}
<img ng-if="journal.user.gender == '0'" src="images/wechat/male.png" width="14" class="ml5" />
<img ng-if="journal.user.gender != '0'" src="images/wechat/female.png" width="14" class="ml5" />
</div>
<div class="post-dynamic-time fr f13">{{journal.lasted_comment}}</div>
<div class="cl"></div>
<div class="post-reply-content c-grey2 mt12" ng-bind-html="journal.content|safeHtml"></div>
<div class="cl"></div>
</div>
</div>
</div>
<div ng-if="!blog.locked" class="post-input-wrap">
<div ng-if="!blog.locked" id="post_input_1" class="post-input-wrap2">
<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">
<textarea class="copy-input"></textarea>
<textarea input-auto type="text" class="post-reply-input" id="postInput" ng-model="formData.comment" /></textarea>
</div>
<button ng-click="addReply(formData)" ng-disabled="formData.disabled" ng-hide="formData.disabled" class="post-reply-submit fr mt10">回复</button>
<button ng-disabled="formData.disabled" ng-hide="!formData.disabled" class="post-reply-submit bg-grey fr mt10">回复</button>
<textarea input-auto type="text" class="post-reply-input" id="postInput1" ng-model="formData.comment" placeholder="输入回复内容~" /></textarea>
<button ng-click="addReply(formData)" ng-disabled="formData.disabled" ng-hide="formData.disabled" class="post-reply-submit fr border-radius">提交</button>
<button ng-disabled="formData.disabled" ng-hide="!formData.disabled" class="post-reply-submit bg-grey fr border-radius">提交</button>
<div class="cl"></div>
</div>
</div>
</div>
</div>
</div>
</div>

@ -1,18 +1,21 @@
<div class="post-container">
<div loading-spinner></div>
<div class="class-detail-name">{{course.name}}<span ng-click="invite()" class="f13 blue-title-sub">邀请码</span></div>
<div class="slice3 fl"></div>
<div class="tab-wrap">
<a ng-click="tab($index+1)" ng-repeat="menu in menus" id="class_tab_1" href="javascript:void(0);" ng-class="['weixin-tab', {'class-tab-active': currentTab == $index+1}]">{{menu}}</a>
</div>
<!--<div class="slice3 fl"></div>-->
<div ng-repeat="menu in menus">
<div id="class_tab_1" ng-class="[{'class-detail-tab': isTeacher},{'class-detail-tab3': !isTeacher},{'class-tab-active':currentTab==$index+1}]" ng-click="tab($index+1);"><a herf="javascript:void(0);">{{menu}}</a></div>
<div ng-if="!$last" class="slice2 fl">
<div class="slice-line2"></div>
</div>
</div>
<!--<div ng-repeat="menu in menus">-->
<!--<div id="class_tab_1" ng-class="[{'class-detail-tab': isTeacher},{'class-detail-tab3': !isTeacher},{'class-tab-active':currentTab==$index+1}]" ng-click="tab($index+1);"><a herf="javascript:void(0);">{{menu}}</a></div>-->
<!--<div ng-if="!$last" class="slice2 fl">-->
<!--<div class="slice-line2"></div>-->
<!--</div>-->
<!--</div>-->
<div class="slice3 fl"></div>
<div class="cl"></div>
<!--<div class="slice3 fl"></div>-->
<!--<div class="cl"></div>-->
<div class="class-search-wrap">
<div class="class-search-inner"> <img src="/images/wechat/search.png" width="18" class="class-search-icon" />
<input class="class-detail-search" ng-model="searchText" placeholder="输入关键词进行搜索" />
@ -20,8 +23,8 @@
</div>
<div ng-class="{'undis': !showResources}">
<div ng-repeat="r in resources|filter:searchText" ng-class="['class-detail-row', 'f13', 'c-grey3', {'border-top': $first}]"><span class="fl ml10">{{r.filename}}</span><a ng-show="isTeacher" herf="javascript:void(0);" class="fr mr10 link-blue2">发送</a></div>
<p ng-show="resources.length<=0" class="class-test-tip">暂无课件,<br />
<div ng-repeat="r in resources|filter:searchText" ng-class="['class-detail-row', 'f13', 'c-grey3', {'border-top': $first}]"><span class="fl ml10">{{r.filename}}</span><a ng-show="isTeacher" herf="javascript:void(0);" class="fr mr10 link-blue2" ng-click="sendFile(r)">发送</a></div>
<p ng-show="resources_tag == true && resources.length<=0" class="class-test-tip">暂无课件,<br />
请登录Trustie网站,在PC浏览器中上传课件。</p>
</div>
<div ng-class="{'undis': !showClassMate}">
@ -37,15 +40,15 @@
</div>
<div ng-class="{'undis': !showHomework}">
<div ng-repeat="r in homeworks|filter:searchText" ng-class="['class-detail-row', 'f13', 'c-grey3', {'border-top': $first}]"><span class="fl ml10">{{r.homework_name}}</span><a ng-show="isTeacher" herf="javascript:void(0);" class="fr mr10 link-blue2">发送</a></div>
<p ng-show="homeworks.length<=0" class="class-test-tip">暂无作业,<br />
<div ng-repeat="r in homeworks|filter:searchText" ng-class="['class-detail-row', 'f13', 'c-grey3', {'border-top': $first}]"><span class="fl ml10">{{r.homework_name}}</span></div>
<p ng-show="homeworks_tag == true && homeworks.length<=0" class="class-test-tip">暂无作业,<br />
请登录Trustie网站,在PC浏览器中上传作业。</p>
</div>
<div ng-class="{'undis': !showTestcase}">
<div ng-repeat="r in exercises|filter:searchText" ng-class="['class-detail-row', 'f13', 'c-grey3', {'border-top': $first}]"><span class="fl ml10">{{r.exercise_name}}</span><a ng-show="isTeacher" herf="javascript:void(0);" class="fr mr10 link-blue2">发送</a></div>
<p ng-show="exercises.length<=0" class="class-test-tip">暂无小测验,<br />
<div ng-repeat="r in exercises|filter:searchText" ng-class="['class-detail-row', 'f13', 'c-grey3', {'border-top': $first}]"><span class="fl ml10">{{r.exercise_name}}</span></div>
<p ng-show="exercises_tag == true && exercises.length<=0" class="class-test-tip">暂无小测验,<br />
请登录Trustie网站,在PC浏览器中上传小测验。</p>
</div>

@ -1,21 +1,25 @@
<div class="post-container" style="padding-bottom: 50px;">
<div loading-spinner></div>
<div class="blue-title">课程列表</div>
<div class="course-list-row f13 c-grey3 mt10"><img src="/images/wechat/plus.png" width="15" class="fl ml10 mt11 spread-btn" /><img src="/images/wechat/minus.png" width="15" class="fl ml10 mt11 retract-btn undis" /><span class="fl ml10">未命名课程</span><img src="/images/wechat/setting.png" width="15" class="fr mr10 mt10" /></div>
<ul class="class-list f13 c-grey3">
<li ng-click="goClass(course.id)" ng-repeat="course in courses" ng-class="{'border-bottom-none': $last}">
<div ng-repeat="syllabus in syllabuses">
<div ng-click="syllabus.show_plus = !syllabus.show_plus" class="course-list-row f13 c-grey3 mt10"><img src="/images/wechat/plus.png" ng-show="syllabus.show_plus" width="15" class="fl ml10 mt11 spread-btn" /><img src="/images/wechat/minus.png" ng-show="!syllabus.show_plus" width="15" class="fl ml10 mt11 retract-btn " /><span class="fl ml10">{{syllabus.title}}</span><img src="/images/wechat/setting.png" ng-show = "syllabus.can_setting" width="15" class="fr mr10 mt10" ng-click="onSetting(syllabus)" /></div>
<ul ng-show="!syllabus.show_plus" class="class-list f13 c-grey3">
<li ng-show="course.id" ng-click="goClass(course.id)" ng-repeat="course in syllabus.courses" ng-class="{'border-bottom-none': $last}">
<img src="/images/wechat/dot.png" width="15px" class="class-list-dot" />
<span class="fl ml10 class-list-name hidden">{{course.name}}</span>
<span class="fr c-grey4">&gt;</span>
<span class="students-amount f12 fr mt10">{{course.course_student_num}}人</span>
<span class="students-amount f12 fr mt10">{{course.member_count}}人</span>
</li>
</ul>
</div>
<div class="bottom-tab-wrap mt10">
<a ng-click="newClass()" href="javascript:void(0);" class="weixin-tab link-blue2 border-top">新建课程</a>
<a href="javascript:void(0);" class="weixin-tab link-blue2 border-top">加入班级</a>
<a ng-click="joinClass()" class="weixin-tab link-blue2 border-top">加入班级</a>
<a ng-click="goResource()" href="javascript:void(0);" class="weixin-tab link-blue2 border-top">我的资源</a>
</div>
<my-alert message="alertService.message" title="alertService.title" visible="alertService.visible" cb="alertService.cb"></my-alert>
</div>

@ -4,53 +4,59 @@
<div ng-if="discussion.act_type == 'Message'">
<div class="post-container">
<div loading-spinner></div>
<div class="post-wrapper">
<div class="post-wrapper" style="margin-top:0;">
<div class="post-main">
<div class="post-title mb5"><span class="c-grey3 f15 fb">{{discussion.subject}}</span><img ng-if="discussion.locked" src="/images/locked.png" style="display:inline-block;" /></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">&nbsp;&nbsp;&nbsp;源:</td>
<td>{{discussion.course_project_name}}&nbsp;&nbsp;|&nbsp;&nbsp;班级问答区</td>
</tr></table>
<div class="f13 c-grey3 mt10 text-control post-all-content" ng-bind-html="discussion.content|safeHtml"></div>
<div class="post-avatar fl mr10"><img ng-src="{{discussion.user.img_url}}" width="30" height="30" class="border-radius img-circle" /></div>
<div class="post-dynamic-author hidden fl">
{{discussion.user.realname}}
<img ng-if="discussion.user.gender == '0'" src="images/wechat/male.png" width="14" class="ml5" />
<img ng-if="discussion.user.gender != '0'" src="images/wechat/female.png" width="14" class="ml5" />
</div>
<div class="cl"></div>
<span class="c-grey f13 mt10 fl">{{discussion.created_on}}</span>
<div class="post-dynamic-title c-grey3 mt12 fb">{{discussion.subject}}<img ng-if="discussion.locked" src="/images/locked.png" style="display:inline-block;" /></div>
<div class="c-grey4 f13 mt10"><span class="mr10">{{discussion.course_project_name}} - 课程问答区</span><span>{{discussion.created_on}}</span></div>
<div class="f13 c-grey3 mt10 text-control post-all-content" ng-bind-html="discussion.content|safeHtml"></div>
<div class="cl"></div>
<div class="fr f13">
<div ng-if="!discussion.praise_count" ng-click="addPraise(discussion);"><img src="/images/wechat/w_praise.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span></span></div>
<div ng-if="discussion.praise_count && !discussion.has_praise" ng-click="addPraise(discussion);"><img src="/images/wechat/w_praise.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span>{{discussion.praise_count}}</span></div>
<div ng-if="discussion.has_praise" ng-click="decreasePraise(discussion);"><img src="/images/wechat/w_praised.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span>{{discussion.praise_count}}</span></div>
</div>
<div class="post-interactive border-bottom">
<div class="post-interactive-reply c-grey">回复 <span class="reply-num">({{discussion.replies_count}})</span></div>
<div class="post-interactive-column c-grey" ng-if="discussion.has_praise" ng-click="decreasePraise(discussion);">已赞 ({{discussion.praise_count}})</div>
<div class="post-interactive-column c-grey" ng-if="!discussion.has_praise" ng-click="addPraise(discussion);">赞 ({{discussion.praise_count}})</div>
<div class="fr mr25 f13">
<a ng-if="!discussion.replies_count"><img src="/images/wechat/w_reply.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span style="vertical-align:top;">回复</span></a>
<a ng-if="discussion.replies_count"><img src="/images/wechat/w_reply.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span style="vertical-align:top;">{{discussion.replies_count}}</span></a>
</div>
<div class="cl"></div>
</div>
<div id="all_course_message_reply">
<div class="post-reply-wrap border-bottom" ng-repeat="journal in discussion.message_children">
<div ng-if="discussion.message_children == ''" style="border-top:1px solid #ccc;"></div>
<div class="post-reply-wrap" ng-repeat="journal in discussion.message_children">
<div class="post-reply-row">
<div class="post-reply-avatar fl"><img ng-src="{{journal.user.img_url}}" width="45" height="45" class="border-radius" /></div>
<div class="ml55">
<div class="post-reply-user hidden">{{journal.user.realname}}</div>
<div class="post-reply-content c-grey2 mb10" ng-bind-html="journal.content|safeHtml"></div>
<div class="post-reply-date fl">{{journal.lasted_comment}}</div>
<div class="post-reply-trigger fr undis">回复</div>
<div class="post-avatar fl mr10"><img ng-src="{{journal.user.img_url}}" width="30" height="30" class="border-radius img-circle" /></div>
<div class="post-dynamic-author hidden fl">
{{journal.user.realname}}
<img ng-if="journal.user.gender == '0'" src="images/wechat/male.png" width="14" class="ml5" />
<img ng-if="journal.user.gender != '0'" src="images/wechat/female.png" width="14" class="ml5" />
</div>
<div class="post-dynamic-time fr f13">{{journal.lasted_comment}}</div>
<div class="cl"></div>
<div class="post-reply-content c-grey2 mt12" ng-bind-html="journal.content|safeHtml"></div>
<div class="cl"></div>
</div>
</div>
</div>
<div ng-if="!discussion.locked" class="post-input-wrap">
<div ng-if="!discussion.locked" id="post_input_1" class="post-input-wrap2">
<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">
<textarea class="copy-input"></textarea>
<textarea input-auto type="text" class="post-reply-input" id="postInput" ng-model="formData.comment" /></textarea>
</div>
<button ng-click="addReply(formData)" ng-disabled="formData.disabled" ng-hide="formData.disabled" class="post-reply-submit fr mt10">回复</button>
<button ng-disabled="formData.disabled" ng-hide="!formData.disabled" class="post-reply-submit bg-grey fr mt10">回复</button>
<textarea input-auto type="text" class="post-reply-input" id="postInput1" ng-model="formData.comment" placeholder="输入回复内容~" /></textarea>
<button ng-click="addReply(formData)" ng-disabled="formData.disabled" ng-hide="formData.disabled" class="post-reply-submit fr border-radius">提交</button>
<button ng-disabled="formData.disabled" ng-hide="!formData.disabled" class="post-reply-submit bg-grey fr border-radius">提交</button>
<div class="cl"></div>
</div>
</div>
</div>
</div>
</div>
</div>

@ -3,53 +3,59 @@
<div loading-spinner></div>
<div ng-if="news.act_type == 'News'">
<div class="post-container">
<div class="post-wrapper">
<div class="post-wrapper" style="margin-top:0;">
<div class="post-main">
<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">&nbsp;&nbsp;&nbsp;源:</td>
<td>{{news.course_name}}&nbsp;&nbsp;|&nbsp;&nbsp;班级通知</td>
</tr></table>
<div class="f13 c-grey3 mt10 text-control post-all-content" ng-bind-html="news.description|safeHtml"></div>
<div class="post-avatar fl mr10"><img ng-src="{{news.author.img_url}}" width="30" height="30" class="border-radius img-circle" /></div>
<div class="post-dynamic-author hidden fl">
{{news.author.realname}}
<img ng-if="news.author.gender == '0'" src="images/wechat/male.png" width="14" class="ml5" />
<img ng-if="news.author.gender != '0'" src="images/wechat/female.png" width="14" class="ml5" />
</div>
<div class="cl"></div>
<span class="c-grey f13 mt10 fl">{{news.created_on}}</span>
<div class="post-dynamic-title c-grey3 mt12 fb">{{news.title}}</div>
<div class="c-grey4 f13 mt10"><span class="mr10">{{news.course_name}} - 课程通知</span><span>{{news.created_on}}</span></div>
<div class="f13 c-grey3 mt10 text-control post-all-content" ng-bind-html="news.description|safeHtml"></div>
<div class="cl"></div>
<div class="fr f13">
<div ng-if="!news.praise_count" ng-click="addPraise(news);"><img src="/images/wechat/w_praise.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span></span></div>
<div ng-if="news.praise_count && !news.has_praise" ng-click="addPraise(news);"><img src="/images/wechat/w_praise.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span>{{news.praise_count}}</span></div>
<div ng-if="news.has_praise" ng-click="decreasePraise(news);"><img src="/images/wechat/w_praised.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span>{{news.praise_count}}</span></div>
</div>
<div class="post-interactive border-bottom">
<div class="post-interactive-reply c-grey">回复 <span class="reply-num">({{news.comments_count}})</span></div>
<div class="post-interactive-column c-grey" ng-if="news.has_praise" ng-click="decreasePraise(news);">已赞 ({{news.praise_count}})</div>
<div class="post-interactive-column c-grey" ng-if="!news.has_praise" ng-click="addPraise(news);">赞 ({{news.praise_count}})</div>
<div class="fr mr25 f13">
<a ng-if="!news.comments_count"><img src="/images/wechat/w_reply.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span style="vertical-align:top;">回复</span></a>
<a ng-if="news.comments_count"><img src="/images/wechat/w_reply.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span style="vertical-align:top;">{{news.comments_count}}</span></a>
</div>
<div class="cl"></div>
</div>
<div id="all_news_reply">
<div class="post-reply-wrap border-bottom" ng-repeat="comments in news.comments">
<div ng-if="news.comments == ''" style="border-top:1px solid #ccc;"></div>
<div class="post-reply-wrap" ng-repeat="comments in news.comments">
<div class="post-reply-row">
<div class="post-reply-avatar fl"><img ng-src="{{comments.author.img_url}}" width="45" height="45" class="border-radius" /></div>
<div class="ml55">
<div class="post-reply-user hidden">{{comments.author.realname}}</div>
<div class="post-reply-content c-grey2 mb10" ng-bind-html="comments.comments|safeHtml"></div>
<div class="post-reply-date fl">{{comments.created_on}}</div>
<div class="post-reply-trigger fr undis">回复</div>
<div class="post-avatar fl mr10"><img ng-src="{{comments.author.img_url}}" width="30" height="30" class="border-radius img-circle" /></div>
<div class="post-dynamic-author hidden fl">
{{comments.author.realname}}
<img ng-if="comments.author.gender == '0'" src="images/wechat/male.png" width="14" class="ml5" />
<img ng-if="comments.author.gender != '0'" src="images/wechat/female.png" width="14" class="ml5" />
</div>
<div class="post-dynamic-time fr f13">{{comments.created_on}}</div>
<div class="cl"></div>
<div class="post-reply-content c-grey2 mt12" ng-bind-html="comments.comments|safeHtml"></div>
<div class="cl"></div>
</div>
</div>
</div>
<div class="post-input-wrap">
<div id="post_input_1" class="post-input-wrap2">
<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">
<textarea class="copy-input"></textarea>
<textarea input-auto type="text" class="post-reply-input" id="postInput" ng-model="formData.comment" /></textarea>
</div>
<button ng-click="addReply(formData)" ng-disabled="formData.disabled" ng-hide="formData.disabled" class="post-reply-submit fr mt10">回复</button>
<button ng-disabled="formData.disabled" ng-hide="!formData.disabled" class="post-reply-submit bg-grey fr mt10">回复</button>
<textarea input-auto type="text" class="post-reply-input" id="postInput1" ng-model="formData.comment" placeholder="输入回复内容~" /></textarea>
<button ng-click="addReply(formData)" ng-disabled="formData.disabled" ng-hide="formData.disabled" class="post-reply-submit fr border-radius">提交</button>
<button ng-disabled="formData.disabled" ng-hide="!formData.disabled" class="post-reply-submit bg-grey fr border-radius">提交</button>
<div class="cl"></div>
</div>
</div>
</div>
</div>
</div>
</div>

@ -0,0 +1,15 @@
<div class="post-container">
<div loading-spinner></div>
<div class="blue-title">管理课程</div>
<form novalidate name="classForm">
<div class="course-list-row f13 c-grey3 mt30"><span class="fl ml15 c-grey3">课程</span><input class="new-class-input ml25 c-black" ng-model="syllabus.tmptitle" required placeholder="请输入课程名" /></div>
<div class="course-list-row f13 c-grey3 mt10" ng-repeat="course in syllabus.courses" ng-show="course.can_setting"><span class="fl ml15 c-grey3">班级</span><input required class="new-class-input ml25 c-black" ng-model="course.tmpname" placeholder="请输入班级名" /><a ng-click="deleteClass($index)" class="fr mr10 c-grey6 delete-class-link">删除</a></div>
<div class="tac"><a ng-click="addClass()" class="link-blue2 f13 mt15 inline-block add-class-link">+新增班级</a></div>
<a ng-click="newClass(classForm, syllabus)" ng-class="['finish-btn', {'btn-disabled':!classForm.$valid} ]" >完成</a>
</form>
<my-alert message="alertService_1.message" title="alertService_1.title" visible="alertService_1.visible" cb="alertService_1.cb"></my-alert>
<my-alert2 message="alertService_2.message" title="alertService_2.title" visible="alertService_2.visible" cb="alertService_2.cb"></my-alert2>
</div>

@ -3,67 +3,66 @@
<div loading-spinner></div>
<div ng-if="homework.act_type == 'HomeworkCommon'">
<div class="post-container">
<div class="post-wrapper">
<div class="post-wrapper" style="margin-top:0;">
<div class="post-main">
<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">&nbsp;&nbsp;&nbsp;源:</td>
<td>{{homework.course_name}}&nbsp;&nbsp;|&nbsp;&nbsp;课程作业</td>
</tr>
<tr>
<td class="text-nowrap v-top">&nbsp;&nbsp;&nbsp;别:</td>
<td><span ng-if="homework.homework_type == 1">普通作业</span>
<span ng-if="homework.homework_type == 2">编程作业</span>
<span ng-if="homework.homework_type == 3">分组作业</span>
</td>
</tr>
</table>
<div class="post-avatar fl mr10"><img ng-src="{{homework.author.img_url}}" width="30" height="30" class="border-radius img-circle" /></div>
<div class="post-dynamic-author hidden fl">
{{homework.author.realname}}
<img ng-if="homework.author.gender == '0'" src="images/wechat/male.png" width="14" class="ml5" />
<img ng-if="homework.author.gender != '0'" src="images/wechat/female.png" width="14" class="ml5" />
</div>
<div class="cl"></div>
<div class="post-dynamic-title c-grey3 mt12 fb">{{homework.name}}</div>
<div class="c-grey4 f13 mt10"><span class="mr10">{{homework.course_name}} - <span ng-if="homework.homework_type == 1">普通作业</span><span ng-if="homework.homework_type == 2">编程作业</span><span ng-if="homework.homework_type == 3">分组作业</span></span><span>{{homework.publish_time}}</span></div>
<div class="f13 c-grey3 mt10 mb10 text-control post-all-content" ng-bind-html="homework.description|safeHtml"></div>
<span class="c-grey f13">迟交扣分:{{homework.late_penalty}}分</span><br/>
<span ng-if="!homework.anonymous_comment" class="c-grey f13">缺评扣分:{{homework.absence_penalty}}分/作品<br /></span>
<span ng-if="!homework.anonymous_comment" class="c-grey f13">匿评开启时间:{{homework.evaluation_start}}<br /></span>
<span class="c-grey f13 mr15">迟交扣分:{{homework.late_penalty}}分</span>
<span ng-if="!homework.anonymous_comment" class="c-grey f13">缺评扣分:{{homework.absence_penalty}}分/作品</span>
<span ng-if="!homework.anonymous_comment" class="c-grey f13 mr15">匿评开启时间:{{homework.evaluation_start}}</span>
<span ng-if="!homework.anonymous_comment" class="c-grey f13">匿评关闭时间:{{homework.evaluation_end}}</span>
<div class="cl"></div>
<span class="c-grey f13 mt10 fl">{{homework.publish_time}}</span>
<div class="cl"></div>
<div class="fr f13">
<div ng-if="!homework.praise_count" ng-click="addPraise(homework);"><img src="/images/wechat/w_praise.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span></span></div>
<div ng-if="homework.praise_count && !homework.has_praise" ng-click="addPraise(homework);"><img src="/images/wechat/w_praise.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span>{{homework.praise_count}}</span></div>
<div ng-if="homework.has_praise" ng-click="decreasePraise(homework);"><img src="/images/wechat/w_praised.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span>{{homework.praise_count}}</span></div>
</div>
<div class="post-interactive border-bottom">
<div class="post-interactive-reply c-grey">回复 <span class="reply-num">({{homework.whomework_journal_count}})</span></div>
<div class="post-interactive-column c-grey" ng-if="homework.has_praise" ng-click="decreasePraise(homework);">已赞 ({{homework.praise_count}})</div>
<div class="post-interactive-column c-grey" ng-if="!homework.has_praise" ng-click="addPraise(homework);">赞 ({{homework.praise_count}})</div>
<div class="fr mr25 f13">
<a ng-if="!homework.whomework_journal_count"><img src="/images/wechat/w_reply.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span style="vertical-align:top;">回复</span></a>
<a ng-if="homework.whomework_journal_count"><img src="/images/wechat/w_reply.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span style="vertical-align:top;">{{homework.whomework_journal_count}}</span></a>
</div>
<div class="cl"></div>
</div>
<div id="all_homework_reply">
<div class="post-reply-wrap border-bottom" ng-repeat="journal in homework.journals_for_messages">
<div ng-if="homework.journals_for_messages == ''" style="border-top:1px solid #ccc;"></div>
<div class="post-reply-wrap" ng-repeat="journal in homework.journals_for_messages">
<div class="post-reply-row">
<div class="post-reply-avatar fl"><img ng-src="{{journal.user.img_url}}" width="45" height="45" class="border-radius" /></div>
<div class="ml55">
<div class="post-reply-user hidden">{{journal.user.realname}}</div>
<div class="post-reply-content c-grey2 mb10" ng-bind-html="journal.notes|safeHtml"></div>
<div class="post-reply-date fl">{{journal.lasted_comment}}</div>
<div class="post-reply-trigger fr undis">回复</div>
<div class="post-avatar fl mr10"><img ng-src="{{journal.user.img_url}}" width="30" height="30" class="border-radius img-circle" /></div>
<div class="post-dynamic-author hidden fl">
{{journal.user.realname}}
<img ng-if="journal.user.gender == '0'" src="images/wechat/male.png" width="14" class="ml5" />
<img ng-if="journal.user.gender != '0'" src="images/wechat/female.png" width="14" class="ml5" />
</div>
<div class="post-dynamic-time fr f13">{{journal.lasted_comment}}</div>
<div class="cl"></div>
<div class="post-reply-content c-grey2 mt12" ng-bind-html="journal.notes|safeHtml"></div>
<div class="cl"></div>
</div>
</div>
</div>
<div class="post-input-wrap">
<div id="post_input_1" class="post-input-wrap2">
<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">
<textarea class="copy-input"></textarea>
<textarea input-auto type="text" class="post-reply-input" id="postInput" ng-model="formData.comment"></textarea>
</div>
<button ng-click="addReply(formData)" ng-disabled="formData.disabled" ng-hide="formData.disabled" class="post-reply-submit fr mt10">回复</button>
<button ng-disabled="formData.disabled" ng-hide="!formData.disabled" class="post-reply-submit bg-grey fr mt10">回复</button>
<textarea input-auto type="text" class="post-reply-input" id="postInput1" ng-model="formData.comment" placeholder="输入回复内容~" /></textarea>
<button ng-click="addReply(formData)" ng-disabled="formData.disabled" ng-hide="formData.disabled" class="post-reply-submit fr border-radius">提交</button>
<button ng-disabled="formData.disabled" ng-hide="!formData.disabled" class="post-reply-submit bg-grey fr border-radius">提交</button>
<div class="cl"></div>
</div>
</div>
</div>
</div>
</div>
</div>

@ -3,57 +3,66 @@
<div loading-spinner></div>
<div ng-if="issue.act_type == 'Issue'">
<div class="post-container">
<div class="post-wrapper">
<div class="post-wrapper" style="margin-top:0;">
<div class="post-main">
<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">&nbsp;&nbsp;&nbsp;源:</td>
<td>{{issue.project_name}}&nbsp;&nbsp;|&nbsp;&nbsp;项目问题</td>
</tr></table>
<div class="f13 c-grey3 mt10 mb10 text-control post-all-content" ng-bind-html="issue.description|safeHtml"></div>
<span class="c-grey f13">&nbsp;&nbsp;&nbsp;态:{{issue.issue_status}}<br>
优先级:{{issue.issue_priority}}<br />
指派给:{{issue.issue_assigned_to}}<br />
完成度:{{issue.done_ratio}}%</span>
<div class="post-avatar fl mr10"><img ng-src="{{issue.author.img_url}}" width="30" height="30" class="border-radius img-circle" /></div>
<div class="post-dynamic-author hidden fl">
{{issue.author.realname}}
<img ng-if="issue.author.gender == '0'" src="images/wechat/male.png" width="14" class="ml5" />
<img ng-if="issue.author.gender != '0'" src="images/wechat/female.png" width="14" class="ml5" />
</div>
<div class="cl"></div>
<span class="c-grey f13 mt10 fl">{{issue.created_on}}</span>
<div class="post-dynamic-title c-grey3 mt12 fb">{{issue.subject}}</div>
<div class="c-grey4 f13 mt10"><span class="mr10">{{issue.project_name}} - 项目问题</span><span>{{issue.created_on}}</span></div>
<div class="f13 c-grey3 mt10 mb10 text-control post-all-content" ng-bind-html="issue.description|safeHtml"></div>
<span class="c-grey f13 mr15">&nbsp;&nbsp;&nbsp;态:{{issue.issue_status}}</span>
<span class="c-grey f13">优先级:{{issue.issue_priority}}</span><br/>
<span class="c-grey f13 mr15">指派给:{{issue.issue_assigned_to}}</span>
<span class="c-grey f13">完成度:{{issue.done_ratio}}%</span>
<div class="cl"></div>
<div class="fr f13">
<div ng-if="!issue.praise_count" ng-click="addPraise(issue);"><img src="/images/wechat/w_praise.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span></span></div>
<div ng-if="issue.praise_count && !issue.has_praise" ng-click="addPraise(discussion);"><img src="/images/wechat/w_praise.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span>{{issue.praise_count}}</span></div>
<div ng-if="issue.has_praise" ng-click="decreasePraise(issue);"><img src="/images/wechat/w_praised.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span>{{issue.praise_count}}</span></div>
</div>
<div class="fr mr25 f13">
<a ng-if="!issue.journals_count"><img src="/images/wechat/w_reply.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span style="vertical-align:top;">回复</span></a>
<a ng-if="issue.journals_count"><img src="/images/wechat/w_reply.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span style="vertical-align:top;">{{issue.journals_count}}</span></a>
</div>
<div class="post-interactive border-bottom">
<div class="post-interactive-reply c-grey">回复 <span class="reply-num">({{issue.journals_count}})</span></div>
<div class="post-interactive-column c-grey" ng-if="issue.has_praise" ng-click="decreasePraise(issue);">已赞 ({{issue.praise_count}})</div>
<div class="post-interactive-column c-grey" ng-if="!issue.has_praise" ng-click="addPraise(issue);">赞 ({{issue.praise_count}})</div>
<div class="cl"></div>
</div>
<div id="all_issue_reply">
<div class="post-reply-wrap border-bottom" ng-repeat="journal in issue.issue_journals">
<div ng-if="issue.issue_journals == ''" style="border-top:1px solid #ccc;"></div>
<div class="post-reply-wrap" ng-repeat="journal in issue.issue_journals">
<div class="post-reply-row">
<div class="post-reply-avatar fl"><img ng-src="{{journal.user.img_url}}" width="45" height="45" class="border-radius" /></div>
<div class="ml55">
<div class="post-reply-user hidden">{{journal.user.realname}}</div>
<div class="post-reply-content c-grey2 mb10" ng-bind-html="journal.notes|safeHtml"></div>
<div class="post-reply-date fl">{{journal.created_on}}</div>
<div class="post-reply-trigger fr undis">回复</div>
<div class="post-avatar fl mr10"><img ng-src="{{journal.user.img_url}}" width="30" height="30" class="border-radius img-circle" /></div>
<div class="post-dynamic-author hidden fl">
{{journal.user.realname}}
<img ng-if="journal.user.gender == '0'" src="images/wechat/male.png" width="14" class="ml5" />
<img ng-if="journal.user.gender != '0'" src="images/wechat/female.png" width="14" class="ml5" />
</div>
<div class="post-dynamic-time fr f13">{{journal.created_on}}</div>
<div class="cl"></div>
<div class="post-reply-content c-grey2 mt12" ng-bind-html="journal.notes|safeHtml"></div>
<div class="cl"></div>
</div>
</div>
</div>
<div class="post-input-wrap">
<div id="post_input_1" class="post-input-wrap2">
<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">
<textarea class="copy-input"></textarea>
<textarea input-auto type="text" class="post-reply-input" id="postInput" ng-model="formData.comment" /></textarea>
</div>
<button ng-click="addReply(formData)" ng-disabled="formData.disabled" ng-hide="formData.disabled" class="post-reply-submit fr mt10">回复</button>
<button ng-disabled="formData.disabled" ng-hide="!formData.disabled" class="post-reply-submit bg-grey fr mt10">回复</button>
<textarea input-auto type="text" class="post-reply-input" id="postInput1" ng-model="formData.comment" placeholder="输入回复内容~" /></textarea>
<button ng-click="addReply(formData)" ng-disabled="formData.disabled" ng-hide="formData.disabled" class="post-reply-submit fr border-radius">提交</button>
<button ng-disabled="formData.disabled" ng-hide="!formData.disabled" class="post-reply-submit bg-grey fr border-radius">提交</button>
<div class="cl"></div>
</div>
</div>
</div>
</div>
</div>
</div>

@ -2,46 +2,63 @@
<div loading-spinner></div>
<div ng-if="message.act_type == 'JournalsForMessage'">
<div class="post-container">
<div class="post-wrapper">
<div class="post-wrapper" style="margin-top:0;">
<div class="post-main">
<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="post-avatar fl mr10"><img ng-src="{{message.user.img_url}}" width="30" height="30" class="border-radius img-circle" /></div>
<div class="post-dynamic-author hidden fl">
{{message.user.realname}}
<img ng-if="message.user.gender == '0'" src="images/wechat/male.png" width="14" class="ml5" />
<img ng-if="message.user.gender != '0'" src="images/wechat/female.png" width="14" class="ml5" />
</div>
<div class="cl"></div>
<div class="c-grey4 f13 mt10"><span class="mr10">留言</span><span>{{message.created_on}}</span></div>
<div class="f13 c-grey3 mt10 text-control" ng-bind-html="message.notes|safeHtml"></div>
<div class="cl"></div>
<div class="fr f13">
<div ng-if="!message.praise_count" ng-click="addPraise(message);"><img src="/images/wechat/w_praise.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span></span></div>
<div ng-if="message.praise_count && !message.has_praise" ng-click="addPraise(message);"><img src="/images/wechat/w_praise.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span>{{message.praise_count}}</span></div>
<div ng-if="message.has_praise" ng-click="decreasePraise(message);"><img src="/images/wechat/w_praised.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span>{{message.praise_count}}</span></div>
</div>
<div class="post-interactive border-bottom">
<div class="post-interactive-reply c-grey">回复 <span class="reply-num">({{message.reply_count}})</span></div>
<div class="post-interactive-column c-grey" ng-if="message.has_praise" ng-click="decreasePraise(message);">已赞 ({{message.praise_count}})</div>
<div class="post-interactive-column c-grey" ng-if="!message.has_praise" ng-click="addPraise(message);">赞 ({{message.praise_count}})</div>
<div class="fr mr25 f13">
<a ng-if="!message.reply_count"><img src="/images/wechat/w_reply.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span style="vertical-align:top;">回复</span></a>
<a ng-if="message.reply_count"><img src="/images/wechat/w_reply.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span style="vertical-align:top;">{{message.reply_count}}</span></a>
</div>
<div class="cl"></div>
</div>
<div id="all_message_reply">
<div class="post-reply-wrap border-bottom" ng-repeat="journal in message.child_reply">
<div ng-if="message.child_reply == ''" style="border-top:1px solid #ccc;"></div>
<div class="post-reply-wrap" ng-repeat="journal in message.child_reply">
<div class="post-reply-row">
<div class="post-reply-avatar fl"><img ng-src="{{journal.user.img_url}}" width="45" height="45" class="border-radius" /></div>
<div class="ml55">
<div class="post-reply-user hidden">{{journal.user.realname}}</div>
<div class="post-reply-content c-grey2 mb10" ng-bind-html="journal.notes|safeHtml"></div>
<div class="post-reply-date fl">{{journal.lasted_comment}}</div>
<div class="post-reply-trigger fr undis">回复</div>
<div class="post-avatar fl mr10"><img ng-src="{{journal.user.img_url}}" width="30" height="30" class="border-radius img-circle" /></div>
<div class="post-dynamic-author hidden fl">
{{journal.user.realname}}
<img ng-if="journal.user.gender == '0'" src="images/wechat/male.png" width="14" class="ml5" />
<img ng-if="journal.user.gender != '0'" src="images/wechat/female.png" width="14" class="ml5" />
</div>
<div class="post-dynamic-time fr f13">{{journal.lasted_comment}}</div>
<div class="cl"></div>
<div class="post-reply-content c-grey2 mt12" ng-bind-html="journal.notes|safeHtml"></div>
<div class="cl"></div>
</div>
</div>
</div>
<div class="post-input-wrap">
<div id="post_input_1" class="post-input-wrap2">
<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">
<textarea class="copy-input"></textarea>
<textarea input-auto type="text" class="post-reply-input" id="postInput" ng-model="formData.comment" /></textarea>
</div>
<button ng-click="addReply(formData)" ng-hide="formData.disabled" ng-disabled="formData.disabled" class="post-reply-submit fr mt10">回复</button>
<button ng-disabled="formData.disabled" ng-hide="!formData.disabled" class="post-reply-submit bg-grey fr mt10">回复</button>
<textarea input-auto type="text" class="post-reply-input" id="postInput1" ng-model="formData.comment" placeholder="输入回复内容~" /></textarea>
<button ng-click="addReply(formData)" ng-disabled="formData.disabled" ng-hide="formData.disabled" class="post-reply-submit fr border-radius">提交</button>
<button ng-disabled="formData.disabled" ng-hide="!formData.disabled" class="post-reply-submit bg-grey fr border-radius">提交</button>
<div class="cl"></div>
</div>
</div>
</div>
</div>
</div>
</div>

@ -1,26 +1,29 @@
<div class="post-container">
<div loading-spinner></div>
<div class="class-detail-name">我的资源</div>
<div class="tab-wrap">
<a ng-click="tab($index+1)" ng-repeat="menu in menus" id="class_tab_1" href="javascript:void(0);" ng-class="['weixin-tab', {'class-tab-active': currentTab == $index+1}]">{{menu}}</a>
</div>
<div class="class-search-wrap">
<div class="class-search-inner"> <img src="/images/wechat/search.png" width="18" class="class-search-icon" />
<input class="class-detail-search" placeholder="输入关键词进行搜索" />
<input class="class-detail-search" placeholder="输入关键词进行搜索" ng-model="searchText" />
</div>
</div>
<div ng-class="{'undis': currentTab!=1}">
<div ng-repeat="r in resources" ng-class="['class-detail-row', 'f13', 'c-grey3', {'border-top': $first}]"><span class="fl ml10">{{r.filename}}</span><a herf="javascript:void(0);" class="fr mr10 link-blue2">发送</a></div>
<p ng-show="resources.length<=0" class="class-test-tip">暂无课件,<br />
<div ng-repeat="r in resources|filter:{filename:searchText}" ng-class="['class-detail-row', 'f13', 'c-grey3', {'border-top': $first}]"><span class="fl ml10">{{r.filename}}</span><a ng-click="sendFile(r)" class="fr mr10 link-blue2">发送</a></div>
<p ng-show="resources && resources.length<=0" class="class-test-tip">暂无课件,<br />
请登录Trustie网站,在PC浏览器中上传课件。</p>
</div>
<div ng-class="{'undis': currentTab!=2}">
<div ng-repeat="r in homeworks" ng-class="['class-detail-row', 'f13', 'c-grey3', {'border-top': $first}]"><span class="fl ml10">{{r.homework_name}}</span><a herf="javascript:void(0);" class="fr mr10 link-blue2">发送</a></div>
<p ng-show="homeworks.length<=0" class="class-test-tip">暂无作业,<br />
<div ng-repeat="r in homeworks|filter:{homework_name: searchText}" ng-class="['class-detail-row', 'f13', 'c-grey3', {'border-top': $first}]"><span class="fl ml10">{{r.homework_name}}</span></div>
<p ng-show="homeworks && homeworks.length<=0" class="class-test-tip">暂无作业,<br />
请登录Trustie网站,在PC浏览器中创建作业。</p>
</div>
<div ng-class="{'undis': currentTab!=3}">
<div ng-repeat="r in exercise" ng-class="['class-detail-row', 'f13', 'c-grey3', {'border-top': $first}]"><span class="fl ml10">{{r.exercise_name}}</span><a herf="javascript:void(0);" class="fr mr10 link-blue2">发送</a></div>
<p ng-show="exercise.length<=0" class="class-test-tip">暂无测验,<br />
<div ng-repeat="r in exercise|filter:{exercise_name: searchText}" ng-class="['class-detail-row', 'f13', 'c-grey3', {'border-top': $first}]"><span class="fl ml10">{{r.exercise_name}}</span></div>
<p ng-show="exercise && exercise.length<=0" class="class-test-tip">暂无测验,<br />
请登录Trustie网站,在PC浏览器中创建测验。</p>
</div>
</div>

@ -1,7 +1,14 @@
<div class="post-container">
<div loading-spinner></div>
<div class="blue-title">新建课程</div>
<div class="course-list-row f13 c-grey3 mt30"><span class="fl ml15 c-grey3">课程</span><input class="new-class-input ml25" placeholder="请输入课程名" /></div>
<div class="course-list-row f13 c-grey3 mt10"><span class="fl ml15 c-grey3">班级</span><input class="new-class-input ml25" placeholder="请输入班级名" /></div>
<div class="tac"><a herf="javascript:void(0);" class="link-blue2 f13 mt15 inline-block add-class-link">+新增班级</a></div>
<a href="javascript:void(0);" class="finish-btn">完成</a>
<form novalidate name="classForm">
<div class="course-list-row f13 c-grey3 mt30"><span class="fl ml15 c-grey3">课程</span><input class="new-class-input ml25" ng-model="syllabus.title" required placeholder="请输入课程名" /></div>
<div class="course-list-row f13 c-grey3 mt10" ng-repeat="course in syllabus.courses"><span class="fl ml15 c-grey3">班级</span><input required class="new-class-input ml25" ng-model="course.name" placeholder="请输入班级名" /><a ng-click="deleteClass($index)" ng-show="!$first" class="fr mr10 c-grey6 delete-class-link">删除</a></div>
<div class="tac"><a ng-click="addClass()" class="link-blue2 f13 mt15 inline-block add-class-link">+新增班级</a></div>
<a ng-click="newClass(classForm, syllabus)" ng-class="['finish-btn', {'btn-disabled':!classForm.$valid} ]" >完成</a>
</form>
<my-alert message="alertService.message" title="alertService.title" visible="alertService.visible" cb="alertService.cb"></my-alert>
</div>

@ -3,53 +3,60 @@
<div loading-spinner></div>
<div ng-if="discussion.act_type == 'Message'">
<div class="post-container">
<div class="post-wrapper">
<div class="post-wrapper" style="margin-top:0;">
<div class="post-main">
<div class="post-title mb5"><span class="c-grey3 f15 fb">{{discussion.subject}}</span><img ng-if="discussion.locked" src="/images/locked.png" style="display:inline-block;" /></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">&nbsp;&nbsp;&nbsp;源:</td>
<td>{{discussion.course_project_name}}&nbsp;&nbsp;|&nbsp;&nbsp;项目讨论区</td>
</tr></table>
<div class="f13 c-grey3 mt10 text-control post-all-content" ng-bind-html="discussion.content|safeHtml"></div>
<div class="post-avatar fl mr10"><img ng-src="{{discussion.user.img_url}}" width="30" height="30" class="border-radius img-circle" /></div>
<div class="post-dynamic-author hidden fl">
{{discussion.user.realname}}
<img ng-if="discussion.user.gender == '0'" src="images/wechat/male.png" width="14" class="ml5" />
<img ng-if="discussion.user.gender != '0'" src="images/wechat/female.png" width="14" class="ml5" />
</div>
<div class="cl"></div>
<span class="c-grey f13 mt10 fl">{{discussion.created_on}}</span>
<div class="post-dynamic-title c-grey3 mt12 fb">{{discussion.subject}}<img ng-if="discussion.locked" src="/images/locked.png" style="display:inline-block;" /></div>
<div class="c-grey4 f13 mt10"><span class="mr10">{{discussion.course_project_name}} - 项目讨论区</span><span>{{discussion.created_on}}</span></div>
<div class="f13 c-grey3 mt10 text-control post-all-content" ng-bind-html="discussion.content|safeHtml"></div>
<div class="cl"></div>
<div class="fr f13">
<div ng-if="!discussion.praise_count" ng-click="addPraise(discussion);"><img src="/images/wechat/w_praise.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span></span></div>
<div ng-if="discussion.praise_count && !discussion.has_praise" ng-click="addPraise(discussion);"><img src="/images/wechat/w_praise.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span>{{discussion.praise_count}}</span></div>
<div ng-if="discussion.has_praise" ng-click="decreasePraise(discussion);"><img src="/images/wechat/w_praised.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span>{{discussion.praise_count}}</span></div>
</div>
<div class="fr mr25 f13">
<a ng-if="!discussion.replies_count"><img src="/images/wechat/w_reply.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span style="vertical-align:top;">回复</span></a>
<a ng-if="discussion.replies_count"><img src="/images/wechat/w_reply.png" width="20" style="vertical-align:top; margin-top:2px;" class="mr5" /><span style="vertical-align:top;">{{discussion.replies_count}}</span></a>
</div>
<div class="post-interactive border-bottom">
<div class="post-interactive-reply c-grey">回复 <span class="reply-num">({{discussion.replies_count}})</span></div>
<div class="post-interactive-column c-grey" ng-if="discussion.has_praise" ng-click="decreasePraise(discussion);">已赞 ({{discussion.praise_count}})</div>
<div class="post-interactive-column c-grey" ng-if="!discussion.has_praise" ng-click="addPraise(discussion);">赞 ({{discussion.praise_count}})</div>
<div class="cl"></div>
</div>
<div id="all_course_message_reply">
<div class="post-reply-wrap border-bottom" ng-repeat="journal in discussion.message_children">
<div ng-if="discussion.message_children == ''" style="border-top:1px solid #ccc;"></div>
<div class="post-reply-wrap" ng-repeat="journal in discussion.message_children">
<div class="post-reply-row">
<div class="post-reply-avatar fl"><img ng-src="{{journal.user.img_url}}" width="45" height="45" class="border-radius" /></div>
<div class="ml55">
<div class="post-reply-user hidden">{{journal.user.realname}}</div>
<div class="post-reply-content c-grey2 mb10" ng-bind-html="journal.content|safeHtml"></div>
<div class="post-reply-date fl">{{journal.lasted_comment}}</div>
<div class="post-reply-trigger fr undis">回复</div>
<div class="post-avatar fl mr10"><img ng-src="{{journal.user.img_url}}" width="30" height="30" class="border-radius img-circle" /></div>
<div class="post-dynamic-author hidden fl">
{{journal.user.realname}}
<img ng-if="journal.user.gender == '0'" src="images/wechat/male.png" width="14" class="ml5" />
<img ng-if="journal.user.gender != '0'" src="images/wechat/female.png" width="14" class="ml5" />
</div>
<div class="post-dynamic-time fr f13">{{journal.lasted_comment}}</div>
<div class="cl"></div>
<div class="post-reply-content c-grey2 mt12" ng-bind-html="journal.content|safeHtml"></div>
<div class="cl"></div>
</div>
</div>
</div>
<div ng-if="!discussion.locked" class="post-input-wrap">
<div ng-if="!discussion.locked" id="post_input_1" class="post-input-wrap2">
<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">
<textarea class="copy-input"></textarea>
<textarea input-auto type="text" class="post-reply-input" id="postInput" ng-model="formData.comment" /></textarea>
</div>
<button ng-click="addReply(formData)" ng-disabled="formData.disabled" ng-hide="formData.disabled" class="post-reply-submit fr mt10">回复</button>
<button ng-disabled="formData.disabled" ng-hide="!formData.disabled" class="post-reply-submit bg-grey fr mt10">回复</button>
<textarea input-auto type="text" class="post-reply-input" id="postInput1" ng-model="formData.comment" placeholder="输入回复内容~" /></textarea>
<button ng-click="addReply(formData)" ng-disabled="formData.disabled" ng-hide="formData.disabled" class="post-reply-submit fr border-radius">提交</button>
<button ng-disabled="formData.disabled" ng-hide="!formData.disabled" class="post-reply-submit bg-grey fr border-radius">提交</button>
<div class="cl"></div>
</div>
</div>
</div>
</div>
</div>
</div>

@ -1,4 +1,7 @@
<div class="post-container">
<div loading-spinner></div>
<form name="regFrm" novalidate>
<div class="blue-title">注册<span class="f13 blue-title-sub" ng-click="goLogin()">登录</span></div>
<img src="/images/wechat/male.jpg" width="60" class="img-circle mt15 block-center"/>
@ -41,3 +44,4 @@
</div>
<my-alert message="errDialog.message" title="errDialog.title" visible="errDialog.visible"></my-alert>
<my-alert message="successDialog.message" title="successDialog.title" visible="successDialog.visible" cb="successDialog.cb"></my-alert>

@ -0,0 +1,24 @@
<div class="post-container">
<div loading-spinner></div>
<div class="blue-title">发送课程列表</div>
<div ng-show="syllabus.can_setting" ng-repeat="syllabus in syllabuses">
<div ng-click="syllabus.show_plus = !syllabus.show_plus" class="course-list-row f13 c-grey3 mt10"><img src="/images/wechat/plus.png" ng-show="syllabus.show_plus" width="15" class="fl ml10 mt11 spread-btn" /><img src="/images/wechat/minus.png" ng-show="!syllabus.show_plus" width="15" class="fl ml10 mt11 retract-btn " /><span class="fl ml10">{{syllabus.title}}</span></div>
<ul ng-show="!syllabus.show_plus" class="class-list f13 c-grey3">
<li ng-show="course.can_setting" ng-click="selectCourse(course)" ng-class="{'border-bottom-none': $last }" ng-repeat="course in syllabus.courses"><img src="/images/wechat/dot.png" width="15px" class="class-list-dot" /><span class="fl ml10 class-list-name hidden">{{course.name}}</span><span ng-class="['login-box', 'fr', 'mr5', 'mt12', {'checked': course.checked}]"></span></li>
</ul>
</div>
<!--<div class="course-list-row f13 c-grey3 mt10"><img src="/images/wechat/plus.png" width="15" class="fl ml10 mt11 spread-btn undis" /><img src="/images/wechat/minus.png" width="15" class="fl ml10 mt11 retract-btn " /><span class="fl ml10">未命名课程</span></div>-->
<!--<ul class="class-list f13 c-grey3">-->
<!--<li ng-click="selectCourse(course)" ng-class="{'border-bottom-none': $last }" ng-repeat="course in courses"><img src="/images/wechat/dot.png" width="15px" class="class-list-dot" /><span class="fl ml10 class-list-name hidden">{{course.name}}</span><span ng-class="['login-box', 'fr', 'mr5', 'mt12', {'checked': course.checked}]"></span></li>-->
<!--</ul>-->
<div class="btn2 bg-blue" ng-click="sendToCourses()">发送</div>
<my-alert message="alertService.message" title="alertService.title" visible="alertService.visible" cb="alertService.cb"></my-alert>
</div>

@ -0,0 +1,11 @@
<div class="weui_dialog_confirm" ng-show="visible">
<div class="weui_mask"></div>
<div class="weui_dialog">
<div class="weui_dialog_hd"><strong class="weui_dialog_title">{{title}}</strong></div>
<div class="weui_dialog_bd">{{message}}</div>
<div class="weui_dialog_ft">
<a class="weui_btn_dialog default" ng-click="dismiss()">取消</a>
<a class="weui_btn_dialog primary" ng-click="confirm()">确定</a>
</div>
</div>
</div>

@ -0,0 +1,21 @@
<!-- loading toast -->
<div id="loadingToast" class="weui_loading_toast" ng-show="activeCalls>0">
<div class="weui_mask_transparent"></div>
<div class="weui_toast">
<div class="weui_loading">
<div class="weui_loading_leaf weui_loading_leaf_0"></div>
<div class="weui_loading_leaf weui_loading_leaf_1"></div>
<div class="weui_loading_leaf weui_loading_leaf_2"></div>
<div class="weui_loading_leaf weui_loading_leaf_3"></div>
<div class="weui_loading_leaf weui_loading_leaf_4"></div>
<div class="weui_loading_leaf weui_loading_leaf_5"></div>
<div class="weui_loading_leaf weui_loading_leaf_6"></div>
<div class="weui_loading_leaf weui_loading_leaf_7"></div>
<div class="weui_loading_leaf weui_loading_leaf_8"></div>
<div class="weui_loading_leaf weui_loading_leaf_9"></div>
<div class="weui_loading_leaf weui_loading_leaf_10"></div>
<div class="weui_loading_leaf weui_loading_leaf_11"></div>
</div>
<p class="weui_toast_content">数据加载中</p>
</div>
</div>

@ -1624,6 +1624,193 @@ function ifDeleteOrgMember(id,name){
pop_up_box(htmlvalue,580,30,50);
}
//省市下拉框
function showcity(province, cityField) {
switch (province) {
case "北京" :
var cityOptions = new Array(
"东城", "西城", "朝阳", "丰台", "石景山", "海淀", "门头沟",
"房山", "通州", "顺义", "昌平", "大兴", "平谷", "怀柔", "密云", "延庆");
break;
case "上海" :
var cityOptions = new Array(
"崇明", "黄浦", "卢湾", "徐汇", "长宁", "静安", "普陀", "闸北", "虹口", "杨浦", "闵行",
"宝山", "嘉定", "浦东", "金山", "松江", "青浦", "南汇", "奉贤");
break;
case "广东" :
var cityOptions = new Array(
"广州", "深圳", "珠海", "东莞", "中山", "佛山", "惠州", "河源", "潮州", "江门", "揭阳", "茂名",
"梅州", "清远", "汕头", "汕尾", "韶关", "顺德", "阳江", "云浮", "湛江", "肇庆");
break;
case "江苏" :
var cityOptions = new Array(
"南京", "常熟", "常州", "海门", "淮安", "江都", "江阴", "昆山", "连云港", "南通",
"启东", "沭阳", "宿迁", "苏州", "太仓", "泰州", "同里", "无锡", "徐州", "盐城",
"扬州", "宜兴", "仪征", "张家港", "镇江", "周庄");
break;
case "重庆" :
var cityOptions = new Array(
"万州", "涪陵", "渝中", "大渡口", "江北", "沙坪坝", "九龙坡", "南岸", "北碚", "万盛",
"双挢", "渝北", "巴南", "黔江", "长寿", "綦江", "潼南", "铜梁", "大足", "荣昌", "壁山",
"梁平", "城口", "丰都", "垫江", "武隆", "忠县", "开县", "云阳", "奉节", "巫山", "巫溪",
"石柱", "秀山", "酉阳", "彭水", "江津", "合川", "永川", "南川");
break;
case "安徽" :
var cityOptions = new Array(
"合肥", "安庆", "蚌埠", "亳州", "巢湖", "滁州", "阜阳", "贵池", "淮北", "淮化", "淮南",
"黄山", "九华山", "六安", "马鞍山", "宿州", "铜陵", "屯溪", "芜湖", "宣城");
break;
case "福建" :
var cityOptions = new Array(
"福州", "厦门", "泉州", "漳州", "龙岩", "南平", "宁德", "莆田", "三明");
break;
case "甘肃" :
var cityOptions = new Array(
"兰州", "白银", "定西", "敦煌", "甘南", "金昌", "酒泉", "临夏", "平凉", "天水",
"武都", "武威", "西峰", "张掖");
break;
case "广西" :
var cityOptions = new Array(
"南宁", "百色", "北海", "桂林", "防城港", "贵港", "河池", "贺州", "柳州", "钦州", "梧州", "玉林");
break;
case "贵州" :
var cityOptions = new Array(
"贵阳", "安顺", "毕节", "都匀", "凯里", "六盘水", "铜仁", "兴义", "玉屏", "遵义");
break;
case "海南" :
var cityOptions = new Array(
"海口", "儋县", "陵水", "琼海", "三亚", "通什", "万宁");
break;
case "河北" :
var cityOptions = new Array(
"石家庄", "保定", "北戴河", "沧州", "承德", "丰润", "邯郸", "衡水", "廊坊", "南戴河", "秦皇岛",
"唐山", "新城", "邢台", "张家口");
break;
case "黑龙江" :
var cityOptions = new Array(
"哈尔滨", "北安", "大庆", "大兴安岭", "鹤岗", "黑河", "佳木斯", "鸡西", "牡丹江", "齐齐哈尔",
"七台河", "双鸭山", "绥化", "伊春");
break;
case "河南" :
var cityOptions = new Array(
"郑州", "安阳", "鹤壁", "潢川", "焦作", "济源", "开封", "漯河", "洛阳", "南阳", "平顶山",
"濮阳", "三门峡", "商丘", "新乡", "信阳", "许昌", "周口", "驻马店");
break;
case "香港" :
var cityOptions = new Array(
"香港", "九龙", "新界");
break;
case "湖北" :
var cityOptions = new Array(
"武汉", "恩施", "鄂州", "黄冈", "黄石", "荆门", "荆州", "潜江", "十堰", "随州", "武穴",
"仙桃", "咸宁", "襄阳", "襄樊", "孝感", "宜昌");
break;
case "湖南" :
var cityOptions = new Array(
"长沙", "常德", "郴州", "衡阳", "怀化", "吉首", "娄底", "邵阳", "湘潭", "益阳", "岳阳",
"永州", "张家界", "株洲");
break;
case "江西" :
var cityOptions = new Array(
"南昌", "抚州", "赣州", "吉安", "景德镇", "井冈山", "九江", "庐山", "萍乡",
"上饶", "新余", "宜春", "鹰潭");
break;
case "吉林" :
var cityOptions = new Array(
"长春", "吉林", "白城", "白山", "珲春", "辽源", "梅河", "四平", "松原", "通化", "延吉");
break;
case "辽宁" :
var cityOptions = new Array(
"沈阳", "鞍山", "本溪", "朝阳", "大连", "丹东", "抚顺", "阜新", "葫芦岛", "锦州",
"辽阳", "盘锦", "铁岭", "营口");
break;
case "澳门" :
var cityOptions = new Array("澳门");
break;
case "内蒙古" :
var cityOptions = new Array(
"呼和浩特", "阿拉善盟", "包头", "赤峰", "东胜", "海拉尔", "集宁", "临河", "通辽", "乌海",
"乌兰浩特", "锡林浩特");
break;
case "宁夏" :
var cityOptions = new Array(
"银川", "固源", "石嘴山", "吴忠");
break;
case "青海" :
var cityOptions = new Array(
"西宁", "德令哈", "格尔木", "共和", "海东", "海晏", "玛沁", "同仁", "玉树");
break;
case "山东" :
var cityOptions = new Array(
"济南", "滨州", "兖州", "德州", "东营", "菏泽", "济宁", "莱芜", "聊城", "临沂",
"蓬莱", "青岛", "曲阜", "日照", "泰安", "潍坊", "威海", "烟台", "枣庄", "淄博");
break;
case "山西" :
var cityOptions = new Array(
"太原", "长治", "大同", "候马", "晋城", "离石", "临汾", "宁武", "朔州", "忻州",
"阳泉", "榆次", "运城");
break;
case "陕西" :
var cityOptions = new Array(
"西安", "安康", "宝鸡", "汉中", "渭南", "商州", "绥德", "铜川", "咸阳", "延安", "榆林");
break;
case "四川" :
var cityOptions = new Array(
"成都", "巴中", "达川", "德阳", "都江堰", "峨眉山", "涪陵", "广安", "广元", "九寨沟",
"康定", "乐山", "泸州", "马尔康", "绵阳", "眉山", "南充", "内江", "攀枝花", "遂宁",
"汶川", "西昌", "雅安", "宜宾", "自贡", "资阳");
break;
case "台湾" :
var cityOptions = new Array(
"台北", "基隆", "台南", "台中", "高雄", "屏东", "南投", "云林", "新竹", "彰化", "苗栗",
"嘉义", "花莲", "桃园", "宜兰", "台东", "金门", "马祖", "澎湖");
break;
case "天津" :
var cityOptions = new Array(
"天津", "和平", "东丽", "河东", "西青", "河西", "津南", "南开", "北辰", "河北", "武清", "红挢",
"塘沽", "汉沽", "大港", "宁河", "静海", "宝坻", "蓟县");
break;
case "新疆" :
var cityOptions = new Array(
"乌鲁木齐", "阿克苏", "阿勒泰", "阿图什", "博乐", "昌吉", "东山", "哈密", "和田", "喀什",
"克拉玛依", "库车", "库尔勒", "奎屯", "石河子", "塔城", "吐鲁番", "伊宁");
break;
case "西藏" :
var cityOptions = new Array(
"拉萨", "阿里", "昌都", "林芝", "那曲", "日喀则", "山南");
break;
case "云南" :
var cityOptions = new Array(
"昆明", "大理", "保山", "楚雄", "大理", "东川", "个旧", "景洪", "开远", "临沧", "丽江",
"六库", "潞西", "曲靖", "思茅", "文山", "西双版纳", "玉溪", "中甸", "昭通");
break;
case "浙江" :
var cityOptions = new Array(
"杭州", "安吉", "慈溪", "定海", "奉化", "海盐", "黄岩", "湖州", "嘉兴", "金华", "临安",
"临海", "丽水", "宁波", "瓯海", "平湖", "千岛湖", "衢州", "江山", "瑞安", "绍兴", "嵊州",
"台州", "温岭", "温州", "余姚", "舟山");
break;
case "海外" :
var cityOptions = new Array(
"美国", "日本", "英国", "法国", "德国", "其他");
break;
default:
var cityOptions = new Array("");
break;
}
cityField.options.length = 0;
for (var i = 0; i < cityOptions.length; i++) {
cityField.options[i] = new Option(cityOptions[i], cityOptions[i]);
/*
if (cityField.options[i].value==city)
{
//alert("here put City ok!");
document.oblogform["city"].selectedIndex = i;
}*/
}
}
function regex_syllabus_name() {
var name = $.trim($("#new_syllabus_name").val());
if(name.length < 2)

File diff suppressed because one or more lines are too long

@ -1,22 +1,24 @@
var app=angular.module("wechat",["ngRoute"]);app.constant("config",{rootPath:"/assets/wechat/",rootUrl:"/",apiUrl:"/api/v1/"}),app.run(["$rootScope","auth","$location","$routeParams",function(t,a,e,r){g_redirect_path&&g_redirect_path.length>1&&(e.path(g_redirect_path),g_redirect_path=null),t.$on("$routeChangeError",function(t,a,r){a&&a.templateUrl&&(a.templateUrl.endsWith("login.html")||a.templateUrl.endsWith("reg.html")||e.path("/login"))}),t.$on("$routeChangeStart",function(t,a,e){})}]);
app.factory("alertService",function(){function t(){this.title=null,this.message=null,this.visible=null,this.cb=null}return t.prototype.showMessage=function(t,e,n){this.message=e,this.title=t,this.visible=!0,this.cb=n},t.prototype.dismiss=function(){this.message=null,this.title=null,this.visible=!1,this.cb&&this.cb()},{create:function(){return new t}}}),app.factory("auth",["$http","$routeParams","$q","session","config",function(t,e,n,o,a){var i=function(){var a=n.defer(),i=c();if(i&&i.length>10)a.resolve(i);else{window.g_code||e.code||o.get("code");t.post("/wechat/get_bind",{}).then(function(t){0!=t.data.status?a.reject(t.data.message):(o.save("token",t.data.token),a.resolve(t.data.token))})["catch"](function(t){a.reject(t)})}return a.promise},c=function(){return o.get("token")};return{get_bind:i,token:c}}]),app.factory("session",function(){return{save:function(t,e){sessionStorage.setItem(t,e)},get:function(t){return sessionStorage.getItem(t)}}}),app.factory("rms",function(){var t={},e=function(e,n){t[e]=n},n=function(e){return t[e]};return{save:e,get:n}}),app.factory("common",["$http","auth","$routeParams",function(t,e,n){var o=function(n,o,a,i){if(a.comment&&!(a.comment.length<=0)){var c=a.comment.replace(/\n/g,"<br/>"),s={type:o,content:c,token:e.token()};a.disabled=!0,t({method:"POST",url:apiUrl+"new_comment/"+n,data:s}).then(function(t){a.disabled=!1,"function"==typeof i&&i()},function(t){})}},a=function(n,o){return t({method:"GET",url:apiUrl+o+"/"+n+"?token="+e.token()})},i=function(n){n.praise_count+=1,n.has_praise=!0,t({method:"POST",url:apiUrl+"praise/"+n.act_id,data:{token:e.token(),type:n.act_type}}).then(function(t){console.log(t.data)},function(t){})},c=function(n){n.praise_count-=1,n.has_praise=!1,t({method:"POST",url:apiUrl+"praise/"+n.act_id,data:{token:e.token(),type:n.act_type}}).then(function(t){console.log(t.data)},function(t){})},s=function(t){t.scope.formData={comment:""};var e=function(e){a(e,t.type).then(function(e){t.loadCallback(e.data)},function(t){})};e(t.id),t.scope.addReply=function(n){console.log(n.comment),o(t.id,t.replyType,n,function(){t.scope.formData={comment:""},e(t.id),"function"==typeof t.replyCallback&&t.replyCallback()})},t.scope.addPraise=i,t.scope.decreasePraise=c};return{init:s,addCommonReply:o,loadCommonData:a,addCommonPraise:i,decreaseCommonPraise:c}}]);
app.filter("safeHtml",["$sce",function(t){return function(n){return t.trustAsHtml(n)}}]),app.filter("identify",function(){return function(t){return"TeachingAsistant"==t?"教辅":""}});
app.controller("ActivityController",["$anchorScroll","$location","$scope","$http","$timeout","auth","rms","common","alertService",function(a,t,e,o,i,c,n,r,s){e.replaceUrl=function(a){return a},e.alertService=s.create(),console.log("ActivityController load"),e.page=n.get("page")||0,e.activities=n.get("activities")||[],e.has_more=n.get("has_more"),e.loadActData=function(a){e.page=a,o({method:"POST",url:apiUrl+"activities",data:{token:c.token(),page:a}}).then(function(a){a.data.page>0?e.activities=e.activities.concat(a.data.data):e.activities=a.data.data,n.save("activities",e.activities),e.has_more=a.data.count+10*a.data.page<a.data.all_count,n.save("has_more",e.has_more),n.save("page",a.data.page),console.log(a.data)},function(a){})},e.activities.length<=0?e.loadActData(0):i(function(){window.scrollTo(0,n.get("yoffset"))}),e.goDetail=function(a,e,o){n.save("yoffset",window.document.body.scrollTop),t.path("/"+a+"/"+e)},e.addPraise=function(a){r.addCommonPraise(a)},e.decreasePraise=function(a){r.decreaseCommonPraise(a)}}]);
app.controller("ActivityController",["$anchorScroll","$location","$scope","$http","$timeout","auth","rms","common","alertService",function(e,a,t,c,o,i,r,s,n){t.replaceUrl=function(e){return e},t.menus=["所有动态","课程动态","项目动态"],t.alertService=n.create(),console.log("ActivityController load"),t.page=r.get("page")||0,t.activities=r.get("activities")||[],t.has_more=r.get("has_more"),t.course_page=r.get("course_page")||0,t.course_activities=r.get("course_activities")||[],t.course_has_more=r.get("course_has_more"),t.project_page=r.get("project_page")||0,t.project_activities=r.get("project_activities")||[],t.project_has_more=r.get("project_has_more"),t.loadActData=function(e,a){switch(container_type="All",e){case 1:container_type="All",t.page=a;break;case 2:container_type="Course",t.course_page=a;break;case 3:container_type="Project",t.project_page=a}c({method:"POST",url:apiUrl+"activities",data:{token:i.token(),page:a,container_type:container_type}}).then(function(e){if(e.data.page>0)switch(e.data.container_type){case"All":t.activities=t.activities.concat(e.data.data);break;case"Course":t.course_activities=t.course_activities.concat(e.data.data);break;case"Project":t.project_activities=t.project_activities.concat(e.data.data);break;case 3:}else switch(e.data.container_type){case"All":t.activities=e.data.data;break;case"Course":t.course_activities=e.data.data;break;case"Project":t.project_activities=e.data.data;break;case 3:}switch(e.data.container_type){case"All":r.save("activities",t.activities),t.has_more=e.data.count+10*e.data.page<e.data.all_count,r.save("has_more",t.has_more),r.save("page",e.data.page);break;case"Course":r.save("course_activities",t.course_activities),t.course_has_more=e.data.count+10*e.data.page<e.data.all_count,r.save("course_has_more",t.course_has_more),r.save("course_page",e.data.page);break;case"Project":r.save("project_activities",t.project_activities),t.project_has_more=e.data.count+10*e.data.page<e.data.all_count,r.save("project_has_more",t.project_has_more),r.save("project_page",e.data.page);break;case 3:}console.log(e.data)},function(e){})},t.tab=function(e){switch(t.currentTab=e,e){case 1:t.activities.length<=0&&t.loadActData(e,0);break;case 2:t.course_activities.length<=0&&t.loadActData(e,0);break;case 3:t.project_activities.length<=0&&t.loadActData(e,0)}},t.currentTab=1,t.activities.length<=0?t.loadActData(1,0):o(function(){window.scrollTo(0,r.get("yoffset"))}),t.goDetail=function(e,t,c){r.save("yoffset",window.document.body.scrollTop),a.path("/"+e+"/"+t)},t.addPraise=function(e){s.addCommonPraise(e)},t.decreasePraise=function(e){s.decreaseCommonPraise(e)}}]);
app.controller("BlogController",["$scope","$http","$routeParams","auth","common",function(o,l,t,n,a){a.init({id:t.id,scope:o,type:"blog_comments",replyType:"BlogComment",loadCallback:function(l){o.blog=l.data},replyCallback:function(){}})}]);
app.controller("ClassController",["$scope","config","$http","auth","$location","$routeParams",function(e,t,s,o,a,n){var c=e,r=n.id,u=function(){c.teachers.length<=0&&s.get(t.apiUrl+"courses/teachers?token="+o.token()+"&course_id="+r).then(function(e){console.log(e.data),c.teachers=e.data.data}),c.students.length<=0&&s.get(t.apiUrl+"courses/students?token="+o.token()+"&course_id="+r).then(function(e){console.log(e.data),c.students=e.data.data})},h=function(){c.resources.length<=0&&s.post(t.apiUrl+"courses/"+r+"/attachments",{token:o.token(),name:""}).then(function(e){c.resources=e.data.data})},i=function(){c.homeworks.length<=0&&s.get(t.apiUrl+"courses/homeworks/"+r+"?token="+o.token()).then(function(e){c.homeworks=e.data.data,console.log(e.data)})},l=function(){c.exercises.length<=0&&s.get(t.apiUrl+"courses/"+r+"/exercises?token="+o.token()).then(function(e){c.exercises=e.data.data,console.log(e.data)})};c.isTeacher=!1,c.currentTab=1,c.tab=function(e){c.currentTab=e,c.searchText="",c.showClassMate=!1,c.showResources=!1,c.showHomework=!1,c.showTestcase=!1,c.isTeacher?1==e?(h(),c.showResources=!0):2==e?(i(),c.showHomework=!0):3==e?(l(),c.showTestcase=!0):4==e&&(u(),c.showClassMate=!0):2==e?(u(),c.showClassMate=!0):1==e&&(h(),c.showResources=!0)},c.course={},c.students=[],c.teachers=[],c.resources=[],c.homeworks=[],c.exercises=[],c.invite=function(){a.path("/invite_code").search({id:r})},s.get(t.apiUrl+"courses/"+r+"?token="+o.token()).then(function(e){console.log(e.data),c.course=e.data.data,d(c.course.current_user_is_teacher),c.tab(1)});var d=function(e){c.isTeacher=e,e?c.menus=["课件","作业","小测验","学生管理"]:c.menus=["课堂资源","我的同学"]}}]);
app.controller("ClassListController",["$scope","config","auth","$http","$location",function(o,s,t,a,e){var n=o;n.courses=[],a.get(s.apiUrl+"courses?token="+t.token()+"&per_page_count=10&page=1").then(function(o){console.log(o.data),n.courses=o.data.data}),n.goClass=function(o){console.log(o),e.path("/class").search({id:o})},n.newClass=function(){e.path("/new_class")},n.goResource=function(){e.path("/myresource")}}]);
app.controller("ClassController",["$scope","config","$http","auth","$location","$routeParams",function(e,s,t,o,a,n){var r=e,c=n.id,u=function(){r.teachers.length<=0&&t.get(s.apiUrl+"courses/teachers?token="+o.token()+"&course_id="+c).then(function(e){console.log(e.data),r.teachers=e.data.data}),r.students.length<=0&&t.get(s.apiUrl+"courses/students?token="+o.token()+"&course_id="+c).then(function(e){console.log(e.data),r.students=e.data.data})},i=function(){r.resources.length<=0&&t.post(s.apiUrl+"courses/"+c+"/attachments",{token:o.token(),name:""}).then(function(e){r.resources=e.data.data,r.resources_tag=!0})},h=function(){r.homeworks.length<=0&&t.get(s.apiUrl+"courses/homeworks/"+c+"?token="+o.token()).then(function(e){r.homeworks=e.data.data,console.log(e.data),r.homeworks_tag=!0})},l=function(){r.exercises.length<=0&&t.get(s.apiUrl+"courses/"+c+"/exercises?token="+o.token()).then(function(e){r.exercises=e.data.data,console.log(e.data),r.exercises_tag=!0})};r.isTeacher=!1,r.currentTab=1,r.tab=function(e){r.currentTab=e,r.searchText="",r.showClassMate=!1,r.showResources=!1,r.showHomework=!1,r.showTestcase=!1,r.resources_tag=!1,r.homeworks_tag=!1,r.exercises_tag=!1,r.isTeacher?1==e?(i(),r.showResources=!0):2==e?(h(),r.showHomework=!0):3==e?(l(),r.showTestcase=!0):4==e&&(u(),r.showClassMate=!0):2==e?(u(),r.showClassMate=!0):1==e&&(i(),r.showResources=!0)},r.course={},r.students=[],r.teachers=[],r.resources=[],r.homeworks=[],r.exercises=[],r.invite=function(){a.path("/invite_code").search({id:c})},r.sendFile=function(e){a.path("/send_class_list").search({id:e.id})},t.get(s.apiUrl+"courses/"+c+"?token="+o.token()).then(function(e){console.log(e.data),r.course=e.data.data,d(r.course.current_user_is_teacher),r.tab(1)});var d=function(e){r.isTeacher=e,e?r.menus=["课件","作业","小测验","学生管理"]:r.menus=["课件","我的同学"]}}]);
app.controller("ClassListController",["$scope","config","auth","$http","$location","alertService","rms",function(e,s,a,t,o,l,n){var c=e;c.syllabuses=n.get("syllabuses")||[],c.alertService=l.create();var i=function(){t.get(s.apiUrl+"syllabuses?token="+a.token()).then(function(e){console.log(e.data),c.syllabuses=e.data.data,n.save("syllabuses",c.syllabuses)})};c.syllabuses.length<=0&&i(),c.goClass=function(e){console.log(e),o.path("/class").search({id:e})},c.newClass=function(){t.post(s.apiUrl+"syllabuses/auth",{token:a.token()}).then(function(e){console.log(e.data),0==e.data.auth?c.alertService.showMessage("提示","非教师身份不能创建课程哦~"):o.path("/new_class")})},c.goResource=function(){o.path("/myresource")},c.joinClass=function(){var e=window.prompt("请输入5位班级邀请码(不区分大小写)");e&&5==e.length?t.post(s.apiUrl+"courses/join",{token:a.token(),invite_code:e}).then(function(e){console.log(e.data),0!=e.data.status?c.alertService.showMessage("错误",e.data.message):(c.alertService.showMessage("提示","加入课程成功"),i())}):e&&c.alertService.showMessage("错误","邀请码格式不正确")},c.onSetting=function(e){console.log(e),n.save("current_edit_syllobus",e),o.path("/edit_class").search({id:e.id})}}]);
app.controller("CourseNoticeController",["$scope","$http","$routeParams","auth","common",function(o,e,t,n,a){a.init({id:t.id,scope:o,type:"newss",replyType:"News",loadCallback:function(e){o.news=e.data},replyCallback:function(){}})}]);
app.controller("DiscussionController",["$scope","$http","$routeParams","auth","common",function(o,s,a,e,n){n.init({id:a.id,scope:o,type:"messages",replyType:"Message",loadCallback:function(s){o.discussion=s.data},replyCallback:function(){}})}]);
app.controller("EditClassController",["$scope","$http","auth","config","alertService","$location","$routeParams","rms",function(s,e,a,l,t,o,r,u){var n=s;n.syllabus=u.get("current_edit_syllobus");var i=r.id;if(n.syllabus||e.get(l.apiUrl+"syllabuses/"+i+"?token="+a.token()).then(function(s){if(console.log(s.data),n.syllabus=s.data.data,n.syllabus){for(var e in n.syllabus.courses){var a=n.syllabus.courses[e];a.tmpname=a.name}n.syllabus.tmptitle=n.syllabus.title}}),console.log(n.syllabus),n.syllabus){for(var c in n.syllabus.courses){var d=n.syllabus.courses[c];d.tmpname=d.name}n.syllabus.tmptitle=n.syllabus.title}n.alertService_1=t.create(),n.alertService_2=t.create(),n.addClass=function(){n.syllabus.courses.push({can_setting:!0})},n.deleteClass=function(s){var t=n.syllabus.courses[s];t.id>0?n.alertService_2.showMessage("提示","您确定要删除该班级吗?",function(){e.post(l.apiUrl+"courses/"+t.id+"/del",{token:a.token()}).then(function(e){0!=e.data.status?n.alertService_1.showMessage("出错了",e.data.message):n.alertService_1.showMessage("提示","删除班级成功",function(){n.syllabus.courses.splice(s,1)}),console.log(e.data.data)})}):n.syllabus.courses.splice(s,1)},n.newClass=function(s,t){if(s.$setSubmitted(),console.log(t),!s.$valid)return void console.log(s.$error);var r=[],c=[];for(var d in n.syllabus.courses){var b=n.syllabus.courses[d];b.id?b.tmpname!=b.name&&c.push({id:b.id,name:b.tmpname}):r.push(b.tmpname)}e.post(l.apiUrl+"syllabuses/"+i+"/edit",{token:a.token(),id:i,title:n.syllabus.tmptitle,add_courses:r,modify_courses:c}).then(function(s){0!=s.data.status?n.alertService_1.showMessage("出错了",s.data.message):n.alertService_1.showMessage("提示","保存课程成功",function(){u.save("syllabuses",[]),o.path("/class_list")}),console.log(s.data.data)})}}]);
app.controller("HomeworkController",["$scope","$http","$routeParams","auth","common",function(o,e,l,n,r){r.init({id:l.id,scope:o,type:"whomeworks",replyType:"HomeworkCommon",loadCallback:function(e){console.log(e),o.homework=e.data},replyCallback:function(){}})}]);
app.controller("InviteCodeController",["$scope","$http","$routeParams","config","auth",function(t,e,i,n,o){var a=t;a.course={};var c=i.id;e.get(n.apiUrl+"courses/"+c+"?token="+o.token()).then(function(t){console.log(t.data),a.course=t.data.data}),a.share=function(){window.WeixinJSBridge.invoke("sendAppMessage",{appid:"wxf694495398c7d470",type:"link",data_url:"",img_url:"http://pnewsapp.tc.qq.com/newsapp_bt/0/9963967/640",img_height:370,img_width:550,link:"http://view.inews.qq.com/a/WXN2013101101385701",desc:"desc",title:"title"},function(t){})}}]);
app.controller("IssueController",["$scope","$http","$routeParams","auth","common",function(o,e,l,s,t){t.init({id:l.id,scope:o,type:"issues",replyType:"Issue",loadCallback:function(e){console.log(e),o.issue=e.data},replyCallback:function(){}})}]);
app.controller("JournalsController",["$scope","$http","$routeParams","auth","common",function(o,a,e,l,n){n.init({id:e.id,scope:o,type:"journal_for_messages",replyType:"JournalsForMessage",loadCallback:function(a){o.message=a.data},replyCallback:function(){}})}]);
app.controller("LoginController",["$scope","$http","$location","$routeParams","alertService","config","auth","session",function(e,o,t,a,i,n,s,l){s.get_bind().then(function(){t.path("/activities")}),a.code&&l.save("code",a.code);var r=e;r.loginFailed=!1,r.alertService=i.create(),r.findPwdDialog=i.create(),r.login=function(a,i){return a.$setSubmitted(),console.log(i),a.$valid?(console.log(apiUrl+"auth"),void o.post(n.apiUrl+"users/wxbind",{login:i.login,password:i.password}).then(function(o){console.log(o.data),r.loginFailed=0!=o.data.status,e.loginFailed?r.alertService.showMessage("出错了",o.data.message):r.alertService.showMessage("提示",o.data.message,function(){t.path("/activities")})})["catch"](function(e){r.alertService.showMessage("出错了",e)})):void console.log(a.$error)},r.showBox=function(){r.findPwdDialog.showMessage("提示","请访问www.trustie.net获取密码谢谢")},r.goReg=function(){t.path("/reg")}}]);
app.controller("MyResourceController",["$scope","$http","auth","config",function(e,o,t,a){var n=e;n.menus=["课件","作业","测验"],n.resources=[],n.homeworks=[],n.exercise=[],n.tab=function(e){n.currentTab=e,1==e?o.get(a.apiUrl+"resources?token="+t.token()).then(function(e){console.log(e.data),n.resources=e.data.data}):2==e?o.get(a.apiUrl+"resources/homeworks?token="+t.token()).then(function(e){console.log(e.data),n.homeworks=e.data.data}):3==e&&o.get(a.apiUrl+"resources/exercies?token="+t.token()).then(function(e){console.log(e.data),n.exercise=e.data.data})},n.tab(1)}]);
app.controller("NewClassController",["$scope","$http","auth","config",function(e,o,r,s){var c=e;c.resources=[],c.homeworks=[],c.exercises=[]}]);
app.controller("RegController",["$scope","$http","$location","alertService",function(e,o,a,r){var s=e;s.errDialog=r.create(),s.goLogin=function(){a.path("/login")},s.isagreed=!0,s.agreed=function(e){s.isagreed=!e},s.reg=function(e,a){return e.$setSubmitted(),console.log(e),e.$valid?(console.log(a),void o.post(apiUrl+"users",{login:a.username,password:a.password,mail:a.email}).then(function(e){0!=e.data.status?s.errDialog.showMessage("出错了",e.data.message):s.errDialog.showMessage("提示","注册且绑定微信成功")},function(e){s.errDialo.showMessage("出错了",e.data)})):void console.log(e.$error)}}]);
app.directive("myAlert",["config",function(t){return{templateUrl:t.rootPath+"templates/alert.html",scope:{title:"=",message:"=",visible:"=",cb:"="},link:function(t){t.dismiss=function(){t.visible=!1,"function"==typeof t.cb&&t.cb()}}}}]);
app.controller("MyResourceController",["$scope","$http","auth","config","$location",function(e,o,t,n,r){var s=e;s.menus=["课件","作业","测验"],s.resources=null,s.homeworks=null,s.exercise=null,s.searchText="",s.tab=function(e){s.currentTab=e,s.searchText="",1==e&&(!s.resources||s.resources.length<=0)?o.get(n.apiUrl+"resources?token="+t.token()).then(function(e){console.log(e.data),s.resources=e.data.data}):2==e&&(!s.homeworks||s.homeworks.length<=0)?o.get(n.apiUrl+"resources/homeworks?token="+t.token()).then(function(e){console.log(e.data),s.homeworks=e.data.data}):3==e&&(!s.exercise||s.exercise.length<=0)&&o.get(n.apiUrl+"resources/exercies?token="+t.token()).then(function(e){console.log(e.data),s.exercise=e.data.data})},s.tab(1),s.sendFile=function(e){r.path("/send_class_list").search({id:e.id})}}]);
app.controller("NewClassController",["$scope","$http","auth","config","alertService","$location",function(s,e,a,o,l,t){var r=s;r.alertService=l.create(),r.syllabus={courses:[{name:""}]},r.addClass=function(){r.syllabus.courses.push({})},r.deleteClass=function(s){r.syllabus.courses.splice(s,1)},r.newClass=function(s,l){if(s.$setSubmitted(),console.log(l),!s.$valid)return void console.log(s.$error);var t=[];for(var n in r.syllabus.courses)t.push(r.syllabus.courses[n].name);e.post(o.apiUrl+"syllabuses",{token:a.token(),title:l.title,courses:t}).then(function(s){0!=s.data.status?r.alertService.showMessage("出错了",s.data.message):r.alertService.showMessage("提示","新建课程成功",function(){window.history.back()}),console.log(s.data.data)})}}]);
app.controller("RegController",["$scope","$http","$location","alertService","$location",function(e,o,a,s,a){var t=e;t.errDialog=s.create(),t.successDialog=s.create(),t.goLogin=function(){a.path("/login")},t.isagreed=!0,t.agreed=function(e){t.isagreed=!e},t.reg=function(e,s){return e.$setSubmitted(),console.log(e),e.$valid?(console.log(s),void o.post(apiUrl+"users",{login:s.username,password:s.password,mail:s.email}).then(function(e){0!=e.data.status?t.errDialog.showMessage("出错了",e.data.message):t.successDialog.showMessage("提示","注册且绑定微信成功",function(){a.path("/activities")})},function(e){t.errDialog.showMessage("出错了",e.data)})):void console.log(e.$error)}}]);
app.controller("SendClassListController",["$scope","$http","$routeParams","config","auth","alertService","rms",function(e,s,o,a,t,r,c){var n=e,l=o.id;n.alertService=r.create(),n.syllabuses=[];var i=function(){s.get(a.apiUrl+"syllabuses?token="+t.token()).then(function(e){console.log(e.data),n.syllabuses=e.data.data})};i(),n.selectCourse=function(e){"boolean"!=typeof e.checked&&(e.checked=!1),e.checked=!e.checked},n.sendToCourses=function(){var e=[];for(var o in n.syllabuses)for(var r in n.syllabuses[o].courses)n.syllabuses[o].courses[r].checked&&e.push(n.syllabuses[o].courses[r].id);return e.length<=0?void n.alertService.showMessage("提醒","请先选择班级"):void s.post(a.apiUrl+"resources/send",{token:t.token(),course_ids:e,send_id:l}).then(function(e){console.log(e.data),0==e.data.status?n.alertService.showMessage("提示","发送成功",function(){window.history.back()}):n.alertService.showMessage("发送出错",e.data.message)})}}]);
app.directive("myAlert",["config",function(t){return{templateUrl:t.rootPath+"templates/alert.html",scope:{title:"=",message:"=",visible:"=",cb:"="},link:function(t){t.dismiss=function(){t.visible=!1,"function"==typeof t.cb&&t.cb()}}}}]),app.directive("myAlert2",["config",function(t){return{templateUrl:t.rootPath+"templates/alert2.html",scope:{title:"=",message:"=",visible:"=",cb:"="},link:function(t){t.dismiss=function(){t.visible=!1},t.confirm=function(){t.visible=!1,"function"==typeof t.cb&&t.cb()}}}}]);
app.directive("pwdconfirm",function(){return{require:"ngModel",link:function(r,n,i,e){e.$validators.pwdconfirm=function(n,i){return r.user&&r.user.password==i}}}});
app.directive("inputAuto",function(){return{restrict:"A",scope:{},link:function(n,t){var e=t.parent().children().eq(0),i=t.parent().next();t.on("input",function(){console.log(i),e.html(t[0].value);var n=e[0].scrollHeight;t.css("height",n+"px")}),i.on("click",function(){t.css("height","28px")})}}});
app.directive("loadingSpinner",["$http",function(i){return{restrict:"A",replace:!0,template:'<div ng-show="activeCalls>0" class="loading-bg"><div class="loading-box"><img src="/images/loading.gif" alt=""/><span>加载中...</span></div></div>'}}]);
app.config(["$routeProvider","$httpProvider","$locationProvider","config",function(e,o,r,t){var l=t.rootPath,n={delay:["auth",function(e){return e.get_bind()}]},s=function(e,o){return{templateUrl:l+e,controller:o,resolve:n}};e.when("/login",{templateUrl:l+"login.html",controller:"LoginController"}).when("/reg",{templateUrl:l+"reg.html",controller:"RegController"}).when("/activites",s("activities.html","ActivityController")).when("/issues/:id",s("issue_detail.html","IssueController")).when("/project_discussion/:id",s("project_discussion.html","DiscussionController")).when("/homework/:id",s("homework_detail.html","HomeworkController")).when("/course_notice/:id",s("course_notice.html","CourseNoticeController")).when("/course_discussion/:id",s("course_discussion.html","DiscussionController")).when("/journal_for_message/:id",s("jour_message_detail.html","JournalsController")).when("/blog_comment/:id",s("blog_detail.html","BlogController")).when("/class",s("class.html","ClassController")).when("/new_class",s("new_class.html","NewClassController")).when("/class_list",s("class_list.html","ClassListController")).when("/myresource",s("myresource.html","MyResourceController")).when("/invite_code",s("invite_code.html","InviteCodeController")).otherwise({redirectTo:"/activites"}),o.interceptors.push(["$q","$rootScope",function(e,o){return void 0==o.activeCalls&&(o.activeCalls=0),{request:function(e){return o.activeCalls+=1,e},requestError:function(e){return o.activeCalls-=1,e},response:function(e){return o.activeCalls-=1,e},responseError:function(e){return o.activeCalls-=1,e}}}])}]);
app.directive("loadingSpinner",["$http","config",function(t,e){return{templateUrl:e.rootPath+"templates/loading.html"}}]);
app.config(["$routeProvider","$httpProvider","$locationProvider","config",function(e,o,t,l){var r=l.rootPath,s={delay:["auth",function(e){return e.get_bind()}]},n=function(e,o){return{templateUrl:r+e,controller:o,resolve:s}};e.when("/login",{templateUrl:r+"login.html",controller:"LoginController"}).when("/reg",{templateUrl:r+"reg.html",controller:"RegController"}).when("/activites",n("activities.html","ActivityController")).when("/issues/:id",n("issue_detail.html","IssueController")).when("/project_discussion/:id",n("project_discussion.html","DiscussionController")).when("/homework/:id",n("homework_detail.html","HomeworkController")).when("/course_notice/:id",n("course_notice.html","CourseNoticeController")).when("/course_discussion/:id",n("course_discussion.html","DiscussionController")).when("/journal_for_message/:id",n("jour_message_detail.html","JournalsController")).when("/blog_comment/:id",n("blog_detail.html","BlogController")).when("/class",n("class.html","ClassController")).when("/new_class",n("new_class.html","NewClassController")).when("/edit_class",n("edit_class.html","EditClassController")).when("/class_list",n("class_list.html","ClassListController")).when("/myresource",n("myresource.html","MyResourceController")).when("/invite_code",n("invite_code.html","InviteCodeController")).when("/send_class_list",n("send_class_list.html","SendClassListController")).otherwise({redirectTo:"/activites"}),o.interceptors.push(["$q","$rootScope",function(e,o){return void 0==o.activeCalls&&(o.activeCalls=0),{request:function(e){return o.activeCalls+=1,e},requestError:function(e){return o.activeCalls-=1,e},response:function(e){return o.activeCalls-=1,e},responseError:function(e){return o.activeCalls-=1,e}}}])}]);

@ -6,6 +6,8 @@ app.controller('ActivityController',
return url;
};
$scope.menus = ['所有动态', '课程动态', '项目动态'];
$scope.alertService = alertService.create();
console.log("ActivityController load");
@ -13,33 +15,119 @@ app.controller('ActivityController',
$scope.activities = rms.get("activities") || [];
$scope.has_more = rms.get("has_more");
$scope.loadActData = function(page){
$scope.course_page = rms.get('course_page') || 0;
$scope.course_activities = rms.get("course_activities") || [];
$scope.course_has_more = rms.get("course_has_more");
$scope.project_page = rms.get('project_page') || 0;
$scope.project_activities = rms.get("project_activities") || [];
$scope.project_has_more = rms.get("project_has_more");
$scope.loadActData = function(index,page){
container_type = "All";
switch(index){
case 1:
container_type = "All";
$scope.page = page;
break;
case 2:
container_type = "Course";
$scope.course_page = page;
break;
case 3:
container_type = "Project";
$scope.project_page = page;
break;
}
$http({
method: 'POST',
url: apiUrl+ "activities",
data: {token: auth.token(), page: page}
data: {token: auth.token(), page: page, container_type: container_type}
}).then(function successCallback(response) {
if(response.data.page >0) {
switch(response.data.container_type){
case "All":
$scope.activities = $scope.activities.concat(response.data.data);
break;
case "Course":
$scope.course_activities = $scope.course_activities.concat(response.data.data);
break;
case "Project":
$scope.project_activities = $scope.project_activities.concat(response.data.data);
break;
case 3:
}
} else {
switch(response.data.container_type){
case "All":
$scope.activities = response.data.data;
break;
case "Course":
$scope.course_activities = response.data.data;
break;
case "Project":
$scope.project_activities = response.data.data;
break;
case 3:
}
}
switch(response.data.container_type){
case "All":
rms.save("activities", $scope.activities);
$scope.has_more = (response.data.count + response.data.page * 10) < response.data.all_count;
rms.save('has_more', $scope.has_more);
rms.save('page', response.data.page);
break;
case "Course":
rms.save("course_activities", $scope.course_activities);
$scope.course_has_more = (response.data.count + response.data.page * 10) < response.data.all_count;
rms.save('course_has_more', $scope.course_has_more);
rms.save('course_page', response.data.page);
break;
case "Project":
rms.save("project_activities", $scope.project_activities);
$scope.project_has_more = (response.data.count + response.data.page * 10) < response.data.all_count;
rms.save('project_has_more', $scope.project_has_more);
rms.save('project_page', response.data.page);
break;
case 3:
}
console.log(response.data);
}, function errorCallback(response) {
});
};
$scope.tab = function(index){
$scope.currentTab = index;
switch(index){
//ALL
case 1:
if($scope.activities.length<=0){
$scope.loadActData(index,0);
}
break;
//Course
case 2:
if($scope.course_activities.length<=0){
$scope.loadActData(index,0);
}
break;
//Project
case 3:
if($scope.project_activities.length<=0){
$scope.loadActData(index,0);
}
break;
}
}
$scope.currentTab = 1;
if($scope.activities.length<=0){
$scope.loadActData(0);
$scope.loadActData(1,0);
} else {
$timeout(function(){
window.scrollTo(0, rms.get("yoffset"));

@ -31,6 +31,7 @@ app.controller('ClassController', ['$scope', 'config','$http', 'auth','$location
{token: auth.token(), name: ''}
).then(function(response){
vm.resources = response.data.data;
vm.resources_tag = true;
});
}
}
@ -40,6 +41,7 @@ app.controller('ClassController', ['$scope', 'config','$http', 'auth','$location
$http.get(config.apiUrl + "courses/homeworks/"+courseid+"?token="+auth.token()).then(function(response){
vm.homeworks = response.data.data;
console.log(response.data);
vm.homeworks_tag = true;
});
}
}
@ -49,6 +51,7 @@ app.controller('ClassController', ['$scope', 'config','$http', 'auth','$location
$http.get(config.apiUrl + "courses/"+courseid+"/exercises?token="+auth.token()).then(function(response){
vm.exercises = response.data.data;
console.log(response.data);
vm.exercises_tag = true;
});
}
}
@ -64,6 +67,9 @@ app.controller('ClassController', ['$scope', 'config','$http', 'auth','$location
vm.showResources = false;
vm.showHomework = false;
vm.showTestcase = false;
vm.resources_tag = false;
vm.homeworks_tag = false;
vm.exercises_tag = false;
if(vm.isTeacher){
if(index == 1){ //课件
@ -105,6 +111,10 @@ app.controller('ClassController', ['$scope', 'config','$http', 'auth','$location
$location.path("/invite_code").search({id: courseid});
};
vm.sendFile = function(r){
$location.path("/send_class_list").search({id: r.id});
}
$http.get(config.apiUrl+ 'courses/'+courseid+"?token="+auth.token()).then(
function(response) {
console.log(response.data);
@ -120,7 +130,7 @@ app.controller('ClassController', ['$scope', 'config','$http', 'auth','$location
if(is_teacher){
vm.menus = ["课件", "作业", "小测验", "学生管理"];
} else {
vm.menus = ['课堂资源', "我的同学"];
vm.menus = ['课', "我的同学"];
}
}

@ -3,16 +3,27 @@
*/
app.controller('ClassListController', ['$scope','config','auth','$http','$location', function($scope, config, auth, $http, $location){
app.controller('ClassListController', ['$scope', 'config', 'auth', '$http', '$location', 'alertService','rms',
function ($scope, config, auth, $http, $location, alertService,rms) {
var vm = $scope;
vm.courses = [];
vm.syllabuses = rms.get('syllabuses') || [];
$http.get(config.apiUrl + "courses?token="+ auth.token() + "&per_page_count=10&page=1").then(
vm.alertService = alertService.create();
var loadClassList = function () {
$http.get(config.apiUrl + "syllabuses?token=" + auth.token()).then(
function (response) {
console.log(response.data);
vm.courses = response.data.data;
vm.syllabuses = response.data.data;
rms.save('syllabuses', vm.syllabuses);
}
);
};
if(vm.syllabuses.length<=0){
loadClassList();
}
vm.goClass = function (course_id) {
console.log(course_id);
@ -20,11 +31,51 @@ app.controller('ClassListController', ['$scope','config','auth','$http','$locati
}
vm.newClass = function () {
//先判断下权限
$http.post(config.apiUrl + "syllabuses/auth",{token: auth.token()} ).then(
function (response) {
console.log(response.data);
if (response.data.auth == 0) {
vm.alertService.showMessage('提示', '非教师身份不能创建课程哦~');
}
else{
$location.path("/new_class");
}
}
);
}
vm.goResource = function () {
$location.path("/myresource");
}
vm.joinClass = function () {
var code = window.prompt("请输入5位班级邀请码(不区分大小写)");
if (code && code.length == 5) {
$http.post(config.apiUrl + "courses/join", {
token: auth.token(),
invite_code: code
}).then(function (response) {
console.log(response.data);
if (response.data.status != 0) {
vm.alertService.showMessage('错误', response.data.message);
} else {
vm.alertService.showMessage('提示', '加入课程成功');
loadClassList();
}
});
} else {
if(code){
vm.alertService.showMessage('错误', '邀请码格式不正确');
}
}
};
vm.onSetting = function (syllabus) {
console.log(syllabus);
rms.save('current_edit_syllobus', syllabus);
$location.path("/edit_class").search({id: syllabus.id});
}
}]);

@ -0,0 +1,110 @@
app.controller('EditClassController', ['$scope', '$http', 'auth', 'config', 'alertService','$location','$routeParams','rms', function($scope, $http, auth, config, alertService, $location,$routeParams, rms){
var vm = $scope;
vm.syllabus = rms.get('current_edit_syllobus');
var syllabus_id = $routeParams.id;
if(!vm.syllabus){
$http.get(config.apiUrl+"syllabuses/"+syllabus_id+"?token="+auth.token()).then(function(response){
console.log(response.data);
vm.syllabus = response.data.data;
if (vm.syllabus) {
for (var i in vm.syllabus.courses) {
var course = vm.syllabus.courses[i];
course.tmpname = course.name;
}
vm.syllabus.tmptitle = vm.syllabus.title;
}
});
}
console.log(vm.syllabus);
//名字用两份
if (vm.syllabus) {
for (var i in vm.syllabus.courses) {
var course = vm.syllabus.courses[i];
course.tmpname = course.name;
}
vm.syllabus.tmptitle = vm.syllabus.title;
}
//单弹框
vm.alertService_1 = alertService.create();
//双弹框
vm.alertService_2 = alertService.create();
vm.addClass = function(){
vm.syllabus.courses.push({can_setting:true});
};
vm.deleteClass = function(index){
var course = vm.syllabus.courses[index];
if(course.id >0){
vm.alertService_2.showMessage('提示', '您确定要删除该班级吗?', function() {
$http.post(config.apiUrl+'courses/'+course.id+'/del', {
token: auth.token()
}).then(function(response){
if(response.data.status!=0){
vm.alertService_1.showMessage('出错了', response.data.message);
} else {
vm.alertService_1.showMessage('提示', '删除班级成功', function(){
vm.syllabus.courses.splice(index, 1);
});
}
console.log(response.data.data);
});
});
} else {
vm.syllabus.courses.splice(index, 1);
}
}
vm.newClass = function (frm, syllabus) {
frm.$setSubmitted();
console.log(syllabus);
if(!frm.$valid){
console.log(frm.$error);
return;
}
var add_courses = [];
var modify_courses = [];
for(var i in vm.syllabus.courses){
var course = vm.syllabus.courses[i];
if(!course.id){
add_courses.push(course.tmpname);
}
else if(course.tmpname != course.name){
modify_courses.push({id:course.id,name:course.tmpname});
}
}
$http.post(config.apiUrl+'syllabuses/'+syllabus_id+'/edit', {
token: auth.token(),
id: syllabus_id,
title:vm.syllabus.tmptitle,
add_courses: add_courses,
modify_courses: modify_courses
}).then(function(response){
if(response.data.status!=0){
vm.alertService_1.showMessage('出错了', response.data.message);
} else {
vm.alertService_1.showMessage('提示', '保存课程成功', function(){
// window.history.back();
rms.save('syllabuses',[]);
$location.path("/class_list");
});
}
console.log(response.data.data);
});
}
}] );

@ -1,24 +1,27 @@
app.controller('MyResourceController', ['$scope', '$http', 'auth', 'config', function($scope, $http, auth, config){
app.controller('MyResourceController', ['$scope', '$http', 'auth', 'config', '$location', function($scope, $http, auth, config, $location){
var vm = $scope;
vm.menus = ['课件', '作业', '测验'];
vm.resources = [];
vm.homeworks = [];
vm.exercise = [];
vm.resources = null;
vm.homeworks = null;
vm.exercise = null;
vm.searchText = "";
vm.tab = function(index){
vm.currentTab = index;
if(index==1){
vm.searchText = "";
if(index==1 && (!vm.resources || vm.resources.length <= 0 )){
$http.get(config.apiUrl + "resources?token="+auth.token()).then(function(response){
console.log(response.data);
vm.resources = response.data.data;
});
} else if(index==2){
} else if(index==2 && (!vm.homeworks || vm.homeworks.length <= 0) ){
$http.get(config.apiUrl + "resources/homeworks?token="+auth.token()).then(function(response){
console.log(response.data);
vm.homeworks = response.data.data;
});
} else if(index==3){
} else if(index==3 && (!vm.exercise || vm.exercise.length <= 0) ){
$http.get(config.apiUrl + "resources/exercies?token="+auth.token()).then(function(response){
console.log(response.data);
vm.exercise = response.data.data;
@ -27,4 +30,8 @@ app.controller('MyResourceController', ['$scope', '$http', 'auth', 'config', fun
}
vm.tab(1);
vm.sendFile = function(r){
$location.path("/send_class_list").search({id: r.id});
}
}] );

@ -1,12 +1,51 @@
app.controller('NewClassController', ['$scope', '$http', 'auth', 'config', function($scope, $http, auth, config){
app.controller('NewClassController', ['$scope', '$http', 'auth', 'config', 'alertService','$location', function($scope, $http, auth, config, alertService, $location){
var vm = $scope;
vm.resources = [];
vm.homeworks = [];
vm.exercises = [];
vm.alertService = alertService.create();
vm.syllabus = {
courses: [{name: ''}],
};
vm.addClass = function(){
vm.syllabus.courses.push({});
};
vm.deleteClass = function(index){
vm.syllabus.courses.splice(index, 1);
}
vm.newClass = function (frm, syllabus) {
frm.$setSubmitted();
console.log(syllabus);
if(!frm.$valid){
console.log(frm.$error);
return;
}
var courses = [];
for(var i in vm.syllabus.courses){
courses .push(vm.syllabus.courses[i].name);
}
$http.post(config.apiUrl+"syllabuses", {
token: auth.token(),
title: syllabus.title,
courses: courses
}).then(function(response){
if(response.data.status!=0){
vm.alertService.showMessage('出错了', response.data.message);
} else {
vm.alertService.showMessage('提示', '新建课程成功', function(){
window.history.back();
});
}
console.log(response.data.data);
});
}
}] );

@ -1,8 +1,9 @@
app.controller('RegController', ['$scope', '$http', '$location', 'alertService',
function ($scope, $http, $location, alertService) {
app.controller('RegController', ['$scope', '$http', '$location', 'alertService','$location',
function ($scope, $http, $location, alertService, $location) {
var vm = $scope;
vm.errDialog = alertService.create();
vm.successDialog = alertService.create();
vm.goLogin = function () {
$location.path("/login");
@ -32,10 +33,12 @@ app.controller('RegController', ['$scope', '$http', '$location', 'alertService',
if (response.data.status != 0) {
vm.errDialog.showMessage('出错了',response.data.message);
} else {
vm.errDialog.showMessage("提示","注册且绑定微信成功");
vm.successDialog.showMessage("提示","注册且绑定微信成功", function(){
$location.path("/activities");
});
}
}, function (response) {
vm.errDialo.showMessage('出错了',response.data);
vm.errDialog.showMessage('出错了',response.data);
});
}

@ -0,0 +1,55 @@
app.controller('SendClassListController', ['$scope', '$http','$routeParams', 'config','auth','alertService', 'rms', function($scope, $http, $routeParams, config, auth, alertService,rms){
var vm = $scope;
var send_id = $routeParams.id;
vm.alertService = alertService.create();
vm.syllabuses = [];
var loadClassList = function () {
$http.get(config.apiUrl + "syllabuses?token=" + auth.token()).then(
function (response) {
console.log(response.data);
vm.syllabuses = response.data.data;
// rms.save('syllabuses', vm.syllabuses);
}
);
};
loadClassList();
vm.selectCourse = function(course){
if( typeof course.checked !== 'boolean' ) course.checked = false;
course.checked = !course.checked;
}
vm.sendToCourses = function(){
var course_ids = [];
for(var i in vm.syllabuses) {
for (var j in vm.syllabuses[i].courses) {
if (vm.syllabuses[i].courses[j].checked) {
course_ids.push(vm.syllabuses[i].courses[j].id);
}
}
}
if(course_ids.length <= 0){
vm.alertService.showMessage('提醒', '请先选择班级');
return;
}
$http.post(config.apiUrl + "resources/send", {
token: auth.token(), course_ids: course_ids, send_id: send_id
}).then(function(response){
console.log(response.data);
if(response.data.status == 0){
vm.alertService.showMessage('提示', '发送成功', function () {
window.history.back();
});
} else {
vm.alertService.showMessage('发送出错', response.data.message);
}
})
}
}]);

@ -17,3 +17,26 @@ app.directive('myAlert', ['config', function(config){
}
}
}]);
app.directive('myAlert2', ['config', function(config){
return {
templateUrl: config.rootPath+ 'templates/alert2.html',
scope: {
title: "=",
message: "=",
visible: "=",
cb: "="
},
link: function(scope){
scope.dismiss = function(){
scope.visible = false;
};
scope.confirm = function(){
scope.visible = false;
if(typeof scope.cb === 'function'){
scope.cb();
}
}
}
}
}]);

@ -1,7 +1,5 @@
app.directive('loadingSpinner', ['$http', function ($http) {
app.directive('loadingSpinner', ['$http', 'config', function ($http, config) {
return {
restrict: 'A',
replace: true,
template: '<div ng-show="activeCalls>0" class="loading-bg"><div class="loading-box"><img src="/images/loading.gif" alt=""/><span>加载中...</span></div></div>',
templateUrl: config.rootPath+ 'templates/loading.html',
};
}]);

@ -32,9 +32,11 @@ app.config(['$routeProvider',"$httpProvider", "$locationProvider",'config', func
.when('/blog_comment/:id', makeRoute('blog_detail.html', 'BlogController'))
.when('/class', makeRoute('class.html', 'ClassController'))
.when('/new_class', makeRoute('new_class.html', 'NewClassController'))
.when('/edit_class', makeRoute('edit_class.html', 'EditClassController'))
.when('/class_list', makeRoute('class_list.html', 'ClassListController'))
.when('/myresource', makeRoute('myresource.html', 'MyResourceController'))
.when('/invite_code', makeRoute('invite_code.html', 'InviteCodeController'))
.when('/send_class_list', makeRoute('send_class_list.html', 'SendClassListController'))
.otherwise({
redirectTo: '/activites'
});

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

Loading…
Cancel
Save