diff --git a/app/assets/javascripts/forums.js b/app/assets/javascripts/forums.js
new file mode 100644
index 000000000..dee720fac
--- /dev/null
+++ b/app/assets/javascripts/forums.js
@@ -0,0 +1,2 @@
+// Place all the behaviors and hooks related to the matching controller here.
+// All this logic will automatically be available in application.js.
diff --git a/app/assets/javascripts/memos.js b/app/assets/javascripts/memos.js
new file mode 100644
index 000000000..dee720fac
--- /dev/null
+++ b/app/assets/javascripts/memos.js
@@ -0,0 +1,2 @@
+// Place all the behaviors and hooks related to the matching controller here.
+// All this logic will automatically be available in application.js.
diff --git a/app/assets/stylesheets/forums.scss b/app/assets/stylesheets/forums.scss
new file mode 100644
index 000000000..fafd631e1
--- /dev/null
+++ b/app/assets/stylesheets/forums.scss
@@ -0,0 +1,3 @@
+// Place all the styles related to the forums controller here.
+// They will automatically be included in application.css.
+// You can use Sass (SCSS) here: http://sass-lang.com/
diff --git a/app/controllers/concerns/paginate_helper.rb b/app/controllers/concerns/paginate_helper.rb
index 34740eb5d..bbe84a348 100644
--- a/app/controllers/concerns/paginate_helper.rb
+++ b/app/controllers/concerns/paginate_helper.rb
@@ -1,7 +1,7 @@
module PaginateHelper
def paginate(objs, **opts)
page = params[:page].to_i <= 0 ? 1 : params[:page].to_i
- per_page = params[:per_page].to_i > 0 ? params[:per_page].to_i : opts[:per_page] || 20
+ per_page = params[:per_page].to_i > 0 && params[:per_page].to_i < 50 ? params[:per_page].to_i : opts[:per_page] || 20
Kaminari.paginate_array(objs).page(page).per(per_page)
end
diff --git a/app/controllers/forums_controller.rb b/app/controllers/forums_controller.rb
new file mode 100644
index 000000000..82573fdd0
--- /dev/null
+++ b/app/controllers/forums_controller.rb
@@ -0,0 +1,2 @@
+class ForumsController < ApplicationController
+end
diff --git a/app/controllers/users/base_controller.rb b/app/controllers/users/base_controller.rb
index afc03ee13..fd138a182 100644
--- a/app/controllers/users/base_controller.rb
+++ b/app/controllers/users/base_controller.rb
@@ -26,9 +26,22 @@ class Users::BaseController < ApplicationController
render_forbidden
end
+ def page_value
+ params[:page].to_i <= 0 ? 1 : params[:page].to_i
+ end
+
+ def per_page_value
+ params[:per_page].to_i > 0 && params[:per_page].to_i < 50 ? params[:per_page].to_i : 20
+ end
+ alias_method :limit_value, :per_page_value
+
+ def offset_value
+ (page_value - 1) * limit_value
+ end
+
def paginate(objs, **opts)
- page = params[:page].to_i <= 0 ? 1 : params[:page].to_i
- per_page = params[:per_page].to_i > 0 ? params[:per_page].to_i : 20
+ page = page_value
+ per_page = per_page_value
return Kaminari.paginate_array(objs).page(page).per(per_page) unless observed_logged_user? && opts[:special]
diff --git a/app/controllers/users/private_message_details_controller.rb b/app/controllers/users/private_message_details_controller.rb
new file mode 100644
index 000000000..486d23d7f
--- /dev/null
+++ b/app/controllers/users/private_message_details_controller.rb
@@ -0,0 +1,23 @@
+class Users::PrivateMessageDetailsController < Users::BaseController
+ before_action :private_user_resources!
+
+ after_action :update_message_status, only: [:show]
+
+ def show
+ messages = observed_user.private_messages.without_deleted.where(target: target_user)
+
+ @count = messages.count
+ @messages = messages.order(send_time: :asc).includes(sender: :user_extension)
+ end
+
+ private
+
+ def target_user
+ @_target_user ||= User.find(params[:target_id])
+ end
+
+ # 置为已读
+ def update_message_status
+ observed_user.private_messages.only_unread.where(target: target_user).update_all(status: 1)
+ end
+end
\ No newline at end of file
diff --git a/app/controllers/users/private_messages_controller.rb b/app/controllers/users/private_messages_controller.rb
new file mode 100644
index 000000000..b80b6152b
--- /dev/null
+++ b/app/controllers/users/private_messages_controller.rb
@@ -0,0 +1,39 @@
+class Users::PrivateMessagesController < Users::BaseController
+ before_action :private_user_resources!
+ after_action :update_onclick_time!, only: [:index]
+
+ def index
+ @count = observed_user.private_messages.without_deleted.group(:target_id).count.count
+
+ subquery = observed_user.private_messages.without_deleted.order(send_time: :desc).to_sql
+ query = "SELECT subquery.*, COUNT(*) message_count FROM (#{subquery}) subquery "\
+ "GROUP BY subquery.target_id ORDER BY subquery.send_time desc LIMIT #{limit_value} OFFSET #{offset_value}"
+ @messages = PrivateMessage.select('*').from("(#{query}) AS query").includes(target: :user_extension)
+ end
+
+ def create
+ receiver = User.find_by(id: params[:target_id])
+ return render_error('用户未找到') if receiver.blank?
+
+ @message = PrivateMessages::CreateService.call(observed_user, receiver, create_params)
+ rescue PrivateMessages::CreateService::Error => ex
+ render_error(ex.message)
+ end
+
+ def destroy
+ message = observed_user.private_messages.without_deleted.find(params[:id])
+ message.destroy!
+
+ render_ok
+ end
+
+ private
+
+ def update_onclick_time!
+ current_user.onclick_time.touch(:onclick_time)
+ end
+
+ def create_params
+ params.permit(:content)
+ end
+end
\ No newline at end of file
diff --git a/app/controllers/users/recent_contacts_controller.rb b/app/controllers/users/recent_contacts_controller.rb
new file mode 100644
index 000000000..bc4b8ea8f
--- /dev/null
+++ b/app/controllers/users/recent_contacts_controller.rb
@@ -0,0 +1,8 @@
+class Users::RecentContactsController < Users::BaseController
+ before_action :private_user_resources!
+
+ def index
+ contacts = observed_user.recent_contacts.distinct
+ @contacts = contacts.order('private_messages.created_at DESC').limit(10).includes(:user_extension)
+ end
+end
\ No newline at end of file
diff --git a/app/controllers/users/unread_message_infos_controller.rb b/app/controllers/users/unread_message_infos_controller.rb
new file mode 100644
index 000000000..7abd36304
--- /dev/null
+++ b/app/controllers/users/unread_message_infos_controller.rb
@@ -0,0 +1,12 @@
+class Users::UnreadMessageInfosController < Users::BaseController
+ before_action :private_user_resources!
+
+ def show
+ click_time = observed_user.click_time
+
+ unread_tiding_count = observed_user.tidings.where('created_at > ?', click_time).count
+ unread_message_count = observed_user.private_messages.only_unread.group(:target_id).count.count
+
+ render_ok(unread_tiding_count: unread_tiding_count, unread_message_count: unread_message_count)
+ end
+end
\ No newline at end of file
diff --git a/app/controllers/users_for_private_messages_controller.rb b/app/controllers/users_for_private_messages_controller.rb
new file mode 100644
index 000000000..bbd5682a1
--- /dev/null
+++ b/app/controllers/users_for_private_messages_controller.rb
@@ -0,0 +1,17 @@
+class UsersForPrivateMessagesController < ApplicationController
+ before_action :require_login, :check_auth
+
+ def index
+ users = User.active.where.not(id: current_user.id)
+
+ keyword = params[:keyword].to_s.strip
+ if keyword.blank?
+ @users = []
+ return
+ end
+
+ users = users.where('LOWER(concat(lastname, firstname, nickname)) LIKE ?', "%#{keyword}%")
+
+ @users = users.limit(10).includes(:user_extension)
+ end
+end
\ No newline at end of file
diff --git a/app/decorators/private_message_decorator.rb b/app/decorators/private_message_decorator.rb
new file mode 100644
index 000000000..6db17acf3
--- /dev/null
+++ b/app/decorators/private_message_decorator.rb
@@ -0,0 +1,9 @@
+module PrivateMessageDecorator
+ extend ApplicationDecorator
+
+ display_time_method :send_time
+
+ def unread?
+ status.zero?
+ end
+end
\ No newline at end of file
diff --git a/app/helpers/export_helper.rb b/app/helpers/export_helper.rb
index 6af88de33..5d36c465f 100644
--- a/app/helpers/export_helper.rb
+++ b/app/helpers/export_helper.rb
@@ -497,7 +497,7 @@ module ExportHelper
def make_zip_name(work, file_name="")
Rails.logger.info("######################file_name: #{file_name}")
# name = file_name === "" ? "" : (file_name[0, file_name.rindex('.')]+"_")
- "#{work&.user&.student_id}_#{work.&user.&real_name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}"
+ "#{work&.user&.student_id}_#{work&.user&.real_name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}"
end
def zipping(zip_name_refer, files_paths, output_path, is_attachment=false, not_exist_file=[])
diff --git a/app/helpers/forums_helper.rb b/app/helpers/forums_helper.rb
new file mode 100644
index 000000000..2e531fd46
--- /dev/null
+++ b/app/helpers/forums_helper.rb
@@ -0,0 +1,2 @@
+module ForumsHelper
+end
diff --git a/app/models/forum.rb b/app/models/forum.rb
new file mode 100644
index 000000000..88aafa676
--- /dev/null
+++ b/app/models/forum.rb
@@ -0,0 +1,2 @@
+class Forum < ApplicationRecord
+end
diff --git a/app/models/private_message.rb b/app/models/private_message.rb
index 1db4c9f66..640e48db7 100644
--- a/app/models/private_message.rb
+++ b/app/models/private_message.rb
@@ -1,3 +1,9 @@
class PrivateMessage < ApplicationRecord
belongs_to :user
+ belongs_to :target, class_name: "User"
+ belongs_to :sender, class_name: "User"
+ belongs_to :receiver, class_name: "User"
+
+ scope :without_deleted, -> { where.not(status: 2) }
+ scope :only_unread, -> { where(status: 0) }
end
diff --git a/app/models/user.rb b/app/models/user.rb
index 14d7b2697..ed9d70c00 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -54,7 +54,8 @@ class User < ApplicationRecord
has_one :onclick_time, :dependent => :destroy
# 新版私信
- has_many :private_messages, :dependent => :destroy
+ has_many :private_messages, dependent: :destroy
+ has_many :recent_contacts, through: :private_messages, source: :target
has_many :tidings, :dependent => :destroy
has_many :games, :dependent => :destroy
diff --git a/app/services/private_messages/create_service.rb b/app/services/private_messages/create_service.rb
new file mode 100644
index 000000000..560f1a540
--- /dev/null
+++ b/app/services/private_messages/create_service.rb
@@ -0,0 +1,35 @@
+class PrivateMessages::CreateService < ApplicationService
+ Error = Class.new(StandardError)
+
+ attr_reader :sender, :receiver, :params
+
+ def initialize(sender, receiver, **params)
+ @sender = sender
+ @receiver = receiver
+ @params = params
+ end
+
+ def call
+ validate!
+
+ same_attr = { sender: sender, receiver: receiver, content: content, send_time: Time.now }
+
+ message = nil
+ ActiveRecord::Base.transaction do
+ message = sender.private_messages.create!(same_attr.merge(target: receiver, status: 1))
+ receiver.private_messages.create!(same_attr.merge(target: sender, status: 0))
+ end
+ message
+ end
+
+ private
+
+ def content
+ @_content ||= params[:content].to_s.strip
+ end
+
+ def validate!
+ raise Error, '内容不能为空' if content.blank?
+ raise Error, '内容太长' if content.size > 255
+ end
+end
\ No newline at end of file
diff --git a/app/services/project_packages/save_service.rb b/app/services/project_packages/save_service.rb
index bcfc19a10..a876f56b3 100644
--- a/app/services/project_packages/save_service.rb
+++ b/app/services/project_packages/save_service.rb
@@ -15,7 +15,7 @@ class ProjectPackages::SaveService < ApplicationService
is_create = package.new_record?
raise Error, '类型不存在' unless ProjectPackageCategory.where(id: params[:category_id]).exists?
- params[:project_package_category_id] = params[:category_id].to_i
+ params[:project_package_category_id] = params.delete(:category_id).to_i
raise Error, '竞标截止时间不能小于当前时间' if params[:deadline_at].present? && params[:deadline_at].to_time < Time.now
@@ -25,7 +25,9 @@ class ProjectPackages::SaveService < ApplicationService
end
ActiveRecord::Base.transaction do
- package.assign_attributes(params)
+ columns = %i[project_package_category_id title content deadline_at
+ min_price max_price contact_name contact_phone]
+ package.assign_attributes(params.slice(*columns))
package.save!
# 处理附件
diff --git a/app/views/users/private_message_details/show.json.jbuilder b/app/views/users/private_message_details/show.json.jbuilder
new file mode 100644
index 000000000..065767fb4
--- /dev/null
+++ b/app/views/users/private_message_details/show.json.jbuilder
@@ -0,0 +1,11 @@
+json.count @count
+json.messages do
+ json.array! @messages.each do |message|
+ json.extract! message, :id, :user_id, :receiver_id, :sender_id, :content
+
+ json.send_time message.display_send_time
+ json.sender do
+ json.partial! 'users/user_simple', user: message.sender
+ end
+ end
+end
\ No newline at end of file
diff --git a/app/views/users/private_messages/create.json.jbuilder b/app/views/users/private_messages/create.json.jbuilder
new file mode 100644
index 000000000..888cfeff6
--- /dev/null
+++ b/app/views/users/private_messages/create.json.jbuilder
@@ -0,0 +1,10 @@
+json.status 0
+json.message 'success'
+json.private_message do
+ json.extract! @message, :id, :user_id, :receiver_id, :sender_id, :content
+
+ json.send_time @message.display_send_time
+ json.sender do
+ json.partial! 'users/user_simple', user: @message.sender
+ end
+end
\ No newline at end of file
diff --git a/app/views/users/private_messages/index.json.jbuilder b/app/views/users/private_messages/index.json.jbuilder
new file mode 100644
index 000000000..c18a7d209
--- /dev/null
+++ b/app/views/users/private_messages/index.json.jbuilder
@@ -0,0 +1,13 @@
+json.count @count
+json.private_messages do
+ json.array! @messages.each do |message|
+ json.extract! message, :id, :content, :message_count
+
+ json.unread message.unread?
+ json.send_time message.display_send_time
+
+ json.target do
+ json.partial! 'users/user_simple', user: message.target
+ end
+ end
+end
\ No newline at end of file
diff --git a/app/views/users/recent_contacts/index.json.jbuilder b/app/views/users/recent_contacts/index.json.jbuilder
new file mode 100644
index 000000000..f2f7f025a
--- /dev/null
+++ b/app/views/users/recent_contacts/index.json.jbuilder
@@ -0,0 +1,2 @@
+json.users @contacts, partial: 'users/user_simple', as: :user
+json.count @contacts.size
\ No newline at end of file
diff --git a/app/views/users_for_private_messages/index.json.jbuilder b/app/views/users_for_private_messages/index.json.jbuilder
new file mode 100644
index 000000000..be040e368
--- /dev/null
+++ b/app/views/users_for_private_messages/index.json.jbuilder
@@ -0,0 +1,2 @@
+json.users @users, partial: 'users/user_simple', as: :user
+json.count @users.size
\ No newline at end of file
diff --git a/config/routes.rb b/config/routes.rb
index 6623edd99..2f9eed61b 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -53,6 +53,11 @@ Rails.application.routes.draw do
resource :grade_records, only: [:show]
resource :watch, only: [:create, :destroy]
resources :project_packages, only: [:index]
+ # 私信
+ resources :private_messages, only: [:index, :create, :destroy]
+ resources :recent_contacts, only: [:index]
+ resource :private_message_details, only: [:show]
+ resource :unread_message_info, only: [:show]
end
@@ -91,6 +96,7 @@ Rails.application.routes.draw do
end
end
end
+ resources :users_for_private_messages, only: [:index]
resources :myshixuns, param: :identifier, shallow: true do
member do
diff --git a/db/migrate/20190730070155_create_forums.rb b/db/migrate/20190730070155_create_forums.rb
new file mode 100644
index 000000000..f1f6eb96a
--- /dev/null
+++ b/db/migrate/20190730070155_create_forums.rb
@@ -0,0 +1,8 @@
+class CreateForums < ActiveRecord::Migration[5.2]
+ def change
+ create_table :forums do |t|
+
+ t.timestamps
+ end
+ end
+end
diff --git a/public/react/src/modules/courses/busyWork/CommonWorkDetailIndex.js b/public/react/src/modules/courses/busyWork/CommonWorkDetailIndex.js
index a690fedc0..2d3361492 100644
--- a/public/react/src/modules/courses/busyWork/CommonWorkDetailIndex.js
+++ b/public/react/src/modules/courses/busyWork/CommonWorkDetailIndex.js
@@ -305,9 +305,6 @@ class CommonWorkDetailIndex extends Component{
.floatSpinParent .ant-spin-nested-loading {
float: right;
}
- .floatSpinParent .ant-spin-nested-loading .ant-spin-spinning{
- top: 10px;
- }
`}
{this.props.isAdmin()?
+ {this.props.current_user&&this.props.current_user.phone!=null&&modalCancel===false?
手机号: @@ -861,7 +861,7 @@ class PackageIndexNEIBannerConcent extends Component {
:""} {/*{this.state.current_userphonetype===true?+ {this.props.current_user&&this.props.current_user.phone===null||modalCancel===true?
{/*未注册才显示!*/}
diff --git a/public/react/src/modules/tpm/NewHeader.js b/public/react/src/modules/tpm/NewHeader.js
index 23330e779..1798bfca8 100644
--- a/public/react/src/modules/tpm/NewHeader.js
+++ b/public/react/src/modules/tpm/NewHeader.js
@@ -718,7 +718,7 @@ submittojoinclass=(value)=>{