diff --git a/app/controllers/users/project_packages_controller.rb b/app/controllers/users/project_packages_controller.rb
new file mode 100644
index 000000000..edd6bd29b
--- /dev/null
+++ b/app/controllers/users/project_packages_controller.rb
@@ -0,0 +1,17 @@
+class Users::ProjectPackagesController < Users::BaseController
+
+ def index
+ packages = Users::ProjectPackageService.call(observed_user, query_params)
+
+ @count = packages.count
+ @packages = paginate(packages.includes(:project_package_category))
+
+ bidding_users = BiddingUser.where(project_package_id: @packages.map(&:id), user_id: observed_user.id)
+ bidding_users = bidding_users.group(:project_package_id).select(:project_package_id, :status)
+ @bidding_status_map = bidding_users.each_with_object({}) { |u, h| h[u.project_package_id] = u.status }
+ end
+
+ def query_params
+ params.permit(:category, :status, :sort_by, :sort_direction)
+ end
+end
\ No newline at end of file
diff --git a/app/models/project_package.rb b/app/models/project_package.rb
index fc541097a..219f60ca4 100644
--- a/app/models/project_package.rb
+++ b/app/models/project_package.rb
@@ -13,6 +13,9 @@ class ProjectPackage < ApplicationRecord
has_many :attachments, as: :container, dependent: :destroy
+ scope :visible, -> { where(status: %i[published bidding_ended bidding_finished]) }
+ scope :invisible, -> { where(status: %i[pending applying refused]) }
+
aasm(:status) do
state :pending, initiali: true
state :applying
diff --git a/app/models/user.rb b/app/models/user.rb
index 73036c73e..03c97b9f3 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -123,6 +123,11 @@ class User < ApplicationRecord
has_many :user_interests, dependent: :delete_all
has_many :interests, through: :user_interests, source: :repertoire
+ # 众包
+ has_many :project_packages, foreign_key: :creator_id, dependent: :destroy
+ has_many :bidding_users, dependent: :destroy
+ has_many :bidden_project_packages, through: :bidding_users, source: :project_package
+
# Groups and active users
scope :active, lambda { where(status: STATUS_ACTIVE) }
@@ -572,6 +577,10 @@ class User < ApplicationRecord
Attendance.find_by(user_id: id)&.next_gold || 60 # 基础50,连续签到+10
end
+ def admin_or_business?
+ admin? || business?
+ end
+
protected
def validate_password_length
# 管理员的初始密码是5位
diff --git a/app/services/users/project_package_service.rb b/app/services/users/project_package_service.rb
new file mode 100644
index 000000000..870cdc98e
--- /dev/null
+++ b/app/services/users/project_package_service.rb
@@ -0,0 +1,76 @@
+class Users::ProjectPackageService < ApplicationService
+ include CustomSortable
+
+ sort_columns :published_at, default_by: :published_at, default_direction: :desc
+
+ attr_reader :user, :params
+
+ def initialize(user, params)
+ @user = user
+ @params = params
+ end
+
+ def call
+ packages = category_scope_filter
+
+ packages = user_policy_filter(packages)
+
+ custom_sort(packages, :published_at, params[:sort_direction])
+ end
+
+ private
+
+ def category_scope_filter
+ case params[:category]
+ when 'bidden' then
+ user.bidden_project_packages
+ when 'manage' then
+ user.project_packages
+ else
+ ids = user.bidding_users.pluck(:project_package_id) + user.project_packages.pluck(:id)
+ ProjectPackage.where(id: ids)
+ end
+ end
+
+ def user_policy_filter(relations)
+ if self_or_admin?
+ status_filter(relations)
+ else
+ relations.visible
+ end
+ end
+
+ def status_filter(relations)
+ return relations unless self_or_admin?
+
+ case params[:category]
+ when 'bidden' then bidding_status_filter(relations)
+ when 'manage' then package_status_filter(relations)
+ else relations
+ end
+ end
+
+ def bidding_status_filter(relations)
+ case params[:status]
+ when 'bidding_lost' then
+ relations.where(bidding_users: { status: :bidding_lost })
+ when 'bidding_won' then
+ relations.where(bidding_users: { status: :bidding_won })
+ else
+ relations
+ end
+ end
+
+ def package_status_filter(relations)
+ case params[:status]
+ when 'unpublished' then relations.invisible
+ when 'bidding' then relations.where(status: :published)
+ when 'finished' then relations.where(status: %w[bidding_ended bidding_finished])
+ else relations
+ end
+ end
+
+ def self_or_admin?
+ User.current&.id == user.id || User.current&.admin_or_business?
+ end
+end
\ No newline at end of file
diff --git a/app/views/exercise_questions/_exercise_questions.json.jbuilder b/app/views/exercise_questions/_exercise_questions.json.jbuilder
index b9565535e..51c30ad92 100644
--- a/app/views/exercise_questions/_exercise_questions.json.jbuilder
+++ b/app/views/exercise_questions/_exercise_questions.json.jbuilder
@@ -21,7 +21,8 @@ if question.question_type <= 2 #当为选择题或判断题时,只显示选
user_answer_b = user_answer.include?(a.id)
json.c_position (index+1) if ex_choice_random_boolean #当选项随机时,选项位置以此为准,否则不出现
json.choice_id a.id
- json.choice_text (edit_type.present? || question.question_type == 2) ? a.choice_text : "#{(index+65).chr}.#{a.choice_text}"
+ # json.choice_text (edit_type.present? || question.question_type == 2) ? a.choice_text : "#{(index+65).chr}.#{a.choice_text}"
+ json.choice_text a.choice_text
json.choice_position a.choice_position
if exercise_type == 1 || exercise_type == 4 #1为教师编辑/预览 试卷或问题,2为空白试卷,即标准答案和用户答案都不显示,3为用户开始答题的显示,4为老师评阅试卷或学生在截止后查看试卷
json.standard_boolean standard_answer_b
diff --git a/app/views/exercises/exercise_result.json.jbuilder b/app/views/exercises/exercise_result.json.jbuilder
index 2c4b3ded7..1ceb8209d 100644
--- a/app/views/exercises/exercise_result.json.jbuilder
+++ b/app/views/exercises/exercise_result.json.jbuilder
@@ -35,15 +35,16 @@ json.commit_results do
if q[:type] != Exercise::PRACTICAL
json.ques_details do
json.array! q[:ques_details].each_with_index.to_a do |d,index|
- if q[:type] <= Exercise::MULTIPLE
- ques_index = (index+65).chr
- elsif q[:type] == Exercise::JUDGMENT
- ques_index = (index+1).to_s
- else
- ques_index = nil
- end
+ # if q[:type] <= Exercise::MULTIPLE
+ # ques_index = (index+65).chr
+ # elsif q[:type] == Exercise::JUDGMENT
+ # ques_index = (index+1).to_s
+ # else
+ # ques_index = nil
+ # end
json.choice_position d[:choice_position]
- json.choice_text ques_index.present? ? "#{ques_index}.#{d[:choice_text]}" : d[:choice_text]
+ # json.choice_text ques_index.present? ? "#{ques_index}.#{d[:choice_text]}" : d[:choice_text]
+ json.choice_text d[:choice_text]
json.choice_users_count d[:choice_users_count]
json.choice_percent d[:choice_percent]
json.choice_right_boolean d[:right_answer]
diff --git a/app/views/users/project_packages/index.json.jbuilder b/app/views/users/project_packages/index.json.jbuilder
new file mode 100644
index 000000000..a2574d558
--- /dev/null
+++ b/app/views/users/project_packages/index.json.jbuilder
@@ -0,0 +1,20 @@
+user = observed_user
+
+json.count @count
+json.project_packages do
+ json.array! @packages.each do |package|
+ json.extract! package, :id, :title, :status, :min_price, :max_price, :visit_count, :bidding_users_count
+
+ is_creator = user.id == package.creator_id
+ json.type is_creator ? 'manage' : 'bidden'
+ json.category_id package.project_package_category_id
+ json.category_name package.category_name
+
+ unless is_creator
+ json.bidden_status @bidding_status_map[package.id]
+ end
+
+ json.deadline_at package.display_deadline_at
+ json.published_at package.display_published_at
+ end
+end
\ No newline at end of file
diff --git a/config/routes.rb b/config/routes.rb
index 16140e99c..bb5bc49cc 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -50,6 +50,7 @@ Rails.application.routes.draw do
resource :experience_records, only: [:show]
resource :grade_records, only: [:show]
resource :watch, only: [:create, :destroy]
+ resources :project_packages, only: [:index]
end
diff --git a/public/react/src/AppConfig.js b/public/react/src/AppConfig.js
index 003ef5a9b..cf62730d7 100644
--- a/public/react/src/AppConfig.js
+++ b/public/react/src/AppConfig.js
@@ -25,9 +25,7 @@ if (isDev) {
if (_search) {
parsed = queryString.parse(_search);
}
- debugType = window.location.search.indexOf('debug=t') != -1 ? 'teacher' :
- window.location.search.indexOf('debug=s') != -1 ? 'student' :
- window.location.search.indexOf('debug=a') != -1 ? 'admin' : parsed.debug || ''
+ debugType = window.location.search.indexOf('debug=t') != -1 ? "cxt" : ''
}
window._debugType = debugType;
@@ -144,6 +142,7 @@ export function initAxiosInterceptors(props) {
// }
if (response.data.status === 403) {
// props.history.replace('/403')
+ debugger
// 这里会分2个情况,1、刚进入页面发请求返回的403;2、进入页面后,其他用户操作触发请求返回的403;
// TODO 这里做一个403弹框比较好?
locationurl('/403');
diff --git a/public/react/src/modules/courses/coursesPublic/Addcourses.js b/public/react/src/modules/courses/coursesPublic/Addcourses.js
index e8bd8b9cf..922c68650 100644
--- a/public/react/src/modules/courses/coursesPublic/Addcourses.js
+++ b/public/react/src/modules/courses/coursesPublic/Addcourses.js
@@ -147,6 +147,8 @@ class Addcourses extends Component{
if(Addcoursestype===true){
this.props.hideAddcoursestype();
+ }else{
+ window.location.href = "/";
}
}
diff --git a/public/react/src/modules/courses/shixunHomework/ShixunhomeWorkItem.js b/public/react/src/modules/courses/shixunHomework/ShixunhomeWorkItem.js
index 5f41cdefb..b4adea17f 100644
--- a/public/react/src/modules/courses/shixunHomework/ShixunhomeWorkItem.js
+++ b/public/react/src/modules/courses/shixunHomework/ShixunhomeWorkItem.js
@@ -382,7 +382,7 @@ class ShixunhomeWorkItem extends Component{
实训详情
{this.props.isAdminOrCreator()?this.editname(discussMessage.name,discussMessage.homework_id)} className={"btn colorblue ml20 font-16"}>重命名:""}
{/* 设置*/}
- 设置
+ 设置
:""}
diff --git a/public/react/src/modules/tpm/NewHeader.js b/public/react/src/modules/tpm/NewHeader.js
index da8e71a40..830c8b1d4 100644
--- a/public/react/src/modules/tpm/NewHeader.js
+++ b/public/react/src/modules/tpm/NewHeader.js
@@ -487,10 +487,11 @@ submittojoinclass=(value)=>{
}
showSearchOpen=(e)=>{
+ debugger
this.setState({
showSearchOpentype:true
})
- e.stopPropagation(e);//阻止冒泡
+
}
hideshowSearchOpen=(e)=>{
@@ -500,7 +501,7 @@ submittojoinclass=(value)=>{
showSearchOpentype:false,
setevaluatinghides:false
})
- e.stopPropagation(e);//阻止冒泡
+
}
}