Merge branch 'weixin_guange' into cxt_course

This commit is contained in:
guange 2016-06-24 15:34:32 +08:00
commit da09983f9e
93 changed files with 1412 additions and 1670 deletions

1
.gitignore vendored
View File

@ -34,3 +34,4 @@ vendor/cache
/config/initializers/gitlab_config.rb
1234567
public/javascripts/wechat/node_modules/
.ruby-version

View File

@ -81,7 +81,7 @@ group :assets do
gem 'coffee-rails', '~> 3.2.1'
# See https://github.com/sstephenson/execjs#readme for more supported runtimes
gem 'therubyracer', :platforms => :ruby
# gem 'therubyracer', :platforms => :ruby
gem 'uglifier', '>= 1.0.3'
end

View File

@ -23,6 +23,7 @@ module Mobile
version 'v1', using: :path
format :json
content_type :json, "application/json;charset=UTF-8"
use ActionDispatch::Session::CookieStore
use Mobile::Middleware::ErrorHandler
helpers do
@ -34,6 +35,10 @@ module Mobile
raise('Unauthorized. 用户认证失败.') unless current_user
end
def session
env['rack.session']
end
def current_user
openid = params[:openid]
if openid
@ -67,8 +72,7 @@ module Mobile
mount Apis::NewComment
mount Apis::Praise
#add_swagger_documentation ({api_version: 'v1', base_path: 'http://u06.shellinfo.cn/trustie/api'})
#add_swagger_documentation ({api_version: 'v1', base_path: '/api'}) if Rails.env.development?
add_swagger_documentation ({api_version: 'v1', base_path: '/api'}) if Rails.env.development?
end
end

View File

@ -9,7 +9,7 @@ module Mobile
params do
requires :page, type: Integer
requires :openid, type: String
requires :token, type: String
end
post do
authenticate!

View File

@ -97,25 +97,20 @@ module Mobile
desc "加入课程"
params do
requires :course_password, type: String
requires :token, type: String
requires :invite_code, type: String, desc: '邀请码'
end
post ":id" do
post "join" do
authenticate!
cs = CoursesService.new
status = cs.join_course({:object_id => params[:id],:course_password => params[:course_password]},current_user)
out = {status: status[:state]}
message = case status[:state]
when 0; "加入成功"
when 1; "密码错误"
when 2; "课程已过期 请联系课程管理员重启课程。(在配置课程处)"
when 3; "您已经加入了课程"
when 4; "您加入的课程不存在"
when 5; "您还未登录"
else; "未知错误,请稍后再试"
end
out.merge(message: message)
status = cs.join_course({openid: params[:openid], invite_code: params[:invite_code]}, current_user)
{
status: status[:state],
messsge:CoursesService::JoinCourseError.message(status[:state])
}
end
desc "退出课程"
params do
requires :token, type: String
@ -201,6 +196,7 @@ module Mobile
end
route_param :id do
get do
authenticate!
cs = CoursesService.new
course = cs.show_course(params,(current_user.nil? ? User.find(2):current_user))
#course = Course.find(params[:id])

View File

@ -8,7 +8,8 @@ module Mobile
desc "get special issuse"
get ':id' do
user = UserWechat.find_by_openid(params[:openid]).user
authenticate!
user = current_user
issue = Issue.find params[:id]
present :data, issue, with: Mobile::Entities::Issue,user: user
present :status, 0

View File

@ -7,7 +7,8 @@ module Mobile
desc "get special journal"
get ':id' do
user = UserWechat.find_by_openid(params[:openid]).user
authenticate!
user = current_user
jour = JournalsForMessage.find params[:id]
present :data, jour, with: Mobile::Entities::Jours,user: user
present :status, 0

View File

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

View File

@ -11,12 +11,12 @@ module Mobile
params do
requires :type, type: String
requires :content, type: String
requires :openid, type: String
requires :token, type: String
end
post ':id' do
authenticate!
type = params[:type]
result = 1
current_user = UserWechat.find_by_openid(params[:openid]).user
if params[:content]!="" && current_user
case type
when "HomeworkCommon"

View File

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

View File

@ -9,12 +9,13 @@ module Mobile
params do
requires :type, type: String
requires :openid, type: String
requires :token, type: String
end
post ':id' do
authenticate!
obj_id = params[:id]
obj_type = params[:type]
user = UserWechat.find_by_openid(params[:openid]).user
user = current_user
pts = PraiseTread.where("praise_tread_object_id=? and praise_tread_object_type=? and user_id=?",obj_id,obj_type.to_s,user.id).first
if pts.blank?
praise_or_cancel(obj_type,obj_id,user,1)

View File

@ -4,6 +4,48 @@ module Mobile
class Users < Grape::API
resource :users do
desc "查询是否已绑定"
params do
requires :openid, type: String, desc: 'wechat openid'
end
post 'isbind' do
openid = params[:openid]
uw = UserWechat.where(openid: openid).first
raise "还未绑定trustie帐户" unless uw
user = uw.user
::ApiKey.delete_all(user_id: user.id)
key = ::ApiKey.create!(user_id: user.id)
present status: 0, token: key.access_token
end
desc "绑定微信用户"
params do
requires :login, type: String, desc: 'username'
requires :password, type: String, desc: 'password'
end
post 'wxbind' do
openid = session[:wechat_openid]
logger.debug "openid ============== #{openid}"
raise "无法获取到openid,请在微信中打开本页面" unless openid
uw = UserWechat.where(openid: openid).first
raise "此微信号已绑定用户(#{uw.user.login}), 不能重复绑定" if uw
user, last_login_on = User.try_to_login(params[:login], params[:password])
raise "用户名或密码错误,请重新输入" unless user
#补全用户信息
raise "此用户已经绑定过公众号, 请换一个帐户试试" if user.user_wechat
UserWechat.create!(
openid: openid,
user: user
)
# ws = WechatService.new
# ws.binding_succ_notice(user.id, "您已成功绑定Trustie平台", user.login, format_time(Time.now))
present status: 0, message: '您已成功绑定Trustie平台'
end
desc "注册用户"
params do
requires :login, type: String, desc: 'username'

View File

@ -7,7 +7,8 @@ module Mobile
desc "get one homework"
get ':id' do
user = UserWechat.find_by_openid(params[:openid]).user
authenticate!
user = current_user
homework = HomeworkCommon.find params[:id]
present :data, homework, with: Mobile::Entities::Whomework,user: user
present :status, 0

View File

@ -45,6 +45,8 @@ module Mobile
course_expose :tea_id
course_expose :term
course_expose :time
course_expose :invite_code
course_expose :qrcode
course_expose :updated_at
course_expose :course_student_num
expose :teacher, using: Mobile::Entities::User do |c, opt|

View File

@ -26,6 +26,8 @@ module Mobile
u.nil? || u.user_extensions.nil? ? "" : u.user_extensions.student_id
when :realname
u.nil? ? "" : get_user_realname(u)
when :name
u.nil? ? "" : u.show_name
end
end
end
@ -57,6 +59,11 @@ module Mobile
user_expose :student_num
# 活跃值
user_expose :active_count
user_expose :role_name
user_expose :name
end
end

View File

@ -3,10 +3,23 @@ class WechatsController < ActionController::Base
wechat_responder
include ApplicationHelper
# ROOT_URL = "#{Setting.protocol}://#{Setting.host_name}/"
ROOT_URL = "http://wechat.trustie.net"
# default text responder when no other match
on :text do |request, content|
request.reply.text "您的意见已收到,感谢您的反馈!" # Just echo
#邀请码
begin
uw = user_binded?(request[:FromUserName])
if !uw
return sendBind()
else
return join_class({invite_code: content}, uw.user)
end
rescue => e
logger.error e.inspect
logger.error e.backtrace.join("\n")
return request.reply.text e
end
end
# When receive 'help', will trigger this responder
@ -35,7 +48,18 @@ class WechatsController < ActionController::Base
# When subscribe user scan scene_id in public account
on :scan, with: 'scene_id' do |request, ticket|
request.reply.text "Subscribe user #{request[:FromUserName]} Ticket #{ticket}"
begin
uw = user_binded?(request[:FromUserName])
if !uw
return sendBind()
else
return join_class({ticket: ticket}, uw.user)
end
rescue => e
logger.error e.inspect
logger.error e.backtrace.join("\n")
return request.reply.text e
end
end
# When no any on :scan responder can match subscribe user scaned scene_id
@ -128,6 +152,15 @@ class WechatsController < ActionController::Base
default_msg(request)
end
on :click, with: 'JOIN_CLASS' do |request, key|
uw = user_binded?(request[:FromUserName])
unless uw
sendBind(request)
else
request.reply.text "请直接回复6位班级邀请码\n(不区分大小写):"
end
end
def default_msg(request)
uw = user_binded?(request[:FromUserName])
if uw && uw.user
@ -145,8 +178,8 @@ class WechatsController < ActionController::Base
" } }
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=#{login_wechat_url}&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect"
pic_url = "#{Setting.protocol}://#{Setting.host_name}/images/weixin_pic.jpg"
url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=#{Wechat.config.appid}&redirect_uri=#{ROOT_URL+'/wechat/user_activities'}&response_type=code&scope=snsapi_base&state=login#wechat_redirect"
pic_url = "#{ROOT_URL}/images/weixin_pic.jpg"
article.item title: "#{n[:title]}",
description: n[:content],
pic_url: pic_url,
@ -154,18 +187,53 @@ class WechatsController < ActionController::Base
end
end
def join_class(params, user)
course = nil
course = Course.where(qrcode: params[:ticket]) if params[:ticket]
course = Course.where(invite_code: params[:invite_code]) if params[:invite_code]
raise "课程不存在" if course.blank?
cs = CoursesService.new
status = cs.join_course(course.invite_code, user)
logger.info status
if status[:state] != 0
raise CoursesService::JoinCourseError.message(status[:state])
end
course = status[:course]
news = (1..1).each_with_object([]) { |n, memo| memo << { title: '恭喜您成功加入班级,开始学习吧!',
content: "课程名称: #{course.name}\n班级名称: #{course.name}\n任课老师: #{course.teacher.show_name}\n进入班级,和小伙伴愉快的学习吧!"} }
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?id='+course.id.to_s}&response_type=code&scope=snsapi_base&state=myclass#wechat_redirect"
pic_url = "#{ROOT_URL}/images/wechat/class.jpg"
article.item title: "#{n[:title]}",
description: n[:content],
pic_url: pic_url,
url: url
end
end
### controller method
module Controllers
def get_open_id
def get_bind
begin
code = params[:code] || session[:wechat_code]
openid = get_openid_from_code(code)
raise "无法获取到微信openid" unless openid
render :json => {status:0, openid: openid}
uw = UserWechat.where(openid: openid).first
raise "还未绑定trustie帐户" unless uw
logger.debug "get_bind ============= #{uw}"
user = uw.user
::ApiKey.delete_all(user_id: user.id)
key = ::ApiKey.create!(user_id: user.id)
render :json =>{status: 0, token: key.access_token}
rescue Exception=>e
render :json => {status: -1, msg: e.message}
render :json => {status: -1, message: e.message}
end
end
@ -175,7 +243,7 @@ class WechatsController < ActionController::Base
code = params[:code] || session[:wechat_code]
openid = get_openid_from_code(code)
raise "无法获取到openid" unless openid
raise "无法获取到openid,请在微信中打开本页面" unless openid
raise "此微信号已绑定用户, 不能重复绑定" if user_binded?(openid)
user, last_login_on = User.try_to_login(params[:username], params[:password])
@ -206,19 +274,26 @@ class WechatsController < ActionController::Base
def user_activities
session[:wechat_code] = params[:code] if params[:code]
code = params[:code] || session[:wechat_code]
openid = get_openid_from_code(code)
@wechat_user = user_binded?(openid)
unless @wechat_user
redirect_to login_wechat_path
return
@path = '/'+(params[:state] || '')
open_id = get_openid_from_code(params[:code]) rescue
unless open_id
render 'wechats/open_wechat', layout: nil and return
end
if params[:state] == 'myclass'
@course_id = params[:id];
end
session[:wechat_openid] = open_id
if params[:code]
redirect_to "/wechat/user_activities##{@path}?id=#{params[:id]}" and return
end
render 'wechats/user_activities', layout: nil
end
private
def get_openid_from_code(code)
return 'oCnvgvz8R7QheXE-R9Kkr39j8Ndg' if code =='only-for-test'
openid = session[:wechat_openid]
unless openid

View File

@ -489,4 +489,26 @@ module ApiHelper
self.update_attribute(:praise_num, self.praise_num.to_i - num)
end
class Errors
def self.define_error(arr)
@errors = {}
arr.each_with_index { |item, index|
if index %2 == 1
@errors[arr[index-1]] = item
end
}
if arr.count % 2== 1
@default_error = arr.last
else
@default_error = "未知错误"
end
end
def self.message(msg_id)
@errors[msg_id] || @default_error
end
end
end

View File

@ -270,13 +270,22 @@ module CoursesHelper
# =====================================================================================
# return people list
def searchPeopleByName(course, role_name)
course.members.select{|m|
m.roles.any?{|r|r.name == role_name}
}
end
def searchTeacherAndAssistant project
#searchPeopleByRoles(project, TeacherRoles)
members = []
project.members.includes(:user).each do |m|
members << m if m && m.user && m.user.allowed_to?(:as_teacher,project)
end
members
searchPeopleByName(project, 'Manager').concat(
searchPeopleByName(project, 'Teacher')
).concat(
searchPeopleByName(project, 'TeachingAsistant')
)
end
def searchStudent project
searchPeopleByName(project, 'Student')
end
def TeacherAndAssistantCount course
@ -293,19 +302,6 @@ module CoursesHelper
members
end
def searchStudent project
#searchPeopleByRoles(project, StudentRoles)
members = []
project.members.each do |m|
if m && m.user && m.user.allowed_to?(:as_student,project)
members << m
end
end
members
end
def searchStudent_by_name project, name
#searchPeopleByRoles(project, StudentRoles)
members = []

View File

@ -1,3 +1,5 @@
#coding=utf-8
require 'elasticsearch/model'
class Course < ActiveRecord::Base
include Redmine::SafeAttributes
@ -405,6 +407,7 @@ class Course < ActiveRecord::Base
self.course_messages << CourseMessage.new(:user_id => self.tea_id, :course_id => self.id, :viewed => false)
end
#项目与课程分离后,很多课程的名称等信息为空,这些数据信息存储在项目表中!!就是数据兼容的问题
#def name
# read_attribute('name') || Project.find_by_identifier(self.extra).try(:name)
@ -422,12 +425,14 @@ class Course < ActiveRecord::Base
# __elasticsearch__.delete_document
# end
def create_course_ealasticsearch_index
return if Rails.env.development?
if self.is_public == 1 and self.is_delete == 0 #公开 和 没有被删除的课程才被索引
self.__elasticsearch__.index_document
end
end
def update_course_ealasticsearch_index
return if Rails.env.development?
if self.is_public == 1 and self.is_delete == 0 #如果是初次更新成为公开或者恢复被删除的情况,会报错,那么这条记录尚未被索引过。没有报错就是更新的其他属性
begin
self.__elasticsearch__.update_document
@ -444,6 +449,7 @@ class Course < ActiveRecord::Base
end
def delete_course_ealasticsearch_index
return if Rails.env.development?
begin
self.__elasticsearch__.delete_document
rescue => e
@ -451,6 +457,31 @@ class Course < ActiveRecord::Base
end
end
# 生成邀请码
CODES = %W(2 3 4 5 6 7 8 9 A B C D E F G H J K L N M O P Q R S T U V W X Y Z)
def generate_invite_code
code = invite_code
if !invite_code || invite_code.size <5
self.invite_code = CODES.sample(5).join
return generate_invite_code if Course.where(invite_code: invite_code).present?
save! && reload
code = invite_code
end
code
end
def generate_qrcode
ticket = self.qrcode
if !ticket || ticket.size < 10
response = Wechat.api.qrcode_create_scene(invite_code)
logger.debug "response = #{response}"
self.qrcode = response['ticket']
save! && reload
ticket = qrcode
end
ticket
end
end

View File

@ -68,7 +68,6 @@ class CoursesService
if current_user.nil? || !(current_user.admin? || c.is_public == 1 || (c.is_public == 0 && current_user.member_of_course?(c)))
raise '403'
end
@teachers= searchTeacherAndAssistant(c)
#@canShowCode = isCourseTeacher(User.current.id,course) && params[:role] != '1'
case params[:role]
when '1'
@ -87,7 +86,11 @@ class CoursesService
gender = m.user.user_extensions.gender.nil? ? 0 : m.user.user_extensions.gender
work_unit = get_user_work_unit 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, :brief_introduction => m.user.user_extensions.brief_introduction,:realname=>m.user.realname}
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,
:brief_introduction => m.user.user_extensions.brief_introduction,:realname=>m.user.realname}
end
users
end
@ -162,6 +165,9 @@ class CoursesService
#显示课程
def show_course(params,current_user)
course = Course.find(params[:id])
course.generate_invite_code
course.generate_qrcode
if course.school
work_unit = course.school.name
else
@ -300,23 +306,31 @@ class CoursesService
@state
end
class JoinCourseError < Errors
define_error [
0, '加入成功',
1, '密码错误',
2, '课程已过期 请联系课程管理员重启课程。',
3, '您已经加入了课程',
4, '您加入的课程不存在',
5, '您还未登录',
6, '申请成功,请等待审核完毕',
7, '您已经发送过申请了,请耐心等待',
8, '您已经是该课程的教师了',
9, '您已经是该课程的教辅了',
10, '您已经是该课程的管理员了',
'未知错误,请稍后再试'
]
end
#加入课程
#object_id课程id
#course_password :加入课程的密码
#@state == 0 加入成功
#@state == 1 密码错误
#@state == 2 课程已过期 请联系课程管理员重启课程。(在配置课程处)
#@state == 3 您已经加入了课程
#@state == 4 您加入的课程不存在
#@state == 5 您还未登录
#@state == 6 申请成功,请等待审核完毕
#@state == 7 您已经发送过申请了,请耐心等待
#@state == 8 您已经是该课程的教师了
#@state == 9 您已经是该课程的教辅了
#@state == 10 您已经是该课程的管理员了
#@state 其他 未知错误,请稍后再试
def join_course params,current_user
course = Course.find_by_id params[:object_id]
course = if params[:invite_code]
Course.find_by_invite_code(params[:invite_code])
else
Course.find_by_id params[:object_id]
end
@state = 10
if course
@ -326,7 +340,7 @@ class CoursesService
if current_user.member_of_course?(course) #如果已经是成员
member = course.members.where("user_id=#{current_user.id} and course_id=#{course.id}")[0]
roleName = member.roles[0].name if member
if params[:course_password] == course.password
if params[:course_password] == course.password || params[:invite_code].present?
#如果加入角色为学生 并且当前是学生
if params[:role] == "10" && roleName == "Student"
@state = 3
@ -359,7 +373,7 @@ class CoursesService
@state = 1
end
else
if params[:course_password] == course.password
if params[:course_password] == course.password || params[:invite_code].present?
if params[:role] == "10" || params[:role] == nil
members = []
members << Member.new(:role_ids => [10], :user_id => current_user.id)

View File

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=0">
</head>
<body>
<script type="text/javascript">
var ua = navigator.userAgent.toLowerCase();
var isWeixin = ua.indexOf('micromessenger') != -1;
var isAndroid = ua.indexOf('android') != -1;
var isIos = (ua.indexOf('iphone') != -1) || (ua.indexOf('ipad') != -1);
if (!isWeixin) {
document.head.innerHTML = '<title>抱歉,出错了</title><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=0"><link rel="stylesheet" type="text/css" href="https://res.wx.qq.com/connect/zh_CN/htmledition/style/wap_err1a9853.css">';
document.body.innerHTML = '<div class="page_msg"><div class="inner"><span class="msg_icon_wrp"><i class="icon80_smile"></i></span><div class="msg_content"><h4>请在微信客户端打开链接</h4></div></div></div>';
}
</script>
</body>
</html>

View File

@ -9,10 +9,16 @@
<meta name="apple-mobile-web-app-capable" content="no" />
<meta content='True' name='HandheldFriendly' />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
<link type="text/css" rel="stylesheet" href="/stylesheets/weui/weui.min.css" />
<link type="text/css" rel="stylesheet" href="/stylesheets/weui/weixin.css" />
<script type="text/javascript">
window.g_openid = '<%= @wechat_user.openid %>';
window.g_debug = false; //调试标志,如果在本地请置为true
window.apiUrl = '/api/v1/';
window.g_redirect_path = '<%= @path %>';
<% if @course_id %>
window.g_courseid = <%= @course_id %>;
<% end %>
</script>
</head>
@ -20,8 +26,29 @@
<div ng-view>
</div>
<script src="/javascripts/wechat/build/angular.all.min.js"></script>
<script src="https://dn-demotest.qbox.me/angular.all.min.js"></script>
<!--<script src="/javascripts/wechat/build/angular.all.min.js"></script>-->
<!--<script src="/javascripts/wechat/build/app.min.js"></script>-->
<script src="/javascripts/wechat/app.js"></script>
<script src="/javascripts/wechat/others/factory.js"></script>
<script src="/javascripts/wechat/others/filter.js"></script>
<script src="/javascripts/wechat/directives/alert.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/loading_spinner.js"></script>
<script src="/javascripts/wechat/controllers/reg.js"></script>
<script src="/javascripts/wechat/controllers/invite_code.js"></script>
<script src="/javascripts/wechat/controllers/login.js"></script>
<script src="/javascripts/wechat/controllers/activity.js"></script>
<script src="/javascripts/wechat/controllers/add_class.js"></script>
<script src="/javascripts/wechat/controllers/blog.js"></script>
<script src="/javascripts/wechat/controllers/course_notice.js"></script>
<script src="/javascripts/wechat/controllers/discussion.js"></script>
<script src="/javascripts/wechat/controllers/homework.js"></script>
<script src="/javascripts/wechat/controllers/issue.js"></script>
<script src="/javascripts/wechat/controllers/journals.js"></script>
<script src="/javascripts/wechat/controllers/myclass.js"></script>
<script src="/javascripts/wechat/others/routes.js"></script>
</body>
</html>

View File

@ -1253,7 +1253,7 @@ RedmineApp::Application.routes.draw do
get :login
get :user_activities
post :bind
post :get_open_id
post :get_bind
end
end

View File

@ -5,11 +5,11 @@ default: &default
# Or if using public account, only need above two line
# guange test
#appid: "wxf694495398c7d470"
#secret: "743e038392f1d89540e95f8f7645849a"
appid: "wxf694495398c7d470"
secret: "743e038392f1d89540e95f8f7645849a"
appid: "wx8e1ab05163a28e37"
secret: "beb4d3bc4b32b3557811680835357841"
# appid: "wx8e1ab05163a28e37"
# secret: "beb4d3bc4b32b3557811680835357841"
token: "123456"
access_token: "1234567"

View File

@ -0,0 +1,5 @@
class AddInviteCodeToCourse < ActiveRecord::Migration
def change
add_column :courses, :invite_code, :string
end
end

View File

@ -0,0 +1,6 @@
class AddIndexToInviteCode < ActiveRecord::Migration
def change
add_column :courses, :qrcode, :string
add_index :courses, :invite_code, unique: true
end
end

View File

@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20160612043259) do
ActiveRecord::Schema.define(:version => 20160624032138) do
create_table "activities", :force => true do |t|
t.integer "act_id", :null => false
@ -550,8 +550,12 @@ ActiveRecord::Schema.define(:version => 20160612043259) do
t.integer "excellent_option", :default => 0
t.integer "is_copy", :default => 0
t.integer "visits", :default => 0
t.string "invite_code"
t.string "qrcode"
end
add_index "courses", ["invite_code"], :name => "index_courses_on_invite_code", :unique => true
create_table "custom_fields", :force => true do |t|
t.string "type", :limit => 30, :default => "", :null => false
t.string "name", :limit => 30, :default => "", :null => false

View File

@ -20,23 +20,25 @@
<div class="cl"></div>
<div class="post-title mt5 mb5 hidden"><span class="c-grey3 f15 fb">{{act.subject|safeHtml}}</span></div>
<div class="post-content c-grey3">
<div class="post-all-content mb5" ng-bind-html="act.description|safeHtml"></div>
<div class="post-all-content" ng-bind-html="act.description|safeHtml"></div>
<span class="mr15 f13 c-grey2">迟交扣分:{{act.homework_common_detail.late_penalty}}分</span> <span ng-if="!act.homework_common_detail.anonymous_comment" class="f13 c-grey2">匿评开启时间:{{act.homework_common_detail.evaluation_start}}</span><br />
<span ng-if="!act.homework_common_detail.anonymous_comment" class="mr15 f13 c-grey2">缺评扣分:{{act.homework_common_detail.absence_penalty}}分/作品</span> <span ng-if="!act.homework_common_detail.anonymous_comment" class="f13 c-grey2">匿评关闭时间:{{act.homework_common_detail.evaluation_end}}</span>
</div>
<!--<a herf="javascript:void(0);" class="c-grey2 f13 fr mt5 mb10 post-more mr20 undis" text-auto-height>点击展开</a>-->
<div class="cl"></div>
</div>
<span ng-if="act.homework_common_detail.homework_type == 1" class="c-grey f12 fl mr15 mt2">普通作业</span>
<span ng-if="act.homework_common_detail.homework_type == 2" class="c-grey f12 fl mr15 mt2">编程作业</span>
<span ng-if="act.homework_common_detail.homework_type == 3" class="c-grey f12 fl mr15 mt2">分组作业</span>
<span class="c-grey f12 fl mt2">{{act.latest_update}}</span>
<a ng-if="!act.reply_count" ng-click="goDetail('homework',act.act_id, act.id)" class="c-grey2 fr f12"><img src="/images/wechat/w_reply.png" height="15" class="mr5" /><span style="vertical-align:top;">回复</span></a>
<a ng-if="act.reply_count" ng-click="goDetail('homework',act.act_id, act.id)" class="c-grey2 fr f12"><img src="/images/wechat/w_reply.png" height="15" class="mr5" /><span style="vertical-align:top;">{{act.reply_count}}</span></a>
<div class="c-grey fr f12 mr25" ng-if="!act.praise_count" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" height="15" class="mr5" /><span style="vertical-align:top;"></span></div>
<div class="c-grey fr f12 mr25" ng-if="act.praise_count && !act.has_praise" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" height="15" class="mr5" /><span style="vertical-align:top;">{{act.praise_count}}</span></div>
<div class="c-grey fr f12 mr25" ng-if="act.has_praise" ng-click="decreasePraise(act);"><img src="/images/wechat/w_praised.png" height="15" class="mr5" /><span style="vertical-align:top;">{{act.praise_count}}</span></div>
<div class="cl"></div>
<div class="post-op-banner">
<span ng-if="act.homework_common_detail.homework_type == 1" class="c-grey f12 fl mr15">普通作业</span>
<span ng-if="act.homework_common_detail.homework_type == 2" class="c-grey f12 fl mr15">编程作业</span>
<span ng-if="act.homework_common_detail.homework_type == 3" class="c-grey f12 fl mr15">分组作业</span>
<span class="c-grey f12 fl">{{act.latest_update}}</span>
<a ng-if="!act.reply_count" ng-click="goDetail('homework',act.act_id, act.id)" class="c-grey2 fr f12"><img src="/images/wechat/w_reply.png" height="15" class="mr5 mt3" /><span style="vertical-align:top;">回复</span></a>
<a ng-if="act.reply_count" ng-click="goDetail('homework',act.act_id, act.id)" class="c-grey2 fr f12"><img src="/images/wechat/w_reply.png" height="15" class="mr5 mt3" /><span style="vertical-align:top;">{{act.reply_count}}</span></a>
<div class="c-grey fr f12 mr25" ng-if="!act.praise_count" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" height="15" class="mr5 mt3" /><span class="num-block"></span></div>
<div class="c-grey fr f12 mr25" ng-if="act.praise_count && !act.has_praise" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" height="15" class="mr5 mt3" /><span class="num-block">{{act.praise_count}}</span></div>
<div class="c-grey fr f12 mr25" ng-if="act.has_praise" ng-click="decreasePraise(act);"><img src="/images/wechat/w_praised.png" height="15" class="mr5 mt3" /><span class="num-block">{{act.praise_count}}</span></div>
<div class="cl"></div>
</div>
</div>
</div>
</div>
@ -58,14 +60,16 @@
<!--<a herf="javascript:void(0);" class="c-grey2 f13 fr mt5 mb10 post-more mr20 undis" text-auto-height>点击展开</a>-->
<div class="cl"></div>
</div>
<span class="c-grey f12 fl mr15 mt2">{{act.activity_type_name}}</span>
<span class="c-grey f13 fl mt2">{{act.latest_update}}</span>
<a ng-if="!act.reply_count" ng-click="goDetail('course_notice',act.act_id, act.id)" class="c-grey2 fr f12"><img src="/images/wechat/w_reply.png" height="15" class="mr5" /><span style="vertical-align:top;">回复</span></a>
<a ng-if="act.reply_count" ng-click="goDetail('course_notice',act.act_id, act.id)" class="c-grey2 fr f12"><img src="/images/wechat/w_reply.png" height="15" class="mr5" /><span style="vertical-align:top;">{{act.reply_count}}</span></a>
<div class="c-grey fr f12 mr25" ng-if="!act.praise_count" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" height="15" class="mr5" /><span style="vertical-align:top;"></span></div>
<div class="c-grey fr f12 mr25" ng-if="act.praise_count && !act.has_praise" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" height="15" class="mr5" /><span style="vertical-align:top;">{{act.praise_count}}</span></div>
<div class="c-grey fr f12 mr25" ng-if="act.has_praise" ng-click="decreasePraise(act);"><img src="/images/wechat/w_praised.png" height="15" class="mr5" /><span style="vertical-align:top;">{{act.praise_count}}</span></div>
<div class="cl"></div>
<div class="post-op-banner">
<span class="c-grey f12 fl mr15">{{act.activity_type_name}}</span>
<span class="c-grey f12 fl">{{act.latest_update}}</span>
<a ng-if="!act.reply_count" ng-click="goDetail('course_notice',act.act_id, act.id)" class="c-grey2 fr f12"><img src="/images/wechat/w_reply.png" height="15" class="mr5 mt3" /><span style="vertical-align:top;">回复</span></a>
<a ng-if="act.reply_count" ng-click="goDetail('course_notice',act.act_id, act.id)" class="c-grey2 fr f12"><img src="/images/wechat/w_reply.png" height="15" class="mr5 mt3" /><span style="vertical-align:top;">{{act.reply_count}}</span></a>
<div class="c-grey fr f12 mr25" ng-if="!act.praise_count" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" height="15" class="mr5 mt3" /><span class="num-block"></span></div>
<div class="c-grey fr f12 mr25" ng-if="act.praise_count && !act.has_praise" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" height="15" class="mr5 mt3" /><span class="num-block">{{act.praise_count}}</span></div>
<div class="c-grey fr f12 mr25" ng-if="act.has_praise" ng-click="decreasePraise(act);"><img src="/images/wechat/w_praised.png" height="15" class="mr5 mt3" /><span class="num-block">{{act.praise_count}}</span></div>
<div class="cl"></div>
</div>
</div>
</div>
</div>
@ -87,14 +91,16 @@
<!--<a herf="javascript:void(0);" class="c-grey2 f13 fr mt5 mb10 post-more mr20 undis" text-auto-height>点击展开</a>-->
<div class="cl"></div>
</div>
<span class="c-grey f12 fl mr15 mt2">{{act.activity_type_name}}</span>
<span class="c-grey f13 fl mt2">{{act.latest_update}}</span>
<a ng-if="!act.reply_count" ng-click="goDetail('course_discussion',act.act_id, act.id)" class="c-grey2 fr f12"><img src="/images/wechat/w_reply.png" height="15" class="mr5" /><span style="vertical-align:top;">回复</span></a>
<a ng-if="act.reply_count" ng-click="goDetail('course_discussion',act.act_id, act.id)" class="c-grey2 fr f12"><img src="/images/wechat/w_reply.png" height="15" class="mr5" /><span style="vertical-align:top;">{{act.reply_count}}</span></a>
<div class="c-grey fr f12 mr25" ng-if="!act.praise_count" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" height="15" class="mr5" /><span style="vertical-align:top;"></span></div>
<div class="c-grey fr f12 mr25" ng-if="act.praise_count && !act.has_praise" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" height="15" class="mr5" /><span style="vertical-align:top;">{{act.praise_count}}</span></div>
<div class="c-grey fr f12 mr25" ng-if="act.has_praise" ng-click="decreasePraise(act);"><img src="/images/wechat/w_praised.png" height="15" class="mr5" /><span style="vertical-align:top;">{{act.praise_count}}</span></div>
<div class="cl"></div>
<div class="post-op-banner">
<span class="c-grey f12 fl mr15">{{act.activity_type_name}}</span>
<span class="c-grey f12 fl">{{act.latest_update}}</span>
<a ng-if="!act.reply_count" ng-click="goDetail('course_discussion',act.act_id, act.id)" class="c-grey2 fr f12"><img src="/images/wechat/w_reply.png" height="15" class="mr5 mt3" /><span style="vertical-align:top;">回复</span></a>
<a ng-if="act.reply_count" ng-click="goDetail('course_discussion',act.act_id, act.id)" class="c-grey2 fr f12"><img src="/images/wechat/w_reply.png" height="15" class="mr5 mt3" /><span style="vertical-align:top;">{{act.reply_count}}</span></a>
<div class="c-grey fr f12 mr25" ng-if="!act.praise_count" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" height="15" class="mr5 mt3" /><span class="num-block"></span></div>
<div class="c-grey fr f12 mr25" ng-if="act.praise_count && !act.has_praise" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" height="15" class="mr5 mt3" /><span class="num-block">{{act.praise_count}}</span></div>
<div class="c-grey fr f12 mr25" ng-if="act.has_praise" ng-click="decreasePraise(act);"><img src="/images/wechat/w_praised.png" height="15" class="mr5 mt3" /><span class="num-block">{{act.praise_count}}</span></div>
<div class="cl"></div>
</div>
</div>
</div>
</div>
@ -127,21 +133,23 @@
<div class="cl"></div>
<div class="post-title hidden mt5 mb5"><span class="c-grey3 f15 fb">{{act.subject|safeHtml}}</span></div>
<div class="post-content c-grey3">
<div class="post-all-content mb5" ng-bind-html="act.description|safeHtml"></div>
<div class="post-all-content" ng-bind-html="act.description|safeHtml"></div>
<span class="mr15 f13 c-grey2">状态:{{act.issue_detail.issue_status}}</span> <span class="mr15 f13 c-grey2">优先级:{{act.issue_detail.issue_priority}}</span> <br />
<span class="mr15 f13 c-grey2">指派给:{{act.issue_detail.issue_assigned_to}}</span> <span class="mr15 f13 c-grey2">完成度:{{act.issue_detail.done_ratio}}%</span>
</div>
<!--<a herf="javascript:void(0);" class="c-grey2 f13 fr mt5 mb10 post-more mr20 undis" text-auto-height>点击展开</a>-->
<div class="cl"></div>
</div>
<span class="c-grey f12 fl mr15 mt2">{{act.activity_type_name}}</span>
<span class="c-grey f13 fl mt2">{{act.latest_update}}</span>
<a ng-if="!act.reply_count" ng-click="goDetail('issues',act.act_id, act.id)" class="c-grey2 fr f12"><img src="/images/wechat/w_reply.png" height="15" class="mr5" /><span style="vertical-align:top;">回复</span></a>
<a ng-if="act.reply_count" ng-click="goDetail('issues',act.act_id, act.id)" class="c-grey2 fr f12"><img src="/images/wechat/w_reply.png" height="15" class="mr5" /><span style="vertical-align:top;">{{act.reply_count}}</span></a>
<div class="c-grey fr f12 mr25" ng-if="!act.praise_count" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" height="15" class="mr5" /><span style="vertical-align:top;"></span></div>
<div class="c-grey fr f12 mr25" ng-if="act.praise_count && !act.has_praise" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" height="15" class="mr5" /><span style="vertical-align:top;">{{act.praise_count}}</span></div>
<div class="c-grey fr f12 mr25" ng-if="act.has_praise" ng-click="decreasePraise(act);"><img src="/images/wechat/w_praised.png" height="15" class="mr5" /><span style="vertical-align:top;">{{act.praise_count}}</span></div>
<div class="cl"></div>
<div class="post-op-banner">
<span class="c-grey f12 fl mr15">{{act.activity_type_name}}</span>
<span class="c-grey f12 fl">{{act.latest_update}}</span>
<a ng-if="!act.reply_count" ng-click="goDetail('issues',act.act_id, act.id)" class="c-grey2 fr f12"><img src="/images/wechat/w_reply.png" height="15" class="mr5 mt3" /><span style="vertical-align:top;">回复</span></a>
<a ng-if="act.reply_count" ng-click="goDetail('issues',act.act_id, act.id)" class="c-grey2 fr f12"><img src="/images/wechat/w_reply.png" height="15" class="mr5 mt3" /><span style="vertical-align:top;">{{act.reply_count}}</span></a>
<div class="c-grey fr f12 mr25" ng-if="!act.praise_count" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" height="15" class="mr5 mt3" /><span class="num-block"></span></div>
<div class="c-grey fr f12 mr25" ng-if="act.praise_count && !act.has_praise" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" height="15" class="mr5 mt3" /><span class="num-block">{{act.praise_count}}</span></div>
<div class="c-grey fr f12 mr25" ng-if="act.has_praise" ng-click="decreasePraise(act);"><img src="/images/wechat/w_praised.png" height="15" class="mr5 mt3" /><span class="num-block">{{act.praise_count}}</span></div>
<div class="cl"></div>
</div>
</div>
</div>
</div>
@ -164,14 +172,16 @@
<!--<a herf="javascript:void(0);" class="c-grey2 f13 fr mt5 mb10 post-more mr20 undis" text-auto-height>点击展开</a>-->
<div class="cl"></div>
</div>
<span class="c-grey f12 fl mr15 mt2">{{act.activity_type_name}}</span>
<span class="c-grey f13 fl mt2">{{act.latest_update}}</span>
<a ng-if="!act.reply_count" ng-click="goDetail('project_discussion',act.act_id, act.id)" class="c-grey2 fr f12"><img src="/images/wechat/w_reply.png" height="15" class="mr5" /><span style="vertical-align:top;">回复</span></a>
<a ng-if="act.reply_count" ng-click="goDetail('project_discussion',act.act_id, act.id)" class="c-grey2 fr f12"><img src="/images/wechat/w_reply.png" height="15" class="mr5" /><span style="vertical-align:top;">{{act.reply_count}}</span></a>
<div class="c-grey fr f12 mr25" ng-if="!act.praise_count" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" height="15" class="mr5" /><span style="vertical-align:top;"></span></div>
<div class="c-grey fr f12 mr25" ng-if="act.praise_count && !act.has_praise" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" height="15" class="mr5" /><span style="vertical-align:top;">{{act.praise_count}}</span></div>
<div class="c-grey fr f12 mr25" ng-if="act.has_praise" ng-click="decreasePraise(act);"><img src="/images/wechat/w_praised.png" height="15" class="mr5" /><span style="vertical-align:top;">{{act.praise_count}}</span></div>
<div class="cl"></div>
<div class="post-op-banner">
<span class="c-grey f12 fl mr15">{{act.activity_type_name}}</span>
<span class="c-grey f12 fl">{{act.latest_update}}</span>
<a ng-if="!act.reply_count" ng-click="goDetail('project_discussion',act.act_id, act.id)" class="c-grey2 fr f12"><img src="/images/wechat/w_reply.png" height="15" class="mr5 mt3" /><span style="vertical-align:top;">回复</span></a>
<a ng-if="act.reply_count" ng-click="goDetail('project_discussion',act.act_id, act.id)" class="c-grey2 fr f12"><img src="/images/wechat/w_reply.png" height="15" class="mr5 mt3" /><span style="vertical-align:top;">{{act.reply_count}}</span></a>
<div class="c-grey fr f12 mr25" ng-if="!act.praise_count" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" height="15" class="mr5 mt3" /><span class="num-block"></span></div>
<div class="c-grey fr f12 mr25" ng-if="act.praise_count && !act.has_praise" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" height="15" class="mr5 mt3" /><span class="num-block">{{act.praise_count}}</span></div>
<div class="c-grey fr f12 mr25" ng-if="act.has_praise" ng-click="decreasePraise(act);"><img src="/images/wechat/w_praised.png" height="15" class="mr5 mt3" /><span class="num-block">{{act.praise_count}}</span></div>
<div class="cl"></div>
</div>
</div>
</div>
</div>
@ -208,13 +218,15 @@
<!--<a herf="javascript:void(0);" class="c-grey2 f13 fr mt5 mb10 post-more mr20 undis" text-auto-height>点击展开</a>-->
<div class="cl"></div>
</div>
<span class="c-grey f13 fl mt2">{{act.latest_update}}</span>
<a ng-if="!act.reply_count" ng-click="goDetail('journal_for_message',act.act_id, act.id)" class="c-grey2 fr f12"><img src="/images/wechat/w_reply.png" height="15" class="mr5" /><span style="vertical-align:top;">回复</span></a>
<a ng-if="act.reply_count" ng-click="goDetail('journal_for_message',act.act_id, act.id)" class="c-grey2 fr f12"><img src="/images/wechat/w_reply.png" height="15" class="mr5" /><span style="vertical-align:top;">{{act.reply_count}}</span></a>
<div class="c-grey fr f12 mr25" ng-if="!act.praise_count" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" height="15" class="mr5" /><span style="vertical-align:top;"></span></div>
<div class="c-grey fr f12 mr25" ng-if="act.praise_count && !act.has_praise" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" height="15" class="mr5" /><span style="vertical-align:top;">{{act.praise_count}}</span></div>
<div class="c-grey fr f12 mr25" ng-if="act.has_praise" ng-click="decreasePraise(act);"><img src="/images/wechat/w_praised.png" height="15" class="mr5" /><span style="vertical-align:top;">{{act.praise_count}}</span></div>
<div class="cl"></div>
<div class="post-op-banner">
<span class="c-grey f12 fl">{{act.latest_update}}</span>
<a ng-if="!act.reply_count" ng-click="goDetail('journal_for_message',act.act_id, act.id)" class="c-grey2 fr f12"><img src="/images/wechat/w_reply.png" height="15" class="mr5 mt3" /><span style="vertical-align:top;">回复</span></a>
<a ng-if="act.reply_count" ng-click="goDetail('journal_for_message',act.act_id, act.id)" class="c-grey2 fr f12"><img src="/images/wechat/w_reply.png" height="15" class="mr5 mt3" /><span style="vertical-align:top;">{{act.reply_count}}</span></a>
<div class="c-grey fr f12 mr25" ng-if="!act.praise_count" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" height="15" class="mr5 mt3" /><span class="num-block"></span></div>
<div class="c-grey fr f12 mr25" ng-if="act.praise_count && !act.has_praise" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" height="15" class="mr5 mt3" /><span class="num-block">{{act.praise_count}}</span></div>
<div class="c-grey fr f12 mr25" ng-if="act.has_praise" ng-click="decreasePraise(act);"><img src="/images/wechat/w_praised.png" height="15" class="mr5 mt3" /><span class="num-block">{{act.praise_count}}</span></div>
<div class="cl"></div>
</div>
</div>
</div>
</div>
@ -237,13 +249,15 @@
<!--<a herf="javascript:void(0);" class="c-grey2 f13 fr mt5 mb10 post-more mr20 undis" text-auto-height>点击展开</a>-->
<div class="cl"></div>
</div>
<span class="c-grey f13 fl mt2">{{act.latest_update}}</span>
<a ng-if="!act.reply_count" ng-click="goDetail('blog_comment',act.act_id, act.id)" class="c-grey2 fr f12"><img src="/images/wechat/w_reply.png" height="15" class="mr5" /><span style="vertical-align:top;">回复</span></a>
<a ng-if="act.reply_count" ng-click="goDetail('blog_comment',act.act_id, act.id)" class="c-grey2 fr f12"><img src="/images/wechat/w_reply.png" height="15" class="mr5" /><span style="vertical-align:top;">{{act.reply_count}}</span></a>
<div class="c-grey fr f12 mr25" ng-if="!act.praise_count" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" height="15" class="mr5" /><span style="vertical-align:top;"></span></div>
<div class="c-grey fr f12 mr25" ng-if="act.praise_count && !act.has_praise" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" height="15" class="mr5" /><span style="vertical-align:top;">{{act.praise_count}}</span></div>
<div class="c-grey fr f12 mr25" ng-if="act.has_praise" ng-click="decreasePraise(act);"><img src="/images/wechat/w_praised.png" height="15" class="mr5" /><span style="vertical-align:top;">{{act.praise_count}}</span></div>
<div class="cl"></div>
<div class="post-op-banner">
<span class="c-grey f12 fl">{{act.latest_update}}</span>
<a ng-if="!act.reply_count" ng-click="goDetail('blog_comment',act.act_id, act.id)" class="c-grey2 fr f12"><img src="/images/wechat/w_reply.png" height="15" class="mr5 mt3" /><span style="vertical-align:top;">回复</span></a>
<a ng-if="act.reply_count" ng-click="goDetail('blog_comment',act.act_id, act.id)" class="c-grey2 fr f12"><img src="/images/wechat/w_reply.png" height="15" class="mr5 mt3" /><span style="vertical-align:top;">{{act.reply_count}}</span></a>
<div class="c-grey fr f12 mr25" ng-if="!act.praise_count" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" height="15" class="mr5 mt3" /><span class="num-block"></span></div>
<div class="c-grey fr f12 mr25" ng-if="act.praise_count && !act.has_praise" ng-click="addPraise(act);"><img src="/images/wechat/w_praise.png" height="15" class="mr5 mt3" /><span class="num-block">{{act.praise_count}}</span></div>
<div class="c-grey fr f12 mr25" ng-if="act.has_praise" ng-click="decreasePraise(act);"><img src="/images/wechat/w_praised.png" height="15" class="mr5 mt3" /><span class="num-block">{{act.praise_count}}</span></div>
<div class="cl"></div>
</div>
</div>
</div>
</div>
@ -254,6 +268,7 @@
<div ng-if="has_more">
<div id="more_activities" class="more-events mt10" ng-click="loadActData(page+1);">更多</div>
</div>
<my-alert message="alertService.message" title="alertService.title" visible="alertService.visible"></my-alert>
</div>

View File

@ -0,0 +1,13 @@
<div class="post-container">
<div class="add-class-box">
<p class="tac add-class-tip">输入班级邀请码,即刻加入班级!</p>
<form class="mb20">
<input type="text" class="class-number-input" />
</form>
<a href="javascript:void(0);" class="c-grey4 fl cancel-btn">取消</a>
<div class="slice fl">
<div class="slice-line"></div>
</div>
<a href="javascript:void(0);" class="c-blue fl submit-btn">确定</a>
</div>
</div>

View File

@ -2,7 +2,7 @@
<html ng-app="wechat">
<head>
<base href="/">
<title>我的动态</title>
<title>仅供本地调试使用</title>
<meta charset='utf-8' />
<meta name="keywords" content="" />
<meta name="description" content="" />
@ -10,6 +10,7 @@
<meta content='True' name='HandheldFriendly' />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
<link type="text/css" rel="stylesheet" href="/stylesheets/weui/weui.min.css" />
<link type="text/css" rel="stylesheet" href="/stylesheets/weui/weixin.css" />
</head>
@ -17,8 +18,38 @@
<div ng-view>
</div>
<script type="text/javascript">
window.g_openid = 'oCnvgvz8R7QheXE-R9Kkr39j8Ndg';
window.g_debug = true; //调试标志,如果在本地请置为true
window.apiUrl = 'http://localhost:3000/api/v1/';
</script>
<script src="/javascripts/wechat/build/angular.all.min.js"></script>
<!--<script src="/javascripts/wechat/build/app.min.js"></script>-->
<script src="/javascripts/wechat/app.js"></script>
<script src="/javascripts/wechat/others/factory.js"></script>
<script src="/javascripts/wechat/others/filter.js"></script>
<script src="/javascripts/wechat/directives/alert.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/loading_spinner.js"></script>
<script src="/javascripts/wechat/controllers/reg.js"></script>
<script src="/javascripts/wechat/controllers/login.js"></script>
<script src="/javascripts/wechat/controllers/activity.js"></script>
<script src="/javascripts/wechat/controllers/add_class.js"></script>
<script src="/javascripts/wechat/controllers/blog.js"></script>
<script src="/javascripts/wechat/controllers/course_notice.js"></script>
<script src="/javascripts/wechat/controllers/discussion.js"></script>
<script src="/javascripts/wechat/controllers/homework.js"></script>
<script src="/javascripts/wechat/controllers/issue.js"></script>
<script src="/javascripts/wechat/controllers/journals.js"></script>
<script src="/javascripts/wechat/others/routes.js"></script>
</body>
</html>

View File

@ -39,7 +39,7 @@
<textarea class="copy-input"></textarea>
<textarea input-auto type="text" class="post-reply-input" id="postInput" ng-model="formData.comment" /></textarea>
</div>
<button ng-click="addBlogReply(formData)" ng-disabled="formData.disabled" ng-hide="formData.disabled" class="post-reply-submit fr mt10">回复</button>
<button ng-click="addReply(formData)" ng-disabled="formData.disabled" ng-hide="formData.disabled" class="post-reply-submit fr mt10">回复</button>
<button ng-disabled="formData.disabled" ng-hide="!formData.disabled" class="post-reply-submit bg-grey fr mt10">回复</button>
<div class="cl"></div>
</div>

View File

@ -15,7 +15,7 @@
<td class="text-nowrap v-top">&nbsp;&nbsp;&nbsp;源:</td>
<td>{{discussion.course_project_name}}&nbsp;&nbsp;|&nbsp;&nbsp;课程问答区</td>
</tr></table>
<div class="f13 c-grey3 mt10 text-control" ng-bind-html="discussion.content|safeHtml"></div>
<div class="f13 c-grey3 mt10 text-control post-all-content" ng-bind-html="discussion.content|safeHtml"></div>
<div class="cl"></div>
<span class="c-grey f13 mt10 fl">{{discussion.created_on}}</span>
<div class="cl"></div>
@ -46,7 +46,7 @@
<textarea class="copy-input"></textarea>
<textarea input-auto type="text" class="post-reply-input" id="postInput" ng-model="formData.comment" /></textarea>
</div>
<button ng-click="addDiscussionReply(formData)" ng-disabled="formData.disabled" ng-hide="formData.disabled" class="post-reply-submit fr mt10">回复</button>
<button ng-click="addReply(formData)" ng-disabled="formData.disabled" ng-hide="formData.disabled" class="post-reply-submit fr mt10">回复</button>
<button ng-disabled="formData.disabled" ng-hide="!formData.disabled" class="post-reply-submit bg-grey fr mt10">回复</button>
<div class="cl"></div>
</div>

View File

@ -14,7 +14,7 @@
<td class="text-nowrap v-top">&nbsp;&nbsp;&nbsp;源:</td>
<td>{{news.course_name}}&nbsp;&nbsp;|&nbsp;&nbsp;课程通知</td>
</tr></table>
<div class="f13 c-grey3 mt10 text-control" ng-bind-html="news.description|safeHtml"></div>
<div class="f13 c-grey3 mt10 text-control post-all-content" ng-bind-html="news.description|safeHtml"></div>
<div class="cl"></div>
<span class="c-grey f13 mt10 fl">{{news.created_on}}</span>
<div class="cl"></div>
@ -45,7 +45,7 @@
<textarea class="copy-input"></textarea>
<textarea input-auto type="text" class="post-reply-input" id="postInput" ng-model="formData.comment" /></textarea>
</div>
<button ng-click="addNoticeReply(formData)" ng-disabled="formData.disabled" ng-hide="formData.disabled" class="post-reply-submit fr mt10">回复</button>
<button ng-click="addReply(formData)" ng-disabled="formData.disabled" ng-hide="formData.disabled" class="post-reply-submit fr mt10">回复</button>
<button ng-disabled="formData.disabled" ng-hide="!formData.disabled" class="post-reply-submit bg-grey fr mt10">回复</button>
<div class="cl"></div>
</div>

View File

@ -18,13 +18,13 @@
</tr>
<tr>
<td class="text-nowrap v-top">&nbsp;&nbsp;&nbsp;别:</td>
<td><span ng-if="homework.homework_type == 1" class="c-grey f12 fl mr15 mt2">普通作业</span>
<span ng-if="homework.homework_type == 2" class="c-grey f12 fl mr15 mt2">编程作业</span>
<span ng-if="homework.homework_type == 3" class="c-grey f12 fl mr15 mt2">分组作业</span>
<td><span ng-if="homework.homework_type == 1">普通作业</span>
<span ng-if="homework.homework_type == 2">编程作业</span>
<span ng-if="homework.homework_type == 3">分组作业</span>
</td>
</tr>
</table>
<div class="f13 c-grey3 mt10 mb10 text-control" ng-bind-html="homework.description|safeHtml"></div>
<div class="f13 c-grey3 mt10 mb10 text-control post-all-content" ng-bind-html="homework.description|safeHtml"></div>
<span class="c-grey f13">迟交扣分:{{homework.late_penalty}}分</span><br/>
<span ng-if="!homework.anonymous_comment" class="c-grey f13">缺评扣分:{{homework.absence_penalty}}分/作品<br /></span>
<span ng-if="!homework.anonymous_comment" class="c-grey f13">匿评开启时间:{{homework.evaluation_start}}<br /></span>
@ -59,7 +59,7 @@
<textarea class="copy-input"></textarea>
<textarea input-auto type="text" class="post-reply-input" id="postInput" ng-model="formData.comment"></textarea>
</div>
<button ng-click="addHomeworkReply(formData)" ng-disabled="formData.disabled" ng-hide="formData.disabled" class="post-reply-submit fr mt10">回复</button>
<button ng-click="addReply(formData)" ng-disabled="formData.disabled" ng-hide="formData.disabled" class="post-reply-submit fr mt10">回复</button>
<button ng-disabled="formData.disabled" ng-hide="!formData.disabled" class="post-reply-submit bg-grey fr mt10">回复</button>
<div class="cl"></div>
</div>

View File

@ -0,0 +1,15 @@
<div class="post-container">
<div class="qr-code-wrap">
<div class="qr-code-box">
<div class="share-class-name">{{course.name}}</div>
<div class="qr-img-wrap"><img ng-src="https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket={{course.qrcode}}" width="152" class="qr-code-img" /></div>
<div class="invitation-code-wrap">邀请码:{{course.invite_code}}</div>
</div>
</div>
<div class="share-code-wrap">
<a ng-click="share()" href="javascript:void(0);" class="share-code-btn">分享邀请码</a>
<div class="share-code-instruction"> 1.将此页面分享给好友,邀请好友加入班级<br />
2.通过微信扫一扫加入班级<br />
3.输入邀请码加入班级</div>
</div>
</div>

View File

@ -1,50 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>react js</title>
<meta charset='utf-8' />
<meta name="keywords" content="" />
<meta name="description" content="" />
<meta name="apple-mobile-web-app-capable" content="no">
<meta content='True' name='HandheldFriendly' />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
<link type="text/css" rel="stylesheet" href="/stylesheets/weui/weixin.css" />
</head>
<body>
<div id="container"></div>
<!-- 模板1开始可以使用scripttype设置为text/html来存放模板片段并且用id标示 -->
<script id="t:result-list" type="text/html">
<! for(var i =0; i < issues.length; ++i){ !>
<div class="post-container">
<div class="post-wrapper">
<div class="post-main">
<div class="post-avatar fl"><img src="<!=issues[i].author.img_url!>" width="45" height="45" class="border-radius" /></div>
<div class="post-title hidden mb5"><span class="c-grey3 f15 fb"><!=issues[i].subject!></span></div>
<div class="post-title hidden"><a herf="javascript:void(0);" class="mr10"><!=issues[i].author.nickname!></a>项目问题</div>
<div class="cl"></div>
<div class="post-content c-grey2 mt10">
<div class="post-all-content"><!=issues[i].description!></div>
</div>
<a herf="javascript:void(0);" class="link-blue f13 fl mt5 post-more " style="text-decoration:underline">点击展开</a>
<div class="cl"></div>
<span class="c-grey f13 mt10 fl"><!=issues[i].created_on!></span>
<div class="cl"></div>
</div>
</div>
</div>
<! } !>
</script>
<script src="/javascripts/jquery-1.3.2.js"></script>
<script src="/javascripts/baiduTemplate.js"></script>
<script src="/javascripts/wechat/auth.js"></script>
<script src="/javascripts/wechat/wechat-dev.js"></script>
</body>
</html>

View File

@ -14,7 +14,7 @@
<td class="text-nowrap v-top">&nbsp;&nbsp;&nbsp;源:</td>
<td>{{issue.project_name}}&nbsp;&nbsp;|&nbsp;&nbsp;项目问题</td>
</tr></table>
<div class="f13 c-grey3 mt10 mb10 text-control" ng-bind-html="issue.description|safeHtml"></div>
<div class="f13 c-grey3 mt10 mb10 text-control post-all-content" ng-bind-html="issue.description|safeHtml"></div>
<span class="c-grey f13">&nbsp;&nbsp;&nbsp;态:{{issue.issue_status}}<br>
优先级:{{issue.issue_priority}}<br />
指派给:{{issue.issue_assigned_to}}<br />
@ -49,7 +49,7 @@
<textarea class="copy-input"></textarea>
<textarea input-auto type="text" class="post-reply-input" id="postInput" ng-model="formData.comment" /></textarea>
</div>
<button ng-click="addIssueReply(formData)" ng-disabled="formData.disabled" ng-hide="formData.disabled" class="post-reply-submit fr mt10">回复</button>
<button ng-click="addReply(formData)" ng-disabled="formData.disabled" ng-hide="formData.disabled" class="post-reply-submit fr mt10">回复</button>
<button ng-disabled="formData.disabled" ng-hide="!formData.disabled" class="post-reply-submit bg-grey fr mt10">回复</button>
<div class="cl"></div>
</div>

View File

@ -37,7 +37,7 @@
<textarea class="copy-input"></textarea>
<textarea input-auto type="text" class="post-reply-input" id="postInput" ng-model="formData.comment" /></textarea>
</div>
<button ng-click="addJournalReply(formData)" ng-hide="formData.disabled" ng-disabled="formData.disabled" class="post-reply-submit fr mt10">回复</button>
<button ng-click="addReply(formData)" ng-hide="formData.disabled" ng-disabled="formData.disabled" class="post-reply-submit fr mt10">回复</button>
<button ng-disabled="formData.disabled" ng-hide="!formData.disabled" class="post-reply-submit bg-grey fr mt10">回复</button>
<div class="cl"></div>
</div>

View File

@ -0,0 +1,25 @@
<div class="post-container">
<div loading-spinner></div>
<form name="loginFrm" novalidate>
<div class="blue-title">绑定<span class="f13 blue-title-sub" ng-click="goReg()">注册</span></div>
<div class="input-box-wrap login-wrap mt30">
<input name="login" ng-model="user.login" required class="input-box f12" placeholder="请输入电子邮箱地址或登录名" />
<div ng-show="loginFrm.$submitted || loginFrm.login.$touched">
<span ng-show="loginFrm.login.$error.required" class="c-red fl f12">电子邮箱地址或登录名不能为空</span>
</div>
</div>
<div class="input-box-wrap login-wrap mt10 mb20">
<input class="input-box f12" placeholder="请输入密码" name="password" type="password" ng-model="user.password" required />
<div ng-show="loginFrm.$submitted || loginFrm.password.$touched">
<span ng-show="loginFrm.password.$error.required" class="c-red fl f12">密码不能为空</span>
</div>
</div>
<div class="login-wrap mt5"><a href="javascript:void(0);" ng-class="['btn1', 'bg-blue', 'f18', {'btn-disabled':!loginFrm.$valid} ]" ng-click="login(loginFrm, user)">确定绑定</a></div>
<div class="forget-psw-wrap"><a href="javascript:void(0);" class="f12 forget-psw" ng-click="showBox()">忘记密码?</a></div>
<my-alert message="findPwdDialog.message" title="findPwdDialog.title" visible="findPwdDialog.visible"></my-alert>
</form>
</div>
<my-alert message="alertService.message" title="alertService.title" visible="alertService.visible" cb="alertService.cb"></my-alert>

View File

@ -0,0 +1,32 @@
<div class="post-container">
<div loading-spinner></div>
<div class="class-detail-name">{{course.name}}<span ng-click="invite()" class="f13 blue-title-sub">邀请码</span></div>
<div class="slice3 fl"></div>
<div id="class_tab_1" ng-class="['class-detail-tab3',{'class-tab-active':currentTab==1}]" ng-click="tab(1);"><a herf="javascript:void(0);">课堂资源</a></div>
<div class="slice2 fl">
<div class="slice-line2"></div>
</div>
<div id="class_tab_2" ng-class="['class-detail-tab3',{'class-tab-active':currentTab==2}]" ng-click="tab(2);"><a herf="javascript:void(0);">我的同学</a></div>
<div class="slice3 fl"></div>
<div class="cl"></div>
<div class="class-search-wrap">
<div class="class-search-inner"> <img src="/images/wechat/search.png" width="18" class="class-search-icon" />
<input class="class-detail-search" ng-model="searchText" placeholder="输入关键词进行搜索" />
</div>
</div>
<div ng-class="{'undis': currentTab!=1}">
<div ng-repeat="r in resources|filter:searchText" ng-class="['class-detail-row', 'f13', 'c-grey3', {'border-top': $first}]"><span class="fl ml10">{{r.filename}}</span></div>
</div>
<div ng-class="{'undis': currentTab!=2}">
<div class="member-banner f13 c-grey3">授课老师</div>
<div class="class-detail-row f13 c-grey3" ng-repeat="teacher in teachers|filter:searchText">
<img ng-src="/images/wechat/{{teacher.gender==0 ? 'male' : 'female'}}.jpg" width="30" class="fl ml10 img-circle mt4" /><span class="fl ml10">{{teacher.name}}</span><span class="fr mr10 c-grey2">{{teacher.role_name|identify}}</span><img ng-src="/images/wechat/{{teacher.gender==0 ? 'male' : 'female'}}.png" width="15" class="fl ml10 mt10" />
</div>
<div class="member-banner f13 mt10 c-grey3">我的同学</div>
<div class="class-detail-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 mt4" /><span class="fl ml10">{{student.name}}</span><img ng-src="/images/wechat/{{student.gender==0 ? 'male' : 'female'}}.png" width="15" class="fl ml10 mt10" />
</div>
</div>
</div>

View File

@ -14,7 +14,7 @@
<td class="text-nowrap v-top">&nbsp;&nbsp;&nbsp;源:</td>
<td>{{discussion.course_project_name}}&nbsp;&nbsp;|&nbsp;&nbsp;项目讨论区</td>
</tr></table>
<div class="f13 c-grey3 mt10 text-control" ng-bind-html="discussion.content|safeHtml"></div>
<div class="f13 c-grey3 mt10 text-control post-all-content" ng-bind-html="discussion.content|safeHtml"></div>
<div class="cl"></div>
<span class="c-grey f13 mt10 fl">{{discussion.created_on}}</span>
<div class="cl"></div>
@ -45,7 +45,7 @@
<textarea class="copy-input"></textarea>
<textarea input-auto type="text" class="post-reply-input" id="postInput" ng-model="formData.comment" /></textarea>
</div>
<button ng-click="addDiscussionReply(formData)" ng-disabled="formData.disabled" ng-hide="formData.disabled" class="post-reply-submit fr mt10">回复</button>
<button ng-click="addReply(formData)" ng-disabled="formData.disabled" ng-hide="formData.disabled" class="post-reply-submit fr mt10">回复</button>
<button ng-disabled="formData.disabled" ng-hide="!formData.disabled" class="post-reply-submit bg-grey fr mt10">回复</button>
<div class="cl"></div>
</div>

View File

@ -0,0 +1,43 @@
<div class="post-container">
<form name="regFrm" novalidate>
<div class="blue-title">注册<span class="f13 blue-title-sub" ng-click="goLogin()">登录</span></div>
<img src="/images/wechat/male.jpg" width="60" class="img-circle mt15 block-center"/>
<div class="input-box-wrap login-wrap mt10 mb20">
<input class="input-box f12" type="email" ng-model="user.email" name="email" required placeholder="请输入电子邮箱地址"/>
<div ng-show="regFrm.$submitted || regFrm.email.$touched">
<span class="f12 c-red fl" ng-show="regFrm.email.$error.required">电子邮箱地址不能为空</span>
<span class="f12 c-red fl" ng-show="regFrm.email.$error.email">电子邮箱地址不合法</span>
</div>
</div>
<div class="input-box-wrap login-wrap mb20">
<input class="input-box f12" type="password" ng-model="user.password" name="password" ng-maxlength="20" ng-minlength="8" required placeholder="请输入密码"/>
<div ng-show="regFrm.$submitted || regFrm.password.$touched">
<span class="f12 c-red fl" ng-show="regFrm.password.$error.required">密码不能为空</span>
<span class="f12 c-red fl" ng-show="regFrm.password.$error.minlength">密码长度为8-20位</span>
<span class="f12 c-red fl" ng-show="regFrm.password.$error.maxlength">密码长度为8-20位</span>
</div>
</div>
<div class="input-box-wrap login-wrap mb20">
<input class="input-box f12" type="password" ng-model="user.password_confirm" name="password_confirm" required placeholder="请再次输入密码" pwdconfirm/>
<div ng-show="regFrm.$submitted || regFrm.password_confirm.$touched">
<span class="f12 c-red fl" ng-show="regFrm.password_confirm.$error.pwdconfirm">两次密码不一致</span>
</div>
</div>
<div class="input-box-wrap login-wrap mb20">
<input class="input-box f12" required ng-model="user.username" name="username" placeholder="输入用户登录名"/>
<div ng-show="regFrm.$submitted || regFrm.username.$touched">
<span class="f12 c-red fl" ng-show="regFrm.username.$error.required">用户名不能为空</span>
</div>
</div>
<div class="login-op-wrap login-wrap f12 c-grey3">
<span ng-class="['login-box', 'mr5',{'checked': isagreed}]"
ng-click="agreed(isagreed)"></span>我已阅读并接受<a
href="javascript:void(0);" class="link-blue2">Trustie服务协议</a>条款
</div>
<div class="login-wrap mt5"><a href="javascript:void(0);" ng-class="['btn1', 'bg-blue', 'f18', {'btn-disabled':!regFrm.$valid} ]" ng-click="reg(regFrm, user)">确定注册</a></div>
</form>
</div>
<my-alert message="errDialog.message" title="errDialog.title" visible="errDialog.visible"></my-alert>

View File

@ -0,0 +1,12 @@
<!--BEGIN dialog2-->
<div class="weui_dialog_alert" id="dialog2" ng-show="visible">
<div class="weui_mask"></div>
<div class="weui_dialog">
<div class="weui_dialog_hd"><strong class="weui_dialog_title">{{title}}</strong></div>
<div class="weui_dialog_bd"><span class="weui_dialog_info">{{message}}</span></div>
<div class="weui_dialog_ft">
<a href="javascript:;" class="weui_btn_dialog primary" ng-click="dismiss()">确定</a>
</div>
</div>
</div>
<!--END dialog2-->

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -1,108 +0,0 @@
/**
* Created by guange on 16/3/19.
*/
var CommentBox = React.createClass({
loadFromServer: function(){
$.ajax({
url: this.props.url,
dataType: 'json',
success: function(data){
this.setState({data: data});
}.bind(this),
error: function(xhr,status,err){
console.error(this.props.url, status, err.toString());
}.bind(this)
});
},
onCommentSubmit: function(comment){
console.log(comment);
},
getInitialState: function(){
return {data: []};
},
componentDidMount: function(){
this.loadFromServer();
setInterval(this.loadFromServer, 2000);
},
render: function(){
return(
<div className="commentBox">
<CommentForm onCommentSubmit={this.onCommentSubmit}/>
<CommentList data={this.state.data}/>
</div>
);
}
});
var CommentList = React.createClass({
render: function(){
var commentNodes = this.props.data.map(function(comment){
return (
<Comment author={comment.author}>
{comment.text}
</Comment>
)
});
return (
<div className="commentList">
{commentNodes}
</div>
);
}
});
var CommentForm = React.createClass({
handleSubmit: function(e){
e.preventDefault();
var author = this.refs.author.value.trim();
var text = this.refs.text.value.trim();
if(!text || !author){
return;
}
this.props.onCommentSubmit({author: author, text: text});
this.refs.author.value = '';
this.refs.text.value = '';
return;
},
render: function(){
return (
<form className="commentForm" onSubmit={this.handleSubmit}>
<input type="text" placeholder="Your name" ref="author" />
<input type="text" placeholder="Say something..." ref="text" />
<input type="submit" value="Post" />
</form>
);
}
});
var Comment = React.createClass({
rawMarkup: function() {
var rawMarkup = marked(this.props.children.toString(), {sanitize: true});
return { __html: rawMarkup };
},
render: function(){
return (
<div className="comment">
<h2 className="commentAuthor">
{this.props.author}
</h2>
<span dangerouslySetInnerHTML={this.rawMarkup()}></span>
</div>
)
}
})
React.render(<CommentBox url="api/comment.json"/>, document.getElementById("example"));

View File

@ -1,546 +1,29 @@
var app = angular.module('wechat', ['ngRoute']);
var apiUrl = '/api/v1/';
var debug = false; //调试标志,如果在本地请置为true
if(debug===true){
//apiUrl = 'http://localhost:3000/api/v1/';
apiUrl = 'http://www.trustie.net/api/v1/';
app.constant('config', {
rootPath: '/assets/wechat/',
rootUrl: '/',
apiUrl: '/api/v1/'
});
app.run(['$rootScope', 'auth', '$location', '$routeParams', function($rootScope, auth, $location, $routeParams){
if(g_redirect_path && g_redirect_path.length>1){
$location.path(g_redirect_path);
g_redirect_path = null;
}
$rootScope.$on('$routeChangeError', function(event, next, current){
if(next && next.templateUrl){
if(!next.templateUrl.endsWith("login.html") && !next.templateUrl.endsWith("reg.html")){
$location.path("/login");
}
}
});
$rootScope.$on('$routeChangeStart', function(event, next, current){
});
}
app.factory('auth', function($http,$routeParams, $q){
var _openid = '';
if(typeof g_openid !== 'undefined'){
_openid = g_openid;
}
if(debug===true){
_openid = "orgVLv8TlS6e7FDiI6xdTGHRaaRo"; //guange的帐号
}
var getOpenId = function() {
var deferred = $q.defer();
if (typeof _openid !== 'undefined' && _openid.length > 0){
deferred.resolve(_openid);
} else {
var code = $routeParams.code;
$http({
url: '/wechat/get_open_id',
data: {code: code},
method: 'POST'
}).then(function successCallback(response) {
_openid = response.data.openid;
deferred.resolve(_openid);
}, function errorCallback(response) {
deferred.reject(response);
});
}
return deferred.promise;
};
var openid = function(){
return _openid;
};
return {getOpenId: getOpenId, openid: openid};
});
app.factory('rms', function(){
var _saveStorage = {};
var save = function(key, value){
_saveStorage[key] = value;
};
var get = function(key){
return _saveStorage[key];
};
return {save: save, get: get};
});
app.controller('ActivityController',function($anchorScroll, $location,$scope, $http, $timeout, auth, rms, common){
$scope.replaceUrl = function(url){
return url;
};
console.log("ActivityController load");
$scope.page = rms.get('page') || 0;
$scope.activities = rms.get("activities") || [];
$scope.has_more = rms.get("has_more");
$scope.loadActData = function(page){
$scope.page = page;
$http({
method: 'POST',
url: apiUrl+ "activities",
data: {openid: auth.openid(), page: page}
}).then(function successCallback(response) {
if(response.data.page >0) {
$scope.activities = $scope.activities.concat(response.data.data);
} else {
$scope.activities = response.data.data;
}
rms.save("activities", $scope.activities);
$scope.has_more = (response.data.count + response.data.page * 10) < response.data.all_count;
rms.save('has_more', $scope.has_more);
rms.save('page', response.data.page);
console.log(response.data);
}, function errorCallback(response) {
});
};
if($scope.activities.length<=0){
auth.getOpenId().then(
function successCallback(response){
$scope.loadActData(0);
}, function errorCallback(response) {
alert("获取openid出错:"+response);
}
);
} else {
$timeout(function(){
window.scrollTo(0, rms.get("yoffset"));
});
}
//跳到详情页
$scope.goDetail = function(type, act_id,id){
rms.save("yoffset", window.document.body.scrollTop);
$location.path('/'+type+'/'+act_id);
}
$scope.addPraise = function(act){
common.addCommonPraise(act);
};
$scope.decreasePraise = function(act){
common.decreaseCommonPraise(act);
};
});
app.factory('common', function($http, auth, $routeParams){
var addCommonReply = function(id, type, data, cb){
if(!data.comment || data.comment.length<=0){
return;
}
var temp = data.comment.replace(/\n/g,'<br/>');
var userInfo = {
type: type,
content: temp,
openid: auth.openid()
};
//回复按钮禁用
data.disabled = true;
$http({
method: 'POST',
url: apiUrl+ "new_comment/"+id,
data: userInfo
}).then(function successCallback(response) {
//alert("提交成功");
//数据提交完成,回复按钮启用
data.disabled = false;
if(typeof cb === 'function'){
cb();
}
}, function errorCallback(response) {
});
};
var loadCommonData = function(id, type){
return $http({
method: 'GET',
url: apiUrl+ type + "/" + id+"?openid="+auth.openid()
})
};
var addCommonPraise = function(act){
act.praise_count += 1;
act.has_praise = true;
$http({
method: 'POST',
url: apiUrl + "praise/" + act.act_id,
data:{openid:auth.openid(),type:act.act_type}
}).then(function successCallback(response) {
console.log(response.data);
}, function errorCallback(response) {
});
};
var decreaseCommonPraise = function(act){
act.praise_count -= 1;
act.has_praise = false;
$http({
method: 'POST',
url: apiUrl + "praise/" + act.act_id,
data:{openid:auth.openid(),type:act.act_type}
}).then(function successCallback(response) {
console.log(response.data);
}, function errorCallback(response) {
});
};
return {addCommonReply: addCommonReply, loadCommonData: loadCommonData, addCommonPraise: addCommonPraise, decreaseCommonPraise: decreaseCommonPraise};
});
app.controller('IssueController', function($scope, $http, $routeParams, auth, common){
$scope.formData = {comment: ''};
var loadData = function(id){
common.loadCommonData(id, 'issues').then(function successCallback(response) {
console.log(response.data);
$scope.issue = response.data.data;
}, function errorCallback(response) {
});
};
auth.getOpenId().then(
function successCallback(response){
loadData($routeParams.id);
}, function errorCallback(response) {
alert("获取openid出错:"+response);
}
);
$scope.addIssueReply = function(data){
console.log(data.comment);
common.addCommonReply($routeParams.id, 'Issue', data, function(){
$scope.formData = {comment: ''};
loadData($routeParams.id);
});
};
$scope.addPraise = function(act){
common.addCommonPraise(act);
};
$scope.decreasePraise = function(act){
common.decreaseCommonPraise(act);
};
});
app.controller('HomeworkController', function($scope, $http, $routeParams, auth, common){
$scope.formData = {comment: ''};
var loadData = function(id){
common.loadCommonData(id, 'whomeworks').then(function successCallback(response) {
console.log(response.data);
$scope.homework = response.data.data;
}, function errorCallback(response) {
});
};
auth.getOpenId().then(
function successCallback(response){
loadData($routeParams.id);
}, function errorCallback(response) {
alert("获取openid出错:"+response);
}
);
$scope.addHomeworkReply = function(data){
console.log(data.comment);
common.addCommonReply($routeParams.id, 'HomeworkCommon', data, function(){
$scope.formData = {comment: ''};
loadData($routeParams.id);
});
};
$scope.addPraise = function(act){
common.addCommonPraise(act);
};
$scope.decreasePraise = function(act){
common.decreaseCommonPraise(act);
};
});
app.controller('CourseNoticeController', function($scope, $http, $routeParams, auth, common){
$scope.formData = {comment: ''};
var loadData = function(id){
common.loadCommonData(id, 'newss').then(function successCallback(response) {
console.log(response.data);
$scope.news = response.data.data;
}, function errorCallback(response) {
});
};
auth.getOpenId().then(
function successCallback(response){
loadData($routeParams.id);
}, function errorCallback(response) {
alert("获取openid出错:"+response);
}
);
$scope.addNoticeReply = function(data){
console.log(data.comment);
common.addCommonReply($routeParams.id, 'News', data, function(){
$scope.formData = {comment: ''};
loadData($routeParams.id);
});
};
$scope.addPraise = function(act){
common.addCommonPraise(act);
};
$scope.decreasePraise = function(act){
common.decreaseCommonPraise(act);
};
});
app.controller('DiscussionController', function($scope, $http, $routeParams, auth, common){
$scope.formData = {comment: ''};
var loadData = function(id){
common.loadCommonData(id, 'messages').then(function successCallback(response) {
console.log(response.data);
$scope.discussion = response.data.data;
}, function errorCallback(response) {
});
};
auth.getOpenId().then(
function successCallback(response){
loadData($routeParams.id);
}, function errorCallback(response) {
alert("获取openid出错:"+response);
}
);
$scope.addDiscussionReply = function(data){
console.log(data.comment);
common.addCommonReply($routeParams.id, 'Message', data, function(){
$scope.formData = {comment: ''};
loadData($routeParams.id);
});
};
$scope.addPraise = function(act){
common.addCommonPraise(act);
};
$scope.decreasePraise = function(act){
common.decreaseCommonPraise(act);
};
});
app.controller('JournalsController', function($scope, $http, $routeParams, auth, common){
$scope.formData = {comment: ''};
var loadData = function(id){
common.loadCommonData(id, 'journal_for_messages').then(function successCallback(response) {
console.log(response.data);
$scope.message = response.data.data;
}, function errorCallback(response) {
});
};
auth.getOpenId().then(
function successCallback(response){
loadData($routeParams.id);
}, function errorCallback(response) {
alert("获取openid出错:"+response);
}
);
$scope.addJournalReply = function(data){
console.log(data.comment);
common.addCommonReply($routeParams.id, 'JournalsForMessage', data, function(){
$scope.formData = {comment: ''};
loadData($routeParams.id);
});
};
$scope.addPraise = function(act){
console.log(act);
common.addCommonPraise(act);
};
$scope.decreasePraise = function(act){
console.log(act);
common.decreaseCommonPraise(act);
};
});
app.controller('BlogController', function($scope, $http, $routeParams, auth, common){
$scope.formData = {comment: ''};
var loadData = function(id){
common.loadCommonData(id, 'blog_comments').then(function successCallback(response) {
console.log(response.data);
$scope.blog = response.data.data;
}, function errorCallback(response) {
});
};
auth.getOpenId().then(
function successCallback(response){
loadData($routeParams.id);
}, function errorCallback(response) {
alert("获取openid出错:"+response);
}
);
$scope.addBlogReply = function(data){
console.log(data.comment);
common.addCommonReply($routeParams.id, 'BlogComment', data, function(){
$scope.formData = {comment: ''};
loadData($routeParams.id);
});
};
$scope.addPraise = function(act){
console.log(act);
common.addCommonPraise(act);
};
$scope.decreasePraise = function(act){
console.log(act);
common.decreaseCommonPraise(act);
};
});
app.filter('safeHtml', function ($sce) {
return function (input) {
return $sce.trustAsHtml(input);
}
});
//app.directive('textAutoHeight', function($timeout){
// return {
// restrict: 'A',
// scope: {},
// link: function(scope, element, attr){
// scope.text = '点击展开';
// $timeout(function(){
// var e = element.parent().children().eq(5);
// var height = e[0].scrollHeight;
// if(height>90){
// element.css('display', 'block');
// element.on('click', function(){
// if(element.text() == "点击展开"){
// e.css("height", height+'px');
// element.text("点击隐藏");
// } else {
// e.css("height", '90px');
// element.text("点击展开");
// }
//
// });
// }
// }, false);
//
// }
// }
//});
app.directive('inputAuto',function(){
return{
restrict: 'A',
scope: {},
link: function(scope, element){
var copyContainer = element.parent().children().eq(0);
var sendButton = element.parent().next();
element.on('input',function(){
console.log(sendButton);
copyContainer.html(element[0].value);
var textHeight = copyContainer[0].scrollHeight;
element.css('height', textHeight + 'px');
});
sendButton.on('click',function(){
element.css('height','28px');
});
}
}
});
app.directive('loadingSpinner', ['$http', function ($http) {
return {
restrict: 'A',
replace: true,
template: '<div ng-show="activeCalls>0" class="loading-bg"><div class="loading-box"><img src="/images/loading.gif" alt=""/><span>加载中...</span></div></div>',
};
}]);
app.config(['$routeProvider',"$httpProvider", "$locationProvider",function ($routeProvider, $httpProvider, $locationProvider) {
var rootPath = '/assets/wechat/'
//$locationProvider.html5Mode(true);
$routeProvider
.when('/activites', {
templateUrl: rootPath + 'activities.html',
controller: 'ActivityController'
})
.when('/issues/:id', {
templateUrl: rootPath + 'issue_detail.html',
controller: 'IssueController'
})
.when('/project_discussion/:id', {
templateUrl: rootPath + 'project_discussion.html',
controller: 'DiscussionController'
})
.when('/homework/:id', {
templateUrl: rootPath + 'homework_detail.html',
controller: 'HomeworkController'
})
.when('/course_notice/:id', {
templateUrl: rootPath + 'course_notice.html',
controller: 'CourseNoticeController'
})
.when('/course_discussion/:id', {
templateUrl: rootPath + 'course_discussion.html',
controller: 'DiscussionController'
})
.when('/journal_for_message/:id', {
templateUrl: rootPath + 'jour_message_detail.html',
controller: 'JournalsController'
})
.when('/blog_comment/:id', {
templateUrl: rootPath + 'blog_detail.html',
controller: 'BlogController'
})
.otherwise({
redirectTo: '/activites'
});
//监听异步请求,实现加载中显隐标记
$httpProvider.interceptors.push(function ($q, $rootScope) {
if ($rootScope.activeCalls == undefined) {
$rootScope.activeCalls = 0;
}
return {
request: function (config) {
$rootScope.activeCalls += 1;
return config;
},
requestError: function (rejection) {
$rootScope.activeCalls -= 1;
return rejection;
},
response: function (response) {
$rootScope.activeCalls -= 1;
return response;
},
responseError: function (rejection) {
$rootScope.activeCalls -= 1;
return rejection;
}
};
});
}]);
]);

View File

@ -1,36 +0,0 @@
$(function(){
//获取url中的参数
function getUrlParam(name) {
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象
var r = window.location.search.substr(1).match(reg); //匹配目标参数
if (r != null) return unescape(r[2]); return null; //返回参数值
}
var debug = false;
var g_openid = "";
if(debug){
g_openid = "填写要调试的openid即可";
}
window.getOpenId = function(cb){
if (g_openid.length>0){
cb(g_openid);
}
var code = getUrlParam("code");
$.ajax({
url: '/wechat/get_open_id',
data: {code: code},
type: 'post',
dataType: 'json',
success: function(data){
g_openid = data.openid;
cb(g_openid);
},
error: function(xhr,err){
alert("认证失败: "+err);
}
});
}
});

View File

@ -1,95 +0,0 @@
/**
* Created by root on 4/1/16.
*/
$(document).ready(function(){
var bt=baidu.template;
bt.LEFT_DELIMITER='<!';
bt.RIGHT_DELIMITER='!>';
var apiUrl = '/api/v1/';
var setTemplate = function(data){
console.log(data);
var html=bt('t:blog-detail',{blog: data});
$('#blog-container').prepend(html);
$('.post-reply-submit').click(function(){
replyInsert();
});
$('post-interactive-praise').click(function(){
praiseClick();
});
};
var loadDataFromServer = function(id){
//getOpenId(function(openid){
$.ajax({
url: apiUrl + 'blog_comments/' + id,
dataType: 'json',
success: function(data){
setTemplate(data.data);
},
error: function(xhr,status,err){
console.log(err);
}
});
//})
};
var homeworkUrl = window.location.search;
var homeworkID = homeworkUrl.split("=")[1];
loadDataFromServer(homeworkID);
//点击回复按钮,插入回复内容
var replyInsert = function(){
var replyContent = $("#postInput").val();
if (!replyContent){
alert("请输入回复");
}else{
//将用户输入内容插入最后一条回复
$(".post-reply-wrap:last").after('<div class="post-reply-wrap border-bottom"><div class="post-reply-row"><div class="post-reply-avatar fl"><img src="images/post-avatar.jpg" width="45" height="45" /></div><div class="ml55"><div class="post-reply-user hidden">Mrs. Ashford</div><div class="post-reply-content c-grey2 mb10"></div><div class="post-reply-date fl"></div><div class="post-reply-trigger fr undis">回复</div></div><div class="cl"></div></div> </div>');
$(".post-reply-content:last").append(replyContent);
$(".post-reply-date:last").append(Date());
var postInput = $("#postInput").val();
$("#postInput").val("");
//回复数目+1
var replyNum = $(".post-interactive-reply").text().match(/\d+/g);
replyNum++;
$(".reply-num").text("(" + replyNum + ")");
//获取并传送回复用户数据
var userInfo = {
"replyType" : "homework_assignment",
"replyContent" : postInput
};
$.ajax({
type: "POST", //提交方式
dataType: "json", //类型
url: "前台地址/后台方法", //提交的页面,方法名
data: userInfo, //参数如果没有可以为null
success: function (data) { //如果执行成功,那么执行此方法
alert(data.d); //用data.d来获取后台传过来的json语句或者是单纯的语句
},
error: function (err) { //如果执行不成功,那么执行此方法
alert("err:" + err);
}
});
}
}
//点赞效果
var praiseClick = function(){
var praiseNum = $(".post-interactive-praise").text().match(/\d+/g);
praiseNum++;
$(".praise-num").text("(" + praiseNum + ")");
}
});

View File

@ -0,0 +1,19 @@
var app=angular.module("wechat",["ngRoute"]);app.constant("config",{rootPath:"/assets/wechat/",rootUrl:"/",apiUrl:"/api/v1/"}),app.run(["$rootScope","auth","$location","$routeParams",function(t,a,e,r){g_redirect_path&&g_redirect_path.length>0&&(e.path(g_redirect_path),g_redirect_path=null),t.$on("$routeChangeError",function(t,a,r){a&&a.templateUrl&&(a.templateUrl.endsWith("login.html")||a.templateUrl.endsWith("reg.html")||e.path("/login"))}),t.$on("$routeChangeStart",function(t,a,e){})}]);
app.factory("alertService",function(){function t(){this.title=null,this.message=null,this.visible=null,this.cb=null}return t.prototype.showMessage=function(t,e,n){this.message=e,this.title=t,this.visible=!0,this.cb=n},t.prototype.dismiss=function(){this.message=null,this.title=null,this.visible=!1,this.cb&&this.cb()},{create:function(){return new t}}}),app.factory("auth",["$http","$routeParams","$q","session","config",function(t,e,n,o,a){var i=function(){var a=n.defer(),i=c();if(i&&i.length>10)a.resolve(i);else{window.g_code||e.code||o.get("code");t.post("/wechat/get_bind",{}).then(function(t){0!=t.data.status?a.reject(t.data.message):(o.save("token",t.data.token),a.resolve(t.data.token))})["catch"](function(t){a.reject(t)})}return a.promise},c=function(){return o.get("token")};return{get_bind:i,token:c}}]),app.factory("session",function(){return{save:function(t,e){sessionStorage.setItem(t,e)},get:function(t){return sessionStorage.getItem(t)}}}),app.factory("rms",function(){var t={},e=function(e,n){t[e]=n},n=function(e){return t[e]};return{save:e,get:n}}),app.factory("common",["$http","auth","$routeParams",function(t,e,n){var o=function(n,o,a,i){if(a.comment&&!(a.comment.length<=0)){var c=a.comment.replace(/\n/g,"<br/>"),s={type:o,content:c,token:e.token()};a.disabled=!0,t({method:"POST",url:apiUrl+"new_comment/"+n,data:s}).then(function(t){a.disabled=!1,"function"==typeof i&&i()},function(t){})}},a=function(n,o){return t({method:"GET",url:apiUrl+o+"/"+n+"?token="+e.token()})},i=function(n){n.praise_count+=1,n.has_praise=!0,t({method:"POST",url:apiUrl+"praise/"+n.act_id,data:{token:e.token(),type:n.act_type}}).then(function(t){console.log(t.data)},function(t){})},c=function(n){n.praise_count-=1,n.has_praise=!1,t({method:"POST",url:apiUrl+"praise/"+n.act_id,data:{token:e.token(),type:n.act_type}}).then(function(t){console.log(t.data)},function(t){})},s=function(t){t.scope.formData={comment:""};var e=function(e){a(e,t.type).then(function(e){t.loadCallback(e.data)},function(t){})};e(t.id),t.scope.addReply=function(n){console.log(n.comment),o(t.id,t.replyType,n,function(){t.scope.formData={comment:""},e(t.id),"function"==typeof t.replyCallback&&t.replyCallback()})},t.scope.addPraise=i,t.scope.decreasePraise=c};return{init:s,addCommonReply:o,loadCommonData:a,addCommonPraise:i,decreaseCommonPraise:c}}]);
app.filter("safeHtml",["$sce",function(t){return function(n){return t.trustAsHtml(n)}}]);
app.controller("ActivityController",["$anchorScroll","$location","$scope","$http","$timeout","auth","rms","common","alertService",function(a,t,e,o,i,c,n,r,s){e.replaceUrl=function(a){return a},e.alertService=s.create(),console.log("ActivityController load"),e.page=n.get("page")||0,e.activities=n.get("activities")||[],e.has_more=n.get("has_more"),e.loadActData=function(a){e.page=a,o({method:"POST",url:apiUrl+"activities",data:{token:c.token(),page:a}}).then(function(a){a.data.page>0?e.activities=e.activities.concat(a.data.data):e.activities=a.data.data,n.save("activities",e.activities),e.has_more=a.data.count+10*a.data.page<a.data.all_count,n.save("has_more",e.has_more),n.save("page",a.data.page),console.log(a.data)},function(a){})},e.activities.length<=0?e.loadActData(0):i(function(){window.scrollTo(0,n.get("yoffset"))}),e.goDetail=function(a,e,o){n.save("yoffset",window.document.body.scrollTop),t.path("/"+a+"/"+e)},e.addPraise=function(a){r.addCommonPraise(a)},e.decreasePraise=function(a){r.decreaseCommonPraise(a)}}]);
app.controller("AddClassController",["$scope",function(o){}]);
app.controller("BlogController",["$scope","$http","$routeParams","auth","common",function(o,l,t,n,a){a.init({id:t.id,scope:o,type:"blog_comments",replyType:"BlogComment",loadCallback:function(l){o.blog=l.data},replyCallback:function(){}})}]);
app.controller("CourseNoticeController",["$scope","$http","$routeParams","auth","common",function(o,e,t,n,a){a.init({id:t.id,scope:o,type:"newss",replyType:"News",loadCallback:function(e){o.news=e.data},replyCallback:function(){}})}]);
app.controller("DiscussionController",["$scope","$http","$routeParams","auth","common",function(o,s,a,e,n){n.init({id:a.id,scope:o,type:"messages",replyType:"Message",loadCallback:function(s){o.discussion=s.data},replyCallback:function(){}})}]);
app.controller("HomeworkController",["$scope","$http","$routeParams","auth","common",function(o,e,l,n,r){r.init({id:l.id,scope:o,type:"whomeworks",replyType:"HomeworkCommon",loadCallback:function(e){console.log(e),o.homework=e.data},replyCallback:function(){}})}]);
app.controller("IssueController",["$scope","$http","$routeParams","auth","common",function(o,e,l,s,t){t.init({id:l.id,scope:o,type:"issues",replyType:"Issue",loadCallback:function(e){console.log(e),o.issue=e.data},replyCallback:function(){}})}]);
app.controller("JournalsController",["$scope","$http","$routeParams","auth","common",function(o,a,e,l,n){n.init({id:e.id,scope:o,type:"journal_for_messages",replyType:"JournalsForMessage",loadCallback:function(a){o.message=a.data},replyCallback:function(){}})}]);
app.controller("LoginController",["$scope","$http","$location","$routeParams","alertService","config","auth","session",function(e,o,t,a,i,n,s,l){s.get_bind().then(function(){t.path("/activities")}),a.code&&l.save("code",a.code);var r=e;r.loginFailed=!1,r.alertService=i.create(),r.findPwdDialog=i.create(),r.login=function(a,i){return a.$setSubmitted(),console.log(i),a.$valid?(console.log(apiUrl+"auth"),void o.post(n.apiUrl+"users/wxbind",{login:i.login,password:i.password}).then(function(o){console.log(o.data),r.loginFailed=0!=o.data.status,e.loginFailed?r.alertService.showMessage("出错了",o.data.message):r.alertService.showMessage("提示",o.data.message,function(){t.path("/activities")})})["catch"](function(e){r.alertService.showMessage("出错了",e)})):void console.log(a.$error)},r.showBox=function(){r.findPwdDialog.showMessage("提示","请访问www.trustie.net获取密码谢谢")},r.goReg=function(){t.path("/reg")}}]);
app.controller("MyClassController",["$scope",function(o){}]);
app.controller("RegController",["$scope","$http","$location","alertService",function(e,o,a,r){var s=e;s.errDialog=r.create(),s.goLogin=function(){a.path("/login")},s.isagreed=!0,s.agreed=function(e){s.isagreed=!e},s.reg=function(e,a){return e.$setSubmitted(),console.log(e),e.$valid?(console.log(a),void o.post(apiUrl+"users",{login:a.username,password:a.password,mail:a.email}).then(function(e){0!=e.data.status?s.errDialog.showMessage("出错了",e.data.message):s.errDialog.showMessage("提示","注册且绑定微信成功")},function(e){s.errDialo.showMessage("出错了",e.data)})):void console.log(e.$error)}}]);
app.directive("myAlert",["config",function(t){return{templateUrl:t.rootPath+"templates/alert.html",scope:{title:"=",message:"=",visible:"=",cb:"="},link:function(t){t.dismiss=function(){t.visible=!1,"function"==typeof t.cb&&t.cb()}}}}]);
app.directive("pwdconfirm",function(){return{require:"ngModel",link:function(r,n,i,e){e.$validators.pwdconfirm=function(n,i){return r.user&&r.user.password==i}}}});
app.directive("inputAuto",function(){return{restrict:"A",scope:{},link:function(n,t){var e=t.parent().children().eq(0),i=t.parent().next();t.on("input",function(){console.log(i),e.html(t[0].value);var n=e[0].scrollHeight;t.css("height",n+"px")}),i.on("click",function(){t.css("height","28px")})}}});
app.directive("loadingSpinner",["$http",function(i){return{restrict:"A",replace:!0,template:'<div ng-show="activeCalls>0" class="loading-bg"><div class="loading-box"><img src="/images/loading.gif" alt=""/><span>加载中...</span></div></div>'}}]);
app.config(["$routeProvider","$httpProvider","$locationProvider","config",function(e,o,r,t){var l=t.rootPath,n={delay:["auth",function(e){return e.get_bind()}]},s=function(e,o){return{templateUrl:l+e,controller:o,resolve:n}};e.when("/login",{templateUrl:l+"login.html",controller:"LoginController"}).when("/reg",{templateUrl:l+"reg.html",controller:"RegController"}).when("/activites",s("activities.html","ActivityController")).when("/issues/:id",s("issue_detail.html","IssueController")).when("/project_discussion/:id",s("project_discussion.html","DiscussionController")).when("/homework/:id",s("homework_detail.html","HomeworkController")).when("/course_notice/:id",s("course_notice.html","CourseNoticeController")).when("/course_discussion/:id",s("course_discussion.html","DiscussionController")).when("/journal_for_message/:id",s("jour_message_detail.html","JournalsController")).when("/blog_comment/:id",s("blog_detail.html","BlogController")).when("/add_class",s("add_class.html","AddClassController")).when("/myclass",s("myclass.html","MyClassController")).otherwise({redirectTo:"/activites"}),o.interceptors.push(["$q","$rootScope",function(e,o){return void 0==o.activeCalls&&(o.activeCalls=0),{request:function(e){return o.activeCalls+=1,e},requestError:function(e){return o.activeCalls-=1,e},response:function(e){return o.activeCalls-=1,e},responseError:function(e){return o.activeCalls-=1,e}}}])}]);

View File

@ -0,0 +1,62 @@
app.controller('ActivityController',
['$anchorScroll', '$location','$scope', '$http', '$timeout', 'auth', 'rms', 'common','alertService',
function($anchorScroll, $location,$scope, $http, $timeout, auth, rms, common, alertService){
$scope.replaceUrl = function(url){
return url;
};
$scope.alertService = alertService.create();
console.log("ActivityController load");
$scope.page = rms.get('page') || 0;
$scope.activities = rms.get("activities") || [];
$scope.has_more = rms.get("has_more");
$scope.loadActData = function(page){
$scope.page = page;
$http({
method: 'POST',
url: apiUrl+ "activities",
data: {token: auth.token(), page: page}
}).then(function successCallback(response) {
if(response.data.page >0) {
$scope.activities = $scope.activities.concat(response.data.data);
} else {
$scope.activities = response.data.data;
}
rms.save("activities", $scope.activities);
$scope.has_more = (response.data.count + response.data.page * 10) < response.data.all_count;
rms.save('has_more', $scope.has_more);
rms.save('page', response.data.page);
console.log(response.data);
}, function errorCallback(response) {
});
};
if($scope.activities.length<=0){
$scope.loadActData(0);
} else {
$timeout(function(){
window.scrollTo(0, rms.get("yoffset"));
});
}
//跳到详情页
$scope.goDetail = function(type, act_id,id){
rms.save("yoffset", window.document.body.scrollTop);
$location.path('/'+type+'/'+act_id);
}
$scope.addPraise = function(act){
common.addCommonPraise(act);
};
$scope.decreasePraise = function(act){
common.decreaseCommonPraise(act);
};
}]);

View File

@ -0,0 +1,4 @@
app.controller('AddClassController', ['$scope',function($scope){
}]);

View File

@ -0,0 +1,16 @@
app.controller('BlogController',
['$scope', '$http', '$routeParams', 'auth', 'common',
function($scope, $http, $routeParams, auth, common){
common.init({
id: $routeParams.id,
scope: $scope,
type: 'blog_comments',
replyType: 'BlogComment',
loadCallback: function(data){
$scope.blog = data.data;
},
replyCallback: function(){
}
});
}]);

View File

@ -0,0 +1,16 @@
app.controller('CourseNoticeController', ['$scope', '$http', '$routeParams', 'auth', 'common',
function($scope, $http, $routeParams, auth, common){
common.init({
id: $routeParams.id,
scope: $scope,
type: 'newss',
replyType: 'News',
loadCallback: function(data){
$scope.news = data.data;
},
replyCallback: function(){
}
});
}]);

View File

@ -0,0 +1,14 @@
app.controller('DiscussionController', ['$scope', '$http', '$routeParams', 'auth', 'common', function($scope, $http, $routeParams, auth, common){
common.init({
id: $routeParams.id,
scope: $scope,
type: 'messages',
replyType: 'Message',
loadCallback: function(data){
$scope.discussion = data.data;
},
replyCallback: function(){
}
});
}]);

View File

@ -0,0 +1,16 @@
app.controller('HomeworkController', ['$scope', '$http', '$routeParams', 'auth', 'common', function($scope, $http, $routeParams, auth, common){
common.init({
id: $routeParams.id,
scope: $scope,
type: 'whomeworks',
replyType: 'HomeworkCommon',
loadCallback: function(data){
console.log(data);
$scope.homework = data.data;
},
replyCallback: function(){
}
});
}]);

View File

@ -0,0 +1,34 @@
/**
* Created by guange on 16/6/22.
*/
app.controller('InviteCodeController', ['$scope','$http', '$routeParams','config','auth', function($scope, $http, $routeParams, config, auth){
var vm = $scope;
vm.course = {};
var courseid = $routeParams.id;
$http.get(config.apiUrl+ 'courses/'+courseid+"?token="+auth.token()).then(
function(response){
console.log(response.data);
vm.course = response.data.data;
}
);
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);
});
}
}]);

View File

@ -0,0 +1,15 @@
app.controller('IssueController', ['$scope', '$http', '$routeParams', 'auth', 'common', function($scope, $http, $routeParams, auth, common){
common.init({
id: $routeParams.id,
scope: $scope,
type: 'issues',
replyType: 'Issue',
loadCallback: function(data){
console.log(data);
$scope.issue = data.data;
},
replyCallback: function(){
}
});
}]);

View File

@ -0,0 +1,13 @@
app.controller('JournalsController', ['$scope', '$http', '$routeParams', 'auth', 'common', function($scope, $http, $routeParams, auth, common){
common.init({
id: $routeParams.id,
scope: $scope,
type: 'journal_for_messages',
replyType: 'JournalsForMessage',
loadCallback: function(data){
$scope.message = data.data;
},
replyCallback: function(){
}
});
}]);

View File

@ -0,0 +1,53 @@
app.controller('LoginController', ['$scope', '$http', '$location', '$routeParams', 'alertService', 'config','auth','session',
function ($scope, $http, $location, $routeParams, alertService, config, auth,session) {
if(auth.get_bind().then(function(){
$location.path("/activities");
}));
if($routeParams.code){
session.save('code', $routeParams.code);
}
var vm = $scope;
vm.loginFailed = false;
vm.alertService = alertService.create();
vm.findPwdDialog = alertService.create();
vm.login = function (frm, user) {
frm.$setSubmitted();
console.log(user);
if (!frm.$valid) {
console.log(frm.$error);
return;
}
console.log(apiUrl + "auth");
$http.post(
config.apiUrl + "users/wxbind",
{login: user.login, password: user.password}
).then(
function(response) {
console.log(response.data);
vm.loginFailed = (response.data.status != 0);
if (!$scope.loginFailed) { //绑定成功
vm.alertService.showMessage('提示', response.data.message, function(){
$location.path("/activities");
});
} else {
vm.alertService.showMessage('出错了', response.data.message);
}
}
).catch(function(e){
vm.alertService.showMessage('出错了', e);
});
};
vm.showBox = function () {
vm.findPwdDialog.showMessage("提示", "请访问www.trustie.net获取密码谢谢");
}
vm.goReg = function () {
$location.path('/reg');
}
}]);

View File

@ -0,0 +1,54 @@
app.controller('MyClassController', ['$scope', 'config','$http', 'auth','$location','$routeParams', function($scope, config, $http, auth, $location, $routeParams){
var vm = $scope;
var courseid = $routeParams.id;
vm.currentTab = 1;
vm.tab = function(index){
vm.currentTab = index;
vm.searchText = '';
console.log(vm.currentTab);
if(index == 2){
if(vm.students.length<=0){
$http.get(config.apiUrl + 'courses/students?token='+auth.token()+'&course_id='+courseid).then(
function(response) {
console.log(response.data);
vm.students = response.data.data;
}
)
}
}
}
vm.course = {};
vm.students = [];
vm.teachers = [];
vm.resources = [];
vm.invite = function(){
$location.path("/invite_code").search({id: courseid});
};
$http.post(config.apiUrl + "courses/"+courseid+"/attachments",
{token: auth.token(), name: ''}
).then(function(response){
vm.resources = response.data.data;
});
$http.get(config.apiUrl+ 'courses/'+courseid+"?token="+auth.token()).then(
function(response){
console.log(response.data);
vm.course = response.data.data;
}
);
if(vm.teachers.length<=0){
$http.get(config.apiUrl + 'courses/teachers?token='+auth.token()+'&course_id='+courseid).then(
function(response) {
console.log(response.data);
vm.teachers = response.data.data;
}
)
}
}]);

View File

@ -0,0 +1,42 @@
app.controller('RegController', ['$scope', '$http', '$location', 'alertService',
function ($scope, $http, $location, alertService) {
var vm = $scope;
vm.errDialog = alertService.create();
vm.goLogin = function () {
$location.path("/login");
}
vm.isagreed = true;
vm.agreed = function (_isagreed) {
vm.isagreed = !_isagreed;
};
vm.reg = function (frm, user) {
frm.$setSubmitted();
console.log(frm);
if (!frm.$valid) {
console.log(frm.$error);
return;
}
console.log(user);
$http.post(
apiUrl + "users",
{login: user.username, password: user.password, mail: user.email}
).then(function (response) {
if (response.data.status != 0) {
vm.errDialog.showMessage('出错了',response.data.message);
} else {
vm.errDialog.showMessage("提示","注册且绑定微信成功");
}
}, function (response) {
vm.errDialo.showMessage('出错了',response.data);
});
}
}]);

View File

@ -1,102 +0,0 @@
/**
* Created by root on 4/1/16.
*/
$(document).ready(function(){
var bt=baidu.template;
bt.LEFT_DELIMITER='<!';
bt.RIGHT_DELIMITER='!>';
var apiUrl = '/api/v1/';
var setReplyTemplate = function(data){
console.log(data);
var html=bt('t:c-message-detail-reply',{reply: data});
$('#all_course_message_reply').prepend(html);
};
var setTemplate = function(data){
console.log(data);
var html=bt('t:course-discussion',{discussion: data});
$('#c-discussion-container').prepend(html);
$('.post-reply-submit').click(function(){
replyInsert();
});
/*$('post-interactive-praise').click(function(){
praiseClick();
});*/
};
var loadDataFromServer = function(id){
//getOpenId(function(openid){
$.ajax({
url: apiUrl + 'messages/' + id,
dataType: 'json',
success: function(data){
setTemplate(data.data);
},
error: function(xhr,status,err){
console.log(err);
}
});
//})
};
var homeworkUrl = window.location.search;
var homeworkID = homeworkUrl.split("=")[1];
loadDataFromServer(homeworkID);
//点击回复按钮,插入回复内容
var replyInsert = function(){
var replyContent = $("#postInput").val();
if (!replyContent){
alert("请输入回复");
}else{
//将用户输入内容插入最后一条回复
/*$(".post-reply-wrap:last").after('<div class="post-reply-wrap border-bottom"><div class="post-reply-row"><div class="post-reply-avatar fl"><img src="images/post-avatar.jpg" width="45" height="45" /></div><div class="ml55"><div class="post-reply-user hidden">Mrs. Ashford</div><div class="post-reply-content c-grey2 mb10"></div><div class="post-reply-date fl"></div><div class="post-reply-trigger fr undis"></div></div><div class="cl"></div></div> </div>');
$(".post-reply-content:last").append(replyContent);
$(".post-reply-date:last").append(Date());*/
var postInput = $("#postInput").val();
$("#postInput").val("");
//回复数目+1
var replyNum = $(".post-interactive-reply").text().match(/\d+/g);
replyNum++;
$(".reply-num").text("(" + replyNum + ")");
//获取并传送回复用户数据
var userInfo = {
"Type" : "Message",
"Content" : postInput
};
$.ajax({
type: "POST", //提交方式
dataType: "json", //类型
url: apiUrl + 'new_comment/' + homeworkID, //提交的页面,方法名
data: userInfo, //参数如果没有可以为null
success: function (data) { //如果执行成功,那么执行此方法
setReplyTemplate(data.data);
alert("6");
},
error: function (err) { //如果执行不成功,那么执行此方法
alert("err:" + err);
}
});
}
}
/*//点赞效果
var praiseClick = function(){
var praiseNum = $(".post-interactive-praise").text().match(/\d+/g);
praiseNum++;
$(".praise-num").text("(" + praiseNum + ")");
}*/
});

View File

@ -1,101 +0,0 @@
/**
* Created by root on 4/1/16.
*/
$(document).ready(function(){
var bt=baidu.template;
bt.LEFT_DELIMITER='<!';
bt.RIGHT_DELIMITER='!>';
var apiUrl = '/api/v1/';
var setReplyTemplate = function(data){
console.log(data);
var html=bt('t:news-detail-reply',{reply: data});
$('#all_news_reply').prepend(html);
};
var setTemplate = function(data){
console.log(data);
var html=bt('t:course-notice',{course: data});
$('#c-notice-container').prepend(html);
$('.post-reply-submit').click(function(){
replyInsert();
});
/*$('post-interactive-praise').click(function(){
praiseClick();
});*/
};
var loadDataFromServer = function(id){
//getOpenId(function(openid){
$.ajax({
url: apiUrl + 'newss/' + id,
dataType: 'json',
success: function(data){
setTemplate(data.data);
},
error: function(xhr,status,err){
console.log(err);
}
});
//})
};
var homeworkUrl = window.location.search;
var homeworkID = homeworkUrl.split("=")[1];
loadDataFromServer(homeworkID);
//点击回复按钮,插入回复内容
var replyInsert = function(){
var replyContent = $("#postInput").val();
if (!replyContent){
alert("请输入回复");
}else{
//将用户输入内容插入最后一条回复
/*$(".post-reply-wrap:last").after('<div class="post-reply-wrap border-bottom"><div class="post-reply-row"><div class="post-reply-avatar fl"><img src="images/post-avatar.jpg" width="45" height="45" /></div><div class="ml55"><div class="post-reply-user hidden">Mrs. Ashford</div><div class="post-reply-content c-grey2 mb10"></div><div class="post-reply-date fl"></div><div class="post-reply-trigger fr undis"></div></div><div class="cl"></div></div> </div>');
$(".post-reply-content:last").append(replyContent);
$(".post-reply-date:last").append(Date());*/
var postInput = $("#postInput").val();
$("#postInput").val("");
//回复数目+1
var replyNum = $(".post-interactive-reply").text().match(/\d+/g);
replyNum++;
$(".reply-num").text("(" + replyNum + ")");
//获取并传送回复用户数据
var userInfo = {
"type" : "News",
"content" : postInput
};
$.ajax({
type: "POST", //提交方式
dataType: "json", //类型
url: apiUrl + 'new_comment/' + homeworkID, //提交的页面,方法名
data: userInfo, //参数如果没有可以为null
success: function (data) { //如果执行成功,那么执行此方法
setReplyTemplate(data.data);
},
error: function (err) { //如果执行不成功,那么执行此方法
alert("err:" + err);
}
});
}
}
//点赞效果
var praiseClick = function(){
var praiseNum = $(".post-interactive-praise").text().match(/\d+/g);
praiseNum++;
$(".praise-num").text("(" + praiseNum + ")");
}
});

View File

@ -0,0 +1,19 @@
app.directive('myAlert', ['config', function(config){
return {
templateUrl: config.rootPath+ 'templates/alert.html',
scope: {
title: "=",
message: "=",
visible: "=",
cb: "="
},
link: function(scope){
scope.dismiss = function(){
scope.visible = false;
if(typeof scope.cb === 'function'){
scope.cb();
}
};
}
}
}]);

View File

@ -0,0 +1,10 @@
app.directive('pwdconfirm', function(){
return {
require: 'ngModel',
link: function(scope, elm, attrs, ctrl){
ctrl.$validators.pwdconfirm = function(modelValue, viewValue) {
return scope.user && scope.user.password == viewValue;
}
}
}
});

View File

@ -0,0 +1,19 @@
app.directive('inputAuto',function(){
return{
restrict: 'A',
scope: {},
link: function(scope, element){
var copyContainer = element.parent().children().eq(0);
var sendButton = element.parent().next();
element.on('input',function(){
console.log(sendButton);
copyContainer.html(element[0].value);
var textHeight = copyContainer[0].scrollHeight;
element.css('height', textHeight + 'px');
});
sendButton.on('click',function(){
element.css('height','28px');
});
}
}
});

View File

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

View File

@ -8,3 +8,10 @@ gulp.task('minify', function () {
.pipe(concat('angular.all.min.js'))
.pipe(gulp.dest('build'))
});
gulp.task("default", function(){
gulp.src(['app.js','others/factory.js','others/filter.js', 'controllers/*.js', 'directives/*.js', 'others/routes.js'])
.pipe(uglify())
.pipe(concat('app.min.js'))
.pipe(gulp.dest('build'))
});

View File

@ -1,104 +0,0 @@
/**
* Created by root on 3/31/16.
*/
$(document).ready(function(){
var bt=baidu.template;
bt.LEFT_DELIMITER='<!';
bt.RIGHT_DELIMITER='!>';
var apiUrl = '/api/v1/';
var setReplyTemplate = function(data){
console.log(data);
var html=bt('t:homework-detail-reply',{reply: data});
$('#all_homework_reply').prepend(html);
};
var setTemplate = function(data){
console.log(data);
var html=bt('t:homework-detail',{homework: data});
$('#homework-container').prepend(html);
$('.post-reply-submit').click(function(){
replyInsert();
});
/*$('post-interactive-praise').click(function(){
praiseClick();
});*/
};
var loadDataFromServer = function(id){
//getOpenId(function(openid){
$.ajax({
url: apiUrl + 'whomeworks/' + id,
dataType: 'json',
success: function(data){
setTemplate(data.data);
},
error: function(xhr,status,err){
console.log(err);
}
});
//})
};
var homeworkUrl = window.location.search;
var homeworkID = homeworkUrl.split("=")[1];
loadDataFromServer(homeworkID);
//点击回复按钮,插入回复内容
var replyInsert = function(){
var replyContent = $("#postInput").val();
if (!replyContent){
alert("请输入回复");
}else{
/*//将用户输入内容插入最后一条回复
$(".post-reply-wrap:last").after('<div class="post-reply-wrap border-bottom"><div class="post-reply-row"><div class="post-reply-avatar fl"><img src="images/post-avatar.jpg" width="45" height="45" /></div><div class="ml55"><div class="post-reply-user hidden">Mrs. Ashford</div><div class="post-reply-content c-grey2 mb10"></div><div class="post-reply-date fl"></div><div class="post-reply-trigger fr undis">回复</div></div><div class="cl"></div></div> </div>');
$(".post-reply-content:last").append(replyContent);
$(".post-reply-date:last").append(Date());*/
var postInput = $("#postInput").val();
$("#postInput").val("");
//回复数目+1
var replyNum = $(".post-interactive-reply").text().match(/\d+/g);
replyNum++;
$(".reply-num").text("(" + replyNum + ")");
getOpenId(function(openid) {
//获取并传送回复用户数据
var userInfo = {
"type": "HomeworkCommon",
"content": postInput,
openid: openid
};
$.ajax({
type: "POST", //提交方式
dataType: "json", //类型
url: apiUrl + 'new_comment/' + homeworkID, //提交的页面,方法名
data: userInfo, //参数如果没有可以为null
success: function (data) { //如果执行成功,那么执行此方法
setReplyTemplate(data.data);
},
error: function (err) { //如果执行不成功,那么执行此方法
alert("err:" + err);
}
})
});
}
};
//点赞效果
/*var praiseClick = function(){
var praiseNum = $(".post-interactive-praise").text().match(/\d+/g);
praiseNum++;
$(".praise-num").text("(" + praiseNum + ")");
};*/
});

View File

@ -1,108 +0,0 @@
/**
* Created by root on 4/1/16.
*/
/**
* Created by root on 3/31/16.
*/
$(document).ready(function(){
var bt=baidu.template;
bt.LEFT_DELIMITER='<!';
bt.RIGHT_DELIMITER='!>';
var apiUrl = '/api/v1/';
var setReplyTemplate = function(data){
console.log(data);
var html=bt('t:issue-detail-reply',{issue_reply: data});
$('#all_issue_reply').prepend(html);
};
var setTemplate = function(data){
console.log(data);
var html=bt('t:issue-detail',{issues: data});
$('#issue-container').prepend(html);
$('.post-reply-submit').click(function(){
IssueReplyInsert();
});
/*$('post-interactive-praise').click(function(){
praiseClick();
});*/
};
var loadDataFromServer = function(id){
//getOpenId(function(openid){
$.ajax({
url: apiUrl + 'issues/' + id,
dataType: 'json',
success: function(data){
setTemplate(data.data);
},
error: function(xhr,status,err){
console.log(err);
}
});
//})
};
var IssueUrl = window.location.search;
var IssueID = IssueUrl.split("=")[1];
loadDataFromServer(IssueID);
//点击回复按钮,插入回复内容
var IssueReplyInsert = function(){
var replyContent = $("#postInput").val();
if (!replyContent){
alert("请输入回复");
}else{
//将用户输入内容插入最后一条回复
/*$(".post-reply-wrap:last").after('<div class="post-reply-wrap border-bottom"><div class="post-reply-row"><div class="post-reply-avatar fl"><img src="images/post-avatar.jpg" width="45" height="45" /></div><div class="ml55"><div class="post-reply-user hidden">Mrs. Ashford</div><div class="post-reply-content c-grey2 mb10"></div><div class="post-reply-date fl"></div><div class="post-reply-trigger fr undis"></div></div><div class="cl"></div></div> </div>');
$(".post-reply-content:last").append(replyContent);
$(".post-reply-date:last").append(Date());*/
var postInput = $("#postInput").val();
$("#postInput").val("");
//回复数目+1
var replyNum = $(".post-interactive-reply").text().match(/\d+/g);
replyNum++;
$(".reply-num").text("(" + replyNum + ")");
getOpenId(function(openid) {
//获取并传送回复用户数据
var userInfo = {
"type": "Issue",
"content": postInput,
openid: openid,
};
$.ajax({
type: "POST", //提交方式
dataType: "json", //类型
url: apiUrl + 'new_comment/' + IssueID, //提交的页面,方法名
data: userInfo, //参数如果没有可以为null
success: function (data) { //如果执行成功,那么执行此方法
setReplyTemplate(data.data);
},
error: function (err) { //如果执行不成功,那么执行此方法
alert("err:" + err);
}
})
});
}
};
//点赞效果
/*var praiseClick = function(){
var praiseNum = $(".post-interactive-praise").text().match(/\d+/g);
praiseNum++;
$(".praise-num").text("(" + praiseNum + ")");
};*/
});

View File

@ -1,95 +0,0 @@
/**
* Created by root on 4/1/16.
*/
$(document).ready(function(){
var bt=baidu.template;
bt.LEFT_DELIMITER='<!';
bt.RIGHT_DELIMITER='!>';
var apiUrl = '/api/v1/';
var setTemplate = function(data){
console.log(data);
var html=bt('t:message-detail',{message: data});
$('#message-container').prepend(html);
$('.post-reply-submit').click(function(){
replyInsert();
});
$('post-interactive-praise').click(function(){
praiseClick();
});
};
var loadDataFromServer = function(id){
//getOpenId(function(openid){
$.ajax({
url: apiUrl + 'journal_for_messages/' + id,
dataType: 'json',
success: function(data){
setTemplate(data.data);
},
error: function(xhr,status,err){
console.log(err);
}
});
//})
};
var homeworkUrl = window.location.search;
var homeworkID = homeworkUrl.split("=")[1];
loadDataFromServer(homeworkID);
//点击回复按钮,插入回复内容
var replyInsert = function(){
var replyContent = $("#postInput").val();
if (!replyContent){
alert("请输入回复");
}else{
//将用户输入内容插入最后一条回复
$(".post-reply-wrap:last").after('<div class="post-reply-wrap border-bottom"><div class="post-reply-row"><div class="post-reply-avatar fl"><img src="images/post-avatar.jpg" width="45" height="45" /></div><div class="ml55"><div class="post-reply-user hidden">Mrs. Ashford</div><div class="post-reply-content c-grey2 mb10"></div><div class="post-reply-date fl"></div><div class="post-reply-trigger fr undis">回复</div></div><div class="cl"></div></div> </div>');
$(".post-reply-content:last").append(replyContent);
$(".post-reply-date:last").append(Date());
var postInput = $("#postInput").val();
$("#postInput").val("");
//回复数目+1
var replyNum = $(".post-interactive-reply").text().match(/\d+/g);
replyNum++;
$(".reply-num").text("(" + replyNum + ")");
//获取并传送回复用户数据
var userInfo = {
"replyType" : "homework_assignment",
"replyContent" : postInput
};
$.ajax({
type: "POST", //提交方式
dataType: "json", //类型
url: "前台地址/后台方法", //提交的页面,方法名
data: userInfo, //参数如果没有可以为null
success: function (data) { //如果执行成功,那么执行此方法
alert(data.d); //用data.d来获取后台传过来的json语句或者是单纯的语句
},
error: function (err) { //如果执行不成功,那么执行此方法
alert("err:" + err);
}
});
}
}
//点赞效果
var praiseClick = function(){
var praiseNum = $(".post-interactive-praise").text().match(/\d+/g);
praiseNum++;
$(".praise-num").text("(" + praiseNum + ")");
}
});

View File

@ -0,0 +1,182 @@
app.factory('alertService', function(){
function Alert(){
this.title = null;
this.message = null;
this.visible = null;
this.cb = null;
}
Alert.prototype.showMessage = function(title, msg, cb){
this.message = msg;
this.title = title;
this.visible = true;
this.cb = cb;
}
Alert.prototype.dismiss = function(){
this.message = null;
this.title = null;
this.visible = false;
if(this.cb) {this.cb();}
}
return {
create: function(){
return new Alert();
}
}
});
app.factory('auth', ['$http','$routeParams', '$q', 'session', 'config',function($http,$routeParams, $q, session,config){
//是否已经绑定
var isBind = function(){
var defer = $q.defer();
var token = getToken();
if(token && token.length>10){
defer.resolve(token);
} else {
var code = window.g_code || $routeParams.code || session.get("code");
$http.post(
'/wechat/get_bind',
{} ///不用传code了,都由服务器来处理
).then(function(response){
if(response.data.status!=0){
defer.reject(response.data.message);
}else {
session.save("token", response.data.token);
defer.resolve(response.data.token);
}
}).catch(function(e){
defer.reject(e);
});
}
return defer.promise;
}
var getToken = function(){
return session.get("token");
}
return {get_bind: isBind, token: getToken};
}]);
app.factory("session", function(){
return {
save: function(key,value){
sessionStorage.setItem(key,value);
},
get: function(key){
return sessionStorage.getItem(key);
}
}
});
app.factory('rms', function(){
var _saveStorage = {};
var save = function(key, value){
_saveStorage[key] = value;
};
var get = function(key){
return _saveStorage[key];
};
return {save: save, get: get};
});
app.factory('common', ['$http', 'auth', '$routeParams', function($http, auth, $routeParams){
var addCommonReply = function(id, type, data, cb){
if(!data.comment || data.comment.length<=0){
return;
}
var temp = data.comment.replace(/\n/g,'<br/>');
var userInfo = {
type: type,
content: temp,
token: auth.token()
};
//回复按钮禁用
data.disabled = true;
$http({
method: 'POST',
url: apiUrl+ "new_comment/"+id,
data: userInfo
}).then(function successCallback(response) {
//alert("提交成功");
//数据提交完成,回复按钮启用
data.disabled = false;
if(typeof cb === 'function'){
cb();
}
}, function errorCallback(response) {
});
};
var loadCommonData = function(id, type){
return $http({
method: 'GET',
url: apiUrl+ type + "/" + id+"?token="+auth.token()
})
};
var addCommonPraise = function(act){
act.praise_count += 1;
act.has_praise = true;
$http({
method: 'POST',
url: apiUrl + "praise/" + act.act_id,
data:{token:auth.token(),type:act.act_type}
}).then(function successCallback(response) {
console.log(response.data);
}, function errorCallback(response) {
});
};
var decreaseCommonPraise = function(act){
act.praise_count -= 1;
act.has_praise = false;
$http({
method: 'POST',
url: apiUrl + "praise/" + act.act_id,
data:{token:auth.token(),type:act.act_type}
}).then(function successCallback(response) {
console.log(response.data);
}, function errorCallback(response) {
});
};
var init = function(args){
args.scope.formData = {comment: ''};
var loadData = function(id){
loadCommonData(id, args.type).then(function successCallback(response) {
args.loadCallback(response.data);
}, function errorCallback(response) {
});
};
loadData(args.id);
args.scope.addReply = function(data){
console.log(data.comment);
addCommonReply(args.id, args.replyType, data, function(){
args.scope.formData = {comment: ''};
loadData(args.id);
if(typeof args.replyCallback === 'function'){
args.replyCallback();
}
});
};
args.scope.addPraise = addCommonPraise;
args.scope.decreasePraise = decreaseCommonPraise;
}
return {init: init, addCommonReply: addCommonReply, loadCommonData: loadCommonData, addCommonPraise: addCommonPraise, decreaseCommonPraise: decreaseCommonPraise};
}]);

View File

@ -0,0 +1,14 @@
app.filter('safeHtml', ['$sce',function ($sce) {
return function (input) {
return $sce.trustAsHtml(input);
}
}]);
app.filter('identify', function () {
return function(input){
if (input == 'TeachingAsistant'){
return '教辅'
}
return '';
}
})

View File

@ -0,0 +1,65 @@
app.config(['$routeProvider',"$httpProvider", "$locationProvider",'config', function ($routeProvider, $httpProvider, $locationProvider, config) {
var rootPath = config.rootPath;
var resolve = {
delay: ['auth',function(auth){
return auth.get_bind();
}]
};
var makeRoute = function(path, ctrl){
return {
templateUrl: rootPath + path,
controller: ctrl,
resolve: resolve
}
}
//$locationProvider.html5Mode(true);
$routeProvider
.when('/login', {
templateUrl: rootPath + 'login.html',
controller: 'LoginController'
})
.when('/reg', {
templateUrl: rootPath + 'reg.html',
controller: 'RegController'
})
.when('/activites', makeRoute('activities.html', 'ActivityController'))
.when('/issues/:id', makeRoute('issue_detail.html', 'IssueController'))
.when('/project_discussion/:id', makeRoute('project_discussion.html', 'DiscussionController'))
.when('/homework/:id', makeRoute('homework_detail.html', 'HomeworkController'))
.when('/course_notice/:id', makeRoute('course_notice.html', 'CourseNoticeController'))
.when('/course_discussion/:id', makeRoute('course_discussion.html', 'DiscussionController'))
.when('/journal_for_message/:id', makeRoute('jour_message_detail.html', 'JournalsController'))
.when('/blog_comment/:id', makeRoute('blog_detail.html', 'BlogController'))
.when('/add_class', makeRoute('add_class.html', 'AddClassController'))
.when('/myclass', makeRoute('myclass.html', 'MyClassController'))
.when('/invite_code', makeRoute('invite_code.html', 'InviteCodeController'))
.otherwise({
redirectTo: '/activites'
});
//监听异步请求,实现加载中显隐标记
$httpProvider.interceptors.push(['$q', '$rootScope', function ($q, $rootScope) {
if ($rootScope.activeCalls == undefined) {
$rootScope.activeCalls = 0;
}
return {
request: function (config) {
$rootScope.activeCalls += 1;
return config;
},
requestError: function (rejection) {
$rootScope.activeCalls -= 1;
return rejection;
},
response: function (response) {
$rootScope.activeCalls -= 1;
return response;
},
responseError: function (rejection) {
$rootScope.activeCalls -= 1;
return rejection;
}
};
}]);
}]);

View File

@ -1,105 +0,0 @@
/**
* Created by root on 4/1/16.
*/
/**
* Created by root on 4/1/16.
*/
$(document).ready(function(){
var bt=baidu.template;
bt.LEFT_DELIMITER='<!';
bt.RIGHT_DELIMITER='!>';
var apiUrl = '/api/v1/';
var setReplyTemplate = function(data){
console.log(data);
var html=bt('t:homework-detail-reply',{reply: data});
$('#all_homework_reply').prepend(html);
};
var setTemplate = function(data){
console.log(data);
var html=bt('t:project-discussion',{discussion: data});
$('#p-discussion-container').prepend(html);
$('.post-reply-submit').click(function(){
replyInsert();
});
/*$('post-interactive-praise').click(function(){
praiseClick();
});*/
};
var loadDataFromServer = function(id){
//getOpenId(function(openid){
$.ajax({
url: apiUrl + 'messages/' + id,
dataType: 'json',
success: function(data){
setTemplate(data.data);
},
error: function(xhr,status,err){
console.log(err);
}
});
//})
};
var homeworkUrl = window.location.search;
var homeworkID = homeworkUrl.split("=")[1];
loadDataFromServer(homeworkID);
//点击回复按钮,插入回复内容
var replyInsert = function(){
var replyContent = $("#postInput").val();
if (!replyContent){
alert("请输入回复");
}else{
/*//将用户输入内容插入最后一条回复
$(".post-reply-wrap:last").after('<div class="post-reply-wrap border-bottom"><div class="post-reply-row"><div class="post-reply-avatar fl"><img src="images/post-avatar.jpg" width="45" height="45" /></div><div class="ml55"><div class="post-reply-user hidden">Mrs. Ashford</div><div class="post-reply-content c-grey2 mb10"></div><div class="post-reply-date fl"></div><div class="post-reply-trigger fr undis">回复</div></div><div class="cl"></div></div> </div>');
$(".post-reply-content:last").append(replyContent);
$(".post-reply-date:last").append(Date());*/
var postInput = $("#postInput").val();
$("#postInput").val("");
//回复数目+1
var replyNum = $(".post-interactive-reply").text().match(/\d+/g);
replyNum++;
$(".reply-num").text("(" + replyNum + ")");
//获取并传送回复用户数据
var userInfo = {
"type" : "Message",
"content" : postInput
};
$.ajax({
type: "POST", //提交方式
dataType: "json", //类型
url: apiUrl + 'new_comment/' + homeworkID, //提交的页面,方法名
data: userInfo, //参数如果没有可以为null
success: function (data) { //如果执行成功,那么执行此方法
setReplyTemplate(data.data); //用data.d来获取后台传过来的json语句或者是单纯的语句
},
error: function (err) { //如果执行不成功,那么执行此方法
alert("err:" + err);
}
});
}
}
//点赞效果
/*var praiseClick = function(){
var praiseNum = $(".post-interactive-praise").text().match(/\d+/g);
praiseNum++;
$(".praise-num").text("(" + praiseNum + ")");
}*/
});

View File

@ -1,57 +0,0 @@
/**
* Created by root on 3/25/16.
*/
$(document).ready(function(){
var bt=baidu.template;
bt.LEFT_DELIMITER='<!';
bt.RIGHT_DELIMITER='!>';
var apiUrl = '/api/v1/';
var loadDataFromServer = function(id, page){
getOpenId(function(openid){
$.ajax({
url: apiUrl + 'activities',
data: {openid: openid, page: page},
type: 'POST',
dataType: 'json',
success: function(data){
setTemplate(data.data, data.all_count, data.count, data.page);
},
error: function(xhr,status,err){
console.log(err);
}
});
})
};
var setTemplate = function(data, all_count, count, page){
console.log(data);
var html=bt('t:result-list',{activities: data, all_count: all_count, count: count, page: page});
if (page == 0) {
$('#container').prepend(html);
} else {
$("#more_activities").remove();
$('#container').append(html);
}
descToggle();
};
//内容全部显示与部分隐藏
var descToggle = function(){
$(".post-all-content").each(function(){
var postHeight = $(this).height();
if (postHeight > 90){
$(this).parent().next().css("display","block");
$(this).parent().next().toggle(function(){
$(this).text("点击隐藏");
$(this).prev().css("height",postHeight);
},function(){
$(this).text("点击展开");
$(this).prev().css("height",90);
});
}
});
}
loadDataFromServer(8686, 0);
});

View File

@ -2,8 +2,10 @@
/* CSS Document */
/*基本样式*/
body,table,input,textarea,select,button { font-family: "微软雅黑","宋体";}
h1,h2,h3,h4,h5,p,pre {padding:0px; margin:0px;}
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{background-color: #EFEFF4;}
ul li {list-style:none;}
img {max-width:100%;}
blockquote {border:1px solid #d4d4d4; padding: 0.6em; margin-left: 1.4em; margin-right: 0.4em; border-radius: 4px; font-family: "Microsoft YaHei"; background-size: 100% 100%; margin-top:5px;}
.text-control {word-break:normal; word-wrap:break-word;}
@ -12,29 +14,43 @@ blockquote {border:1px solid #d4d4d4; padding: 0.6em; margin-left: 1.4em; margin
.f15 {font-size:15px;}
.fb {font-weight:bold;}
.mt2 {margin-top:2px;}
.mt3 {margin-top:3px;}
.mt4 {margin-top:4px;}
.mt5 {margin-top:5px;}
.mt10 {margin-top:10px;}
.mt11 {margin-top:11px;}
.mt15 {margin-top:15px;}
.mt30 {margin-top:30px;}
.mt70 {margin-top:70px;}
.mb5 {margin-bottom:5px;}
.mb10 {margin-bottom:10px;}
.mb20 {margin-bottom:20px;}
.ml10 {margin-left:10px;}
.mr5 {margin-right:5px;}
.mr10 {margin-right:10px;}
.ml15 {margin-left:15px;}
.mr15 {margin-right:15px;}
.mr20 {margin-right:20px;}
.ml25 {margin-left:25px;}
.mr25 {margin-right:25px;}
.ml55 {margin-left:55px;}
.mr55 {margin-right:55px;}
.c-red {color:#e81a1a;}
.c-blue {color:#269ac9;}
.c-grey {color:#9a9a9a;}
.c-grey2 {color:#707070;}
.c-grey3 {color:#555555;}
.c-grey4 {color:#888888;}
.c-grey5 {color:#aaaaaa;}
.c-grey6 {color:#777777;}
.c-blue {color:#3b94d6;}
a {color:#707070;}
a.c-grey {color:#707070;}
a.c-grey2 {color:#9a9a9a;}
a:link,a:visited{text-decoration:none;}
a:hover,a:active{cursor:pointer;}
a.link-blue {color:#269ac9;}
a.link-blue2 {color:#3b94d6;}
a.underline {text-decoration:underline;}
.border-radius {border-radius:5px;}
.w36 {width:36px;}
@ -42,9 +58,23 @@ a.underline {text-decoration:underline;}
.max-width-130 {max-width:130px;}
.hidden {overflow:hidden; white-space:nowrap; text-overflow:ellipsis;}
.inline-block {display:inline-block;}
.dis {display:block;}
.undis {display:none;}
.text-nowrap {white-space:nowrap;}
.v-top {vertical-align:top;}
.tac {text-align:center;}
.block-center {margin-left:auto; margin-right:auto; display:block;}
/*背景色*/
.bg-grey {background-color:#c1c1c1 !important;}
.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;}
.bg-blue:not(.btn-disabled):active {background-color:#2780c2;}
.btn-disabled {background-color:#ccc;}
/*背景色*/
/*动态样式*/
.post-container {width:100%;}
@ -56,7 +86,8 @@ a.underline {text-decoration:underline;}
.fl {float:left;}
.fr {float:right;}
.cl {clear:both; overflow:hidden;}
.post-content {width:100%; font-size:13px; line-height:18px; height:95px; overflow:hidden; word-break:break-all; word-wrap:break-word;}
.post-content {width:100%; font-size:13px; line-height:18px; height:90px; overflow:hidden; word-break:break-all; word-wrap:break-word;}
.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-column,
.post-interactive-reply,
@ -78,6 +109,8 @@ a.underline {text-decoration:underline;}
.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;}
.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;}
.post-op-banner {height:20px; line-height:20px; vertical-align:middle;}
/* 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;}
@ -86,6 +119,67 @@ a.underline {text-decoration:underline;}
.loading-box span {display: block; font-size:12px;}
/*帖子锁定样式*/
.locked_btn_cir {background: url("/images/locked.png") 0 0 no-repeat; cursor: default;}
.locked_btn_cir {background: url("/images/wechat/locked.png") 0 0 no-repeat; cursor: default;}
.bg-grey {background-color:#c1c1c1;}
/*20150612加入班级样式*/
.add-class-box {width:80%; max-width:300px; min-width:240px; height:150px; font-size:15px; color:#444; background-color:#fff; margin:0 auto; box-shadow: 0px 2px 8px rgba(146, 153, 169, 0.5); border-radius:5px; margin-top:100px;}
.add-class-tip {padding-top:20px; padding-bottom:20px;}
.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;}
.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-line {width:1px; height:37px; margin:auto; background:#ccc;}
/*20160613邀请码样式*/
.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;}
.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-code-img {margin:36px auto; display:block;}
.invitation-code-wrap {text-align:center; font-size:18px; color:#3b3b3b; padding:16px;}
.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-instruction {max-width:228px; font-size:12px; color:#666; line-height:20px; margin:0 auto;}
/*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;}
.blue-title-sub {position:absolute; right:10px;}
.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;}
.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-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-tab-active {border-bottom:1px solid #3b94d6;}
.class-search-wrap {padding:8px 12px; position:relative;}
.class-search-inner {padding:0 30px; background-color:#fff;}
.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;}
.border-top {border-top:1px solid #ccc;}
.class-detail-row {width:100%; height:38px; line-height:38px; vertical-align:middle; border-bottom:1px solid #ccc; background-color:#fff;}
.class-test-tip {text-align:center; font-size:13px; color:#444; padding-top:40px;}
.img-circle {border-radius:50%;}
.member-banner {height:24px; line-height:24px; text-align:center; vertical-align:middle; background-color:#dfdfdf;}
/*20160614班级列表*/
.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 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-dot {position:absolute; top:13px; left:-8px;}
.border-bottom-none {border-bottom:none !important;}
.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;}
.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:#aaa; height:35px; line-height:35px; vertical-align:middle; border:none; outline:none;}
/*20160616登录注册*/
.login-wrap {padding:0 10px;}
.input-box-wrap {padding-right:17px;}
.input-box { -webkit-appearance: none; font-size: 16px;width:100%; height:16px; padding: 10px 0px 10px 5px; line-height:16px; border:1px solid #ccc; border-radius:5px;}
.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.checked{background:#63c360;}
.login-box.checked:after{content:url(/images/wechat/checked.png);}
.forget-psw-wrap {width:60px; margin:0 auto;}
.forget-psw {position:fixed; bottom:10px;}

3
script/assets Normal file
View File

@ -0,0 +1,3 @@
#!/usr/bin/env bash
cd public/javascripts/wechat && gulp && gulp minify