From b9b1e67c14523a31130d3bb7a03abf5a75079bdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Sat, 24 Aug 2019 11:23:44 +0800 Subject: [PATCH 01/11] =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/modules/courses/new/CoursesNew.js | 71 ++++++------------- .../src/modules/courses/new/Goldsubject.js | 41 ++++++++++- 2 files changed, 61 insertions(+), 51 deletions(-) diff --git a/public/react/src/modules/courses/new/CoursesNew.js b/public/react/src/modules/courses/new/CoursesNew.js index b87b4e81d..8c68dd4c5 100644 --- a/public/react/src/modules/courses/new/CoursesNew.js +++ b/public/react/src/modules/courses/new/CoursesNew.js @@ -44,7 +44,9 @@ class CoursesNew extends Component { fetching:false, boolxinjian:false, checkboxgroup:undefined, - checkbofrup:["shixun_homework","common_homework","group_homework","exercise","attachment","course_group","graduation","poll","board"], + checkbofrup:[{module_type:"shixun_homework",module_name:"实训作业"},{module_type:"common_homework",module_name:"普通作业"},{module_type:"group_homework",module_name:"分组作业"} + ,{module_type:"exercise",module_name:"试卷"},{module_type:"poll",module_name:"问卷"},{module_type:"graduation",module_name:"毕业设计"} + ,{module_type:"board",module_name:"讨论"},{module_type:"attachment",module_name:"资源"},{module_type:"course_group",module_name:"分班"}], checkbofrups:[], } } @@ -78,32 +80,22 @@ class CoursesNew extends Component { is_public: data.is_public === 1 ? true : false, Realnamecertification: data.authentication, Professionalcertification:data.professional_certification, - + checkbofrups:data.course_modules, }); try { - var datasysl=[]; - var dataysl2=[]; - var dataysl3=[]; - var checkbofrup =this.state.checkbofrup; - dataysl2=data.course_module_types; - datasysl=checkbofrup; - for (var k=0;k { console.log(error); @@ -450,6 +442,7 @@ class CoursesNew extends Component { search: value } }).then((result)=>{ + if(result){ if (result.data.status===0) { this.setState({ searchlistscholl: result.data.school_names, @@ -461,6 +454,7 @@ class CoursesNew extends Component { }) } } + } }).catch((error)=>{ console.log(error) }) @@ -469,7 +463,7 @@ class CoursesNew extends Component { this.applyForAddOrgForm.setVisible(true) } render() { - let {datatime,school,searchlistscholl,checkboxgroup} = this.state; + let {datatime,school,searchlistscholl,checkbofrups} = this.state; const {getFieldDecorator} = this.props.form; const propsWithoutForm = Object.assign({}, this.props) delete propsWithoutForm.form @@ -699,27 +693,9 @@ class CoursesNew extends Component { this.props.match.params.coursesId != undefined? { - checkboxgroup===undefined?"":checkboxgroup.length===0?"":checkboxgroup.map((item,key)=>{ + checkbofrups===undefined?"":checkbofrups.length===0?"":checkbofrups.map((item,key)=>{ return( - item ==="shixun_homework"? - 实训作业 - :item ==="common_homework"? - 普通作业 - :item ==="group_homework"? - 分组作业 - :item ==="exercise"? - 试卷 - :item ==="attachment"? - 资源 - :item ==="course_group"? - 分班 - :item ==="graduation"? - 毕业设计 - :item ==="poll"? - 问卷 - :item ==="board"? - 讨论 - :"" + {item.module_name} ) }) } @@ -729,16 +705,13 @@ class CoursesNew extends Component { 实训作业 普通作业 分组作业 - 试卷 - 资源 - 分班 毕业设计 + 试卷 问卷 + 资源 讨论 + 分班 - - - )} diff --git a/public/react/src/modules/courses/new/Goldsubject.js b/public/react/src/modules/courses/new/Goldsubject.js index 7214f46a8..ee1d3b9c7 100644 --- a/public/react/src/modules/courses/new/Goldsubject.js +++ b/public/react/src/modules/courses/new/Goldsubject.js @@ -50,7 +50,12 @@ class Goldsubject extends Component { subject_id:"", start_date:"", Whethertocreateanewclassroom:true, - + checkbofrup:[ + {module_type:"announcement",module_name:"公告栏"},{module_type:"online_learning",module_name:"在线学习"} + ,{module_type:"shixun_homework",module_name:"实训作业"},{module_type:"common_homework",module_name:"普通作业"} + ,{module_type:"exercise",module_name:"试卷"},{module_type:"poll",module_name:"问卷"} + ,{module_type:"attachment",module_name:"资源"},{module_type:"board",module_name:"讨论"},{module_type:"course_group",module_name:"分班"},], + checkbofrups:[], } } // disabledEndDate= endValue => { @@ -139,7 +144,20 @@ class Goldsubject extends Component { course_module_types: data.course_module_types, school:data.school, Whethertocreateanewclassroom:false, + checkbofrups:data.course_modules, }); + + try { + if(data.course_modules===undefined||data.course_modules.length===0){ + this.setState({ + checkbofrups:this.state.checkbofrup, + }); + } + }catch (e) { + this.setState({ + checkbofrups:this.state.checkbofrup, + }); + } this.handleSearchschool(data.school); }).catch((error) => { console.log(error); @@ -591,7 +609,7 @@ class Goldsubject extends Component { this.applyForAddOrgForm.setVisible(true) } render() { - let {datatime,datatimetwo,school,searchlistscholl,Whethertocreateanewclassroom} = this.state; + let {datatime,datatimetwo,school,searchlistscholl,Whethertocreateanewclassroom,checkbofrups} = this.state; const {getFieldDecorator} = this.props.form; const propsWithoutForm = Object.assign({}, this.props) delete propsWithoutForm.form @@ -860,6 +878,25 @@ class Goldsubject extends Component { "announcement","online_learning","shixun_homework","common_homework", ], })( + this.props.match.params.coursesId != undefined? + + { + checkbofrups===undefined?"":checkbofrups.length===0?"":checkbofrups.map((item,key)=>{ + return( + item.module_type==="announcement"? + 公告栏 + : + item.module_type==="online_learning"? + 在线学习 + : + item.module_type==="graduation"?"": + item.module_type==="group_homework"?"": + {item.module_name} + ) + }) + } + + : 公告栏 在线学习 From 94049f7592501621bd4f97d6f25c6ad7dd126111 Mon Sep 17 00:00:00 2001 From: p31729568 Date: Mon, 26 Aug 2019 10:13:11 +0800 Subject: [PATCH 02/11] admins: identity and professional auth feature --- app/assets/javascripts/admin.js | 27 ++++- .../javascripts/admins/common-refuse-modal.js | 54 ++++++++++ .../admins/identity_authentications/index.js | 18 ++++ .../professional_authentications/index.js | 18 ++++ .../javascripts/admins/search-form-tab.js | 10 ++ app/assets/javascripts/bootstrap.viewer.js | 50 +++++++++ app/assets/stylesheets/admin.scss | 6 +- app/assets/stylesheets/admins/common.scss | 6 ++ .../admins/identity-authentications.scss | 9 ++ .../admins/professional-authentications.scss | 9 ++ .../identity_authentications_controller.rb | 26 +++++ ...professional_authentications_controller.rb | 26 +++++ .../concerns/admins/render_helper.rb | 1 + app/helpers/admins/base_helper.rb | 102 ++++++++++++++++++ app/helpers/application_helper.rb | 101 +++-------------- app/libs/util/file_manage.rb | 40 +++++++ app/models/apply_user_authentication.rb | 6 ++ .../admins/apply_user_authentication_query.rb | 34 ++++++ .../identity_auths/agree_apply_service.rb | 38 +++++++ .../identity_auths/refuse_apply_service.rb | 40 +++++++ .../professional_auths/agree_apply_service.rb | 38 +++++++ .../refuse_apply_service.rb | 40 +++++++ .../identity_authentications/index.html.erb | 32 ++++++ .../identity_authentications/index.js.erb | 1 + .../shared/_list.html.erb | 74 +++++++++++++ .../index.html.erb | 32 ++++++ .../professional_authentications/index.js.erb | 1 + .../shared/_list.html.erb | 72 +++++++++++++ .../admins/school_statistics/index.html.erb | 4 +- .../_admin_common_refuse_modal.html.erb | 26 +++++ app/views/admins/shared/_sidebar.html.erb | 7 ++ .../admins/shared/after_render_js_hook.js.erb | 3 +- app/views/admins/shared/delete.js.erb | 2 + .../admins/users/shared/_user_list.html.erb | 22 ++-- .../apply_user_authentications/zh-CN.yml | 7 ++ config/routes.rb | 15 ++- 36 files changed, 886 insertions(+), 111 deletions(-) create mode 100644 app/assets/javascripts/admins/common-refuse-modal.js create mode 100644 app/assets/javascripts/admins/identity_authentications/index.js create mode 100644 app/assets/javascripts/admins/professional_authentications/index.js create mode 100644 app/assets/javascripts/admins/search-form-tab.js create mode 100755 app/assets/javascripts/bootstrap.viewer.js create mode 100644 app/assets/stylesheets/admins/identity-authentications.scss create mode 100644 app/assets/stylesheets/admins/professional-authentications.scss create mode 100644 app/controllers/admins/identity_authentications_controller.rb create mode 100644 app/controllers/admins/professional_authentications_controller.rb create mode 100644 app/helpers/admins/base_helper.rb create mode 100644 app/libs/util/file_manage.rb create mode 100644 app/queries/admins/apply_user_authentication_query.rb create mode 100644 app/services/admins/identity_auths/agree_apply_service.rb create mode 100644 app/services/admins/identity_auths/refuse_apply_service.rb create mode 100644 app/services/admins/professional_auths/agree_apply_service.rb create mode 100644 app/services/admins/professional_auths/refuse_apply_service.rb create mode 100644 app/views/admins/identity_authentications/index.html.erb create mode 100644 app/views/admins/identity_authentications/index.js.erb create mode 100644 app/views/admins/identity_authentications/shared/_list.html.erb create mode 100644 app/views/admins/professional_authentications/index.html.erb create mode 100644 app/views/admins/professional_authentications/index.js.erb create mode 100644 app/views/admins/professional_authentications/shared/_list.html.erb create mode 100644 app/views/admins/shared/_admin_common_refuse_modal.html.erb create mode 100644 config/locales/apply_user_authentications/zh-CN.yml diff --git a/app/assets/javascripts/admin.js b/app/assets/javascripts/admin.js index 27844be53..72a2ff118 100644 --- a/app/assets/javascripts/admin.js +++ b/app/assets/javascripts/admin.js @@ -11,6 +11,7 @@ //= require select2 //= require jquery.cxselect //= require bootstrap-datepicker +//= require bootstrap.viewer //= require_tree ./i18n //= require_tree ./admins @@ -25,6 +26,9 @@ $(document).on('turbolinks:load', function(){ $('[data-toggle="tooltip"]').tooltip(); $('[data-toggle="popover"]').popover(); + // 图片查看大图 + $('img.preview-image').bootstrapViewer(); + // flash alert提示框自动关闭 if($('.admin-alert-container .alert').length > 0){ setTimeout(function(){ @@ -33,10 +37,25 @@ $(document).on('turbolinks:load', function(){ } }); -$(document).on("turbolinks:before-cache", function () { - $('[data-toggle="tooltip"]').tooltip('hide'); - $('[data-toggle="popover"]').popover('hide'); -}); +// var progressBar = new Turbolinks.ProgressBar(); + +// $(document).on('ajax:send', function(event){ +// console.log('ajax send', event); +// progressBar.setValue(0) +// progressBar.show() +// }); +// +// $(document).on('ajax:complete', function(event){ +// console.log('ajax complete', event); +// progressBar.setValue(1) +// progressBar.hide() // 分页时不触发,奇怪 +// }); +// $(document).on('ajax:success', function(event){ +// console.log('ajax success', event); +// }); +// $(document).on('ajax:error', function(event){ +// console.log('ajax error', event); +// }); $(function () { }); \ No newline at end of file diff --git a/app/assets/javascripts/admins/common-refuse-modal.js b/app/assets/javascripts/admins/common-refuse-modal.js new file mode 100644 index 000000000..5eb2f3f46 --- /dev/null +++ b/app/assets/javascripts/admins/common-refuse-modal.js @@ -0,0 +1,54 @@ +$(document).on('turbolinks:load', function() { + var $refuseModal = $('.admin-common-refuse-modal'); + if ($refuseModal.length > 0) { + var $form = $refuseModal.find('form.admin-common-refuse-form'); + var $applyIdInput = $refuseModal.find('.modal-body input[name="apply_id"]'); + + $form.validate({ + errorElement: 'span', + errorClass: 'danger text-danger', + rules: { + reason: { + required: true, + maxlength: 200 + }, + } + }); + + // modal ready fire + $refuseModal.on('show.bs.modal', function (event) { + var $link = $(event.relatedTarget); + + var applyId = $link.data('id'); + var url = $link.data('url'); + + $applyIdInput.val(applyId); + $form.data('url', url); + }); + // modal visited fire + $refuseModal.on('shown.bs.modal', function(){ + $refuseModal.find('.modal-body input[name="reason"]').focus(); + }); + $refuseModal.on('hide.bs.modal', function () { + $applyIdInput.val(''); + $form.data('url', ''); + }) + + $refuseModal.on('click', '.submit-btn', function(){ + $form.find('.error').html(''); + + if ($form.valid()) { + var url = $form.data('url'); + + $.ajax({ + method: 'POST', + dataType: 'script', + url: url, + data: $form.serialize(), + }).done(function(){ + $refuseModal.modal('hide'); + }); + } + }); + } +}); \ No newline at end of file diff --git a/app/assets/javascripts/admins/identity_authentications/index.js b/app/assets/javascripts/admins/identity_authentications/index.js new file mode 100644 index 000000000..2da644ec2 --- /dev/null +++ b/app/assets/javascripts/admins/identity_authentications/index.js @@ -0,0 +1,18 @@ +$(document).on('turbolinks:load', function() { + if ($('body.admins-identity-authentications-index-page').length > 0) { + var $searchFrom = $('.identity-authentication-list-form'); + + $searchFrom.on('click', '.search-form-tab', function(){ + var $link = $(this); + + $searchFrom.find('input[name="keyword"]').val(''); + $searchFrom.find('select[name="status"]').val('processed'); + + if($link.data('value') === 'processed'){ + $searchFrom.find('.status-filter').show(); + } else { + $searchFrom.find('.status-filter').hide(); + } + }); + } +}) \ No newline at end of file diff --git a/app/assets/javascripts/admins/professional_authentications/index.js b/app/assets/javascripts/admins/professional_authentications/index.js new file mode 100644 index 000000000..769a6b2fc --- /dev/null +++ b/app/assets/javascripts/admins/professional_authentications/index.js @@ -0,0 +1,18 @@ +$(document).on('turbolinks:load', function() { + if ($('body.admins-professional-authentications-index-page').length > 0) { + var $searchFrom = $('.professional-authentication-list-form'); + + $searchFrom.on('click', '.search-form-tab', function(){ + var $link = $(this); + + $searchFrom.find('input[name="keyword"]').val(''); + $searchFrom.find('select[name="status"]').val('processed'); + + if($link.data('value') === 'processed'){ + $searchFrom.find('.status-filter').show(); + } else { + $searchFrom.find('.status-filter').hide(); + } + }); + } +}) \ No newline at end of file diff --git a/app/assets/javascripts/admins/search-form-tab.js b/app/assets/javascripts/admins/search-form-tab.js new file mode 100644 index 000000000..6009412d5 --- /dev/null +++ b/app/assets/javascripts/admins/search-form-tab.js @@ -0,0 +1,10 @@ +$(document).on('turbolinks:load', function() { + var $tabs = $('.search-form-container .search-form-tabs'); + if ($tabs.length > 0) { + $tabs.on('click', '.search-form-tab', function(){ + var $activeTab = $(this); + $tabs.find('.search-form-tab').removeClass('active'); + $activeTab.addClass('active'); + }); + } +}); \ No newline at end of file diff --git a/app/assets/javascripts/bootstrap.viewer.js b/app/assets/javascripts/bootstrap.viewer.js new file mode 100755 index 000000000..4c6aa549a --- /dev/null +++ b/app/assets/javascripts/bootstrap.viewer.js @@ -0,0 +1,50 @@ +/* + * Copyright 2018-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * WebSite: http://bootstrap-viewer.leftso.com + */ +$.fn.bootstrapViewer = function (options) { + $(this).on('click', function () { + var opts = $.extend({}, $.fn.bootstrapViewer.defaults, options); + var viewer = $(''); + $('body').append(viewer); + if ($(this).attr(opts.src)) { + $("#bootstrapViewer").find(".img-viewer").attr("src", $(this).attr(opts.src)); + $("#bootstrapViewer").modal(); + } else { + throw "图片不存在" + } + + }) + + $(this).on('mouseover', function () { + $(this).css('cursor', 'zoom-in'); + }) + +} +$.fn.bootstrapViewer.defaults = { + src: 'src' +} \ No newline at end of file diff --git a/app/assets/stylesheets/admin.scss b/app/assets/stylesheets/admin.scss index 33d585d83..0aa1329ca 100644 --- a/app/assets/stylesheets/admin.scss +++ b/app/assets/stylesheets/admin.scss @@ -25,7 +25,7 @@ a { } } -input.danger { +textarea.danger, input.danger { border-color: #dc3545!important; } @@ -43,4 +43,8 @@ label.error { height: calc(1.5em + 0.75rem + 2px) } } +} + +.flex-1 { + flex: 1; } \ No newline at end of file diff --git a/app/assets/stylesheets/admins/common.scss b/app/assets/stylesheets/admins/common.scss index 9830df3c7..2254166fd 100644 --- a/app/assets/stylesheets/admins/common.scss +++ b/app/assets/stylesheets/admins/common.scss @@ -100,5 +100,11 @@ font-size: 24px; } } + + .nav-tabs { + .nav-link { + padding: 0.5rem 2rem; + } + } } diff --git a/app/assets/stylesheets/admins/identity-authentications.scss b/app/assets/stylesheets/admins/identity-authentications.scss new file mode 100644 index 000000000..417581058 --- /dev/null +++ b/app/assets/stylesheets/admins/identity-authentications.scss @@ -0,0 +1,9 @@ +.admins-identity-authentications-index-page { + .identity-authentication-list-container { + span { + &.apply-status-1 { color: #28a745; } + &.apply-status-2 { color: #dc3545; } + &.apply-status-3 { color: #6c757d; } + } + } +} \ No newline at end of file diff --git a/app/assets/stylesheets/admins/professional-authentications.scss b/app/assets/stylesheets/admins/professional-authentications.scss new file mode 100644 index 000000000..6ef78f92d --- /dev/null +++ b/app/assets/stylesheets/admins/professional-authentications.scss @@ -0,0 +1,9 @@ +.admins-professional-authentications-index-page { + .professional-authentication-list-container { + span { + &.apply-status-1 { color: #28a745; } + &.apply-status-2 { color: #dc3545; } + &.apply-status-3 { color: #6c757d; } + } + } +} \ No newline at end of file diff --git a/app/controllers/admins/identity_authentications_controller.rb b/app/controllers/admins/identity_authentications_controller.rb new file mode 100644 index 000000000..90758ace8 --- /dev/null +++ b/app/controllers/admins/identity_authentications_controller.rb @@ -0,0 +1,26 @@ +class Admins::IdentityAuthenticationsController < Admins::BaseController + def index + params[:status] ||= 'pending' + + applies = Admins::ApplyUserAuthenticationQuery.call(params.merge(type: 1)) + + @applies = paginate applies.preload(user: { user_extension: [:school, :department] }) + end + + def agree + Admins::IdentityAuths::AgreeApplyService.call(current_apply) + render_success_js + end + + def refuse + Admins::IdentityAuths::RefuseApplyService.call(current_apply, params) + + render_success_js + end + + private + + def current_apply + @_current_apply ||= ApplyUserAuthentication.real_name_auth.find(params[:id]) + end +end \ No newline at end of file diff --git a/app/controllers/admins/professional_authentications_controller.rb b/app/controllers/admins/professional_authentications_controller.rb new file mode 100644 index 000000000..327ee696c --- /dev/null +++ b/app/controllers/admins/professional_authentications_controller.rb @@ -0,0 +1,26 @@ +class Admins::ProfessionalAuthenticationsController < Admins::BaseController + def index + params[:status] ||= 'pending' + + applies = Admins::ApplyUserAuthenticationQuery.call(params.merge(type: 2)) + + @applies = paginate applies.preload(user: { user_extension: [:school, :department] }) + end + + def agree + Admins::ProfessionalAuths::AgreeApplyService.call(current_apply) + render_success_js + end + + def refuse + Admins::ProfessionalAuths::RefuseApplyService.call(current_apply, params) + + render_success_js + end + + private + + def current_apply + @_current_apply ||= ApplyUserAuthentication.professional_auth.find(params[:id]) + end +end \ No newline at end of file diff --git a/app/controllers/concerns/admins/render_helper.rb b/app/controllers/concerns/admins/render_helper.rb index c77c0ad32..3651f892b 100644 --- a/app/controllers/concerns/admins/render_helper.rb +++ b/app/controllers/concerns/admins/render_helper.rb @@ -40,6 +40,7 @@ module Admins::RenderHelper def render_delete_success render_js_template 'admins/shared/delete' end + alias_method :render_success_js, :render_delete_success def render_js_error(message) render_js_template 'admins/shared/error', locals: { message: message } diff --git a/app/helpers/admins/base_helper.rb b/app/helpers/admins/base_helper.rb new file mode 100644 index 000000000..c655be2e7 --- /dev/null +++ b/app/helpers/admins/base_helper.rb @@ -0,0 +1,102 @@ +module Admins::BaseHelper + def sidebar_item_group(url, text, **opts) + link_opts = url.start_with?('/') ? {} : { 'data-toggle': 'collapse', 'aria-expanded': false } + content = + link_to url, link_opts do + content_tag(:i, '', class: "fa fa-#{opts[:icon]}", 'data-toggle': 'tooltip', 'data-placement': 'right', 'data-boundary': 'window', title: text) + + content_tag(:span, text) + end + + content += + content_tag(:ul, id: url[1..-1], class: 'collapse list-unstyled', "data-parent": '#sidebar') do + yield + end + + raw content + end + + def sidebar_item(url, text, **opts) + content = + link_to url, 'data-controller': opts[:controller] do + content_tag(:i, '', class: "fa fa-#{opts[:icon]}", 'data-toggle': 'tooltip', 'data-placement': 'right', 'data-boundary': 'window', title: text) + + content_tag(:span, text) + end + + raw content + end + + def admin_sidebar_controller + key = params[:controller].to_s.gsub(/\//, '-') + SidebarUtil.controller_name(key) || key + end + + def define_admin_breadcrumbs(&block) + content_for(:setup_admin_breadcrumb, &block) + end + + def add_admin_breadcrumb(text, url = nil) + @_admin_breadcrumbs ||= [] + @_admin_breadcrumbs << OpenStruct.new(text: text, url: url) + end + + def display_text(str, default = '--') + str.presence || default + end + + def overflow_hidden_span(text, width: 300) + opts = { class: 'd-inline-block text-truncate', style: "max-width: #{width}px" } + opts.merge!('data-toggle': 'tooltip', title: text) if text != '--' + + content_tag(:span, text, opts) + end + + def sort_tag(content = '', **opts) + options = {} + options[:sort_by] = opts.delete(:name) + is_current_sort = params[:sort_by].to_s == options[:sort_by] + options[:sort_direction] = is_current_sort && params[:sort_direction].to_s == 'desc' ? 'asc' : 'desc' + + path = opts.delete(:path) + "?" + unsafe_params.merge(options).to_query + arrow_class = case params[:sort_direction].to_s + when 'desc' then 'fa-sort-amount-desc' + when 'asc' then 'fa-sort-amount-asc' + else '' + end + opts[:style] = "#{opts[:style]} ;position: relative;" + + content_tag(:span, opts) do + link_to path, remote: true do + content = content_tag(:span) { yield } if block_given? + + content += content_tag(:i, '', class: "fa color-light-green ml-1 #{arrow_class}", style: 'position: absolute;top:0;') if is_current_sort + raw content + end + end + end + + def javascript_void_link(name, **opts) + raw link_to(name, 'javascript:void(0)', opts) + end + + def agree_link(name, url, **opts) + klass = ['action agree-action', opts.delete(:class)].compact.join(' ') + + refresh_url_data = "refresh_url=#{CGI::escape(request.fullpath)}" + url = url + (url.index('?') ? '&' : '?') + refresh_url_data + + raw link_to(name, url, { method: :post, remote: true, class: klass, 'data-confirm': '确认审核通过?'}.merge(opts)) + end + + def delete_link(name, url, **opts) + klass = ['action delete-action', opts.delete(:class)].compact.join(' ') + + refresh_url_data = "refresh_url=#{CGI::escape(request.fullpath)}" + url = url + (url.index('?') ? '&' : '?') + refresh_url_data + + raw link_to(name, url, { method: :delete, remote: true, class: klass, 'data-confirm': '确认删除?'}.merge(opts)) + end + + def unsafe_params + params.except(:controller, :action).to_unsafe_h + end +end \ No newline at end of file diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 0f536433d..44169dc59 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -158,10 +158,22 @@ module ApplicationHelper disk_auth_filename('UserAuthentication', source_id, 'ID') end + def auth_file_url(source_type, source_id, type) + File.join('/images', relative_path, source_type, "#{source_id}#{type}") + end + + def real_name_auth_file_url(source_id) + auth_file_url('UserAuthentication', source_id, 'ID') + end + def disk_professional_auth_filename(source_id) disk_auth_filename('UserAuthentication', source_id, 'PRO') end + def professional_auth_file_url(source_id) + auth_file_url('UserAuthentication', source_id, 'PRO') + end + def shixun_url_to_avatar(shixun) if File.exist?(disk_filename(shixun.class, shixun.id)) File.join("images/#{relative_path}", "#{shixun.class}", "#{shixun.id}") @@ -386,95 +398,6 @@ module ApplicationHelper m_t&.include?("src=\"") ? m_t&.gsub("src=\"","src=\"#{origin_url}") : m_t end - # =========== Admin Helpers Begin =========== - def sidebar_item_group(url, text, **opts) - link_opts = url.start_with?('/') ? {} : { 'data-toggle': 'collapse', 'aria-expanded': false } - content = - link_to url, link_opts do - content_tag(:i, '', class: "fa fa-#{opts[:icon]}", 'data-toggle': 'tooltip', 'data-placement': 'right', 'data-boundary': 'window', title: text) + - content_tag(:span, text) - end - - content += - content_tag(:ul, id: url[1..-1], class: 'collapse list-unstyled', "data-parent": '#sidebar') do - yield - end - - raw content - end - - def sidebar_item(url, text, **opts) - content = - link_to url, 'data-controller': opts[:controller] do - content_tag(:i, '', class: "fa fa-#{opts[:icon]}", 'data-toggle': 'tooltip', 'data-placement': 'right', 'data-boundary': 'window', title: text) + - content_tag(:span, text) - end - - raw content - end - - def admin_sidebar_controller - key = params[:controller].to_s.gsub(/\//, '-') - SidebarUtil.controller_name(key) || key - end - - def define_admin_breadcrumbs(&block) - content_for(:setup_admin_breadcrumb, &block) - end - - def add_admin_breadcrumb(text, url = nil) - @_admin_breadcrumbs ||= [] - @_admin_breadcrumbs << OpenStruct.new(text: text, url: url) - end - - def display_text(str, default = '--') - str.presence || default - end - - def overflow_hidden_span(text, width: 300) - opts = { class: 'd-inline-block text-truncate', style: "max-width: #{width}px" } - opts.merge!('data-toggle': 'tooltip', title: text) if text != '--' - - content_tag(:span, text, opts) - end - - def sort_tag(content = '', **opts) - options = {} - options[:sort_by] = opts.delete(:name) - is_current_sort = params[:sort_by].to_s == options[:sort_by] - options[:sort_direction] = is_current_sort && params[:sort_direction].to_s == 'desc' ? 'asc' : 'desc' - - path = opts.delete(:path) + "?" + params.slice(:action, :controller).merge(options).to_unsafe_h.to_query - arrow_class = case params[:sort_direction].to_s - when 'desc' then 'fa-sort-amount-desc' - when 'asc' then 'fa-sort-amount-asc' - else '' - end - opts[:style] = "#{opts[:style]} ;position: relative;" - - content_tag(:span, opts) do - link_to path, remote: true do - content = content_tag(:span) { yield } if block_given? - - content += content_tag(:i, '', class: "fa color-light-green ml-1 #{arrow_class}", style: 'position: absolute;top:0;') if is_current_sort - raw content - end - end - end - - def javascript_void_link(name, **opts) - raw link_to(name, 'javascript:void(0)', opts) - end - - def delete_link(name, url, **opts) - klass = ['action delete-action', opts.delete(:class)].compact.join(' ') - - refresh_url_data = "refresh_url=#{CGI::escape(request.fullpath)}" - url = url + (url.index('?') ? '&' : '?') + refresh_url_data - - raw link_to(name, url, { method: :delete, remote: true, class: klass, 'data-confirm': '确认删除?'}.merge(opts)) - end - # =========== Admin Helpers End =========== end diff --git a/app/libs/util/file_manage.rb b/app/libs/util/file_manage.rb new file mode 100644 index 000000000..620fd7f01 --- /dev/null +++ b/app/libs/util/file_manage.rb @@ -0,0 +1,40 @@ +module Util::FileManage + module_function + + # 不同的类型扩展不同的目录 + def relative_path + "avatars" + end + + def storage_path + File.join(Rails.root, "public", "images", relative_path) + end + + def disk_filename(source_type,source_id,image_file=nil) + File.join(storage_path, "#{source_type}", "#{source_id}") + end + + def disk_auth_filename(source_type, source_id, type) + File.join(storage_path, "#{source_type}", "#{source_id}#{type}") + end + + def disk_real_name_auth_filename(source_id) + disk_auth_filename('UserAuthentication', source_id, 'ID') + end + + def auth_file_url(source_type, source_id, type) + File.join('/images', relative_path, source_type, "#{source_id}#{type}") + end + + def real_name_auth_file_url(source_id) + auth_file_url('UserAuthentication', source_id, 'ID') + end + + def disk_professional_auth_filename(source_id) + disk_auth_filename('UserAuthentication', source_id, 'PRO') + end + + def professional_auth_file_url(source_id) + auth_file_url('UserAuthentication', source_id, 'PRO') + end +end \ No newline at end of file diff --git a/app/models/apply_user_authentication.rb b/app/models/apply_user_authentication.rb index d467eb850..c379fb82e 100644 --- a/app/models/apply_user_authentication.rb +++ b/app/models/apply_user_authentication.rb @@ -12,6 +12,12 @@ class ApplyUserAuthentication < ApplicationRecord after_create :send_tiding + def status_text + I18n.t!("apply_user_authentication.status.#{status}") + rescue I18n::MissingTranslationData + nil + end + private def send_tiding diff --git a/app/queries/admins/apply_user_authentication_query.rb b/app/queries/admins/apply_user_authentication_query.rb new file mode 100644 index 000000000..a4d1c2a4a --- /dev/null +++ b/app/queries/admins/apply_user_authentication_query.rb @@ -0,0 +1,34 @@ +class Admins::ApplyUserAuthenticationQuery < ApplicationQuery + include CustomSortable + + attr_reader :params + + sort_columns :updated_at, default_by: :updated_at, default_direction: :desc + + def initialize(params) + @params = params + end + + def call + applies = ApplyUserAuthentication.where(auth_type: params[:type].presence || 1) + + status = + case params[:status] + when 'pending' then 0 + when 'processed' then [1, 2] + when 'agreed' then 1 + when 'refused' then 2 + else 0 + end + applies = applies.where(status: status) if status.present? + + # 关键字模糊查询 + keyword = params[:keyword].to_s.strip + if keyword.present? + applies = applies.joins(user: { user_extension: :school }) + .where('CONCAT(lastname,firstname) LIKE :keyword OR schools.name LIKE :keyword', keyword: "%#{keyword}%") + end + + custom_sort(applies, params[:sort_by], params[:sort_direction]) + end +end \ No newline at end of file diff --git a/app/services/admins/identity_auths/agree_apply_service.rb b/app/services/admins/identity_auths/agree_apply_service.rb new file mode 100644 index 000000000..65a3b2376 --- /dev/null +++ b/app/services/admins/identity_auths/agree_apply_service.rb @@ -0,0 +1,38 @@ +class Admins::IdentityAuths::AgreeApplyService < ApplicationService + attr_reader :apply, :user + + def initialize(apply) + @apply = apply + @user = apply.user + end + + def call + ActiveRecord::Base.transaction do + apply.update!(status: 1) + user.update!(authentication: true) + + RewardGradeService.call(user, container_id: user.id, container_type: 'Authentication', score: 500) + + deal_tiding! + delete_auth_file! + end + end + + private + + def deal_tiding! + apply.tidings.where(tiding_type: 'Apply').update_all(status: 1) + + Tiding.create!(user_id: apply.user_id, trigger_user_id: 0, + container_id: apply.id, container_type: 'ApplyUserAuthentication', + belong_container_id: apply.user_id, belong_container_type: 'User', + status: 1, tiding_type: 'System') + end + + def delete_auth_file! + path = Util::FileManage.disk_real_name_auth_filename(user.id) + File.delete(path) if File.exists?(path) + + apply.update!(is_delete: true) + end +end \ No newline at end of file diff --git a/app/services/admins/identity_auths/refuse_apply_service.rb b/app/services/admins/identity_auths/refuse_apply_service.rb new file mode 100644 index 000000000..57581dd40 --- /dev/null +++ b/app/services/admins/identity_auths/refuse_apply_service.rb @@ -0,0 +1,40 @@ +class Admins::IdentityAuths::RefuseApplyService < ApplicationService + attr_reader :apply, :user, :params + + def initialize(apply, params) + @apply = apply + @user = apply.user + @params = params + end + + def call + ActiveRecord::Base.transaction do + apply.update!(status: 2, remarks: reason) + + deal_tiding! + delete_auth_file! + end + end + + private + + def reason + params[:reason].to_s.strip + end + + def deal_tiding! + apply.tidings.where(tiding_type: 'Apply').update_all(status: 1) + + Tiding.create!(user_id: apply.user_id, trigger_user_id: 0, + container_id: apply.id, container_type: 'ApplyUserAuthentication', + belong_container_id: apply.user_id, belong_container_type: 'User', + status: 2, tiding_type: 'System') + end + + def delete_auth_file! + path = Util::FileManage.disk_real_name_auth_filename(user.id) + File.delete(path) if File.exists?(path) + + apply.update!(is_delete: true) + end +end \ No newline at end of file diff --git a/app/services/admins/professional_auths/agree_apply_service.rb b/app/services/admins/professional_auths/agree_apply_service.rb new file mode 100644 index 000000000..81654f0d3 --- /dev/null +++ b/app/services/admins/professional_auths/agree_apply_service.rb @@ -0,0 +1,38 @@ +class Admins::ProfessionalAuths::AgreeApplyService < ApplicationService + attr_reader :apply, :user + + def initialize(apply) + @apply = apply + @user = apply.user + end + + def call + ActiveRecord::Base.transaction do + apply.update!(status: 1) + user.update!(professional_certification: true) + + RewardGradeService.call(user, container_id: user.id, container_type: 'Professional', score: 500) + + deal_tiding! + delete_auth_file! + end + end + + private + + def deal_tiding! + apply.tidings.where(tiding_type: 'Apply').update_all(status: 1) + + Tiding.create!(user_id: apply.user_id, trigger_user_id: 0, + container_id: apply.id, container_type: 'ApplyUserAuthentication', + belong_container_id: apply.user_id, belong_container_type: 'User', + status: 1, tiding_type: 'System') + end + + def delete_auth_file! + path = Util::FileManage.disk_professional_auth_filename(user.id) + File.delete(path) if File.exists?(path) + + apply.update!(is_delete: true) + end +end \ No newline at end of file diff --git a/app/services/admins/professional_auths/refuse_apply_service.rb b/app/services/admins/professional_auths/refuse_apply_service.rb new file mode 100644 index 000000000..b5332c999 --- /dev/null +++ b/app/services/admins/professional_auths/refuse_apply_service.rb @@ -0,0 +1,40 @@ +class Admins::ProfessionalAuths::RefuseApplyService < ApplicationService + attr_reader :apply, :user, :params + + def initialize(apply, params) + @apply = apply + @user = apply.user + @params = params + end + + def call + ActiveRecord::Base.transaction do + apply.update!(status: 2, remarks: reason) + + deal_tiding! + delete_auth_file! + end + end + + private + + def reason + params[:reason].to_s.strip + end + + def deal_tiding! + apply.tidings.where(tiding_type: 'Apply').update_all(status: 1) + + Tiding.create!(user_id: apply.user_id, trigger_user_id: 0, + container_id: apply.id, container_type: 'ApplyUserAuthentication', + belong_container_id: apply.user_id, belong_container_type: 'User', + status: 2, tiding_type: 'System') + end + + def delete_auth_file! + path = Util::FileManage.disk_professional_auth_filename(user.id) + File.delete(path) if File.exists?(path) + + apply.update!(is_delete: true) + end +end \ No newline at end of file diff --git a/app/views/admins/identity_authentications/index.html.erb b/app/views/admins/identity_authentications/index.html.erb new file mode 100644 index 000000000..170a8fc4a --- /dev/null +++ b/app/views/admins/identity_authentications/index.html.erb @@ -0,0 +1,32 @@ +<% define_admin_breadcrumbs do %> + <% add_admin_breadcrumb('实名认证') %> +<% end %> + +
+ + + <%= form_tag(admins_identity_authentications_path(unsafe_params), method: :get, class: 'form-inline search-form justify-content-end mt-3', remote: true) do %> +
+ + <% status_options = [['全部', 'processed'], ['已同意', 'agreed'], ['已拒绝', 'refused']] %> + <%= select_tag(:status, options_for_select(status_options), class: 'form-control') %> +
+ <%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-sm-2 ml-3', placeholder: '姓名/学校/单位检索') %> + <%= submit_tag('搜索', class: 'btn btn-primary ml-3') %> + <% end %> +
+ +
+ <%= render(partial: 'admins/identity_authentications/shared/list', locals: { applies: @applies }) %> +
+ +<%= render(partial: 'admins/shared/admin_common_refuse_modal') %> \ No newline at end of file diff --git a/app/views/admins/identity_authentications/index.js.erb b/app/views/admins/identity_authentications/index.js.erb new file mode 100644 index 000000000..81d108b0d --- /dev/null +++ b/app/views/admins/identity_authentications/index.js.erb @@ -0,0 +1 @@ +$('.identity-authentication-list-container').html("<%= j( render partial: 'admins/identity_authentications/shared/list', locals: { applies: @applies } ) %>"); \ No newline at end of file diff --git a/app/views/admins/identity_authentications/shared/_list.html.erb b/app/views/admins/identity_authentications/shared/_list.html.erb new file mode 100644 index 000000000..1cd849e72 --- /dev/null +++ b/app/views/admins/identity_authentications/shared/_list.html.erb @@ -0,0 +1,74 @@ +<% is_processed = params[:status].to_s != 'pending' %> + + + + + + + + + + <% unless is_processed %> + + <% end %> + + <% if is_processed %> + + + <% else %> + + <% end %> + + + + <% if applies.present? %> + <% applies.each do |apply| %> + <% user = apply.user %> + + + + + + + + <% unless is_processed %> + + <% end %> + + + + <% if is_processed %> + + + <% else %> + + <% end %> + + <% end %> + <% else %> + <%= render 'admins/shared/no_data_for_table' %> + <% end %> + +
头像姓名身份证号学校/单位职称 + 照片 + + 时间拒绝原因状态操作
+ <%= link_to "/users/#{user.login}", class: 'identity-authentication-avatar', target: '_blank', data: { toggle: 'tooltip', title: '个人主页' } do %> + + <% end %> + <%= user.real_name %><%= user.ID_number %><%= raw [user.school_name.presence, user.department_name.presence].compact.join('
') %>
<%= user.identity %> <%= raw user.user_extension.student? && user.student_id ? "
#{user.student_id}" : '' %>
+ <% if File.exists?(disk_real_name_auth_filename(user.id)) %> + <%= image_tag(real_name_auth_file_url(user.id).to_s + "?#{Time.now.to_i}", width: 40, height: 40, class: 'preview-image auth-image', data: { toggle: 'tooltip', title: '点击预览' }) %> + <% else %> + <%= content_tag(:span, '图片已删除', class: 'text-secondary') %> + <% end %> + <%= apply.updated_at.strftime('%Y-%m-%d %H:%M') %><%= overflow_hidden_span apply.remarks, width: 140 %><%= apply.status_text %> + <%= agree_link '同意', agree_admins_identity_authentication_path(apply, element: ".identity-authentication-#{user.id}"), 'data-confirm': '确认审核通过?' %> + <%= javascript_void_link('拒绝', class: 'action refuse-action', + data: { + toggle: 'modal', target: '.admin-common-refuse-modal', id: apply.id, + url: refuse_admins_identity_authentication_path(apply, element: ".identity-authentication-#{user.id}") + }) %> +
+ +<%= render partial: 'admins/shared/paginate', locals: { objects: applies } %> \ No newline at end of file diff --git a/app/views/admins/professional_authentications/index.html.erb b/app/views/admins/professional_authentications/index.html.erb new file mode 100644 index 000000000..e10d2bd80 --- /dev/null +++ b/app/views/admins/professional_authentications/index.html.erb @@ -0,0 +1,32 @@ +<% define_admin_breadcrumbs do %> + <% add_admin_breadcrumb('职业认证') %> +<% end %> + +
+ + + <%= form_tag(admins_professional_authentications_path(unsafe_params), method: :get, class: 'form-inline search-form justify-content-end mt-3', remote: true) do %> +
+ + <% status_options = [['全部', 'processed'], ['已同意', 'agreed'], ['已拒绝', 'refused']] %> + <%= select_tag(:status, options_for_select(status_options), class: 'form-control') %> +
+ <%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-sm-2 ml-3', placeholder: '姓名/学校/单位检索') %> + <%= submit_tag('搜索', class: 'btn btn-primary ml-3') %> + <% end %> +
+ +
+ <%= render(partial: 'admins/professional_authentications/shared/list', locals: { applies: @applies }) %> +
+ +<%= render(partial: 'admins/shared/admin_common_refuse_modal') %> \ No newline at end of file diff --git a/app/views/admins/professional_authentications/index.js.erb b/app/views/admins/professional_authentications/index.js.erb new file mode 100644 index 000000000..468c131d6 --- /dev/null +++ b/app/views/admins/professional_authentications/index.js.erb @@ -0,0 +1 @@ +$('.professional-authentication-list-container').html("<%= j( render partial: 'admins/professional_authentications/shared/list', locals: { applies: @applies } ) %>"); \ No newline at end of file diff --git a/app/views/admins/professional_authentications/shared/_list.html.erb b/app/views/admins/professional_authentications/shared/_list.html.erb new file mode 100644 index 000000000..acd62eae5 --- /dev/null +++ b/app/views/admins/professional_authentications/shared/_list.html.erb @@ -0,0 +1,72 @@ +<% is_processed = params[:status].to_s != 'pending' %> + + + + + + + + + <% unless is_processed %> + + <% end %> + + <% if is_processed %> + + + <% else %> + + <% end %> + + + + <% if applies.present? %> + <% applies.each do |apply| %> + <% user = apply.user %> + + + + + + + <% unless is_processed %> + + <% end %> + + + + <% if is_processed %> + + + <% else %> + + <% end %> + + <% end %> + <% else %> + <%= render 'admins/shared/no_data_for_table' %> + <% end %> + +
头像姓名学校/单位职称 + 照片 + + 时间拒绝原因状态操作
+ <%= link_to "/users/#{user.login}", class: 'professional-authentication-avatar', target: '_blank', data: { toggle: 'tooltip', title: '个人主页' } do %> + + <% end %> + <%= user.real_name %><%= raw [user.school_name.presence, user.department_name.presence].compact.join('
') %>
<%= user.identity %> <%= raw user.user_extension.student? && user.student_id ? "
#{user.student_id}" : '' %>
+ <% if File.exists?(disk_professional_auth_filename(user.id)) %> + <%= image_tag(professional_auth_file_url(user.id).to_s + "?#{Time.now.to_i}", width: 40, height: 40, class: 'preview-image auth-image', data: { toggle: 'tooltip', title: '点击预览' }) %> + <% else %> + <%= content_tag(:span, '图片已删除', class: 'text-secondary') %> + <% end %> + <%= apply.updated_at.strftime('%Y-%m-%d %H:%M') %><%= overflow_hidden_span apply.remarks, width: 140 %><%= apply.status_text %> + <%= agree_link '同意', agree_admins_professional_authentication_path(apply, element: ".professional-authentication-#{user.id}"), 'data-confirm': '确认审核通过?' %> + <%= javascript_void_link('拒绝', class: 'action refuse-action', + data: { + toggle: 'modal', target: '.admin-common-refuse-modal', id: apply.id, + url: refuse_admins_professional_authentication_path(apply, element: ".professional-authentication-#{user.id}") + }) %> +
+ +<%= render partial: 'admins/shared/paginate', locals: { objects: applies } %> \ No newline at end of file diff --git a/app/views/admins/school_statistics/index.html.erb b/app/views/admins/school_statistics/index.html.erb index fd0c7cac1..0453dfffa 100644 --- a/app/views/admins/school_statistics/index.html.erb +++ b/app/views/admins/school_statistics/index.html.erb @@ -32,9 +32,9 @@
<%= hidden_field_tag :data_type, params[:data_type] || 'grow' %> - <%= javascript_void_link '时段对比', class: "btn btn-outline-primary btn-sm contrast-btn #{params[:data_type] == 'contrast' ? 'active' : ''}", + <%= javascript_void_link '时段对比', class: "btn btn-outline-info btn-sm contrast-btn #{params[:data_type] == 'contrast' ? 'active' : ''}", data: { toggle: 'tooltip', trigger: 'hover', title: '请在左侧分别选择需进行对比的两个时段,具体从当日5:00开始计算,下表显示两时段选定指标两时段变化情况对比' } %> - <%= javascript_void_link '数据变化', class: "btn btn-outline-primary btn-sm grow-btn #{params[:data_type] == 'contrast' ? '' : 'active'}", + <%= javascript_void_link '数据变化', class: "btn btn-outline-info btn-sm grow-btn #{params[:data_type] == 'contrast' ? '' : 'active'}", data: { toggle: 'tooltip', trigger: 'hover', title: '请在左侧选择时间段,具体从当日5:00开始计算,下表显示选定时间段内各项指标数据变化情况' } %>
diff --git a/app/views/admins/shared/_admin_common_refuse_modal.html.erb b/app/views/admins/shared/_admin_common_refuse_modal.html.erb new file mode 100644 index 000000000..a2daf7f0c --- /dev/null +++ b/app/views/admins/shared/_admin_common_refuse_modal.html.erb @@ -0,0 +1,26 @@ + \ No newline at end of file diff --git a/app/views/admins/shared/_sidebar.html.erb b/app/views/admins/shared/_sidebar.html.erb index cd64f3d0f..2be899ebd 100644 --- a/app/views/admins/shared/_sidebar.html.erb +++ b/app/views/admins/shared/_sidebar.html.erb @@ -37,6 +37,13 @@ <% end %> +
  • + <%= sidebar_item_group('#apply-review-submenu', '审核', icon: 'gavel') do %> +
  • <%= sidebar_item(admins_identity_authentications_path, '实名认证', icon: 'id-card-o', controller: 'admins-identity_authentications') %>
  • +
  • <%= sidebar_item(admins_professional_authentications_path, '职业认证', icon: 'drivers-license', controller: 'admins-professional_authentications') %>
  • + <% end %> + +
  • <%= sidebar_item('/', '返回主站', icon: 'sign-out', controller: 'root') %>
  • \ No newline at end of file diff --git a/app/views/admins/shared/after_render_js_hook.js.erb b/app/views/admins/shared/after_render_js_hook.js.erb index 9ceb13f5c..efc1e9295 100644 --- a/app/views/admins/shared/after_render_js_hook.js.erb +++ b/app/views/admins/shared/after_render_js_hook.js.erb @@ -1,3 +1,4 @@ ; $('[data-toggle="tooltip"]').tooltip(); -$('[data-toggle="popover"]').popover(); \ No newline at end of file +$('[data-toggle="popover"]').popover(); +$('img.preview-image').bootstrapViewer(); \ No newline at end of file diff --git a/app/views/admins/shared/delete.js.erb b/app/views/admins/shared/delete.js.erb index a10e1ae28..74512d55b 100644 --- a/app/views/admins/shared/delete.js.erb +++ b/app/views/admins/shared/delete.js.erb @@ -1,6 +1,8 @@ var deleteRow = $('<%= params[:element] %>'); var refreshUrl = '<%= params[:refresh_url] %>'; +$.notify({ message: '操作成功' },{ type: 'success' }); + var refreshFunc = function(url) { $.ajax({ url: url.length > 0 ? url : window.location.href, diff --git a/app/views/admins/users/shared/_user_list.html.erb b/app/views/admins/users/shared/_user_list.html.erb index e23e918fb..36b5d0f6e 100644 --- a/app/views/admins/users/shared/_user_list.html.erb +++ b/app/views/admins/users/shared/_user_list.html.erb @@ -1,29 +1,23 @@ - - + - - - - - + + + + + <% if users.present? %> <% users.each do |user| %> - - @@ -35,6 +29,8 @@ + <% else %> <% end %> diff --git a/app/views/admins/professional_authentications/shared/_list.html.erb b/app/views/admins/professional_authentications/shared/_list.html.erb index acd62eae5..fd7685f98 100644 --- a/app/views/admins/professional_authentications/shared/_list.html.erb +++ b/app/views/admins/professional_authentications/shared/_list.html.erb @@ -26,7 +26,7 @@ <% if applies.present? %> <% applies.each do |apply| %> <% user = apply.user %> - + <% else %> <% end %> From 0993a0d485290cc6f8174295f2c87308c9e27d91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Mon, 26 Aug 2019 11:13:54 +0800 Subject: [PATCH 04/11] =?UTF-8?q?=E8=B0=83=E6=95=B4=20=E5=85=AC=E5=91=8A?= =?UTF-8?q?=E6=A0=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modules/courses/gradinforms/Bullsubdirectory.js | 10 +++++++++- .../src/modules/courses/gradinforms/Eduinforms.js | 10 +++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/public/react/src/modules/courses/gradinforms/Bullsubdirectory.js b/public/react/src/modules/courses/gradinforms/Bullsubdirectory.js index c7f773190..ebfd2d51b 100644 --- a/public/react/src/modules/courses/gradinforms/Bullsubdirectory.js +++ b/public/react/src/modules/courses/gradinforms/Bullsubdirectory.js @@ -218,11 +218,19 @@ class Bullsubdirectory extends Component{ *
    +
    diff --git a/public/react/src/modules/courses/gradinforms/Eduinforms.js b/public/react/src/modules/courses/gradinforms/Eduinforms.js index f847c87d3..10beb4507 100644 --- a/public/react/src/modules/courses/gradinforms/Eduinforms.js +++ b/public/react/src/modules/courses/gradinforms/Eduinforms.js @@ -287,11 +287,19 @@ class Eduinforms extends Component{ *
    +
    From 0124871bf586bb62e9fc44e99da16dab3dff3b93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Mon, 26 Aug 2019 11:49:50 +0800 Subject: [PATCH 05/11] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dsuffix=20=E9=80=A0?= =?UTF-8?q?=E6=88=90=E7=9A=84=E9=87=8D=E5=8F=A0=20=E6=96=87=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/modules/courses/boards/BoardsNew.js | 15 ++++++++-- .../src/modules/courses/busyWork/NewWork.js | 13 ++++++++- .../modules/courses/exercise/ExerciseNew.js | 15 ++++++++-- .../graduation/tasks/GraduationTasksedit.js | 14 ++++++++-- .../graduation/tasks/GraduationTasksnew.js | 14 ++++++++-- .../graduation/topics/GraduateTopicNew.js | 13 ++++++++- .../react/src/modules/courses/poll/PollNew.js | 14 ++++++++-- .../modules/user/LoginRegisterComponent.js | 6 +++- .../modules/user/account/AccountBasicEdit.js | 28 ++++++++++++++++--- .../user/usersInfo/video/EditVideoModal.js | 16 +++++++++-- .../user/usersInfo/video/VideoUpload.js | 16 +++++++++-- 11 files changed, 140 insertions(+), 24 deletions(-) diff --git a/public/react/src/modules/courses/boards/BoardsNew.js b/public/react/src/modules/courses/boards/BoardsNew.js index b02f6a73f..2df6270c2 100644 --- a/public/react/src/modules/courses/boards/BoardsNew.js +++ b/public/react/src/modules/courses/boards/BoardsNew.js @@ -337,6 +337,17 @@ class BoardsNew extends Component{ } + + )} diff --git a/public/react/src/modules/courses/busyWork/NewWork.js b/public/react/src/modules/courses/busyWork/NewWork.js index ca79e8ac5..525e13922 100644 --- a/public/react/src/modules/courses/busyWork/NewWork.js +++ b/public/react/src/modules/courses/busyWork/NewWork.js @@ -389,6 +389,17 @@ class NewWork extends Component{

    {/* onSubmit={this.handleSubmit} */} +
    + )} + {/* )} */} diff --git a/public/react/src/modules/courses/graduation/tasks/GraduationTasksedit.js b/public/react/src/modules/courses/graduation/tasks/GraduationTasksedit.js index 42a128719..869295c59 100644 --- a/public/react/src/modules/courses/graduation/tasks/GraduationTasksedit.js +++ b/public/react/src/modules/courses/graduation/tasks/GraduationTasksedit.js @@ -375,11 +375,21 @@ class GraduationTasksedit extends Component{ (选择确认后,无法修改) - + {getFieldDecorator('name', { rules: [{ required: true, message: "请输入标题" }], - })()} + })()}
    diff --git a/public/react/src/modules/courses/graduation/tasks/GraduationTasksnew.js b/public/react/src/modules/courses/graduation/tasks/GraduationTasksnew.js index 7c499430a..fae87fb65 100644 --- a/public/react/src/modules/courses/graduation/tasks/GraduationTasksnew.js +++ b/public/react/src/modules/courses/graduation/tasks/GraduationTasksnew.js @@ -377,15 +377,23 @@ class GraduationTasksnew extends Component { margin-top: 0px; margin-bottom: 0px; } + .yslgts .ant-input{ + border-right: none !important; + height: 40px !important; + } ` } {getFieldDecorator('name', { rules: [{required: true, message: "不能为空"}], - })()} + })( + + + + )} diff --git a/public/react/src/modules/courses/graduation/topics/GraduateTopicNew.js b/public/react/src/modules/courses/graduation/topics/GraduateTopicNew.js index 3845721be..329cd169b 100644 --- a/public/react/src/modules/courses/graduation/topics/GraduateTopicNew.js +++ b/public/react/src/modules/courses/graduation/topics/GraduateTopicNew.js @@ -358,6 +358,17 @@ class GraduateTopicNew extends Component{ )} + + )} diff --git a/public/react/src/modules/courses/poll/PollNew.js b/public/react/src/modules/courses/poll/PollNew.js index 48bc69c79..27194e5e0 100644 --- a/public/react/src/modules/courses/poll/PollNew.js +++ b/public/react/src/modules/courses/poll/PollNew.js @@ -2529,14 +2529,24 @@ class PollNew extends Component { {/*suffix={String(addonAfter)}*/} + + className="searchViewAfter yslpollls">
    @@ -1112,7 +1116,7 @@ class LoginRegisterComponent extends Component { autoComplete="new-password" onClick={this.changeType} value={this.state.passwords} onChange={this.passwordonChanges} - suffix={ + addonAfter={ this.Showandhide(key)}> }> diff --git a/public/react/src/modules/user/account/AccountBasicEdit.js b/public/react/src/modules/user/account/AccountBasicEdit.js index cb6941070..27aae8893 100644 --- a/public/react/src/modules/user/account/AccountBasicEdit.js +++ b/public/react/src/modules/user/account/AccountBasicEdit.js @@ -492,7 +492,17 @@ class AccountBasic extends Component { } `}
    基本信息
    - + {String(nameLength)}/{MAX_NICKNAME_LENGTH} }> )} - + this.showOrHide(showRealName)}> }> diff --git a/public/react/src/modules/user/usersInfo/video/EditVideoModal.js b/public/react/src/modules/user/usersInfo/video/EditVideoModal.js index fc05cc932..7420d6750 100644 --- a/public/react/src/modules/user/usersInfo/video/EditVideoModal.js +++ b/public/react/src/modules/user/usersInfo/video/EditVideoModal.js @@ -63,7 +63,17 @@ function EditVideoModal (props) { onOk={onOk} onCancel={onCancel} className="editVideoModal" - > + > + )} diff --git a/public/react/src/modules/user/usersInfo/video/VideoUpload.js b/public/react/src/modules/user/usersInfo/video/VideoUpload.js index 26036529a..8efc308a7 100644 --- a/public/react/src/modules/user/usersInfo/video/VideoUpload.js +++ b/public/react/src/modules/user/usersInfo/video/VideoUpload.js @@ -36,13 +36,23 @@ function VideoUpload (props) { cancelUpload(index, loaded == '100' )}>{loaded == '100' ? "删除" : "取消上传"}
    - +
    标题: - {String(title.length)}/{MAX_LENGTH} } - className="titleInput" + className="titleInput titleInputysl" >
    From e9fb87759f26d61ae0864d557277a54b9b56607c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Mon, 26 Aug 2019 14:03:39 +0800 Subject: [PATCH 06/11] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dsuffix=20=E9=80=A0?= =?UTF-8?q?=E6=88=90=E7=9A=84=E9=87=8D=E5=8F=A0=20=E6=96=87=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/modules/courses/new/CoursesNew.js | 17 +++++++++++++++- .../src/modules/courses/new/Goldsubject.js | 20 ++++++++++++------- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/public/react/src/modules/courses/new/CoursesNew.js b/public/react/src/modules/courses/new/CoursesNew.js index 8c68dd4c5..ed07d5c4a 100644 --- a/public/react/src/modules/courses/new/CoursesNew.js +++ b/public/react/src/modules/courses/new/CoursesNew.js @@ -1,11 +1,12 @@ import React, {Component} from "React"; -import {Form, Select, Input, Button, Checkbox, DatePicker,Spin,Icon,AutoComplete,InputNumber} from "antd"; +import {Form, Select, Input, Button, Checkbox, DatePicker,Spin,Icon,AutoComplete,InputNumber,Breadcrumb} from "antd"; import ApplyForAddOrgModal from '../../user/modal/ApplyForAddOrgModal'; import axios from 'axios'; import "../css/Courses.css"; import locale from 'antd/lib/date-picker/locale/zh_CN'; import moment from 'moment'; import Modals from '../../modals/Modals'; +import {WordsBtn, ActionBtn} from 'educoder'; @@ -503,6 +504,20 @@ class CoursesNew extends Component { />
    + {/**/} + {/* */} + {/* 翻转课堂*/} + {/* */} + {/* {this.props.match.params.coursesId === undefined ?"新建课堂":"编辑课堂"}*/} + {/**/} + +

    + 翻转课堂 + > + {this.props.match.params.coursesId === undefined ?"新建课堂":"编辑课堂"} +

    + +

    {this.props.match.params.coursesId === undefined ? "新建课堂" : "编辑课堂"}

    返回 diff --git a/public/react/src/modules/courses/new/Goldsubject.js b/public/react/src/modules/courses/new/Goldsubject.js index ee1d3b9c7..a51e535e9 100644 --- a/public/react/src/modules/courses/new/Goldsubject.js +++ b/public/react/src/modules/courses/new/Goldsubject.js @@ -6,7 +6,7 @@ import "../css/Courses.css"; import locale from 'antd/lib/date-picker/locale/zh_CN'; import moment from 'moment'; import Modals from '../../modals/Modals'; - +import {WordsBtn, ActionBtn} from 'educoder'; const { Option } = Select; @@ -651,12 +651,18 @@ class Goldsubject extends Component {
    - - - 首页 - - {Whethertocreateanewclassroom===true?"新建课堂":"编辑课堂"} - + {/**/} + {/* */} + {/* 翻转课堂*/} + {/* */} + {/* {Whethertocreateanewclassroom===true?"新建课堂":"编辑课堂"}*/} + {/**/} +

    + 翻转课堂 + > + {Whethertocreateanewclassroom===true?"新建课堂":"编辑课堂"} +

    +

    {Whethertocreateanewclassroom===true ? "新建课堂" : "编辑课堂"}

    From dc2478b88b36662ffcb146aa6e87fbbf42c271f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Mon, 26 Aug 2019 14:10:16 +0800 Subject: [PATCH 07/11] =?UTF-8?q?=E8=B0=83=E6=95=B4=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/react/src/modules/courses/new/CoursesNew.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/react/src/modules/courses/new/CoursesNew.js b/public/react/src/modules/courses/new/CoursesNew.js index ed07d5c4a..46380d85b 100644 --- a/public/react/src/modules/courses/new/CoursesNew.js +++ b/public/react/src/modules/courses/new/CoursesNew.js @@ -519,7 +519,7 @@ class CoursesNew extends Component {
    -

    {this.props.match.params.coursesId === undefined ? "新建课堂" : "编辑课堂"}

    +

    {this.props.match.params.coursesId === undefined ? "新建课堂" : "编辑课堂"}

    返回
    - +

    微信扫一扫

    关注公众号

    From 4374223f7dff0eefe865d9f030c83076d2443929 Mon Sep 17 00:00:00 2001 From: p31729568 Date: Mon, 26 Aug 2019 15:41:31 +0800 Subject: [PATCH 11/11] admins: shixun publish and subject publish feature --- .../admins/shixun_authorizations/index.js | 18 ++++++ .../admins/subject_authorizations/index.js | 18 ++++++ ...tics.scss => daily_school_statistics.scss} | 0 ...ons.scss => identity_authentications.scss} | 0 ...scss => professional_authentications.scss} | 0 ...statistics.scss => school_statistics.scss} | 0 .../admins/shixun_authorizations.scss | 9 +++ .../admins/subject_authorizations.scss | 9 +++ .../shixun_authorizations_controller.rb | 48 ++++++++++++++ .../subject_authorizations_controller.rb | 49 ++++++++++++++ .../concerns/admins/error_rescue_handler.rb | 2 +- .../concerns/admins/render_helper.rb | 2 +- app/models/apply_action.rb | 8 +++ .../shixun_auths/agree_apply_service.rb | 43 +++++++++++++ .../shixun_auths/refuse_apply_service.rb | 35 ++++++++++ .../subject_auths/agree_apply_service.rb | 30 +++++++++ .../subject_auths/refuse_apply_service.rb | 35 ++++++++++ app/views/admins/shared/_sidebar.html.erb | 2 + app/views/admins/shared/error.js.erb | 5 +- .../shixun_authorizations/index.html.erb | 32 ++++++++++ .../admins/shixun_authorizations/index.js.erb | 1 + .../shared/_list.html.erb | 60 +++++++++++++++++ .../subject_authorizations/index.html.erb | 33 ++++++++++ .../subject_authorizations/index.js.erb | 1 + .../shared/_list.html.erb | 64 +++++++++++++++++++ config/locales/apply_actions/zh-CN.yml | 7 ++ config/routes.rb | 12 ++++ 27 files changed, 520 insertions(+), 3 deletions(-) create mode 100644 app/assets/javascripts/admins/shixun_authorizations/index.js create mode 100644 app/assets/javascripts/admins/subject_authorizations/index.js rename app/assets/stylesheets/admins/{daily-school-statistics.scss => daily_school_statistics.scss} (100%) rename app/assets/stylesheets/admins/{identity-authentications.scss => identity_authentications.scss} (100%) rename app/assets/stylesheets/admins/{professional-authentications.scss => professional_authentications.scss} (100%) rename app/assets/stylesheets/admins/{school-statistics.scss => school_statistics.scss} (100%) create mode 100644 app/assets/stylesheets/admins/shixun_authorizations.scss create mode 100644 app/assets/stylesheets/admins/subject_authorizations.scss create mode 100644 app/controllers/admins/shixun_authorizations_controller.rb create mode 100644 app/controllers/admins/subject_authorizations_controller.rb create mode 100644 app/services/admins/shixun_auths/agree_apply_service.rb create mode 100644 app/services/admins/shixun_auths/refuse_apply_service.rb create mode 100644 app/services/admins/subject_auths/agree_apply_service.rb create mode 100644 app/services/admins/subject_auths/refuse_apply_service.rb create mode 100644 app/views/admins/shixun_authorizations/index.html.erb create mode 100644 app/views/admins/shixun_authorizations/index.js.erb create mode 100644 app/views/admins/shixun_authorizations/shared/_list.html.erb create mode 100644 app/views/admins/subject_authorizations/index.html.erb create mode 100644 app/views/admins/subject_authorizations/index.js.erb create mode 100644 app/views/admins/subject_authorizations/shared/_list.html.erb create mode 100644 config/locales/apply_actions/zh-CN.yml diff --git a/app/assets/javascripts/admins/shixun_authorizations/index.js b/app/assets/javascripts/admins/shixun_authorizations/index.js new file mode 100644 index 000000000..ba7b23821 --- /dev/null +++ b/app/assets/javascripts/admins/shixun_authorizations/index.js @@ -0,0 +1,18 @@ +$(document).on('turbolinks:load', function() { + if ($('body.admins-shixun-authorizations-index-page').length > 0) { + var $searchFrom = $('.shixun-authorization-list-form'); + + $searchFrom.on('click', '.search-form-tab', function(){ + var $link = $(this); + + $searchFrom.find('input[name="keyword"]').val(''); + $searchFrom.find('select[name="status"]').val('processed'); + + if($link.data('value') === 'processed'){ + $searchFrom.find('.status-filter').show(); + } else { + $searchFrom.find('.status-filter').hide(); + } + }); + } +}) \ No newline at end of file diff --git a/app/assets/javascripts/admins/subject_authorizations/index.js b/app/assets/javascripts/admins/subject_authorizations/index.js new file mode 100644 index 000000000..d80f0850c --- /dev/null +++ b/app/assets/javascripts/admins/subject_authorizations/index.js @@ -0,0 +1,18 @@ +$(document).on('turbolinks:load', function() { + if ($('body.admins-subject-authorizations-index-page').length > 0) { + var $searchFrom = $('.subject-authorization-list-form'); + + $searchFrom.on('click', '.search-form-tab', function(){ + var $link = $(this); + + $searchFrom.find('input[name="keyword"]').val(''); + $searchFrom.find('select[name="status"]').val('processed'); + + if($link.data('value') === 'processed'){ + $searchFrom.find('.status-filter').show(); + } else { + $searchFrom.find('.status-filter').hide(); + } + }); + } +}) \ No newline at end of file diff --git a/app/assets/stylesheets/admins/daily-school-statistics.scss b/app/assets/stylesheets/admins/daily_school_statistics.scss similarity index 100% rename from app/assets/stylesheets/admins/daily-school-statistics.scss rename to app/assets/stylesheets/admins/daily_school_statistics.scss diff --git a/app/assets/stylesheets/admins/identity-authentications.scss b/app/assets/stylesheets/admins/identity_authentications.scss similarity index 100% rename from app/assets/stylesheets/admins/identity-authentications.scss rename to app/assets/stylesheets/admins/identity_authentications.scss diff --git a/app/assets/stylesheets/admins/professional-authentications.scss b/app/assets/stylesheets/admins/professional_authentications.scss similarity index 100% rename from app/assets/stylesheets/admins/professional-authentications.scss rename to app/assets/stylesheets/admins/professional_authentications.scss diff --git a/app/assets/stylesheets/admins/school-statistics.scss b/app/assets/stylesheets/admins/school_statistics.scss similarity index 100% rename from app/assets/stylesheets/admins/school-statistics.scss rename to app/assets/stylesheets/admins/school_statistics.scss diff --git a/app/assets/stylesheets/admins/shixun_authorizations.scss b/app/assets/stylesheets/admins/shixun_authorizations.scss new file mode 100644 index 000000000..05bcbc2bb --- /dev/null +++ b/app/assets/stylesheets/admins/shixun_authorizations.scss @@ -0,0 +1,9 @@ +.admins-shixun-authorizations-index-page { + .shixun-authorization-list-container { + span { + &.apply-status-1 { color: #28a745; } + &.apply-status-2 { color: #dc3545; } + &.apply-status-3 { color: #6c757d; } + } + } +} \ No newline at end of file diff --git a/app/assets/stylesheets/admins/subject_authorizations.scss b/app/assets/stylesheets/admins/subject_authorizations.scss new file mode 100644 index 000000000..f16c30151 --- /dev/null +++ b/app/assets/stylesheets/admins/subject_authorizations.scss @@ -0,0 +1,9 @@ +.admins-subject-authorizations-index-page { + .subject-authorization-list-container { + span { + &.apply-status-1 { color: #28a745; } + &.apply-status-2 { color: #dc3545; } + &.apply-status-3 { color: #6c757d; } + } + } +} \ No newline at end of file diff --git a/app/controllers/admins/shixun_authorizations_controller.rb b/app/controllers/admins/shixun_authorizations_controller.rb new file mode 100644 index 000000000..31bd5faf7 --- /dev/null +++ b/app/controllers/admins/shixun_authorizations_controller.rb @@ -0,0 +1,48 @@ +class Admins::ShixunAuthorizationsController < Admins::BaseController + def index + params[:status] ||= 'pending' + + applies = ApplyAction.where(container_type: 'ApplyShixun') + + status = + case params[:status] + when 'pending' then 0 + when 'processed' then [1, 2] + when 'agreed' then 1 + when 'refused' then 2 + else 0 + end + applies = applies.where(status: status) if status.present? + + # 关键字模糊查询 + keyword = params[:keyword].to_s.strip + if keyword.present? + applies = applies.joins('JOIN shixuns ON shixuns.id = apply_actions.container_id') + .where('shixuns.name LIKE :keyword', keyword: "%#{keyword}%") + end + + applies = applies.order(updated_at: :desc) + + @applies = paginate applies.includes(user: :user_extension) + + shixun_ids = @applies.map(&:container_id) + @shixun_map = Shixun.where(id: shixun_ids).each_with_object({}) { |s, h| h[s.id] = s } + end + + def agree + Admins::ShixunAuths::AgreeApplyService.call(current_apply, current_user) + render_success_js + end + + def refuse + Admins::ShixunAuths::RefuseApplyService.call(current_apply, current_user, params) + + render_success_js + end + + private + + def current_apply + @_current_apply ||= ApplyAction.where(container_type: 'ApplyShixun').find(params[:id]) + end +end \ No newline at end of file diff --git a/app/controllers/admins/subject_authorizations_controller.rb b/app/controllers/admins/subject_authorizations_controller.rb new file mode 100644 index 000000000..3d3733fa4 --- /dev/null +++ b/app/controllers/admins/subject_authorizations_controller.rb @@ -0,0 +1,49 @@ +class Admins::SubjectAuthorizationsController < Admins::BaseController + def index + params[:status] ||= 'pending' + + applies = ApplyAction.where(container_type: 'ApplySubject') + + status = + case params[:status] + when 'pending' then 0 + when 'processed' then [1, 2] + when 'agreed' then 1 + when 'refused' then 2 + else 0 + end + applies = applies.where(status: status) if status.present? + + # 关键字模糊查询 + keyword = params[:keyword].to_s.strip + if keyword.present? + applies = applies.joins('JOIN subjects ON subjects.id = apply_actions.container_id') + .where('subjects.name LIKE :keyword', keyword: "%#{keyword}%") + end + + applies = applies.order(updated_at: :desc) + + @applies = paginate applies.includes(user: :user_extension) + + subject_ids = @applies.map(&:container_id) + @subject_map = Subject.where(id: subject_ids).each_with_object({}) { |s, h| h[s.id] = s } + @challenge_count_map = Challenge.joins(shixun: :stage_shixuns).where(st: 0, stage_shixuns: { subject_id: subject_ids}).group('subject_id').count + end + + def agree + Admins::SubjectAuths::AgreeApplyService.call(current_apply, current_user) + render_success_js + end + + def refuse + Admins::SubjectAuths::RefuseApplyService.call(current_apply, current_user, params) + + render_success_js + end + + private + + def current_apply + @_current_apply ||= ApplyAction.where(container_type: 'ApplySubject').find(params[:id]) + end +end \ No newline at end of file diff --git a/app/controllers/concerns/admins/error_rescue_handler.rb b/app/controllers/concerns/admins/error_rescue_handler.rb index b1e29d5ce..ceb810f36 100644 --- a/app/controllers/concerns/admins/error_rescue_handler.rb +++ b/app/controllers/concerns/admins/error_rescue_handler.rb @@ -2,7 +2,7 @@ module Admins::ErrorRescueHandler extend ActiveSupport::Concern included do - rescue_from Exception, Educoder::TipException do |e| + rescue_from Exception do |e| raise e if Rails.env.development? Util.logger_error e diff --git a/app/controllers/concerns/admins/render_helper.rb b/app/controllers/concerns/admins/render_helper.rb index 3651f892b..0ccc16a09 100644 --- a/app/controllers/concerns/admins/render_helper.rb +++ b/app/controllers/concerns/admins/render_helper.rb @@ -28,7 +28,7 @@ module Admins::RenderHelper def internal_server_error respond_to do |format| format.html { render 'admins/shared/500' } - format.js { render_js_error(message) } + format.js { render_js_error('系统错误') } format.json { render status: 500, json: { message: '系统错误' } } end end diff --git a/app/models/apply_action.rb b/app/models/apply_action.rb index 2d31f394d..54bdaa396 100644 --- a/app/models/apply_action.rb +++ b/app/models/apply_action.rb @@ -1,8 +1,16 @@ # 申请消息 class ApplyAction < ApplicationRecord + belongs_to :user + has_many :tidings, :as => :container, :dependent => :destroy after_create :send_tiding + def status_text + I18n.t!("apply_action.status.#{status}") + rescue I18n::MissingTranslationData + nil + end + def send_tiding if container_type == 'TrialAuthorization' && status == 1 tidings.create(user_id: user_id, trigger_user_id: 0, status: 1, viewed: 0, tiding_type: 'System', diff --git a/app/services/admins/shixun_auths/agree_apply_service.rb b/app/services/admins/shixun_auths/agree_apply_service.rb new file mode 100644 index 000000000..4734e03bb --- /dev/null +++ b/app/services/admins/shixun_auths/agree_apply_service.rb @@ -0,0 +1,43 @@ +class Admins::ShixunAuths::AgreeApplyService < ApplicationService + attr_reader :apply, :user, :shixun + + def initialize(apply, user) + @apply = apply + @user = user + @shixun = Shixun.find(apply.container_id) + end + + def call + ActiveRecord::Base.transaction do + apply.update!(status: 1, dealer_id: user.id) + shixun.update!(status: 2, publish_time: Time.now) + + # 奖励金币、经验 + reward_grade_and_experience! + + deal_tiding! + end + end + + private + + def reward_grade_and_experience! + score = shixun.all_score + shixun_creator = shixun.user + + RewardGradeService.call(shixun_creator, container_id: shixun.id, container_type: 'shixunPublish', score: score) + + Experience.create!(user_id: shixun_creator.id, container_id: shixun.id, container_type: 'shixunPublish', score: score) + shixun_creator.update_column(:experience, shixun_creator.experience.to_i + score) + end + + def deal_tiding! + apply.tidings.where(tiding_type: 'Apply', status: 0).update_all(status: 1) + + Tiding.create!(user_id: apply.user_id, trigger_user_id: 0, + container_id: apply.id, container_type: 'ApplyAction', + parent_container_id: apply.container_id, parent_container_type: apply.container_type, + belong_container_id: apply.container_id, belong_container_type: 'Shixun', + status: 1, tiding_type: 'System') + end +end \ No newline at end of file diff --git a/app/services/admins/shixun_auths/refuse_apply_service.rb b/app/services/admins/shixun_auths/refuse_apply_service.rb new file mode 100644 index 000000000..49416a2b0 --- /dev/null +++ b/app/services/admins/shixun_auths/refuse_apply_service.rb @@ -0,0 +1,35 @@ +class Admins::ShixunAuths::RefuseApplyService < ApplicationService + attr_reader :apply, :user, :shixun, :params + + def initialize(apply, user, params) + @apply = apply + @user = user + @shixun = Shixun.find(apply.container_id) + @params = params + end + + def call + ActiveRecord::Base.transaction do + shixun.update!(status: 0) + apply.update!(status: 2, reason: reason, dealer_id: user.id) + + deal_tiding! + end + end + + private + + def reason + params[:reason].to_s.strip + end + + def deal_tiding! + apply.tidings.where(tiding_type: 'Apply', status: 0).update_all(status: 1) + + Tiding.create!(user_id: apply.user_id, trigger_user_id: 0, + container_id: apply.id, container_type: 'ApplyAction', + parent_container_id: apply.container_id, parent_container_type: apply.container_type, + belong_container_id: apply.container_id, belong_container_type: 'Shixun', + status: 2, tiding_type: 'System') + end +end \ No newline at end of file diff --git a/app/services/admins/subject_auths/agree_apply_service.rb b/app/services/admins/subject_auths/agree_apply_service.rb new file mode 100644 index 000000000..465e3e903 --- /dev/null +++ b/app/services/admins/subject_auths/agree_apply_service.rb @@ -0,0 +1,30 @@ +class Admins::SubjectAuths::AgreeApplyService < ApplicationService + attr_reader :apply, :user, :subject + + def initialize(apply, user) + @apply = apply + @user = user + @subject = Subject.find(apply.container_id) + end + + def call + ActiveRecord::Base.transaction do + apply.update!(status: 1, dealer_id: user.id) + subject.update!(status: 2, publish_time: Time.now) + + deal_tiding! + end + end + + private + + def deal_tiding! + apply.tidings.where(tiding_type: 'Apply', status: 0).update_all(status: 1) + + Tiding.create!(user_id: apply.user_id, trigger_user_id: 0, + container_id: apply.id, container_type: 'ApplyAction', + parent_container_id: apply.container_id, parent_container_type: apply.container_type, + belong_container_id: apply.container_id, belong_container_type: 'Subject', + status: 1, tiding_type: 'System') + end +end \ No newline at end of file diff --git a/app/services/admins/subject_auths/refuse_apply_service.rb b/app/services/admins/subject_auths/refuse_apply_service.rb new file mode 100644 index 000000000..f51d55185 --- /dev/null +++ b/app/services/admins/subject_auths/refuse_apply_service.rb @@ -0,0 +1,35 @@ +class Admins::SubjectAuths::RefuseApplyService < ApplicationService + attr_reader :apply, :user, :subject, :params + + def initialize(apply, user, params) + @apply = apply + @user = user + @subject = Subject.find(apply.container_id) + @params = params + end + + def call + ActiveRecord::Base.transaction do + subject.update!(status: 0) + apply.update!(status: 2, reason: reason, dealer_id: user.id) + + deal_tiding! + end + end + + private + + def reason + params[:reason].to_s.strip + end + + def deal_tiding! + apply.tidings.where(tiding_type: 'Apply', status: 0).update_all(status: 1) + + Tiding.create!(user_id: apply.user_id, trigger_user_id: 0, + container_id: apply.id, container_type: 'ApplyAction', + parent_container_id: apply.container_id, parent_container_type: apply.container_type, + belong_container_id: apply.container_id, belong_container_type: 'Subject', + status: 2, tiding_type: 'System') + end +end \ No newline at end of file diff --git a/app/views/admins/shared/_sidebar.html.erb b/app/views/admins/shared/_sidebar.html.erb index 2be899ebd..ab30e8bd3 100644 --- a/app/views/admins/shared/_sidebar.html.erb +++ b/app/views/admins/shared/_sidebar.html.erb @@ -41,6 +41,8 @@ <%= sidebar_item_group('#apply-review-submenu', '审核', icon: 'gavel') do %>
  • <%= sidebar_item(admins_identity_authentications_path, '实名认证', icon: 'id-card-o', controller: 'admins-identity_authentications') %>
  • <%= sidebar_item(admins_professional_authentications_path, '职业认证', icon: 'drivers-license', controller: 'admins-professional_authentications') %>
  • +
  • <%= sidebar_item(admins_shixun_authorizations_path, '实训发布', icon: 'object-ungroup', controller: 'admins-shixun_authorizations') %>
  • +
  • <%= sidebar_item(admins_subject_authorizations_path, '实践课程发布', icon: 'object-group', controller: 'admins-subject_authorizations') %>
  • <% end %> diff --git a/app/views/admins/shared/error.js.erb b/app/views/admins/shared/error.js.erb index ebb78aec6..261796d0b 100644 --- a/app/views/admins/shared/error.js.erb +++ b/app/views/admins/shared/error.js.erb @@ -4,4 +4,7 @@ setTimeout(function() { if ($('.admin-alert-container button.close').length > 0) { $('.admin-alert-container button.close').trigger('click'); } -}, 2000) \ No newline at end of file +}, 5000) +$(".admin-body-container").animate({ + scrollTop: 0 +}, 200); \ No newline at end of file diff --git a/app/views/admins/shixun_authorizations/index.html.erb b/app/views/admins/shixun_authorizations/index.html.erb new file mode 100644 index 000000000..743f2e1b2 --- /dev/null +++ b/app/views/admins/shixun_authorizations/index.html.erb @@ -0,0 +1,32 @@ +<% define_admin_breadcrumbs do %> + <% add_admin_breadcrumb('实训发布') %> +<% end %> + +
    + + + <%= form_tag(admins_shixun_authorizations_path(unsafe_params), method: :get, class: 'form-inline search-form justify-content-end mt-3', remote: true) do %> +
    + + <% status_options = [['全部', 'processed'], ['已同意', 'agreed'], ['已拒绝', 'refused']] %> + <%= select_tag(:status, options_for_select(status_options), class: 'form-control') %> +
    + <%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-sm-2 ml-3', placeholder: '实训名称检索') %> + <%= submit_tag('搜索', class: 'btn btn-primary ml-3') %> + <% end %> +
    + +
    + <%= render(partial: 'admins/shixun_authorizations/shared/list', locals: { applies: @applies, shixun_map: @shixun_map }) %> +
    + +<%= render(partial: 'admins/shared/admin_common_refuse_modal') %> \ No newline at end of file diff --git a/app/views/admins/shixun_authorizations/index.js.erb b/app/views/admins/shixun_authorizations/index.js.erb new file mode 100644 index 000000000..caa8bb389 --- /dev/null +++ b/app/views/admins/shixun_authorizations/index.js.erb @@ -0,0 +1 @@ +$('.shixun-authorization-list-container').html("<%= j( render partial: 'admins/shixun_authorizations/shared/list', locals: { applies: @applies, shixun_map: @shixun_map } ) %>"); \ No newline at end of file diff --git a/app/views/admins/shixun_authorizations/shared/_list.html.erb b/app/views/admins/shixun_authorizations/shared/_list.html.erb new file mode 100644 index 000000000..ce3b4ca43 --- /dev/null +++ b/app/views/admins/shixun_authorizations/shared/_list.html.erb @@ -0,0 +1,60 @@ +<% is_processed = params[:status].to_s != 'pending' %> + +
    ID真实姓名真实姓名 邮件地址 手机号码 单位<%= sort_tag('创建于', name: 'created_on', path: admins_users_path) %><%= sort_tag('最后登录', name: 'last_login_on', path: admins_users_path) %><%= sort_tag('经验值', name: 'experience', path: admins_users_path) %><%= sort_tag('金币', name: 'grade', path: admins_users_path) %>操作<%= sort_tag('创建于', name: 'created_on', path: admins_users_path) %><%= sort_tag('最后登录', name: 'last_login_on', path: admins_users_path) %><%= sort_tag('经验值', name: 'experience', path: admins_users_path) %><%= sort_tag('金币', name: 'grade', path: admins_users_path) %>操作
    + <%= link_to "/users/#{user.login}", target: '_blank' do %> - <%= overflow_hidden_span user.login, width: 100 %> - <% end %> - - <%= link_to edit_admins_user_path(user) do %> <%= overflow_hidden_span user.real_name, width: 100 %> <% end %> <%= user.experience.to_i %> <%= user.grade.to_i %> + <%= link_to '编辑', edit_admins_user_path(user), class: 'action' %> + <%= javascript_void_link('奖励', class: 'action reward-grade-action', data: { toggle: 'modal', target: '.admin-users-reward-grade-modal', id: user.id }) %> <%= javascript_void_link '解锁', class: 'action unlock-action', data: { id: user.id, confirm: '确认解锁吗?' }, style: user.locked? ? '' : 'display: none;' %> diff --git a/config/locales/apply_user_authentications/zh-CN.yml b/config/locales/apply_user_authentications/zh-CN.yml new file mode 100644 index 000000000..e886c2695 --- /dev/null +++ b/config/locales/apply_user_authentications/zh-CN.yml @@ -0,0 +1,7 @@ +zh-CN: + apply_user_authentication: + status: + '0': '待处理' + '1': '已同意' + '2': '已拒绝' + '3': '已撤销' \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 5ed8ecd69..4fc660a45 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -753,7 +753,7 @@ Rails.application.routes.draw do get :contrast, on: :collection end - resources :users, only: [:index, :edit, :update] do + resources :users, only: [:index, :edit, :update, :destroy] do member do post :reward_grade post :lock @@ -761,6 +761,19 @@ Rails.application.routes.draw do post :active end end + + resources :identity_authentications, only: [:index] do + member do + post :agree + post :refuse + end + end + resources :professional_authentications, only: [:index] do + member do + post :agree + post :refuse + end + end end #git 认证回调 From 27e549796fda5c6f19475c461ecfe94155da9272 Mon Sep 17 00:00:00 2001 From: p31729568 Date: Mon, 26 Aug 2019 10:28:50 +0800 Subject: [PATCH 03/11] fix --- .../admins/identity_authentications/shared/_list.html.erb | 6 +++--- .../professional_authentications/shared/_list.html.erb | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/views/admins/identity_authentications/shared/_list.html.erb b/app/views/admins/identity_authentications/shared/_list.html.erb index 1cd849e72..f6aa53dd1 100644 --- a/app/views/admins/identity_authentications/shared/_list.html.erb +++ b/app/views/admins/identity_authentications/shared/_list.html.erb @@ -27,7 +27,7 @@ <% if applies.present? %> <% applies.each do |apply| %> <% user = apply.user %> -
    <%= link_to "/users/#{user.login}", class: 'identity-authentication-avatar', target: '_blank', data: { toggle: 'tooltip', title: '个人主页' } do %> @@ -55,11 +55,11 @@ <%= apply.status_text %> - <%= agree_link '同意', agree_admins_identity_authentication_path(apply, element: ".identity-authentication-#{user.id}"), 'data-confirm': '确认审核通过?' %> + <%= agree_link '同意', agree_admins_identity_authentication_path(apply, element: ".identity-authentication-#{apply.id}"), 'data-confirm': '确认审核通过?' %> <%= javascript_void_link('拒绝', class: 'action refuse-action', data: { toggle: 'modal', target: '.admin-common-refuse-modal', id: apply.id, - url: refuse_admins_identity_authentication_path(apply, element: ".identity-authentication-#{user.id}") + url: refuse_admins_identity_authentication_path(apply, element: ".identity-authentication-#{apply.id}") }) %>
    <%= link_to "/users/#{user.login}", class: 'professional-authentication-avatar', target: '_blank', data: { toggle: 'tooltip', title: '个人主页' } do %> @@ -53,11 +53,11 @@ <%= apply.status_text %> - <%= agree_link '同意', agree_admins_professional_authentication_path(apply, element: ".professional-authentication-#{user.id}"), 'data-confirm': '确认审核通过?' %> + <%= agree_link '同意', agree_admins_professional_authentication_path(apply, element: ".professional-authentication-#{apply.id}"), 'data-confirm': '确认审核通过?' %> <%= javascript_void_link('拒绝', class: 'action refuse-action', data: { toggle: 'modal', target: '.admin-common-refuse-modal', id: apply.id, - url: refuse_admins_professional_authentication_path(apply, element: ".professional-authentication-#{user.id}") + url: refuse_admins_professional_authentication_path(apply, element: ".professional-authentication-#{apply.id}") }) %>
    + + + + + + + + <% if is_processed %> + + + <% else %> + + <% end %> + + + + <% if applies.present? %> + <% applies.each do |apply| %> + <% user = apply.user %> + <% shixun = shixun_map[apply.container_id] %> + + + + + + + + <% if is_processed %> + + + <% else %> + + <% end %> + + <% end %> + <% else %> + <%= render 'admins/shared/no_data_for_table' %> + <% end %> + +
    头像创建者实训名称任务数时间拒绝原因状态操作
    + <%= link_to "/users/#{user.login}", class: 'shixun-authorization-avatar', target: '_blank', data: { toggle: 'tooltip', title: '个人主页' } do %> + + <% end %> + <%= user.real_name %> + <%= link_to "/shixuns/#{shixun.identifier}", target: '_blank' do %> + <%= overflow_hidden_span shixun.name, width: 300 %> + <% end %> + <%= shixun.challenges_count %><%= apply.updated_at.strftime('%Y-%m-%d %H:%M') %><%= overflow_hidden_span apply.reason, width: 140 %><%= apply.status_text %> + <%= agree_link '同意', agree_admins_shixun_authorization_path(apply, element: ".shixun-authorization-#{apply.id}"), 'data-confirm': '确认审核通过?' %> + <%= javascript_void_link('拒绝', class: 'action refuse-action', + data: { + toggle: 'modal', target: '.admin-common-refuse-modal', id: apply.id, + url: refuse_admins_shixun_authorization_path(apply, element: ".shixun-authorization-#{apply.id}") + }) %> +
    + +<%= render partial: 'admins/shared/paginate', locals: { objects: applies } %> \ No newline at end of file diff --git a/app/views/admins/subject_authorizations/index.html.erb b/app/views/admins/subject_authorizations/index.html.erb new file mode 100644 index 000000000..3d5539663 --- /dev/null +++ b/app/views/admins/subject_authorizations/index.html.erb @@ -0,0 +1,33 @@ +<% define_admin_breadcrumbs do %> + <% add_admin_breadcrumb('实践课程发布') %> +<% end %> + +
    + + + <%= form_tag(admins_subject_authorizations_path(unsafe_params), method: :get, class: 'form-inline search-form justify-content-end mt-3', remote: true) do %> +
    + + <% status_options = [['全部', 'processed'], ['已同意', 'agreed'], ['已拒绝', 'refused']] %> + <%= select_tag(:status, options_for_select(status_options), class: 'form-control') %> +
    + <%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-sm-2 ml-3', placeholder: '实训课程名称检索') %> + <%= submit_tag('搜索', class: 'btn btn-primary ml-3') %> + <% end %> +
    + +
    + <%= render(partial: 'admins/subject_authorizations/shared/list', + locals: { applies: @applies, subject_map: @subject_map, challenge_count_map: @challenge_count_map }) %> +
    + +<%= render(partial: 'admins/shared/admin_common_refuse_modal') %> \ No newline at end of file diff --git a/app/views/admins/subject_authorizations/index.js.erb b/app/views/admins/subject_authorizations/index.js.erb new file mode 100644 index 000000000..a21809041 --- /dev/null +++ b/app/views/admins/subject_authorizations/index.js.erb @@ -0,0 +1 @@ +$('.subject-authorization-list-container').html("<%= j( render partial: 'admins/subject_authorizations/shared/list', locals: { applies: @applies, subject_map: @subject_map, challenge_count_map: @challenge_count_map } ) %>"); \ No newline at end of file diff --git a/app/views/admins/subject_authorizations/shared/_list.html.erb b/app/views/admins/subject_authorizations/shared/_list.html.erb new file mode 100644 index 000000000..7b8da800d --- /dev/null +++ b/app/views/admins/subject_authorizations/shared/_list.html.erb @@ -0,0 +1,64 @@ +<% is_processed = params[:status].to_s != 'pending' %> + + + + + + + + + + + + <% if is_processed %> + + + <% else %> + + <% end %> + + + + <% if applies.present? %> + <% applies.each do |apply| %> + <% user = apply.user %> + <% subject = subject_map[apply.container_id] %> + + + + + + + + + + <% if is_processed %> + + + <% else %> + + <% end %> + + <% end %> + <% else %> + <%= render 'admins/shared/no_data_for_table' %> + <% end %> + +
    头像创建者实践课程名称阶段数实训数关卡数时间拒绝原因状态操作
    + <%= link_to "/users/#{user.login}", class: 'subject-authorization-avatar', target: '_blank', data: { toggle: 'tooltip', title: '个人主页' } do %> + + <% end %> + <%= user.real_name %> + <%= link_to "/paths/#{subject.id}", target: '_blank' do %> + <%= overflow_hidden_span subject.name, width: 300 %> + <% end %> + <%= subject.stages_count %><%= subject.shixuns_count %><%= challenge_count_map.fetch(subject.id, 0) %><%= apply.updated_at.strftime('%Y-%m-%d %H:%M') %><%= overflow_hidden_span apply.reason, width: 140 %><%= apply.status_text %> + <%= agree_link '同意', agree_admins_subject_authorization_path(apply, element: ".subject-authorization-#{apply.id}"), 'data-confirm': '确认审核通过?' %> + <%= javascript_void_link('拒绝', class: 'action refuse-action', + data: { + toggle: 'modal', target: '.admin-common-refuse-modal', id: apply.id, + url: refuse_admins_subject_authorization_path(apply, element: ".subject-authorization-#{apply.id}") + }) %> +
    + +<%= render partial: 'admins/shared/paginate', locals: { objects: applies } %> \ No newline at end of file diff --git a/config/locales/apply_actions/zh-CN.yml b/config/locales/apply_actions/zh-CN.yml new file mode 100644 index 000000000..933ef6223 --- /dev/null +++ b/config/locales/apply_actions/zh-CN.yml @@ -0,0 +1,7 @@ +zh-CN: + apply_action: + status: + '0': '待处理' + '1': '已同意' + '2': '已拒绝' + '3': '已撤销' \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 4fc660a45..7e2cf72f3 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -774,6 +774,18 @@ Rails.application.routes.draw do post :refuse end end + resources :shixun_authorizations, only: [:index] do + member do + post :agree + post :refuse + end + end + resources :subject_authorizations, only: [:index] do + member do + post :agree + post :refuse + end + end end #git 认证回调