@ -0,0 +1,105 @@
|
|||||||
|
class LibrariesController < ApplicationController
|
||||||
|
layout 'base_library'
|
||||||
|
|
||||||
|
before_filter :require_login
|
||||||
|
|
||||||
|
def index
|
||||||
|
libraries = Library.where(nil)
|
||||||
|
|
||||||
|
libraries =
|
||||||
|
if params[:type] == 'mine'
|
||||||
|
libraries.where(user_id: current_user.id).order('created_at desc')
|
||||||
|
else
|
||||||
|
libraries.where(status: :published).order('visited_count desc')
|
||||||
|
end
|
||||||
|
|
||||||
|
search = params[:search].to_s.strip
|
||||||
|
libraries = libraries.where('title LIKE ?', "%#{search}%") if search.present?
|
||||||
|
|
||||||
|
per_page = params[:per_page].to_i <= 0 ? 20 : params[:per_page].to_i
|
||||||
|
@libraries = paginateHelper libraries.includes(user: :user_extensions), per_page
|
||||||
|
end
|
||||||
|
|
||||||
|
def show
|
||||||
|
@library = Library.find(params[:id])
|
||||||
|
return redirect_to libraries_path unless admin_or_self?
|
||||||
|
|
||||||
|
@library_applies = @library.library_applies.where(status: :refused).order('created_at desc')
|
||||||
|
@library.increment_visited_count!
|
||||||
|
end
|
||||||
|
|
||||||
|
def new
|
||||||
|
@library = current_user.libraries.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@library = current_user.libraries.new
|
||||||
|
Libraries::SaveService.new(@library, current_user, form_params).call
|
||||||
|
if with_publish?
|
||||||
|
Libraries::SubmitService.new(current_library).call
|
||||||
|
redirect_to publish_success_libraries_path
|
||||||
|
else
|
||||||
|
flash[:message] = '保存成功'
|
||||||
|
render 'new'
|
||||||
|
end
|
||||||
|
rescue ActiveRecord::RecordInvalid => _
|
||||||
|
render 'new'
|
||||||
|
rescue Libraries::SubmitService::Error => ex
|
||||||
|
flash[:message] = ex.message
|
||||||
|
render 'new'
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
@library = current_library
|
||||||
|
redirect_to library_path(id: @library.id) unless @library.editable?
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
@library = current_library
|
||||||
|
Libraries::SaveService.new(@library, current_user, form_params).call
|
||||||
|
if with_publish?
|
||||||
|
Libraries::SubmitService.new(current_library).call
|
||||||
|
redirect_to publish_success_libraries_path
|
||||||
|
else
|
||||||
|
flash[:message] = '保存成功'
|
||||||
|
render 'edit'
|
||||||
|
end
|
||||||
|
rescue ActiveRecord::RecordInvalid => _
|
||||||
|
render 'edit'
|
||||||
|
rescue Libraries::SubmitService::Error => ex
|
||||||
|
flash[:message] = ex.message
|
||||||
|
render 'edit'
|
||||||
|
end
|
||||||
|
|
||||||
|
def publish
|
||||||
|
Libraries::SubmitService.new(current_library).call
|
||||||
|
render json: { status: 0 }
|
||||||
|
rescue Libraries::SubmitService::Error => ex
|
||||||
|
render json: { status: 0, message: ex.message }
|
||||||
|
end
|
||||||
|
|
||||||
|
def publish_success
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def current_library
|
||||||
|
@_current_library ||= current_user.libraries.find(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def form_params
|
||||||
|
@_form_params ||= begin
|
||||||
|
hash = params[:library].presence || {}
|
||||||
|
hash[:attachment_ids] = (params[:attachments].presence || []).values.map{|h| h[:attachment_id]}
|
||||||
|
hash
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def with_publish?
|
||||||
|
params[:apply_publish].to_s == 'true'
|
||||||
|
end
|
||||||
|
|
||||||
|
def admin_or_self?
|
||||||
|
@library.user_id == current_user.id || current_user.admin?
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,47 @@
|
|||||||
|
class Managements::LibraryAppliesController < Managements::BaseController
|
||||||
|
before_filter :set_menu_type
|
||||||
|
|
||||||
|
def index
|
||||||
|
applies = LibraryApply.order('library_applies.updated_at desc')
|
||||||
|
|
||||||
|
search = params[:search].to_s.strip
|
||||||
|
if search.present?
|
||||||
|
applies = applies.joins(:library)
|
||||||
|
.where('libraries.uuid like :search or libraries.title like :search', search: "%#{search}%")
|
||||||
|
end
|
||||||
|
|
||||||
|
applies = applies.where(status: params[:status].presence || :pending)
|
||||||
|
|
||||||
|
@library_applies = paginateHelper applies.includes(library: { user: :user_extensions })
|
||||||
|
|
||||||
|
respond_to do |format|
|
||||||
|
format.js
|
||||||
|
format.html
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def agree
|
||||||
|
Libraries::AgreeApplyService.new(current_library_apply, current_user).call
|
||||||
|
render json: { status: 0 }
|
||||||
|
rescue Libraries::AgreeApplyService::Error => e
|
||||||
|
render json: { status: -1, message: e.message }
|
||||||
|
end
|
||||||
|
|
||||||
|
def refuse
|
||||||
|
Libraries::RefuseApplyService.new(current_library_apply, current_user, reason: params[:reason]).call
|
||||||
|
render json: { status: 0 }
|
||||||
|
rescue Libraries::RefuseApplyService::Error => e
|
||||||
|
render json: { status: -1, message: e.message }
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def current_library_apply
|
||||||
|
@_current_library_apply ||= LibraryApply.find(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_menu_type
|
||||||
|
@menu_type = 10
|
||||||
|
@sub_type = 8
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,7 @@
|
|||||||
|
module Util
|
||||||
|
module_function
|
||||||
|
|
||||||
|
def generate_time_uuid
|
||||||
|
"#{Time.zone.now.strftime('%Y%m%d%H%M%S')}#{Random.rand(10**8).to_i}"
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,52 @@
|
|||||||
|
class Library < ActiveRecord::Base
|
||||||
|
include AASM
|
||||||
|
|
||||||
|
belongs_to :user
|
||||||
|
|
||||||
|
has_many :library_applies, dependent: :delete_all
|
||||||
|
has_many :attachments, as: :container
|
||||||
|
|
||||||
|
attr_accessible :title, :content
|
||||||
|
|
||||||
|
validates :title, presence: true
|
||||||
|
validates :content, presence: true
|
||||||
|
validates :uuid, presence: true, uniqueness: true
|
||||||
|
|
||||||
|
acts_as_attachable
|
||||||
|
|
||||||
|
aasm(:status) do
|
||||||
|
state :pending, initiali: true
|
||||||
|
state :processing
|
||||||
|
state :refused
|
||||||
|
state :published
|
||||||
|
|
||||||
|
event :submit do
|
||||||
|
transitions from: [:pending, :refused], to: :processing
|
||||||
|
end
|
||||||
|
|
||||||
|
event :refuse do
|
||||||
|
transitions from: :processing, to: :refused
|
||||||
|
end
|
||||||
|
|
||||||
|
event :publish do
|
||||||
|
transitions from: :processing, to: :published
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def generate_uuid
|
||||||
|
uuid = Util.generate_time_uuid
|
||||||
|
while Library.exists?(uuid: uuid)
|
||||||
|
uuid = Util.generate_time_uuid
|
||||||
|
end
|
||||||
|
|
||||||
|
self.uuid = uuid
|
||||||
|
end
|
||||||
|
|
||||||
|
def increment_visited_count!
|
||||||
|
Library.connection.execute("update libraries set visited_count = COALESCE(visited_count, 0) + 1 where id = #{id}")
|
||||||
|
end
|
||||||
|
|
||||||
|
def editable?
|
||||||
|
pending? || refused?
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,19 @@
|
|||||||
|
class LibraryApply < ActiveRecord::Base
|
||||||
|
include AASM
|
||||||
|
|
||||||
|
belongs_to :library
|
||||||
|
|
||||||
|
aasm(:status) do
|
||||||
|
state :pending, initiali: true
|
||||||
|
state :refused
|
||||||
|
state :agreed
|
||||||
|
|
||||||
|
event :refuse do
|
||||||
|
transitions from: :pending, to: :refused
|
||||||
|
end
|
||||||
|
|
||||||
|
event :agree do
|
||||||
|
transitions from: :pending, to: :agreed
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,32 @@
|
|||||||
|
class Libraries::AgreeApplyService
|
||||||
|
Error = Class.new(StandardError)
|
||||||
|
|
||||||
|
attr_reader :library_apply, :library, :user
|
||||||
|
|
||||||
|
def initialize(library_apply, user)
|
||||||
|
@library_apply = library_apply
|
||||||
|
@library = library_apply.library
|
||||||
|
@user = user
|
||||||
|
end
|
||||||
|
|
||||||
|
def call
|
||||||
|
raise Error, '该状态下不能进行此操作' unless library_apply.may_agree?
|
||||||
|
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
library_apply.agree!
|
||||||
|
library_apply.library.publish!
|
||||||
|
|
||||||
|
# 将消息改为已处理
|
||||||
|
Tiding.where(container_id: library.id, container_type: 'Library', tiding_type: 'Apply', status: 0).update_all(status: 1)
|
||||||
|
notify_library_author!
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def notify_library_author!
|
||||||
|
Tiding.create!(user_id: library.user_id, trigger_user_id: 1,
|
||||||
|
container_id: library.id, container_type: 'Library',
|
||||||
|
tiding_type: 'System', status: 1)
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,39 @@
|
|||||||
|
class Libraries::RefuseApplyService
|
||||||
|
Error = Class.new(StandardError)
|
||||||
|
|
||||||
|
attr_reader :library_apply, :library, :user, :params
|
||||||
|
|
||||||
|
def initialize(library_apply, user, params)
|
||||||
|
@library_apply = library_apply
|
||||||
|
@library = library_apply.library
|
||||||
|
@user = user
|
||||||
|
@params = params
|
||||||
|
end
|
||||||
|
|
||||||
|
def call
|
||||||
|
reason = params[:reason].to_s.strip
|
||||||
|
raise Error, '原因不能为空' if reason.blank?
|
||||||
|
raise Error, '该状态下不能进行此操作' unless library_apply.may_refuse?
|
||||||
|
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
library_apply.reason = reason
|
||||||
|
library_apply.refused_at = Time.current
|
||||||
|
library_apply.refuse
|
||||||
|
library_apply.save!
|
||||||
|
|
||||||
|
library.refuse!
|
||||||
|
|
||||||
|
# 将消息改为已处理
|
||||||
|
Tiding.where(container_id: library.id, container_type: 'Library', tiding_type: 'Apply', status: 0).update_all(status: 1)
|
||||||
|
notify_library_author!
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def notify_library_author!
|
||||||
|
Tiding.create!(user_id: library.user_id, trigger_user_id: 1,
|
||||||
|
container_id: library.id, container_type: 'Library',
|
||||||
|
tiding_type: 'System', status: 2, extra: library_apply.reason)
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,37 @@
|
|||||||
|
class Libraries::SaveService
|
||||||
|
Error = Class.new(StandardError)
|
||||||
|
|
||||||
|
attr_reader :library, :user, :params
|
||||||
|
|
||||||
|
def initialize(library, user, params)
|
||||||
|
@library = library
|
||||||
|
@user = user
|
||||||
|
@params = params
|
||||||
|
end
|
||||||
|
|
||||||
|
def call
|
||||||
|
validate_params!
|
||||||
|
|
||||||
|
if library.new_record?
|
||||||
|
library.user_id = user.id
|
||||||
|
library.generate_uuid
|
||||||
|
end
|
||||||
|
|
||||||
|
attachment_ids = params.delete(:attachment_ids)
|
||||||
|
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
library.assign_attributes(params)
|
||||||
|
library.save!
|
||||||
|
|
||||||
|
Attachment.where(id: attachment_ids).update_all(container_id: library.id, container_type: 'Library')
|
||||||
|
end
|
||||||
|
|
||||||
|
library
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def validate_params!
|
||||||
|
raise Error, '附件不能为空' if params[:attachment_ids].blank?
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,31 @@
|
|||||||
|
class Libraries::SubmitService
|
||||||
|
Error = Class.new(StandardError)
|
||||||
|
|
||||||
|
attr_reader :library
|
||||||
|
|
||||||
|
def initialize(library)
|
||||||
|
@library = library
|
||||||
|
end
|
||||||
|
|
||||||
|
def call
|
||||||
|
raise Error, '该状态下不能提交审核' unless library.may_submit?
|
||||||
|
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
library.published_at = Time.current
|
||||||
|
library.submit
|
||||||
|
library.save!
|
||||||
|
|
||||||
|
library.library_applies.create!
|
||||||
|
send_library_apply_notify!
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def send_library_apply_notify!
|
||||||
|
Tiding.create!(user_id: 1, trigger_user_id: library.user_id,
|
||||||
|
container_id: library.id, container_type: 'Library',
|
||||||
|
tiding_type: 'Apply', status: 0)
|
||||||
|
Trustie::Sms.send(mobile: '18711011226', send_type:'publish_library' , name: '管理员') rescue nil
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,65 @@
|
|||||||
|
<p class="second_1" style="background: url('/images/educoder/competition/qg/qg_two_1.png') no-repeat top center;"></p>
|
||||||
|
<p class="second_2" style="background: url('/images/educoder/competition/qg/qg_two_2.png') no-repeat top center;"></p>
|
||||||
|
<div class="second_3" style="background: url('/images/educoder/competition/qg/qg_two_3.png') no-repeat top center;">
|
||||||
|
<div class="enter_panel">
|
||||||
|
<ul class="mb40">
|
||||||
|
<p class="mb30 font-22 enter_title"><span class="mr20 font-bd">第一阶段</span><span>2019-6-25 09:00-2019-7-10 24:00 </span></p>
|
||||||
|
<li class="inline enter_btn">
|
||||||
|
<a href="javascript:void(0)" class="active">Java入口</a>
|
||||||
|
<a href="javascript:void(0)" class="active">C/C++入口</a>
|
||||||
|
<a href="javascript:void(0)">Python入口</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul>
|
||||||
|
<p class="mb30 font-22 enter_title"><span class="mr20 font-bd">第一阶段</span><span>2019-6-25 09:00-2019-7-10 24:00 </span></p>
|
||||||
|
<li class="inline enter_btn">
|
||||||
|
<a href="javascript:void(0)">Java入口</a>
|
||||||
|
<a href="javascript:void(0)">C/C++入口</a>
|
||||||
|
<a href="javascript:void(0)">Python入口</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="second_4" style="background: url('/images/educoder/competition/qg/qg_two_4.png') no-repeat top center;">
|
||||||
|
<div class="enter_panel">
|
||||||
|
<ul class="mb40">
|
||||||
|
<p class="mb30 font-22 enter_title"><span class="mr20 font-bd">第一阶段</span><span>2019-6-25 09:00-2019-7-10 24:00 </span></p>
|
||||||
|
<li class="inline enter_btn">
|
||||||
|
<a href="javascript:void(0)" class="active">Java入口</a>
|
||||||
|
<a href="javascript:void(0)" class="active">C/C++入口</a>
|
||||||
|
<a href="javascript:void(0)">Python入口</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul>
|
||||||
|
<p class="mb30 font-22 enter_title"><span class="mr20 font-bd">第一阶段</span><span>2019-6-25 09:00-2019-7-10 24:00 </span></p>
|
||||||
|
<li class="inline enter_btn">
|
||||||
|
<a href="javascript:void(0)">Java入口</a>
|
||||||
|
<a href="javascript:void(0)">C/C++入口</a>
|
||||||
|
<a href="javascript:void(0)">Python入口</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="second_5" style="background: url('/images/educoder/competition/qg/qg_two_5.png') no-repeat top center;">
|
||||||
|
<div class="enter_panel">
|
||||||
|
<ul class="mb40">
|
||||||
|
<p class="mb30 font-22 enter_title"><span class="mr20 font-bd">第一阶段</span><span>2019-6-25 09:00-2019-7-10 24:00 </span></p>
|
||||||
|
<li class="inline enter_btn">
|
||||||
|
<a href="javascript:void(0)" class="active">Java入口</a>
|
||||||
|
<a href="javascript:void(0)" class="active">C/C++入口</a>
|
||||||
|
<a href="javascript:void(0)">Python入口</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul>
|
||||||
|
<p class="mb30 font-22 enter_title"><span class="mr20 font-bd">第一阶段</span><span>2019-6-25 09:00-2019-7-10 24:00 </span></p>
|
||||||
|
<li class="inline enter_btn">
|
||||||
|
<a href="javascript:void(0)">Java入口</a>
|
||||||
|
<a href="javascript:void(0)">C/C++入口</a>
|
||||||
|
<a href="javascript:void(0)">Python入口</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p class="second_6" style="background: url('/images/educoder/competition/qg/qg_two_6.png') no-repeat top center;"></p>
|
||||||
|
<p class="second_7" style="background: url('/images/educoder/competition/qg/qg_two_7.png') no-repeat top center;"></p>
|
||||||
|
<p class="second_8" style="background: url('/images/educoder/competition/qg/qg_two_8.png') no-repeat top center;"></p>
|
@ -0,0 +1,71 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" xmlns="http://www.w3.org/1999/html">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>
|
||||||
|
<%= h html_title %>
|
||||||
|
</title>
|
||||||
|
<meta name="description" content="高校智能课堂与综合实训平台"/>
|
||||||
|
<meta name="keywords" content="智能课堂,实训项目"/>
|
||||||
|
<%= csrf_meta_tag %>
|
||||||
|
<%= favicon %>
|
||||||
|
<%= javascript_heads %>
|
||||||
|
<%= heads_for_theme %>
|
||||||
|
<%= call_hook :view_layouts_base_html_head %>
|
||||||
|
<%= stylesheet_link_tag 'jquery/jquery-ui-1.9.2', 'css/common', 'css/public', 'css/ketang', 'css/structure', 'prettify', 'css/courses', 'css/popup', 'css/syllabus', 'css/moduel', 'css/font-awesome', 'css/contest', 'css/font-awesome', 'css/edu-class', 'css/edu-popup', 'educoder/magic-check', 'css/edu-common', "css/edu-public", 'educoder/edu-main', 'educoder/edu-all' %>
|
||||||
|
<%= javascript_include_tag "avatars", "header", "attachments", 'prettify', "edu/application", 'jquery.datetimepicker.js', 'educoder/edu_application', 'educoder/edu_file' %>
|
||||||
|
<%= javascript_include_tag "/codemirror/lib/codemirror", "/codemirror/mode/javascript/javascript", "/codemirror/addon/hint/show-hint", "/codemirror/addon/hint/javascript-hint", "/codemirror/addon/selection/active-line", "/codemirror/addon/lint/javascript-lint", "/codemirror/addon/lint/css-lint", "/codemirror/addon/lint/lint", "/codemirror/addon/lint/json-lint", "/editormd/lib/codemirror/addon/lint/css-lint" %>
|
||||||
|
<%= stylesheet_link_tag "/codemirror/lib/codemirror" %>
|
||||||
|
<%= stylesheet_link_tag '/editormd/css/editormd' %>
|
||||||
|
<%= javascript_include_tag '/editormd/editormd', '/editormd/lib/marked.min.js', '/editormd/lib/prettify.min.js', '/editormd/lib/raphael.min.js', '/editormd/lib/underscore.min.js', '/editormd/lib/sequence-diagram.min.js',
|
||||||
|
'/editormd/lib/flowchart.min.js', '/editormd/lib/jquery.flowchart.min.js', '/editormd/editormd.js' %>
|
||||||
|
<%= yield :header_tags -%>
|
||||||
|
<!-- MathJax的配置 -->
|
||||||
|
<script type="text/javascript" src="/javascripts/MathJax/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
|
||||||
|
</script>
|
||||||
|
<script type="text/x-mathjax-config">
|
||||||
|
MathJax.Hub.Config({
|
||||||
|
|
||||||
|
showMathMenu: false,
|
||||||
|
showMathMenuMSIE: false,
|
||||||
|
tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<!--add by huang-->
|
||||||
|
<body onload="prettyPrint();" style="height: 100%;background: #fff">
|
||||||
|
<div class="newContainer"> <!-- 页面全部内容 -->
|
||||||
|
<div class="newHeader" id="nHeader"> <!-- 头部 -->
|
||||||
|
<% if User.current.logged? %>
|
||||||
|
<%= render :partial => 'layouts/logined_header' %>
|
||||||
|
<% else %>
|
||||||
|
<%= render :partial => 'layouts/unlogin_header' %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
<div class="cl"></div>
|
||||||
|
<div class="newMain clearfix">
|
||||||
|
<%= yield %>
|
||||||
|
<!-------------------侧边提示区域-------------------------->
|
||||||
|
<%= render :partial => 'users/returnTop_btn' %>
|
||||||
|
</div>
|
||||||
|
<!----------------------- 左侧导航栏 ----------------------------->
|
||||||
|
<%#= render :partial => 'layouts/public_left_info' %>
|
||||||
|
<%= render :partial => 'layouts/footer' %>
|
||||||
|
<div class="cl"></div>
|
||||||
|
<%#= render :partial => 'layouts/new_feedback' %>
|
||||||
|
|
||||||
|
<div id="ajax-indicator" style="display:none;">
|
||||||
|
<span><%= l(:label_loading) %></span>
|
||||||
|
</div>
|
||||||
|
<div id="ajax-notice" style="display: none; text-align: center; bottom: 200px; left: 50%; margin-left: -70px; background: #a1a1a1; width: 140px; height: 80px; position: absolute; z-index: 999999;">
|
||||||
|
<p id="ajax_notice_p" style="text-align: center; color: #fff; font-size: 18px; padding-top: 26px;">分数已保存</p>
|
||||||
|
</div>
|
||||||
|
<div id="ajax-modal" style="display:none;"></div>
|
||||||
|
|
||||||
|
<%= call_hook :view_layouts_base_body_bottom %>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
<script>
|
||||||
|
</script>
|
||||||
|
</html>
|
@ -0,0 +1,28 @@
|
|||||||
|
<div class="library_list">
|
||||||
|
<% if @libraries.present? %>
|
||||||
|
<% @libraries.each do |library| %>
|
||||||
|
<li class="library_list_item">
|
||||||
|
<img src="/<%= url_to_avatar(library.user) %>" width="50" height="50" class="radius mr15 mt3">
|
||||||
|
<div class="flex1">
|
||||||
|
<p class="task-hide font-16 mb15 lineh-20"><%= link_to library.title, library_path(library) %></p>
|
||||||
|
<p class="clearfix lineh-20">
|
||||||
|
<span class="color-grey-3 mr20"><%= link_to library.user.show_real_name, user_path(library.user) %></span>
|
||||||
|
<span class="color-grey-c mr20"><%= library.visited_count || 0 %> 浏览</span>
|
||||||
|
<span class="color-grey-c mr20">发布时间:<%= library.published_at.try(:strftime, '%Y-%m-%d %H:%M') %></span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<% end %>
|
||||||
|
<% else %>
|
||||||
|
<%= render :partial => "welcome/no_data" %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
<div class="mt30 mb50 edu-txt-center clearfix">
|
||||||
|
<!--这里放分页-->
|
||||||
|
<div class="inline pages_user_show">
|
||||||
|
<ul>
|
||||||
|
<%= pagination_links_full @obj_pages, @obj_count, :per_page_links => false, :remote => true, :flag => true, :is_new => true %>
|
||||||
|
</ul>
|
||||||
|
<div class="cl"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -0,0 +1,8 @@
|
|||||||
|
<div class="educontent mb50">
|
||||||
|
<p class="mt10 mb20 clearfix lineh-20">
|
||||||
|
<%= link_to '文库', libraries_path, class: 'color-grey-9' %> >
|
||||||
|
<span class="color-grey-3">编辑</span>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<%= render partial: 'form' %>
|
||||||
|
</div>
|
@ -0,0 +1,51 @@
|
|||||||
|
<div class="educontent">
|
||||||
|
<div class="edu-back-white mb30 mt30">
|
||||||
|
<p class="padding20-30 clearfix bor-bottom-greyE">
|
||||||
|
<span class="font-18 fl color-grey-3">文库</span>
|
||||||
|
<%= link_to '新建', new_library_path, class: 'fr color-blue font-16 mt3' %>
|
||||||
|
</p>
|
||||||
|
<div class="clearfix pt20 pl30 pr30">
|
||||||
|
<ul class="fl library_nav">
|
||||||
|
<li class="<%= params[:type] == 'mine' ? '' : 'active' %>">
|
||||||
|
<%= link_to '全部', libraries_path(search: params[:search]), remote: true %>
|
||||||
|
</li>
|
||||||
|
<li class="<%= params[:type] == 'mine' ? 'active' : '' %>">
|
||||||
|
<%= link_to '我的', libraries_path(search: params[:search], type: 'mine'), remote: true %>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="edu-position fr">
|
||||||
|
<%= hidden_field_tag(:type, params[:type]) %>
|
||||||
|
<input class="winput-240-30 panel-box-sizing" placeholder="输入文库标题、编号进行检索" type="text" id="search_name">
|
||||||
|
<a href="javascript:void(0);" class="edu-btn-search font-16 color-grey" id="search"><i class="fa fa-search"></i></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="library-list-container">
|
||||||
|
<%= render partial: 'library_list' %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
$(function(){
|
||||||
|
$(".library_nav").on("click","li",function(){
|
||||||
|
$(".library_nav li").removeClass("active");
|
||||||
|
$(this).addClass("active");
|
||||||
|
});
|
||||||
|
|
||||||
|
var searchFunc = function() {
|
||||||
|
var search = $("#search_name").val();
|
||||||
|
var type = $("input[name='type']").val();
|
||||||
|
$.ajax({
|
||||||
|
url: "/libraries",
|
||||||
|
dataType: 'script',
|
||||||
|
data: {search: search, type: type}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
$("#search").live("click", searchFunc);
|
||||||
|
$('#search_name').bind('keypress',function(event) {
|
||||||
|
if (event.keyCode == "13") {
|
||||||
|
searchFunc();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
</script>
|
@ -0,0 +1,3 @@
|
|||||||
|
$('input[name="type"]').val('<%= params[:type].to_s %>');
|
||||||
|
$('#search_name').val('<%= params[:search].to_s %>');
|
||||||
|
$('.library-list-container').html('<%= j render(partial: 'library_list') %>')
|
@ -0,0 +1,8 @@
|
|||||||
|
<div class="educontent mb50">
|
||||||
|
<p class="mt10 mb20 clearfix lineh-20">
|
||||||
|
<%= link_to '文库', libraries_path, class: 'color-grey-9' %> >
|
||||||
|
<span class="color-grey-3">新建</span>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<%= render partial: 'form' %>
|
||||||
|
</div>
|
@ -0,0 +1,14 @@
|
|||||||
|
<div class="educontent edu-back-white mt20 successPage">
|
||||||
|
<div>
|
||||||
|
<img src="/images/educoder/success.png" width="100" class="mb30">
|
||||||
|
<div class="lineh-30 ed-txt-center font-24 color-grey-3 font-bd mb15">
|
||||||
|
<p>恭喜!</p>
|
||||||
|
<p>文档上传成功</p>
|
||||||
|
</div>
|
||||||
|
<p class="lineh-30 ed-txt-center font-16 color-grey-9 font-bd mb15">通过平台管理员审核后,即可公开显示</p>
|
||||||
|
<li class="inline">
|
||||||
|
<%= link_to '查看已上传文档', libraries_path(type: 'mine'), class: 'white-btn edu-blueline-btn changebtn mr20 fl' %>
|
||||||
|
<%= link_to '继续上传', new_library_path, class: 'white-btn edu-blueback-btn changebtn fl' %>
|
||||||
|
</li>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -0,0 +1,92 @@
|
|||||||
|
<%
|
||||||
|
admin_or_self = User.current.admin? || @library.user_id == User.current.id
|
||||||
|
%>
|
||||||
|
<div class="educontent mb50">
|
||||||
|
<p class="mt10 mb20 clearfix lineh-20">
|
||||||
|
<%= link_to '文库', libraries_path, class: 'color-grey-9' %> >
|
||||||
|
<span class="color-grey-3">详情</span>
|
||||||
|
</p>
|
||||||
|
<p class="lineh-25 mb20 clearfix">
|
||||||
|
<span class="font-22 fl mr10 task-hide" style="max-width: 800px"><%= @library.title %></span>
|
||||||
|
<% if admin_or_self %>
|
||||||
|
<% if @library.pending? %>
|
||||||
|
<span class="fl edu-filter-btn edu-activity-green mt5">草稿</span>
|
||||||
|
<% elsif @library.processing? %>
|
||||||
|
<span class="fl edu-filter-btn edu-activity-green mt5">审核中</span>
|
||||||
|
<% elsif @library.refused? %>
|
||||||
|
<span class="fl edu-filter-btn edu-activity-orange mt5">未通过</span>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
<%= link_to('返回', libraries_path, class: 'fr color-grey-9 mt5') %>
|
||||||
|
</p>
|
||||||
|
<div class="edu-back-white">
|
||||||
|
<% if admin_or_self && !@library.published? && @library_applies.size > 0 %>
|
||||||
|
<div class="padding30">
|
||||||
|
<p class="mb10 clearfix">
|
||||||
|
<span class="color-grey-6 font-16 mr10">私有化原因</span>
|
||||||
|
<span class="color-grey-c font-12">(请按照提示修改,并在完成编辑后重新提交)</span>
|
||||||
|
<a href="javascript:void(0)" class="color-blue fr" at="0" onclick="getMore(this)">点击展开<i class="iconfont icon-xiajiantou color-blue font-14 ml5"></i></a>
|
||||||
|
</p>
|
||||||
|
<div class="private_reason">
|
||||||
|
<% @library_applies.each do |apply| %>
|
||||||
|
<li>
|
||||||
|
<p class="color-grey-9"><%= apply.updated_at.strftime('%Y-%m-%d %H:%M') %></p>
|
||||||
|
<p class="lineh-25 font-16 break-word"><%= apply.reason %></p>
|
||||||
|
</li>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
<div class="padding30 bor-top-greyE">
|
||||||
|
<p class="mb10 clearfix">
|
||||||
|
<span class="color-grey-6 font-16 mr10">详情</span>
|
||||||
|
<% if admin_or_self && @library.editable? %>
|
||||||
|
<%= link_to '编辑', edit_library_path(id: @library.id), class: 'white-btn edu-blueline-btn fr' %>
|
||||||
|
<% end %>
|
||||||
|
</p>
|
||||||
|
<div class="df mb20">
|
||||||
|
<img src="<%= url_to_avatar(@library.user) %>" width="50" height="50" class="radius mr15 mt3"/>
|
||||||
|
<div class="flex1">
|
||||||
|
<li class="font-16"><%= @library.user.show_real_name %></li>
|
||||||
|
<li class="clearfix">
|
||||||
|
<span class="fl color-grey-9 mr20"><%= @library.user.school_name %></span>
|
||||||
|
<span class="fl color-grey-9"><%= @library.user.identity %></span>
|
||||||
|
<span class="fr">
|
||||||
|
<span class="fl color-grey-9 mr30">编码:<span class="color-grey-6"><%= @library.uuid %></span></span>
|
||||||
|
<span class="fl color-grey-9">上传时间:<span class="color-grey-6"><%= @library.created_at.strftime('%Y-%m-%d %H:%M') %></span></span>
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="break_full_word new_li" id="labraries_editorMd_content">
|
||||||
|
<textarea style="display:none;"><%= @library.content %></textarea>
|
||||||
|
</div>
|
||||||
|
<div class="mt10">
|
||||||
|
<%= render partial: 'attachments/links', locals: { attachments: @library.attachments, options: {} } %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
function getMore(item) {
|
||||||
|
var at=$(item).attr("at");
|
||||||
|
if(at=="0"){
|
||||||
|
$(item).html('点击收起<i class="iconfont icon-shangjiantou color-blue font-14 ml5"></i>');
|
||||||
|
$(item).attr("at","1");
|
||||||
|
$(".private_reason").css({maxHeight:"unset"});
|
||||||
|
}else{
|
||||||
|
$(item).html('点击展开<i class="iconfont icon-xiajiantou color-blue font-14 ml5"></i>');
|
||||||
|
$(item).attr("at","0");
|
||||||
|
$(".private_reason").css({maxHeight:"150px"});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var homeworkDescr = editormd.markdownToHTML("labraries_editorMd_content", {
|
||||||
|
htmlDecode: "style,script,iframe", // you can filter tags decode
|
||||||
|
taskList: true,
|
||||||
|
tex: true, // 默认不解析
|
||||||
|
flowChart: true, // 默认不解析
|
||||||
|
sequenceDiagram: true // 默认不解析
|
||||||
|
});
|
||||||
|
</script>
|
@ -0,0 +1,120 @@
|
|||||||
|
<div class="edu-class-container mb15">
|
||||||
|
<div class="edu-con-top clearfix">
|
||||||
|
<p class="ml15 fl color-grey">文库发布</p>
|
||||||
|
</div>
|
||||||
|
<div class="edu-con-bg01 mt15">
|
||||||
|
<div class="edu-tab clearfix mb20">
|
||||||
|
<ul id="edu-tab-nav" class="border-bottom-orange">
|
||||||
|
<li id="edu-tab-nav-1" class="new-tab-nav background-orange" onclick="HoverLi(1);">
|
||||||
|
<%= link_to "待审批", library_applies_path(status: :pending), class: 'tab_type', remote: true %>
|
||||||
|
</li>
|
||||||
|
<li id="edu-tab-nav-2" class="new-tab-nav" onclick="HoverLi(2);">
|
||||||
|
<%= link_to "已审批", library_applies_path(status: [:refused, :agreed]), class: 'tab_type', remote: true %>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="cl"></div>
|
||||||
|
<div id="edu-tab-con-1">
|
||||||
|
<div class="mt10">
|
||||||
|
<div class="edu-position fr task-form-30 mb10 mr15">
|
||||||
|
<input class="task-form-100 panel-box-sizing" placeholder="输入文库标题、编号进行检索" type="text" id="search_name">
|
||||||
|
<a href="javascript:void(0);" class="edu-btn-search font-16 color-grey mt10" id="search"><i class="fa fa-search"></i></a>
|
||||||
|
</div>
|
||||||
|
<div class="cl"></div>
|
||||||
|
<div id="authentication_list" class="auth_table">
|
||||||
|
<%= render :partial => "managements/library_applies/library_apply_list"%>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="edu-tab-con-2" class="undis">
|
||||||
|
<div class="mt10">
|
||||||
|
<p class="fl task-form-60 mt8 ml15 clearfix">
|
||||||
|
<%= link_to "全部", library_applies_path(status: [:refused, :agreed]), :class => "edu-filter-cir-grey mr5 fl font-12 active", :id => "library_all_authentication", :remote => true %>
|
||||||
|
<%= link_to "同意", library_applies_path(status: :agreed), :class => "edu-filter-cir-grey mr5 fl font-12", :id => "library_agree_authentication", :remote => true %>
|
||||||
|
<%= link_to "拒绝", library_applies_path(status: :refused), :class => "edu-filter-cir-grey mr5 fl font-12", :id => "library_reject_authentication", :remote => true %>
|
||||||
|
</p>
|
||||||
|
<div class="edu-position fr task-form-30 mb10 fr mr15">
|
||||||
|
<input class="task-form-100 panel-box-sizing" placeholder="输入文库标题、编号进行检索" type="text" id="library_search_name">
|
||||||
|
<a href="javascript:void(0);" class="edu-btn-search font-16 color-grey mt10" id="library_search"><i class="fa fa-search"></i></a>
|
||||||
|
</div>
|
||||||
|
<div class="cl"></div>
|
||||||
|
<div id="library_authentication_list" class="auth_table">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="cl"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
/* -------------------------- 拒绝 ------------------------------------ */
|
||||||
|
function reject_library_authentication_reason(nThis){
|
||||||
|
var reason = $(nThis).parent().parent().find('div');
|
||||||
|
reason.find("input").val("");
|
||||||
|
reason.toggle();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------- 取消 ------------------------------------ */
|
||||||
|
function library_hide_reject_reason(nThis){
|
||||||
|
var reason = $(nThis).parent().parent();
|
||||||
|
reason.find("input").val("");
|
||||||
|
reason.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------- 提交拒绝原因 --------------------------------- */
|
||||||
|
function library_submit_reject_reason(id, nThis){
|
||||||
|
var nReason = $(nThis).parent().parent();
|
||||||
|
var reason = nReason.find("input").val();
|
||||||
|
if (reason == '') {
|
||||||
|
alert('请输入原因');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$.ajax({
|
||||||
|
url: '/managements/library_applies/' + id + '/refuse',
|
||||||
|
type: 'post',
|
||||||
|
data: {reason: reason},
|
||||||
|
success: function(data){
|
||||||
|
if (data && data.status != -1) {
|
||||||
|
$('#authentication_list .admin-con-box.apply-' + id).remove();
|
||||||
|
|
||||||
|
if($('#authentication_list .admin-con-box').length == 0){
|
||||||
|
location.reload();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
alert(data.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------- 按名字进行搜索(未审批) ----------------------------- */
|
||||||
|
$("#search").live("click", function(){
|
||||||
|
var iName = $("#search_name").val();
|
||||||
|
$.ajax({
|
||||||
|
url: "/managements/library_applies",
|
||||||
|
dataType: 'script',
|
||||||
|
data: { search: iName, status: 'pending' }
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
/* ------------------- 按名字进行搜索(已审批)-------------------- */
|
||||||
|
$("#library_search").live("click", function(){
|
||||||
|
var iName = $("#library_search_name").val();
|
||||||
|
var id = $("#library_all_authentication").parent().find(".active").attr("id");
|
||||||
|
var status = '';
|
||||||
|
|
||||||
|
if(id == "library_all_authentication"){
|
||||||
|
status = ['refused', 'agreed'];
|
||||||
|
}else if(id=="library_agree_authentication"){
|
||||||
|
status = 'agreed';
|
||||||
|
}else{
|
||||||
|
status = 'refused';
|
||||||
|
}
|
||||||
|
$.ajax({
|
||||||
|
url: "/managements/library_applies",
|
||||||
|
dataType: 'script',
|
||||||
|
data: { search: iName, status: status}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
@ -0,0 +1,30 @@
|
|||||||
|
var nTabIcon_1 = $("#edu-tab-con-1");
|
||||||
|
var nTabIcon_2 = $("#edu-tab-con-2");
|
||||||
|
var nTabNav_1 = $("#edu-tab-nav-1");
|
||||||
|
var nTabNav_2 = $("#edu-tab-nav-2");
|
||||||
|
var nAudit = $("#library_all_authentication").parent();
|
||||||
|
|
||||||
|
<% if params[:status].to_s == 'pending' %>
|
||||||
|
$("#authentication_list").html("<%= j( render :partial => "managements/library_applies/library_apply_list" ) %>");
|
||||||
|
nTabNav_1.addClass("background-orange");
|
||||||
|
nTabNav_2.removeClass("background-orange");
|
||||||
|
nTabIcon_1.show();
|
||||||
|
nTabIcon_2.hide();
|
||||||
|
<% else %>
|
||||||
|
$("#library_authentication_list").html("<%= j( render :partial => "managements/library_applies/library_apply_list" ) %>");
|
||||||
|
nTabNav_1.removeClass("background-orange");
|
||||||
|
nTabNav_2.addClass("background-orange");
|
||||||
|
nTabIcon_1.hide();
|
||||||
|
nTabIcon_2.show();
|
||||||
|
/* -------------------------- 未审批(全部、同意、拒绝点击时动态样式) ------------------------------ */
|
||||||
|
if(<%= params[:status].to_s == 'agreed' %>){
|
||||||
|
nAudit.find(".active").removeClass("active");
|
||||||
|
$("#library_agree_authentication").addClass("active");
|
||||||
|
}else if(<%= params[:status].to_s == 'refused' %>){
|
||||||
|
nAudit.find(".active").removeClass("active");
|
||||||
|
$("#library_reject_authentication").addClass("active");
|
||||||
|
}else{
|
||||||
|
nAudit.find(".active").removeClass("active");
|
||||||
|
$("#library_all_authentication").addClass("active");
|
||||||
|
}
|
||||||
|
<% end %>
|
@ -0,0 +1,8 @@
|
|||||||
|
'zh':
|
||||||
|
activerecord:
|
||||||
|
models:
|
||||||
|
library: '文库'
|
||||||
|
attributes:
|
||||||
|
library:
|
||||||
|
title: '标题'
|
||||||
|
content: '描述'
|
@ -0,0 +1,18 @@
|
|||||||
|
class CreateLibraries < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
create_table :libraries do |t|
|
||||||
|
t.references :user
|
||||||
|
|
||||||
|
t.string :title
|
||||||
|
t.text :content
|
||||||
|
t.string :uuid, unique: true
|
||||||
|
t.string :status
|
||||||
|
t.integer :visited_count, default: 0
|
||||||
|
t.datetime :published_at
|
||||||
|
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
|
||||||
|
add_index :libraries, :published_at
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,14 @@
|
|||||||
|
class CreateLibraryApplies < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
create_table :library_applies do |t|
|
||||||
|
t.references :library
|
||||||
|
t.string :status
|
||||||
|
t.string :reason
|
||||||
|
|
||||||
|
t.datetime :refused_at
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
|
||||||
|
add_index :library_applies, :refused_at
|
||||||
|
end
|
||||||
|
end
|
After Width: | Height: | Size: 213 KiB |
After Width: | Height: | Size: 111 KiB |
After Width: | Height: | Size: 45 KiB |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 94 KiB |
After Width: | Height: | Size: 93 KiB |
After Width: | Height: | Size: 98 KiB |
After Width: | Height: | Size: 3.3 KiB |