dev_video
jingquan huang 5 years ago
commit df87486cf4

@ -0,0 +1,71 @@
$(document).on('turbolinks:load', function () {
if ($('body.admins-subject-settings-index-page').length > 0) {
var $form = $('.subject-setting-list-form');
// ************** 学校选择 *************
$form.find('.school-select').select2({
theme: 'bootstrap4',
placeholder: '请选择创建者单位',
minimumInputLength: 1,
ajax: {
delay: 500,
url: '/api/schools/search.json',
dataType: 'json',
data: function (params) {
return {keyword: params.term};
},
processResults: function (data) {
return {results: data.schools}
}
},
templateResult: function (item) {
if (!item.id || item.id === '') return item.text;
return item.name;
},
templateSelection: function (item) {
if (item.id) {
}
return item.name || item.text;
}
});
$(".subject-setting-list-container").on("change", '.subject-setting-form', function () {
var s_id = $(this).attr("data-id");
var s_value = $(this).val();
var s_name = $(this).attr("name");
var json = {};
json[s_name] = s_value;
$.ajax({
url: "/admins/subject_settings/" + s_id,
type: "PUT",
dataType:'script',
data: json
})
});
// 清空
$form.on('click', '.clear-btn', function () {
$form.find('select[name="status"]').val('');
$form.find('.school-select').val('').trigger('change');
$form.find('input[name="keyword"]').val('');
$form.find('#homepage_show').attr('checked', false);
$form.find('#excellent').attr('checked', false);
$form.find('input[type="submit"]').trigger('click');
});
// 上传图片
$('.modal.admin-upload-file-modal').on('upload:success', function (e, data) {
if(data.suffix == '_qrcode'){
var $imageElement = $('.subject-weapp-image-' + data.source_id);
$imageElement.attr('src', data.url);
$imageElement.show();
$imageElement.next().html('重新上传');
} else {
var $imageElement = $('.subject-image-' + data.source_id);
$imageElement.attr('src', data.url);
$imageElement.show();
$imageElement.next().html('重新上传');
}
});
}
});

@ -37,22 +37,8 @@ $(document).on('turbolinks:load', function () {
$form.find('#homepage_show').attr('checked', false);
$form.find('#excellent').attr('checked', false);
$form.find('input[type="submit"]').trigger('click');
})
// 上传图片
$('.modal.admin-upload-file-modal').on('upload:success', function (e, data) {
if(data.suffix == '_qrcode'){
var $imageElement = $('.subject-weapp-image-' + data.source_id);
$imageElement.attr('src', data.url);
$imageElement.show();
$imageElement.next().html('重新上传');
} else {
var $imageElement = $('.subject-image-' + data.source_id);
$imageElement.attr('src', data.url);
$imageElement.show();
$imageElement.next().html('重新上传');
}
});
// 定义状态切换监听事件
var defineStatusChangeFunc = function (doElement, undoElement, url, callback) {
$('.subject-list-container').on('click', doElement, function () {

@ -0,0 +1,30 @@
class Admins::SubjectSettingsController < Admins::BaseController
def index
default_sort('created_at', 'desc')
subjects = Admins::SubjectQuery.call(params)
@sub_disciplines = SubDiscipline.where(subject: 1).pluck(:name,:id)
@subjects = paginate subjects.includes(:repertoire, :subject_level_system, :sub_disciplines)
end
def update
if params[:sub_disciplines]
sub_ids = params[:sub_disciplines].reject(&:blank?).map(&:to_i)
old_sub_ids = current_subject.sub_discipline_containers.pluck(:sub_discipline_id)
new_ids = sub_ids - old_sub_ids
delete_ids = old_sub_ids - sub_ids
sub_params = new_ids.map{|sub| {sub_discipline_id: sub}}
ActiveRecord::Base.transaction do
current_subject.sub_discipline_containers.where(sub_discipline_id: delete_ids).destroy_all
current_subject.sub_discipline_containers.create!(sub_params)
end
end
end
private
def current_subject
@_current_subject ||= Subject.find(params[:id])
end
end

@ -3,7 +3,7 @@ class Admins::SubjectsController < Admins::BaseController
default_sort('created_at', 'desc')
subjects = Admins::SubjectQuery.call(params)
@subjects = paginate subjects.includes(:repertoire, :subject_level_system, user: { user_extension: :school })
@subjects = paginate subjects.includes(user: { user_extension: :school })
end
def edit

@ -224,7 +224,7 @@ class ApplicationController < ActionController::Base
# 未授权的捕捉407弹试用申请弹框
def require_login
#6.13 -hs
tip_exception(401, "..") unless User.current.logged?
tip_exception(401, "请登录后再操作") unless User.current.logged?
end
# 异常提醒

@ -181,7 +181,7 @@ class ChallengesController < ApplicationController
begin
ActiveRecord::Base.transaction do
tab = params[:tab].to_i
@challenge.update_attributes(challenge_params)
@challenge.update_attributes!(challenge_params)
if tab == 0 && @challenge.st == 0
@challenge.challenge_tags.delete_all
if params[:challenge_tag].present?
@ -211,7 +211,7 @@ class ChallengesController < ApplicationController
# last 末尾匹配, full: 全完匹配
logger.info("set: #{set}; match_rule : #{set[:match_rule]}")
match_rule = set[:match_rule] == 'last' ? 'last' : 'full'
TestSet.create(:challenge_id => @challenge.id,
TestSet.create!(:challenge_id => @challenge.id,
:input => "#{set[:input]}",
:output => "#{set[:output]}",
:is_public => params_hidden[index],
@ -237,9 +237,9 @@ class ChallengesController < ApplicationController
end
end
rescue => e
logger_error("##update_challenges: ##{e.message}")
tip_exception("更新失败!")
rescue Exception => e
logger.error("##update_challenges: ##{e.message}")
tip_exception("#{e.message}")
end
end
@ -262,7 +262,7 @@ class ChallengesController < ApplicationController
params[:challenge_answer].each_with_index do |answer, index|
# 内容为空不保存
next if answer[:contents].blank?
ChallengeAnswer.create(name: answer[:name], contents: answer[:contents],
ChallengeAnswer.create!(name: answer[:name], contents: answer[:contents],
level: index+1, score: answer[:score], challenge_id: @challenge.id)
end
end

@ -145,13 +145,13 @@ class CollegesController < ApplicationController
def check_college_present!
return if current_college.present?
redirect_to '/404'
tip_exception(404, "")
end
def check_manage_permission!
return if can_manage_college?
redirect_to '/403'
tip_exception(403, "")
end
def can_manage_college?
@ -160,7 +160,7 @@ class CollegesController < ApplicationController
return true if current_user.is_teacher? && current_user.school_id == current_school.id # 学校老师
# return true if current_school.customers.exists? && current_user.partner&.partner_customers&.exists?(customer_id: current_school.customer_id)
false
tip_exception(403, "")
end
def current_school

@ -3,7 +3,7 @@ class ChallengeAnswer < ApplicationRecord
belongs_to :challenge
has_many :game_answers, :dependent => :destroy
validates :contents, length: { maximum: 5000 , too_long: "不能超过5000个字符"}
validates :contents, length: { maximum: 25000 , too_long: "不能超过25000个字符"}
def view_answer_time(user_id)
game_answers.where(user_id: user_id).last&.view_time

@ -1,6 +1,7 @@
class SubDiscipline < ApplicationRecord
belongs_to :discipline
has_many :tag_disciplines, dependent: :destroy
has_many :sub_discipline_containers, dependent: :destroy
has_one :hack
has_many :shixun_tag_disciplines, -> { where("shixun = 1") }, class_name: "TagDiscipline"

@ -0,0 +1,5 @@
class SubDisciplineContainer < ApplicationRecord
belongs_to :sub_discipline
belongs_to :container, polymorphic: true, optional: true, touch: true
end

@ -30,6 +30,8 @@ class Subject < ApplicationRecord
has_many :subject_course_records, dependent: :destroy
has_many :subject_shixun_infos, dependent: :destroy
has_many :subject_user_infos, dependent: :destroy
has_many :sub_discipline_containers, as: :container, dependent: :destroy
has_many :sub_disciplines, through: :sub_discipline_containers
validates :name, length: { maximum: 60, too_long: "不能超过60个字符" }
validates :description, length: { maximum: 8000, too_long: "不能超过8000个字符" }

@ -1,7 +1,7 @@
class TestSet < ApplicationRecord
# match_rule: 匹配规则: full 完全匹配, last 末尾匹配
#
validates :input, length: { maximum: 5000, too_long: "不能超过5000个字符" }
validates :output, length: { maximum: 5000, too_long: "不能超过5000个字符" }
validates :input, length: { maximum: 65000, too_long: "不能超过65000个字符" }
validates :output, length: { maximum: 65000, too_long: "不能超过65000个字符" }
end

@ -1,2 +1,2 @@
$('.admin-modal-container').html("<%= j( render partial: 'admins/repertoires/shared/edit_repertoire_modal', locals: { repertoire: @repertoire } ) %>");
$('.modal.admin-edit-repertoires-modal').modal('show');
$('.modal.admin-edit-repertoire-modal').modal('show');

@ -35,6 +35,7 @@
<li>
<%= sidebar_item_group('#subject-submenu', '实践课程', icon: 'th-list') do %>
<li><%= sidebar_item(admins_subjects_path, '课程列表', icon: 'cog', controller: 'admins-subjects') %></li>
<li><%= sidebar_item(admins_subject_settings_path, '课程配置', icon: 'cog', controller: 'admins-subject_settings') %></li>
<% end %>
</li>

@ -0,0 +1,41 @@
<% define_admin_breadcrumbs do %>
<% add_admin_breadcrumb('课程配置') %>
<% end %>
<div class="box search-form-container subject-setting-list-form">
<%= form_tag(admins_subject_settings_path, method: :get, class: 'form-inline search-form flex-1', remote: true) do %>
<div class="form-group mr-1">
<label for="status">状态:</label>
<% status_options = [['全部', ''], ['编辑中', 'pending'], ['审核中', 'applying'], ['已发布', 'published']] %>
<%= select_tag(:status, options_for_select(status_options), class: 'form-control') %>
</div>
<div class="form-group col-12 col-md-3">
<label for="school_name">单位:</label>
<%= select_tag :school_id, options_for_select([''], params[:school_id]), class: 'form-control school-select flex-1' %>
</div>
<%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-12 col-md-2 mr-3', placeholder: '创建者/课程名称检索') %>
<div class="form-check mr-2">
<%= hidden_field_tag(:homepage_show, false, id:'') %>
<%= check_box_tag(:homepage_show, true, params[:homepage_show].to_s == 'true', class: 'form-check-input') %>
<label class="form-check-label" for="homepage_show">只看首页展示</label>
</div>
<div class="form-check mr-2">
<%= hidden_field_tag(:excellent, false, id:'') %>
<%= check_box_tag(:excellent, true, params[:excellent].to_s == 'true', class: 'form-check-input') %>
<label class="form-check-label" for="excellent">只看金课</label>
</div>
<%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %>
<input type="reset" class="btn btn-secondary clear-btn" value="清空"/>
<% end %>
</div>
<div class="box admin-list-container subject-setting-list-container">
<%= render partial: 'admins/subject_settings/shared/list', locals: { subjects: @subjects } %>
</div>
<%= render partial: 'admins/shared/modal/upload_file_modal', locals: { title: '上传图片', accept: 'image/*' } %>

@ -0,0 +1 @@
$('.subject-setting-list-container').html("<%= j( render partial: 'admins/subject_settings/shared/list', locals: { subjects: @subjects } ) %>");

@ -0,0 +1,33 @@
<div class="modal fade admin-edit-subject-modal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">编辑课程信息</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<%= simple_form_for([:admins, subject], html: { class: 'admin-edit-subject-form' }, defaults: { wrapper_html: { class: 'offset-md-1 col-md-10' } }) do |f| %>
<%= f.input :repertoire_id, label: '技术体系:' do %>
<% repertoire_options = Repertoire.order('CONVERT(name USING gbk) COLLATE gbk_chinese_ci ASC').map{|r| [r.name, r.id]} %>
<%= f.select :repertoire_id, [['请选择', '']] + repertoire_options, {}, class: 'form-control' %>
<% end %>
<%= f.input :subject_level_system_id, label: '等级体系:' do %>
<% level_options = SubjectLevelSystem.all.map{|r| [r.name, r.id]} %>
<%= f.select :subject_level_system_id, [['请选择', '']] + level_options, {}, class: 'form-control' %>
<% end %>
<%= f.input :student_count, as: :integer, label: '开课人数:' %>
<div class="error text-danger"></div>
<% end %>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary submit-btn">确认</button>
</div>
</div>
</div>
</div>

@ -0,0 +1,28 @@
<table class="table table-hover text-center subject-list-table">
<thead class="thead-light">
<tr>
<th width="4%">序号</th>
<th width="25%" class="text-left">名称</th>
<th width="12%">技术体系</th>
<th width="10%">等级体系</th>
<th width="25%">课程体系</th>
<th width="10%">封面</th>
<th width="8%">开课人数</th>
<th width="6%">操作</th>
</tr>
</thead>
<tbody>
<% if subjects.present? %>
<% subjects.each_with_index do |subject, index| %>
<tr class="subject-item-<%= subject.id %>">
<% page_no = ((params[:page] || 1).to_i - 1) * 20 + index + 1 %>
<%= render partial: "admins/subject_settings/shared/td",locals: {subject: subject,page_no:page_no} %>
</tr>
<% end %>
<% else %>
<%= render 'admins/shared/no_data_for_table' %>
<% end %>
</tbody>
</table>
<%= render partial: 'admins/shared/paginate', locals: { objects: subjects } %>

@ -0,0 +1,27 @@
<td class="subject-line-no"><%= page_no %></td>
<td class="text-left">
<%= link_to(subject.name, "/paths/#{subject.id}", target: '_blank') %>
<span class="badge badge-pill badge-success homepage-show-badge" style="<%= subject.homepage_show? ? '' : 'display:none' %>">首页</span>
<span class="badge badge-pill badge-info excellent-badge" style="<%= subject.excellent? ? '' : 'display:none' %>">金课</span>
</td>
<td><%= display_text subject.repertoire&.name %></td>
<td><%= display_text subject.subject_level_system&.name %></td>
<td>
<%= select_tag(:sub_disciplines, options_for_select(@sub_disciplines, subject.sub_disciplines.pluck(:id)),multiple:true,class:"form-control subject-setting-form",data:{id:subject.id},id:"tags-chosen-#{subject.id}") %>
</td>
<td>
<% image_exists = Util::FileManage.exists?(subject) %>
<%= image_tag(image_exists ? Util::FileManage.source_disk_file_url(subject) : '', height: 40, class: "w-100 preview-image subject-image-#{subject.id}", style: image_exists ? '' : 'display:none') %>
<%= javascript_void_link image_exists ? '重新上传' : '上传图片', class: 'action upload-image-action', data: { source_id: subject.id, source_type: 'Subject', toggle: 'modal', target: '.admin-upload-file-modal' } %>
</td>
<td><%= subject.student_count %></td>
<td class="action-container">
<%= link_to('编辑', edit_admins_subject_path(subject), remote: true, class: 'edit-action') %>
</td>
<script>
$("#tags-chosen-<%= subject.id %>").select2({
multiple: true,
maximumSelectionLength: 3,
placeholder: '请选择课程体系'});
</script>

@ -0,0 +1 @@
$.notify({ message: '更新成功' });

@ -1,5 +1,5 @@
<% define_admin_breadcrumbs do %>
<% add_admin_breadcrumb('课程配置') %>
<% add_admin_breadcrumb('课程列表') %>
<% end %>
<div class="box search-form-container subject-list-form">
@ -36,6 +36,4 @@
<div class="box admin-list-container subject-list-container">
<%= render partial: 'admins/subjects/shared/list', locals: { subjects: @subjects } %>
</div>
<%= render partial: 'admins/shared/modal/upload_file_modal', locals: { title: '上传图片', accept: 'image/*' } %>
</div>

@ -5,12 +5,8 @@
<th width="14%" class="text-left">名称</th>
<th width="5%">阶段数</th>
<th width="5%">实训数</th>
<th width="7%">技术体系</th>
<th width="7%">等级体系</th>
<th width="8%">封面</th>
<th width="7%">创建者</th>
<th width="10%">单位</th>
<th width="6%">开课人数</th>
<th width="10%"><%= sort_tag('创建时间', name: 'created_at', path: admins_subjects_path) %></th>
<th width="7%">状态</th>
<th width="9%">操作</th>
@ -28,40 +24,30 @@
</td>
<td><%= subject.stages_count %></td>
<td><%= subject.shixuns_count %></td>
<td><%= display_text subject.repertoire&.name %></td>
<td><%= display_text subject.subject_level_system&.name %></td>
<td>
<% image_exists = Util::FileManage.exists?(subject) %>
<%= image_tag(image_exists ? Util::FileManage.source_disk_file_url(subject) : '', height: 40, class: "w-100 preview-image subject-image-#{subject.id}", style: image_exists ? '' : 'display:none') %>
<%= javascript_void_link image_exists ? '重新上传' : '上传图片', class: 'action upload-image-action', data: { source_id: subject.id, source_type: 'Subject', toggle: 'modal', target: '.admin-upload-file-modal' } %>
</td>
<td><%= subject.user.real_name %></td>
<td><%= subject.user.school_name %></td>
<td><%= subject.student_count %></td>
<td><%= subject.created_at&.strftime('%Y-%m-%d %H:%M') %></td>
<td>
<%= display_subject_status(subject) %>
</td>
<td class="action-container">
<%= link_to('编辑', edit_admins_subject_path(subject), remote: true, class: 'edit-action') %>
<%= javascript_void_link('隐藏', class: 'hide-action', data: { id: subject.id }, style: subject.hidden? ? 'display:none' : '') %>
<%= javascript_void_link('取消隐藏', class: 'active-action', data: { id: subject.id }, style: subject.hidden? ? '' : 'display:none') %>
<div class="d-inline">
<%= javascript_void_link('更多', class: 'action dropdown-toggle', 'data-toggle': 'dropdown', 'aria-haspopup': true, 'aria-expanded': false) %>
<div class="dropdown-menu more-action-dropdown">
<% if subject.published? %>
<%= delete_link '删除', admins_subject_path(subject, element: ".subject-item-#{subject.id}"), class: 'delete-subject-action' %>
<% if subject.published? %>
<div class="d-inline">
<%= javascript_void_link('更多', class: 'action dropdown-toggle', 'data-toggle': 'dropdown', 'aria-haspopup': true, 'aria-expanded': false) %>
<div class="dropdown-menu more-action-dropdown">
<%= javascript_void_link('首页展示', class: 'dropdown-item homepage-show-action', data: { id: subject.id }, style: subject.homepage_show? ? 'display:none' : '') %>
<%= javascript_void_link('取消首页展示', class: 'dropdown-item homepage-hide-action', data: { id: subject.id }, style: subject.homepage_show? ? '' : 'display:none') %>
<%= javascript_void_link('选为金课', class: 'dropdown-item excellent-action', data: { id: subject.id }, style: subject.excellent? ? 'display:none' : '') %>
<%= javascript_void_link('取消金课', class: 'dropdown-item cancel-excellent-action', data: { id: subject.id }, style: subject.excellent? ? '' : 'display:none') %>
<% end %>
<%= delete_link '删除', admins_subject_path(subject, element: ".subject-item-#{subject.id}"), class: 'dropdown-item delete-subject-action' %>
</div>
</div>
</div>
<% end %>
</td>
</tr>
<% end %>

@ -1303,6 +1303,8 @@ Rails.application.routes.draw do
post :drag, on: :collection
end
resources :subject_settings, only: [:index, :update]
resources :subjects, only: [:index, :edit, :update, :destroy] do
member do
post :hide

@ -0,0 +1,13 @@
class CreateSubDisciplineContainers < ActiveRecord::Migration[5.2]
def change
create_table :sub_discipline_containers do |t|
t.references :sub_discipline, index: true
t.integer :container_id
t.string :container_type
t.timestamps
end
add_index :sub_discipline_containers, [:container_type, :container_id], name: "index_on_container"
end
end

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe SubDisciplineContainer, type: :model do
pending "add some examples to (or delete) #{__FILE__}"
end
Loading…
Cancel
Save