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/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb index d1357d43f..e60e37bce 100644 --- a/app/controllers/accounts_controller.rb +++ b/app/controllers/accounts_controller.rb @@ -160,7 +160,7 @@ class AccountsController < ApplicationController # 发送验证码 # params[:login] 手机号或者邮箱号 - # params[:type]为事件通知类型 1:用户注册注册 2:忘记密码 3: 绑定手机 4: 绑定邮箱 # 如果有新的继续后面加 + # params[:type]为事件通知类型 1:用户注册注册 2:忘记密码 3: 绑定手机 4: 绑定邮箱, 5: 验收手机号有效 # 如果有新的继续后面加 # 发送验证码:send_type 1:注册手机验证码 2:找回密码手机验证码 3:找回密码邮箱验证码 4:绑定手机 5:绑定邮箱 # 6:手机验证码登录 7:邮箱验证码登录 8:邮箱注册验证码 9: 验收手机号有效 def get_verification_code @@ -200,7 +200,7 @@ class AccountsController < ApplicationController session[:user_id] = nil end - # type 事件类型 1:用户注册 2:忘记密码 3: 绑定手机 4: 绑定邮箱 # 如果有新的继续后面加 + # type 事件类型 1:用户注册 2:忘记密码 3: 绑定手机 4: 绑定邮箱, 5: 验证手机号是否有效 # 如果有新的继续后面加 # login_type 1:手机类型 2:邮箱类型 def verify_type login_type, type case type @@ -212,6 +212,8 @@ class AccountsController < ApplicationController login_type == 1 ? 4 : tip_exception('请填写正确的手机号') when 4 login_type == 1 ? tip_exception('请填写正确的邮箱') : 5 + when 5 + login_type == 1 ? 9 : tip_exception('请填写正确的手机号') end end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index f01ad4b6b..7aa89dbd7 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -38,6 +38,7 @@ class ApplicationController < ActionController::Base def user_course_identity @user_course_identity = current_user.course_identity(@course) if @user_course_identity > Course::STUDENT && @course.is_public == 0 + tip_exception(401, "..") unless User.current.logged? tip_exception(409, "您没有权限进入") end uid_logger("###############user_course_identity:#{@user_course_identity}") @@ -63,10 +64,10 @@ class ApplicationController < ActionController::Base # 发送及记录激活码 # 发送验证码:type 1:注册手机验证码 2:找回密码手机验证码 3:找回密码邮箱验证码 4:绑定手机 5:绑定邮箱 - # 6:手机验证码登录 7:邮箱验证码登录 8:邮箱注册验证码 + # 6:手机验证码登录 7:邮箱验证码登录 8:邮箱注册验证码 9:验证手机号有效 def check_verification_code(code, send_type, value) case send_type - when 1, 2, 4 + when 1, 2, 4, 9 # 手机类型的发送 sigle_para = {phone: value} status = Educoder::Sms.send(mobile: value, code: code) @@ -240,14 +241,17 @@ class ApplicationController < ActionController::Base User.current = User.find 57703 end - if params[:debug] == 'teacher' #todo 为了测试,记得讲debug删除 - User.current = User.find 81403 - elsif params[:debug] == 'student' - User.current = User.find 8686 - elsif params[:debug] == 'admin' - User.current = User.find 1 - end + # 测试版前端需求 + if request.host == "47.96.87.25" + if params[:debug] == 'teacher' #todo 为了测试,记得讲debug删除 + User.current = User.find 81403 + elsif params[:debug] == 'student' + User.current = User.find 8686 + elsif params[:debug] == 'admin' + User.current = User.find 1 + end + end # User.current = User.find 81403 end @@ -582,4 +586,8 @@ class ApplicationController < ActionController::Base def render_parameter_missing render json: { status: -1, message: '参数缺失' } end + + def set_export_cookies + cookies[:fileDownload] = true + end end 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/courses_controller.rb b/app/controllers/courses_controller.rb index bdb367111..abc3e4856 100644 --- a/app/controllers/courses_controller.rb +++ b/app/controllers/courses_controller.rb @@ -1027,10 +1027,13 @@ class CoursesController < ApplicationController tip_exception(403,"无权限操作") elsif @all_members.size == 0 normal_status(-1,"课堂暂时没有学生") + elsif params[:export].present? && params[:export] + normal_status(0,"正在下载中") else + set_export_cookies member_to_xlsx(@course, @all_members, @c_homeworks, @c_exercises, @c_tasks) - filename_ = "#{current_user.real_name}_#{@course.name}_全部成绩" - render xlsx: "#{format_sheet_name filename_.strip.first(30)}",template: "courses/export_member_scores_excel.xlsx.axlsx", + filename_ = "#{current_user.real_name}_#{@course.name}_全部成绩_#{Time.now.strftime('%Y%m%d_%H%M%S')}" + render xlsx: "#{format_sheet_name filename_.strip}",template: "courses/export_member_scores_excel.xlsx.axlsx", locals: {course_info:@course_info, activity_level:@user_activity_level, course_scores:@course_user_scores,shixun_works:@shixun_work_arrays, common_works:@common_work_arrays,group_works:@group_work_arrays,task_works:@task_work_arrays, diff --git a/app/controllers/discusses_controller.rb b/app/controllers/discusses_controller.rb index 3b987be51..6a270f619 100644 --- a/app/controllers/discusses_controller.rb +++ b/app/controllers/discusses_controller.rb @@ -1,7 +1,7 @@ class DiscussesController < ApplicationController LIMIT = 10 before_action :find_container, only: [:index, :hidden] - before_action :find_discuss, except: [:create, :index, :new_message, :reward_code] + before_action :find_discuss, except: [:create, :index, :new_message, :reward_code, :forum_discusses] def index page = params[:page].to_i @@ -28,6 +28,48 @@ class DiscussesController < ApplicationController @current_user = current_user end + def forum_discusses + page = params[:page] || 1 + limit = params[:limit] || 15 + offset = (page.to_i-1) * limit + search = params[:search] + tag = params[:tag_repertoire_id] + sql, sql1, sql2 = '', '', '' + sql1 = + unless search.blank? + "and d.content like '%#{search}%'" + end + + sql2 = + if tag + shixun_ids = ShixunTagRepertoire.where(:tag_repertoire_id => tag).pluck(:shixun_id) + "and d.dis_id in(#{shixun_ids.join(",")})" + end + + sql = "select d.id from discusses d join shixuns s on d.dis_id = s.id where s.status = 2 and s.hidden = false and d.root_id is null + and d.hidden = false #{sql1} #{sql2} order by d.created_at desc" + + memo_ids = Discuss.find_by_sql(sql).pluck(:id) + @memo_count = memo_ids.size + memo_ids = memo_ids[offset, limit] + order_ids = memo_ids.size > 0 ? memo_ids.join(',') : -1 + @memos = Discuss.where(id: memo_ids).order("field(id,#{order_ids})").includes(:praise_treads, dis: :tag_repertoires, user: :user_extension) + # @memos = memos.includes(:praise_treads, user: :user_extension).page(page).per(limit) + # 实训标签使用最多的9个 + # @hot_tags = TagRepertoire.find_by_sql("select distinct(a.name), a.id from + # (select tr.id, tr.name, count(d.dis_id) cnt + # from tag_repertoires tr join (shixun_tag_repertoires str + # left join (shixuns s join discusses d on d.dis_id = s.id) + # on s.id = str.shixun_id) on tr.id = str.tag_repertoire_id + # group by d.dis_id order by cnt desc) a limit 9").map{|ht| ht.attributes.dup} + tag_id = ShixunTagRepertoire.joins(:shixun).order("myshixuns_count desc").pluck(:tag_repertoire_id).uniq.first(9) + @hot_tags = TagRepertoire.select([:id, :name]).where(id: tag_id).order("FIELD(id, #{tag_id.join(",")})").map{|ht| ht.attributes.dup} if tag_id + + @memos = DiscussesService.new.memo_list @memos + @hot_memos = Memo.field_for_recommend.posts.hot.includes(:tag_repertoires).limit(4) + @recommend_shixuns = DiscussesService.new.recommends + end + def new_message onclick_time = Myshixun.find(params[:myshixun_id]).try(:onclick_time) ids = Discuss.where(user_id: User.current.id, dis_id: params[:container_id], dis_type: params[:container_type]). diff --git a/app/controllers/exercises_controller.rb b/app/controllers/exercises_controller.rb index 03c943f8d..6f121db5f 100644 --- a/app/controllers/exercises_controller.rb +++ b/app/controllers/exercises_controller.rb @@ -1256,13 +1256,16 @@ class ExercisesController < ApplicationController normal_status(-1,"试卷未发布") elsif (@exercise_users_size == 0) || ( @export_ex_users&.exercise_user_committed.size == 0) normal_status(-1,"暂无用户提交") + elsif params[:export].present? && params[:export] + normal_status(0,"正在下载中") else respond_to do |format| format.xlsx{ + set_export_cookies get_export_users(@exercise,@course,@export_ex_users) exercise_export_name_ = "#{current_user.real_name}_#{@course.name}_#{@exercise.exercise_name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}" - render xlsx: "#{exercise_export_name_.strip.first(30)}",template: "exercises/exercise_lists.xlsx.axlsx",locals: {table_columns:@table_columns,exercise_users:@user_columns} + render xlsx: "#{exercise_export_name_.strip}",template: "exercises/exercise_lists.xlsx.axlsx",locals: {table_columns:@table_columns,exercise_users:@user_columns} } end end @@ -1281,7 +1284,12 @@ class ExercisesController < ApplicationController @exercise_questions = @exercise.exercise_questions.includes(:exercise_choices).order("question_number ASC") filename_ = "#{@exercise.user.real_name}_#{@course.name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}.pdf" stylesheets = "#{Rails.root}/app/templates/exercise_export/exercise_export.css" - render pdf: 'exercise_export/blank_exercise', filename: filename_, stylesheets: stylesheets + if params[:export].present? && params[:export] + normal_status(0,"正在下载中") + else + set_export_cookies + render pdf: 'exercise_export/blank_exercise', filename: filename_, stylesheets: stylesheets + end end #空白试卷预览页面,仅供测试使用,无其他任何用途 diff --git a/app/controllers/games_controller.rb b/app/controllers/games_controller.rb index b2de6dcad..b3b062c1a 100644 --- a/app/controllers/games_controller.rb +++ b/app/controllers/games_controller.rb @@ -116,10 +116,11 @@ class GamesController < ApplicationController @qrcode_str = Base64.encode64( qr.to_img.resize(400,400).to_s ) else - @type = "image" #conv = Iconv.new("GBK", "utf-8") @game_challenge = @game.challenge type = @game_challenge.show_type + @type = shixun_show_type type + workspace_path = @game.try(:picture_path) @answer_path = "#{Rails.root}/#{workspace_path}/#{@game_challenge.expect_picture_path}" @user_path = "#{Rails.root}/#{workspace_path}/#{@game_challenge.picture_path}" diff --git a/app/controllers/graduation_tasks_controller.rb b/app/controllers/graduation_tasks_controller.rb index ab99e8d86..0885eeae2 100644 --- a/app/controllers/graduation_tasks_controller.rb +++ b/app/controllers/graduation_tasks_controller.rb @@ -132,12 +132,14 @@ class GraduationTasksController < ApplicationController tip_exception(403, "无权限操作") elsif complete_works == 0 normal_status(-1,"暂无用户提交") + elsif params[:export].present? && params[:export] + normal_status(0,"正在下载中") else respond_to do |format| format.xlsx{ graduation_work_to_xlsx(@work_excel,@task,current_user) task_export_name_ = "#{current_user.real_name}_#{@course.name}_#{@task.name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}" - render xlsx: "#{task_export_name_.strip.first(30)}",template: "graduation_tasks/tasks_list.xlsx.axlsx",locals: {table_columns:@head_cells_column, task_users:@task_cells_column} + render xlsx: "#{task_export_name_.strip}",template: "graduation_tasks/tasks_list.xlsx.axlsx",locals: {table_columns:@head_cells_column, task_users:@task_cells_column} } end end @@ -148,12 +150,17 @@ class GraduationTasksController < ApplicationController zip_works = @work_excel.where("work_status > 0") status = checkfileSize(zip_works) if status == 0 - respond_to do |format| - format.zip{ - zipfile = zip_homework_common @task, zip_works - file = decode64(zipfile[0][:base64file]) - send_file "#{OUTPUT_FOLDER}/#{file}", filename: filename_for_content_disposition(file), type: 'application/zip' - } + if params[:export].present? && params[:export] + normal_status(0,"正在下载中") + else + respond_to do |format| + format.zip{ + set_export_cookies + zipfile = zip_homework_common @task, zip_works + file = decode64(zipfile[0][:base64file]) + send_file "#{OUTPUT_FOLDER}/#{file}", filename: filename_for_content_disposition(file), type: 'application/zip' + } + end end else normal_status(status,status == -2 ? "500M" : "无附件可下载") diff --git a/app/controllers/graduation_topics_controller.rb b/app/controllers/graduation_topics_controller.rb index 754b472c5..bd93401f3 100644 --- a/app/controllers/graduation_topics_controller.rb +++ b/app/controllers/graduation_topics_controller.rb @@ -271,7 +271,12 @@ class GraduationTopicsController < ApplicationController students = course.students.joins(user: :user_extension).order("user_extensions.student_id") graduation_topic_to_xlsx(students,course) topic_export_name_ = "#{current_user.real_name}_#{course.name}_毕设选题_#{Time.now.strftime('%Y%m%d_%H%M%S')}" - render xlsx: "#{topic_export_name_.strip.first(30)}",template: "graduation_topics/export.xlsx.axlsx",locals: {table_columns:@topic_head_cells,topic_users:@topic_body_cells} + if params[:export].present? && params[:export] + normal_status(0,"正在下载中") + else + set_export_cookies + render xlsx: "#{topic_export_name_.strip}",template: "graduation_topics/export.xlsx.axlsx",locals: {table_columns:@topic_head_cells,topic_users:@topic_body_cells} + end rescue Exception => e uid_logger(e.message) missing_template diff --git a/app/controllers/homework_commons_controller.rb b/app/controllers/homework_commons_controller.rb index 5cccb3ee7..603a59920 100644 --- a/app/controllers/homework_commons_controller.rb +++ b/app/controllers/homework_commons_controller.rb @@ -207,9 +207,12 @@ class HomeworkCommonsController < ApplicationController tip_exception(403, "无权限操作") elsif @work_excel.blank? || @work_excel.size == 0 normal_status(-1,"暂无用户提交!") + elsif params[:export].present? && params[:export] + normal_status(0,"正在下载中") else respond_to do |format| format.xlsx{ + set_export_cookies student_work_to_xlsx(@work_excel,@homework) exercise_export_name = "#{current_user.real_name}_#{@course.name}_#{@homework.name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}" render xlsx: "#{exercise_export_name.strip}",template: "homework_commons/works_list.xlsx.axlsx",locals: @@ -229,12 +232,17 @@ class HomeworkCommonsController < ApplicationController end if status == 0 - respond_to do |format| - format.zip{ - zipfile = zip_homework_common @homework, zip_works - file = decode64(zipfile[0][:base64file]) - send_file "#{OUTPUT_FOLDER}/#{file}", filename: filename_for_content_disposition(file), type: 'application/zip' - } + if params[:export].present? && params[:export] + normal_status(0,"正在下载中") + else + respond_to do |format| + format.zip{ + set_export_cookies + zipfile = zip_homework_common @homework, zip_works + file = decode64(zipfile[0][:base64file]) + send_file "#{OUTPUT_FOLDER}/#{file}", filename: filename_for_content_disposition(file), type: 'application/zip' + } + end end else normal_status(status, status == -2 ? "500M" : "无附件可下载") @@ -328,7 +336,7 @@ class HomeworkCommonsController < ApplicationController @messages = @messages.parent_comment end - @messages = @messages.page(@page).per(@limit).order("created_on desc") + @messages = @messages.includes(:praise_treads).page(@page).per(@limit).order("created_on desc") end def reference_answer diff --git a/app/controllers/memos_controller.rb b/app/controllers/memos_controller.rb index 723f2e9a4..66adcc46b 100644 --- a/app/controllers/memos_controller.rb +++ b/app/controllers/memos_controller.rb @@ -1,5 +1,9 @@ class MemosController < ApplicationController - before_action :set_memo, only: [:show, :edit, :update, :destroy] + before_action :require_login, except: [:show, :index] + before_action :set_memo, only: [:show, :edit, :update, :destroy, :sticky_or_cancel, :hidden, :more_reply] + before_action :validate_memo_params, only: [:create, :update] + before_action :owner_or_admin, only: [:edit, :update, :destroy] + before_action :is_admin, only: [:sticky_or_cancel, :hidden] include ApplicationHelper # GET /memos @@ -8,27 +12,21 @@ class MemosController < ApplicationController @user = current_user @memos = Memo.all s_order = (params[:order] == "replies_count" ? "all_replies_count" : params[:order]) || "updated_at" - #@tidding_count = unviewed_tiddings(current_user) if current_user.present? - page = params[:page].to_i + # @tidding_count = unviewed_tiddings(current_user) if current_user.present? + page = params[:page] || 1 + limit = params[:limit] || 15 search = params[:search] - offset = page * 15 forum_id = params[:forum] - user_id = params[:user_id] - if user_id == -1 - user_id = current_user.try(:id) - end tag_repertoire_id = params[:tag_repertoire_id] sql = if forum_id - search ? "forum_id = #{forum_id} and root_id is null and subject like '%#{search}%'" : + !search.blank? ? "forum_id = #{forum_id} and root_id is null and subject like '%#{search}%'" : "forum_id = #{forum_id} and root_id is null" - elsif search - user_id ? "author_id = #{user_id.to_i} and forum_id in(3, 5) and root_id is null and subject like '%#{search}%'" : - "forum_id in(3, 5) and root_id is null and subject like '%#{search}%'" + elsif !search.blank? + "forum_id in(3, 5) and root_id is null and subject like '%#{search}%'" else - user_id ? "author_id = #{user_id.to_i} and forum_id in(3, 5) and root_id is null" : - "forum_id in(3, 5) and root_id is null" + "forum_id in(3, 5) and root_id is null" end if tag_repertoire_id @@ -41,75 +39,74 @@ class MemosController < ApplicationController sql += " and all_replies_count != 0" end - memos = Memo.field_for_list.includes(:praise_tread, :author).where("#{sql}") + memos = Memo.field_for_list.where("#{sql}") @memos_count = memos.length - @memos = memos.order("sticky = 1 desc, #{Memo.table_name}.#{s_order} desc").offset(offset).limit(15) - @my_memos_count = Memo.user_posts(current_user.try(:id)).count + @memos = memos.order("sticky = 1 desc, #{Memo.table_name}.#{s_order} desc").page(page).per(limit) + @memos = @memos.includes(:praise_treads, :tag_repertoires, author: :user_extension) + # @my_memos_count = Memo.user_posts(current_user.try(:id)).count @tags_info = MemoTagRepertoire.find_by_sql("SELECT tag_repertoire_id, tr.name, count(*) cnt FROM memo_tag_repertoires mtr join tag_repertoires tr on tr.id = mtr.tag_repertoire_id group by tag_repertoire_id order by cnt desc, tag_repertoire_id desc limit 9") - @hot_memos = Memo.field_for_recommend.posts.hot.limit(4) + @hot_memos = Memo.field_for_recommend.posts.hot.includes(:tag_repertoires).limit(4) + @recommend_shixuns = DiscussesService.new.recommends end - # GET /memos/1 # GET /memos/1.json def show # tidding_count = unviewed_tiddings(current_user) if current_user @user = current_user - # TODO 附件最后再做 - # attachments_list = @memo.update_column(:viewed_count, @memo.viewed_count+1) - @memos = @memo.reply_for_memo.includes(:praise_tread, :author).order("created_at desc").limit(10) - + @memos = @memo.reply_for_memo.includes(:praise_treads, author: :user_extension).order("created_at desc").limit(10) + @attachments = @memo.attachments + @recommend_shixuns = DiscussesService.new.recommends end # GET /memos/new def new - @csrf_token = session[:_csrf_toke] ||= SecureRandom.base64(32) @tag_list = TagRepertoire.field_for_list.order("name asc") - end # GET /memos/1/edit def edit + @tag_list = TagRepertoire.field_for_list.order("name asc") + @memo_tags = @memo.tag_repertoires.field_for_list + @attachments = @memo.attachments end - # POST /memos # POST /memos.json def create ActiveRecord::Base.transaction do begin @memo = Memo.new(memo_params) @memo.author = current_user - # TODO 保存附件 - # @memo.save_attachments(params[:attachments]) if params[:attachments] @memo.save! + Attachment.associate_container(params[:attachment_ids], @memo.id, @memo.class.name) params[:tags].each do |tag| - MemoTagRepertoire.create(:memo_id => @memo.id, :tag_repertoire_id => tag) + MemoTagRepertoire.create!(memo_id: @memo.id, tag_repertoire_id: tag) end - @status = 0 - @message = "帖子创建成功!" + normal_status("帖子创建成功") rescue Exception => e - @status = -1 - @message = "帖子创建失败,原因:#{e}" + tip_exception("帖子创建失败,原因:#{e}") raise ActiveRecord::Rollback end end - - end - # PATCH/PUT /memos/1 # PATCH/PUT /memos/1.json def update - respond_to do |format| - if @memo.update(memo_params) - format.html { redirect_to @memo, notice: 'Memo was successfully updated.' } - format.json { render :show, status: :ok, location: @memo } - else - format.html { render :edit } - format.json { render json: @memo.errors, status: :unprocessable_entity } + ActiveRecord::Base.transaction do + begin + @memo.update_attributes!(memo_params) + Attachment.associate_container(params[:attachment_ids], @memo.id, @memo.class.name) + @memo.memo_tag_repertoires.destroy_all + params[:tags].each do |tag| + MemoTagRepertoire.create!(memo_id: @memo.id, tag_repertoire_id: tag) + end + normal_status("帖子更新成功") + rescue Exception => e + tip_exception("帖子更新失败,原因:#{e}") + raise ActiveRecord::Rollback end end end @@ -118,21 +115,88 @@ class MemosController < ApplicationController # DELETE /memos/1.json def destroy @memo.destroy - respond_to do |format| - format.html { redirect_to memos_url, notice: 'Memo was successfully destroyed.' } - format.json { head :no_content } + normal_status("删除成功") + end + + def sticky_or_cancel + tip_exception("只能对主贴进行置顶操作") unless @memo.parent_id.nil? + begin + @memo.update_attributes!(sticky: !@memo.sticky) + normal_status("更新成功") + rescue Exception => e + tip_exception("更新失败,原因:#{e}") + raise ActiveRecord::Rollback end end - private - # Use callbacks to share common setup or constraints between actions. - def set_memo - @memo = Memo.find(params[:id]) + def hidden + tip_exception("不能对主贴进行隐藏操作") if @memo.parent_id.nil? + begin + @memo.update_attributes!(hidden: !@memo.hidden) + normal_status("更新成功") + rescue Exception => e + tip_exception("更新失败,原因:#{e}") + raise ActiveRecord::Rollback end + end + + def reply + tip_exception("parent_id不能为空") if params[:parent_id].blank? + tip_exception("content不能为空") if params[:content].blank? - # Never trust parameters from the scary internet, only allow the white list through. - def memo_params - params.fetch(:memo, {}) + ActiveRecord::Base.transaction do + begin + memo = Memo.find_by!(id: params[:parent_id]) + reply = Memo.new + reply.content = params[:content] + reply.author = current_user + reply.forum_id = memo.forum_id + reply.subject = memo.subject + reply.root_id = memo.root_id || memo.id + memo.children << reply + m = Memo.find_by!(id: reply.root_id) + m.increment!(:all_replies_count) + normal_status("回复成功") + rescue Exception => e + tip_exception("回复失败,原因:#{e}") + raise ActiveRecord::Rollback + end end + end + + def more_reply + @user = current_user + page = params[:page] || 2 + limit = params[:limit] || 10 + offset = (page.to_i - 1) * limit + @memos_count = Memo.where(parent_id: @memo.id).count + @memos = Memo.limit(limit).where(parent_id: @memo.id).includes(:author, :praise_treads).order("created_at desc").offset(offset) + end + + private + # Use callbacks to share common setup or constraints between actions. + def set_memo + @memo = Memo.find(params[:id]) + end + + def owner_or_admin + tip_exception(403, "无权限操作") unless @memo.author == current_user || current_user.admin? || current_user.business? + end + + def is_admin + tip_exception(403, "无权限操作") unless current_user.admin? || current_user.business? + end + + # Never trust parameters from the scary internet, only allow the white list through. + def memo_params + params.require(:memo).permit(:subject, :content, :forum_id) + end + + def validate_memo_params + tip_exception("话题名称不能为空") if params[:subject].blank? + tip_exception("话题内容不能为空") if params[:content].blank? + tip_exception("话题类型不能为空") if params[:forum_id].blank? + tip_exception("技术标签不能为空") if params[:tags].blank? + end end diff --git a/app/controllers/myshixuns_controller.rb b/app/controllers/myshixuns_controller.rb index fa47fd7f6..1d6b15969 100644 --- a/app/controllers/myshixuns_controller.rb +++ b/app/controllers/myshixuns_controller.rb @@ -24,7 +24,7 @@ class MyshixunsController < ApplicationController ActiveRecord::Base.transaction do begin @shixun = Shixun.select(:id, :identifier).find(@myshixun.shixun_id) - @myshixun.destroy + @myshixun.destroy! StudentWork.where(:myshixun_id => @myshixun.id).update_all(:myshixun_id => 0, :work_status => 0) diff --git a/app/controllers/polls_controller.rb b/app/controllers/polls_controller.rb index 4348b3bfc..7d978d722 100644 --- a/app/controllers/polls_controller.rb +++ b/app/controllers/polls_controller.rb @@ -945,12 +945,15 @@ class PollsController < ApplicationController tip_exception(403,"无权限操作") elsif (@poll.polls_status == 1) || (@poll_export_questions.size == 0) || (@poll_commit_ids.size == 0) normal_status(-1,"暂无用户提交") + elsif params[:export].present? && params[:export] + normal_status(0,"正在下载中") else respond_to do |format| format.xlsx{ + set_export_cookies polls_export_name_ = "#{current_user.real_name}_#{@course.name}_#{@poll.polls_name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}" polls_user_commit = poll_commit_result(@poll,@poll_export_questions,@poll_users,@poll_commit_ids) - render xlsx: "#{polls_export_name_.strip.first(30)}",template: "polls/commit_result.xlsx.axlsx",locals: {polls_user_commit:polls_user_commit} + render xlsx: "#{polls_export_name_.strip}",template: "polls/commit_result.xlsx.axlsx",locals: {polls_user_commit:polls_user_commit} } end end diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index c9ed6c597..672477790 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -1,10 +1,2 @@ class ProjectsController < ApplicationController - def search - query_params = { keyword: params[:keyword], category: 'manage' } - projects = Users::ProjectService.new(current_user, query_params).call - - params[:limit] = params[:per_page].to_i.zero? ? 20 : params[:per_page].to_i - @count = projects.count - @projects = paginate projects - end end \ No newline at end of file diff --git a/app/controllers/shixuns_controller.rb b/app/controllers/shixuns_controller.rb index 6c3f34a60..26effd12e 100644 --- a/app/controllers/shixuns_controller.rb +++ b/app/controllers/shixuns_controller.rb @@ -714,6 +714,7 @@ class ShixunsController < ApplicationController end end rescue Exception => e + logger.info("shixun_exec error: #{e.message}") if e.message != "ActiveRecord::RecordInvalid" logger.error("##########project_fork error #{e.message}") @myshixun.destroy! diff --git a/app/controllers/student_works_controller.rb b/app/controllers/student_works_controller.rb index f9f4717a6..a5d46e46a 100644 --- a/app/controllers/student_works_controller.rb +++ b/app/controllers/student_works_controller.rb @@ -457,8 +457,8 @@ class StudentWorksController < ApplicationController @myself_eff = @echart_data[:efficiency_list].find { |item| item.last == @user.id } @myself_consume = @echart_data[:consume_list].find { |item| item.last == @user.id } - filename_ = "实训报告_#{@shixun&.name}_#{@use&.real_name}" - filename = Base64.urlsafe_encode64(filename_.strip.first(30)) + filename_ = "#{@use&.student_id}_#{@use&.real_name}_#{@shixun&.name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}" + filename = Base64.urlsafe_encode64(filename_.strip) stylesheets = %w(shixun_work/shixun_work.css shared/codemirror.css) render pdf: 'shixun_work/shixun_work', filename: filename, stylesheets: stylesheets end diff --git a/app/controllers/users/base_controller.rb b/app/controllers/users/base_controller.rb index afc03ee13..969aca320 100644 --- a/app/controllers/users/base_controller.rb +++ b/app/controllers/users/base_controller.rb @@ -26,11 +26,24 @@ 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] + return Kaminari.paginate_array(objs).page(page).per(per_page) unless opts[:special] && observed_logged_user? # note: 为实现第一页少一条记录,让前端放置新建入口 if page == 1 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/projects_controller.rb b/app/controllers/users/projects_controller.rb index 863b99b37..07f4d5cac 100644 --- a/app/controllers/users/projects_controller.rb +++ b/app/controllers/users/projects_controller.rb @@ -1,4 +1,6 @@ class Users::ProjectsController < Users::BaseController + skip_before_action :check_observed_user_exists!, only: [:search] + def index projects = Users::ProjectService.new(observed_user, query_params).call @@ -6,6 +8,15 @@ class Users::ProjectsController < Users::BaseController @projects = paginate(projects.includes(:project_score, owner: { user_extension: :school }), special: true) end + def search + query_params = { keyword: params[:keyword], category: 'manage' } + projects = Users::ProjectService.new(current_user, query_params).call + + params[:limit] = params[:per_page].to_i.zero? ? 20 : params[:per_page].to_i + @count = projects.count + @projects = paginate projects + end + private def query_params 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/controllers/zips_controller.rb b/app/controllers/zips_controller.rb index f4822b96b..3ed1eb8b3 100644 --- a/app/controllers/zips_controller.rb +++ b/app/controllers/zips_controller.rb @@ -8,7 +8,13 @@ class ZipsController < ApplicationController def shixun_report service = BatchExportShixunReportService.new(@homework, @all_student_works) filename_ = filename_for_content_disposition(service.filename) - send_file service.zip, filename: filename_, type: 'application/zip' + if params[:export].present? && params[:export] + normal_status(0,"正在下载中") + else + set_export_cookies + send_file service.zip, filename: filename_, type: 'application/zip' + end + rescue BatchExportShixunReportService::Error => ex normal_status(-1, ex.message) end @@ -18,7 +24,12 @@ class ZipsController < ApplicationController exercises = ExportExercisesService.new(@exercise,@ex_users,@request_url) file_name_ = filename_for_content_disposition(exercises.filename) - send_file exercises.ex_zip, filename: file_name_, type: 'application/zip' + if params[:export].present? && params[:export] + normal_status(0,"正在下载中") + else + set_export_cookies + send_file exercises.ex_zip, filename: file_name_, type: 'application/zip' + end rescue Exception => e normal_status(-1, e.message) end 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/application_helper.rb b/app/helpers/application_helper.rb index 5df86ef54..7e9fd652b 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -329,6 +329,23 @@ module ApplicationHelper content end + def strip_html(text, len=0, endss="...") + ss = "" + if !text.nil? && text.length>0 + ss=text.gsub(/<\/?.*?>/, '').strip + ss = ss.gsub(/ */, '') + ss = ss.gsub(/\r\n/,'') #新增 + ss = ss.gsub(/\n/,'') #新增 + if len > 0 && ss.length > len + ss = ss[0, len] + endss + elsif len > 0 && ss.length <= len + ss = ss + #ss = truncate(ss, :length => len) + end + end + ss + end + def strip_export_title(content) con_ = "" if content.length > 0 diff --git a/app/helpers/export_helper.rb b/app/helpers/export_helper.rb index 742deb85b..5d36c465f 100644 --- a/app/helpers/export_helper.rb +++ b/app/helpers/export_helper.rb @@ -418,7 +418,7 @@ module ExportHelper end end - out_file_name = "#{Time.now.to_i}_#{homework_common.name}.zip" + out_file_name = "作品附件_#{homework_common&.course&.name}_#{homework_common.name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}.zip" out_file_name.gsub!(" ", "-") out_file_name.gsub!("/", "_") out_file = find_or_pack(homework_common, homework_common.user_id, digests.sort){ @@ -496,8 +496,8 @@ 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('.')]+"_") - "#{name}#{work.user.real_name}_#{((work.user.student_id.nil?) ? "" : work.user.student_id)}" + # 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')}" end def zipping(zip_name_refer, files_paths, output_path, is_attachment=false, not_exist_file=[]) diff --git a/app/helpers/games_helper.rb b/app/helpers/games_helper.rb index aff05904f..5a9871673 100644 --- a/app/helpers/games_helper.rb +++ b/app/helpers/games_helper.rb @@ -6,7 +6,7 @@ module GamesHelper end # 获取目录下所有文件,返回一个文件名的数组 type是查看文件的类型image表示图片 - # type [[1, "图片"], [2, "apk/exe"], [3, "txt"], [4, "html"]] + # type [[1, "图片"], [2, "apk/exe"], [3, "txt"], [4, "html"], [5, "mp3"], [6, "mp4"]] def get_dir_filename(path, type, game_id) answer_picture = [] return answer_picture unless File.directory?(path) @@ -39,6 +39,12 @@ module GamesHelper end f.close @type = 'txt' + elsif extension == 'mp3' && type == 5 + answer_picture << file + @type = 'mp3' + elsif extension == 'mp4' && type == 6 + answer_picture << file + @type = 'mp4' end end @@ -51,4 +57,21 @@ module GamesHelper "编译失败,请在测试结果中查看具体的错误信息" : test_set.try(:actual_output) end end + + def shixun_show_type type + case type.to_i + when 1 + "image" + when 2 + "apk/exe" + when 3 + "txt" + when 4 + "html" + when 5 + "mp3" + when 6 + "mp4" + end + end end diff --git a/app/helpers/memos_helper.rb b/app/helpers/memos_helper.rb index 7df887a4b..434d9b66a 100644 --- a/app/helpers/memos_helper.rb +++ b/app/helpers/memos_helper.rb @@ -1,2 +1,6 @@ module MemosHelper + + def forum_list + [{id: 5, name: "技术分享"}, {id: 3, name: "操作指南"}] + end end diff --git a/app/models/challenge.rb b/app/models/challenge.rb index 0bea54eb4..8e4d2ae42 100644 --- a/app/models/challenge.rb +++ b/app/models/challenge.rb @@ -1,5 +1,6 @@ class Challenge < ApplicationRecord # difficulty: 关卡难度: 1.简单 2.中等 3.困难 + # show_type: 效果展示:-1.无效果 1.图片 2.apk/exe 3.txt 4.html 5.mp3 6.mp4 default_scope { order("challenges.position asc") } belongs_to :shixun, :touch => true, counter_cache: true diff --git a/app/models/discuss.rb b/app/models/discuss.rb index 2d9c00110..a50b18a6f 100644 --- a/app/models/discuss.rb +++ b/app/models/discuss.rb @@ -8,6 +8,7 @@ class Discuss < ApplicationRecord has_many :praise_treads, as: :praise_tread_object, dependent: :destroy has_many :tidings, as: :container, dependent: :destroy has_one :praise_tread_cache, as: :object, dependent: :destroy + belongs_to :dis, polymorphic: true belongs_to :challenge after_create :send_tiding @@ -44,6 +45,10 @@ class Discuss < ApplicationRecord Discuss.where(parent_id: self.id).includes(:user).reorder(created_at: :asc) end + def child_discuss_count + Discuss.where(root_id: id).count + end + private def send_tiding 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/memo.rb b/app/models/memo.rb index 610a7684d..e70a7cec9 100644 --- a/app/models/memo.rb +++ b/app/models/memo.rb @@ -1,10 +1,12 @@ class Memo < ApplicationRecord include Searchable::Memo - has_many :memo_tag_repertoires, :dependent => :destroy + belongs_to :forum, touch: true + + has_many :memo_tag_repertoires, dependent: :destroy has_many :tag_repertoires, :through => :memo_tag_repertoires - has_many :praise_tread, as: :praise_tread_object, dependent: :destroy + has_many :praise_treads, as: :praise_tread_object, dependent: :destroy has_one :praise_tread_cache, as: :object, dependent: :destroy belongs_to :author, class_name: 'User', foreign_key: 'author_id' @@ -12,6 +14,7 @@ class Memo < ApplicationRecord has_many :descendants, foreign_key: :root_id, class_name: 'Memo' has_many :children, foreign_key: :parent_id, class_name: 'Memo' + has_many :attachments, as: :container, dependent: :destroy scope :field_for_list, lambda{ select([:id, :subject, :author_id, :sticky, :updated_at, :language, :reward, :all_replies_count, :viewed_count, :forum_id]) 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/tiding.rb b/app/models/tiding.rb index 3ef625c57..90abdf809 100644 --- a/app/models/tiding.rb +++ b/app/models/tiding.rb @@ -13,9 +13,14 @@ class Tiding < ApplicationRecord value = container.try(:identifier) end + if value.blank? && parent_container_type && Object.const_defined?(parent_container_type) + value = parent_container_type.try(:identifier) + end + if value.blank? && belong_container_type && Object.const_defined?(belong_container_type) value = belong_container.try(:identifier) end + value end end \ No newline at end of file diff --git a/app/models/user.rb b/app/models/user.rb index 14d7b2697..b453f9998 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 @@ -439,7 +440,7 @@ class User < ApplicationRecord end def manager_of_memo?(memo) - id == memo.author_id || admin? + id == memo.author_id || admin? || business? end # 是否是项目管理者 diff --git a/app/services/batch_export_shixun_report_service.rb b/app/services/batch_export_shixun_report_service.rb index d71235790..253eb4480 100644 --- a/app/services/batch_export_shixun_report_service.rb +++ b/app/services/batch_export_shixun_report_service.rb @@ -14,7 +14,7 @@ class BatchExportShixunReportService end def filename - @_filename ||= "#{homework.name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}" + @_filename ||= "实训报告_#{homework&.course&.name}_#{homework.name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}" end def zip diff --git a/app/services/discusses_service.rb b/app/services/discusses_service.rb index 91fa523c9..c14850a4c 100644 --- a/app/services/discusses_service.rb +++ b/app/services/discusses_service.rb @@ -148,30 +148,6 @@ class DiscussesService @discuss = Discuss.select([:id, :hidden, :reward, :dis_type, :dis_id, :position, :challenge_id, :root_id]).find(id) end - protected - def memo_list memos - memos.map do |m| - user = User.find(m.user_id) - praise_count = m.praise_tread.where(:praise_or_tread => 1).count - replies_count = Discuss.where(:root_id => m.id).count - shixun_tag = m.dis.tag_repertoires.map(&:name) - m.attributes.dup.except("user_id", "dis_id", "dis_type", "root_id").merge({ - subject: (message_content m.content), - username: user.show_name, - login: user.login, - praise_count: praise_count, - replies_count: replies_count, - image_url: url_to_avatar(user), - shixun_tag: shixun_tag, - tpm_url: "/shixuns/#{m.dis.identifier}/shixun_discuss" - }) - end - end - - def format_for_current_user current_user - {username: current_user.show_name, login: current_user.login, user_id: current_user.id, image_url: url_to_avatar(current_user), admin: current_user.admin?} - end - def recommends hot_shixuns = Shixun.field_for_recommend.published.order("myshixuns_count desc").limit(2) newest_shixuns = Shixun.field_for_recommend.published.order("created_at desc").limit(2) @@ -185,6 +161,30 @@ class DiscussesService return recommend_shixuns end + def memo_list memos + memos.map do |m| + user = m.user + # praise_count = m.praise_treads.select{|pt| pt.praise_or_tread == 1}.count + replies_count = m.child_discuss_count + shixun_tag = m.dis.tag_repertoires.map(&:name) + m.attributes.dup.except("user_id", "dis_id", "dis_type", "root_id", "praise_count", "content").merge({ + subject: (message_content m.content), + username: user.full_name, + login: user.login, + replies_count: replies_count, + image_url: url_to_avatar(user), + shixun_tag: shixun_tag, + tpm_url: "/shixuns/#{m.dis.identifier}/shixun_discuss" + }) + end + end + + protected + + def format_for_current_user current_user + {username: current_user.show_name, login: current_user.login, user_id: current_user.id, image_url: url_to_avatar(current_user), admin: current_user.admin?} + end + # 将数据库对象转换成哈希对象 def object_to_hash objects objects.map{|o| o.attributes.dup} diff --git a/app/services/exercise_user_pdf_service.rb b/app/services/exercise_user_pdf_service.rb index 73711192f..6891e53ea 100644 --- a/app/services/exercise_user_pdf_service.rb +++ b/app/services/exercise_user_pdf_service.rb @@ -15,8 +15,8 @@ class ExerciseUserPdfService end def filename - user_course = @course.course_members.find_by(user_id:@ex_user_user.id)&.course_group_name - exercise_user_name = "#{@ex_user_user.real_name}_#{user_course.present? ? user_course : "未分班"}_#{exercise.exercise_name}_#{Time.now.strftime('%Y%m%d_%H%M')}" + # user_course = @course.course_members.find_by(user_id:@ex_user_user.id)&.course_group_name + exercise_user_name = "#{@ex_user_user&.student_id}_#{@ex_user_user.real_name}_#{exercise.exercise_name}_#{Time.now.strftime('%Y%m%d_%H%M')}" "#{exercise_user_name.strip}.pdf" end diff --git a/app/services/export_exercises_service.rb b/app/services/export_exercises_service.rb index ca2d347a6..1f1e15326 100644 --- a/app/services/export_exercises_service.rb +++ b/app/services/export_exercises_service.rb @@ -10,7 +10,7 @@ class ExportExercisesService end def filename - exercise_export_name = "#{exercise.user.real_name}_#{exercise.exercise_name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}" + exercise_export_name = "学生答题_#{exercise&.course&.name}_#{exercise.exercise_name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}" "#{exercise_export_name.strip}.zip" end diff --git a/app/services/export_shixun_report_service.rb b/app/services/export_shixun_report_service.rb index f9da3d6f2..57b955762 100644 --- a/app/services/export_shixun_report_service.rb +++ b/app/services/export_shixun_report_service.rb @@ -10,7 +10,7 @@ class ExportShixunReportService end def filename - @_filename ||= "#{homework.name}-#{work.user&.student_id}-#{work.user.real_name}.pdf".gsub(' ', '-').gsub('/', '_') + @_filename ||= "#{work.user&.student_id}_#{work.user.real_name}_#{homework.name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}.pdf".gsub(' ', '-').gsub('/', '_') end def prepare_binding diff --git a/app/services/private_messages/create_service.rb b/app/services/private_messages/create_service.rb new file mode 100644 index 000000000..88f3a084f --- /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/services/projects/apply_join_service.rb b/app/services/projects/apply_join_service.rb index a177de930..d14b3dc52 100644 --- a/app/services/projects/apply_join_service.rb +++ b/app/services/projects/apply_join_service.rb @@ -22,7 +22,7 @@ class Projects::ApplyJoinService < ApplicationService apply.forge_activities.find_or_create_by!(user: user, project: project) - notify_project_manager! + notify_project_manager!(apply) end # notify_project_owner @@ -47,10 +47,13 @@ class Projects::ApplyJoinService < ApplicationService end end - def notify_project_manager! + def notify_project_manager!(apply) columns = %i[user_id applied_id applied_type status viewed applied_user_id role project_id created_at updated_at] AppliedMessage.bulk_insert(*columns) do |worker| - base_attr = { status: false, viewed: false, applied_user_id: user.id, role: role_value, project_id: project.id } + base_attr = { + applied_id: apply.id, applied_type: 'AppliedProject', status: false, viewed: false, + applied_user_id: user.id, role: role_value, project_id: project.id + } project.manager_members.each do |manager| worker.add(base_attr.merge(user_id: manager.user_id)) diff --git a/app/views/courses/search_users.json.jbuilder b/app/views/courses/search_users.json.jbuilder index ac826fdf2..61362de66 100644 --- a/app/views/courses/search_users.json.jbuilder +++ b/app/views/courses/search_users.json.jbuilder @@ -1,6 +1,7 @@ json.users do json.array! @users do |user| json.id user.id + json.login user.login json.name user.real_name json.student_id user&.student_id json.school_name user&.school_name diff --git a/app/views/discusses/forum_discusses.json.jbuilder b/app/views/discusses/forum_discusses.json.jbuilder new file mode 100644 index 000000000..3b1aefd89 --- /dev/null +++ b/app/views/discusses/forum_discusses.json.jbuilder @@ -0,0 +1,27 @@ +json.memo_list @memos +# do |memo| +# json.(memo, :id, :updated_at, :reward) +# json.subject message_content(memo.content) +# json.praise_count memo.praises_count +# json.replies_count memo.child_discuss_count +# json.shixun_tag memo.dis.tag_repertoires.map(&:name) +# json.username memo.user.full_name +# json.login memo.user.login +# json.image_url url_to_avatar(memo.user) +# json.tpm_url "/shixuns/#{memo.dis.identifier}/shixun_discuss" +# end + +json.memo_count @memo_count + +json.hot_memos do + json.array! @hot_memos do |hm| + json.(hm, :id, :subject, :language, :forum_id) + json.replies_count hm.all_replies_count + # json.praise_count hm.praise_tread.praise_count + json.tag hm.tag_repertoires.map(&:name) + end +end + +json.hot_tags @hot_tags + +json.recommend_shixuns @recommend_shixuns \ No newline at end of file diff --git a/app/views/discusses/reward_code.json.jbuilder b/app/views/discusses/reward_code.json.jbuilder index e5e0e9152..e2a98192b 100644 --- a/app/views/discusses/reward_code.json.jbuilder +++ b/app/views/discusses/reward_code.json.jbuilder @@ -1 +1,2 @@ +json.status 0 json.code @code \ No newline at end of file diff --git a/app/views/games/picture_display.json.jbuilder b/app/views/games/picture_display.json.jbuilder index 541c478a9..770f0d71b 100644 --- a/app/views/games/picture_display.json.jbuilder +++ b/app/views/games/picture_display.json.jbuilder @@ -24,5 +24,29 @@ elsif @type == "txt" json.contents @contents.html_safe elsif @type =="qrcode" json.qrcode_str @qrcode_str - +elsif @type == "mp3" || @type == "mp4" + # if @type == "mp4" + # json.orignal_file [{"file_url": "http://120.27.231.56:48080/attachments/download/378171/123.mp4"}] + # json.user_file [{"file_url": "http://120.27.231.56:48080/attachments/download/378172/456.mp4"}] + # json.answer_file [{"file_url": "http://120.27.231.56:48080/attachments/download/378173/789.mp4"}] + # else + # json.orignal_file [{"file_url": "http://120.27.231.56:48080/attachments/download/378174/58099.mp3"}] + # json.user_file [{"file_url": "http://120.27.231.56:48080/attachments/download/378175/654058514.mp3"}] + # json.answer_file [{"file_url": "http://120.27.231.56:48080/attachments/download/378175/654058514.mp3"}] + # end + json.orignal_file do + json.array! @orignal_picture do |file| + json.file_url attachment_show_users_path(:file_name => file, :path => @original_path) + end + end + json.user_file do + json.array! @user_picture do |file| + json.file_url attachment_show_users_path(:file_name => file, :path => @user_path, :time => Time.now.to_i) + end + end + json.answer_file do + json.array! @answer_picture do |file| + json.file_url attachment_show_users_path(:file_name => file, :path => @answer_path) + end + end end \ No newline at end of file diff --git a/app/views/graduation_topics/_graduation_comments.json.jbuilder b/app/views/graduation_topics/_graduation_comments.json.jbuilder index 1d49d450f..ee9ed7529 100644 --- a/app/views/graduation_topics/_graduation_comments.json.jbuilder +++ b/app/views/graduation_topics/_graduation_comments.json.jbuilder @@ -10,7 +10,7 @@ json.hidden message.hidden if message.m_parent_id json.can_delete message.can_delete(identity) else - json.praise_count message.praise_treads.liker.count - json.user_praise message.praise_treads.user_liker(current_user).count + json.praise_count message.praise_treads.select{|pt| pt.praise_or_tread == 1}.count + json.user_praise message.praise_treads.select{|pt| pt.praise_or_tread == 1 && user_id == current_user.id}.count json.child_message_count message.m_reply_count end diff --git a/app/views/memos/_memo.json.jbuilder b/app/views/memos/_memo.json.jbuilder index 22adba5fc..bc3744d1f 100644 --- a/app/views/memos/_memo.json.jbuilder +++ b/app/views/memos/_memo.json.jbuilder @@ -1,8 +1,14 @@ -json.(memo, :id, :subject, :is_md, :content, :sticky, :reward, :viewed_count) - -json.tag memo.tag_repertoires.map(&:name) -json.time memo.created_at -json.replies_count memo.all_replies_count -json.attachments_list [] -json.user_praise memo.praise_tread.user_liker(@user.try(:id)) ? true : false -json.memo_praise_count = memo.praise_tread.liker.count +json.memo do + json.id memo.id + json.subject memo.subject + json.is_md memo.is_md + json.content memo.content + json.sticky memo.sticky + json.reward memo.reward + json.viewed_count memo.viewed_count + json.tag memo.tag_repertoires.map(&:name) + json.time memo.created_at + json.replies_count memo.all_replies_count + json.user_praise memo.praise_treads.user_liker(@user.try(:id)) ? true : false + json.memo_praise_count memo.praise_treads.liker.count +end diff --git a/app/views/memos/_memo_list.json.jbuilder b/app/views/memos/_memo_list.json.jbuilder index 8da056e92..1f45070a1 100644 --- a/app/views/memos/_memo_list.json.jbuilder +++ b/app/views/memos/_memo_list.json.jbuilder @@ -1,7 +1,7 @@ json.(memo, :id, :subject, :author_id, :sticky, :updated_at, :language, :reward, :all_replies_count, :viewed_count, :forum_id) -json.praise_count memo.praise_tread.praise_count +json.praise_count memo.praise_treads.liker.count json.replies_count memo.all_replies_count json.tag memo.tag_repertoires.map(&:name) json.user_name memo.author.full_name diff --git a/app/views/memos/_replies_list.json.jbuilder b/app/views/memos/_replies_list.json.jbuilder index 3dae61813..9ec6976c2 100644 --- a/app/views/memos/_replies_list.json.jbuilder +++ b/app/views/memos/_replies_list.json.jbuilder @@ -7,10 +7,10 @@ json.username memo.author.full_name json.reward memo.reward json.hidden memo.hidden json.permission @user.manager_of_memo?(memo) -json.praise_count memo.praise_tread.liker.count -json.user_praise memo.praise_tread.select{|pt| pt.user_id == @user.id}.length > 0 +json.praise_count memo.praise_treads.select{|pt| pt.praise_or_tread == 1}.count +json.user_praise memo.praise_treads.select{|pt| pt.praise_or_tread == 1 && pt.user_id == @user.id}.length > 0 json.user_login memo.author.login -json.admin @user.admin +json.admin @user.admin? || @user.business? json.children do json.array! memo.children_of_reply do |child| diff --git a/app/views/memos/edit.json.jbuilder b/app/views/memos/edit.json.jbuilder new file mode 100644 index 000000000..f3d3f3724 --- /dev/null +++ b/app/views/memos/edit.json.jbuilder @@ -0,0 +1,7 @@ +json.(@memo, :subject, :content, :forum_id) +json.memo_tags @memo_tags +json.attachments @attachments do |attachment| + json.partial! "attachments/attachment_simple", locals: {attachment: attachment} +end +json.tag_list @tag_list +json.forums forum_list diff --git a/app/views/memos/index.json.jbuilder b/app/views/memos/index.json.jbuilder index 8a90e374a..e004f7ea7 100644 --- a/app/views/memos/index.json.jbuilder +++ b/app/views/memos/index.json.jbuilder @@ -8,22 +8,30 @@ # tidding_count: 消息数 # # -json.memo_list do - json.array! @memos do |memo| - json.partial! "memos/memo_list", locals: {memo: memo} - end +json.memo_list @memos do |memo| + json.(memo, :id, :subject, :sticky, + :updated_at, :language, :reward, + :viewed_count, :forum_id) + json.praise_count memo.praise_treads.select{|pt| pt.praise_or_tread == 1}.count + json.replies_count memo.all_replies_count + json.tag memo.tag_repertoires.map(&:name) + json.user_name memo.author.full_name + json.login memo.author.login + json.image_url url_to_avatar(memo.author) end json.memo_count @memos_count json.hot_memos do json.array! @hot_memos do |hm| - json.(hm, :id, :subject, :language, :forum_id, :all_replies_count) + json.(hm, :id, :subject, :language, :forum_id) json.replies_count hm.all_replies_count - json.praise_count hm.praise_tread.praise_count + # json.praise_count hm.praise_tread.praise_count json.tag hm.tag_repertoires.map(&:name) end end json.hot_tags @tags_info.map{|o| o.attributes.dup.except("cnt", "id")} +json.recommend_shixuns @recommend_shixuns + diff --git a/app/views/memos/more_reply.json.jbuilder b/app/views/memos/more_reply.json.jbuilder new file mode 100644 index 000000000..af1a9f1ac --- /dev/null +++ b/app/views/memos/more_reply.json.jbuilder @@ -0,0 +1,7 @@ +json.memo_replies do + json.array! @memos do |memo| + json.partial! "memos/replies_list", memo: memo + end +end + +json.memos_count @memos_count \ No newline at end of file diff --git a/app/views/memos/new.json.jbuilder b/app/views/memos/new.json.jbuilder index 14313b2ac..c35066023 100644 --- a/app/views/memos/new.json.jbuilder +++ b/app/views/memos/new.json.jbuilder @@ -1,3 +1,2 @@ json.tag_list @tag_list -json.csrf_token @csrf_token - +json.forums forum_list \ No newline at end of file diff --git a/app/views/memos/show.json.jbuilder b/app/views/memos/show.json.jbuilder index 7acd6ba4a..1f7840983 100644 --- a/app/views/memos/show.json.jbuilder +++ b/app/views/memos/show.json.jbuilder @@ -1,5 +1,9 @@ json.partial! "memos/memo", memo: @memo +json.attachments_list @attachments do |attachment| + json.partial! "attachments/attachment_simple", locals: {attachment: attachment} +end + json.memo_replies do json.array! @memos do |memo| json.partial! "memos/replies_list", memo: memo @@ -9,10 +13,11 @@ end json.author_info do json.username @memo.author.full_name # TODO watched_by 插件没法用,等把lib文件载入后在打开代码 - #json.watched @memo.author.watched_by?(@user) + json.watched @user.watched?(@memo.author) json.image_url url_to_avatar(@memo.author) json.identity @memo.author.identity json.login @memo.author.login json.user_id @memo.author.id end +json.recommend_shixuns @recommend_shixuns \ No newline at end of file diff --git a/app/views/users/get_user_info.json.jbuilder b/app/views/users/get_user_info.json.jbuilder index d9eb736ad..fc2eca762 100644 --- a/app/views/users/get_user_info.json.jbuilder +++ b/app/views/users/get_user_info.json.jbuilder @@ -1,4 +1,5 @@ json.username @user.full_name +json.real_name @user.real_name json.login @user.login json.user_id @user.id json.image_url url_to_avatar(@user) @@ -7,6 +8,7 @@ json.is_teacher @user.user_extension&.teacher? json.user_identity @user.identity json.tidding_count 0 json.user_phone_binded @user.phone.present? +json.phone @user.phone json.profile_completed @user.profile_completed? if @course json.course_identity @course_identity 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/projects/search.json.jbuilder b/app/views/users/projects/search.json.jbuilder similarity index 100% rename from app/views/projects/search.json.jbuilder rename to app/views/users/projects/search.json.jbuilder 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..79542817f 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -20,7 +20,18 @@ Rails.application.routes.draw do put 'commons/unhidden', to: 'commons#unhidden' delete 'commons/delete', to: 'commons#delete' - resources :memos + resources :memos do + member do + post :sticky_or_cancel + post :hidden + get :more_reply + end + + collection do + post :reply + end + end + resources :tem_tests # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html # @@ -53,6 +64,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 @@ -70,7 +86,7 @@ Rails.application.routes.draw do get :system_update resource :trial_apply, only: [:create] - resources :projects, only: [] do + resources :projects, module: :users, only: [] do get :search, on: :collection end @@ -91,6 +107,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 @@ -216,6 +233,7 @@ Rails.application.routes.draw do resources :discusses do collection do get :new_message + get :forum_discusses end member do @@ -697,7 +715,7 @@ Rails.application.routes.draw do resources :libraries, only: [:index, :show, :create, :update, :destroy] scope module: :projects do - resources :applied_projects, only: [:create] + resources :project_applies, only: [:create] end end diff --git a/db/migrate/20190730024112_add_index_to_user.rb b/db/migrate/20190730024112_add_index_to_user.rb new file mode 100644 index 000000000..fa198cffa --- /dev/null +++ b/db/migrate/20190730024112_add_index_to_user.rb @@ -0,0 +1,7 @@ +class AddIndexToUser < ActiveRecord::Migration[5.2] + def change + # add_index :users, :login, unique: true + # add_index :users, :mail, unique: true + # add_index :users, :phone, unique: true + end +end diff --git a/public/compatibility.html b/public/compatibility.html index f13c673f5..f28bad2c8 100644 --- a/public/compatibility.html +++ b/public/compatibility.html @@ -5,9 +5,9 @@