Merge branch 'weixin_guange' into develop

yuanke_cache v20160804_01
yuanke 9 years ago
commit 88c7018537

@ -100,15 +100,34 @@ module Mobile
params do params do
requires :token, type: String requires :token, type: String
requires :invite_code, type: String, desc: '邀请码' requires :invite_code, type: String, desc: '邀请码'
requires :teacher_flag, type: Boolean
requires :assistant_flag, type: Boolean
requires :student_flag, type: Boolean
end end
post "join" do post "join_class" do
authenticate! authenticate!
cs = CoursesService.new
status = cs.join_course({role: "10", openid: params[:openid], invite_code: params[:invite_code]}, current_user) roles_ids = []
{ if params[:teacher_flag]
status: status[:state], roles_ids << "9"
message:CoursesService::JoinCourseError.message(status[:state]) elsif params[:assistant_flag]
} roles_ids << "7"
end
if params[:student_flag]
roles_ids << "10"
end
if roles_ids.length <= 0
{status:-1,message:"请至少选择一个角色"}
else
cs = CoursesService.new
status = cs.join_course_roles({role: roles_ids, openid: params[:openid], invite_code: params[:invite_code]}, current_user)
{
status: status[:state],
message:CoursesService::JoinCourseError.message(status[:state])
}
end
end end
@ -166,7 +185,52 @@ module Mobile
present :status, 0 present :status, 0
end end
desc "设置教辅" desc "课程未审核列表"
params do
requires :token, type: String
requires :course_id, type: Integer, desc: "课程id"
end
get 'reviewers' do
authenticate!
cs = CoursesService.new
reviewers = cs.reviewers_list(params[:course_id])
present :data, reviewers, with: Mobile::Entities::User
present :status, 0
end
desc "课程单个未审核用户信息"
params do
requires :token, type: String
requires :course_id, type: Integer, desc: "课程id"
requires :user_id, type: Integer, desc: "用户id"
end
post 'review_member_info' do
authenticate!
cs = CoursesService.new
reviewer = cs.get_reviewer_info(params)
present :data, reviewer, with: Mobile::Entities::User
present :status, 0
end
desc "处理教师或助教的身份申请"
params do
requires :token, type: String
requires :course_id, type: Integer, desc: "课程id"
requires :user_id, type: Integer, desc: "用户id"
requires :type, type: Integer, desc: "同意或拒绝"
end
post 'deal_join_apply' do
authenticate!
cs = CoursesService.new
result = cs.deal_join_apply(params,current_user)
present :status, result[:status]
present :message, result[:message]
end
desc "设置助教"
params do params do
requires :token,type:String requires :token,type:String
requires :user_id,type:Integer,desc: '用户id' requires :user_id,type:Integer,desc: '用户id'
@ -178,7 +242,7 @@ module Mobile
present :status, 0 present :status, 0
end end
desc "删除" desc "删除"
params do params do
requires :token,type:String requires :token,type:String
requires :user_id,type:Integer,desc: '用户id' requires :user_id,type:Integer,desc: '用户id'
@ -448,20 +512,35 @@ module Mobile
requires :id, type: Integer requires :id, type: Integer
requires :token, type: String requires :token, type: String
requires :user_id, type: Integer requires :user_id, type: Integer
requires :role_id, type: Integer requires :teacher_flag, type: Boolean
requires :assistant_flag, type: Boolean
requires :student_flag, type: Boolean
end end
post 'edit_member_role' do post 'edit_member_role' do
authenticate! authenticate!
roles_id = []
if params[:teacher_flag]
roles_id << 9
elsif params[:assistant_flag]
roles_id << 7
end
if params[:student_flag]
roles_id << 10
end
c = Course.find("#{params[:id]}") c = Course.find("#{params[:id]}")
#7教辅 9教师 10学生 #7教辅 9教师 10学生
if c.tea_id == params[:user_id] || c.tea_id != current_user.id || !(params[:role_id] == 7 || params[:role_id] == 9 || params[:role_id] == 10) if c.tea_id == params[:user_id] || c.tea_id != current_user.id || roles_id.length <= 0
present :status, -1 present :status, -1
else else
cs = CoursesService.new cs = CoursesService.new
status = cs.modify_user_course_role params status = cs.modify_user_course_role params,roles_id
present :status, status present :status, status
end end
end end

@ -86,9 +86,24 @@ module Mobile
develop_members = project.member_principals.includes(:roles, :principal).where("member_roles.role_id=4").all.sort develop_members = project.member_principals.includes(:roles, :principal).where("member_roles.role_id=4").all.sort
report_members = project.member_principals.includes(:roles, :principal).where("member_roles.role_id=5").all.sort report_members = project.member_principals.includes(:roles, :principal).where("member_roles.role_id=5").all.sort
review_master_members = []
review_develop_members = []
my_member = project.member_principals.where("users.id=#{current_user.id}").first
if my_member && my_member.roles[0] && my_member.roles[0].id == 3
ps = ProjectsService.new
user = current_user
review_master_members = ps.get_project_review_members(project,3,user)
review_develop_members = ps.get_project_review_members(project,4,user)
end
present :master_members,master_members, with: Mobile::Entities::ProjectMember present :master_members,master_members, with: Mobile::Entities::ProjectMember
present :develop_members,develop_members, with: Mobile::Entities::ProjectMember present :develop_members,develop_members, with: Mobile::Entities::ProjectMember
present :report_members,report_members, with: Mobile::Entities::ProjectMember present :report_members,report_members, with: Mobile::Entities::ProjectMember
present :review_master_members,review_master_members
present :review_develop_members,review_develop_members
present :status, 0 present :status, 0
end end
@ -163,16 +178,55 @@ module Mobile
params do params do
requires :token, type: String requires :token, type: String
requires :invite_code, type: String, desc: '邀请码' requires :invite_code, type: String, desc: '邀请码'
requires :role_id, type: Integer, desc: '身份'
end
post "join_project" do
authenticate!
role_id = params[:role_id]
if role_id != 3 && role_id != 4 && role_id != 5
{status:-1,message:"请至少选择一个角色"}
else
ps = ProjectsService.new
status = ps.join_project({role: role_id, openid: params[:openid], invite_code: params[:invite_code]}, current_user)
{status:status, message:ProjectsService::JoinProjectError.message(status)}
end
# {status:-1, message: '该功能将在近日开放,敬请期待!' }
end
desc "项目单个未审核用户信息"
params do
requires :token, type: String
requires :project_id, type: Integer, desc: "项目id"
requires :user_id, type: Integer, desc: "用户id"
end end
post "join" do post 'review_member_info' do
authenticate! authenticate!
# ps = ProjectsService.new ps = ProjectsService.new
# status = ps.join_project({role: "5", openid: params[:openid], invite_code: params[:invite_code]}, current_user) reviewer = ps.get_reviewer_info params
# present :data, reviewer, with: Mobile::Entities::User
# present :status, status present :status, 0
end
desc "处理管理或开发的身份申请"
params do
requires :token, type: String
requires :project_id, type: Integer, desc: "项目id"
requires :user_id, type: Integer, desc: "用户id"
requires :type, type: Integer, desc: "同意或拒绝"
end
post 'deal_join_apply' do
authenticate!
ps = ProjectsService.new
result = ps.deal_join_apply(params,current_user)
{status:-1, message: '该功能将在近日开放,敬请期待!' } present :status, result[:status]
present :message, result[:message]
end end
end end

@ -85,7 +85,7 @@ module Mobile
#取二级回复的底楼层 #取二级回复的底楼层
parents_reply = [] parents_reply = []
parents_reply = get_reply_parents_no_root(parents_reply, c) parents_reply = get_reply_parents_no_root(parents_reply, c)
if parents_reply.count > 0 && parents_reply.count != 2 && !opt[:bottom] if parents_reply.count > 0 && !opt[:bottom]
if opt[:type] == 1 if opt[:type] == 1
# opt[:bottom] = true # opt[:bottom] = true
# parents_reply[opt[:page]..opt[:page]] # parents_reply[opt[:page]..opt[:page]]
@ -104,9 +104,9 @@ module Mobile
#取二级回复的顶楼层 #取二级回复的顶楼层
parents_reply = [] parents_reply = []
parents_reply = get_reply_parents_no_root(parents_reply, c) parents_reply = get_reply_parents_no_root(parents_reply, c)
if parents_reply.count >= 2 && !opt[:top] if parents_reply.count > 2 && !opt[:top]
if opt[:type] == 1 if opt[:type] == 1
opt[:bottom] = true opt[:top] = true
tStart = (opt[:page]-1)*5+2 tStart = (opt[:page]-1)*5+2
tEnd = (opt[:page])*5+2 - 1 tEnd = (opt[:page])*5+2 - 1
@ -125,6 +125,10 @@ module Mobile
parents_reply = parents_reply.reverse[0..1] parents_reply = parents_reply.reverse[0..1]
parents_reply.reverse parents_reply.reverse
end end
elsif parents_reply.count == 2 && !opt[:top]
opt[:top] = true
parents_reply = parents_reply.reverse[0..0]
parents_reply.reverse
else else
[] []
end end

@ -34,6 +34,8 @@ module Mobile
'Issue' 'Issue'
when :act_id when :act_id
issue.id issue.id
when :title
issue.subject
end end
end end
end end
@ -43,6 +45,7 @@ module Mobile
expose :description expose :description
expose :author, using: Mobile::Entities::User expose :author, using: Mobile::Entities::User
expose :done_ratio expose :done_ratio
issue_expose :title
issue_expose :act_type issue_expose :act_type
issue_expose :act_id issue_expose :act_id
issue_expose :created_on issue_expose :created_on

@ -101,7 +101,7 @@ module Mobile
elsif opt[:comment_type] == "homework" elsif opt[:comment_type] == "homework"
parents_reply = get_reply_parents(parents_reply, f) parents_reply = get_reply_parents(parents_reply, f)
end end
if parents_reply.count > 0 && parents_reply.count != 2 && !opt[:bottom] if parents_reply.count > 0 && !opt[:bottom]
if opt[:type] == 1 if opt[:type] == 1
# opt[:bottom] = true # opt[:bottom] = true
# parents_reply[opt[:page]..opt[:page]] # parents_reply[opt[:page]..opt[:page]]
@ -125,9 +125,9 @@ module Mobile
elsif opt[:comment_type] == "homework" elsif opt[:comment_type] == "homework"
parents_reply = get_reply_parents(parents_reply, f) parents_reply = get_reply_parents(parents_reply, f)
end end
if parents_reply.count >= 2 && !opt[:top] if parents_reply.count > 2 && !opt[:top]
if opt[:type] == 1 if opt[:type] == 1
opt[:bottom] = true opt[:top] = true
tStart = (opt[:page]-1)*5+2 tStart = (opt[:page]-1)*5+2
tEnd = (opt[:page])*5+2 - 1 tEnd = (opt[:page])*5+2 - 1
@ -146,6 +146,10 @@ module Mobile
parents_reply = parents_reply.reverse[0..1] parents_reply = parents_reply.reverse[0..1]
parents_reply.reverse parents_reply.reverse
end end
elsif parents_reply.count == 2 && !opt[:top]
opt[:top] = true
parents_reply = parents_reply.reverse[0..0]
parents_reply.reverse
else else
[] []
end end

@ -33,6 +33,8 @@ module Mobile
when :comment_count when :comment_count
all_comments = [] all_comments = []
get_all_children(all_comments, u).count get_all_children(all_comments, u).count
when :title
u.subject
end end
end end
end end
@ -50,6 +52,7 @@ module Mobile
message_expose :course_project_name message_expose :course_project_name
message_expose :board_id message_expose :board_id
message_expose :subject message_expose :subject
message_expose :title
message_expose :content message_expose :content
message_expose :comment_count message_expose :comment_count
message_expose :praise_count message_expose :praise_count
@ -92,7 +95,7 @@ module Mobile
#取二级回复的底楼层 #取二级回复的底楼层
parents_reply = [] parents_reply = []
parents_reply = get_reply_parents_no_root(parents_reply, c) parents_reply = get_reply_parents_no_root(parents_reply, c)
if parents_reply.count > 0 && parents_reply.count != 2 && !opt[:bottom] if parents_reply.count > 0 && !opt[:bottom]
if opt[:type] == 1 if opt[:type] == 1
# opt[:bottom] = true # opt[:bottom] = true
# parents_reply[opt[:page]..opt[:page]] # parents_reply[opt[:page]..opt[:page]]
@ -111,9 +114,9 @@ module Mobile
#取二级回复的顶楼层 #取二级回复的顶楼层
parents_reply = [] parents_reply = []
parents_reply = get_reply_parents_no_root(parents_reply, c) parents_reply = get_reply_parents_no_root(parents_reply, c)
if parents_reply.count >= 2 && !opt[:top] if parents_reply.count > 2 && !opt[:top]
if opt[:type] == 1 if opt[:type] == 1
opt[:bottom] = true opt[:top] = true
tStart = (opt[:page]-1)*5+2 tStart = (opt[:page]-1)*5+2
tEnd = (opt[:page])*5+2 - 1 tEnd = (opt[:page])*5+2 - 1
@ -132,6 +135,10 @@ module Mobile
parents_reply = parents_reply.reverse[0..1] parents_reply = parents_reply.reverse[0..1]
parents_reply.reverse parents_reply.reverse
end end
elsif parents_reply.count == 2 && !opt[:top]
opt[:top] = true
parents_reply = parents_reply.reverse[0..0]
parents_reply.reverse
else else
[] []
end end

@ -4,8 +4,8 @@ module Mobile
expose :name expose :name
expose :id expose :id
expose :user_id expose :user_id
# expose :invite_code expose :invite_code
# expose :qrcode expose :qrcode
expose :can_setting, if: lambda { |instance, options| options[:user] } do |instance, options| expose :can_setting, if: lambda { |instance, options| options[:user] } do |instance, options|
current_user = options[:user] current_user = options[:user]

@ -14,11 +14,11 @@ module Mobile
else else
case f case f
when :roles_id when :roles_id
u.roles[0].id # u.roles[0].id
u.roles.map {|r| r.id}
end end
end end
end end
end end
end end

@ -34,6 +34,8 @@ module Mobile
'HomeworkCommon' 'HomeworkCommon'
when :act_id when :act_id
wh.id wh.id
when :title
wh.name
end end
end end
end end
@ -59,6 +61,7 @@ module Mobile
expose :quotes expose :quotes
expose :is_open expose :is_open
expose :id expose :id
whomework_expose :title
whomework_expose :act_type whomework_expose :act_type
whomework_expose :act_id whomework_expose :act_id
whomework_expose :course_name whomework_expose :course_name

@ -10,8 +10,8 @@ class WechatsController < ActionController::Base
#邀请码 #邀请码
if join_class_request(request) if join_class_request(request)
sendBindClass(request, {invite_code: content}) sendBindClass(request, {invite_code: content})
# elsif join_project_request(request) elsif join_project_request(request)
# sendBindProject(request, {invite_code: content}) sendBindProject(request, {invite_code: content})
else else
request.reply.text "您的意见已收到,非常感谢~ \n更多问题可以通过以下方式联系我们:\n官方QQ群173184401\n我们会认真聆听您的意见和建议。" request.reply.text "您的意见已收到,非常感谢~ \n更多问题可以通过以下方式联系我们:\n官方QQ群173184401\n我们会认真聆听您的意见和建议。"
end end
@ -49,7 +49,7 @@ class WechatsController < ActionController::Base
# When no any on :scan responder can match subscribe user scaned scene_id # When no any on :scan responder can match subscribe user scaned scene_id
on :event, with: 'scan' do |request| on :event, with: 'scan' do |request|
if request[:EventKey].present? if request[:EventKey].present?
sendBindClass(request, {ticket: request[:Ticket]}) checkTicket(request, {ticket: request[:Ticket]})
end end
end end
@ -149,13 +149,13 @@ class WechatsController < ActionController::Base
end end
on :click, with: 'JOIN_PROJECT' do |request, key| on :click, with: 'JOIN_PROJECT' do |request, key|
request.reply.text "该功能将在近日开放,敬请期待!" # request.reply.text "该功能将在近日开放,敬请期待!"
# uw = user_binded?(request[:FromUserName]) uw = user_binded?(request[:FromUserName])
# unless uw unless uw
# sendBind(request) sendBind(request)
# else else
# request.reply.text "请直接回复6位项目邀请码\n(不区分大小写):" request.reply.text "请直接回复6位项目邀请码\n(不区分大小写):"
# end end
end end
on :click, with: 'JOIN_CLASS' do |request, key| on :click, with: 'JOIN_CLASS' do |request, key|
@ -209,6 +209,39 @@ class WechatsController < ActionController::Base
end end
end end
def checkTicket(request,params)
begin
uw = user_binded?(request[:FromUserName])
if !uw
return sendBind(request)
end
course = nil
course = Course.where(qrcode: params[:ticket]).first if params[:ticket]
course = Course.where(invite_code: params[:invite_code]).first if params[:invite_code]
if course
return join_class(params, uw.user, request)
else
project = nil
project = Project.where(qrcode: params[:ticket]).first if params[:ticket]
project = Project.where(invite_code: params[:invite_code]).first if params[:invite_code]
if project
return join_project(params, uw.user, request)
end
end
raise "该二维码已失效"
rescue => e
logger.error e.inspect
logger.error e.backtrace.join("\n")
return request.reply.text e
end
end
def default_msg(request) def default_msg(request)
uw = user_binded?(request[:FromUserName]) uw = user_binded?(request[:FromUserName])
if uw && uw.user if uw && uw.user
@ -273,9 +306,9 @@ class WechatsController < ActionController::Base
role = 5 role = 5
ps = ProjectsService.new ps = ProjectsService.new
status = ps.join_project({invite_code: project.invite_code}, user) status = ps.join_project({role:5, invite_code: project.invite_code}, user)
if status[:state] != 0 if status != 0
raise ProjectService::JoinProjectError.message(status) raise ProjectsService::JoinProjectError.message(status)
end end
creator = User.find(project.user_id) creator = User.find(project.user_id)
@ -284,7 +317,7 @@ class WechatsController < ActionController::Base
content: "项目名称:#{project.name}\n发起人:#{creator.name}\n进入项目,和小伙伴轻松的研发吧!"} } content: "项目名称:#{project.name}\n发起人:#{creator.name}\n进入项目,和小伙伴轻松的研发吧!"} }
return request.reply.news(news) do |article, n, index| # article is return object return request.reply.news(news) do |article, n, index| # article is return object
url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=#{Wechat.config.appid}&redirect_uri=#{ROOT_URL+'/wechat/user_activities#/project?id='+project.id.to_s}&response_type=code&scope=snsapi_base&state=myproject#wechat_redirect" url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=#{Wechat.config.appid}&redirect_uri=#{ROOT_URL+'/wechat/user_activities#/project?id='+project.id.to_s}&response_type=code&scope=snsapi_base&state=myproject#wechat_redirect"
pic_url = "#{ROOT_URL}/images/wechat/class.jpg" pic_url = "#{ROOT_URL}/images/wechat/project.jpg"
article.item title: "#{n[:title]}", article.item title: "#{n[:title]}",
description: n[:content], description: n[:content],
pic_url: pic_url, pic_url: pic_url,
@ -350,7 +383,15 @@ class WechatsController < ActionController::Base
render 'wechats/user_activities', layout: nil render 'wechats/user_activities', layout: nil
end end
def user_activities def user_activities
@appid = Wechat.config.appid
## sign
@sign_params = wechat.jsapi_ticket.signature(current_url)
session[:wechat_code] = params[:code] if params[:code] session[:wechat_code] = params[:code] if params[:code]
@path = '/'+(params[:state] || '') @path = '/'+(params[:state] || '')
open_id = get_openid_from_code(params[:code]) rescue open_id = get_openid_from_code(params[:code]) rescue
@ -398,6 +439,9 @@ class WechatsController < ActionController::Base
uw = UserWechat.where(openid: openid).first uw = UserWechat.where(openid: openid).first
end end
def current_url
"#{request.protocol}#{request.host_with_port}#{request.fullpath}"
end
end end

@ -1,3 +1,4 @@
#coding=utf-8
class AppliedProject < ActiveRecord::Base class AppliedProject < ActiveRecord::Base
attr_accessible :project_id, :user_id, :role attr_accessible :project_id, :user_id, :role
@ -11,6 +12,14 @@ class AppliedProject < ActiveRecord::Base
def send_appliled_message def send_appliled_message
self.project.managers.each do |member| self.project.managers.each do |member|
self.applied_messages << AppliedMessage.new(:user_id => member.user_id, :status => true, :viewed => false, :applied_user_id => self.user_id, :role => self.role, :project_id => self.project_id) self.applied_messages << AppliedMessage.new(:user_id => member.user_id, :status => true, :viewed => false, :applied_user_id => self.user_id, :role => self.role, :project_id => self.project_id)
#----------------微信通知----------------------
count = ShieldWechatMessage.where("container_type='User' and container_id=#{member.user_id} and shield_type='Project' and shield_id=#{self.project_id}").count
if count == 0
ws = WechatService.new
ws.project_review_notice member.user_id, "review_project_member", self.project_id, "项目成员审批通知", self.project.name, self.user.show_name, format_time(Time.now),"点击查看申请详情。",self.user.id
end
#--------------------------------------------
end end
# end # end
end end

@ -928,6 +928,18 @@ class Project < ActiveRecord::Base
code code
end end
def generate_qrcode
ticket = self.qrcode
if !ticket || ticket.size < 10
response = Wechat.api.qrcode_create_scene(invite_code, 2592000)
logger.debug "response = #{response}"
self.qrcode = response['ticket']
save!
ticket = qrcode
end
ticket
end
private private
def after_parent_changed(parent_was) def after_parent_changed(parent_was)

@ -101,16 +101,149 @@ class CoursesService
gender = m.user.user_extensions.gender.nil? ? 0 : m.user.user_extensions.gender gender = m.user.user_extensions.gender.nil? ? 0 : m.user.user_extensions.gender
work_unit = get_user_work_unit m.user work_unit = get_user_work_unit m.user
location = get_user_location m.user location = get_user_location m.user
users << {:id => m.user.id, :img_url => img_url, :nickname => m.user.login, :gender => gender,
:work_unit => work_unit, :mail => m.user.mail, :location => location, role_ids = []
role_name: m.roles.first.name, m.roles.each do |r|
name: m.user.show_name, role_ids << r.id
roles_id: m.roles[0].id, end
:brief_introduction => m.user.user_extensions.brief_introduction,:realname=>m.user.realname}
#双重身份 学生列表中不显示
unless (params[:role] == '2' && role_ids.length >= 2)
users << {:id => m.user.id, :img_url => img_url, :nickname => m.user.login, :gender => gender,
:work_unit => work_unit, :mail => m.user.mail, :location => location,
role_name: m.roles.first.name,
name: m.user.show_name,
roles_id: role_ids.include?(7) ? 7 : (role_ids.include?(9) ? 9 : 10 ),
:brief_introduction => m.user.user_extensions.brief_introduction,:realname=>m.user.realname}
end
end end
users users
end end
def reviewers_list course_id
reviewers = []
c = Course.find(course_id)
if c
messages = CourseMessage.where("course_id=? and course_message_type = 'JoinCourseRequest' and status = 0 ",course_id)
messages.each do |m|
user = User.find(m.course_message_id)
if user
img_url = url_to_avatar(user)
gender = user.user_extensions.gender.nil? ? 0 : user.user_extensions.gender
work_unit = get_user_work_unit user
location = get_user_location user
roles_ids = m.content.split(",")
reviewers << {:id => user.id, :img_url => img_url, :nickname => user.login, :gender => gender,
:work_unit => work_unit, :mail => user.mail, :location => location,
role_name: "",
name: user.show_name,
roles_id: roles_ids.include?("7") ? 7 : 9,
:brief_introduction => user.user_extensions.brief_introduction,:realname=>user.realname}
end
end
end
reviewers
end
def get_reviewer_info params
info = nil
c = Course.find(params[:course_id])
if c
messages = CourseMessage.where("course_id=? and course_message_id = ? and course_message_type = 'JoinCourseRequest' and status = 0 ",params[:course_id],params[:user_id]).first
if messages
user = User.find(params[:user_id])
if user
img_url = url_to_avatar(user)
gender = user.user_extensions.gender.nil? ? 0 : user.user_extensions.gender
work_unit = get_user_work_unit user
location = get_user_location user
roles_ids = messages.content.split(",")
info = {:id => user.id, :img_url => img_url, :nickname => user.login, :gender => gender,
:work_unit => work_unit, :mail => user.mail, :location => location,
role_name: "",
name: user.show_name,
roles_id: roles_ids.include?("7") ? 7 : 9,
:brief_introduction => user.user_extensions.brief_introduction,:realname=>user.realname}
end
end
end
info
end
def deal_join_apply params,current_user
status = -1
message = ""
c = Course.find(params[:course_id])
if c
messages = CourseMessage.where("course_id=? and course_message_id = ? and course_message_type = 'JoinCourseRequest' and status = 0 ",params[:course_id],params[:user_id]).first
if messages
apply_user = User.find(params[:user_id])
ids = messages.content.split(",") # content保存的是申请的职位角色
integer_ids = []
ids.each do |role_id|
integer_ids << role_id.to_i
end
if params[:type] == 0
if apply_user.member_of_course?(c)
#将角色改为老师或者教辅
member = c.members.where(:user_id=>apply_user.id).all[0]
member.role_ids = integer_ids
#删除为学生的记录
unless member.role_ids.include?(10)
joined = StudentsForCourse.where('student_id = ? and course_id = ?', member.user_id,c.id)
joined.each do |join|
join.delete
end
end
member.course_group_id = 0
member.save
CourseMessage.create(:user_id => apply_user.id, :course_id => c.id, :viewed => false,:content=> messages.content,:course_message_id=>current_user.id,:course_message_type=>'CourseRequestDealResult',:status=>1)
messages.update_attributes(:status=>1,:viewed=>1)
else
members = []
members << Member.new(:role_ids => integer_ids, :user_id => apply_user.id)
c.members << members
CourseMessage.create(:user_id => apply_user.id, :course_id => c.id, :viewed => false,:content=> messages.content,:course_message_id=>current_user.id,:course_message_type=>'CourseRequestDealResult',:status=>1)
messages.update_attributes(:status=>1,:viewed=>1)
end
if integer_ids.include?(9)
message = "您已同意教师"+apply_user.show_name+",加入班级"
else
message = "您已同意助教"+apply_user.show_name+",加入班级"
end
else
CourseMessage.create(:user_id => apply_user.id, :course_id => c.id, :viewed => false,:content=> messages.content,:course_message_id=>current_user.id,:course_message_type=>'CourseRequestDealResult',:status=>2)
messages.update_attributes(:status=>2,:viewed=>1)
if integer_ids.include?(9)
message = "您已拒绝教师"+apply_user.show_name+",加入班级"
else
message = "您已拒绝助教"+apply_user.show_name+",加入班级"
end
end
status = 0
else
message = "该申请不存在或已被处理"
end
else
message = "该班级不存在或已被删除"
end
{:status => status,:message => message}
end
#获取用户的工作单位 #获取用户的工作单位
def get_user_work_unit user def get_user_work_unit user
work_unit = "" work_unit = ""
@ -329,15 +462,17 @@ class CoursesService
0, '加入成功', 0, '加入成功',
1, '密码错误', 1, '密码错误',
2, '班级已过期 请联系班级管理员重启班级。', 2, '班级已过期 请联系班级管理员重启班级。',
3, '您已经加入了班级', 3, '您已经是该班级的成员了',
4, '您的邀请码不正确', 4, '您的邀请码不正确',
5, '您还未登录', 5, '您还未登录',
6, '申请成功,请等待审核完毕', 6, '您的申请已提交,请等待管理员审批',
7, '您已经发送过申请了,请耐心等待', 7, '您已经发送过申请了,请耐心等待',
8, '您已经是该班级的教师了', 8, '您已经是该班级的教师了',
9, '您已经是该班级的教辅了', 9, '您已经是该班级的教辅了',
10, '您已经是该班级的管理员了', 10, '您已经是该班级的管理员了',
11, '该班级不存在或已被删除啦', 11, '该班级不存在或已被删除啦',
12, '您已经发送过申请了,请耐心等待',
13, '您的申请已提交,请等待管理员审批',
'未知错误,请稍后再试' '未知错误,请稍后再试'
] ]
end end
@ -460,15 +595,31 @@ class CoursesService
is_stu = true is_stu = true
end end
#如果已经发送过消息了,那么就要给个提示 #如果已经发送过消息了,那么就要给个提示
if CourseMessage.where("course_message_type = 'JoinCourseRequest' and user_id = #{course.tea_id} and content = '#{role_str}' and course_message_id = #{User.current.id} and course_id = #{course.id} and status = 0").count != 0 if CourseMessage.where("course_message_type = 'JoinCourseRequest' and user_id = #{course.tea_id} and content = '#{role_str}' and course_message_id = #{current_user.id} and course_id = #{course.id} and status = 0").count != 0
if is_stu if is_stu
@state = 12 @state = 12
else else
@state = 7 @state = 7
end end
else else
Mailer.run.join_course_request(course, User.current, params[:role]) Mailer.run.join_course_request(course, current_user, params[:role])
CourseMessage.create(:user_id => course.tea_id, :course_id => course.id, :viewed => false,:content=> role_str,:course_message_id=>User.current.id,:course_message_type=>'JoinCourseRequest',:status=>0) CourseMessage.create(:user_id => course.tea_id, :course_id => course.id, :viewed => false,:content=> role_str,:course_message_id=>current_user.id,:course_message_type=>'JoinCourseRequest',:status=>0)
#----------------微信通知----------------------
if role_ids.include?("7") || role_ids.include?("9")
tea_user = User.find(course.tea_id)
count = ShieldWechatMessage.where("container_type='User' and container_id=#{tea_user.id} and shield_type='Course' and shield_id=#{course.id}").count
if count == 0
rolename = role_ids.include?("7") ? "助教" : "教师"
content = current_user.show_name + "申请以"+rolename+"身份加入班级,等待您的审批。"
ws = WechatService.new
ws.class_notice tea_user.id, "review_class_member", course.id, "班级成员审批通知", course.name, tea_user.show_name, format_time(Time.now), content, "点击查看申请详情。",current_user.id
end
end
#--------------------------------------------
if is_stu if is_stu
@state = 13 @state = 13
else else
@ -1054,20 +1205,21 @@ class CoursesService
# end # end
#修改班级成员角色 #修改班级成员角色
def modify_user_course_role params def modify_user_course_role params,roles_id
status = -1 status = -1
c = Course.find("#{params[:id]}") c = Course.find("#{params[:id]}")
member = c.member_principals.includes(:roles, :principal).where("user_id=?",params[:user_id]).first # member = c.member_principals.includes(:roles, :principal).where("user_id=?",params[:user_id]).first
member = c.members.where("user_id=?",params[:user_id]).first
if member if member
role = Role.find(params[:role_id]) member.role_ids = roles_id
member.member_roles[0].role_id = params[:role_id] role = Role.find(roles_id[0])
# 这里的判断只能通过角色名,可以弄成常量 # 这里的判断只能通过角色名,可以弄成常量
if params[:role_id] == 10 if roles_id && roles_id.include?(10)
StudentsForCourse.create(:student_id => params[:user_id], :course_id =>params[:id]) StudentsForCourse.create(:student_id => params[:user_id], :course_id =>params[:id])
else else
joined = StudentsForCourse.where('student_id = ? and course_id = ?', params[:user_id],params[:id]) joined = StudentsForCourse.where('student_id = ? and course_id = ?', params[:user_id],params[:id])
@ -1090,7 +1242,7 @@ class CoursesService
Role.givable.all[3..5] Role.givable.all[3..5]
if member.member_roles[0].save if member.save
status = 0 status = 0
end end
end end

@ -3,6 +3,9 @@
class ProjectsService class ProjectsService
include ApplicationHelper include ApplicationHelper
include ApiHelper
include ActionView::Helpers::DateHelper
include ProjectsHelper
#获取指定用户的项目列表 #获取指定用户的项目列表
def user_projects(user) def user_projects(user)
@ -13,8 +16,8 @@ class ProjectsService
#显示项目 #显示项目
def show_project(params,current_user) def show_project(params,current_user)
project = Project.find(params[:id]) project = Project.find(params[:id])
# project.generate_invite_code project.generate_invite_code
# project.generate_qrcode project.generate_qrcode
project project
end end
@ -101,20 +104,22 @@ class ProjectsService
class JoinProjectError < Errors class JoinProjectError < Errors
define_error [ define_error [
0, '加入成功', 0, '您已成功加入项目',
1, '您的邀请码不正确', 1, '您的邀请码不正确',
2, '您还未登录', 2, '您还未登录',
3, '您已经是该项目的管理人员', 3, '您已经是该项目的管理人员',
4, '您已经是该项目的开发人员', 4, '您已经是该项目的开发人员',
5, '您已经是该项目的报告人员', 5, '您已经是该项目的报告人员',
6, '该项目不存在或已被删除啦', 6, '该项目不存在或已被删除啦',
7, '您的申请已提交,请等待管理员审批',
8, '您已经发送过申请了,请耐心等待',
'未知错误,请稍后再试' '未知错误,请稍后再试'
] ]
end end
def join_project params,current_user def join_project params,current_user
status = -1 status = -1
project = project.find_by_invite_code(params[:invite_code]) if params[:invite_code] project = Project.find_by_invite_code(params[:invite_code]) if params[:invite_code]
if project if project
if project[:is_delete] == 1 if project[:is_delete] == 1
@ -125,12 +130,31 @@ class ProjectsService
status = member.member_roles[0].role_id status = member.member_roles[0].role_id
else else
if params[:invite_code].present? if params[:invite_code].present?
members = []
members << Member.new(:role_ids => [5], :user_id => current_user.id) if params[:role] == 5
project.members << members members = []
projectInfo = ProjectInfo.new(:user_id => current_user.id, :project_id => project.id) user_grades = []
projectInfo.save project_info = []
status = 0
user_grades << UserGrade.new(:user_id => current_user.id, :project_id => project.id)
project.user_grades << user_grades unless user_grades.first.user_id.nil?
members << Member.new(:role_ids => ["5"], :user_id => current_user.id)
project.members << members
project_info << ProjectInfo.new(:user_id => current_user.id, :project_id => project.id)
project.project_infos << project_info
status = 0
else
if !AppliedProject.where(:project_id => project.id, :user_id => current_user.id).first.nil?
status = 8
else
AppliedProject.create(:user_id => current_user.id, :project_id => project.id, :role => params[:role])
status = 7
end
end
else else
status = 4 status = 4
end end
@ -142,4 +166,126 @@ class ProjectsService
status status
end end
def get_project_review_members(project,role_id,current_user)
review_members = []
if role_id == 3 || role_id == 4
#AppliedMessage.where(:applied_id => @applied_message.applied_id, :project_id => @applied_message.project_id, :status => 1,
#:applied_type => "AppliedProject")
apply_messages = AppliedMessage.where(:user_id => current_user.id, :project_id => project.id, :status => 1, :role=>role_id)
apply_messages.each do |m|
user = User.find(m.applied_user_id)
if user
img_url = url_to_avatar(user)
gender = user.user_extensions.gender.nil? ? 0 : user.user_extensions.gender
work_unit = get_user_work_unit user
location = get_user_location user
review_members << {:id => user.id, :img_url => img_url, :nickname => user.login, :gender => gender,
:work_unit => work_unit, :mail => user.mail, :location => location,
role_name: "",
name: user.show_name,
roles_id: role_id,
:brief_introduction => user.user_extensions.brief_introduction,:realname=>user.realname,:real_name=>user.realname}
end
end
end
review_members
end
def get_reviewer_info params
info = nil
project = Project.find(params[:project_id])
if project
messages = AppliedProject.where(:project_id=> project.id, :user_id=>params[:user_id]).first
if messages
user = User.find(params[:user_id])
if user
img_url = url_to_avatar(user)
gender = user.user_extensions.gender.nil? ? 0 : user.user_extensions.gender
work_unit = get_user_work_unit user
location = get_user_location user
info = {:id => user.id, :img_url => img_url, :nickname => user.login, :gender => gender,
:work_unit => work_unit, :mail => user.mail, :location => location,
role_name: "",
name: user.show_name,
roles_id: messages.role,
:brief_introduction => user.user_extensions.brief_introduction,:realname=>user.realname}
end
end
end
info
end
def deal_join_apply params,current_user
status = -1
message = ""
project = Project.find(params[:project_id])
user = User.find(params[:user_id])
if project
applied_messages = AppliedMessage.where(:user_id => current_user.id, :project_id => project.id, :status => 1, :applied_user_id=>user.id,:applied_type => "AppliedProject")
apply_message = applied_messages.first
if apply_message
if user.member_of?(project)
message = "已经是该项目的成员了"
applied_messages.update_all(:status=>7)
else
applied_project = apply_message.applied
ap_role = applied_project.try(:role)
if ap_role
rolename = ap_role == 3 ? "管理人员" : "开发人员"
if params[:type] == 0
#同意
members = []
user_grades = []
project_info = []
members << Member.new(:role_ids => ["#{ap_role}"], :user_id => user.id)
user_grades << UserGrade.new(:user_id => user.id, :project_id => project.id)
role = Role.find(ap_role)
project_info << ProjectInfo.new(:project_id => project.id, :user_id => user.id) if role.allowed_to?(:is_manager)
project.members << members
project.project_infos << project_info
project.user_grades << user_grades unless user_grades.first.user_id.nil?
# 添加成功后所有管理员收到的消息状态都要更新
applied_messages.update_all(:status => 7, :viewed => true)
# 添加成功后,申请人收到消息
AppliedMessage.create(:user_id => user.id, :applied_type => "AppliedProject", :applied_id => applied_project.id ,
:status => 6, :viewed => false, :applied_user_id => current_user.id, :role => applied_project.role, :project_id => applied_project.project_id)
message = "您已同意"+rolename+user.show_name+",加入项目"
else
#拒绝
AppliedMessage.create(:user_id => user.id, :applied_type => "AppliedProject", :applied_id => applied_project.id ,:status => 4,
:viewed => false, :applied_user_id => current_user.id, :role => applied_project.role, :project_id => applied_project.project_id)
applied_messages.update_all(:status => 5, :viewed => true)
applied_project.delete
message = "您已拒绝"+rolename+user.show_name+",加入项目"
end
status = 0
else
message = "该申请不存在或已被处理"
end
end
else
message = "该申请不存在或已被处理"
end
else
message = "该项目不存在或已被删除"
end
{:status => status,:message => message}
end
end end

@ -139,11 +139,16 @@ class WechatService
data data
end end
def three_keys_template(openid, template_id, type, id, first, key1, key2, key3, remark="") def three_keys_template(openid, template_id, type, id, first, key1, key2, key3, remark="",uid)
tmpurl = "#{Setting.protocol}://#{Setting.host_name}/wechat/user_activities#/#{type}/#{id}"
if uid && uid != 0
tmpurl = "#{Setting.protocol}://#{Setting.host_name}/wechat/user_activities#/#{type}?id=#{id}"+ "&user_id="+uid.to_s
end
data = { data = {
touser:openid, touser:openid,
template_id:template_id, template_id:template_id,
url:"#{Setting.protocol}://#{Setting.host_name}/wechat/user_activities#/#{type}/#{id}",#/assets/wechat/app.html#/#{type}/#{id} url:tmpurl,#/assets/wechat/app.html#/#{type}/#{id}
topcolor:"#FF0000", topcolor:"#FF0000",
data:{ data:{
first: { first: {
@ -171,11 +176,16 @@ class WechatService
data data
end end
def four_keys_template(openid, template_id, type, id, first, key1, key2, key3, key4, remark="") def four_keys_template(openid, template_id, type, id, first, key1, key2, key3, key4, remark="",uid)
tmpurl = "#{Setting.protocol}://#{Setting.host_name}/wechat/user_activities#/#{type}/#{id}"
if uid && uid != 0
tmpurl = "#{Setting.protocol}://#{Setting.host_name}/wechat/user_activities#/#{type}?id=#{id}"+ "&user_id="+uid.to_s
end
data = { data = {
touser:openid, touser:openid,
template_id:template_id, template_id:template_id,
url:"#{Setting.protocol}://#{Setting.host_name}/wechat/user_activities#/#{type}/#{id}", #/assets/wechat/app.html#/#{type}/#{id} url:tmpurl, #/assets/wechat/app.html#/#{type}/#{id}
topcolor:"#FF0000", topcolor:"#FF0000",
data:{ data:{
first: { first: {
@ -269,10 +279,10 @@ class WechatService
end end
end end
def class_notice(user_id, type, id, first, key1, key2, key3, key4, remark="") def class_notice(user_id, type, id, first, key1, key2, key3, key4, remark="",uid=0)
uw = UserWechat.where(user_id: user_id).first uw = UserWechat.where(user_id: user_id).first
unless uw.nil? unless uw.nil?
data = four_keys_template uw.openid,Wechat.config.class_notice, type, id, first, key1, key2, key3, key4, remark data = four_keys_template uw.openid,Wechat.config.class_notice, type, id, first, key1, key2, key3, key4, remark, uid
begin begin
req = Wechat.api.template_message_send Wechat::Message.to(uw.openid).template(data) req = Wechat.api.template_message_send Wechat::Message.to(uw.openid).template(data)
rescue Exception => e rescue Exception => e
@ -360,4 +370,17 @@ class WechatService
end end
end end
def project_review_notice(user_id, type, id, first, key1, key2,key3,remark="",uid=0)
uw = UserWechat.where(user_id: user_id).first
unless uw.nil?
data = three_keys_template uw.openid,Wechat.config.project_review_notice, type, id, first, key1, key2, key3, remark,uid
begin
req = Wechat.api.template_message_send Wechat::Message.to(uw.openid).template(data)
rescue Exception => e
Rails.logger.error "[project_review_notice] ===> #{e}"
end
Rails.logger.info "send over. #{req}"
end
end
end end

@ -12,15 +12,40 @@
<link type="text/css" rel="stylesheet" href="/stylesheets/weui/weui.min.css" /> <link type="text/css" rel="stylesheet" href="/stylesheets/weui/weui.min.css" />
<%= stylesheet_link_tag '/stylesheets/weui/weixin.css' %> <%= stylesheet_link_tag '/stylesheets/weui/weixin.css' %>
<script src="//res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
<script type="text/javascript"> <script type="text/javascript">
window.g_debug = false; //调试标志,如果在本地请置为true window.g_debug = false; //调试标志,如果在本地请置为true
window.apiUrl = '/api/v1/'; window.apiUrl = '/api/v1/';
window.g_redirect_path = '<%= @path %>'; window.g_redirect_path = '<%= @path %>';
window.g_localhost = "<%= Setting.protocol%>://"+"<%= Setting.host_name%>";
<% if @course_id %> <% if @course_id %>
window.g_courseid = <%= @course_id %>; window.g_courseid = <%= @course_id %>;
<% elsif @project_id %> <% elsif @project_id %>
window.g_projectid = <%= @project_id %>; window.g_projectid = <%= @project_id %>;
<% end %> <% end %>
//参考文档
//https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115&token=&lang=zh_CN
<% unless @sign_params.nil? %>
wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来若要查看传入的参数可以在pc端打开参数信息会通过log打出仅在pc端时才会打印。
appId: '<%= @appid %>', // 必填,公众号的唯一标识
timestamp: <%= @sign_params[:timestamp] %>, // 必填,生成签名的时间戳
nonceStr: '<%= @sign_params[:noncestr] %>', // 必填,生成签名的随机串
signature: '<%= @sign_params[:signature] %>',// 必填签名见附录1
jsApiList: ['onMenuShareTimeline', 'onMenuShareAppMessage', 'onMenuShareQQ', 'onMenuShareWeibo', 'onMenuShareQZone',
'hideOptionMenu','showOptionMenu','showMenuItems', 'hideMenuItems',
'hideAllNonBaseMenuItem','showAllNonBaseMenuItem','closeWindow', 'scanQRCode'] // 必填需要使用的JS接口列表所有JS接口列表见附录2
});
<% end %>
wx.ready(function(){
console.log("wx ready");
});
wx.error(function(err){
console.log(err);
});
</script> </script>
</head> </head>

@ -3,6 +3,7 @@ require File.expand_path('../boot', __FILE__)
require 'rails/all' require 'rails/all'
require 'sprockets/railtie' require 'sprockets/railtie'
require 'elasticsearch/model' require 'elasticsearch/model'
if defined?(Bundler) if defined?(Bundler)
# If you precompile assets before deploying to production, use this line # If you precompile assets before deploying to production, use this line
Bundler.require(*Rails.groups(:assets => %w(development test))) Bundler.require(*Rails.groups(:assets => %w(development test)))
@ -83,9 +84,11 @@ module RedmineApp
end end
end end
config.wechat_srcs = ['app.js','others/factory.js','others/filter.js', 'controllers/*.js', 'directives/*.js', 'others/routes.js'] config.wechat_srcs = ['app.js','others/factory.js','others/filter.js', 'controllers/*.js', 'directives/*.js', 'others/routes.js']
config.before_initialize do config.before_initialize do
config.middleware.use ::ResponseIp
end end
config.after_initialize do config.after_initialize do

@ -1,5 +1,15 @@
#coding=utf-8
#
require 'active_record' require 'active_record'
## ruby2.3在这个rails版本的activerecord有bug, 直接用respond_to?(:to_proc)作判断
#而ruby2.3中hash可以返回 to_proc
if RUBY_VERSION > '2.3' && Rails.version < '3.2.22.3'
Hash.class_eval do
remove_method :to_proc
end
end
module ActiveRecord module ActiveRecord
class Base class Base
include Redmine::I18n include Redmine::I18n

@ -23,13 +23,13 @@ button:
name: "更多" name: "更多"
sub_button: sub_button:
- -
type: "click" type: "view"
name: "加入班级" name: "加入班级"
key: "JOIN_CLASS" 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=join_class#wechat_redirect"
- -
type: "click" type: "view"
name: "加入项目" name: "加入项目"
key: "JOIN_PROJECT" 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=join_project#wechat_redirect"
- -
type: "view" type: "view"
name: "历史推文" name: "历史推文"

@ -23,13 +23,13 @@ button:
name: "更多" name: "更多"
sub_button: sub_button:
- -
type: "click" type: "view"
name: "加入班级" name: "加入班级"
key: "JOIN_CLASS" url: "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxc09454f171153c2d&redirect_uri=https://test.forge.trustie.net/wechat/user_activities&response_type=code&scope=snsapi_base&state=join_class#wechat_redirect"
- -
type: "click" type: "view"
name: "加入项目" name: "加入项目"
key: "JOIN_PROJECT" url: "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxc09454f171153c2d&redirect_uri=https://test.forge.trustie.net/wechat/user_activities&response_type=code&scope=snsapi_base&state=join_project#wechat_redirect"
- -
type: "view" type: "view"
name: "历史推文" name: "历史推文"

@ -22,7 +22,7 @@ default: &default
class_notice: "MQ_mFupbXP-9jWbeHT3C5xqNBvPo8EIlNv4ULakSpJA" class_notice: "MQ_mFupbXP-9jWbeHT3C5xqNBvPo8EIlNv4ULakSpJA"
create_class_notice: "2GtJJGzzNlNy2i0UrsjEDlvfSVIUXQfSo47stpcQAVw" create_class_notice: "2GtJJGzzNlNy2i0UrsjEDlvfSVIUXQfSo47stpcQAVw"
create_project_notice: "jYu0iimbDpgWYZaTLXioZe2lvqoWTdKnUPyphTJ1mxs" create_project_notice: "jYu0iimbDpgWYZaTLXioZe2lvqoWTdKnUPyphTJ1mxs"
project_review_notice: "kdb-8UlMjTc3z51Qcf8g2vY4i_nE4OGKZAucdQma_2E"
production: production:
<<: *default <<: *default

@ -22,6 +22,7 @@ default: &default
class_notice: "8LVu33l6bP-56SDomVgHn-yJc57YpCwwJ81rAJgRONk" class_notice: "8LVu33l6bP-56SDomVgHn-yJc57YpCwwJ81rAJgRONk"
create_class_notice: "9CDIvHIKiGwPEQWRw_-wieec1o50tMXQPPZIfECKu0I" create_class_notice: "9CDIvHIKiGwPEQWRw_-wieec1o50tMXQPPZIfECKu0I"
create_project_notice: "R2ZaQKJfDJgujPcHWPzadKHIRkIyj2CjX2o_qIuRqig" create_project_notice: "R2ZaQKJfDJgujPcHWPzadKHIRkIyj2CjX2o_qIuRqig"
project_review_notice: "cwpAHzdrYQo0Gc5ZKCBHMYEe8NjlOF6KpMGklMch8RM"
production: production:
<<: *default <<: *default

File diff suppressed because it is too large Load Diff

@ -0,0 +1,20 @@
#coding=utf-8
#
require 'socket'
class ResponseIp
def initialize(app)
@app = app
end
def ip
addr = Socket.ip_address_list.detect{|intf| intf.ipv4_private?}.ip_address rescue
addr || ''
end
def call(env)
status, headers, body = @app.call(env)
headers["X-response-ip"] = ip
[status, headers, body]
end
end

@ -36,7 +36,7 @@
<script src="/javascripts/wechat/directives/form_validate.js"></script> <script src="/javascripts/wechat/directives/form_validate.js"></script>
<script src="/javascripts/wechat/directives/input_auto.js"></script> <script src="/javascripts/wechat/directives/input_auto.js"></script>
<script src="/javascripts/wechat/directives/loading_spinner.js"></script> <script src="/javascripts/wechat/directives/loading_spinner.js"></script>
<!--<script src="/javascripts/wechat/directives/ellipsis.js"></script>--> <script src="/javascripts/wechat/directives/ellipsis.js"></script>
<script src="/javascripts/wechat/controllers/reg.js"></script> <script src="/javascripts/wechat/controllers/reg.js"></script>
<script src="/javascripts/wechat/controllers/login.js"></script> <script src="/javascripts/wechat/controllers/login.js"></script>
<script src="/javascripts/wechat/controllers/activity.js"></script> <script src="/javascripts/wechat/controllers/activity.js"></script>

@ -34,9 +34,17 @@
<img ng-src="/images/wechat/{{teacher.gender==0 ? 'male' : 'female'}}.jpg" width="30" class="fl ml10 img-circle" /><span class="fl ml10 mt5">{{teacher.name}}</span><img ng-src="/images/wechat/{{teacher.gender==0 ? 'male' : 'female'}}.png" width="15" class="fl ml10 mt5" /> <img ng-src="/images/wechat/{{teacher.gender==0 ? 'male' : 'female'}}.jpg" width="30" class="fl ml10 img-circle" /><span class="fl ml10 mt5">{{teacher.name}}</span><img ng-src="/images/wechat/{{teacher.gender==0 ? 'male' : 'female'}}.png" width="15" class="fl ml10 mt5" />
<img src="/images/wechat/setting.png" ng-show = "course.is_creator && teacher.id != course.tea_id" width="15" class="fr mr10" style="margin-top:7px;" ng-click="onSetting(teacher)" /> <img src="/images/wechat/setting.png" ng-show = "course.is_creator && teacher.id != course.tea_id" width="15" class="fr mr10" style="margin-top:7px;" ng-click="onSetting(teacher)" />
<span class = "fr mr25 mt5" ng-show ="teacher.id == course.tea_id">管理员</span> <span class = "fr mr25 mt5" ng-show ="teacher.id == course.tea_id">管理员</span>
<span ng-class="['fr','mt5',{'mr10': course.is_creator,'mr25': !course.is_creator}]" ng-show ="teacher.id != course.tea_id && teacher.roles_id == 7"></span> <span ng-class="['fr','mt5',{'mr10': course.is_creator,'mr25': !course.is_creator}]" ng-show ="teacher.id != course.tea_id && teacher.roles_id == 7"></span>
<div class="cl"></div> <div class="cl"></div>
</div> </div>
<div ng-show ="course.is_creator" class="class-member-row f13 c-grey3" ng-repeat="reviewer in reviewers|filter:searchText">
<img ng-src="/images/wechat/{{reviewer.gender==0 ? 'male' : 'female'}}.jpg" width="30" class="fl ml10 img-circle" /><span class="fl ml10 mt5">{{reviewer.name}}</span><img ng-src="/images/wechat/{{reviewer.gender==0 ? 'male' : 'female'}}.png" width="15" class="fl ml10 mt5" />
<span ng-click="review(reviewer)" class = "fr mr10 mt5 c-red">待审批 ▶</span>
<div class="cl"></div>
</div>
<div class="member-banner f13 mt10 c-grey3">我的同学</div> <div class="member-banner f13 mt10 c-grey3">我的同学</div>
<div class="class-member-row f13 c-grey3" ng-repeat="student in students|filter:searchText"> <div class="class-member-row f13 c-grey3" ng-repeat="student in students|filter:searchText">
<img ng-src="/images/wechat/{{student.gender==0 ? 'male' : 'female'}}.jpg" width="30" class="fl ml10 img-circle" /><span class="fl ml10 mt5">{{student.name}}</span><img ng-src="/images/wechat/{{student.gender==0 ? 'male' : 'female'}}.png" width="15" class="fl ml10 mt5" /> <img ng-src="/images/wechat/{{student.gender==0 ? 'male' : 'female'}}.jpg" width="30" class="fl ml10 img-circle" /><span class="fl ml10 mt5">{{student.name}}</span><img ng-src="/images/wechat/{{student.gender==0 ? 'male' : 'female'}}.png" width="15" class="fl ml10 mt5" />

@ -5,9 +5,9 @@
<div class="class-detail-row f13 c-grey3"><img ng-src="/images/wechat/{{current_edit_member.user.gender==0 ? 'male' : 'female'}}.jpg" width="30" class="fl ml10 img-circle mt4" /><span class="fl mt10 ml10">{{current_edit_member.user.realname == "" ? current_edit_member.user.name : current_edit_member.user.realname}}</span><img ng-src="/images/wechat/{{current_edit_member.user.gender==0 ? 'male' : 'female'}}.png" width="15" class="fl ml10 mt10" /><div class="cl"></div> </div> <div class="class-detail-row f13 c-grey3"><img ng-src="/images/wechat/{{current_edit_member.user.gender==0 ? 'male' : 'female'}}.jpg" width="30" class="fl ml10 img-circle mt4" /><span class="fl mt10 ml10">{{current_edit_member.user.realname == "" ? current_edit_member.user.name : current_edit_member.user.realname}}</span><img ng-src="/images/wechat/{{current_edit_member.user.gender==0 ? 'male' : 'female'}}.png" width="15" class="fl ml10 mt10" /><div class="cl"></div> </div>
<div class="course-list-row f13 c-grey3 mt10"><span class="fl ml10">角色</span></div> <div class="course-list-row f13 c-grey3 mt10"><span class="fl ml10">角色</span></div>
<ul class="class-list f13 c-grey3"> <ul class="class-list f13 c-grey3">
<li><span class="fl ml10 class-list-name hidden">教师</span><span ng-click="selectRole(9)" ng-class="['login-box', 'fr', 'mr10', 'mt12','img-circle', {'checked': current_edit_member.roles_id == 9}]"></span></li> <li><span class="fl ml10 class-list-name hidden">教师</span><span ng-click="selectRole(9)" ng-class="['login-box', 'fr', 'mr10', 'mt12', {'bg-grey':assistant,'checked': teacher}]"></span></li>
<li><span class="fl ml10 class-list-name hidden"></span><span ng-click="selectRole(7)" ng-class="['login-box', 'fr', 'mr10', 'mt12','img-circle', {'checked': current_edit_member.roles_id == 7}]"></span></li> <li><span class="fl ml10 class-list-name hidden"></span><span ng-click="selectRole(7)" ng-class="['login-box', 'fr', 'mr10', 'mt12', {'bg-grey':teacher, 'checked': assistant}]"></span></li>
<li class="border-bottom-none"><span class="fl ml10 class-list-name hidden">学生</span><span ng-click="selectRole(10)" ng-class="['login-box', 'fr', 'mr10', 'mt12','img-circle', {'checked': current_edit_member.roles_id == 10}]"></span></li> <li class="border-bottom-none"><span class="fl ml10 class-list-name hidden">学生</span><span ng-click="selectRole(10)" ng-class="['login-box', 'fr', 'mr10', 'mt12', {'checked': student}]"></span></li>
</ul> </ul>
<div class="bottom-tab-wrap mt10"> <div class="bottom-tab-wrap mt10">
<a href="javascript:void(0);" ng-click="cancel()" class="weixin-tab c-grey border-top">取消</a> <a href="javascript:void(0);" ng-click="cancel()" class="weixin-tab c-grey border-top">取消</a>
@ -15,7 +15,5 @@
</div> </div>
</div> </div>
<my-alert message="alertService.message" title="alertService.title" visible="alertService.visible" cb="alertService.cb"></my-alert> <my-alert message="alertService.message" title="alertService.title" visible="alertService.visible" cb="alertService.cb"></my-alert>
</div> </div>

@ -0,0 +1,28 @@
<div class="post-container">
<div loading-spinner></div>
<div class="post-container" style="padding-bottom:50px;">
<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" ng-model="invite_code" required placeholder="请输入5位邀请码" /></div>
<div class="course-list-row f13 c-grey3 mt10"><span class="fl ml15">角色</span></div>
<ul class="class-list f13 c-grey3">
<li><span class="fl ml10 class-list-name hidden">教师</span><span ng-click="selectRole(9)" ng-class="['login-box', 'fr', 'mr10', 'mt12', {'bg-grey':assistant,'checked': teacher}]"></span></li>
<li><span class="fl ml10 class-list-name hidden">助教</span><span ng-click="selectRole(7)" ng-class="['login-box', 'fr', 'mr10', 'mt12', {'bg-grey':teacher, 'checked': assistant}]"></span></li>
<li class="border-bottom-none"><span class="fl ml10 class-list-name hidden">学生</span><span ng-click="selectRole(10)" ng-class="['login-box', 'fr', 'mr10', 'mt12', {'checked': student}]"></span></li>
</ul>
<div class="f12 c-grey6 mt10 ml15">
<span class="f13 fb c-grey3">提示</span>
<ul class="mb15 mt5 ml10 new-tip">
<li><span class="project-intro-dot"></span>教师、助教角色需要班级管理员审批</li>
<li><span class="project-intro-dot"></span>学生角色无需管理员审批</li>
</ul>
</div>
<div class="bottom-tab-wrap mt10">
<a href="javascript:void(0);" ng-click="cancel()" class="weixin-tab c-grey border-top">取消</a>
<a href="javascript:void(0);" ng-click="joinClass()" class="weixin-tab link-blue2 border-top">确定</a>
</div>
</div>
<my-alert message="alertService.message" title="alertService.title" visible="alertService.visible" cb="alertService.cb"></my-alert>
</div>

@ -0,0 +1,20 @@
<div class="post-container">
<div loading-spinner></div>
<div class="post-container" style="padding-bottom:50px;">
<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" ng-model="invite_code" required placeholder="请输入6位邀请码" /></div>
<div class="course-list-row f13 c-grey3 mt10"><span class="fl ml15">角色</span></div>
<ul class="class-list f13 c-grey3">
<li><span class="fl ml10 class-list-name hidden">管理人员</span><span ng-click="selectRole(3)" ng-class="['login-box', 'fr', 'mr10', 'mt12','img-circle', {'checked': role_id == 3}]"></span></li>
<li><span class="fl ml10 class-list-name hidden">开发人员</span><span ng-click="selectRole(4)" ng-class="['login-box', 'fr', 'mr10', 'mt12','img-circle', {'checked': role_id == 4}]"></span></li>
<li class="border-bottom-none"><span class="fl ml10 class-list-name hidden">报告人员</span><span ng-click="selectRole(5)" ng-class="['login-box', 'fr', 'mr10', 'mt12','img-circle', {'checked': role_id == 5}]"></span></li>
</ul>
<div class="bottom-tab-wrap mt10">
<a href="javascript:void(0);" ng-click="cancel()" class="weixin-tab c-grey border-top">取消</a>
<a href="javascript:void(0);" ng-click="join_project()" class="weixin-tab link-blue2 border-top">确定</a>
</div>
</div>
<my-alert message="alertService.message" title="alertService.title" visible="alertService.visible" cb="alertService.cb"></my-alert>
</div>

@ -1,26 +1,26 @@
<div class="post-container"> <div class="post-container">
<div loading-spinner></div> <div loading-spinner></div>
<div class="blue-title">新建项目</div> <div class="blue-title">新建项目</div>
<form novalidate name="classForm"> <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="project.name" required placeholder="如:团队协作方法与机制研究" /></div> <div class="course-list-row f13 c-grey3 mt30"><span class="fl ml15 c-grey3">项目名称</span><input class="new-class-input ml25" ng-model="project.name" required placeholder="如:团队协作方法与机制研究" /></div>
<a ng-click="newProject(classForm, project)" ng-class="['finish-btn', {'btn-disabled':!classForm.$valid} ]" >完成</a> <a ng-click="newProject(classForm, project)" ng-class="['finish-btn', {'btn-disabled':!classForm.$valid} ]" >完成</a>
<div class="f12 c-grey6 tac"> <div class="f12 c-grey6 tac">
<span class="f13 fb c-grey3">项目功能特性(微信版)</span> <span class="f13 fb c-grey3">项目功能特性(微信版)</span>
<ul class="project-intro mb15 mt5"> <ul class="project-intro mb15 mt5">
<li>创建项目、加入项目</li> <li><span class="project-intro-dot"></span>创建项目、加入项目</li>
<li>邀请成员、修改角色</li> <li><span class="project-intro-dot"></span>邀请成员、修改角色</li>
<li>浏览、回复项目动态</li> <li><span class="project-intro-dot"></span>浏览、回复项目动态</li>
<li>点赞、分享项目动态</li> <li><span class="project-intro-dot"></span>点赞、分享项目动态</li>
</ul> </ul>
<span class="f13 fb c-grey3">更多项目特性(浏览器版)</span> <span class="f13 fb c-grey3">更多项目特性(浏览器版)</span>
<ul class="project-intro mt5"> <ul class="project-intro mt5">
<li>发布任务、问题跟踪</li> <li><span class="project-intro-dot"></span>发布任务、问题跟踪</li>
<li>代码托管、质量分析</li> <li><span class="project-intro-dot"></span>代码托管、质量分析</li>
<li>资源分享、交流研讨</li> <li><span class="project-intro-dot"></span>资源分享、交流研讨</li>
</ul> </ul>
</div> </div>
</form> </form>
<my-alert message="alertService.message" title="alertService.title" visible="alertService.visible" cb="alertService.cb"></my-alert> <my-alert message="alertService.message" title="alertService.title" visible="alertService.visible" cb="alertService.cb"></my-alert>
</div> </div>

@ -5,7 +5,7 @@
<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> <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>
<div ng-class="{'undis': currentTab != 1}"> <div ng-show="project" ng-class="{'undis': currentTab != 1}">
<div ng-repeat="act in project_activities"> <div ng-repeat="act in project_activities">
<div ng-if="act.container_type=='Project' "> <div ng-if="act.container_type=='Project' ">
<div ng-if="act.act_type=='Issue'"> <div ng-if="act.act_type=='Issue'">
@ -30,7 +30,7 @@
</div> </div>
<div class="cl"></div> <div class="cl"></div>
</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 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" 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.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>
@ -67,7 +67,7 @@
</div> </div>
<div class="cl"></div> <div class="cl"></div>
</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 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" 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.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>
@ -102,7 +102,7 @@
</div> </div>
</div> </div>
<div ng-class="{'undis': currentTab != 2}"> <div ng-show="project" ng-class="{'undis': currentTab != 2}">
<div class="class-search-wrap"> <div class="class-search-wrap">
<div class="class-search-inner"> <img src="/images/wechat/search.png" width="18" class="class-search-icon" /> <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="输入关键词进行搜索" /> <input class="class-detail-search" ng-model="searchText" placeholder="输入关键词进行搜索" />
@ -110,16 +110,27 @@
</div> </div>
<div class="member-banner f13 c-grey3">管理人员({{project_master_members.length}})</div> <div class="member-banner f13 c-grey3">管理人员({{project_master_members.length}})</div>
<div class="class-member-row f13 c-grey3" ng-repeat="master in project_master_members|filter:searchText"> <div class="class-member-row f13 c-grey3" ng-repeat="master in project_master_members|filter:searchText">
<img ng-src="/images/wechat/{{master.user.gender==0 ? 'male' : 'female'}}.jpg" width="30" class="fl ml10 img-circle" /><span class="fl ml10 mt5">{{master.user.real_name == "" ? master.user.name : master.user.real_name }}</span><span class="fr mr10 c-grey2">{{teacher.role_name|identify}}</span><img ng-src="/images/wechat/{{master.user.gender==0 ? 'male' : 'female'}}.png" width="15" class="fl ml10 mt5" /> <img ng-src="/images/wechat/{{master.user.gender==0 ? 'male' : 'female'}}.jpg" width="30" class="fl ml10 img-circle" /><span class="fl ml10 mt5">{{master.user.real_name == "" ? master.user.name : master.user.real_name }}</span><img ng-src="/images/wechat/{{master.user.gender==0 ? 'male' : 'female'}}.png" width="15" class="fl ml10 mt5" />
<img src="/images/wechat/setting.png" ng-show = "master.user.id != project.user_id && project.can_setting" width="15" class="class-list-setting" ng-click="onSetting(master)" /> <img src="/images/wechat/setting.png" ng-show = "master.user.id != project.user_id && project.can_setting" width="15" class="class-list-setting" ng-click="onSetting(master)" />
<div class="cl"></div> <div class="cl"></div>
</div> </div>
<div ng-show="project.can_setting" class="class-member-row f13 c-grey3" ng-repeat="user in review_master_members|filter:searchText">
<img ng-src="/images/wechat/{{user.gender==0 ? 'male' : 'female'}}.jpg" width="30" class="fl ml10 img-circle" /><span class="fl ml10 mt5">{{user.real_name == "" ? user.name : user.real_name }}</span><span class="fr mr10 c-grey2"></span><img ng-src="/images/wechat/{{user.gender==0 ? 'male' : 'female'}}.png" width="15" class="fl ml10 mt5" />
<span ng-click="review(user)" class = "fr mr10 mt5 c-red">待审批 ▶</span>
<div class="cl"></div>
</div>
<div class="member-banner f13 mt10 c-grey3">开发人员({{project_develop_members.length}})</div> <div class="member-banner f13 mt10 c-grey3">开发人员({{project_develop_members.length}})</div>
<div class="class-member-row f13 c-grey3" ng-repeat="develop in project_develop_members|filter:searchText"> <div class="class-member-row f13 c-grey3" ng-repeat="develop in project_develop_members|filter:searchText">
<img ng-src="/images/wechat/{{develop.user.gender==0 ? 'male' : 'female'}}.jpg" width="30" class="fl ml10 img-circle" /><span class="fl ml10 mt5">{{develop.user.real_name == "" ? develop.user.name : develop.user.real_name}}</span><img ng-src="/images/wechat/{{develop.user.gender==0 ? 'male' : 'female'}}.png" width="15" class="fl ml10 mt5" /> <img ng-src="/images/wechat/{{develop.user.gender==0 ? 'male' : 'female'}}.jpg" width="30" class="fl ml10 img-circle" /><span class="fl ml10 mt5">{{develop.user.real_name == "" ? develop.user.name : develop.user.real_name}}</span><img ng-src="/images/wechat/{{develop.user.gender==0 ? 'male' : 'female'}}.png" width="15" class="fl ml10 mt5" />
<img src="/images/wechat/setting.png" ng-show = "master.user.id != project.user_id && project.can_setting " width="15" class="class-list-setting" ng-click="onSetting(develop)" /> <img src="/images/wechat/setting.png" ng-show = "master.user.id != project.user_id && project.can_setting " width="15" class="class-list-setting" ng-click="onSetting(develop)" />
<div class="cl"></div> <div class="cl"></div>
</div> </div>
<div ng-show="project.can_setting" class="class-member-row f13 c-grey3" ng-repeat="user in review_develop_members|filter:searchText">
<img ng-src="/images/wechat/{{user.gender==0 ? 'male' : 'female'}}.jpg" width="30" class="fl ml10 img-circle" /><span class="fl ml10 mt5">{{user.real_name == "" ? user.name : user.real_name}}</span><img ng-src="/images/wechat/{{user.gender==0 ? 'male' : 'female'}}.png" width="15" class="fl ml10 mt5" />
<span ng-click="review(user)" class = "fr mr10 mt5 c-red">待审批 ▶</span>
<div class="cl"></div>
</div>
<div class="member-banner f13 mt10 c-grey3">报告人员({{project_report_members.length}})</div> <div class="member-banner f13 mt10 c-grey3">报告人员({{project_report_members.length}})</div>
<div class="class-member-row f13 c-grey3" ng-repeat="report in project_report_members|filter:searchText"> <div class="class-member-row f13 c-grey3" ng-repeat="report in project_report_members|filter:searchText">
<img ng-src="/images/wechat/{{report.user.gender==0 ? 'male' : 'female'}}.jpg" width="30" class="fl ml10 img-circle" /><span class="fl ml10 mt5">{{report.user.real_name == "" ? report.user.name : report.user.real_name}}</span><img ng-src="/images/wechat/{{report.user.gender==0 ? 'male' : 'female'}}.png" width="15" class="fl ml10 mt5" /> <img ng-src="/images/wechat/{{report.user.gender==0 ? 'male' : 'female'}}.jpg" width="30" class="fl ml10 img-circle" /><span class="fl ml10 mt5">{{report.user.real_name == "" ? report.user.name : report.user.real_name}}</span><img ng-src="/images/wechat/{{report.user.gender==0 ? 'male' : 'female'}}.png" width="15" class="fl ml10 mt5" />

@ -0,0 +1,18 @@
<div class="post-container">
<div loading-spinner></div>
<div ng-show="current_course && current_review_member " class="post-container" style="padding-bottom:50px;">
<div class="blue-title">{{current_course.name}}</div>
<div class="class-detail-row f13 c-grey3"><img ng-src="/images/wechat/{{current_review_member.gender==0 ? 'male' : 'female'}}.jpg" width="30" class="fl ml10 img-circle mt4" /><span class="fl mt10 ml10">{{current_review_member.realname == "" ? current_review_member.name : current_review_member.realname}}</span><img ng-src="/images/wechat/{{current_review_member.gender==0 ? 'male' : 'female'}}.png" width="15" class="fl ml10 mt10" /><div class="cl"></div> </div>
<div class="course-list-row f13 c-grey3 mt10"><span class="fl ml10">角色</span></div>
<ul class="class-list f13 c-grey3">
<li><span class="fl ml10 class-list-name hidden">教师</span><span ng-class="['login-box', 'fr', 'mr10', 'mt12', {'bg-grey':current_review_member.roles_id == 7,'checked': current_review_member.roles_id == 9}]"></span></li>
<li class="border-bottom-none"><span class="fl ml10 class-list-name hidden">助教</span><span ng-class="['login-box', 'fr', 'mr10', 'mt12', {'bg-grey':current_review_member.roles_id == 9, 'checked': current_review_member.roles_id == 7}]"></span></li>
</ul>
<div class="bottom-tab-wrap mt10">
<a href="javascript:void(0);" ng-click="deal(1)" class="weixin-tab c-grey border-top">拒绝</a>
<a href="javascript:void(0);" ng-click="deal(0)" class="weixin-tab link-blue2 border-top">同意</a>
</div>
</div>
<my-alert message="alertService.message" title="alertService.title" visible="alertService.visible" cb="alertService.cb"></my-alert>
</div>

@ -0,0 +1,19 @@
<div class="post-container">
<div loading-spinner></div>
<div ng-show="current_review_member" class="post-container" style="padding-bottom:50px;">
<div class="blue-title">{{project.name}}</div>
<div class="class-detail-row f13 c-grey3"><img ng-src="/images/wechat/{{current_review_member.gender==0 ? 'male' : 'female'}}.jpg" width="30" class="fl ml10 img-circle mt4" /><span class="fl mt10 ml10">{{current_review_member.realname == "" ? current_review_member.name : current_review_member.realname}}</span><img ng-src="/images/wechat/{{current_review_member.gender==0 ? 'male' : 'female'}}.png" width="15" class="fl ml10 mt10" /><div class="cl"></div> </div>
<div class="course-list-row f13 c-grey3 mt10"><span class="fl ml10">角色</span></div>
<ul class="class-list f13 c-grey3">
<li><span class="fl ml10 class-list-name hidden">管理人员</span><span ng-class="['login-box', 'fr', 'mr10', 'mt12','img-circle',{'bg-grey':current_review_member.roles_id == 4,'checked': current_review_member.roles_id == 3}]"></span></li>
<li class="border-bottom-none"><span class="fl ml10 class-list-name hidden">开发人员</span><span ng-class="['login-box', 'fr', 'mr10', 'mt12','img-circle',{'bg-grey':current_review_member.roles_id == 3,'checked': current_review_member.roles_id == 4}]"></span></li>
</ul>
<div class="bottom-tab-wrap mt10">
<a href="javascript:void(0);" ng-click="deal(1)" class="weixin-tab c-grey border-top">拒绝</a>
<a href="javascript:void(0);" ng-click="deal(0)" class="weixin-tab link-blue2 border-top">同意</a>
</div>
</div>
<my-alert message="alertService.message" title="alertService.title" visible="alertService.visible" cb="alertService.cb"></my-alert>
</div>

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

@ -15,6 +15,17 @@ app.controller('ClassController', ['$scope', 'config','$http', 'auth','$location
) )
} }
if(vm.course.is_creator){
if(vm.reviewers.length<=0){
$http.get(config.apiUrl + 'courses/reviewers?token='+auth.token()+'&course_id='+courseid).then(
function(response) {
console.log(response.data);
vm.reviewers = response.data.data;
}
)
}
}
if(vm.students.length<=0){ if(vm.students.length<=0){
$http.get(config.apiUrl + 'courses/students?token='+auth.token()+'&course_id='+courseid).then( $http.get(config.apiUrl + 'courses/students?token='+auth.token()+'&course_id='+courseid).then(
function(response) { function(response) {
@ -100,6 +111,7 @@ app.controller('ClassController', ['$scope', 'config','$http', 'auth','$location
vm.course = {}; vm.course = {};
vm.students = []; vm.students = [];
vm.teachers = []; vm.teachers = [];
vm.reviewers = []; //待审批
vm.resources = []; vm.resources = [];
vm.homeworks = []; vm.homeworks = [];
vm.exercises = []; vm.exercises = [];
@ -157,6 +169,12 @@ app.controller('ClassController', ['$scope', 'config','$http', 'auth','$location
$location.path("/edit_class_member").search({id: courseid,user_id: user.id}); $location.path("/edit_class_member").search({id: courseid,user_id: user.id});
}; };
vm.review = function(user){
rms.save('current_review_member', user);
rms.save('current_course', vm.course);
$location.path("/review_class_member").search({id: courseid,user_id: user.id});
}

@ -16,6 +16,27 @@ app.controller('ClassListController', ['$scope', 'config', 'auth', '$http', '$lo
function (response) { function (response) {
console.log(response.data); console.log(response.data);
vm.syllabuses = response.data.data; vm.syllabuses = response.data.data;
var show_1 = false;
var show_2 = false;
for (var i in vm.syllabuses) {
if(vm.syllabuses[i].can_setting && vm.syllabuses[i].courses.length > 0 && show_1 == false ){
vm.syllabuses[i].show_plus = true;
show_1 = true;
}
if(!vm.syllabuses[i].can_setting && vm.syllabuses[i].courses.length > 0 && show_2 == false ){
vm.syllabuses[i].show_plus = true;
show_2 = true;
}
if(show_1 && show_2){
break;
}
}
rms.save('syllabuses', vm.syllabuses); rms.save('syllabuses', vm.syllabuses);
} }
); );
@ -25,7 +46,6 @@ app.controller('ClassListController', ['$scope', 'config', 'auth', '$http', '$lo
loadClassList(); loadClassList();
} }
vm.goClass = function (course_id) { vm.goClass = function (course_id) {
console.log(course_id); console.log(course_id);
$location.path("/class").search({id: course_id}); $location.path("/class").search({id: course_id});
@ -33,45 +53,49 @@ app.controller('ClassListController', ['$scope', 'config', 'auth', '$http', '$lo
vm.newClass = function () { vm.newClass = function () {
//先判断下权限 //先判断下权限
$http.post(config.apiUrl + "syllabuses/auth",{token: auth.token()} ).then( // $http.post(config.apiUrl + "syllabuses/auth",{token: auth.token()} ).then(
function (response) { // function (response) {
console.log(response.data); // console.log(response.data);
if (response.data.auth == 0) { // if (response.data.auth == 0) {
vm.alertService_1.showMessage('提示', '非教师身份不能创建课程哦~'); // vm.alertService_1.showMessage('提示', '非教师身份不能创建课程哦~');
} // }
else{ // else{
$location.path("/new_class"); // $location.path("/new_class");
} // }
} // }
); // );
} $location.path("/new_class");
};
vm.goResource = function () { vm.goResource = function () {
$location.path("/myresource"); $location.path("/myresource");
} };
vm.joinClass = function () { vm.joinClass = function () {
vm.alertService_3.showMessage('提示', '请输入5位班级邀请码(不区分大小写)', function(){ // vm.alertService_3.showMessage('提示', '请输入5位班级邀请码(不区分大小写)', function(){
if (vm.alertService_3.invite && vm.alertService_3.invite.length == 5) { // if (vm.alertService_3.invite && vm.alertService_3.invite.length == 5) {
$http.post(config.apiUrl + "courses/join", { // $http.post(config.apiUrl + "courses/join", {
token: auth.token(), // token: auth.token(),
invite_code: vm.alertService_3.invite // invite_code: vm.alertService_3.invite
}).then(function (response) { // }).then(function (response) {
console.log(response.data); // console.log(response.data);
if (response.data.status != 0) { // if (response.data.status != 0) {
vm.alertService_1.showMessage('提示', response.data.message); // vm.alertService_1.showMessage('提示', response.data.message);
} else { // } else {
vm.alertService_1.showMessage('提示', '加入课程成功'); // vm.alertService_1.showMessage('提示', '加入课程成功');
vm.alertService_3.invite = ""; // vm.alertService_3.invite = "";
loadClassList(); // loadClassList();
} // }
}); // });
} else { // } else {
if(vm.alertService_3.invite){ // if(vm.alertService_3.invite){
vm.alertService_1.showMessage('提示', '邀请码格式不正确'); // vm.alertService_1.showMessage('提示', '邀请码格式不正确');
} // }
} // }
}); // });
$location.path("/join_class").search({tag: 1});
}; };
vm.onSetting = function (syllabus) { vm.onSetting = function (syllabus) {

@ -10,6 +10,16 @@ app.controller('EditClassMemberController', ['$scope', '$http', 'auth', 'config'
var course_id = $routeParams.id; var course_id = $routeParams.id;
var user_id = $routeParams.user_id; var user_id = $routeParams.user_id;
vm.teacher = false; //教师
vm.assistant = false; //教辅
vm.student = false; //学生.
vm.tmpteacher = false; //教师
vm.tmpassistant = false; //教辅
vm.tmpstudent = false; //学生
if(!vm.current_edit_member){ if(!vm.current_edit_member){
$http.post(config.apiUrl+'courses/get_member_info', { $http.post(config.apiUrl+'courses/get_member_info', {
token: auth.token(), token: auth.token(),
@ -19,54 +29,81 @@ app.controller('EditClassMemberController', ['$scope', '$http', 'auth', 'config'
if(response.data.status!=0){ if(response.data.status!=0){
vm.alertService.showMessage('提示', response.data.message); vm.alertService.showMessage('提示', response.data.message);
} else { } else {
console.log(response);
course_id = response.data.course_id; course_id = response.data.course_id;
user_id = response.data.user_id; user_id = response.data.user_id;
vm.current_edit_member = response.data.member_info; vm.current_edit_member = response.data.member_info;
vm.current_roles_id = vm.current_edit_member.roles_id; vm.current_roles_id = vm.current_edit_member.roles_id;
for(var i in vm.current_roles_id){
if(vm.current_roles_id[i] == 9){
vm.teacher = true;
vm.tmpteacher = true;
}
else if(vm.current_roles_id[i] == 7){
vm.assistant = true;
vm.tmpassistant = true;
}
else if(vm.current_roles_id[i] == 10){
vm.student = true;
vm.tmpstudent = true;
}
}
} }
}); });
} }
console.log(vm.current_edit_member);
vm.cancel = function(){ vm.cancel = function(){
vm.alertService.showMessage('提示', '您确定不对角色进行变更吗?', function(){ // vm.alertService.showMessage('提示', '您确定不对角色进行变更吗?', function(){
// rms.save("project_master_members",[]); // window.history.back();
// rms.save("project_develop_members",[]); // });
// rms.save("project_report_members",[]); window.history.back();
window.history.back();
// $location.path("/project").search({id: project_id});
});
}; };
vm.edit_member_role = function(){ vm.edit_member_role = function(){
if(vm.current_roles_id == vm.current_edit_member.roles_id){ if((vm.teacher == vm.tmpteacher)&& (vm.assistant == vm.tmpassistant)&&(vm.student == vm.tmpstudent)){
vm.alertService.showMessage('提示', "该用户当前已是该角色"); vm.alertService.showMessage('提示', "该用户当前已是该角色");
return; return;
} }
if((vm.teacher == false)&& (vm.assistant == false)&&(vm.student == false)){
vm.alertService.showMessage('提示', "请至少选择一种角色");
return;
}
$http.post(config.apiUrl+'courses/edit_member_role', { $http.post(config.apiUrl+'courses/edit_member_role', {
token: auth.token(), token: auth.token(),
id: course_id, id: course_id,
user_id:vm.current_edit_member.user.id, user_id:vm.current_edit_member.user.id,
role_id:vm.current_edit_member.roles_id teacher_flag:vm.teacher,
assistant_flag:vm.assistant,
student_flag:vm.student
}).then(function(response){ }).then(function(response){
if(response.data.status!=0){ if(response.data.status!=0){
vm.alertService.showMessage('提示', response.data.message); vm.alertService.showMessage('提示', response.data.message);
} else { } else {
vm.alertService.showMessage('提示', '修改角色成功', function(){ vm.alertService.showMessage('提示', '修改角色成功', function(){
// window.history.back(); // window.history.back();
$location.path("/class").search({id: course_id,tag:1}); $location.path("/class").search({id: course_id,tag:1});
}); });
} }
}); });
}; };
vm.selectRole = function(role_id){ vm.selectRole = function(role_id){
vm.current_edit_member.roles_id = role_id; if (role_id == 7){
if(!vm.teacher){
vm.assistant = !vm.assistant;
}
}
else if (role_id == 9){
if(!vm.assistant){
vm.teacher = !vm.teacher;
}
}
else if (role_id == 10){
vm.student = !vm.student;
}
} }
}] ); }] );

@ -23,6 +23,7 @@ app.controller('EditProjectMemberController', ['$scope', '$http', 'auth', 'confi
project_id = response.data.project_id; project_id = response.data.project_id;
user_id = response.data.user_id; user_id = response.data.user_id;
vm.current_edit_member = response.data.member_info; vm.current_edit_member = response.data.member_info;
vm.current_edit_member.roles_id = vm.current_edit_member.roles_id[0];
vm.current_roles_id = vm.current_edit_member.roles_id; vm.current_roles_id = vm.current_edit_member.roles_id;
} }
}); });
@ -31,13 +32,10 @@ app.controller('EditProjectMemberController', ['$scope', '$http', 'auth', 'confi
console.log(vm.current_edit_member); console.log(vm.current_edit_member);
vm.cancel = function(){ vm.cancel = function(){
vm.alertService.showMessage('提示', '您确定不对角色进行变更吗?', function(){ // vm.alertService.showMessage('提示', '您确定不对角色进行变更吗?', function(){
// rms.save("project_master_members",[]); // window.history.back();
// rms.save("project_develop_members",[]); // });
// rms.save("project_report_members",[]); window.history.back();
window.history.back();
// $location.path("/project").search({id: project_id});
});
}; };
vm.edit_member_role = function(){ vm.edit_member_role = function(){
@ -63,6 +61,8 @@ app.controller('EditProjectMemberController', ['$scope', '$http', 'auth', 'confi
rms.save("project_master_members",[]); rms.save("project_master_members",[]);
rms.save("project_develop_members",[]); rms.save("project_develop_members",[]);
rms.save("project_report_members",[]); rms.save("project_report_members",[]);
rms.save("review_master_members",[]);
rms.save("review_develop_members",[]);
rms.save('tab_num',null); rms.save('tab_num',null);
// window.history.back(); // window.history.back();
$location.path("/project").search({id: project_id,tag:1}); $location.path("/project").search({id: project_id,tag:1});
@ -70,7 +70,6 @@ app.controller('EditProjectMemberController', ['$scope', '$http', 'auth', 'confi
} }
}); });
}; };
vm.selectRole = function(role_id){ vm.selectRole = function(role_id){

@ -3,7 +3,7 @@
*/ */
app.controller('InviteCodeController', ['$scope','$http', '$routeParams','config','auth', function($scope, $http, $routeParams, config, auth){ app.controller('InviteCodeController', ['$scope','$http', '$routeParams','config','auth','wx','common', function($scope, $http, $routeParams, config, auth, wx,common){
var vm = $scope; var vm = $scope;
vm.course = {}; vm.course = {};
@ -12,6 +12,40 @@ app.controller('InviteCodeController', ['$scope','$http', '$routeParams','config
function(response){ function(response){
console.log(response.data); console.log(response.data);
vm.course = response.data.data; vm.course = response.data.data;
var desc = "班级邀请:"+vm.course.name+" 班级";
common.wxConfig("",desc,"");
// wx.ready(function(){
// wx.onMenuShareTimeline({
// title: 'Trustie创新实践平台', // 分享标题
//// link: 'http://www.trustie.net/', // 分享链接
// imgUrl: 'http://www.trustie.net/images/logo2.png', // 分享图标
// success: function () {
// console.log("share successed.");
// },
// cancel: function () {
// console.log("share canceled.");
// }
// });
//
// wx.onMenuShareAppMessage({
// title: 'Trustie创新实践平台', // 分享标题
// desc: desc, // 分享描述
//// link: '', // 分享链接
//// imgUrl: '', // 分享图标
// imgUrl: 'http://www.trustie.net/images/logo2.png', // 分享图标
//// type: '', // 分享类型,music、video或link不填默认为link
//// dataUrl: '', // 如果type是music或video则要提供数据链接默认为空
// success: function () {
// // 用户确认分享后执行的回调函数
// },
// cancel: function () {
// // 用户取消分享后执行的回调函数
// }
// });
// });
} }
); );

@ -0,0 +1,80 @@
app.controller('JoinClassController', ['$scope', '$http', 'auth', 'config', 'alertService','$location','$routeParams','rms','wx', function($scope, $http, auth, config, alertService, $location,$routeParams, rms,wx){
var vm = $scope;
// vm.current_edit_member = rms.get('current_edit_member');
vm.current_edit_member = null;
var tag = $routeParams.tag;
vm.alertService = alertService.create();
vm.invite_code = "";
vm.teacher = false; //教师
vm.assistant = false; //教辅
vm.student = false; //学生.
vm.cancel = function(){
// vm.alertService.showMessage('提示', '您确定不对角色进行变更吗?', function(){
// window.history.back();
// });
if(tag){
window.history.back();
}
else{
wx.closeWindow();
}
};
vm.joinClass = function(){
if((vm.teacher == false)&& (vm.assistant == false)&&(vm.student == false)){
vm.alertService.showMessage('提示', "请至少选择一个角色");
return;
}
if(vm.invite_code.length == 0)
{
vm.alertService.showMessage('提示', '请输入5位邀请码');
return;
}
if(vm.invite_code.length != 5)
{
vm.alertService.showMessage('提示', '邀请码格式不正确');
return;
}
$http.post(config.apiUrl+'courses/join_class', {
token: auth.token(),
invite_code: vm.invite_code,
teacher_flag:vm.teacher,
assistant_flag:vm.assistant,
student_flag:vm.student
}).then(function(response){
if(response.data.status == 0){
vm.alertService.showMessage('提示', response.data.message,function(){
$location.path("/class_list");
});
} else {
vm.alertService.showMessage('提示', response.data.message);
}
});
};
vm.selectRole = function(role_id){
if (role_id == 7){
if(!vm.teacher){
vm.assistant = !vm.assistant;
}
}
else if (role_id == 9){
if(!vm.assistant){
vm.teacher = !vm.teacher;
}
}
else if (role_id == 10){
vm.student = !vm.student;
}
}
}] );

@ -0,0 +1,60 @@
app.controller('JoinProjectController', ['$scope', '$http', 'auth', 'config', 'alertService','$location','$routeParams','rms','wx', function($scope, $http, auth, config, alertService, $location,$routeParams, rms,wx){
var vm = $scope;
// vm.current_edit_member = rms.get('current_edit_member');
vm.role_id = 0;
vm.alertService = alertService.create();
vm.invite_code = "";
var tag = $routeParams.tag;
vm.cancel = function(){
if(tag){
window.history.back();
}
else{
wx.closeWindow();
}
};
vm.join_project = function(){
if(vm.role_id == 0){
vm.alertService.showMessage('提示', "请至少选择一个角色");
return;
}
if(vm.invite_code.length == 0)
{
vm.alertService.showMessage('提示', '请输入6位邀请码');
return;
}
if(vm.invite_code.length != 6)
{
vm.alertService.showMessage('提示', '邀请码格式不正确');
return;
}
$http.post(config.apiUrl+'projects/join_project', {
token: auth.token(),
invite_code: vm.invite_code,
role_id:vm.role_id
}).then(function(response){
if(response.data.status == 0){
vm.alertService.showMessage('提示', response.data.message,function(){
$location.path("/project_list");
});
} else {
vm.alertService.showMessage('提示', response.data.message);
}
});
};
vm.selectRole = function(role_id){
vm.role_id = role_id;
}
}] );

@ -1,5 +1,11 @@
app.controller('LoginController', ['$scope', '$http', '$location', '$routeParams', 'alertService', 'config','auth','session', app.controller('LoginController', ['$scope', '$http', '$location', '$routeParams', 'alertService', 'config','auth','session','wx',
function ($scope, $http, $location, $routeParams, alertService, config, auth,session) { function ($scope, $http, $location, $routeParams, alertService, config, auth,session, wx) {
// 登录页不用显示菜音
wx.ready(function(){
wx.hideOptionMenu();
})
if(auth.get_bind().then(function(){ if(auth.get_bind().then(function(){
$location.path("/activities"); $location.path("/activities");
})); }));
@ -33,8 +39,7 @@ app.controller('LoginController', ['$scope', '$http', '$location', '$routeParams
vm.loginFailed = (response.data.status != 0); vm.loginFailed = (response.data.status != 0);
if (!$scope.loginFailed) { //绑定成功 if (!$scope.loginFailed) { //绑定成功
vm.alertService.showMessage('提示', response.data.message, function(){ vm.alertService.showMessage('提示', response.data.message, function(){
// $location.path("/activities"); wx.closeWindow();
window.WeixinJSBridge.call('closeWindow');
}); });
} else { } else {
vm.alertService.showMessage('出错了', response.data.message); vm.alertService.showMessage('出错了', response.data.message);

@ -19,16 +19,31 @@ app.controller('ProjectController', ['$scope', 'config','$http','$timeout', 'aut
vm.project_develop_members = rms.get("project_develop_members") || []; vm.project_develop_members = rms.get("project_develop_members") || [];
vm.project_report_members = rms.get("project_report_members") || []; vm.project_report_members = rms.get("project_report_members") || [];
// vm.review_master_members = rms.get("review_master_members") || [];
// vm.review_develop_members = rms.get("review_master_members") || [];
vm.review_master_members = rms.get("review_master_members") || [];
vm.review_develop_members = rms.get("review_develop_members") || [];
// vm.project_members_has_more = rms.get("project_members_has_more"); // vm.project_members_has_more = rms.get("project_members_has_more");
vm.alertService = alertService.create(); vm.alertService = alertService.create();
//跳入邀请界面 //跳入邀请界面
vm.invite = function(){ vm.invite = function(){
vm.alertService.showMessage('提示', "该功能将在近日开放,敬请期待!"); // vm.alertService.showMessage('提示', "该功能将在近日开放,敬请期待!");
rms.save('project_activities_page',vm.project_activities_page);
rms.save("project_activities",vm.project_activities);
rms.save("project_has_more",vm.project_has_more);
rms.save("project",vm.project);
rms.save("project_master_members",vm.project_master_members);
rms.save("project_develop_members",vm.project_develop_members);
rms.save("project_report_members",vm.project_report_members);
rms.save("review_master_members",vm.review_master_members);
rms.save("review_develop_members",vm.review_develop_members);
// $location.path("/project_invite_code").search({id: projectid}); $location.path("/project_invite_code").search({id: projectid});
}; };
//获取项目动态 //获取项目动态
@ -82,6 +97,8 @@ app.controller('ProjectController', ['$scope', 'config','$http','$timeout', 'aut
vm.project_develop_members = response.data.develop_members; vm.project_develop_members = response.data.develop_members;
vm.project_report_members = response.data.report_members; vm.project_report_members = response.data.report_members;
vm.review_master_members = response.data.review_master_members;
vm.review_develop_members = response.data.review_develop_members;
} }
else{ else{
vm.alertService.showMessage('提示', response.data.message); vm.alertService.showMessage('提示', response.data.message);
@ -141,9 +158,11 @@ app.controller('ProjectController', ['$scope', 'config','$http','$timeout', 'aut
if(tag){ if(tag){
vm.tab(2); vm.tab(2);
tag = null; tag = null;
vm.currentTab = 2;
} }
else{ else{
vm.tab(1); vm.tab(1);
vm.currentTab = 1;
} }
} }
else{ else{
@ -154,8 +173,6 @@ app.controller('ProjectController', ['$scope', 'config','$http','$timeout', 'aut
} }
} }
); );
vm.currentTab = 1;
vm.tab(vm.currentTab);
} else { } else {
$timeout(function(){ $timeout(function(){
window.scrollTo(0, rms.get("yoffset")); window.scrollTo(0, rms.get("yoffset"));
@ -197,8 +214,23 @@ app.controller('ProjectController', ['$scope', 'config','$http','$timeout', 'aut
rms.save("project_master_members",vm.project_master_members); rms.save("project_master_members",vm.project_master_members);
rms.save("project_develop_members",vm.project_develop_members); rms.save("project_develop_members",vm.project_develop_members);
rms.save("project_report_members",vm.project_report_members); rms.save("project_report_members",vm.project_report_members);
rms.save("review_master_members",vm.review_master_members);
rms.save("review_develop_members",vm.review_develop_members);
$location.path("/edit_project_member").search({id: projectid,user_id: data.user.id}); $location.path("/edit_project_member").search({id: projectid,user_id: data.user.id});
}; };
vm.review = function(user){
rms.save('current_review_member', user);
rms.save('current_project', vm.project);
rms.save("project",vm.project);
rms.save("project_master_members",vm.project_master_members);
rms.save("project_develop_members",vm.project_develop_members);
rms.save("project_report_members",vm.project_report_members);
rms.save("review_master_members",vm.review_master_members);
rms.save("review_develop_members",vm.review_develop_members);
$location.path("/review_project_member").search({id: projectid,user_id: user.id});
}
}]); }]);

@ -3,7 +3,7 @@
*/ */
app.controller('ProjectInviteCodeController', ['$scope','$http', '$routeParams','config','auth', function($scope, $http, $routeParams, config, auth){ app.controller('ProjectInviteCodeController', ['$scope','$http', '$routeParams','config','auth','wx','common', function($scope, $http, $routeParams, config, auth,wx,common){
var vm = $scope; var vm = $scope;
vm.project = {}; vm.project = {};
@ -12,23 +12,43 @@ app.controller('ProjectInviteCodeController', ['$scope','$http', '$routeParams',
function(response){ function(response){
console.log(response.data); console.log(response.data);
vm.project = response.data.data; vm.project = response.data.data;
var desc = "项目邀请:"+vm.project.name+" 项目";
common.wxConfig("",desc,"");
// wx.ready(function(){
// wx.onMenuShareTimeline({
// title: 'Trustie创新实践平台', // 分享标题
//// link: 'http://www.trustie.net/', // 分享链接
// imgUrl: 'http://www.trustie.net/images/logo2.png', // 分享图标
// success: function () {
// console.log("share successed.");
// },
// cancel: function () {
// console.log("share canceled.");
// }
// });
//
// wx.onMenuShareAppMessage({
// title: 'Trustie创新实践平台', // 分享标题
// desc: desc, // 分享描述
//// link: '', // 分享链接
//// imgUrl: '', // 分享图标
// imgUrl: 'http://www.trustie.net/images/logo2.png', // 分享图标
//// type: '', // 分享类型,music、video或link不填默认为link
//// dataUrl: '', // 如果type是music或video则要提供数据链接默认为空
// success: function () {
// // 用户确认分享后执行的回调函数
// },
// cancel: function () {
// // 用户取消分享后执行的回调函数
// }
// });
// });
} }
); );
vm.share = function(){
window.WeixinJSBridge.invoke('sendAppMessage',{
'appid': 'wxf694495398c7d470', // 公众号appID
'type': 'link', // 非必填music,vido或link,默认为link。
'data_url': '', // 非必填,连接地址,如音乐的mp3数据地址,供内置播放器使用
'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(res){
//alert(res.err_msg);
});
}
}]); }]);

@ -17,6 +17,10 @@ app.controller('ProjectListController', ['$scope', 'config', 'auth', '$http', '$
function (response) { function (response) {
console.log(response.data); console.log(response.data);
vm.projects = response.data.data; vm.projects = response.data.data;
rms.save('projects', vm.projects); rms.save('projects', vm.projects);
} }
); );
@ -32,9 +36,12 @@ app.controller('ProjectListController', ['$scope', 'config', 'auth', '$http', '$
rms.save("project_activities",[]); rms.save("project_activities",[]);
rms.save("project_has_more",false); rms.save("project_has_more",false);
rms.save("project",null); rms.save("project",null);
rms.save('project_members_page',0); rms.save("project_master_members",[]);
rms.save("project_members",[]); rms.save("project_develop_members",[]);
rms.save("project_members_has_more",false); rms.save("project_report_members",[]);
rms.save("review_master_members",[]);
rms.save("review_develop_members",[]);
rms.save('tab_num',null); rms.save('tab_num',null);
console.log(project_id); console.log(project_id);
$location.path("/project").search({id: project_id}); $location.path("/project").search({id: project_id});
@ -45,7 +52,7 @@ app.controller('ProjectListController', ['$scope', 'config', 'auth', '$http', '$
}; };
vm.joinProject = function () { vm.joinProject = function () {
vm.alertService_1.showMessage('提示', "该功能将在近日开放,敬请期待!"); // vm.alertService_1.showMessage('提示', "该功能将在近日开放,敬请期待!");
// vm.alertService_3.showMessage('提示', '请输入6位项目邀请码(不区分大小写)', function(){ // vm.alertService_3.showMessage('提示', '请输入6位项目邀请码(不区分大小写)', function(){
// if (vm.alertService_3.invite && vm.alertService_3.invite.length == 6) { // if (vm.alertService_3.invite && vm.alertService_3.invite.length == 6) {
@ -68,6 +75,7 @@ app.controller('ProjectListController', ['$scope', 'config', 'auth', '$http', '$
// } // }
// } // }
// }); // });
$location.path("/join_project").search({tag: 1});
}; };
vm.onSetting = function (project) { vm.onSetting = function (project) {

@ -0,0 +1,68 @@
app.controller('ReviewClassMemberController', ['$scope', '$http', 'auth', 'config', 'alertService','$location','$routeParams','rms', function($scope, $http, auth, config, alertService, $location,$routeParams, rms){
var vm = $scope;
// vm.current_edit_member = rms.get('current_edit_member');
vm.current_review_member = rms.get('current_review_member');
vm.current_course = rms.get('current_course');
vm.alertService = alertService.create();
var course_id = $routeParams.id;
var user_id = $routeParams.user_id;
if(!vm.current_course){
$http.get(config.apiUrl+ 'courses/'+course_id+"?token="+auth.token()).then(
function(response) {
console.log(response.data);
if (response.data.status == 0){
vm.current_course = response.data.data;
console.log("courses");
console.log(response.data.data);
}
else{
vm.alertService.showMessage('提示', response.data.message);
}
}
);
}
if(!vm.current_review_member){
$http.post(config.apiUrl+'courses/review_member_info', {
token: auth.token(),
course_id: course_id,
user_id:user_id
}).then(function(response){
if(response.data.status!=0){
vm.alertService.showMessage('提示', response.data.message);
} else {
vm.current_review_member = response.data.data;
console.log("review_member_info");
console.log(response.data.data);
}
});
}
vm.deal = function(result){
$http.post(config.apiUrl+'courses/deal_join_apply', {
token: auth.token(),
course_id: course_id,
user_id:user_id,
type:result
}).then(function(response) {
if (response.data.status == 0) {
vm.alertService.showMessage('提示', response.data.message, function () {
$location.path("/class").search({id: course_id,tag:1});
});
}
else{
vm.alertService.showMessage('提示', response.data.message);
}
});
};
}] );

@ -0,0 +1,72 @@
app.controller('ReviewProjectMemberController', ['$scope', '$http', 'auth', 'config', 'alertService','$location','$routeParams','rms', function($scope, $http, auth, config, alertService, $location,$routeParams, rms){
var vm = $scope;
// vm.current_edit_member = rms.get('current_edit_member');
vm.current_review_member = rms.get('current_review_member');
vm.current_project = rms.get('current_project');
vm.alertService = alertService.create();
var project_id = $routeParams.id;
var user_id = $routeParams.user_id;
if(!vm.current_project){
$http.get(config.apiUrl+ 'projects/'+project_id+"?token="+auth.token()).then(
function(response) {
console.log(response.data);
if (response.data.status == 0){
vm.current_project = response.data.data;
console.log("projects");
console.log(response.data.data);
}
else{
vm.alertService.showMessage('提示', response.data.message);
}
}
);
}
if(!vm.current_review_member){
$http.post(config.apiUrl+'projects/review_member_info', {
token: auth.token(),
project_id: project_id,
user_id:user_id
}).then(function(response){
if(response.data.status!=0){
vm.alertService.showMessage('提示', response.data.message);
} else {
vm.current_review_member = response.data.data;
console.log("review_member_info");
console.log(response.data.data);
}
});
}
vm.deal = function(result){
$http.post(config.apiUrl+'projects/deal_join_apply', {
token: auth.token(),
project_id: project_id,
user_id:user_id,
type:result
}).then(function(response) {
if (response.data.status == 0) {
vm.alertService.showMessage('提示', response.data.message, function () {
rms.save("project_master_members",[]);
rms.save("project_develop_members",[]);
rms.save("project_report_members",[]);
rms.save("review_master_members",[]);
rms.save("review_develop_members",[]);
rms.save("tab_num",null);
$location.path("/project").search({id: project_id,tag:1});
});
}
else{
vm.alertService.showMessage('提示', response.data.message);
}
});
};
}] );

@ -1,25 +1,25 @@
/** /**
* Created by Tim on 7/22/16. * Created by Tim on 7/22/16.
*/ */
//app.directive('ellipsisShow',["$timeout",function(timer){ app.directive('ellipsisShow',["$timeout",function(timer){
// return{ return{
// restrict: 'A', restrict: 'A',
// scope: {}, scope: {},
// link: function(scope, element){ link: function(scope, element){
// timer(function() { timer(function() {
// var textSplit = element.text().split(" "); var textSplit = element.text().split("");
// var newContent = []; var newContent = [];
// element.text(""); element.text("");
// for (var i = 0; i < textSplit.length; i++) { for (var i = 0; i < textSplit.length; i++) {
// newContent = newContent + " " + textSplit[i]; newContent = newContent + textSplit[i];
// element.text(newContent); element.text(newContent);
// if(element[0].scrollHeight >= 100){ if(element[0].scrollHeight >= 100){
// newContent = newContent + " " + textSplit[i+1] + " " + textSplit[i+2] + " " + textSplit[i+3] + " " + textSplit[i+4] + "..."; newContent = newContent + textSplit[i+1] + textSplit[i+2] + textSplit[i+3] + textSplit[i+4] + textSplit[i+5] + textSplit[i+6] + textSplit[i+7] + textSplit[i+8] + textSplit[i+9] + textSplit[i+10] + "...";
// element.text(newContent); element.text(newContent);
// break; break;
// } }
// } }
// }); });
// } }
// } }
//}]); }]);

@ -30,6 +30,10 @@ app.factory('alertService', function(){
} }
}); });
app.factory('wx', ['$window', function($window){
var wechat = $window.wx;
return wechat;
}]);
app.factory('auth', ['$http','$routeParams', '$q', 'session', 'config',function($http,$routeParams, $q, session,config){ app.factory('auth', ['$http','$routeParams', '$q', 'session', 'config',function($http,$routeParams, $q, session,config){
//是否已经绑定 //是否已经绑定
@ -89,7 +93,7 @@ app.factory('rms', function(){
return {save: save, get: get}; return {save: save, get: get};
}); });
app.factory('common', ['$http', 'auth', '$routeParams','rms','config', function($http, auth, $routeParams,rms,config){ app.factory('common', ['$http', 'auth', '$routeParams','rms','config','wx', function($http, auth, $routeParams,rms,config,wx){
var addCommonReply = function(id, type, data, cb){ var addCommonReply = function(id, type, data, cb){
if(!data.comment || data.comment.length<=0){ if(!data.comment || data.comment.length<=0){
@ -196,6 +200,47 @@ app.factory('common', ['$http', 'auth', '$routeParams','rms','config', function(
args.scope.formData = {comment: ''}; args.scope.formData = {comment: ''};
var loadData = function(id,replytype,page){ var loadData = function(id,replytype,page){
loadCommonData(id, args.type,replytype,page).then(function successCallback(response) { loadCommonData(id, args.type,replytype,page).then(function successCallback(response) {
console.log(response.data);
//--------------分享内容定制-------------
var tmptile = "分享动态";
var imgUrl = "";
if(response.data.data.title){
tmptile = response.data.data.title;
}
var tmpname = "匿名用户";
if(response.data.data.user){
tmpname = response.data.data.user.realname;
imgUrl = window.g_localhost+response.data.data.user.img_url;
}
if(response.data.data.author){
tmpname = response.data.data.author.realname;
imgUrl = window.g_localhost+response.data.data.author.img_url;
}
var desc = ""
if(response.data.data.content){
desc = response.data.data.content.replace(/<[^>]+>/g,"").replace(/\s*/g,"").replace(/&nbsp;/g,"");
}
if(response.data.data.description){
desc = response.data.data.description.replace(/<[^>]+>/g,"").replace(/\s*/g,"").replace(/&nbsp;/g,"");
}
if(desc.length > 30){
desc = desc.substring(0,30)+"...";
}
var title = tmpname+""+tmptile;
console.log("desc = "+desc);
console.log("imgUrl= "+imgUrl);
wxConfig(title,desc,imgUrl);
//--------------分享内容定制-------------
args.loadCallback(response.data); args.loadCallback(response.data);
}, function errorCallback(response) { }, function errorCallback(response) {
}); });
@ -298,7 +343,52 @@ app.factory('common', ['$http', 'auth', '$routeParams','rms','config', function(
args.scope.commentreply_path = config.rootPath+ 'templates/comment_reply.html'; args.scope.commentreply_path = config.rootPath+ 'templates/comment_reply.html';
} };
var wxConfig = function(title,desc,imgUrl){
if(title == null || title == ""){
title = 'Trustie创新实践平台';
}
if(desc == null || desc == ""){
desc = 'Trustie创新实践平台';
}
if(imgUrl == null || imgUrl == ""){
imgUrl = 'http://www.trustie.net/images/logo2.png';
}
wx.ready(function(){
wx.onMenuShareTimeline({
title: title, // 分享标题
// link: 'http://www.trustie.net/', // 分享链接
imgUrl: imgUrl, // 分享图标
success: function () {
console.log("share successed.");
},
cancel: function () {
console.log("share canceled.");
}
});
wx.onMenuShareAppMessage({
title: title, // 分享标题
desc: desc, // 分享描述
// link: '', // 分享链接
// imgUrl: '', // 分享图标
imgUrl: imgUrl, // 分享图标
// type: '', // 分享类型,music、video或link不填默认为link
// dataUrl: '', // 如果type是music或video则要提供数据链接默认为空
success: function () {
// 用户确认分享后执行的回调函数
},
cancel: function () {
// 用户取消分享后执行的回调函数
}
});
});
};
return {init: init, addCommonReply: addCommonReply, loadCommonData: loadCommonData, addCommonPraise: addCommonPraise, decreaseCommonPraise: decreaseCommonPraise}; return {init: init, addCommonReply: addCommonReply, loadCommonData: loadCommonData, addCommonPraise: addCommonPraise, decreaseCommonPraise: decreaseCommonPraise, wxConfig: wxConfig};
}]); }]);

@ -38,11 +38,15 @@ app.config(['$routeProvider',"$httpProvider", "$locationProvider",'config', func
.when('/myresource', makeRoute('myresource.html', 'MyResourceController')) .when('/myresource', makeRoute('myresource.html', 'MyResourceController'))
.when('/invite_code', {templateUrl: rootPath + 'invite_code.html', controller: 'InviteCodeController'}) .when('/invite_code', {templateUrl: rootPath + 'invite_code.html', controller: 'InviteCodeController'})
.when('/send_class_list', makeRoute('send_class_list.html', 'SendClassListController')) .when('/send_class_list', makeRoute('send_class_list.html', 'SendClassListController'))
.when('/join_class', makeRoute('join_class.html', 'JoinClassController'))
.when('/review_class_member', makeRoute('review_class_member.html', 'ReviewClassMemberController'))
.when('/project_list', makeRoute('project_list.html', 'ProjectListController')) .when('/project_list', makeRoute('project_list.html', 'ProjectListController'))
.when('/project', makeRoute('project.html', 'ProjectController')) .when('/project', makeRoute('project.html', 'ProjectController'))
.when('/edit_project_member', makeRoute('edit_project_member.html', 'EditProjectMemberController')) .when('/edit_project_member', makeRoute('edit_project_member.html', 'EditProjectMemberController'))
.when('/new_project', makeRoute('new_project.html', 'NewProjectController')) .when('/new_project', makeRoute('new_project.html', 'NewProjectController'))
.when('/project_invite_code', {templateUrl: rootPath + 'project_invite_code.html', controller: 'ProjectInviteCodeController'}) .when('/project_invite_code', {templateUrl: rootPath + 'project_invite_code.html', controller: 'ProjectInviteCodeController'})
.when('/join_project', makeRoute('join_project.html', 'JoinProjectController'))
.when('/review_project_member', makeRoute('review_project_member.html', 'ReviewProjectMemberController'))
.otherwise({ .otherwise({
redirectTo: '/activites' redirectTo: '/activites'
}); });

@ -1,245 +1,250 @@
@charset "utf-8"; @charset "utf-8";
/* CSS Document */ /* CSS Document */
/*基本样式*/ /*基本样式*/
body,table,input,textarea,select,button { font-family: "微软雅黑","宋体","Helvetica Neue", Helvetica, Arial, sans-serif;} body,table,input,textarea,select,button { font-family: "微软雅黑","宋体","Helvetica Neue", Helvetica, Arial, sans-serif;}
body, ul, h1,h2,h3,h4,h5,p,pre,input {padding:0px; margin:0px;} body, ul, h1,h2,h3,h4,h5,p,pre,input {padding:0px; margin:0px;}
body{background-color: #efeff4;} body{background-color: #efeff4;}
ul li {list-style:none;} ul li {list-style:none;}
img {max-width:100%;} img {max-width:100%;}
blockquote {border:1px solid #d4d4d4; padding: 0.6em; margin: 5px 0.4em 5px 1.4em; border-radius: 4px; font-family: "Microsoft YaHei"; background-size: 100% 100%;} blockquote {border:1px solid #d4d4d4; padding: 0.6em; margin: 5px 0.4em 5px 1.4em; border-radius: 4px; font-family: "Microsoft YaHei"; background-size: 100% 100%;}
.text-control {word-break:normal; word-wrap:break-word;} .text-control {word-break:normal; word-wrap:break-word;}
.f12 {font-size:12px;} .f12 {font-size:12px;}
.f13 {font-size:13px;} .f13 {font-size:13px;}
.f14 {font-size:14px;} .f14 {font-size:14px;}
.f15 {font-size:15px;} .f15 {font-size:15px;}
.f16 {font-size:16px;} .f16 {font-size:16px;}
.fb {font-weight:bold;} .fb {font-weight:bold;}
.mt2 {margin-top:2px;} .mt2 {margin-top:2px;}
.mt3 {margin-top:3px;} .mt3 {margin-top:3px;}
.mt4 {margin-top:4px;} .mt4 {margin-top:4px;}
.mt5 {margin-top:5px;} .mt5 {margin-top:5px;}
.mt10 {margin-top:10px;} .mt10 {margin-top:10px;}
.mt11 {margin-top:11px;} .mt11 {margin-top:11px;}
.mt12 {margin-top:12px;} .mt12 {margin-top:12px;}
.mt15 {margin-top:15px;} .mt15 {margin-top:15px;}
.mt30 {margin-top:30px;} .mt30 {margin-top:30px;}
.mt70 {margin-top:70px;} .mt70 {margin-top:70px;}
.mb5 {margin-bottom:5px;} .mb5 {margin-bottom:5px;}
.mb10 {margin-bottom:10px;} .mb10 {margin-bottom:10px;}
.mb15 {margin-bottom:15px;} .mb15 {margin-bottom:15px;}
.mb20 {margin-bottom:20px;} .mb20 {margin-bottom:20px;}
.mb50 {margin-bottom:50px;} .mb50 {margin-bottom:50px;}
.ml5 {margin-left:5px;} .ml5 {margin-left:5px;}
.ml10 {margin-left:10px;} .ml10 {margin-left:10px;}
.ml40 {margin-left:40px;} .ml40 {margin-left:40px;}
.mr5 {margin-right:5px;} .mr5 {margin-right:5px;}
.mr10 {margin-right:10px;} .mr10 {margin-right:10px;}
.ml15 {margin-left:15px;} .ml15 {margin-left:15px;}
.ml35 {margin-left:35px;} .ml35 {margin-left:35px;}
.mr15 {margin-right:15px;} .mr15 {margin-right:15px;}
.mr20 {margin-right:20px;} .mr20 {margin-right:20px;}
.ml25 {margin-left:25px;} .ml25 {margin-left:25px;}
.mr25 {margin-right:25px;} .mr25 {margin-right:25px;}
.ml55 {margin-left:55px;} .ml55 {margin-left:55px;}
.mr55 {margin-right:55px;} .mr55 {margin-right:55px;}
.c-red {color:#e81a1a;} .c-red {color:#e81a1a;}
.c-blue {color:#269ac9;} .c-blue {color:#269ac9;}
.c-grey {color:#9a9a9a !important;} .c-grey {color:#9a9a9a !important;}
.c-grey2 {color:#707070;} .c-grey2 {color:#707070;}
.c-grey3 {color:#555555;} .c-grey3 {color:#555555;}
.c-grey4 {color:#888888;} .c-grey4 {color:#888888;}
.c-grey5 {color:#aaaaaa;} .c-grey5 {color:#aaaaaa;}
.c-grey6 {color:#777777;} .c-grey6 {color:#777777;}
.c-blue {color:#3b94d6;} .c-blue {color:#3b94d6;}
.c-white {color:#ffffff;} .c-white {color:#ffffff;}
.c-black {color:#333} .c-black {color:#333}
a {color:#707070;} a {color:#707070;}
a.c-grey {color:#707070;} a.c-grey {color:#707070;}
a.c-grey2 {color:#9a9a9a;} a.c-grey2 {color:#9a9a9a;}
a.c-grey3 {color:#353535;} a.c-grey3 {color:#353535;}
a.c-green {color:#0bb20c;} a.c-green {color:#0bb20c;}
a:link,a:visited{text-decoration:none;} a:link,a:visited{text-decoration:none;}
a:hover,a:active{cursor:pointer;} a:hover,a:active{cursor:pointer;}
a.link-blue {color:#269ac9;} a.link-blue {color:#269ac9;}
a.link-blue2 {color:#3b94d6;} a.link-blue2 {color:#3b94d6;}
a.underline {text-decoration:underline;} a.underline {text-decoration:underline;}
.border-radius {border-radius:5px;} .border-radius {border-radius:5px;}
.w36 {width:36px;} .w36 {width:36px;}
.max-width-60 {max-width:60px;} .max-width-60 {max-width:60px;}
.max-width-130 {max-width:130px;} .max-width-130 {max-width:130px;}
.hidden {overflow:hidden; white-space:nowrap; text-overflow:ellipsis;} .hidden {overflow:hidden; white-space:nowrap; text-overflow:ellipsis;}
.inline-block {display:inline-block;} .inline-block {display:inline-block;}
.dis {display:block;} .dis {display:block;}
.undis {display:none;} .undis {display:none;}
.text-nowrap {white-space:nowrap;} .text-nowrap {white-space:nowrap;}
.v-top {vertical-align:top;} .v-top {vertical-align:top;}
.tac {text-align:center;} .tac {text-align:center;}
.block-center {margin-left:auto; margin-right:auto; display:block;} .block-center {margin-left:auto; margin-right:auto; display:block;}
/*背景色*/ /*背景色*/
.bg-grey {background-color:#c1c1c1 !important;} .bg-grey {background-color:#c1c1c1 !important;}
.bg-blue {background-color:#3b94d6;} .bg-blue {background-color:#3b94d6;}
/*按钮样式*/ /*按钮样式*/
.btn1 {width:100%; height:40px; line-height:40px; vertical-align:middle; text-align:center; color:#fff; display:block; border-radius:5px;} .btn1 {width:100%; height:40px; line-height:40px; vertical-align:middle; text-align:center; color:#fff; display:block; border-radius:5px;}
.bg-blue:not(.btn-disabled):active {background-color:#2780c2;} .bg-blue:not(.btn-disabled):active {background-color:#2780c2;}
.btn-disabled {background-color:#ccc !important;} .btn-disabled {background-color:#ccc !important;}
.btn2 {width:145px; height:35px; color:#fff; font-size:15px; line-height:35px; text-align:center; vertical-align:middle; margin:18px auto 20px auto; border-radius:50px; display:block;} .btn2 {width:145px; height:35px; color:#fff; font-size:15px; line-height:35px; text-align:center; vertical-align:middle; margin:18px auto 20px auto; border-radius:50px; display:block;}
.btn3 {width:145px; height:35px; color:#fff; font-size:15px; line-height:35px; text-align:center; vertical-align:middle; border-radius:50px; display:block;} .btn3 {width:145px; height:35px; color:#fff; font-size:15px; line-height:35px; text-align:center; vertical-align:middle; border-radius:50px; display:block;}
.fixed-bottom-btn {position:fixed; bottom:5px; left:50%; transform:translate(-50%,0);} .fixed-bottom-btn {position:fixed; bottom:5px; left:50%; transform:translate(-50%,0);}
/*tab*/ /*tab*/
.tab-wrap {position:relative; width:100%; line-height:38px; display:-webkit-box; display:-moz-box; display:-ms-flexbox; display:-webkit-flex; display:flex; font-size:13px; background-color:#fff;} .tab-wrap {position:relative; width:100%; line-height:38px; display:-webkit-box; display:-moz-box; display:-ms-flexbox; display:-webkit-flex; display:flex; font-size:13px; background-color:#fff;}
.tab-wrap a {position:relative; display:block; -webkit-box-flex:1; -moz-box-flex:1; -ms-flex:1; flex:1;} .tab-wrap a {position:relative; display:block; -webkit-box-flex:1; -moz-box-flex:1; -ms-flex:1; flex:1;}
.tab-wrap a:first-child:after {display:none;} .tab-wrap a:first-child:after {display:none;}
.tab-wrap a:after {content:" "; position:absolute; left:0; top:0; width:1px; height:100%; border-left:1px solid #ccc; color:#707070;} .tab-wrap a:after {content:" "; position:absolute; left:0; top:0; width:1px; height:100%; border-left:1px solid #ccc; color:#707070;}
.weixin-tab {text-align:center; border-bottom:1px solid #ccc;} .weixin-tab {text-align:center; border-bottom:1px solid #ccc;}
/*bottom-tab*/ /*bottom-tab*/
.bottom-tab-wrap {position:fixed; width:100%; bottom:0; line-height:38px; display:-webkit-box; display:-moz-box; display:-ms-flexbox; display:-webkit-flex; display:flex; font-size:13px; background-color:#fff;} .bottom-tab-wrap {position:fixed; width:100%; bottom:0; line-height:38px; display:-webkit-box; display:-moz-box; display:-ms-flexbox; display:-webkit-flex; display:flex; font-size:13px; background-color:#fff;}
.bottom-tab-wrap a {display:block; -webkit-box-flex:1; -moz-box-flex:1; -ms-flex:1; flex:1; position:relative;} .bottom-tab-wrap a {display:block; -webkit-box-flex:1; -moz-box-flex:1; -ms-flex:1; flex:1; position:relative;}
.bottom-tab-wrap a:after {content:" "; position:absolute; left:0; top:0; width:1px; height:100%; border-left:1px solid #ccc; color:#707070;} .bottom-tab-wrap a:after {content:" "; position:absolute; left:0; top:0; width:1px; height:100%; border-left:1px solid #ccc; color:#707070;}
/*动态样式*/ /*动态样式*/
.post-container {width:100%;} .post-container {width:100%;}
.post-wrapper {width:100%; background-color:#ffffff; margin:10px auto;} .post-wrapper {width:100%; background-color:#ffffff; margin:10px auto;}
.post-main {padding:10px 15px; color:#9a9a9a;} .post-main {padding:10px 15px; color:#9a9a9a;}
.post-avatar {width:30px; height:30px;} .post-avatar {width:30px; height:30px;}
.post-title {font-size:13px; text-align:left;} .post-title {font-size:13px; text-align:left;}
.post-detail-info {font-size:13px; text-align:left; color:#9a9a9a;} .post-detail-info {font-size:13px; text-align:left; color:#9a9a9a;}
.fl {float:left;} .fl {float:left;}
.fr {float:right;} .fr {float:right;}
.cl {clear:both; overflow:hidden;} .cl {clear:both; overflow:hidden;}
.post-content {width:100%; font-size:14px; line-height:20px; height:100px; overflow:hidden; word-break:normal; word-wrap:break-word; text-align:justify;} .post-content {width:100%; font-size:14px; line-height:20px; height:100px; overflow:hidden; word-break:normal; word-wrap:break-word; text-align:justify;}
.post-all-content a {color:#136ec2;} .post-all-content a {color:#136ec2;}
.post-interactive {width:100%; height:35px; line-height:35px; vertical-align:middle; border-top:1px solid #e6e6e6; background-color:#f8f9fb;} .post-interactive {width:100%; height:35px; line-height:35px; vertical-align:middle; border-top:1px solid #e6e6e6; background-color:#f8f9fb;}
.post-interactive-column, .post-interactive-column,
.post-interactive-reply, .post-interactive-reply,
.post-interactive-praise {width:50%; text-align:center; float:left; font-size:13px;} .post-interactive-praise {width:50%; text-align:center; float:left; font-size:13px;}
.more-wrap {width:100%;} .more-wrap {width:100%;}
.more-events {width:100%; font-size:13px; text-align:center; margin:0 auto; padding: 5px 0; border-top:1px solid #e6e6e6; border-bottom:1px solid #e6e6e6; border-radius:3px; background-color:#f8f9fb; } .more-events {width:100%; font-size:13px; text-align:center; margin:0 auto; padding: 5px 0; border-top:1px solid #e6e6e6; border-bottom:1px solid #e6e6e6; border-radius:3px; background-color:#f8f9fb; }
.border-bottom {border-bottom:1px solid #e6e6e6;} .border-bottom {border-bottom:1px solid #e6e6e6;}
.post-reply-wrap {width:100%;} .post-reply-wrap {width:100%;}
.post-reply-wrap:first-child {border-top:1px solid #ccc;} .post-reply-wrap:first-child {border-top:1px solid #ccc;}
.post-input-wrap {width:100%; position:fixed; bottom:0; background-color:#fff;} .post-input-wrap {width:100%; position:fixed; bottom:0; background-color:#fff;}
.post-input-wrap2 {width:100%;} .post-input-wrap2 {width:100%;}
.post-reply-row {margin:10px 15px; color:#9a9a9a; background-color:#fff; border-bottom:1px solid #f0f0f0;} .post-reply-row {margin:10px 15px; color:#9a9a9a; background-color:#fff; border-bottom:1px solid #f0f0f0;}
.post-reply-avatar {width:45px; height:30px; text-align:center; margin-right:10px;} .post-reply-avatar {width:45px; height:30px; text-align:center; margin-right:10px;}
.post-reply-user {font-size:13px; text-align:left; margin-bottom:10px;} .post-reply-user {font-size:13px; text-align:left; margin-bottom:10px;}
.post-reply-content {font-size:13px; word-break:break-all; word-wrap:break-word; overflow:hidden; text-align:justify;} .post-reply-content {font-size:13px; word-break:break-all; word-wrap:break-word; overflow:hidden; text-align:justify;}
.post-reply-content img {max-width:100%;} .post-reply-content img {max-width:100%;}
.post-reply-content a {color:#136ec2;} .post-reply-content a {color:#136ec2;}
.post-reply-date, .post-reply-trigger {font-size:13px;} .post-reply-date, .post-reply-trigger {font-size:13px;}
.post-input-container {position:relative; padding-right:70px;} .post-input-container {position:relative; padding-right:70px;}
.copy-input-container {position:relative; padding-right:70px;} .copy-input-container {position:relative; padding-right:70px;}
.copy-input {width:100%; height:18px; line-height:18px; padding:5px; vertical-align: middle; font-size:12px; border-radius:3px; position:absolute; left:-999em;} .copy-input {width:100%; height:18px; line-height:18px; padding:5px; vertical-align: middle; font-size:12px; border-radius:3px; position:absolute; left:-999em;}
.post-reply-input {width:100%; height:18px; max-height:54px; line-height:18px; vertical-align: middle; font-size:13px; border:1px solid #e6e6e6; outline:none; padding:5px; margin:0; border-radius:3px; overflow-y:auto; resize:none; background-color:#f0eff4;} .post-reply-input {width:100%; height:18px; max-height:54px; line-height:18px; vertical-align: middle; font-size:13px; border:1px solid #e6e6e6; outline:none; padding:5px; margin:0; border-radius:3px; overflow-y:auto; resize:none; background-color:#f0eff4;}
.post-reply-submit {position:absolute; font-size:13px; height:30px; line-height:30px; vertical-align:middle; padding:0 8px; color:#fff; background-color:#269ac9; outline:none; border:none; top:0; right:0;} .post-reply-submit {position:absolute; font-size:13px; height:30px; line-height:30px; vertical-align:middle; padding:0 8px; color:#fff; background-color:#269ac9; outline:none; border:none; top:0; right:0;}
.reply-icon {background:url(/images/wechat/icon_list.gif) -150px -155px no-repeat; width:20px; height:20px; display:inline-block; vertical-align:middle;} .reply-icon {background:url(/images/wechat/icon_list.gif) -150px -155px no-repeat; width:20px; height:20px; display:inline-block; vertical-align:middle;}
.praise-icon {background:url(/images/wechat/icon_list.gif) -36px -88px no-repeat; width:20px; height:20px; display:inline-block; vertical-align:middle;} .praise-icon {background:url(/images/wechat/icon_list.gif) -36px -88px no-repeat; width:20px; height:20px; display:inline-block; vertical-align:middle;}
.praised-icon {background:url(/images/wechat/icon_list.gif) -152px -86px no-repeat; width:20px; height:20px; display:inline-block; vertical-align:middle;} .praised-icon {background:url(/images/wechat/icon_list.gif) -152px -86px no-repeat; width:20px; height:20px; display:inline-block; vertical-align:middle;}
.num-block {display:inline-block; vertical-align:top;} .num-block {display:inline-block; vertical-align:top;}
.post-op-banner {height:20px; line-height:20px; vertical-align:middle;} .post-op-banner {height:20px; line-height:20px; vertical-align:middle;}
/*20160628动态新样式*/ /*20160628动态新样式*/
.post-dynamic-author {width:50%; height:30px; line-height:30px; font-size:14px; color:#5b5b5b; vertical-align:middle;} .post-dynamic-author {width:50%; height:30px; line-height:30px; font-size:14px; color:#5b5b5b; vertical-align:middle;}
.post-dynamic-time {height:30px; line-height:30px; vertical-align:middle;} .post-dynamic-time {height:30px; line-height:30px; vertical-align:middle;}
.post-dynamic-title {font-size:15px;} .post-dynamic-title {font-size:15px;}
.post-dynamic-from {width:50%; font-size:13px;} .post-dynamic-from {width:50%; font-size:13px;}
.post-box-shadow {box-shadow: 0px 2px 8px rgba(146, 153, 169, 0.5);} .post-box-shadow {box-shadow: 0px 2px 8px rgba(146, 153, 169, 0.5);}
.post-reply-author {width:50%; height:20px; line-height:20px; font-size:12px; color:#5d5d5d; vertical-align:middle;} .post-reply-author {width:50%; height:20px; line-height:20px; font-size:12px; color:#5d5d5d; vertical-align:middle;}
.post-reply-time {height:20px; line-height:20px; vertical-align:middle;} .post-reply-time {height:20px; line-height:20px; vertical-align:middle;}
/* loading 弹框*/ /* loading 弹框*/
.loading-bg {position:fixed; width:100%; height:100%; left:0; top:0; z-index:99; background:rgba(206, 206, 206, 0.3); overflow:hidden;} .loading-bg {position:fixed; width:100%; height:100%; left:0; top:0; z-index:99; background:rgba(206, 206, 206, 0.3); overflow:hidden;}
.loading-box {position:absolute; top:50%; background:rgba(240,240,240, 0.5); width:160px; height:72px; left:50%; margin-top:-36px; margin-left:-80px; text-align:center;} .loading-box {position:absolute; top:50%; background:rgba(240,240,240, 0.5); width:160px; height:72px; left:50%; margin-top:-36px; margin-left:-80px; text-align:center;}
.loading-box img {margin-top: 3px; text-align: center;} .loading-box img {margin-top: 3px; text-align: center;}
.loading-box span {display: block; font-size:12px;} .loading-box span {display: block; font-size:12px;}
/*帖子锁定样式*/ /*帖子锁定样式*/
.locked_btn_cir {background: url("/images/wechat/locked.png") 0 0 no-repeat; cursor: default;} .locked_btn_cir {background: url("/images/wechat/locked.png") 0 0 no-repeat; cursor: default;}
/*20150612加入班级样式*/ /*20150612加入班级样式*/
.add-class-box {position:fixed; width:80%; max-width:300px; min-width:240px; font-size:15px; color:#444; background-color:#fff; box-shadow: 0px 2px 8px rgba(146, 153, 169, 0.5); border-radius:5px; top:50%; left:50%; transform: translate(-50%,-50%); -ms-transform: translate(-50%,-50%); -moz-transform: translate(-50%,-50%); -webkit-transform: translate(-50%,-50%); -o-transform: translate(-50%,-50%);} .add-class-box {position:fixed; width:80%; max-width:300px; min-width:240px; font-size:15px; color:#444; background-color:#fff; box-shadow: 0px 2px 8px rgba(146, 153, 169, 0.5); border-radius:5px; top:50%; left:50%; transform: translate(-50%,-50%); -ms-transform: translate(-50%,-50%); -moz-transform: translate(-50%,-50%); -webkit-transform: translate(-50%,-50%); -o-transform: translate(-50%,-50%);}
.add-class-tip {padding-top:1.2em; padding-bottom:.5em; font-weight:400;} .add-class-tip {padding-top:1.2em; padding-bottom:.5em; font-weight:400;}
.class-number-input {width:80%; max-width:240px; height:28px; border:1px solid #ccc; padding-left:5px; margin:0 auto; display:block;} .class-number-input {width:80%; max-width:240px; height:28px; border:1px solid #ccc; padding-left:5px; margin:0 auto; display:block;}
.cancel-btn {width:49%; height:37px; line-height:37px; text-align:center; vertical-align:middle; border-top:1px solid #ccc;} .cancel-btn {width:49%; height:37px; line-height:37px; text-align:center; vertical-align:middle; border-top:1px solid #ccc;}
.submit-btn {width:49%; height:37px; line-height:37px; text-align:center; vertical-align:middle; border-top:1px solid #ccc;} .submit-btn {width:49%; height:37px; line-height:37px; text-align:center; vertical-align:middle; border-top:1px solid #ccc;}
.slice {width:2%; text-align:center; border-top:1px solid #ccc;} .slice {width:2%; text-align:center; border-top:1px solid #ccc;}
.slice-line {width:1px; height:37px; margin:auto; background:#ccc;} .slice-line {width:1px; height:37px; margin:auto; background:#ccc;}
/*20160613邀请码样式*/ /*20160613邀请码样式*/
.qr-code-wrap {width:100%; padding:40px 0; background-color:#3b94d6;} .qr-code-wrap {width:100%; padding:40px 0; background-color:#3b94d6;}
.qr-code-box {width:225px; background-color:#fff; border-radius:3px; margin:0 auto;} .qr-code-box {width:225px; background-color:#fff; border-radius:3px; margin:0 auto;}
.share-class-name {font-size:18px; color:#3b3b3b; text-align:center; padding:12px; border-bottom:1px solid #cccccc;} .share-class-name {font-size:18px; color:#3b3b3b; text-align:center; padding:12px; border-bottom:1px solid #cccccc;}
.qr-img-wrap {width:100%; border-bottom:1px dashed #ccc;} .qr-img-wrap {width:100%; border-bottom:1px dashed #ccc;}
.qr-code-img {margin:36px auto; display:block;} .qr-code-img {margin:36px auto; display:block;}
.invitation-code-wrap {text-align:center; font-size:18px; color:#3b3b3b; padding:16px;} .invitation-code-wrap {text-align:center; font-size:18px; color:#3b3b3b; padding:16px;}
.share-code-wrap {width:100%; background-color:#efeff4;} .share-code-wrap {width:100%; background-color:#efeff4;}
.share-code-btn, .finish-btn {width:145px; height:35px; color:#fff; font-size:15px; line-height:35px; text-align:center; vertical-align:middle; background-color:#ff7239; margin:18px auto 20px auto; border-radius:50px; display:block;} .share-code-btn, .finish-btn {width:145px; height:35px; color:#fff; font-size:15px; line-height:35px; text-align:center; vertical-align:middle; background-color:#ff7239; margin:18px auto 20px auto; border-radius:50px; display:block;}
.share-code-instruction {max-width:228px; font-size:12px; color:#666; line-height:20px; margin:0 auto;} .share-code-instruction {max-width:228px; font-size:12px; color:#666; line-height:20px; margin:0 auto;}
/*20160613班级详情*/ /*20160613班级详情*/
.class-detail-name, .blue-title {width:100%; height:45px; line-height:45px; vertical-align:middle; background-color:#3b94d6; color:#fff; font-size:18px; text-align:center;} .class-detail-name, .blue-title {width:100%; height:45px; line-height:45px; vertical-align:middle; background-color:#3b94d6; color:#fff; font-size:18px; text-align:center;}
.blue-title-sub {position:absolute; right:10px;} .blue-title-sub {position:absolute; right:10px;}
.slice2 {width:2%; text-align:center; background-color:#fff; border-bottom:1px solid #ccc;} .slice2 {width:2%; text-align:center; background-color:#fff; border-bottom:1px solid #ccc;}
.slice3 {width:1%; height:38px; text-align:center; background-color:#fff; border-bottom:1px solid #ccc;} .slice3 {width:1%; height:38px; text-align:center; background-color:#fff; border-bottom:1px solid #ccc;}
.slice-line2 {width:1px; height:38px; margin:auto; background:#ccc;} .slice-line2 {width:1px; height:38px; margin:auto; background:#ccc;}
.class-detail-tab {width:23%; height:38px; line-height:38px; font-size:13px; color:#444; background-color:#fff; float:left; text-align:center; vertical-align:middle; border-bottom:1px solid #ccc;} .class-detail-tab {width:23%; height:38px; line-height:38px; font-size:13px; color:#444; background-color:#fff; float:left; text-align:center; vertical-align:middle; border-bottom:1px solid #ccc;}
.class-detail-tab2 {width:32%; height:38px; line-height:38px; font-size:13px; color:#444; background-color:#fff; float:left; text-align:center; vertical-align:middle; border-bottom:1px solid #ccc;} .class-detail-tab2 {width:32%; height:38px; line-height:38px; font-size:13px; color:#444; background-color:#fff; float:left; text-align:center; vertical-align:middle; border-bottom:1px solid #ccc;}
.class-detail-tab3 {width:48%; height:38px; line-height:38px; font-size:13px; color:#444; background-color:#fff; float:left; text-align:center; vertical-align:middle; border-bottom:1px solid #ccc;} .class-detail-tab3 {width:48%; height:38px; line-height:38px; font-size:13px; color:#444; background-color:#fff; float:left; text-align:center; vertical-align:middle; border-bottom:1px solid #ccc;}
.class-tab-active {border-bottom:3px solid #3b94d6;} .class-tab-active {border-bottom:3px solid #3b94d6;}
.tab-active-arrow {border-width:4px; position:absolute; top:41px; left:50%; transform:translate(-50%,0); border-color:#3b94d6 transparent transparent transparent; border-style:solid dashed dashed dashed;} .tab-active-arrow {border-width:4px; position:absolute; top:41px; left:50%; transform:translate(-50%,0); border-color:#3b94d6 transparent transparent transparent; border-style:solid dashed dashed dashed;}
.class-search-wrap {padding:8px 12px; position:relative;} .class-search-wrap {padding:8px 12px; position:relative;}
.class-search-inner {padding:0 30px; background-color:#fff;} .class-search-inner {padding:0 30px; background-color:#fff;}
.class-search-icon {position:absolute; top:16px; left:16px;} .class-search-icon {position:absolute; top:16px; left:16px;}
.class-detail-search {width:100%; height:33px; color:#999; background-color:#fff; border:none; outline:none;} .class-detail-search {width:100%; height:33px; color:#999; background-color:#fff; border:none; outline:none;}
.border-top {border-top:1px solid #ccc;} .border-top {border-top:1px solid #ccc;}
.class-detail-row {width:100%; line-height:18px; padding:10px 0; border-bottom:1px solid #ccc; background-color:#fff;} .class-detail-row {width:100%; line-height:18px; padding:10px 0; border-bottom:1px solid #ccc; background-color:#fff;}
.class-member-row {width:100%; line-height:18px; padding:5px 0; border-bottom:1px solid #ccc; background-color:#fff; position:relative;} .class-member-row {width:100%; line-height:18px; padding:5px 0; border-bottom:1px solid #ccc; background-color:#fff; position:relative;}
.class-test-tip {text-align:center; font-size:13px; color:#444; padding-top:40px;} .class-test-tip {text-align:center; font-size:13px; color:#444; padding-top:40px;}
.img-circle {border-radius:50% !important;} .img-circle {border-radius:50% !important;}
.member-banner {height:24px; line-height:24px; text-align:center; vertical-align:middle; background-color:#dfdfdf;} .member-banner {height:24px; line-height:24px; text-align:center; vertical-align:middle; background-color:#dfdfdf;}
.resource-width {width:76%;} .resource-width {width:76%;}
.courseware-from-width {max-width:57%;} .courseware-from-width {max-width:57%;}
.other-from-width {max-width:80%;} .other-from-width {max-width:80%;}
.course-name-width {width:68%;} .course-name-width {width:68%;}
/*20160614班级列表*/ /*20160614班级列表*/
.course-diff-row {width:100%; height:28px; line-height:28px; vertical-align:middle; background-color:#fff; border-bottom:1px solid #ccc;} .course-diff-row {width:100%; height:28px; line-height:28px; vertical-align:middle; background-color:#fff; border-bottom:1px solid #ccc;}
.course-list-row {width:100%; height:38px; line-height:38px; vertical-align:middle; border-top:1px solid #ccc; border-bottom:1px solid #ccc; background-color:#fff;} .course-list-row {width:100%; height:38px; line-height:38px; vertical-align:middle; border-top:1px solid #ccc; border-bottom:1px solid #ccc; background-color:#fff;}
.class-list {width:100%; border-bottom:1px solid #ccc;} .class-list {width:100%; border-bottom:1px solid #ccc;}
.class-list li {height:40px; line-height:40px; vertical-align:middle; margin:0 25px; border-left:1px solid #ccc; border-bottom:1px solid #ccc; position:relative;} .class-list li {height:40px; line-height:40px; vertical-align:middle; margin:0 25px; border-left:1px solid #ccc; border-bottom:1px solid #ccc; position:relative;}
.class-list-name {max-width:75%; display:inline-block;} .class-list-name {max-width:75%; display:inline-block;}
.class-list-dot {position:absolute; top:13px; left:-8px;} .class-list-dot {position:absolute; top:13px; left:-8px;}
.border-bottom-none {border-bottom:none !important;} .border-bottom-none {border-bottom:none !important;}
.border-top-none {border-top:none !important;} .border-top-none {border-top:none !important;}
.students-amount {height:14px; line-height:14px; vertical-align:middle; padding:2px 5px; background-color:#e6e6e6; border-radius:10px;} .students-amount {height:14px; line-height:14px; vertical-align:middle; padding:2px 5px; background-color:#e6e6e6; border-radius:10px;}
.new-class-btn {font-size:15px; color:#fff; background-color:#3b94d6; padding:10px 40px; border-radius:20px; display:inline-block; margin:0 auto;} .new-class-btn {font-size:15px; color:#fff; background-color:#3b94d6; padding:10px 40px; border-radius:20px; display:inline-block; margin:0 auto;}
.join-class-btn {font-size:15px; color:#444; background-color:#ccc; padding:10px 40px; border-radius:20px; display:inline-block; margin:0 auto;} .join-class-btn {font-size:15px; color:#444; background-color:#ccc; padding:10px 40px; border-radius:20px; display:inline-block; margin:0 auto;}
.new-class-input {width:60%; color:#555; height:16px; line-height:16px; vertical-align:middle; border:none; outline:none; padding:8px 0;} .new-class-input {width:60%; color:#555; height:16px; line-height:16px; vertical-align:middle; border:none; outline:none; padding:8px 0;}
.class-list-setting {position:absolute; top:11px; right:10px;} .class-list-setting {position:absolute; top:11px; right:10px;}
.class-setting-wrap {width:38px; height:38px; position:absolute; top:0; right:0;} .class-setting-wrap {width:38px; height:38px; position:absolute; top:0; right:0;}
/*20160616登录注册*/ /*20160616登录注册*/
.login-wrap {padding:0 10px;} .login-wrap {padding:0 10px;}
.input-box-wrap {padding-right:17px;} .input-box-wrap {padding-right:17px;}
.input-box { -webkit-appearance: none; font-size: 15px;width:100%; height:18px; padding: 10px 0px 10px 5px; line-height:18px; border:1px solid #ccc; border-radius:5px;} .input-box { -webkit-appearance: none; font-size: 15px;width:100%; height:18px; padding: 10px 0px 10px 5px; line-height:18px; border:1px solid #ccc; border-radius:5px;}
.login-op-wrap {height:30px; line-height:30px; vertical-align:middle;} .login-op-wrap {height:30px; line-height:30px; vertical-align:middle;}
.login-box{display:inline-block; width:14px; height:14px; line-height:14px; text-align:center; vertical-align:middle; border:1px solid #ccc; background:#fff; border-radius:3px; color:#fff; cursor:pointer;} .login-box{display:inline-block; width:14px; height:14px; line-height:14px; text-align:center; vertical-align:middle; border:1px solid #ccc; background:#fff; border-radius:3px; color:#fff; cursor:pointer;}
.login-box.checked{background:#63c360; border:1px solid #63c360;} .login-box.checked{background:#63c360; border:1px solid #63c360;}
.login-box.checked:after{content:url(/images/wechat/checked.png);} .login-box.checked:after{content:url(/images/wechat/checked.png);}
.forget-psw-wrap {width:60px; margin:0 auto;} .forget-psw-wrap {width:60px; margin:0 auto;}
.forget-psw {position:fixed; bottom:10px;} .forget-psw {position:fixed; bottom:10px;}
/*二级回复*/ /*二级回复*/
.mult-reply-container{ border:solid 1px #f3ddb3; background:#fffef4; padding:4px;color:#999;} .mult-reply-container{ border:solid 1px #f3ddb3; background:#fffef4; padding:4px;color:#999;}
.mult-reply-content{ color:#555; font-size:13px;} .mult-reply-content{ color:#555; font-size:13px;}
.mult-reply-hide{ text-align:center; display:block; font-size:14px; color:#aaa; border-bottom:1px solid #F3DDB3; padding:8px 0;} .mult-reply-hide{ text-align:center; display:block; font-size:14px; color:#aaa; border-bottom:1px solid #F3DDB3; padding:8px 0;}
.mult-reply-arrow{ color:#aaa; margin-right:10px; font-size:14px; font-weight:bold;} .mult-reply-arrow{ color:#aaa; margin-right:10px; font-size:14px; font-weight:bold;}
/*20160729项目说明*/ /*20160729项目说明*/
.project-intro {line-height:2; width:140px; margin-left:auto; margin-right:auto;} .project-intro {line-height:2; width:120px; margin-left:auto; margin-right:auto;}
.project-intro li {list-style:disc; margin-left:20px;} .project-intro li {position:relative;}
.project-intro-dot {font-size:25px; font-weight:bold; position:absolute; left:-10px; top:-13px;}
/*新建说明*/
.new-tip {line-height:2;}
.new-tip li {position:relative; padding-left:10px;}
Loading…
Cancel
Save