chenlw_dev
cxt 9 years ago
commit 5e3e2e64a9

@ -0,0 +1 @@
{"access_token":"7MBMEBoE6sSC15bIHZYAZSxj47yCKlbWEVjrkUgEJxPP3K083tbhc1RIWmxGu3WoB5dAXxK_yd4l1jrcvt6YrsTcOfFGRirOHVfzrpvhsQgxOoxcdc7YljfO_dnwUtWgFTAcAIALZG","expires_in":7200,"got_token_at":1460189856}

@ -6,6 +6,7 @@ unless RUBY_PLATFORM =~ /w32/
gem 'iconv'
end
gem 'wechat',git: 'https://github.com/guange2015/wechat.git'
gem 'grack', path:'lib/grack'
gem 'gitlab', path: 'lib/gitlab-cli'
gem 'rest-client'
@ -16,8 +17,9 @@ gem 'delayed_job_active_record'#, :group => :production
gem 'daemons'
gem 'grape', '~> 0.9.0'
gem 'grape-entity'
gem 'rack-cors', :require => 'rack/cors'
gem 'seems_rateable', '~> 1.0.13'
gem "rails", "~> 3.2.13"
gem 'rails', '~> 3.2'
gem "jquery-rails", "~> 2.0.2"
gem "i18n", "~> 0.6.0"
gem 'coderay', '~> 1.1.0'
@ -43,7 +45,7 @@ gem 'elasticsearch-rails'
group :development do
gem 'grape-swagger'
gem 'better_errors', '~> 1.1.0'
gem 'rack-mini-profiler', '~> 0.9.3'
# gem 'rack-mini-profiler', '~> 0.9.3'
if RUBY_PLATFORM =~ /w32/
gem 'win32console'
end

@ -7,6 +7,16 @@ module Mobile
require_relative 'apis/upgrade'
require_relative 'apis/homeworks'
require_relative 'apis/comments'
require_relative 'apis/issues'
require_relative 'apis/activities'
require_relative 'apis/whomeworks'
require_relative 'apis/newss'
require_relative 'apis/journal_for_messages'
require_relative 'apis/messages'
require_relative 'apis/blog_comments'
require_relative 'apis/new_comment'
require_relative 'apis/praise'
class API < Grape::API
version 'v1', using: :path
format :json
@ -39,6 +49,15 @@ module Mobile
mount Apis::Upgrade
mount Apis::Homeworks
mount Apis::Comments
mount Apis::Issues
mount Apis::Activities
mount Apis::Whomeworks
mount Apis::Newss
mount Apis::JournalForMessages
mount Apis::Messages
mount Apis::BlogComments
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?

@ -0,0 +1,63 @@
#coding=utf-8
module Mobile
module Apis
class Activities< Grape::API
resources :activities do
desc "get user activities"
params do
requires :page, type: Integer
requires :openid, type: String
end
post do
user = UserWechat.find_by_openid(params[:openid]).user
=begin
shield_project_ids = ShieldActivity.where("container_type='User' and container_id=#{user.id} and shield_type='Project'").map(&:shield_id)
shield_course_ids = ShieldActivity.where("container_type='User' and container_id=#{user.id} and shield_type='Course'").map(&:shield_id)
page = params[:page] ? params[:page] : 0
user_project_ids = (user.projects.visible.map{|project| project.id}-shield_project_ids).empty? ? "(-1)" : "(" + (user.projects.visible.map{|project| project.id}-shield_project_ids).join(",") + ")"
user_course_ids = (user.courses.visible.map{|course| course.id}-shield_course_ids).empty? ? "(-1)" : "(" + (user.courses.visible.map{|course| course.id}-shield_course_ids).join(",") + ")"
course_types = "('Message','News','HomeworkCommon','Poll','Course')"
project_types = "('Message','Issue','ProjectCreateInfo')"
principal_types = "JournalsForMessage"
blog_ids = "("+user.blog.id.to_s+","+((User.watched_by(user.id).count == 0 )? '0' :User.watched_by(user.id).map{|u| u.blog.id}.join(','))+")"
activities = UserActivity.where("(container_type = 'Project' and container_id in #{user_project_ids} and act_type in #{project_types})" +
"or (container_type = 'Course' and container_id in #{user_course_ids} and act_type in #{course_types}) "+
"or (container_type = 'Principal' and act_type= '#{principal_types}' and container_id = #{user.id}) " +
"or (container_type = 'Blog' and act_type= 'BlogComment' and container_id in #{blog_ids})").order('updated_at desc')
=end
shield_project_ids = ShieldActivity.select("shield_id").where("container_type='User' and container_id=#{user.id} and shield_type='Project'").map(&:shield_id)
shield_course_ids = ShieldActivity.select("shield_id").where("container_type='User' and container_id=#{user.id} and shield_type='Course'").map(&:shield_id)
page = params[:page] ? params[:page] : 0
user_project_ids = (user.projects.map{|project| project.id}-shield_project_ids).empty? ? "(-1)" : "(" + (user.projects.map{|project| project.id}-shield_project_ids).join(",") + ")"
user_course_ids = (user.courses.map{|course| course.id}-shield_course_ids).empty? ? "(-1)" : "(" + (user.courses.map{|course| course.id}-shield_course_ids).join(",") + ")"
course_types = "('Message','News','HomeworkCommon','Poll','Course')"
project_types = "('Message','Issue','ProjectCreateInfo')"
principal_types = "JournalsForMessage"
watched_user_ids = User.watched_by(user.id).count == 0 ? " " : ("," + User.watched_by(user.id).map{|u| u.id.to_s }.join(','))
user_ids = "(" + user.id.to_s + watched_user_ids + ")"
watched_user_blog_ids = Blog.select("id").where("author_id in #{user_ids}").map { |blog| blog.id}.join(",")
blog_ids = "(" + watched_user_blog_ids + ")"
activities = UserActivity.where("(container_type = 'Project' and container_id in #{user_project_ids} and act_type in #{project_types})" +
"or (container_type = 'Course' and container_id in #{user_course_ids} and act_type in #{course_types}) "+
"or (container_type = 'Principal' and act_type= '#{principal_types}' and container_id = #{user.id}) " +
"or (container_type = 'Blog' and act_type= 'BlogComment' and container_id in #{blog_ids})").order('updated_at desc')
all_count = activities.count
activities = activities.limit(10).offset(page * 10)
count = activities.count
present :data, activities, with: Mobile::Entities::Activity,user: user
present :all_count, all_count
present :count, count
present :page, page
present :status, 0
end
end
end
end
end

@ -0,0 +1,19 @@
#coding=utf-8
module Mobile
module Apis
class BlogComments< Grape::API
resources :blog_comments do
desc "get special topic"
get ':id' do
user = UserWechat.find_by_openid(params[:openid]).user
blog = BlogComment.find params[:id]
present :data, blog, with: Mobile::Entities::BlogComment,user: user
present :status, 0
end
end
end
end
end

@ -115,7 +115,7 @@ module Mobile
desc '通知评论列表'
params do
requires :token, type: String
#requires :token, type: String
requires :notice_id,type:Integer,desc:'通知id'
optional :page,type:Integer,desc:'页码'
end

@ -0,0 +1,19 @@
#coding=utf-8
module Mobile
module Apis
class Issues< Grape::API
resources :issues do
include IssuesHelper
desc "get special issuse"
get ':id' do
user = UserWechat.find_by_openid(params[:openid]).user
issue = Issue.find params[:id]
present :data, issue, with: Mobile::Entities::Issue,user: user
present :status, 0
end
end
end
end
end

@ -0,0 +1,18 @@
#coding=utf-8
module Mobile
module Apis
class JournalForMessages< Grape::API
resources :journal_for_messages do
desc "get special journal"
get ':id' do
user = UserWechat.find_by_openid(params[:openid]).user
jour = JournalsForMessage.find params[:id]
present :data, jour, with: Mobile::Entities::Jours,user: user
present :status, 0
end
end
end
end
end

@ -0,0 +1,18 @@
#coding=utf-8
module Mobile
module Apis
class Messages< Grape::API
resources :messages do
desc "get special topic"
get ':id' do
user = UserWechat.find_by_openid(params[:openid]).user
message = Message.find params[:id]
present :data, message, with: Mobile::Entities::Message,user: user
present :status, 0
end
end
end
end
end

@ -0,0 +1,105 @@
#coding=utf-8
module Mobile
module Apis
class NewComment< Grape::API
include ApplicationHelper
include ApiHelper
resources :new_comment do
desc "add a new comment"
params do
requires :type, type: String
requires :content, type: String
requires :openid, type: String
end
post ':id' do
type = params[:type]
result = 1
current_user = UserWechat.find_by_openid(params[:openid]).user
if params[:content]!="" && current_user
case type
when "HomeworkCommon"
homework_common = HomeworkCommon.find(params[:id])
feedback = HomeworkCommon.add_homework_jour(current_user, params[:content], params[:id])
if (feedback.errors.empty?)
homework_common.update_column(:updated_at, Time.now)
result = 2
end
when "News"
news = News.find(params[:id])
comment = Comment.new
comment.comments = params[:content]
comment.author = current_user
if news.comments << comment
result = 2
end
when "Message"
message = Message.find(params[:id])
board = Board.find(message.board_id)
topic = message.root
reply = Message.new
reply.author = current_user
reply.board = board
reply.content = params[:content]
reply.parent_id = params[:id]
reply.subject = "RE: #{topic.subject}"
if topic.children << reply
result = 2
end
when "JournalsForMessage"
jour = JournalsForMessage.find params[:id]
parent_id = params[:id]
author_id = current_user.id
reply_user_id = jour.user_id
reply_id = params[:id]
content = params[:content]
options = {:user_id => author_id,
:status => true,
:m_parent_id => parent_id,
:m_reply_id => reply_id,
:reply_id => reply_user_id,
:notes => content,
:is_readed => false}
jfm = jour.user.add_jour(nil, nil, nil, options)
if jfm.errors.empty?
(JournalsForMessage.find parent_id).update_attribute(:updated_on,Time.now)
result = 2
end
when 'Issue'
issue = Issue.find params[:id]
is_jour = Journal.new
is_jour.user_id = current_user.id
is_jour.notes = params[:content]
is_jour.journalized = issue
if is_jour.save
result = 2
end
when 'BlogComment'
blog = BlogComment.find(params[:id]).root
blogComment = BlogComment.new
blogComment.author = current_user
blogComment.blog = blog.blog
blogComment.content = params[:content]
blogComment.title = "RE: #{blog.title}"
if blog.children << blogComment
result = 2
end
end
if result == 2
update_course_activity_api(type,params[:id])
update_user_activity_api(type,params[:id])
update_org_activity_api(type,params[:id])
update_forge_activity_api(type,params[:id])
update_principal_activity_api(type,params[:id])
end
else
result = 3
end
present :result, result
present :status, 0
end
end
end
end
end

@ -0,0 +1,18 @@
#coding=utf-8
module Mobile
module Apis
class Newss< Grape::API
resources :newss do
desc "get special news"
get ':id' do
user = UserWechat.find_by_openid(params[:openid]).user
news = News.find params[:id]
present :data, news, with: Mobile::Entities::News,user: user
present :status, 0
end
end
end
end
end

@ -0,0 +1,41 @@
#coding=utf-8
module Mobile
module Apis
class Praise< Grape::API
include ApiHelper
resources :praise do
desc "praise an activity"
params do
requires :type, type: String
requires :openid, type: String
end
post ':id' do
obj_id = params[:id]
obj_type = params[:type]
user = UserWechat.find_by_openid(params[:openid]).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)
obj = PraiseTreadCache.where("object_id=? and object_type=?",obj_id,obj_type.to_s).first
num = get_activity_praise_num(obj) if !obj.blank?
else
pts.destroy if !pts.blank?
#再更新praise_tread_cache表 使相应的记录减1 当为0时删除
ptc = PraiseTreadCache.where("object_id=? and object_type=?",obj_id,obj_type.to_s).first
ptc.praise_minus(1) if !ptc.blank?
if ptc.praise_num == 0
ptc.delete
end
obj = PraiseTreadCache.where("object_id=? and object_type=?",obj_id,obj_type.to_s).first
num = !obj.blank? ? get_activity_praise_num(obj) : 0
end
present :data, num
present :status, 0
end
end
end
end
end

@ -0,0 +1,18 @@
#coding=utf-8
module Mobile
module Apis
class Whomeworks< Grape::API
resources :whomeworks do
desc "get one homework"
get ':id' do
user = UserWechat.find_by_openid(params[:openid]).user
homework = HomeworkCommon.find params[:id]
present :data, homework, with: Mobile::Entities::Whomework,user: user
present :status, 0
end
end
end
end
end

@ -0,0 +1,146 @@
# encoding: utf-8
module Mobile
module Entities
class Activity <Grape::Entity
include ApplicationHelper
include ApiHelper
def self.act_expose(f)
expose f do |ac,opt|
if ac.is_a?(Hash) && ac.key?(f)
ac[f]
elsif ac.is_a?(::UserActivity)
if ac.respond_to?(f)
ac.send(f)
else
case f
when :user_act
if ac.act_type == "ProjectCreateInfo"
ac unless ac.nil?
else
ac.act unless ac.nil? || ac.act.nil?
end
when :reply_count
if ac.act_type == "HomeworkCommon"
ac.nil? || ac.act.nil? ? 0 : ac.act.journals_for_messages.count
elsif ac.act_type == "News"
ac.nil? || ac.act.nil? ? 0 : ac.act.comments.count
elsif ac.act_type == "Message" || ac.act_type == "BlogComment" || ac.act_type == "JournalsForMessage"
ac.nil? || ac.act.nil? ? 0 : ac.act.children.count
elsif ac.act_type == "Issue"
ac.nil? || ac.act.nil? ? 0 : ac.act.journals.where("notes is not null and notes != ''").count
end
when :subject
if ac.act_type == "HomeworkCommon"
ac.act.name unless ac.nil? || ac.act.nil?
elsif ac.act_type == "News" || ac.act_type == "BlogComment"
ac.act.title unless ac.nil? || ac.act.nil?
elsif ac.act_type == "Message" || ac.act_type == "Issue"
ac.act.subject unless ac.nil? || ac.act.nil?
elsif ac.act_type == "JournalsForMessage"
ac.act.private == 0 ? "留言" : "私信" unless ac.nil? || ac.act.nil?
end
when :description
if ac.act_type == "HomeworkCommon" || ac.act_type == "Issue" || ac.act_type == "News"
ac.act.description unless ac.nil? || ac.act.nil?
elsif ac.act_type == "Message" || ac.act_type == "BlogComment"
ac.act.content unless ac.nil? || ac.act.nil?
elsif ac.act_type == "JournalsForMessage"
ac.act.notes unless ac.nil? || ac.act.nil?
end
when :latest_update
time_from_now ac.updated_at unless ac.nil?
when :praise_count
if ac.act_type == "HomeworkCommon" || ac.act_type == "News" || ac.act_type == "Message" || ac.act_type == "BlogComment" || ac.act_type == "JournalsForMessage" || ac.act_type == "Issue"
ac.nil? || ac.act.nil? ? 0 : get_activity_praise_num(ac.act)
end
#when :homework_common_detail_manual
# if ac.act_type == "HomeworkCommon"
# ac.act.homework_detail_manual unless ac.nil? || ac.act.nil? || ac.act.homework_detail_manual.nil?
# end
when :course_project_name
if ac.container_type == "Course"
name = (get_course(ac.container_id)).name
name
elsif ac.container_type == "Project"
name = (get_project(ac.container_id)).name
name
elsif ac.container_type == "Blog"
"发表博客"
end
when :activity_type_name
if ac.container_type == "Course"
case ac.act_type
when "HomeworkCommon"
"课程作业"
when "News"
"课程通知"
when "Message"
"课程问答区"
when "Poll"
"课程问卷"
when "Course"
"课程"
end
elsif ac.container_type == "Project"
case ac.act_type
when "Issue"
"项目缺陷"
when "Message"
"项目讨论区"
when "ProjectCreateInfo"
"项目"
end
end
end
end
end
end
end
expose :act_type #缺陷/作业/讨论区/留言等类型
expose :act_id
expose :container_type #课程/项目/博客/个人
expose :author, using: Mobile::Entities::User do |a, opt| #用户信息
if a.is_a? ::UserActivity
if a.act_type == "ProjectCreateInfo"
get_user(get_project(a.act_id).user_id)
elsif !a.act.nil?
if a.act_type == 'Issue' || a.act_type == 'News' || a.act_type == 'Message' || a.act_type == 'BlogComment'
a.act.author
elsif a.act_type == 'HomeworkCommon' || a.act_type == 'Poll' || a.act_type == 'JournalsForMessage'
a.act.user
elsif a.act_type == 'Course'
a.act.teacher
end
end
end
end
expose :homework_common_detail , using: Mobile::Entities::Whomework do |a, opt| #作业相关信息
if a.act_type == "HomeworkCommon"
a.act
end
end
expose :issue_detail, using: Mobile::Entities::Issue do |a, opt| #缺陷信息
if a.act_type == "Issue"
a.act
end
end
act_expose :reply_count #回复数
act_expose :praise_count #点赞数
#act_expose :user_act #某个动态
act_expose :subject #标题
act_expose :description #描述
act_expose :latest_update #最新更新时间
act_expose :course_project_name #课程/项目名字
act_expose :activity_type_name #课程问答区/项目缺陷等
expose :has_praise , if: lambda { |instance, options| options[:user] } do |instance, options|
if instance.act_type == "HomeworkCommon" || instance.act_type == "News" || instance.act_type == "Message" || instance.act_type == "BlogComment" || instance.act_type == "JournalsForMessage" || instance.act_type == "Issue"
has_praise = false
current_user = options[:user]
obj = PraiseTread.where("praise_tread_object_id=? and praise_tread_object_type=? and user_id=?",instance.act_id,instance.act_type.to_s,current_user.id)
has_praise = obj.empty? ? false : true
has_praise
end
end
end
end
end

@ -0,0 +1,65 @@
module Mobile
module Entities
class BlogComment < Grape::Entity
include ApplicationHelper
include ApiHelper
def self.blog_comment_expose(f)
expose f do |u,opt|
if u.is_a?(Hash) && u.key?(f)
u[f]
elsif u.is_a?(::BlogComment)
if u.respond_to?(f)
if f == :created_at
format_time( u.send(f))
else
u.send(f)
end
else
case f
when :praise_count
get_activity_praise_num(u)
when :lasted_comment
time_from_now(u.created_at)
when :act_type
'BlogComment'
when :act_id
u.id
when :comment_count
u.children.count
end
end
end
end
end
expose :user, using: Mobile::Entities::User do |c, opt|
if c.is_a?(::BlogComment)
c.author
end
end
blog_comment_expose :act_type
blog_comment_expose :act_id
blog_comment_expose :blog_id
blog_comment_expose :title
blog_comment_expose :content
blog_comment_expose :comment_count
blog_comment_expose :created_at
blog_comment_expose :lasted_comment
blog_comment_expose :id
blog_comment_expose :praise_count
expose :blog_comment_children, using:Mobile::Entities::BlogComment do |c,opt|
if c.is_a? (::BlogComment)
c.children.reverse
end
end
expose :has_praise, if: lambda { |instance, options| options[:user] } do |instance, options|
has_praise = false
current_user = options[:user]
obj = PraiseTread.where("praise_tread_object_id=? and praise_tread_object_type=? and user_id=?",instance.id,instance.class.to_s,current_user.id)
has_praise = obj.empty? ? false : true
has_praise
end
end
end
end

@ -9,7 +9,7 @@ module Mobile
elsif f.is_a?(::Comment)
if f.respond_to?(field)
if field == :created_on
format_time(f.send(field))
time_from_now(f.send(field))
else
f.send(field)
end

@ -0,0 +1,67 @@
module Mobile
module Entities
class Issue <Grape::Entity
include ApiHelper
include Redmine::I18n
def self.issue_expose(f)
expose f do |issue, opt|
if issue.is_a?(Hash) && issue.key?(f)
issue[f]
elsif issue.is_a?(::Issue)
if issue.respond_to?(f)
if f == :created_on
format_time(issue.send(f))
else
issue.send(f)
end
else
case f
when :issue_priority
get_issue_priority_api issue.priority_id
when :issue_assigned_to
(get_user(issue.assigned_to_id)).login
when :issue_status
IssueStatus.find(issue.status_id).name
when :journals_count
issue.journals.where("notes is not null and notes != ''").count
when :project_name
issue.project.name
when :praise_count
get_activity_praise_num(issue)
when :act_type
'Issue'
when :act_id
issue.id
end
end
end
end
end
expose :subject
expose :description
expose :author, using: Mobile::Entities::User
expose :done_ratio
issue_expose :act_type
issue_expose :act_id
issue_expose :created_on
issue_expose :issue_priority
issue_expose :issue_assigned_to
issue_expose :issue_status
issue_expose :journals_count
issue_expose :project_name
issue_expose :praise_count
expose :issue_journals, using: Mobile::Entities::Journal do |f, opt|
if f.is_a?(::Issue)
f.journals.where("notes is not null and notes != ''").reverse
end
end
expose :has_praise , if: lambda { |instance, options| options[:user] } do |instance, options|
has_praise = false
current_user = options[:user]
obj = PraiseTread.where("praise_tread_object_id=? and praise_tread_object_type=? and user_id=?",instance.id,instance.class.to_s,current_user.id)
has_praise = obj.empty? ? false : true
has_praise
end
end
end
end

@ -0,0 +1,44 @@
module Mobile
module Entities
class Journal <Grape::Entity
include Redmine::I18n
=begin
include Redmine::I18n
include ApplicationHelper
include ApiHelper
include IssuesHelper
include ActionView::Helpers::TagHelper
include ActionView::Helpers::UrlHelper
=end
def self.journal_expose(f)
expose f do |journal, opt|
if journal.is_a?(Hash) && journal.key?(f)
journal[f]
elsif journal.is_a?(::Journal)
if journal.respond_to?(f)
if f == :created_on
time_from_now(journal.send(f))
else
journal.send(f)
end
else
case f
when :detail_journal
if journal.details.any?
details_to_strings(journal.details)
end
end
end
end
end
end
expose :notes
journal_expose :created_on
expose :user,using: Mobile::Entities::User do |f, opt|
f.user
end
#journal_expose :detail_journal
end
end
end

@ -3,7 +3,6 @@ module Mobile
#普通留言
class Jours < Grape::Entity
include Redmine::I18n
include WordsHelper
def self.jours_expose(field)
expose field do |f,opt|
if f.is_a?(Hash) && f.key?(field)
@ -15,13 +14,24 @@ module Mobile
f.send(field)
end
else
case f
when :course_name
f[:jour_type] == "Course" ? f.course.name : ""
case field
when :lasted_comment
time_from_now f.created_on
when :reply_count
f.children.count
when :praise_count
get_activity_praise_num(f)
when :act_type
'JournalsForMessage'
when :act_id
f.id
end
end
end
end
jours_expose :act_type
jours_expose :act_id
jours_expose :id
jours_expose :jour_type
jours_expose :jour_id
@ -29,9 +39,12 @@ module Mobile
f.user
end
jours_expose :created_on
jours_expose :lasted_comment
jours_expose :notes
jours_expose :m_reply_id
jours_expose :m_parent_id
jours_expose :reply_count
jours_expose :praise_count
expose :course,using:Mobile::Entities::Course do |f,opt|
if f.is_a?(::JournalsForMessage) && f[:jour_type] == "Course"
f.course
@ -42,9 +55,16 @@ module Mobile
end
expose :child_reply,using: Mobile::Entities::Jours do |f, opt|
if f.is_a?(::JournalsForMessage)
fetch_user_leaveWord_reply(f)
f.children.reverse
end
end
expose :has_praise , if: lambda { |instance, options| options[:user] } do |instance, options|
has_praise = false
current_user = options[:user]
obj = PraiseTread.where("praise_tread_object_id=? and praise_tread_object_type=? and user_id=?",instance.id,instance.class.to_s,current_user.id)
has_praise = obj.empty? ? false : true
has_praise
end
end
end
end

@ -15,10 +15,22 @@ module Mobile
u.send(f)
end
else
# case f
# when :xx
# #
# end
case f
when :course_project_name
if u.board.project_id == -1
u.course.name
else
u.project.name
end
when :lasted_comment
time_from_now u.created_on
when :praise_count
get_activity_praise_num(u)
when :act_type
'Message'
when :act_id
u.id
end
end
end
@ -30,16 +42,28 @@ module Mobile
c.author
end
end
message_expose :act_type
message_expose :act_id
message_expose :course_project_name
message_expose :board_id
message_expose :subject
message_expose :content
message_expose :replies_count
message_expose :praise_count
message_expose :created_on
message_expose :id
message_expose :lasted_comment
expose :message_children,using:Mobile::Entities::Message do |c,opt|
if c.is_a? (::Message)
c.children
c.children.reverse
end
end
expose :has_praise , if: lambda { |instance, options| options[:user] } do |instance, options|
has_praise = false
current_user = options[:user]
obj = PraiseTread.where("praise_tread_object_id=? and praise_tread_object_type=? and user_id=?",instance.id,instance.class.to_s,current_user.id)
has_praise = obj.empty? ? false : true
has_praise
end
end
end

@ -2,15 +2,29 @@ module Mobile
module Entities
class News < Grape::Entity
include Redmine::I18n
include ApiHelper
def self.news_expose(field)
expose field do |f,opt|
if f.is_a?(Hash) && f.key?(field)
f[field]
elsif f.is_a?(::News)
if f.respond_to?(field)
if field == :created_on
format_time(f.send(field)) if f.respond_to?(field)
format_time(f.send(field))
else
f.send(field) if f.respond_to?(field)
f.send(field)
end
else
case field
when :course_name
get_course(f.course_id).name unless f.course_id == nil
when :praise_count
get_activity_praise_num(f)
when :act_type
'News'
when :act_id
f.id
end
end
elsif f.is_a?(Hash) && !f.key?(field)
n = f[:news]
@ -40,6 +54,8 @@ module Mobile
end
obj
end
news_expose :act_type
news_expose :act_id
#作者id
news_expose :author_id
#作者名
@ -52,16 +68,24 @@ module Mobile
news_expose :created_on
#评论数量
news_expose :comments_count
news_expose :praise_count
#课程名字
news_expose :course_name
#评论
expose :comments, using: Mobile::Entities::Comment do |f, opt|
if f.is_a?(Hash) && f.key?(:comments)
f[:comments]
elsif f.is_a?(::News) && f.respond_to?(:comments)
f.send(:comments)
f.comments.reverse
end
end
expose :has_praise , if: lambda { |instance, options| options[:user] } do |instance, options|
has_praise = false
current_user = options[:user]
obj = PraiseTread.where("praise_tread_object_id=? and praise_tread_object_type=? and user_id=?",instance.id,instance.class.to_s,current_user.id)
has_praise = obj.empty? ? false : true
has_praise
end
end
end
end

@ -0,0 +1,85 @@
# encoding: utf-8
module Mobile
module Entities
class Whomework <Grape::Entity
include ApiHelper
include ApplicationHelper
include Redmine::I18n
def self.whomework_expose(f)
expose f do |wh, opt|
if wh.is_a?(Hash) && wh.key?(f)
wh[f]
elsif wh.is_a?(::HomeworkCommon)
if wh.respond_to?(f)
if f == :created_at
format_time(wh.send(f))
else
wh.send(f)
end
else
case f
when :absence_penalty
wh.nil? || wh.homework_detail_manual.nil? ? 0 : wh.homework_detail_manual.absence_penalty
when :evaluation_start
wh.nil? || wh.homework_detail_manual.nil? ? nil : convert_to_time(wh.homework_detail_manual.evaluation_start, 0)
when :evaluation_end
wh.nil? || wh.homework_detail_manual.nil? ? nil : convert_to_time(wh.homework_detail_manual.evaluation_end, 1)
when :praise_count
get_activity_praise_num(wh)
when :whomework_journal_count
wh.journals_for_messages.count
when :course_name
wh.course.name
when :act_type
'HomeworkCommon'
when :act_id
wh.id
end
end
end
end
end
expose :author, using: Mobile::Entities::User do |w, opt|
if w.is_a?(::HomeworkCommon)
w.user
end
end
expose :current_user, using: Mobile::Entities::User do |w, opt|
current_user
end
expose :name
expose :description
expose :publish_time
expose :end_time
expose :homework_type
expose :late_penalty
expose :course_id
expose :anonymous_comment
expose :quotes
expose :is_open
whomework_expose :act_type
whomework_expose :act_id
whomework_expose :course_name
whomework_expose :created_at
whomework_expose :absence_penalty
whomework_expose :evaluation_start
whomework_expose :evaluation_end
whomework_expose :praise_count
whomework_expose :whomework_journal_count
expose :journals_for_messages, using: Mobile::Entities::Jours do |f, opt|
#f[:journals_for_messages] if f.is_a?(Hash) && f.key?(:journals_for_messages)
if f.is_a?(::HomeworkCommon)
f.journals_for_messages.reverse
end
end
expose :has_praise , if: lambda { |instance, options| options[:user] } do |instance, options|
has_praise = false
current_user = options[:user]
obj = PraiseTread.where("praise_tread_object_id=? and praise_tread_object_type=? and user_id=?",instance.id,instance.class.to_s,current_user.id)
has_praise = obj.empty? ? false : true
has_praise
end
end
end
end

@ -7,7 +7,8 @@ module Mobile
@app.call(@env)
rescue =>e
message = {status: 1, message: e.message }.to_json
puts(e.backtrace.join("\n")) if Rails.env.development?
Rails.logger.error e.inspect
Rails.logger.error e.backtrace.join("\n")
status = 200
headers = { 'Content-Type' => content_type }
Rack::Response.new([message], status, headers).finish

@ -660,8 +660,10 @@ class AttachmentsController < ApplicationController
end
def has_login
unless @attachment && @attachment.container_type == "Organization"
unless @attachment && @attachment.container_type == "PhoneAppVersion"
render_403 if !User.current.logged? && !(@attachment.container_type == 'OrgSubfield' && @attachment.container.organization.allow_guest_download) && !(@attachment.container_type == 'OrgDocumentComment' && @attachment.container.organization.allow_guest_download)
end
end
end
end

@ -79,8 +79,8 @@ class OrganizationsController < ApplicationController
if @organization.show_mode == 1 && params[:org_subfield_id].nil? && params[:list] .nil?
if @organization.is_public? || User.current.admin? || User.current.member_of_org?(@organization)
# REDO:时间紧,暂时先这样
@org_logo_attchment = Attachment.where("container_id =? and container_type =? and attachtype =?", @organization, "Organization", 0).order("created_on desc").first
@org_banner_attchment = Attachment.where("container_id =? and container_type =? and attachtype =?", @organization, "Organization", 1).order("created_on desc").first
@org_logo_attchment = Attachment.find_by_sql("SELECT * from attachments WHERE container_id = #{@organization.id} and container_type = 'Organization' and attachtype = 0 and filename REGEXP '(.jpg|.png|.bmp|.gif|.jpeg)' ORDER BY created_on desc limit 1").first
@org_banner_attchment = Attachment.find_by_sql("SELECT * from attachments WHERE container_id = #{@organization.id} and container_type = 'Organization' and attachtype = 1 and filename REGEXP '(.jpg|.png|.bmp|.gif|.jpeg)' ORDER BY created_on desc limit 1").first
@subfield_content = @organization.org_subfields.order("priority")
@organization = Organization.find(params[:id])
@ -352,7 +352,7 @@ class OrganizationsController < ApplicationController
if !params[:name].nil?
condition = "%#{params[:name].strip}%".gsub(" ","")
end
sql = "select courses.* from courses inner join members on courses.id = members.course_id where members.user_id = #{User.current.id} and courses.name like '#{condition}'"+
sql = "select courses.* from courses inner join members on courses.id = members.course_id where members.user_id = #{User.current.id} and courses.is_public = 1 and courses.name like '#{condition}'"+
"and courses.id not in (select distinct org_courses.course_id from org_courses where org_courses.organization_id = #{@organization.id}) and courses.is_delete=0"
#user_courses = Course.find_by_sql(sql)
@courses = Course.find_by_sql(sql)
@ -396,7 +396,7 @@ class OrganizationsController < ApplicationController
if !params[:name].nil?
condition = "%#{params[:name].strip}%".gsub(" ","")
end
sql = "select projects.* from projects inner join members on projects.id = members.project_id where members.user_id = #{User.current.id} and projects.status != 9 and projects.name like '#{condition}'" +
sql = "select projects.* from projects inner join members on projects.id = members.project_id where members.user_id = #{User.current.id} and projects.status != 9 and projects.is_public = 1 and projects.name like '#{condition}'" +
" and projects.id not in (select org_projects.project_id from org_projects where organization_id = #{@organization.id}) and status=1"
#user_projects = Course.find_by_sql(sql)
@projects = Course.find_by_sql(sql)

@ -450,7 +450,7 @@ class StudentWorkController < ApplicationController
stu_project.save
end
end
@homework.update_attributes(:updated_at => Time.now)
@homework.update_column(:updated_at, Time.now)
update_course_activity(@homework.class,@homework.id)
update_user_activity(@homework.class,@homework.id)
update_org_activity(@homework.class,@homework.id)

@ -836,8 +836,8 @@ class UsersController < ApplicationController
render_403
return
end
user_course_ids = User.current.courses.map { |c| c.id}
user_project_ids = User.current.projects.map {|p| p.id}
user_course_ids = User.current.courses.map { |c| c.is_delete == 0 && c.id}
user_project_ids = User.current.projects.map {|p| p.status != 9 && p.id }
# user_org_ids = User.current.organizations.map {|o| o.id}
if(params[:type].blank? || params[:type] == "1") # 我的资源
# 修正:我的资源库的话,那么应该是我上传的所有资源加上,我加入的课程、项目、组织的所有资源
@ -886,11 +886,11 @@ class UsersController < ApplicationController
def user_ref_resource_search
search = params[:search].to_s.strip.downcase
if(params[:type].blank? || params[:type] == "1") #全部
user_course_ids = User.current.courses.map { |c| c.id} #我的资源库的话,那么应该是我上传的所有资源 加上 我加入的课程的所有资源 取交集并查询
user_course_ids = User.current.courses.map { |c| c.is_delete == 0 && c.id} #我的资源库的话,那么应该是我上传的所有资源 加上 我加入的课程的所有资源 取交集并查询
@attachments = Attachment.where("((author_id = #{params[:id]} and container_type in('Project','Principal','Course','Issue','Document','Message','News','StudentWorkScore','HomewCommon')) "+
" or (container_type = 'Course' and container_id in (#{user_course_ids.empty? ? '0': user_course_ids.join(',')}))) and (filename like '%#{search}%') ").order("created_on desc")
elsif params[:type] == "2" #课程资源
user_course_ids = User.current.courses.map { |c| c.id}
user_course_ids = User.current.courses.map { |c| c.is_delete == 0 && c.id}
@attachments = Attachment.where("(author_id = #{params[:id]} and container_type = 'Course') or (container_type = 'Course' and container_id in (#{user_course_ids.empty? ? '0': user_course_ids.join(',')})) and (filename like '%#{search}%') ").order("created_on desc")
elsif params[:type] == "3" #项目资源
@attachments = Attachment.where("author_id = #{params[:id]} and container_type = 'Project' and (filename like '%#{search}%')").order("created_on desc")
@ -1579,16 +1579,14 @@ class UsersController < ApplicationController
# 上传用户资源
def user_resource_create
user_course_ids = User.current.courses.map { |c| c.id}
user_project_ids = User.current.projects.map {|p| p.id}
user_course_ids = User.current.courses.map { |c| c.is_delete == 0 && c.id}
user_project_ids = User.current.projects.map {|p| p.status != 9 && p.id }
# user_org_ids = User.current.organizations.map {|o| o.id}
@user = User.find(params[:id])
# 保存文件
attach = Attachment.attach_filesex_public(@user, params[:attachments], params[:attachment_type], is_public = true)
@order, @b_sort = params[:order] || "created_on", params[:sort] || "asc"
@score = @b_sort == "desc" ? "asc" : "desc"
user_course_ids = User.current.courses.map { |c| c.id}
user_project_ids = User.current.projects.map {|p| p.id}
# user_org_ids = User.current.organizations.map {|o| o.id}
if(params[:type].blank? || params[:type] == "1") # 我的资源
# 修正:我的资源库的话,那么应该是我上传的所有资源加上,我加入的课程、项目、组织的所有资源
@ -2467,7 +2465,7 @@ class UsersController < ApplicationController
# 获取我的资源
def get_my_resources author_id, user_course_ids, user_project_ids, order, score
attachments = Attachment.where("(author_id = #{author_id} and is_publish = 1 and container_id is not null and container_type in('Project','OrgSubfield','Principal','Course','Issue','Document','Message','News','StudentWorkScore','HomewCommon')) "+
attachments = Attachment.where("(author_id = #{author_id} and is_publish = 1 and container_id is not null and container_type in('OrgSubfield','Principal','Issue','Document','Message','News','StudentWorkScore','HomewCommon')) "+
"or (container_type = 'Course' and container_id in (#{user_course_ids.empty? ? '0': user_course_ids.join(',')}) and is_publish = 1 and container_id is not null)" +
"or (container_type = 'Project' and container_id in (#{user_project_ids.empty? ? '0': user_project_ids.join(',')}) and is_publish = 1 and container_id is not null)" ).order("#{order.nil? ? 'created_on' : order} #{score}")
end
@ -2580,8 +2578,8 @@ class UsersController < ApplicationController
end
@order, @b_sort = params[:order] || "created_on", params[:sort] || "asc"
@score = @b_sort == "desc" ? "asc" : "desc"
user_course_ids = User.current.courses.map { |c| c.id}
user_project_ids = User.current.projects.map {|p| p.id}
user_course_ids = User.current.courses.map { |c| c.is_delete == 0 && c.id}
user_project_ids = User.current.projects.map {|p| p.status != 9 && p.id }
# user_org_ids = User.current.organizations.map {|o| o.id}
if(params[:type].blank? || params[:type] == "1") # 我的资源
# 修正:我的资源库的话,那么应该是我上传的所有资源加上,我加入的课程、项目、组织的所有资源
@ -2638,8 +2636,8 @@ class UsersController < ApplicationController
@user = User.find(params[:id])
@order, @b_sort = params[:order] || "created_on", params[:sort] || "asc"
@score = @b_sort == "desc" ? "asc" : "desc"
user_course_ids = User.current.courses.map { |c| c.id}
user_project_ids = User.current.projects.map {|p| p.id} # user_org_ids = User.current.organizations.map {|o| o.id}
user_course_ids = User.current.courses.map { |c| c.is_delete == 0 && c.id}
user_project_ids = User.current.projects.map {|p| p.status != 9 && p.id } # user_org_ids = User.current.organizations.map {|o| o.id}
if(params[:type].blank? || params[:type] == "1") # 我的资源
# 修正:我的资源库的话,那么应该是我上传的所有资源加上,我加入的课程、项目、组织的所有资源
@attachments = get_my_resources(params[:id], user_course_ids, user_project_ids, @order, @score)
@ -2677,8 +2675,8 @@ class UsersController < ApplicationController
# 别人的资源库是没有权限去看的
if(params[:type].blank? || params[:type] == "1") # 我的资源
# 修正:我的资源库的话,那么应该是我上传的所有资源加上,我加入的课程、项目、组织的所有资源
user_course_ids = User.current.courses.map { |c| c.id}
user_project_ids = User.current.projects.map {|p| p.id}
user_course_ids = User.current.courses.map { |c| c.is_delete == 0 && c.id}
user_project_ids = User.current.projects.map {|p| p.status != 9 && p.id }
# user_org_ids = User.current.organizations.map {|o| o.id}
@attachments = get_my_resources_search(params[:id], user_course_ids, user_project_ids, @order, @score, search)
elsif params[:type] == "6" # 公共资源
@ -2735,6 +2733,10 @@ class UsersController < ApplicationController
attach_copied_obj.attachtype = 4
end
attach_copied_obj.save
# 附件保存成功后更新项目和课程的统计数
if params[:mul_type] == "Project"
mul_container.project_score.update_attribute(:attach_num, mul_container.project_score.attach_num + 1) unless mul_container.project_score.nil?
end
@save_message = attach_copied_obj.errors.full_messages
end
end
@ -2758,8 +2760,8 @@ class UsersController < ApplicationController
@user = User.current
@switch_search = params[:search].nil? ? " " : params[:search]
search = "%#{@switch_search.strip.downcase}%"
user_course_ids = User.current.courses.map {|c| c.id}
user_project_ids = User.current.projects.map {|p| p.id}
user_course_ids = User.current.courses.map { |c| c.is_delete == 0 && c.id}
user_project_ids = User.current.projects.map {|p| p.status != 9 && p.id }
if(params[:type].nil? || params[:type].blank? || params[:type] == "1" || params[:type] == 'all') # 全部
if params[:status] == "2"
@attachments = get_course_resources_search(params[:id], user_course_ids, @order, @score, search)

@ -0,0 +1,235 @@
#coding=utf-8
class WechatsController < ActionController::Base
wechat_responder
include ApplicationHelper
# default text responder when no other match
on :text do |request, content|
request.reply.text "您的意见已收到" # Just echo
end
# When receive 'help', will trigger this responder
on :text, with: 'help' do |request|
request.reply.text 'help content'
end
# When receive '<n>news', will match and will got count as <n> as parameter
on :text, with: /^(\d+) news$/ do |request, count|
# Wechat article can only contain max 10 items, large than 10 will dropped.
news = (1..count.to_i).each_with_object([]) { |n, memo| memo << { title: 'News title', content: "No. #{n} news content" } }
request.reply.news(news) do |article, n, index| # article is return object
article.item title: "#{index} #{n[:title]}", description: n[:content], pic_url: 'http://www.baidu.com/img/bdlogo.gif', url: 'http://www.baidu.com/'
end
end
on :event, with: 'subscribe' do |request|
default_msg(request)
end
# When unsubscribe user scan qrcode qrscene_xxxxxx to subscribe in public account
# notice user will subscribe public account at same time, so wechat won't trigger subscribe event any more
on :scan, with: 'qrscene_xxxxxx' do |request, ticket|
request.reply.text "Unsubscribe user #{request[:FromUserName]} Ticket #{ticket}"
end
# 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}"
end
# When no any on :scan responder can match subscribe user scaned scene_id
on :event, with: 'scan' do |request|
if request[:EventKey].present?
request.reply.text "event scan got EventKey #{request[:EventKey]} Ticket #{request[:Ticket]}"
end
end
# When enterprise user press menu BINDING_QR_CODE and success to scan bar code
on :scan, with: 'BINDING_QR_CODE' do |request, scan_result, scan_type|
request.reply.text "User #{request[:FromUserName]} ScanResult #{scan_result} ScanType #{scan_type}"
end
# Except QR code, wechat can also scan CODE_39 bar code in enterprise account
on :scan, with: 'BINDING_BARCODE' do |message, scan_result|
if scan_result.start_with? 'CODE_39,'
message.reply.text "User: #{message[:FromUserName]} scan barcode, result is #{scan_result.split(',')[1]}"
end
end
# When user click the menu button
on :click, with: 'BOOK_LUNCH' do |request, key|
request.reply.text "User: #{request[:FromUserName]} click #{key}"
end
# When user view URL in the menu button
on :view, with: 'http://wechat.somewhere.com/view_url' do |request, view|
request.reply.text "#{request[:FromUserName]} view #{view}"
end
# When user sent the imsage
on :image do |request|
request.reply.image(request[:MediaId]) # Echo the sent image to user
end
# When user sent the voice
on :voice do |request|
request.reply.voice(request[:MediaId]) # Echo the sent voice to user
end
# When user sent the video
on :video do |request|
nickname = wechat.user(request[:FromUserName])['nickname'] # Call wechat api to get sender nickname
request.reply.video(request[:MediaId], title: 'Echo', description: "Got #{nickname} sent video") # Echo the sent video to user
end
# When user sent location
on :location do |request|
request.reply.text("Latitude: #{message[:Latitude]} Longitude: #{message[:Longitude]} Precision: #{message[:Precision]}")
end
on :event, with: 'unsubscribe' do |request|
request.reply.success # user can not receive this message
end
# When user enter the app / agent app
on :event, with: 'enter_agent' do |request|
request.reply.text "#{request[:FromUserName]} enter agent app now"
end
# When batch job create/update user (incremental) finished.
on :batch_job, with: 'sync_user' do |request, batch_job|
request.reply.text "sync_user job #{batch_job[:JobId]} finished, return code #{batch_job[:ErrCode]}, return message #{batch_job[:ErrMsg]}"
end
# When batch job replace user (full sync) finished.
on :batch_job, with: 'replace_user' do |request, batch_job|
request.reply.text "replace_user job #{batch_job[:JobId]} finished, return code #{batch_job[:ErrCode]}, return message #{batch_job[:ErrMsg]}"
end
# When batch job invent user finished.
on :batch_job, with: 'invite_user' do |request, batch_job|
request.reply.text "invite_user job #{batch_job[:JobId]} finished, return code #{batch_job[:ErrCode]}, return message #{batch_job[:ErrMsg]}"
end
# When batch job replace department (full sync) finished.
on :batch_job, with: 'replace_party' do |request, batch_job|
request.reply.text "replace_party job #{batch_job[:JobId]} finished, return code #{batch_job[:ErrCode]}, return message #{batch_job[:ErrMsg]}"
end
# Any not match above will fail to below
on :fallback, respond: 'fallback message'
on :click, with: 'FEEDBACK' do |request, key|
request.reply.text "如有反馈问题,请直接切入至输入框,发微信给我们即可"
end
on :click, with: 'MY_NEWS' do |request, key|
default_msg(request)
end
def default_msg(request)
uw = user_binded?(request[:FromUserName])
if uw && uw.user
request.reply.text "欢迎回来, #{uw.user.show_name}"
else
sendBind(request)
end
end
def sendBind(request)
news = (1..1).each_with_object([]) { |n, memo| memo << { title: '绑定登录', content: "您还未绑定确实的用户,请先绑定." } }
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"
article.item title: "#{n[:title]}",
description: n[:content],
pic_url: 'http://wechat.trustie.net/images/trustie_logo2.png',
url: url
end
end
def get_open_id
begin
raise "非法操作, code不存在" unless params[:code]
openid = get_openid_from_code(params[:code])
raise "无法获取到openid" unless openid
render :json => {status:0, openid: openid}
rescue Exception=>e
render :json => {status: -1, msg: e.message}
end
end
def bind
begin
raise "非法操作, code不存在" unless params[:code]
openid = get_openid_from_code(params[:code])
raise "无法获取到openid" unless openid
raise "此微信号已绑定用户, 不能得复绑定" if user_binded?(openid)
user, last_login_on = User.try_to_login(params[:username], params[:password])
raise "用户名或密码错误,请重新登录" unless user
#补全用户信息
raise "此用户已经绑定了公众号" if user.user_wechat
UserWechat.create!(
openid: openid,
user: user
)
render :json => {status:0, msg: "绑定成功"}
rescue Exception=>e
render :json => {status: -1, msg: e.message}
end
end
def login
@code = params[:code] #TODO 安全性
render 'wechats/login', layout: 'base_wechat'
end
private
def get_openid_from_code(code)
url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=#{Wechat.config.appid}&secret=#{Wechat.config.secret}&code=#{code}&grant_type=authorization_code"
logger.debug url
body = URI.parse(url).read
logger.debug body
JSON.parse(body)["openid"]
end
def user_binded?(openid)
uw = UserWechat.where(openid: openid).first
end
def user_activity(user)
@user = user
shield_project_ids = ShieldActivity.where("container_type='User' and container_id=#{@user.id} and shield_type='Project'").map(&:shield_id)
shield_course_ids = ShieldActivity.where("container_type='User' and container_id=#{@user.id} and shield_type='Course'").map(&:shield_id)
@page = params[:page] ? params[:page].to_i + 1 : 0
user_project_ids = (@user.projects.visible.map{|project| project.id}-shield_project_ids).empty? ? "(-1)" : "(" + (@user.projects.visible.map{|project| project.id}-shield_project_ids).join(",") + ")"
user_course_ids = (@user.courses.visible.map{|course| course.id}-shield_course_ids).empty? ? "(-1)" : "(" + (@user.courses.visible.map{|course| course.id}-shield_course_ids).join(",") + ")"
course_types = "('Message','News','HomeworkCommon','Poll','Course')"
project_types = "('Message','Issue','ProjectCreateInfo')"
principal_types = "JournalsForMessage"
blog_ids = "("+@user.blog.id.to_s+","+((User.watched_by(@user.id).count == 0 )? '0' :User.watched_by(@user.id).map{|u| u.blog.id}.join(','))+")"
@user_activities = UserActivity.where("(container_type = 'Project' and container_id in #{user_project_ids} and act_type in #{project_types})" +
"or (container_type = 'Course' and container_id in #{user_course_ids} and act_type in #{course_types}) "+
"or (container_type = 'Principal' and act_type= '#{principal_types}' and container_id = #{@user.id}) " +
"or (container_type = 'Blog' and act_type= 'BlogComment' and container_id in #{blog_ids})").order('updated_at desc').limit(10).offset(@page * 10)
end
def process_activity(user_activity)
act= user_activity.act
case user_activity.container_type.to_s
when 'Course'
when 'Project'
case user_activity.act_type.to_s
when 'Issue'
[act.project.name.to_s+" | 项目问题", act.subject.to_s, url_to_avatar(act.author),"http://wechat.trustie.net/app.html#/issue/#{act.id}"]
end
end
end
end

@ -276,7 +276,7 @@ class WordsController < ApplicationController
ids = params[:asset_id].split(',')
update_kindeditor_assets_owner ids,feedback[:id],OwnerTypeHelper::JOURNALSFORMESSAGE
end
@homework_common.update_attributes(:updated_at => Time.now)
@homework_common.update_column(:updated_at, Time.now)
update_course_activity(@homework_common.class,@homework_common.id)
update_user_activity(@homework_common.class,@homework_common.id)
update_org_activity(@homework_common.class,@homework_common.id)

@ -201,5 +201,288 @@ module ApiHelper
end
#日期转换为时间
def convert_to_time date, num
if num == 0
date = date.to_s + " 00:00"
elsif num == 1
date = date.to_s + " 23:59"
end
return date
end
#获取用户
def get_user user_id
user = User.find user_id
user
end
#获取项目
def get_project project_id
project = Project.find project_id
project
end
#获取课程
def get_course course_id
course = Course.find course_id
course
end
#获取点赞数
def get_activity_praise_num(object)
obj_type = object.class
obj_id = object.id
record = PraiseTreadCache.find_by_object_id_and_object_type(obj_id,obj_type)
if record
return ((record.praise_num.nil? ? 0 : record.praise_num.to_i)-(record.tread_num.nil? ? 0 : record.tread_num.to_i))
else
return 0
end
end
#获取缺陷的优先级
def get_issue_priority_api value
issuetype = ""
if value == 4
issuetype = "紧急"
elsif value == 2
issuetype = "正常"
elsif value == 3
issuetype = ""
elsif value == 1
issuetype = ""
else
issuetype = "立刻"
end
end
def jdetails_to_strings(details, no_html=false, options={})
options[:only_path] = (options[:only_path] == false ? false : true)
options[:token] = options[:token] if options[:token]
strings = []
values_by_field = {}
details.each do |detail|
if detail.property == 'cf'
field_id = detail.prop_key
field = CustomField.find_by_id(field_id)
if field && field.multiple?
values_by_field[field_id] ||= {:added => [], :deleted => []}
if detail.old_value
values_by_field[field_id][:deleted] << detail.old_value
end
if detail.value
values_by_field[field_id][:added] << detail.value
end
next
end
end
strings << jshow_detail(detail, no_html, options)
end
values_by_field.each do |field_id, changes|
detail = JournalDetail.new(:property => 'cf', :prop_key => field_id)
if changes[:added].any?
detail.value = changes[:added]
strings << jshow_detail(detail, no_html, options)
elsif changes[:deleted].any?
detail.old_value = changes[:deleted]
strings << jshow_detail(detail, no_html, options)
end
end
strings
end
# Returns the textual representation of a single journal detail
def jshow_detail(detail, no_html=false, options={})
multiple = false
case detail.property
when 'attr'
field = detail.prop_key.to_s.gsub(/\_id$/, "")
label = l(("field_" + field).to_sym)
case detail.prop_key
when 'due_date', 'start_date'
value = format_date(detail.value.to_date) if detail.value
old_value = format_date(detail.old_value.to_date) if detail.old_value
when 'project_id', 'status_id', 'tracker_id', 'assigned_to_id',
'priority_id', 'category_id', 'fixed_version_id'
value = find_name_by_reflection(field, detail.value)
old_value = find_name_by_reflection(field, detail.old_value)
when 'estimated_hours'
value = "%0.02f" % detail.value.to_f unless detail.value.blank?
old_value = "%0.02f" % detail.old_value.to_f unless detail.old_value.blank?
when 'parent_id'
label = l(:field_parent_issue)
value = "##{detail.value}" unless detail.value.blank?
old_value = "##{detail.old_value}" unless detail.old_value.blank?
when 'is_private'
value = l(detail.value == "0" ? :general_text_No : :general_text_Yes) unless detail.value.blank?
old_value = l(detail.old_value == "0" ? :general_text_No : :general_text_Yes) unless detail.old_value.blank?
end
when 'cf'
custom_field = CustomField.find_by_id(detail.prop_key)
if custom_field
multiple = custom_field.multiple?
label = custom_field.name
value = format_value(detail.value, custom_field.field_format) if detail.value
old_value = format_value(detail.old_value, custom_field.field_format) if detail.old_value
end
when 'attachment'
label = l(:label_attachment)
end
call_hook(:helper_issues_show_detail_after_setting,
{:detail => detail, :label => label, :value => value, :old_value => old_value })
label ||= detail.prop_key
value ||= detail.value
old_value ||= detail.old_value
unless no_html
label = content_tag('strong', label)
old_value = content_tag("i", old_value) if detail.old_value
old_value = content_tag("del", old_value) if detail.old_value and detail.value.blank?
if detail.property == 'attachment' && !value.blank? && atta = Attachment.find_by_id(detail.prop_key)
# Link to the attachment if it has not been removed
if options[:token].nil?
value = atta.filename
else
value = atta.filename
end
# 放大镜搜索功能
# if options[:only_path] != false && atta.is_text?
# value += link_to(
# image_tag('magnifier.png'),
# :controller => 'attachments', :action => 'show',
# :id => atta, :filename => atta.filename
# )
# end
else
value = content_tag("i", value) if value
end
end
# 缺陷更新结果在消息中显示样式
if no_html == "message"
label = content_tag(:span, label, :class => "issue_update_message")
old_value = content_tag("span", old_value) if detail.old_value
old_value = content_tag("del", old_value) if detail.old_value and detail.value.blank?
if detail.property == 'attachment' && !value.blank? && atta = Attachment.find_by_id(detail.prop_key)
# Link to the attachment if it has not been removed
if options[:token].nil?
value = atta.filename
else
value = atta.filename
end
else
value = content_tag(:span, value, :class => "issue_update_message_value") if value
end
end
if detail.property == 'attr' && detail.prop_key == 'description'
s = l(:text_journal_changed_no_detail, :label => label)
unless no_html
diff_link = link_to l(:label_diff),
{:controller => 'journals', :action => 'diff', :id => detail.journal_id,
:detail_id => detail.id, :only_path => options[:only_path]},
:title => l(:label_view_diff)
s << " (#{ diff_link })"
end
s.html_safe
elsif detail.value.present?
case detail.property
when 'attr', 'cf'
if detail.old_value.present?
l(:text_journal_changed, :label => label, :old => old_value, :new => value).html_safe
elsif multiple
l(:text_journal_added, :label => label, :value => value).html_safe
else
l(:text_journal_set_to, :label => label, :value => value).html_safe
end
when 'attachment'
l(:text_journal_added, :label => label, :value => value).html_safe
end
else
l(:text_journal_deleted, :label => label, :old => old_value).html_safe
end
end
#课程动态的更新
def update_course_activity_api type, id
course_activity = CourseActivity.where("course_act_type=? and course_act_id =?", type.to_s, id.to_i).first
if course_activity
course_activity.updated_at = Time.now
course_activity.save
end
end
#首页动态更新
def update_user_activity_api type, id
user_activity = UserActivity.where("act_type=? and act_id =?", type.to_s, id.to_i).first
if user_activity
user_activity.updated_at = Time.now
user_activity.save
end
end
#项目动态更新
def update_forge_activity_api type, id
forge_activity = ForgeActivity.where("forge_act_type=? and forge_act_id=?", type.to_s, id.to_i).first
if forge_activity
forge_activity.updated_at = Time.now
forge_activity.save
end
end
#组织动态更新
def update_org_activity_api type , id
org_activity = OrgActivity.where("org_act_type=? and org_act_id =?", type.to_s, id.to_i).first
if org_activity
org_activity.updated_at = Time.now
org_activity.save
end
end
#个人动态更新
def update_principal_activity_api type, id
principal_activity = PrincipalActivity.where("principal_act_type=? and principal_act_id =?", type.to_s, id.to_i).first
if principal_activity
principal_activity.updated_at = Time.now
principal_activity.save
end
end
#赞/取消赞
def praise_or_cancel(type,id,user,flag)
unless id.nil? and type.nil?
#首先创建或更新praise_tread 表
pt = PraiseTread.new
pt.user_id = user.id
pt.praise_tread_object_id = id.to_i
pt.praise_tread_object_type = type
pt.praise_or_tread = flag
pt.save
# end
#再创建或更新praise_tread_cache表
#@ptc = PraiseTreadCache.find_by_object_id_and_object_type(id,type)
ptc = PraiseTreadCache.where("object_id = ? and object_type = ?",id.to_i,type).first
ptc = ptc.nil? ? PraiseTreadCache.new : ptc
ptc.object_id = id.to_i
ptc.object_type = type
ptc.save
ptc.praise_plus(flag,1)
end
end
def praise_plus(flag,num)
case flag
when 1
self.update_attribute(:praise_num, self.praise_num.to_i + num)
end
end
def praise_minus(num)
self.update_attribute(:praise_num, self.praise_num.to_i - num)
end
end

@ -2104,6 +2104,8 @@ module ApplicationHelper
attachment.container.board.course
course = attachment.container.board.course
candown= User.current.member_of_course?(course) || (course.is_public==1 && attachment.is_public == 1)
elsif attachment.container.class.to_s=="Organization"
candown = true
elsif attachment.container.class.to_s=="HomeworkAttach"
candown = true
elsif attachment.container.class.to_s=="StudentWorksScore"

@ -19,7 +19,7 @@
module IssuesHelper
include ApplicationHelper
include TagsHelper
def issue_list(issues, &block)
ancestors = []
issues.each do |issue|

@ -1,5 +1,8 @@
#encoding: utf-8
class BlogComment < ActiveRecord::Base
# attr_accessible :title, :body
require 'net/http'
require 'json'
include Redmine::SafeAttributes
belongs_to :blog
belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
@ -18,7 +21,7 @@ class BlogComment < ActiveRecord::Base
after_save :add_user_activity
after_update :update_activity
after_create :update_parent_time
after_create :update_parent_time, :blog_wechat_message
before_destroy :destroy_user_activity
scope :like, lambda {|arg|
@ -72,4 +75,51 @@ class BlogComment < ActiveRecord::Base
end
def project
end
#博客回复微信模板消息
def blog_wechat_message
# 发布博客
unless self.parent_id.nil?
uw = UserWechat.where(user_id: self.parent.author_id).first
#unless uw.nil? && self.parent.author_id != User.current.id
unless uw.nil?
data = {
touser:uw.openid,
template_id:"A_3f5v90-zK73V9Kijm-paDkl9S-NuM8Cf-1UJi92_c",
url:"http://www.trustie.net/",
topcolor:"#FF0000",
data:{
first: {
value:"您的博客有新回复了",
color:"#173177"
},
keyword1:{
value:self.author.try(:realname),
color:"#173177"
},
keyword2:{
value:format_time(self.created_at),
color:"#173177"
},
keyword3:{
value:self.content.html_safe,
color:"#173177"
},
remark:{
value:"具体内容请点击详情查看网站",
color:"#173177"
}
}
}
logger.info "start send template message: #{data}"
begin
req = Wechat.api.template_message_send Wechat::Message.to(uw.openid).template(data)
rescue Exception => e
logger.error "[blog_comment] ===> #{e}"
end
logger.info "send over. #{req}"
end
end
end
end

@ -1,7 +1,10 @@
#encoding: utf-8
#老师布置的作业表
#homework_type: 0:普通作业;1:匿评作业;2:编程作业
class HomeworkCommon < ActiveRecord::Base
# attr_accessible :name, :user_id, :description, :publish_time, :end_time, :homework_type, :late_penalty, :course_id
require 'net/http'
require 'json'
include Redmine::SafeAttributes
include ApplicationHelper
@ -26,7 +29,7 @@ class HomeworkCommon < ActiveRecord::Base
:author => :author,
:url => Proc.new {|o| {:controller => 'student_work', :action => 'index', :homework => o.id}}
after_create :act_as_activity, :send_mail, :act_as_course_message
after_update :update_activity
after_update :update_activity, :wechat_message
after_save :act_as_course_activity
after_destroy :delete_kindeditor_assets
@ -98,6 +101,50 @@ class HomeworkCommon < ActiveRecord::Base
jfm
end
#修改作业后发送微信模板消息
def wechat_message
self.course.members.each do |member|
uw = UserWechat.where("user_id=?", member.user_id).first
unless uw.nil?
data = {
touser:uw.openid,
template_id:"3e5Dj2GIx8MOcMyRKpTUEQnM7Tg0ASSCNc01NS9HCGI",
url:"http://www.trustie.net/",
topcolor:"#FF0000",
data:{
first: {
value:"您的作业已被修改",
color:"#173177"
},
keyword1:{
value:self.course.name,
color:"#173177"
},
keyword2:{
value:self.name,
color:"#173177"
},
keyword3:{
value:self.end_time.to_s + "23:59:59",
color:"#173177"
},
remark:{
value:"具体内容请点击详情查看网站",
color:"#173177"
}
}
}
logger.info "start send template message: #{data}"
begin
req = Wechat.api.template_message_send Wechat::Message.to(uw.openid).template(data)
rescue Exception => e
logger.error "[homework_common] ===> #{e}"
end
logger.info "send over. #{req}"
end
end
end
delegate :language_name, :language, :to => :homework_detail_programing
end

@ -1,3 +1,4 @@
#coding=utf-8
# Redmine - project management software
# Copyright (C) 2006-2013 Jean-Philippe Lang
#
@ -16,6 +17,8 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
class Journal < ActiveRecord::Base
require 'net/http'
require 'json'
include UserScoreHelper
belongs_to :journalized, :polymorphic => true,:touch => true
# added as a quick fix to allow eager loading of the polymorphic association
@ -52,7 +55,7 @@ class Journal < ActiveRecord::Base
# fq
after_save :act_as_activity,:be_user_score, :act_as_forge_message, act_as_at_message(:notes, :user_id)
after_create :update_issue_time
after_create :issue_wechat_message
# end
#after_destroy :down_user_score
#before_save :be_user_score
@ -233,4 +236,47 @@ class Journal < ActiveRecord::Base
forge_activity.update_attribute(:created_at, self.created_on) unless forge_activity.nil?
end
end
#缺陷回复微信模板消息
def issue_wechat_message
uw = UserWechat.where(user_id: self.issue.author_id).first
#unless uw.nil? && self.issue.author_id != User.current.id
unless uw.nil?
data = {
touser:uw.openid,
template_id:"A_3f5v90-zK73V9Kijm-paDkl9S-NuM8Cf-1UJi92_c",
url:"http://www.trustie.net/",
topcolor:"#FF0000",
data:{
first: {
value:"您的缺陷有新回复了",
color:"#173177"
},
keyword1:{
value:self.user.try(:realname),
color:"#173177"
},
keyword2:{
value:format_time(self.created_on),
color:"#173177"
},
keyword3:{
value:self.notes.html_safe,
color:"#173177"
},
remark:{
value:"具体内容请点击详情查看网站",
color:"#173177"
}
}
}
logger.info "start send template message: #{data}"
begin
req = Wechat.api.template_message_send Wechat::Message.to(uw.openid).template(data)
rescue Exception => e
logger.error "[journal] ===> #{e}"
end
logger.info "send over. #{req}"
end
end
end

@ -1,7 +1,9 @@
# fq
#coding=utf-8
# 数据库字段中带有m前缀和is_readed是二次开发添加之前的字段基本复用
# 注意reply_id 是提到人的id不是留言id, Base中叫做 at_user
class JournalsForMessage < ActiveRecord::Base
require 'net/http'
require 'json'
include Redmine::SafeAttributes
include UserScoreHelper
include ApplicationHelper
@ -253,6 +255,9 @@ class JournalsForMessage < ActiveRecord::Base
self.course_messages << CourseMessage.new(:user_id => r, :course_id => self.jour.id, :viewed => false)
end
end
if self.jour_type == 'HomeworkCommon'
journal_wechat_message '您的作业有新回复了',self.jour.user_id
end
end
@ -264,6 +269,7 @@ class JournalsForMessage < ActiveRecord::Base
if self.reply_id == 0
if self.user_id != self.jour_id # 过滤自己给自己的留言消息
receivers << self.jour
journal_wechat_message "您有新留言了",self.jour_id
end
else # 留言回复
reply_to = User.find(self.reply_id)
@ -273,6 +279,7 @@ class JournalsForMessage < ActiveRecord::Base
if self.user_id != self.parent.jour_id && self.reply_id != self.parent.jour_id # 给东家发信息,如果回复的对象是东家则不发
receivers << self.parent.jour
end
journal_wechat_message "您的留言有新回复了",self.reply_id
end
receivers.each do |r|
self.user_feedback_messages << UserFeedbackMessage.new(:user_id => r.id, :journals_for_message_id => self.id, :journals_for_message_type => "Principal", :viewed => false)
@ -299,4 +306,47 @@ class JournalsForMessage < ActiveRecord::Base
end
end
#微信模板消息
def journal_wechat_message type, user_id
uw = UserWechat.where(user_id: user_id).first
#unless uw.nil? && self.reply_id != User.current.id
unless uw.nil?
data = {
touser:uw.openid,
template_id:"A_3f5v90-zK73V9Kijm-paDkl9S-NuM8Cf-1UJi92_c",
url:"http://www.trustie.net/",
topcolor:"#FF0000",
data:{
first: {
value:type,
color:"#173177"
},
keyword1:{
value:self.user.try(:realname),
color:"#173177"
},
keyword2:{
value:format_time(self.created_on),
color:"#173177"
},
keyword3:{
value:self.notes.html_safe,
color:"#173177"
},
remark:{
value:"具体内容请点击详情查看网站",
color:"#173177"
}
}
}
logger.info "start send template message: #{data}"
begin
req = Wechat.api.template_message_send Wechat::Message.to(uw.openid).template(data)
rescue Exception => e
logger.error "[journal_for_message] ===> #{e}"
end
logger.info "send over. #{req}"
end
end
end

@ -1,3 +1,4 @@
#encoding: utf-8
# Redmine - project management software
# Copyright (C) 2006-2013 Jean-Philippe Lang
#
@ -16,6 +17,8 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
class Mailer < ActionMailer::Base
require 'net/http'
require 'json'
layout 'mailer'
helper :application
helper :issues
@ -626,6 +629,7 @@ class Mailer < ActionMailer::Base
# attachments_added(attachments) => Mail::Message object
# Mailer.attachments_added(attachments).deliver => sends an email to the project's recipients
def homework_added(homework_common)
logger.info "homework added"
@homework_common = homework_common
@author = homework_common.user
@homework_common_url = url_for(:controller => "homework_common", :action =>"index", :homework => @homework_common.id)
@ -638,6 +642,9 @@ class Mailer < ActionMailer::Base
mail :to => recipients,
:subject => "[ #{l(:label_user_homework)} : #{homework_common.name} #{l(:label_memo_create_succ)}]",
:filter => true
@homework_common.course.members.each do |member|
mail_wechat_message member.user_id, "3e5Dj2GIx8MOcMyRKpTUEQnM7Tg0ASSCNc01NS9HCGI", "您的课程有新作业了", @homework_common.course.name, @homework_common.name, @homework_common.end_time.to_s + " 23:59:59"
end
end
# Builds a Mail::Message object used to email recipients of a news' project when a news item is added.
@ -703,6 +710,8 @@ class Mailer < ActionMailer::Base
mail :to => recipients,
:subject => "[#{news.course.name}] #{l(:label_news)}: #{news.title}",
:filter => true
mail_wechat_message news.author_id, "A_3f5v90-zK73V9Kijm-paDkl9S-NuM8Cf-1UJi92_c", "您的课程通知有新回复了", @author.try(:realname), format_time(comment.created_on), comment.comments.html_safe
end
end
@ -727,6 +736,13 @@ class Mailer < ActionMailer::Base
:cc => cc,
:subject => "[#{message.board.project.name} - #{message.board.name} - msg#{message.root.id}] #{message.subject}",
:filter => true
if message.parent_id == nil
message.project.members.each do |member|
mail_wechat_message member.user_id, "oKzFCdk7bsIHnGbscA__N8LPQrBkUShvpjV3-kuwWDQ", "项目讨论区有新帖子发布了", message.subject, @author.try(:realname), format_time(message.created_on)
end
else
mail_wechat_message message.parent.author_id, "A_3f5v90-zK73V9Kijm-paDkl9S-NuM8Cf-1UJi92_c", "您的帖子有新回复了", @author.try(:realname), format_time(message.created_on), message.content.html_safe
end
elsif message.course
redmine_headers 'Course' => message.course.id,
'Topic-Id' => (message.parent_id || message.id)
@ -742,6 +758,13 @@ class Mailer < ActionMailer::Base
:cc => cc,
:subject => "[#{message.board.course.name} - #{message.board.name} - msg#{message.root.id}] #{message.subject}",
:filter => true
if message.parent_id == nil
message.course.members.each do |member|
mail_wechat_message member.user_id, "oKzFCdk7bsIHnGbscA__N8LPQrBkUShvpjV3-kuwWDQ", "课程问答区有新帖子发布了", message.subject, @author.try(:realname), format_time(message.created_on)
end
else
mail_wechat_message message.parent.author_id, "A_3f5v90-zK73V9Kijm-paDkl9S-NuM8Cf-1UJi92_c", "您的帖子有新回复了", @author.try(:realname), format_time(message.created_on), message.content.html_safe
end
end
end
@ -1097,4 +1120,47 @@ class Mailer < ActionMailer::Base
return newpass
end
#微信模板消息
def mail_wechat_message user_id, template_id, first, key1, key2, key3, remark="具体内容请点击详情查看网站"
uw = UserWechat.where(user_id: user_id).first
logger.info "mail_wechat_message #{user_id} #{uw}"
unless uw.nil?
data = {
touser:uw.openid,
template_id:template_id,
url:"http://www.trustie.net/",
topcolor:"#FF0000",
data:{
first: {
value:first,
color:"#173177"
},
keyword1:{
value:key1,
color:"#173177"
},
keyword2:{
value:key2,
color:"#173177"
},
keyword3:{
value:key3,
color:"#173177"
},
remark:{
value:remark,
color:"#173177"
}
}
}
logger.info "start send template message: #{data}"
begin
req = Wechat.api.template_message_send Wechat::Message.to(uw.openid).template(data)
rescue Exception => e
logger.error "[mailer] ===> #{e}"
end
logger.info "send over. #{req}"
end
end
end

@ -179,6 +179,7 @@ class User < Principal
#####
has_many :shares ,:dependent => :destroy
has_one :user_wechat
# add by zjc
has_one :level, :class_name => 'UserLevels', :dependent => :destroy
@ -1181,17 +1182,17 @@ class User < Principal
def create_user_ealasticsearch_index
if self.id != 2 && self.id != 4
self.__elasticsearch__.index_document
self.__elasticsearch__.index_document if Rails.env.production?
end
end
def update_user_ealasticsearch_index
if self.id != 2 && self.id != 4
self.__elasticsearch__.update_document
self.__elasticsearch__.update_document if Rails.env.production?
end
end
def delete_user_ealasticsearch_index
if self.id != 2 && self.id != 4
self.__elasticsearch__.delete_document
self.__elasticsearch__.delete_document if Rails.env.production?
end
end

@ -0,0 +1,6 @@
class UserWechat < ActiveRecord::Base
attr_accessible :subscribe, :openid, :nickname, :sex, :language, :city, :province, :country,
:headimgurl, :subscribe_time, :unionid, :remark, :groupid, :user, :user_id
belongs_to :user
end

@ -23,10 +23,8 @@
<!--<input type="submit" name="" value="上传文件" class="f_l ml10" style="width:80px; height:26px;">-->
<span id="upload_file_count<%=container.id %>">
<%= l(:label_no_file_uploaded)%>
建议上传高度不超过52px的图片
</span>
(<%= l(:label_max_size) %>:<%= number_to_human_size(Setting.attachment_max_size.to_i.kilobytes) %>)
<p style="padding-left: 68px;">建议上传高度不超过52px的图片</p>
<div class="cl"></div>
<div>
<span id="attachments_fields<%= container.id %>" data-containerid="<%= container.id %>" xmlns="http://www.w3.org/1999/html">

@ -0,0 +1,32 @@
<span class="add_attachment" data-containerid="<%= container.id %>">
<button name="button" class="sub_btn" onclick="_file<%=container.id %>.click()" onmouseover="this.focus()" style="<%= ie8? ? 'display:none' : ''%>" type="button" ><%= l(:label_browse_org) %></button>
<%= file_field_tag 'attachments[dummy][file]',
:id => "_file#{container.id}",
:class => ie8? ? '':'file_selector',
:multiple => true,
:onchange => "addInputFiles_board(this, '#{container.id}','"+"submit_resource"+"');",
:style => ie8? ? '': 'display:none',
:data => {
:max_file_size => Setting.attachment_max_size.to_i.kilobytes,
:max_file_size_message => l(:error_attachment_too_big, :max_size => number_to_human_size(Setting.attachment_max_size.to_i.kilobytes)),
:max_concurrent_uploads => Redmine::Configuration['max_concurrent_ajax_uploads'].to_i,
:upload_path => uploads_path(:format => 'js'),
:description_placeholder => l(:label_optional_description),
:field_is_public => l(:field_is_public),
:are_you_sure => l(:text_are_you_sure),
:file_count => l(:label_file_count),
:delete_all_files => l(:text_are_you_sure_all),
:lebel_file_uploding => l(:lebel_file_uploding),
:containerid => "#{container.id}"
} %>
</span>
<!--<input type="submit" name="" value="上传文件" class="f_l ml10" style="width:80px; height:26px;">-->
<span id="upload_file_count<%=container.id %>">
建议上传 长度:1920px 高度:313px 的图片
</span>
<div class="cl"></div>
<div>
<span id="attachments_fields<%= container.id %>" data-containerid="<%= container.id %>" xmlns="http://www.w3.org/1999/html">
</span>
</div>

@ -0,0 +1,25 @@
<div id="popbox_upload" class="mb10" style="margin-top: -30px;color:#15bccf; font-size:16px;">
<div class="upload_con">
<h2 style="text-align: center">更换背景图片</h2>
<div class="upload_box">
<%= error_messages_for 'attachment' %>
<div id="network_issue" style="color: red; display: none;"><%= l(:label_file_upload_error_messages)%></div>
<%= form_tag(organization_files_path(org, :in_org => params[:in_org]), :multipart => true,:remote => !ie8?,:name=>"upload_form") do %>
<!--<input type="hidden" name="org_subfield_attachment_type" value="<%#= org_subfield_attachment_type%>">-->
<%= render :partial => 'files/org_upload_attachment_list_banner', :locals => {:container => org}%>
<div class="cl"></div>
<a href="javascript:void(0);" class=" fr grey_btn mr40" onclick="hideModal();"><%= l(:button_cancel)%></a>
<a id="submit_org_resource" href="javascript:void(0);" class="blue_btn fr" onclick="submit_resource();"><%= l(:button_confirm)%></a>
<% end %>
</div>
</div>
</div>
<script>
function submit_resource()
{
$('#submit_org_resource').parent().submit();
}
</script>

@ -62,9 +62,19 @@
<!--add by huang-->
<script type="text/javascript">
function orge_new_files_upload()
function org_new_files_upload()
{
$('#ajax-modal').html('<%= escape_javascript(render :partial => 'files/upload_org_new_files',:locals => {:org => @organization, :org_attachment_type => 1}) %>');
$('#ajax-modal').html('<%= escape_javascript(render :partial => 'files/upload_org_new_files',:locals => {:org => @organization, :org_attachment_type => 0}) %>');
showModal('ajax-modal', '513px');
$('#ajax-modal').siblings().remove();
$('#ajax-modal').before("<a href='javascript:void(0)' onclick='hideModal()' style='margin-left: 480px;'><img src='/images/bid/close.png' width='26px' height='26px' /></a>");
$('#ajax-modal').parent().css("top","40%").css("left","36%").css("border","3px solid #269ac9");
$('#ajax-modal').parent().addClass("popbox_polls");
}
function org_new_files_banner_upload()
{
$('#ajax-modal').html('<%= escape_javascript(render :partial => 'files/upload_org_new_files_banner',:locals => {:org => @organization, :org_attachment_type => 1}) %>');
showModal('ajax-modal', '513px');
$('#ajax-modal').siblings().remove();
$('#ajax-modal').before("<a href='javascript:void(0)' onclick='hideModal()' style='margin-left: 480px;'><img src='/images/bid/close.png' width='26px' height='26px' /></a>");
@ -78,33 +88,30 @@
<div class="header">
<div class="header-con">
<% if User.current.admin_of_org?(@organization) %>
<a href="javascript:void(0);" class="fl logo" onclick="orge_new_files_upload();">
<!--"/files/uploads/image#{iamge_path}"-->
<div class="logo fl">
<% if @org_logo_attchment.blank? %>
<img src="/images/org_new_style/logo.jpg" height="52" alt=""/>
<a class="logo-img"><img src="/images/org_new_style/logo.jpg" alt=""/></a>
<% else %>
<img src="/attachments/<%= @org_logo_attchment.id %>/<%= @org_logo_attchment.filename %>" height="52">
<img src="/attachments/<%= @org_logo_attchment.id %>/<%= @org_logo_attchment.filename %>" class="logo-img">
<% end %>
</a>
<a href="#" class="logo-add" title="点击替换LOGO" onclick="org_new_files_upload();"></a>
</div>
<% else %>
<a href="javascript:void(0);" class="fl logo" onclick="orge_new_files_upload();">
<!--"/files/uploads/image#{iamge_path}"-->
<div class="logo fl">
<% if @org_logo_attchment.blank? %>
<img src="/images/org_new_style/logo.jpg" height="52" alt=""/>
<a class="logo-img"><img src="/images/org_new_style/logo.jpg" alt=""/></a>
<% else %>
<img src="/attachments/<%= @org_logo_attchment.id %>/<%= @org_logo_attchment.filename %>" height="52">
<img src="/attachments/<%= @org_logo_attchment.id %>/<%= @org_logo_attchment.filename %>" class="logo-img">
<% end %>
</a>
</div>
<% end %>
<%# 登录 %>
<%= render :partial => 'organizations/org_logined_header' %>
</div>
<div class="cl"></div>
</div><!--header end-->
<div class="nav-box">
<div class="nav-con">
<div class="nav fl">
<% @subfield_content.each do |field| %>
<% if is_default_field?(field) %>
@ -128,13 +135,35 @@
<a href="<%= setting_organization_path(@organization) %>" class="fl">配置</a>
<% end %>
</div>
</div><!--nav end-->
<div class="cl"></div>
</div>
</div>
<!--nav end-->
<div class="banner">
<h2><%= @organization.name %></h2>
<div class="banner-inner">
<% if User.current.admin_of_org?(@organization) %>
<% if @org_banner_attchment.blank? %>
<img class="banner-img" src="/images/org_new_style/banner.jpg" alt=""/>
<% else %>
<img src="/attachments/<%= @org_banner_attchment.id %>/<%= @org_banner_attchment.filename %>" class="banner-img">
<% end %>
<a href="#" class="banner-add" title="点击替换图片" onclick="org_new_files_banner_upload();"></a>
<div class="banner-txt">
<p ><%= @organization.name %></p>
</div>
<% else %>
<% if @org_banner_attchment.blank? %>
<img class="banner-img" src="/images/org_new_style/banner.jpg" alt=""/>
<% else %>
<img src="/attachments/<%= @org_banner_attchment.id %>/<%= @org_banner_attchment.filename %>" class="banner-img">
<% end %>
<div class="banner-txt">
<p ><%= @organization.name %></p>
</div>
<% end %>
</div>
</div>
<div class="cl"></div>
<!--模块-->
<% @subfield_content.each do |field| %>

@ -0,0 +1,44 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<%= csrf_meta_tag %>
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=0">
<title>绑定用户</title>
<link rel="stylesheet" href="/stylesheets/weui/weui.min.css"/>
<script src="/javascripts/jquery.min.js"></script>
<script src="/javascripts/wechat/alert.js"></script>
</head>
<%= yield %>
<!--BEGIN dialog2-->
<div class="weui_dialog_alert" id="dialog2" style="display: none;">
<div class="weui_mask"></div>
<div class="weui_dialog">
<div class="weui_dialog_hd"><strong class="weui_dialog_title">弹窗标题</strong></div>
<div class="weui_dialog_bd"><span class="weui_dialog_info">弹窗内容,告知当前页面信息等</span></div>
<div class="weui_dialog_ft">
<a href="javascript:;" class="weui_btn_dialog primary">确定</a>
</div>
</div>
</div>
<!--END dialog2-->
<!--BEGIN dialog1-->
<div class="weui_dialog_confirm" id="dialog1" style="display: none;">
<div class="weui_mask"></div>
<div class="weui_dialog">
<div class="weui_dialog_hd"><strong class="weui_dialog_title">弹窗标题</strong></div>
<div class="weui_dialog_bd"><span class="weui_dialog_info">自定义弹窗内容,居左对齐显示,告知需要确认的信息等</span></div>
<div class="weui_dialog_ft">
<a href="javascript:;" class="weui_btn_dialog default cancel">取消</a>
<a href="javascript:;" class="weui_btn_dialog primary confirm">确定</a>
</div>
</div>
</div>
<!--END dialog1-->
</body>
</html>

@ -24,7 +24,8 @@
<body>
<!--<div class="resourceSharePopup">-->
<div>
<div class="relateText fl">请选择关联到组织的课程</div>
<div class="relateText">请选择关联到组织的课程</div>
<div class="c_red">您的私有课程不能被关联到组织</div>
</div>
<div class="fl">
<%=form_tag url_for(:controller => 'organizations', :action => 'join_courses', :organization_id => organization_id),:method => 'post', :id => 'join_courses_form', :remote => true,:class=>"resourcesSearchBox" do %>

@ -24,7 +24,8 @@
<body>
<div>
<div class="relateText fl">请选择关联到组织的项目</div>
<div class="relateText">请选择关联到组织的项目</div>
<div class="c_red">您的私有项目不能被关联到组织</div>
</div>
<div class="fl">
<%=form_tag url_for(:controller => 'organizations', :action => 'join_projects', :organization_id => organization_id),:method => 'post', :id => 'join_projects_form', :remote => true,:class=>"resourcesSearchBox" do %>

@ -138,7 +138,7 @@
</li>
<% roles.each do |role| %>
<li>
<%= radio_button_tag 'membership[role_ids][]', role.id %>
<%= radio_button_tag 'membership[role_ids][]', role.id, role.name == "报告人员" || role.name == "Reporter" %>
<% if User.current.language == "zh" %>
<% if role.id == 3 %>
<label >管理人员</label>

@ -7,8 +7,7 @@
</span>
<%= link_to('&nbsp;'.html_safe, attachment_path(attachment, :format => 'js'), :method => 'delete', :remote => true, :title => '删除', :class => 'remove-upload fl', :confirm => l(:text_are_you_sure)) if attachment.id && User.current == attachment.author && status != 2 %>
<span class="postAttSize">(<%= number_to_human_size attachment.filesize %>)</span>
<span class="author" title="<%= attachment.author%>">
<%= link_to h(truncate(attachment.author.name, length: 10, omission: '...')),user_path(attachment.author),:class => "c_orange" %>,
<span class="author">
<%= format_time(attachment.created_on) %>
</span>
<div class="cl"></div>

@ -145,6 +145,7 @@
</div>
<% end %>
<% if !activity.locked? %>
<div class="homepagePostReplyContainer borderBottomNone minHeight48">
<div class="homepagePostReplyPortrait mr15 imageFuzzy" id="reply_image_<%= user_activity_id%>"><%= link_to image_tag(url_to_avatar(User.current), :width => "33", :height => "33"), user_path(activity.author_id), :alt => "用户头像" %></div>
<div class="homepagePostReplyInputContainer mb10">
@ -163,5 +164,6 @@
</div>
<div class="cl"></div>
</div>
<% end %>
</div>
</div>

@ -0,0 +1,34 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=0">
<title>绑定用户</title>
<link rel="stylesheet" href="/stylesheets/weui/weui.min.css"/>
<script type="text/javascript">
function close(){
WeixinJSBridge.call('closeWindow');
}
</script>
</head>
<body>
<div class="page">
<div class="weui_msg">
<div class="weui_icon_area"><i class="weui_icon_success weui_icon_msg"></i></div>
<div class="weui_text_area">
<h2 class="weui_msg_title">操作成功</h2>
<p class="weui_msg_desc">您已成功绑定微信</p>
</div>
<div class="weui_opr_area">
<p class="weui_btn_area">
<a href="javascript:close();" class="weui_btn weui_btn_primary">确定</a>
</p>
</div>
</div>
</div>
</body>
</html>

@ -0,0 +1,68 @@
<div class="loginIn">
<div>
<p class="weui_cells_title wechat-error">
<%= @wechat_bind_errors %>
</p>
</div>
<%= form_tag(bind_wechat_path,:id=>'main_login_form',:method=>'post') do %>
<div class="weui_cells weui_cells_form">
<div class="weui_cell">
<div class="weui_cell_hd"><label class="weui_label">用户名</label></div>
<div class="weui_cell_bd weui_cell_primary">
<input class="weui_input" autocapitalize="off" type="text" name="username" placeholder="请输入邮箱地址或昵称"/>
</div>
</div>
<div class="weui_cell">
<div class="weui_cell_hd"><label class="weui_label">用户名</label></div>
<div class="weui_cell_bd weui_cell_primary">
<input class="weui_input" type="password" name="password" placeholder="请输密码"/>
</div>
</div>
<input type="hidden" value="<%=@code%>" name="code">
<div class="weui_btn_area">
<a class="weui_btn weui_btn_primary" id="submitForm">确定</a>
</div>
</div>
<% end %>
</div>
<script type="text/javascript">
$(function(){
console.log("started.");
$("#submitForm").click(function(){
var data = {};
$("#main_login_form").serializeArray().map(function(x){data[x.name] = x.value;});
console.log(data);
$.ajax({
type: "POST",
url: $("#main_login_form").attr("action"),
data:data,
dataType: 'json',
success: function(data){
console.log(data);
if(data.status == 0){
byConfirm(data.msg, function(){
window.closeWindow();
});
} else {
byAlert(data.msg, "绑定失败");
}
}
});
})
});
</script>

@ -69,6 +69,14 @@ module RedmineApp
config.action_view.sanitized_allowed_tags = 'div', 'p', 'span', 'img', 'embed'
config.middleware.use Rack::Cors do
allow do
origins '*'
# location of your API
resource '/api/*', :headers => :any, :methods => [:get, :post, :options, :put]
end
end
config.before_initialize do
end

@ -0,0 +1,3 @@
class ActiveRecord::ConnectionAdapters::Mysql2Adapter
NATIVE_DATABASE_TYPES[:primary_key] = "int(11) auto_increment PRIMARY KEY"
end

@ -0,0 +1,20 @@
button:
-
type: "view"
name: "最新动态"
url: "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxc09454f171153c2d&redirect_uri=http://wechat.trustie.net/assets/wechat/app.html#/activities?response_type=code&scope=snsapi_base&state=123#wechat_redirect"
-
type: "click"
name: "意见返馈"
key: "FEEDBACK"
-
name: "更多"
sub_button:
-
type: "view"
name: "进入网站"
url: "http://www.trustie.net/"
-
type: "view"
name: "使用手册"
url: "https://www.trustie.net/organizations/1/downloads"

@ -1170,6 +1170,13 @@ RedmineApp::Application.routes.draw do
end
resources :at
resource :wechat, only:[:show, :create] do
collection do
get :login
post :bind
post :get_open_id
end
end
get '/:sub_dir_name', :to => 'org_subfields#show', :as => 'show_subfield_without_id'

@ -0,0 +1,21 @@
default: &default
# corpid: "corpid"
# corpsecret: "corpsecret"
# agentid: 1
# Or if using public account, only need above two line
appid: "wxc09454f171153c2d"
secret: "dff5b606e34dcafe24163ec82c2715f8"
token: "123456"
access_token: "1234567"
encrypt_mode: false # if true must fill encoding_aes_key
encoding_aes_key: "QyocNOkRmrT5HzBpCG54EVPUQjk86nJapXNVDQm6Yy6"
jsapi_ticket: "C:/Users/[user_name]/wechat_jsapi_ticket"
production:
<<: *default
development:
<<: *default
test:
<<: *default

@ -0,0 +1,11 @@
class CreateWechatLogs < ActiveRecord::Migration
def change
create_table :wechat_logs do |t|
t.string :openid, null: false, index: true
t.text :request_raw
t.text :response_raw
t.text :session_raw
t.datetime :created_at, null: false
end
end
end

@ -0,0 +1,21 @@
class CreateUserWechats < ActiveRecord::Migration
def change
create_table :user_wechats do |t|
t.integer :subscribe
t.string :openid
t.string :nickname
t.integer :sex
t.string :language
t.string :city
t.string :province
t.string :country
t.string :headimgurl
t.string :subscribe_time
t.string :unionid
t.string :remark
t.integer :groupid
t.references :user
t.timestamps
end
end
end

@ -0,0 +1,21 @@
class DeleteBlogUserActivity < ActiveRecord::Migration
def up
UserActivity.all.each do |activity|
if activity.act_type == 'BlogComment'
if activity.act
unless activity.act.parent_id.nil?
parent_act = UserActivity.where("act_id = #{activity.act.parent.id} and act_type='BlogComment'").first
parent_act.created_at = activity.act.parent.children.maximum("created_on")
parent_act.save
activity.destroy
end
else
activity.destroy
end
end
end
end
def down
end
end

@ -11,11 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.
<<<<<<< HEAD
ActiveRecord::Schema.define(:version => 20160331063938) do
=======
ActiveRecord::Schema.define(:version => 20160405021915) do
>>>>>>> c3ee4dadfb92c75e8649cad7e0ed57c2ec02ec00
ActiveRecord::Schema.define(:version => 20160408074854) do
create_table "activities", :force => true do |t|
t.integer "act_id", :null => false
@ -1921,6 +1917,25 @@ ActiveRecord::Schema.define(:version => 20160405021915) do
add_index "user_statuses", ["grade"], :name => "index_user_statuses_on_grade"
add_index "user_statuses", ["watchers_count"], :name => "index_user_statuses_on_watchers_count"
create_table "user_wechats", :force => true do |t|
t.integer "subscribe"
t.string "openid"
t.string "nickname"
t.integer "sex"
t.string "language"
t.string "city"
t.string "province"
t.string "country"
t.string "headimgurl"
t.string "subscribe_time"
t.string "unionid"
t.string "remark"
t.integer "groupid"
t.integer "user_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "users", :force => true do |t|
t.string "login", :default => "", :null => false
t.string "hashed_password", :limit => 40, :default => "", :null => false
@ -1997,6 +2012,14 @@ ActiveRecord::Schema.define(:version => 20160405021915) do
t.datetime "updated_at", :null => false
end
create_table "wechat_logs", :force => true do |t|
t.string "openid", :null => false
t.text "request_raw"
t.text "response_raw"
t.text "session_raw"
t.datetime "created_at", :null => false
end
create_table "wiki_content_versions", :force => true do |t|
t.integer "wiki_content_id", :null => false
t.integer "page_id", :null => false

@ -140,6 +140,7 @@ module Redmine
if file && file.size > 0
a = Attachment.create(:file => file, :author => author)
elsif token
# 通过token值找到对应的attachment
a = Attachment.find_by_token_only(token)
if a
a.filename = attachment['filename'] unless attachment['filename'].blank?

@ -0,0 +1,23 @@
<!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" />
<script src="/javascripts/wechat/react.js"></script>
<script src="/javascripts/wechat/JSXTransformer.js"></script>
<script src="/javascripts/wechat/ReactRouter.js"></script>
</head>
<body>
<div id="container"></div>
<script src="/javascripts/wechat/jquery.min.js"></script>
<script type="text/jsx" src="/javascripts/wechat/wechat.jsx"></script>
</body>
</html>

@ -0,0 +1,223 @@
<div id="container">
<!-- 模板1开始可以使用scripttype设置为text/html来存放模板片段并且用id标示 -->
<div ng-repeat="act in activities">
<div ng-if="act.container_type=='Course'">
<div ng-if="act.act_type=='HomeworkCommon'">
<div class="post-container">
<div class="post-wrapper">
<div class="post-main">
<div class="post-avatar fl"><img ng-src="{{replaceUrl(act.author.img_url)}}" width="45" height="45" class="border-radius" /></div>
<div class="post-title hidden mb5"><span class="c-grey3 f15 fb">{{act.subject|safeHtml}}</span></div>
<div class="post-title hidden"><a herf="javascript:void(0);" class="mr10">{{act.author.realname}}</a>to<a herf="javascript:void(0);" class="ml10">{{act.course_project_name}}&nbsp;&nbsp;|&nbsp;&nbsp;{{act.activity_type_name}}</a></div>
<div class="cl"></div>
<div class="post-content c-grey2 mt10">
<div class="post-all-content" ng-bind-html="act.description|safeHtml"></div>
<span class="mr15">迟交扣分:{{act.homework_common_detail.late_penalty}}分</span> 匿评开启时间:{{act.homework_common_detail.evaluation_start}}<br />
<span class="mr15">缺评扣分:{{act.homework_common_detail.absence_penalty}}分/作品</span> 匿评关闭时间:{{act.homework_common_detail.evaluation_end}}
</div>
<a herf="javascript:void(0);" class="link-blue f13 fl mt5 post-more undis underline" text-auto-height>点击展开</a>
<div class="cl"></div>
<span class="c-grey f13 mt10 fl">{{act.latest_update}}</span>
<div class="cl"></div>
</div>
<div class="post-interactive">
<div class="post-interactive-column c-grey2"><a href="javascript:void(0);" ng-href="#/homework/{{act.act_id}}" class="c-grey">回复 ({{act.reply_count}})</a></div>
<div class="post-interactive-column c-grey2" ng-if="!act.has_praise" ng-click="addPraise(act);">赞 ({{act.praise_count}})</div>
<div class="post-interactive-column c-grey2" ng-if="act.has_praise" ng-click="decreasePraise(act);">已赞 ({{act.praise_count}})</div>
</div>
</div>
</div>
</div>
<div ng-if="act.act_type=='News'">
<div class="post-container">
<div class="post-wrapper">
<div class="post-main">
<div class="post-avatar fl"><img ng-src="{{replaceUrl(act.author.img_url)}}" width="45" height="45" class="border-radius" /></div>
<div class="post-title hidden mb5"><span class="c-grey3 f15 fb">{{act.subject|safeHtml}}</span></div>
<div class="post-title hidden"><a herf="javascript:void(0);" class="mr10">{{act.author.realname}}</a>to<a herf="javascript:void(0);" class="ml10">{{act.course_project_name}}&nbsp;&nbsp;|&nbsp;&nbsp;{{act.activity_type_name}}</a></div>
<div class="cl"></div>
<div class="post-content c-grey2 mt10">
<div class="post-all-content" ng-bind-html="act.description|safeHtml"></div>
</div>
<a herf="javascript:void(0);" class="link-blue f13 fl mt5 post-more undis underline" text-auto-height>点击展开</a>
<div class="cl"></div>
<span class="c-grey f13 mt10 fl">{{act.latest_update}}</span>
<div class="cl"></div>
</div>
<div class="post-interactive">
<div class="post-interactive-column c-grey2"><a href="javascript:void(0);" ng-href="#/course_notice/{{act.act_id}}" class="c-grey">回复 ({{act.reply_count}})</a></div>
<div class="post-interactive-column c-grey2" ng-if="!act.has_praise" ng-click="addPraise(act);">赞 ({{act.praise_count}})</div>
<div class="post-interactive-column c-grey2" ng-if="act.has_praise" ng-click="decreasePraise(act);">已赞 ({{act.praise_count}})</div>
</div>
</div>
</div>
</div>
<div ng-if="act.act_type=='Message'">
<div class="post-container">
<div class="post-wrapper">
<div class="post-main">
<div class="post-avatar fl"><img ng-src="{{replaceUrl(act.author.img_url)}}" width="45" height="45" class="border-radius" /></div>
<div class="post-title hidden mb5"><span class="c-grey3 f15 fb">{{act.subject|safeHtml}}</span></div>
<div class="post-title fl mb10 hidden"><a herf="javascript:void(0);" class="mr10">{{act.author.realname}}</a>to<a herf="javascript:void(0);" class="ml10">{{act.course_project_name}}&nbsp;&nbsp;|&nbsp;&nbsp;{{act.activity_type_name}}</a></div>
<div class="cl"></div>
<div class="post-content c-grey2 mt10">
<div class="post-all-content" ng-bind-html="act.description|safeHtml"></div>
</div>
<a herf="javascript:void(0);" class="link-blue f13 fl mt5 post-more undis underline" text-auto-height>点击展开</a>
<div class="cl"></div>
<span class="c-grey f13 mt10 fl">{{act.latest_update}}</span>
<div class="cl"></div>
</div>
<div class="post-interactive">
<div class="post-interactive-column c-grey2"><a href="javascript:void(0);" ng-href="#/course_discussion/{{act.act_id}}" class="c-grey">回复 ({{act.reply_count}})</a></div>
<div class="post-interactive-column c-grey2" ng-if="!act.has_praise" ng-click="addPraise(act);">赞 ({{act.praise_count}})</div>
<div class="post-interactive-column c-grey2" ng-if="act.has_praise" ng-click="decreasePraise(act);">已赞 ({{act.praise_count}})</div>
</div>
</div>
</div>
</div>
<div ng-if="act.act_type=='Course'">
<div class="post-container">
<div class="post-wrapper">
<div class="post-main">
<div class="post-avatar fl"><img ng-src="{{replaceUrl(act.author.img_url)}}" width="45" height="45" class="border-radius" /></div>
<div class="post-title hidden mb5"><span class="c-grey3 f13 fb mr10">{{act.author.realname}}</span>创建了<span class="c-grey3 f13 fb ml10">{{act.course_project_name}}</span></div>
<div class="post-title hidden"><a herf="javascript:void(0);" class="mr10">{{act.latest_update}}</a></div>
<div class="cl"></div>
</div>
</div>
</div>
</div>
</div>
<div ng-if="act.container_type=='Project'">
<div ng-if="act.act_type=='Issue'">
<div class="post-container">
<div class="post-wrapper">
<div class="post-main">
<div class="post-avatar fl"><img ng-src="{{replaceUrl(act.author.img_url)}}" width="45" height="45" class="border-radius" /></div>
<div class="post-title hidden mb5"><span class="c-grey3 f15 fb">{{act.subject|safeHtml}}</span></div>
<div class="post-title hidden"><a herf="javascript:void(0);" class="mr10">{{act.author.realname}}</a>to<a herf="javascript:void(0);" class="ml10">{{act.course_project_name}}&nbsp;&nbsp;|&nbsp;&nbsp;{{act.activity_type_name}}</a></div>
<div class="cl"></div>
<div class="post-content c-grey2 mt10">
<div class="post-all-content" ng-bind-html="act.description|safeHtml"></div>
<span class="mr15">状态:{{act.issue_detail.issue_status}}</span> <span class="mr15">优先级:{{act.issue_detail.issue_priority}}</span> <br />
<span class="mr15">指派给:{{act.issue_detail.issue_assigned_to}}</span> <span class="mr15">完成度:{{act.issue_detail.done_ratio}}%</span>
</div>
<a herf="javascript:void(0);" class="link-blue f13 fl mt5 post-more undis underline" text-auto-height>点击展开</a>
<div class="cl"></div>
<span class="c-grey f13 mt10 fl">{{act.latest_update}}</span>
<div class="cl"></div>
</div>
<div class="post-interactive">
<div class="post-interactive-column c-grey2"><a href="javascript:void(0);" ng-href="#/issues/{{act.act_id}}" class="c-grey"> 回复 ({{act.reply_count}})</a></div>
<div class="post-interactive-column c-grey2" ng-if="!act.has_praise" ng-click="addPraise(act);">赞 ({{act.praise_count}})</div>
<div class="post-interactive-column c-grey2" ng-if="act.has_praise" ng-click="decreasePraise(act);">已赞 ({{act.praise_count}})</div>
</div>
</div>
</div>
</div>
<div ng-if="act.act_type=='Message'">
<div class="post-container">
<div class="post-wrapper">
<div class="post-main">
<div class="post-avatar fl"><img ng-src="{{replaceUrl(act.author.img_url)}}" width="45" height="45" class="border-radius" /></div>
<div class="post-title hidden mb5"><span class="c-grey3 f15 fb">{{act.subject|safeHtml}}</span></div>
<div class="post-title hidden"><a herf="javascript:void(0);" class="mr10">{{act.author.realname}}</a>to<a herf="javascript:void(0);" class="ml10">{{act.course_project_name}}&nbsp;&nbsp;|&nbsp;&nbsp;{{act.activity_type_name}}</a></div>
<div class="cl"></div>
<div class="post-content c-grey2 mt10">
<div class="post-all-content" ng-bind-html="act.description|safeHtml"></div>
</div>
<a herf="javascript:void(0);" class="link-blue f13 fl mt5 post-more undis underline" text-auto-height>点击展开</a>
<div class="cl"></div>
<span class="c-grey f13 mt10 fl">{{act.latest_update}}</span>
<div class="cl"></div>
</div>
<div class="post-interactive">
<div class="post-interactive-column c-grey2"><a href="javascript:void(0);" ng-href="#/project_discussion/{{act.act_id}}" class="c-grey"> 回复 ({{act.reply_count}}) </a></div>
<div class="post-interactive-column c-grey2" ng-if="!act.has_praise" ng-click="addPraise(act);">赞 ({{act.praise_count}})</div>
<div class="post-interactive-column c-grey2" ng-if="act.has_praise" ng-click="decreasePraise(act);">已赞 ({{act.praise_count}})</div>
</div>
</div>
</div>
</div>
<div ng-if="act.act_type=='ProjectCreateInfo'">
<div class="post-container">
<div class="post-wrapper">
<div class="post-main">
<div class="post-avatar fl"><img ng-src="{{replaceUrl(act.author.img_url)}}" width="45" height="45" class="border-radius" /></div>
<div class="post-title hidden mb5"><span class="c-grey3 f15 fb">{{act.author.realname}}</span>创建了<span class="c-grey3 f15 fb">{{act.course_project_name}}</span></div>
<div class="post-title hidden"><a herf="javascript:void(0);" class="mr10">{{act.latest_update}}</a></div>
<div class="cl"></div>
</div>
</div>
</div>
</div>
</div>
<div ng-if="act.container_type=='Principal'">
<div ng-if="act.act_type=='JournalsForMessage'">
<div class="post-container">
<div class="post-wrapper">
<div class="post-main">
<div class="post-avatar fl"><img ng-src="{{replaceUrl(act.author.img_url)}}" width="45" height="45" class="border-radius" /></div>
<div class="post-title mb5 hidden"><a herf="javascript:void(0);" class="mr10">{{act.author.realname}}</a> <span style="vertical-align:top;">给您留言了</span></div>
<div class="post-title hidden">{{act.latest_update}}</div>
<div class="cl"></div>
<div class="post-content c-grey2 mt10">
<p class="post-all-content" ng-bind-html="act.description|safeHtml"></p>
</div>
<a herf="javascript:void(0);" class="link-blue f13 fl mt5 post-more undis underline" text-auto-height>点击展开</a>
<div class="cl"></div>
</div>
<div class="post-interactive">
<div class="post-interactive-column c-grey2"><a href="javascript:void(0);" ng-href="#/journal_for_message/{{act.act_id}}" class="c-grey"> 回复 ({{act.reply_count}})</a></div>
<div class="post-interactive-column c-grey2" ng-if="!act.has_praise" ng-click="addPraise(act);">赞 ({{act.praise_count}})</div>
<div class="post-interactive-column c-grey2" ng-if="act.has_praise" ng-click="decreasePraise(act);">已赞 ({{act.praise_count}})</div>
</div>
</div>
</div>
</div>
</div>
<div ng-if="act.act_type=='BlogComment'">
<div class="post-container">
<div class="post-wrapper">
<div class="post-main">
<div class="post-avatar fl"><img ng-src="{{replaceUrl(act.author.img_url)}}" width="45" height="45" class="border-radius" /></div>
<div class="post-title hidden mb5"><span class="c-grey3 f15 fb">{{act.subject|safeHtml}}</span></div>
<div class="post-title hidden"><a herf="javascript:void(0);" class="mr10">{{act.author.realname}}</a>发表博客</div>
<div class="cl"></div>
<div class="post-content c-grey2 mt10">
<div class="post-all-content" ng-bind-html="act.description|safeHtml"></div>
</div>
<a herf="javascript:void(0);" class="link-blue f13 fl mt5 post-more undis underline" text-auto-height>点击展开</a>
<div class="cl"></div>
<span class="c-grey f13 mt10 fl">{{act.latest_update}}</span>
<div class="cl"></div>
</div>
<div class="post-interactive">
<div class="post-interactive-column c-grey2"><a href="javascript:void(0);" ng-href="#/blog_comment/{{act.act_id}}" class="c-grey"> 回复 ({{act.reply_count}})</a></div>
<div class="post-interactive-column c-grey2" ng-if="!act.has_praise" ng-click="addPraise(act);">赞 ({{act.praise_count}})</div>
<div class="post-interactive-column c-grey2" ng-if="act.has_praise" ng-click="decreasePraise(act);">已赞 ({{act.praise_count}})</div>
</div>
</div>
</div>
</div>
</div>
<div ng-if="(count + page * 10) < all_count">
<div id="more_activities" class="more-events mt10" ng-click="loadActData(current_page+1);">更多</div>
</div>
</div>

@ -0,0 +1,27 @@
<!DOCTYPE html>
<html ng-app="wechat">
<head>
<title>最新动态</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 ng-view></div>
<script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.js"></script>
<script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular-route.js"></script>
<script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular-sanitize.min.js"></script>
<script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular-cookies.js"></script>
<script src="/javascripts/jquery-1.3.2.js"></script>
<script src="/javascripts/wechat/app.js"></script>
</body>
</html>

@ -0,0 +1,45 @@
<!-- 模板1开始可以使用scripttype设置为text/html来存放模板片段并且用id标示 -->
<div class="post-container">
<div class="post-wrapper">
<div class="post-main">
<div class="post-avatar fl"><img ng-src="{{blog.user.img_url}}" width="45" height="45" class="border-radius" /></div>
<div class="post-title hidden mb5"><span class="c-grey3 f15 fb">{{blog.title}}</span></div>
<div class="post-title hidden"><a herf="javascript:void(0);" class="mr10">{{blog.user.realname}}</a>发表博客</div>
<div class="cl"></div>
<div class="post-content" style="height:auto;">
<div class="post-all-content c-grey2 mt10" ng-bind-html="blog.content|safeHtml"></div>
</div>
<div class="cl"></div>
<span class="c-grey f13 mt10 fl">{{blog.created_at}}</span>
<div class="cl"></div>
</div>
<div class="post-interactive border-bottom">
<div class="post-interactive-reply c-grey2">回复 <span class="reply-num">({{blog.comment_count}})</span></div>
<div class="post-interactive-column c-grey2" ng-if="blog.has_praise" ng-click="decreasePraise(blog);">已赞 ({{blog.praise_count}})</div>
<div class="post-interactive-column c-grey2" ng-if="!blog.has_praise" ng-click="addPraise(blog);">赞 ({{blog.praise_count}})</div>
</div>
<div id="all_blog_reply">
<div class="post-reply-wrap border-bottom" ng-repeat="journal in blog.blog_comment_children">
<div class="post-reply-row">
<div class="post-reply-avatar fl"><img ng-src="{{journal.user.img_url}}" width="45" height="45" class="border-radius" /></div>
<div class="ml55">
<div class="post-reply-user hidden">{{journal.user.realname}}</div>
<div class="post-reply-content c-grey2 mb10" ng-bind-html="journal.content|safeHtml"></div>
<div class="post-reply-date fl">{{journal.lasted_comment}}</div>
<div class="post-reply-trigger fr undis">回复</div>
</div>
<div class="cl"></div>
</div>
</div>
</div>
<div class="post-input-wrap">
<div class="post-reply-row">
<!--<div class="post-reply-avatar fl"><img src="images/post-avatar.jpg" width="30" height="30" /></div>-->
<input type="text" class="post-reply-input" id="postInput" ng-model="formData.comment" />
<button ng-click="addBlogReply(formData)" class="post-reply-submit fr mt10">回复</button>
<div class="cl"></div>
</div>
</div>
</div>
</div>

@ -0,0 +1,45 @@
<!-- 模板1开始可以使用scripttype设置为text/html来存放模板片段并且用id标示 -->
<div class="post-container">
<div class="post-wrapper">
<div class="post-main">
<div class="post-avatar fl"><img ng-src="{{discussion.user.img_url}}" width="45" height="45" class="border-radius" /></div>
<div class="post-title hidden mb5"><span class="c-grey3 f15 fb">{{discussion.subject}}</span></div>
<div class="post-title hidden"><a herf="javascript:void(0);" class="mr10">{{discussion.user.realname}}</a>to<a herf="javascript:void(0);" class="ml10">{{discussion.course_project_name}}&nbsp;&nbsp;|&nbsp;&nbsp;课程问答区</a></div>
<div class="cl"></div>
<div class="post-content c-grey2 mt10" style="height:auto;">
<div class="post-all-content" ng-bind-html="discussion.content|safeHtml"></div>
</div>
<div class="cl"></div>
<span class="c-grey f13 mt10 fl">{{discussion.created_on}}</span>
<div class="cl"></div>
</div>
<div class="post-interactive border-bottom">
<div class="post-interactive-reply c-grey2">回复 <span class="reply-num">({{discussion.replies_count}})</span></div>
<div class="post-interactive-column c-grey2" ng-if="discussion.has_praise" ng-click="decreasePraise(discussion);">已赞 ({{discussion.praise_count}})</div>
<div class="post-interactive-column c-grey2" ng-if="!discussion.has_praise" ng-click="addPraise(discussion);">赞 ({{discussion.praise_count}})</div>
</div>
<div id="all_course_message_reply">
<div class="post-reply-wrap border-bottom" ng-repeat="journal in discussion.message_children">
<div class="post-reply-row">
<div class="post-reply-avatar fl"><img ng-src="{{journal.user.img_url}}" width="45" height="45" class="border-radius" /></div>
<div class="ml55">
<div class="post-reply-user hidden">{{journal.user.realname}}</div>
<div class="post-reply-content c-grey2 mb10" ng-bind-html="journal.content|safeHtml"></div>
<div class="post-reply-date fl">{{journal.lasted_comment}}</div>
<div class="post-reply-trigger fr undis">回复</div>
</div>
<div class="cl"></div>
</div>
</div>
</div>
<div class="post-input-wrap">
<div class="post-reply-row">
<!--<div class="post-reply-avatar fl"><img src="images/post-avatar.jpg" width="30" height="30" /></div>-->
<input type="text" class="post-reply-input" id="postInput" ng-model="formData.comment" />
<button ng-click="addDiscussionReply(formData)" class="post-reply-submit fr mt10">回复</button>
<div class="cl"></div>
</div>
</div>
</div>
</div>

@ -0,0 +1,45 @@
<!-- 模板1开始可以使用scripttype设置为text/html来存放模板片段并且用id标示 -->
<div class="post-container">
<div class="post-wrapper">
<div class="post-main">
<div class="post-avatar fl"><img ng-src="{{news.author.img_url}}" width="45" height="45" class="border-radius" /></div>
<div class="post-title hidden mb5"><span class="c-grey3 f15 fb">{{news.title}}</span></div>
<div class="post-title hidden"><a herf="javascript:void(0);" class="mr10">{{news.author.realname}}</a>to<a herf="javascript:void(0);" class="ml10">{{news.course_name}}&nbsp;&nbsp;|&nbsp;&nbsp;课程通知</a></div>
<div class="cl"></div>
<div class="post-content c-grey2 mt10" style="height:auto;">
<div class="post-all-content" ng-bind-html="news.description|safeHtml"></div>
</div>
<div class="cl"></div>
<span class="c-grey f13 mt10 fl">{{news.created_on}}</span>
<div class="cl"></div>
</div>
<div class="post-interactive border-bottom">
<div class="post-interactive-reply c-grey2">回复 <span class="reply-num">({{news.comments_count}})</span></div>
<div class="post-interactive-column c-grey2" ng-if="news.has_praise" ng-click="decreasePraise(news);">已赞 ({{news.praise_count}})</div>
<div class="post-interactive-column c-grey2" ng-if="!news.has_praise" ng-click="addPraise(news);">赞 ({{news.praise_count}})</div>
</div>
<div id="all_news_reply">
<div class="post-reply-wrap border-bottom" ng-repeat="comments in news.comments">
<div class="post-reply-row">
<div class="post-reply-avatar fl"><img ng-src="{{comments.author.img_url}}" width="45" height="45" class="border-radius" /></div>
<div class="ml55">
<div class="post-reply-user hidden">{{comments.author.realname}}</div>
<div class="post-reply-content c-grey2 mb10" ng-bind-html="comments.comments|safeHtml"></div>
<div class="post-reply-date fl">{{comments.created_on}}</div>
<div class="post-reply-trigger fr undis">回复</div>
</div>
<div class="cl"></div>
</div>
</div>
</div>
<div class="post-input-wrap">
<div class="post-reply-row">
<!--<div class="post-reply-avatar fl"><img src="images/post-avatar.jpg" width="30" height="30" /></div>-->
<input type="text" class="post-reply-input" id="postInput" ng-model="formData.comment" />
<button ng-click="addNoticeReply(formData)" class="post-reply-submit fr mt10">回复</button>
<div class="cl"></div>
</div>
</div>
</div>
</div>

@ -0,0 +1,47 @@
<!-- 模板1开始可以使用scripttype设置为text/html来存放模板片段并且用id标示 -->
<div class="post-container">
<div class="post-wrapper">
<div class="post-main">
<div class="post-avatar fl"><img ng-src="{{homework.author.img_url}}" width="45" height="45" class="border-radius" /></div>
<div class="post-title hidden mb5"><span class="c-grey3 f15 fb">{{homework.name}}</span></div>
<div class="post-title hidden"><a herf="javascript:void(0);" class="mr10">{{homework.author.realname}}</a>to<a herf="javascript:void(0);" class="ml10">{{homework.course_name}}&nbsp;&nbsp;|&nbsp;&nbsp;课程作业</a></div>
<div class="cl"></div>
<div class="post-content c-grey2 mt10" style="height:auto;">
<div class="post-all-content" ng-bind-html="homework.description|safeHtml"></div>
<span class="mr15">迟交扣分:{{homework.late_penalty}}分</span> 匿评开启时间:{{homework.evaluation_start}}<br />
<span class="mr15">缺评扣分:{{homework.absence_penalty}}分/作品</span> 匿评关闭时间:{{homework.evaluation_end}}
</div>
<div class="cl"></div>
<span class="c-grey f13 mt10 fl">{{homework.publish_time}}</span>
<div class="cl"></div>
</div>
<div class="post-interactive border-bottom">
<div class="post-interactive-reply c-grey2">回复 <span class="reply-num">({{homework.whomework_journal_count}})</span></div>
<div class="post-interactive-column c-grey2" ng-if="homework.has_praise" ng-click="decreasePraise(homework);">已赞 ({{homework.praise_count}})</div>
<div class="post-interactive-column c-grey2" ng-if="!homework.has_praise" ng-click="addPraise(homework);">赞 ({{homework.praise_count}})</div>
</div>
<div id="all_homework_reply">
<div class="post-reply-wrap border-bottom" ng-repeat="journal in homework.journals_for_messages">
<div class="post-reply-row">
<div class="post-reply-avatar fl"><img ng-src="{{journal.user.img_url}}" width="45" height="45" class="border-radius" /></div>
<div class="ml55">
<div class="post-reply-user hidden">{{journal.user.realname}}</div>
<div class="post-reply-content c-grey2 mb10" ng-bind-html="journal.notes|safeHtml"></div>
<div class="post-reply-date fl">{{journal.lasted_comment}}</div>
<div class="post-reply-trigger fr undis">回复</div>
</div>
<div class="cl"></div>
</div>
</div>
</div>
<div class="post-input-wrap">
<div class="post-reply-row">
<!--<div class="post-reply-avatar fl"><img src="images/post-avatar.jpg" width="30" height="30" /></div>-->
<input type="text" class="post-reply-input" id="postInput" ng-model="formData.comment" />
<button ng-click="addHomeworkReply(formData)" value="回复" class="post-reply-submit fr mt10">回复</button>
<div class="cl"></div>
</div>
</div>
</div>
</div>

@ -0,0 +1,50 @@
<!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>

@ -0,0 +1,47 @@
<!-- 模板1开始可以使用scripttype设置为text/html来存放模板片段并且用id标示 -->
<div class="post-container">
<div class="post-wrapper">
<div class="post-main">
<div class="post-avatar fl"><img ng-src="{{issue.author.img_url}}" width="45" height="45" class="border-radius" /></div>
<div class="post-title hidden mb5"><span class="c-grey3 f15 fb">{{issue.subject}}</span></div>
<div class="post-title hidden"><a herf="javascript:void(0);" class="mr10">{{issue.author.realname}}</a>to<span class="ml10">{{issue.project_name}}&nbsp;&nbsp;|&nbsp;&nbsp;项目缺陷</span></div>
<div class="cl"></div>
<div class="post-content" style="height:auto;">
<div class="post-all-content c-grey2 mt10" ng-bind-html="issue.description|safeHtml"></div>
<span class="mr15">状态:{{issue.issue_status}}</span> <span class="mr15">优先级:{{issue.issue_priority}}</span> <br />
<span class="mr15">指派给:{{issue.issue_assigned_to}}</span> <span class="mr15">完成度:{{issue.done_ratio}}%</span>
</div>
<div class="cl"></div>
<span class="c-grey f13 mt10 fl">{{issue.created_on}}</span>
<div class="cl"></div>
</div>
<div class="post-interactive border-bottom">
<div class="post-interactive-reply c-grey2">回复 <span class="reply-num">({{issue.journals_count}})</span></div>
<div class="post-interactive-column c-grey2" ng-if="issue.has_praise" ng-click="decreasePraise(issue);">已赞 ({{issue.praise_count}})</div>
<div class="post-interactive-column c-grey2" ng-if="!issue.has_praise" ng-click="addPraise(issue);">赞 ({{issue.praise_count}})</div>
</div>
<div id="all_issue_reply">
<div class="post-reply-wrap border-bottom" ng-repeat="journal in issue.issue_journals">
<div class="post-reply-row">
<div class="post-reply-avatar fl"><img ng-src="{{journal.user.img_url}}" width="45" height="45" class="border-radius" /></div>
<div class="ml55">
<div class="post-reply-user hidden">{{journal.user.realname}}</div>
<div class="post-reply-content c-grey2 mb10" ng-bind-html="journal.notes|safeHtml"></div>
<div class="post-reply-date fl">{{journal.created_on}}</div>
<div class="post-reply-trigger fr undis">回复</div>
</div>
<div class="cl"></div>
</div>
</div>
</div>
<div class="post-input-wrap">
<div class="post-reply-row">
<!--<div class="post-reply-avatar fl"><img src="images/post-avatar.jpg" width="30" height="30" /></div>-->
<input type="text" class="post-reply-input" id="postInput" ng-model="formData.comment" />
<button ng-click="addIssueReply(formData)" class="post-reply-submit fr mt10">回复</button>
<div class="cl"></div>
</div>
</div>
</div>
</div>

@ -0,0 +1,43 @@
<!-- 模板1开始可以使用scripttype设置为text/html来存放模板片段并且用id标示 -->
<div class="post-container">
<div class="post-wrapper">
<div class="post-main">
<div class="post-avatar fl"><img ng-src="{{message.user.img_url}}" width="45" height="45" class="border-radius" /></div>
<div class="post-title mb5 hidden"><a herf="javascript:void(0);" class="mr10">{{message.user.realname}}</a><span style="vertical-align:top;">给您留言了</span><br /></div>
<div class="post-title hidden">{{message.created_on}}</div>
<div class="cl"></div>
<div class="post-content c-grey2 mt10" style="height:auto;">
<div class="post-all-content" ng-bind-html="message.notes|safeHtml"></div>
</div>
<div class="cl"></div>
</div>
<div class="post-interactive border-bottom">
<div class="post-interactive-reply c-grey2">回复 <span class="reply-num">({{message.reply_count}})</span></div>
<div class="post-interactive-column c-grey2" ng-if="message.has_praise" ng-click="decreasePraise(message);">已赞 ({{message.praise_count}})</div>
<div class="post-interactive-column c-grey2" ng-if="!message.has_praise" ng-click="addPraise(message);">赞 ({{message.praise_count}})</div>
</div>
<div id="all_message_reply">
<div class="post-reply-wrap border-bottom" ng-repeat="journal in message.child_reply">
<div class="post-reply-row">
<div class="post-reply-avatar fl"><img ng-src="{{journal.user.img_url}}" width="45" height="45" class="border-radius" /></div>
<div class="ml55">
<div class="post-reply-user hidden">{{journal.user.realname}}</div>
<div class="post-reply-content c-grey2 mb10" ng-bind-html="journal.notes|safeHtml"></div>
<div class="post-reply-date fl">{{journal.lasted_comment}}</div>
<div class="post-reply-trigger fr undis">回复</div>
</div>
<div class="cl"></div>
</div>
</div>
</div>
<div class="post-input-wrap">
<div class="post-reply-row">
<!--<div class="post-reply-avatar fl"><img src="images/post-avatar.jpg" width="30" height="30" /></div>-->
<input type="text" class="post-reply-input" id="postInput" ng-model="formData.comment" />
<button ng-click="addJournalReply(formData)" class="post-reply-submit fr mt10">回复</button>
<div class="cl"></div>
</div>
</div>
</div>
</div>

@ -0,0 +1,45 @@
<!-- 模板1开始可以使用scripttype设置为text/html来存放模板片段并且用id标示 -->
<div class="post-container">
<div class="post-wrapper">
<div class="post-main">
<div class="post-avatar fl"><img ng-src="{{discussion.user.img_url}}" width="45" height="45" class="border-radius" /></div>
<div class="post-title hidden mb5"><span class="c-grey3 f15 fb">{{discussion.subject}}</span></div>
<div class="post-title hidden"><a herf="javascript:void(0);" class="mr10">{{discussion.user.realname}}</a>to<a herf="javascript:void(0);" class="ml10">{{discussion.course_project_name}}&nbsp;&nbsp;|&nbsp;&nbsp;项目讨论区</a></div>
<div class="cl"></div>
<div class="post-content c-grey2 mt10" style="height:auto;">
<div class="post-all-content" ng-bind-html="discussion.content|safeHtml"></div>
</div>
<div class="cl"></div>
<span class="c-grey f13 mt10 fl">{{discussion.created_on}}</span>
<div class="cl"></div>
</div>
<div class="post-interactive border-bottom">
<div class="post-interactive-reply c-grey2">回复 <span class="reply-num">({{discussion.replies_count}})</span></div>
<div class="post-interactive-column c-grey2" ng-if="discussion.has_praise" ng-click="decreasePraise(discussion);">已赞 ({{discussion.praise_count}})</div>
<div class="post-interactive-column c-grey2" ng-if="!discussion.has_praise" ng-click="addPraise(discussion);">赞 ({{discussion.praise_count}})</div>
</div>
<div id="all_course_message_reply">
<div class="post-reply-wrap border-bottom" ng-repeat="journal in discussion.message_children">
<div class="post-reply-row">
<div class="post-reply-avatar fl"><img ng-src="{{journal.user.img_url}}" width="45" height="45" class="border-radius" /></div>
<div class="ml55">
<div class="post-reply-user hidden">{{journal.user.realname}}</div>
<div class="post-reply-content c-grey2 mb10" ng-bind-html="journal.content|safeHtml"></div>
<div class="post-reply-date fl">{{journal.lasted_comment}}</div>
<div class="post-reply-trigger fr undis">回复</div>
</div>
<div class="cl"></div>
</div>
</div>
</div>
<div class="post-input-wrap">
<div class="post-reply-row">
<!--<div class="post-reply-avatar fl"><img src="images/post-avatar.jpg" width="30" height="30" /></div>-->
<input type="text" class="post-reply-input" id="postInput" ng-model="formData.comment" />
<button ng-click="addDiscussionReply(formData)" class="post-reply-submit fr mt10">回复</button>
<div class="cl"></div>
</div>
</div>
</div>
</div>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 171 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 28 KiB

@ -0,0 +1,108 @@
/**
* 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"));

@ -0,0 +1,43 @@
$(function(){
window.byAlert = function(info, title){
if(typeof title === 'undefined'){
title = '提示';
}
$('.weui_dialog_alert .weui_dialog_title').text(title);
$('.weui_dialog_alert .weui_dialog_info').text(info);
var $dialog = $('#dialog2');
$dialog.show();
$dialog.find('.weui_btn_dialog').one('click', function () {
$dialog.hide();
});
};
window.byConfirm = function(info, cb){
var title;
if(typeof title === 'undefined'){
title = '提示';
}
$('.weui_dialog_confirm .weui_dialog_title').text(title);
$('.weui_dialog_confirm .weui_dialog_info').text(info);
var $dialog = $('#dialog1');
$dialog.show();
$dialog.find('.weui_btn_dialog.confirm').one('click', function () {
$dialog.hide();
if(typeof cb === 'function'){
cb();
}
});
$dialog.find('.weui_btn_dialog.cancel').one('click', function () {
$dialog.hide();
});
}
window.closeWindow = function(){
WeixinJSBridge.call('closeWindow');
}
});

@ -0,0 +1,439 @@
var app = angular.module('wechat', ['ngRoute','ngCookies']);
var apiUrl = 'http://wechat.trustie.net/api/v1/';
var debug = false; //调试标志,如果在本地请置为true
if(debug===true){
apiUrl = 'http://localhost:3000/api/v1/';
}
app.factory('auth', function($http,$routeParams, $cookies, $q){
var _openid = '';
if(debug===true){
_openid = "3";
}
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;
if(typeof _openid !== 'undefined' && _openid.length>0){
if(debug !== true){ //如果是生产环境,就存到cookies中
$cookies.put("openid", _openid);
}
} else {
if(debug!==true){//考虑从cookies中取出
_openid = $cookies.get('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($scope, $http, auth, rms, common){
$scope.replaceUrl = function(url){
return "http://www.trustie.net/" + url;
};
console.log("ActivityController load");
$scope.activities = rms.get("activities") || [];
$scope.page = 0;
var loadActData = function(page){
$scope.page = page;
$http({
method: 'POST',
url: apiUrl+ "activities",
data: {openid: auth.openid(), page: page}
}).then(function successCallback(response) {
$scope.current_page = 0;
console.log($scope.current_page);
console.log(response.data.page);
if($scope.current_page < response.data.page) {
$scope.activities = $scope.activities.concat(response.data.data);
} else {
$scope.activities = response.data.data;
}
$scope.current_page = response.data.page;
$scope.all_count = response.data.all_count;
$scope.count = response.data.count;
console.log(response.data);
rms.save('activities', $scope.activities);
}, function errorCallback(response) {
});
};
auth.getOpenId().then(
function successCallback(response){
loadActData($scope.page);
}, function errorCallback(response) {
alert("获取openid出错:"+response);
}
);
$scope.loadActData = loadActData;
$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 userInfo = {
type: type,
content: data.comment,
openid: auth.openid()
};
$http({
method: 'POST',
url: apiUrl+ "new_comment/"+id,
data: userInfo
}).then(function successCallback(response) {
alert("提交成功");
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) {
});
};
loadData($routeParams.id);
$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) {
});
};
loadData($routeParams.id);
$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) {
});
};
loadData($routeParams.id);
$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) {
});
};
loadData($routeParams.id);
$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) {
});
};
loadData($routeParams.id);
$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) {
});
};
loadData($routeParams.id);
$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(4);
var height = e[0].scrollHeight;
var offsetHeight = e[0].offsetHeight;
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.config(['$routeProvider',function ($routeProvider) {
$routeProvider
.when('/activities', {
templateUrl: 'activities.html',
controller: 'ActivityController'
})
.when('/issues/:id', {
templateUrl: 'issue_detail.html',
controller: 'IssueController'
})
.when('/project_discussion/:id', {
templateUrl: 'project_discussion.html',
controller: 'DiscussionController'
})
.when('/homework/:id', {
templateUrl: 'homework_detail.html',
controller: 'HomeworkController'
})
.when('/course_notice/:id', {
templateUrl: 'course_notice.html',
controller: 'CourseNoticeController'
})
.when('/course_discussion/:id', {
templateUrl: 'course_discussion.html',
controller: 'DiscussionController'
})
.when('/journal_for_message/:id', {
templateUrl: 'jour_message_detail.html',
controller: 'JournalsController'
})
.when('/blog_comment/:id', {
templateUrl: 'blog_detail.html',
controller: 'BlogController'
})
.otherwise({
redirectTo: '/activities'
});
}]);

@ -0,0 +1,36 @@
$(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);
}
});
}
});

@ -0,0 +1,95 @@
/**
* 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 + ")");
}
});

@ -0,0 +1,102 @@
/**
* 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 + ")");
}*/
});

@ -0,0 +1,101 @@
/**
* 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 + ")");
}
});

@ -0,0 +1,104 @@
/**
* 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 + ")");
};*/
});

@ -0,0 +1,108 @@
/**
* 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 + ")");
};*/
});

File diff suppressed because one or more lines are too long

@ -0,0 +1,95 @@
/**
* 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 + ")");
}
});

@ -0,0 +1,105 @@
/**
* 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 + ")");
}*/
});

@ -0,0 +1,57 @@
/**
* 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);
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

@ -18,38 +18,67 @@ a:hover{color:#29156f;}
.bg-grey{ background:#f2f2f2;}
/** header **/
.header{ width:100%; height:60px; background:#29146f; padding:5px 0 0px; }
.header{ width:100%; height:60px; padding:5px 0 0px; }
.header-con{ width:1200px; margin:0 auto; }
.logo,.logo img{ display:block; height:52px; }
a.login{ background:url(../images/org_new_style/icons.png) -7px -11px no-repeat; width:146px; height:55px; margin-right:40px; margin-top:11px;}
a:hover.login{ background:url(../images/org_new_style/icons.png) -7px -88px no-repeat; }
a.register{ background:url(../images/org_new_style/icons.png) -190px -11px no-repeat; width:158px; height:55px; ;margin-top:11px;}
a:hover.register{ background:url(../images/org_new_style/icons.png) -190px -88px no-repeat; }
.logo{ position:relative; }
.logo-img{ height:52px; }
.login{ margin-top:15px;}
.login a{ color:#fff; font-size:14px; margin-top:10px; }
.login a{ color:#000; font-size:14px; margin-top:10px; }
.logo-add{ display:block; top:3px; left:0px; position:absolute; width:20px; height:20px;background:url(../images/org_new_style/icons.png) -7px -573px no-repeat;}
/*.header{ width:100%; height:60px; background:#29146f; padding:5px 0 0px; }*/
/*.header-con{ width:1200px; margin:0 auto;}*/
/*.logo,.logo img{ display:block; height:52px; }*/
/*a.login{ background:url(../images/org_new_style/icons.png) -7px -11px no-repeat; width:146px; height:55px; margin-right:40px; margin-top:11px;}*/
/*a:hover.login{ background:url(../images/org_new_style/icons.png) -7px -88px no-repeat; }*/
/*a.register{ background:url(../images/org_new_style/icons.png) -190px -11px no-repeat; width:158px; height:55px; ;margin-top:11px;}*/
/*a:hover.register{ background:url(../images/org_new_style/icons.png) -190px -88px no-repeat; }*/
/*.login{ margin-top:15px;}*/
/*.login a{ color:#fff; font-size:14px; margin-top:10px; }*/
/** nav **/
.nav-box{ width:1200px; height:60px; margin:0 auto;}
.nav a{ display:block; padding:15px 10px; font-size:18px; color:#000; margin-right:20px; }
.navact{border-bottom:3px solid #ffbd18;}
.nav a:hover{border-bottom:3px solid #ffbd18;}
.searchbox{ width:338px; height:57px; border:1px solid #ccc; -webkit-border-radius: 3px;border-radius: 3px; margin:10px 0px 0 0;}
.search-input{width:270px; height:40px; color:#bebebe; font-size:18px; border:1px solid #ccc; -webkit-border-radius: 3px;border-radius: 3px;border:0px; background:none; margin:10px 0 0 20px;}
.search-input:hover{ border:none;color:#fff; }
a.search-icon{ background:url(../images/org_new_style/icons.png) -387px -11px no-repeat; width:40px; height:40px; margin-top:8px;}
a:hover.search-icon{ background:url(../images/org_new_style/icons.png) -387px -89px no-repeat;}
.searchbox:hover{ background:#999999; color:#fff;}
.nav-box{ width:100%; padding:0px 0 5px; background:#eeeeee;}
.nav-con{width:1200px; margin:0 auto; background:#eee;}
.nav{ }
.nav a{ display:block; padding:15px 10px; font-size:18px; color:#666666; background:#eee; border-top:3px solid #eee; margin-right:20px; }
a.navact{border-top:3px solid #ffbd18;}
.nav a:hover{border-top:3px solid #ffbd18;}
/*.nav-box{ width:1200px; height:60px; margin:0 auto;}*/
/*.nav a{ display:block; padding:15px 10px; font-size:18px; color:#000; margin-right:20px; }*/
/*.navact{border-bottom:3px solid #ffbd18;}*/
/*.nav a:hover{border-bottom:3px solid #ffbd18;}*/
/*.searchbox{ width:338px; height:57px; border:1px solid #ccc; -webkit-border-radius: 3px;border-radius: 3px; margin:10px 0px 0 0;}*/
/*.search-input{width:270px; height:40px; color:#bebebe; font-size:18px; border:1px solid #ccc; -webkit-border-radius: 3px;border-radius: 3px;border:0px; background:none; margin:10px 0 0 20px;}*/
/*.search-input:hover{ border:none;color:#fff; }*/
/*a.search-icon{ background:url(../images/org_new_style/icons.png) -387px -11px no-repeat; width:40px; height:40px; margin-top:8px;}*/
/*a:hover.search-icon{ background:url(../images/org_new_style/icons.png) -387px -89px no-repeat;}*/
/*.searchbox:hover{ background:#999999; color:#fff;}*/
/* banner */
.banner{ width:100%; height:234px; background:#070317 url(../images/org_new_style/banner.jpg) 0 0 no-repeat; color:#fff; text-align:center; padding-top:70px; line-height:2.4;}
.banner h2{ font-size:42px; }
.banner p{ font-size:18px;}
.banner span{ font-size:16px;}
.banner{ width:100%; height:304px; color:#fff; text-align:center; line-height:2.4;position:relative;}
.banner-inner{ width:100%; margin:0 auto; text-align:center;}
.banner-img{ height:313px;}
.banner-txt{position:absolute; top:25%; left:35%; width:500px; padding:30px 0; margin:0 auto; background-color:rgba(255,255,255,.3); }
.banner-add{ display:block; position:absolute; top:10%; left:20%;width:27px; height:27px; background:url(../images/org_new_style/icons.png) -39px -570px no-repeat;}
.banner h1{ font-size:42px;}
.banner p{font-size:40px; color:#fff;}
/*.banner{ width:100%; height:304px; background:#070317; color:#fff; text-align:center; line-height:2.4;}*/
/*.banner-inner{ width:1500px; margin:0 auto; position:relative; text-align:center;}*/
/*.banner-img{ height:304px;}*/
/*.banner-txt{position:absolute; top:30%; left:0%; width:1500px; margin:0 auto;}*/
/*.banner h1{ font-size:42px;}*/
/*.banner a{font-size:28px; color:#fff;}*/
/*.banner a:hover{ text-decoration:underline;}*/
/*.banner p{ font-size:18px;}*/
/*.banner span{ font-size:16px;}*/
/** box1 **/
.box1{ width:100%; padding:60px 0;}
.content{ width:1200px; margin:0 auto;}
.box-top{ margin:0 auto; text-align:center; margin-bottom:45px; }
.box-title{ width:355px; height:67px; margin:0 auto; background:#29156f; color:#fff; text-align:center; font-size:40px; font-weight: lighter; margin-bottom:2px;}
.box-title{ width:355px; height:67px; margin:0 auto; border-top:1px solid #ccc; border-bottom:1px solid #ccc; color:#000; text-align:center; font-size:40px; font-weight: lighter; margin-bottom:2px;}
.box-title-p{ font-size:20px; color:#999999;}
.row{ width:1200px; margin: 0 auto; }
.row-box1{ width:365px;}
@ -61,8 +90,6 @@ a:hover.search-icon{ background:url(../images/org_new_style/icons.png) -387px -8
.row-txt{line-height:2.4; padding-bottom:10px; margin-bottom:10px; color:#888;}
.row-txt:hover{color:#29156f;}
.row-txt-line{border-bottom:1px solid #cccccc; width:365px;}
a.btn-more{ display:block; font-size:14px; width:110px; height:40px; -webkit-border-radius: 3px;border-radius: 3px;background:#ffbd18; color:#fff; text-align:center; line-height:3.0;}
a:hover.btn-more{ background:#29156f;}
.row-box2{ width:388px; border:1px solid #ccc; border-bottom:none;}
.row-con2 a{ display:block;padding:20px 10px; border-bottom:1px solid #ccc;}
.row-con2 a:hover{ background:#29156f; color:#fff;}
@ -70,6 +97,30 @@ a:hover.btn-more{ background:#29156f;}
.row-txt2{line-height:2.4; color:#888;}
.row-txt2:hover{ color:#fff; }
/*.box1{ width:100%; padding:60px 0;}*/
/*.content{ width:1200px; margin:0 auto;}*/
/*.box-top{ margin:0 auto; text-align:center; margin-bottom:45px; }*/
/*.box-title{ width:355px; height:67px; margin:0 auto; background:#29156f; color:#fff; text-align:center; font-size:40px; font-weight: lighter; margin-bottom:2px;}*/
/*.box-title-p{ font-size:20px; color:#999999;}*/
/*.row{ width:1200px; margin: 0 auto; }*/
/*.row-box1{ width:365px;}*/
/*.row-img{ margin-bottom:10px; width:365px; height:230px; display:block;}*/
/*.row-time{ color:#ffbd18; font-size:14px; font-weight:bold; line-height:1.9;}*/
/*.row-title{ font-size:16px; font-weight:bold; line-height:1.9;display:block;white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}*/
/*.row-con { display:block; }*/
/*.row-con:hover{ color:#29156f; }*/
/*.row-txt{line-height:2.4; padding-bottom:10px; margin-bottom:10px; color:#888;}*/
/*.row-txt:hover{color:#29156f;}*/
/*.row-txt-line{border-bottom:1px solid #cccccc; width:365px;}*/
/*a.btn-more{ display:block; font-size:14px; width:110px; height:40px; -webkit-border-radius: 3px;border-radius: 3px;background:#ffbd18; color:#fff; text-align:center; line-height:3.0;}*/
/*a:hover.btn-more{ background:#29156f;}*/
/*.row-box2{ width:388px; border:1px solid #ccc; border-bottom:none;}*/
/*.row-con2 a{ display:block;padding:20px 10px; border-bottom:1px solid #ccc;}*/
/*.row-con2 a:hover{ background:#29156f; color:#fff;}*/
/*.row-con2 a:hover{ color:#fff;}*/
/*.row-txt2{line-height:2.4; color:#888;}*/
/*.row-txt2:hover{ color:#fff; }*/
/** 活动专区 **/
.con-left{ width:618px;}
.con-left-box{ margin-bottom:20px; height:96px; display:block;}
@ -90,7 +141,7 @@ a.con-arrow-btn{ display: block;width:25px;height:25px;background:url(../images/
a.pre-arrow,a.pre-back{ display:block; width:25px; height:10px; background:#29156f; margin-left:5px;}
a.pre-back{ background:#888;}
/** footer **/
.footer{ height:150px; background:#29156f; width:100%;}
.footer{ height:150px; background:#bbb; width:100%;}
.footer-con{ width:1200px; padding:30px 0 0 60px; margin:0 auto; text-align:center; font-size:14px; color:#fff;}
.footer-con ul{ display:block; width:430px; height:50px; margin:0 auto; }
.footer-con ul li a{font-size:18px; color:#fff; margin-right:35px; font-weight:bold;}
@ -175,14 +226,17 @@ a:hover.read-more{ text-decoration:underline;}
opacity: 1;
}
a.more-btn{ display:block; background:#ccc; color:#fff; margin-top:10px; width:100px; height:38px;font-size:14px; -webkit-border-radius: 5px;border-radius:5px;text-align:center; line-height:38px;}
a.more-btn{ display:block; border:1px solid #ccc; color:#000; margin-top:10px; width:120px; height:38px;font-size:14px; -webkit-border-radius: 25px;border-radius:25px;text-align:center; line-height:38px; margin:0 auto; margin-top:30px;}
a.more-btn-center{ display:block; border:1px solid #ccc; color:#000; margin-top:10px; width:120px; height:38px;font-size:14px; -webkit-border-radius: 25px;border-radius:25px;text-align:center; line-height:38px; margin:0 auto; margin-top:30px;}
a:hover.more-btn{ background:#29146f; color:#fff;}
a:hover.more-btn-center{ background:#29146f; color:#fff;}
a:hover.more-btn-center{ background:#aaa; color:#fff;}
.mt30{ margin-top:30px;}
/*a.more-btn{ display:block; background:#ccc; color:#fff; margin-top:10px; width:100px; height:38px;font-size:14px; -webkit-border-radius: 5px;border-radius:5px;text-align:center; line-height:38px;}*/
/*a.more-btn{ display:block; border:1px solid #ccc; color:#000; margin-top:10px; width:120px; height:38px;font-size:14px; -webkit-border-radius: 25px;border-radius:25px;text-align:center; line-height:38px; margin:0 auto; margin-top:30px;}*/
/*a.more-btn-center{ display:block; border:1px solid #ccc; color:#000; margin-top:10px; width:120px; height:38px;font-size:14px; -webkit-border-radius: 25px;border-radius:25px;text-align:center; line-height:38px; margin:0 auto; margin-top:30px;}*/
/*a:hover.more-btn{ background:#29146f; color:#fff;}*/
/*a:hover.more-btn-center{ background:#29146f; color:#fff;}*/
/*.mt30{ margin-top:30px;}*/
.nocontent{ font-size:30px; color:#888; margin:150px auto; text-align:center;}
/** 帖子列表模式 **/
@ -274,3 +328,5 @@ div.ui-progressbar { width: 100px; height:14px; margin: 2px 0 -5px 8px; display:

@ -0,0 +1,63 @@
@charset "utf-8";
/* CSS Document */
/*基本样式*/
body,table,input,textarea,select,button { font-family: "微软雅黑","宋体";}
h1,h2,h3,h4,h5,p {padding:0px; margin:0px;}
.f13 {font-size:13px;}
.f15 {font-size:15px;}
.fb {font-weight:bold;}
.mt5 {margin-top:5px;}
.mt10 {margin-top:10px;}
.mb5 {margin-bottom:5px;}
.mb10 {margin-bottom:10px;}
.ml10 {margin-left:10px;}
.mr10 {margin-right:10px;}
.ml15 {margin-left:15px;}
.mr15 {margin-right:15px;}
.ml55 {margin-left:55px;}
.mr55 {margin-right:55px;}
.c-blue {color:#269ac9;}
.c-grey {color:#9a9a9a;}
.c-grey2 {color:#707070;}
.c-grey3 {color:#555555;}
a {color:#707070;}
a.c-grey {color:#707070;}
a:link,a:visited{text-decoration:none;}
a:hover,a:active{cursor:pointer;}
a.link-blue {color:#269ac9;}
a.underline {text-decoration:underline;}
.border-radius {border-radius:5px;}
.max-width-60 {max-width:60px;}
.max-width-130 {max-width:130px;}
.hidden {overflow:hidden; white-space:nowrap; text-overflow:ellipsis;}
.inline-block {display:inline-block;}
.undis {display:none;}
/*动态样式*/
.post-container {width:100%;}
.post-wrapper {width:98%; border:1px solid #e6e6e6; border-radius:3px; background-color:#ffffff; margin:15px auto;}
.post-main {padding:10px; color:#9a9a9a;}
.post-avatar {width:45px; height:45px; margin-right:10px;}
.post-title {font-size:13px; text-align:left;}
.fl {float:left;}
.fr {float:right;}
.cl {clear:both; overflow:hidden;}
.post-content {width:100%; font-size:13px; line-height:18px; height:90px; overflow:hidden; word-break:break-all; word-wrap:break-word;}
.post-interactive {width:100%; height:35px; line-height:35px; vertical-align:middle; border-top:1px solid #e6e6e6; background-color:#f8f9fb;}
.post-interactive-column {width:50%; text-align:center; float:left; font-size:13px;}
.post-interactive-reply {width:50%; text-align:center; float:left; font-size:13px;}
.post-interactive-praise {width:50%; text-align:center; float:left; font-size:13px;}
.more-wrap {width:100%;}
.more-events {width:98%; font-size:13px; text-align:center; margin:0 auto; padding: 5px 0; border:1px solid #e6e6e6; border-radius:3px; background-color:#f8f9fb; }
.border-bottom {border-bottom:1px solid #e6e6e6;}
.post-reply-wrap {width:100%; line-height:18px; background-color:#f8f9fb;}
.post-input-wrap {width:100%; line-height:18px; background-color:#f8f9fb;}
.post-reply-row {padding:10px; color:#9a9a9a;}
.post-reply-avatar {width:45px; height:30px; text-align:center; margin-right:10px;}
.post-reply-user {font-size:13px; text-align:left; margin-bottom:10px;}
.post-reply-content {font-size:13px; text-align:left; word-break:break-all; word-wrap:break-word; overflow:hidden;}
.post-reply-date {font-size:13px;}
.post-reply-trigger {font-size:13px;}
.post-reply-input {width:100%; height:28px; line-height:28px; border:1px solid #e6e6e6; outline:none; border-radius:3px;}
.post-reply-submit {font-size:13px; padding:3px 8px; color:#fff; background-color:#269ac9; outline:none; border:none; display:inline-block;}

File diff suppressed because one or more lines are too long

@ -1 +0,0 @@
just test
Loading…
Cancel
Save