diff --git a/api_document.md b/api_document.md index 8a579f8e7..a43147bb2 100644 --- a/api_document.md +++ b/api_document.md @@ -51,6 +51,51 @@ http://localhost:3000/api/accounts/remote_register | jq |-- token |string|用户token| +返回值 +```json +{ + "status": 0, + "message": "success", + "user": { + "id": 36400, + "token": "8c87a80d9cfacc92fcb2451845104f35119eda96" + } +} +``` +--- + +#### 独立注册接口 +``` +POST accounts/register +``` +*示例* +```bash +curl -X POST \ +-d "login=2456233122@qq.com" \ +-d "password=djs_D_00001" \ +-d "namespace=16895620" \ +-d "code=forge" \ +http://localhost:3000/api/accounts/remote_register | jq +``` +*请求参数说明:* + +|参数名|必选|类型|说明| +|-|-|-|-| +|login |是|string |邮箱或者手机号 | +|namespace |是|string |登录名 | +|password |是|string |密码 | +|code |是|string |验证码 | + + +*返回参数说明:* + +|参数名|类型|说明| +|-|-|-| +|user|json object |返回数据| +|-- id |int |用户id | +|-- token |string|用户token| + + 返回值 ```json { diff --git a/app/assets/images/logo.png b/app/assets/images/logo.png index 436d23490..72505d8a2 100644 Binary files a/app/assets/images/logo.png and b/app/assets/images/logo.png differ diff --git a/app/assets/javascripts/admin.js b/app/assets/javascripts/admin.js index 0cab04359..d738e5caa 100644 --- a/app/assets/javascripts/admin.js +++ b/app/assets/javascripts/admin.js @@ -99,3 +99,38 @@ $(document).on("turbolinks:before-cache", function () { $(function () { }); + +$(document).on('turbolinks:load', function() { + + $('.logo-item-left').on("change", 'input[type="file"]', function () { + var $fileInput = $(this); + var file = this.files[0]; + var imageType = /image.*/; + if (file && file.type.match(imageType)) { + var reader = new FileReader(); + reader.onload = function () { + var $box = $fileInput.parent(); + $box.find('img').attr('src', reader.result).css('display', 'block'); + $box.addClass('has-img'); + }; + reader.readAsDataURL(file); + } else { + } + }); + + $('.attachment-item-left').on("change", 'input[type="file"]', function () { + var $fileInput = $(this); + var file = this.files[0]; + var imageType = /image.*/; + if (file && file.type.match(imageType)) { + var reader = new FileReader(); + reader.onload = function () { + var $box = $fileInput.parent(); + $box.find('img').attr('src', reader.result).css('display', 'block'); + $box.addClass('has-img'); + }; + reader.readAsDataURL(file); + } else { + } + }); +}) \ No newline at end of file diff --git a/app/assets/javascripts/admins/projects/index.js b/app/assets/javascripts/admins/projects/index.js new file mode 100644 index 000000000..dbf710ea5 --- /dev/null +++ b/app/assets/javascripts/admins/projects/index.js @@ -0,0 +1,141 @@ +/* + * @Description: Do not edit + * @Date: 2021-08-31 11:16:45 + * @LastEditors: viletyy + * @Author: viletyy + * @LastEditTime: 2021-08-31 14:19:46 + * @FilePath: /forgeplus/app/assets/javascripts/admins/system_notifications/index.js + */ +$(document).on('turbolinks:load', function(){ + + var showSuccessNotify = function() { + $.notify({ + message: '操作成功' + },{ + type: 'success' + }); + } + + // close user + $('.project-list-container').on('click', '.recommend-action', function(){ + var $closeAction = $(this); + var $uncloseAction = $closeAction.siblings('.unrecommend-action'); + var $editAction = $closeAction.siblings('.edit-recommend-action'); + + var keywordID = $closeAction.data('id'); + customConfirm({ + content: '确认将该项目设置为推荐项目吗?', + ok: function(){ + $.ajax({ + url: '/admins/projects/' + keywordID, + method: 'PUT', + dataType: 'json', + data: { + project: { + recommend: true, + recommend_index: 1 + } + }, + success: function() { + showSuccessNotify(); + $closeAction.hide(); + $uncloseAction.show(); + $editAction.show(); + $(".project-item-"+keywordID).children('td').eq(5).text("√") + } + }); + } + }); + }); + + // unclose user + $('.project-list-container').on('click', '.unrecommend-action', function(){ + var $uncloseAction = $(this); + var $closeAction = $uncloseAction.siblings('.recommend-action'); + var $editAction = $closeAction.siblings('.edit-recommend-action'); + + var keywordID = $uncloseAction.data('id'); + customConfirm({ + content: '确认取消该推荐项目吗?', + ok: function () { + $.ajax({ + url: '/admins/projects/' + keywordID, + method: 'PUT', + dataType: 'json', + data: { + project: { + recommend: false, + recommend_index: 0 + } + }, + success: function() { + showSuccessNotify(); + $closeAction.show(); + $uncloseAction.hide(); + $editAction.hide(); + $(".project-item-"+keywordID).children('td').eq(5).text("") + } + }); + } + }) + }); + + + // close user + $('.project-list-container').on('click', '.pinned-action', function(){ + var $closeAction = $(this); + var $uncloseAction = $closeAction.siblings('.unpinned-action'); + + var keywordID = $closeAction.data('id'); + customConfirm({ + content: '确认将该项目设置为精选项目吗?', + ok: function(){ + $.ajax({ + url: '/admins/projects/' + keywordID, + method: 'PUT', + dataType: 'json', + data: { + project: { + is_pinned: true, + } + }, + success: function() { + showSuccessNotify(); + $closeAction.hide(); + $uncloseAction.show(); + $(".project-item-"+keywordID).children('td').eq(4).text("√") + } + }); + } + }); + }); + + // unclose user + $('.project-list-container').on('click', '.unpinned-action', function(){ + var $uncloseAction = $(this); + var $closeAction = $uncloseAction.siblings('.pinned-action'); + + var keywordID = $uncloseAction.data('id'); + customConfirm({ + content: '确认取消该精选项目吗?', + ok: function () { + $.ajax({ + url: '/admins/projects/' + keywordID, + method: 'PUT', + dataType: 'json', + data: { + project: { + is_pinned: false, + } + }, + success: function() { + showSuccessNotify(); + $closeAction.show(); + $uncloseAction.hide(); + $(".project-item-"+keywordID).children('td').eq(4).text("") + } + }); + } + }) + }); +}) \ No newline at end of file diff --git a/app/assets/stylesheets/admin.scss b/app/assets/stylesheets/admin.scss index a401fc379..03c3970a6 100644 --- a/app/assets/stylesheets/admin.scss +++ b/app/assets/stylesheets/admin.scss @@ -58,3 +58,149 @@ input.form-control { position: absolute; } +.logo-item { + display: flex; + + &-img { + display: block; + width: 80px; + height: 80px; + background: #e9ecef; + } + + &-upload { + cursor: pointer; + position: absolute; + top: 0; + width: 80px; + height: 80px; + background: #e9ecef; + border: 1px solid #ced4da; + + &::before { + content: ''; + position: absolute; + top: 27px; + left: 39px; + width: 2px; + height: 26px; + background: #495057; + } + + &::after { + content: ''; + position: absolute; + top: 39px; + left: 27px; + width: 26px; + height: 2px; + background: #495057; + } + } + + &-left { + position: relative; + width: 80px; + height: 80px; + + &.has-img { + .logo-item-upload { + display: none; + } + + &:hover { + .logo-item-upload { + display: block; + background: rgba(145, 145, 145, 0.8); + } + } + } + } + + &-right { + display: flex; + flex-direction: column; + justify-content: space-between; + color: #777777; + font-size: 0.8rem; + } + + &-title { + color: #23272B; + font-size: 1rem; + } +} + +.attachment-item { + display: flex; + + &-img { + display: block; + width: 160px; + height: 160px; + background: #e9ecef; + } + + &-upload { + cursor: pointer; + position: absolute; + top: 0; + width: 160px; + height: 160px; + background: #e9ecef; + border: 1px solid #ced4da; + + &::before { + content: ''; + position: absolute; + top: 54px; + left: 78px; + width: 2px; + height: 52px; + background: #495057; + } + + &::after { + content: ''; + position: absolute; + top: 78px; + left: 54px; + width: 52px; + height: 2px; + background: #495057; + } + } + + &-left { + position: relative; + width: 160px; + height: 160px; + + &.has-img { + .attachment-item-upload { + display: none; + } + + &:hover { + .attachment-item-upload { + display: block; + background: rgba(145, 145, 145, 0.8); + } + } + } + } + + &-right { + padding-top: 100px; + display: flex; + flex-direction: column; + justify-content: space-between; + color: #777777; + font-size: 0.8rem; + } + + &-title { + color: #23272B; + font-size: 1rem; + } +} \ No newline at end of file diff --git a/app/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb index 18fa65fbe..70e5b603b 100644 --- a/app/controllers/accounts_controller.rb +++ b/app/controllers/accounts_controller.rb @@ -1,6 +1,5 @@ class AccountsController < ApplicationController - - #skip_before_action :check_account, :only => [:logout] + include ApplicationHelper def index render json: session @@ -9,7 +8,7 @@ class AccountsController < ApplicationController # 其他平台同步注册的用户 def remote_register username = params[:username]&.gsub(/\s+/, "") - tip_exception("无法使用以下关键词:#{username},请重新命名") if ReversedKeyword.is_reversed(username).present? + tip_exception("无法使用以下关键词:#{username},请重新命名") if ReversedKeyword.check_exists?(username) email = params[:email]&.gsub(/\s+/, "") password = params[:password] platform = (params[:platform] || 'forge')&.gsub(/\s+/, "") @@ -109,67 +108,48 @@ class AccountsController < ApplicationController # 用户注册 # 注意:用户注册需要兼顾本地版,本地版是不需要验证码及激活码以及使用授权的,注册完成即可使用 # params[:login] 邮箱或者手机号 + # params[:namespace] 登录名 # params[:code] 验证码 # code_type 1:注册手机验证码 8:邮箱注册验证码 - # 本地forge注册入口 + # 本地forge注册入口需要重新更改逻辑 def register + # type只可能是1或者8 + user = nil begin - # 查询验证码是否正确;type只可能是1或者8 - type = phone_mail_type(params[:login].strip) - # code = params[:code].strip + Register::Form.new(register_params).validate! - if type == 1 - uid_logger("start register by phone: type is #{type}") - pre = 'p' - email = nil - phone = params[:login] - # verifi_code = VerificationCode.where(phone: phone, code: code, code_type: 1).last - # TODO: 暂时限定邮箱注册 - return normal_status(-1, '只支持邮箱注册') - else - uid_logger("start register by email: type is #{type}") - pre = 'm' - email = params[:login] - phone = nil - return normal_status(-1, "该邮箱已注册") if User.exists?(mail: params[:login]) - return normal_status(-1, "邮箱格式错误") unless params[:login] =~ CustomRegexp::EMAIL - # verifi_code = VerificationCode.where(email: email, code: code, code_type: 8).last - end - # uid_logger("start register: verifi_code is #{verifi_code}, code is #{code}, time is #{Time.now.to_i - verifi_code.try(:created_at).to_i}") - # check_code = (verifi_code.try(:code) == code.strip && (Time.now.to_i - verifi_code.created_at.to_i) <= 10*60) - # todo 上线前请删除万能验证码"513231" - return normal_status(-1, "8~16位密码,支持字母数字和符号") unless params[:password] =~ CustomRegexp::PASSWORD + user = Users::RegisterService.call(register_params) + password = register_params[:password].strip - code = generate_identifier User, 8, pre - login = pre + code - - is_admin = !User.exists?(type: 'User') - @user = User.new(admin: is_admin, login: login, mail: email, phone: phone, type: "User") - @user.password = params[:password] - # 现在因为是验证码,所以在注册的时候就可以激活 - @user.activate - # 必须要用save操作,密码的保存是在users中 - - interactor = Gitea::RegisterInteractor.call({username: login, email: email, password: params[:password]}) + # gitea用户注册, email, username, password + interactor = Gitea::RegisterInteractor.call({username: user.login, email: user.mail, password: password}) if interactor.success? gitea_user = interactor.result - result = Gitea::User::GenerateTokenService.new(login, params[:password]).call - @user.gitea_token = result['sha1'] - @user.gitea_uid = gitea_user[:body]['id'] - if @user.save! - # set user for admin role - if @user.admin? - sync_params = { email: @user.mail, admin: true } - Gitea::User::UpdateInteractor.call(@user.login, sync_params) - end - UserExtension.create!(user_id: @user.id) - successful_authentication(@user) - normal_status("注册成功") + result = Gitea::User::GenerateTokenService.call(user.login, password) + user.gitea_token = result['sha1'] + user.gitea_uid = gitea_user[:body]['id'] + if user.save! + UserExtension.create!(user_id: user.id) + successful_authentication(user) + render_ok end else tip_exception(-1, interactor.error) end + rescue Register::BaseForm::EmailError => e + render_result(-2, e.message) + rescue Register::BaseForm::LoginError => e + render_result(-3, e.message) + rescue Register::BaseForm::PhoneError => e + render_result(-4, e.message) + rescue Register::BaseForm::PasswordFormatError => e + render_result(-5, e.message) + rescue Register::BaseForm::PasswordConfirmationError => e + render_result(-7, e.message) + rescue Register::BaseForm::VerifiCodeError => e + render_result(-6, e.message) rescue Exception => e + Gitea::User::DeleteService.call(user.login) unless user.nil? uid_logger_error(e.message) tip_exception(-1, e.message) end @@ -177,7 +157,7 @@ class AccountsController < ApplicationController # 用户登录 def login - Users::LoginForm.new(account_params).validate! + Users::LoginForm.new(login_params).validate! @user = User.try_to_login(params[:login], params[:password]) return normal_status(-2, "错误的账号或密码") if @user.blank? @@ -226,28 +206,27 @@ class AccountsController < ApplicationController # 忘记密码 def reset_password begin - code = params[:code] - login_type = phone_mail_type(params[:login].strip) - # 获取验证码 - if login_type == 1 - phone = params[:login] - verifi_code = VerificationCode.where(phone: phone, code: code, code_type: 2).last - user = User.find_by_phone(phone) - else - email = params[:login] - verifi_code = VerificationCode.where(email: email, code: code, code_type: 3).last - user = User.find_by_mail(email) #这里有问题,应该是为email,而不是mail 6.13-hs - end - return normal_status(-2, "验证码不正确") if verifi_code.try(:code) != code.strip - return normal_status(-2, "验证码已失效") if !verifi_code&.effective? - return normal_status(-1, "8~16位密码,支持字母数字和符号") unless params[:new_password] =~ CustomRegexp::PASSWORD + Accounts::ResetPasswordForm.new(reset_password_params).validate! - user.password, user.password_confirmation = params[:new_password], params[:new_password_confirmation] - ActiveRecord::Base.transaction do - user.save! - LimitForbidControl::UserLogin.new(user).clear - end - sucess_status + user = find_user + return render_error('未找到相关账号') if user.blank? + + user = Accounts::ResetPasswordService.call(user, reset_password_params) + LimitForbidControl::UserLogin.new(user).clear if user.save! + + render_ok + rescue Register::BaseForm::EmailError => e + render_result(-2, e.message) + rescue Register::BaseForm::PhoneError => e + render_result(-4, e.message) + rescue Register::BaseForm::PasswordFormatError => e + render_result(-5, e.message) + rescue Register::BaseForm::PasswordConfirmationError => e + render_result(-7, e.message) + rescue Register::BaseForm::VerifiCodeError => e + render_result(-6, e.message) + rescue ActiveRecord::Rollback => e + render_result(-1, "服务器异常") rescue Exception => e uid_logger_error(e.message) tip_exception(e.message) @@ -304,7 +283,7 @@ class AccountsController < ApplicationController # 发送验证码 # params[:login] 手机号或者邮箱号 - # params[:type]为事件通知类型 1:用户注册注册 2:忘记密码 3: 绑定手机 4: 绑定邮箱, 5: 验收手机号有效 # 如果有新的继续后面加 + # params[:type]为事件通知类型 1:用户注册 2:忘记密码 3: 绑定手机 4: 绑定邮箱, 5: 验收手机号有效 # 如果有新的继续后面加 # 发送验证码:send_type 1:注册手机验证码 2:找回密码手机验证码 3:找回密码邮箱验证码 4:绑定手机 5:绑定邮箱 # 6:手机验证码登录 7:邮箱验证码登录 8:邮箱注册验证码 9: 验收手机号有效 def get_verification_code @@ -318,19 +297,22 @@ class AccountsController < ApplicationController sign = Digest::MD5.hexdigest("#{OPENKEY}#{value}") tip_exception(501, "请求不合理") if sign != params[:smscode] + logger.info "########### 验证码:#{verification_code}" logger.info("########get_verification_code: login_type: #{login_type}, send_type:#{send_type}, ") # 记录验证码 check_verification_code(verification_code, send_type, value) - sucess_status + render_ok end - # 1 手机类型;0 邮箱类型 - # 注意新版的login是自动名生成的 - def phone_mail_type value - value =~ /^1\d{10}$/ ? 1 : 0 + # check user's login or email or phone is used + # params[:value] 手机号或者邮箱号或者登录名 + # params[:type] 为事件类型 1:登录名(login) 2:email(邮箱) 3:phone(手机号) + def check + Register::CheckColumnsForm.new(check_params).validate! + render_ok end - + private # type 事件类型 1:用户注册 2:忘记密码 3: 绑定手机 4: 绑定邮箱, 5: 验证手机号是否有效 # 如果有新的继续后面加 @@ -373,7 +355,25 @@ class AccountsController < ApplicationController params.require(:user).permit(:login, :email, :phone) end - def account_params + def login_params params.require(:account).permit(:login, :password) end + + def check_params + params.permit(:type, :value) + end + + def register_params + params.permit(:login, :namespace, :password, :password_confirmation, :code) + end + + def reset_password_params + params.permit(:login, :password, :password_confirmation, :code) + end + + def find_user + phone_or_mail = strip(reset_password_params[:login]) + User.where("phone = :search OR mail = :search", search: phone_or_mail).last + end + end diff --git a/app/controllers/admins/project_categories_controller.rb b/app/controllers/admins/project_categories_controller.rb index ba83e841d..72cb833fa 100644 --- a/app/controllers/admins/project_categories_controller.rb +++ b/app/controllers/admins/project_categories_controller.rb @@ -22,7 +22,7 @@ class Admins::ProjectCategoriesController < Admins::BaseController max_position_items = ProjectCategory.select(:id, :position).pluck(:position).reject!(&:blank?) max_position = max_position_items.present? ? max_position_items.max.to_i : 0 - @project_category = ProjectCategory.new(name: @name,position: max_position) + @project_category = ProjectCategory.new(name: @name,position: max_position, pinned_index: params[:project_category][:pinned_index].to_i) if @project_category.save redirect_to admins_project_categories_path flash[:success] = '创建成功' @@ -33,17 +33,18 @@ class Admins::ProjectCategoriesController < Admins::BaseController end def update - if @project_category.update_attribute(:name, @name) + if @project_category.update_attributes({name: @name, pinned_index: params[:project_category][:pinned_index].to_i}) + save_image_file(params[:logo], 'logo') redirect_to admins_project_categories_path flash[:success] = '更新成功' else redirect_to admins_project_categories_path - flash[:success] = '更新失败' + flash[:danger] = '更新失败' end end def destroy - if @project_language.destroy + if @project_category.destroy redirect_to admins_project_categories_path flash[:success] = "删除成功" else @@ -80,4 +81,12 @@ class Admins::ProjectCategoriesController < Admins::BaseController flash[:danger] = '分类已存在' end end + + def save_image_file(file, type) + return unless file.present? && file.is_a?(ActionDispatch::Http::UploadedFile) + + file_path = Util::FileManage.source_disk_filename(@project_category, type) + File.delete(file_path) if File.exist?(file_path) # 删除之前的文件 + Util.write_file(file, file_path) + end end \ No newline at end of file diff --git a/app/controllers/admins/projects_controller.rb b/app/controllers/admins/projects_controller.rb index 9e06eb1c9..4175f7250 100644 --- a/app/controllers/admins/projects_controller.rb +++ b/app/controllers/admins/projects_controller.rb @@ -1,4 +1,5 @@ class Admins::ProjectsController < Admins::BaseController + before_action :find_project, only: [:edit, :update] def index sort_by = Project.column_names.include?(params[:sort_by]) ? params[:sort_by] : 'created_on' @@ -8,6 +9,26 @@ class Admins::ProjectsController < Admins::BaseController @projects = paginate projects.includes(:owner, :members, :issues, :versions, :attachments, :project_score) end + def edit ;end + + def update + respond_to do |format| + if @project.update_attributes(project_update_params) + format.html do + redirect_to admins_projects_path + flash[:sucess] = "更新成功" + end + format.js {render_ok} + else + format.html do + redirect_to admins_projects_path + flash[:danger] = "更新失败" + end + format.js {render_js_error} + end + end + end + def destroy project = Project.find_by!(id: params[:id]) ActiveRecord::Base.transaction do @@ -21,4 +42,13 @@ class Admins::ProjectsController < Admins::BaseController redirect_to admins_projects_path flash[:danger] = "删除失败" end + + private + def find_project + @project = Project.find_by_id(params[:id]) + end + + def project_update_params + params.require(:project).permit(:is_pinned, :recommend, :recommend_index) + end end \ No newline at end of file diff --git a/app/controllers/admins/system_notifications_controller.rb b/app/controllers/admins/system_notifications_controller.rb index 0dc7dd2a2..e2081f1a2 100644 --- a/app/controllers/admins/system_notifications_controller.rb +++ b/app/controllers/admins/system_notifications_controller.rb @@ -10,6 +10,10 @@ class Admins::SystemNotificationsController < Admins::BaseController @notifications = paginate(notifications) end + def history + @users = @notification.users + end + def new @notification = SystemNotification.new end diff --git a/app/controllers/admins/topic/activity_forums_controller.rb b/app/controllers/admins/topic/activity_forums_controller.rb new file mode 100644 index 000000000..b027dc003 --- /dev/null +++ b/app/controllers/admins/topic/activity_forums_controller.rb @@ -0,0 +1,57 @@ +class Admins::Topic::ActivityForumsController < Admins::Topic::BaseController + before_action :find_activity_forum, only: [:edit, :update, :destroy] + + def index + q = ::Topic::ActivityForum.ransack(title_cont: params[:search]) + activity_forums = q.result(distinct: true) + @activity_forums = paginate(activity_forums) + end + + def new + @activity_forum = ::Topic::ActivityForum.new + end + + def create + @activity_forum = ::Topic::ActivityForum.new(activity_forum_params) + if @activity_forum.save + redirect_to admins_topic_activity_forums_path + flash[:success] = "新增平台动态成功" + else + redirect_to admins_topic_activity_forums_path + flash[:danger] = "新增平台动态失败" + end + end + + def edit + end + + def update + @activity_forum.attributes = activity_forum_params + if @activity_forum.save + redirect_to admins_topic_activity_forums_path + flash[:success] = "更新平台动态成功" + else + redirect_to admins_topic_activity_forums_path + flash[:danger] = "更新平台动态失败" + end + end + + def destroy + if @activity_forum.destroy + redirect_to admins_topic_activity_forums_path + flash[:success] = "删除平台动态成功" + else + redirect_to admins_topic_activity_forums_path + flash[:danger] = "删除平台动态失败" + end + end + + private + def find_activity_forum + @activity_forum = ::Topic::ActivityForum.find_by_id(params[:id]) + end + + def activity_forum_params + params.require(:topic_activity_forum).permit(:title, :uuid, :url, :order_index) + end +end \ No newline at end of file diff --git a/app/controllers/admins/topic/banners_controller.rb b/app/controllers/admins/topic/banners_controller.rb new file mode 100644 index 000000000..359845806 --- /dev/null +++ b/app/controllers/admins/topic/banners_controller.rb @@ -0,0 +1,57 @@ +class Admins::Topic::BannersController < Admins::Topic::BaseController + before_action :find_banner, only: [:edit, :update, :destroy] + + def index + @banners = paginate(::Topic::Banner) + end + + def new + @banner = ::Topic::Banner.new + end + + def create + @banner = ::Topic::Banner.new(banner_params) + if @banner.save + save_image_file(params[:image], @banner) + redirect_to admins_topic_banners_path + flash[:success] = "新增banner成功" + else + redirect_to admins_topic_banners_path + flash[:danger] = "新增banner失败" + end + end + + def edit + end + + def update + @banner.attributes = banner_params + if @banner.save + save_image_file(params[:image], @banner) + redirect_to admins_topic_banners_path + flash[:success] = "更新banner成功" + else + redirect_to admins_topic_banners_path + flash[:danger] = "更新banner失败" + end + end + + def destroy + if @banner.destroy + redirect_to admins_topic_banners_path + flash[:success] = "删除banner成功" + else + redirect_to admins_topic_banners_path + flash[:danger] = "删除banner失败" + end + end + + private + def find_banner + @banner = ::Topic::Banner.find_by_id(params[:id]) + end + + def banner_params + params.require(:topic_banner).permit(:title, :order_index) + end +end \ No newline at end of file diff --git a/app/controllers/admins/topic/base_controller.rb b/app/controllers/admins/topic/base_controller.rb new file mode 100644 index 000000000..1360232c8 --- /dev/null +++ b/app/controllers/admins/topic/base_controller.rb @@ -0,0 +1,11 @@ +class Admins::Topic::BaseController < Admins::BaseController + + protected + def save_image_file(file, topic) + return unless file.present? && file.is_a?(ActionDispatch::Http::UploadedFile) + + file_path = Util::FileManage.source_disk_filename(topic, 'image') + File.delete(file_path) if File.exist?(file_path) # 删除之前的文件 + Util.write_file(file, file_path) + end +end \ No newline at end of file diff --git a/app/controllers/admins/topic/cards_controller.rb b/app/controllers/admins/topic/cards_controller.rb new file mode 100644 index 000000000..732f17e5b --- /dev/null +++ b/app/controllers/admins/topic/cards_controller.rb @@ -0,0 +1,57 @@ +class Admins::Topic::CardsController < Admins::Topic::BaseController + before_action :find_card, only: [:edit, :update, :destroy] + + def index + q = ::Topic::Card.ransack(title_cont: params[:search]) + cards = q.result(distinct: true) + @cards = paginate(cards) + end + + def new + @card = ::Topic::Card.new + end + + def create + @card = ::Topic::Card.new(card_params) + if @card.save + redirect_to admins_topic_cards_path + flash[:success] = "新增合作单位成功" + else + redirect_to admins_topic_cards_path + flash[:danger] = "新增合作单位失败" + end + end + + def edit + end + + def update + @card.attributes = card_params + if @card.save + redirect_to admins_topic_cards_path + flash[:success] = "更新合作单位成功" + else + redirect_to admins_topic_cards_path + flash[:danger] = "更新合作单位失败" + end + end + + def destroy + if @card.destroy + redirect_to admins_topic_cards_path + flash[:success] = "删除合作单位成功" + else + redirect_to admins_topic_cards_path + flash[:danger] = "删除合作单位失败" + end + end + + private + def find_card + @card = ::Topic::Card.find_by_id(params[:id]) + end + + def card_params + params.require(:topic_card).permit(:title, :url, :order_index) + end +end \ No newline at end of file diff --git a/app/controllers/admins/topic/cooperators_controller.rb b/app/controllers/admins/topic/cooperators_controller.rb new file mode 100644 index 000000000..a1a700cbc --- /dev/null +++ b/app/controllers/admins/topic/cooperators_controller.rb @@ -0,0 +1,57 @@ +class Admins::Topic::CooperatorsController < Admins::Topic::BaseController + before_action :find_cooperator, only: [:edit, :update, :destroy] + + def index + @cooperators = paginate(::Topic::Cooperator) + end + + def new + @cooperator = ::Topic::Cooperator.new + end + + def create + @cooperator = ::Topic::Cooperator.new(cooperator_params) + if @cooperator.save + save_image_file(params[:image], @cooperator) + redirect_to admins_topic_cooperators_path + flash[:success] = "新增合作单位成功" + else + redirect_to admins_topic_cooperators_path + flash[:danger] = "新增合作单位失败" + end + end + + def edit + end + + def update + @cooperator.attributes = cooperator_params + if @cooperator.save + save_image_file(params[:image], @cooperator) + redirect_to admins_topic_cooperators_path + flash[:success] = "更新合作单位成功" + else + redirect_to admins_topic_cooperators_path + flash[:danger] = "更新合作单位失败" + end + end + + def destroy + if @cooperator.destroy + redirect_to admins_topic_cooperators_path + flash[:success] = "删除合作单位成功" + else + redirect_to admins_topic_cooperators_path + flash[:danger] = "删除合作单位失败" + end + end + + private + def find_cooperator + @cooperator = ::Topic::Cooperator.find_by_id(params[:id]) + end + + def cooperator_params + params.require(:topic_cooperator).permit(:title, :url, :order_index) + end +end \ No newline at end of file diff --git a/app/controllers/admins/topic/excellent_projects_controller.rb b/app/controllers/admins/topic/excellent_projects_controller.rb new file mode 100644 index 000000000..b60dac54c --- /dev/null +++ b/app/controllers/admins/topic/excellent_projects_controller.rb @@ -0,0 +1,57 @@ +class Admins::Topic::ExcellentProjectsController < Admins::Topic::BaseController + before_action :find_excellent_project, only: [:edit, :update, :destroy] + + def index + q = ::Topic::ExcellentProject.ransack(title_cont: params[:search]) + excellent_projects = q.result(distinct: true) + @excellent_projects = paginate(excellent_projects) + end + + def new + @excellent_project = ::Topic::ExcellentProject.new + end + + def create + @excellent_project = ::Topic::ExcellentProject.new(excellent_project_params) + if @excellent_project.save + redirect_to admins_topic_excellent_projects_path + flash[:success] = "新增优秀仓库成功" + else + redirect_to admins_topic_excellent_projects_path + flash[:danger] = "新增优秀仓库失败" + end + end + + def edit + end + + def update + @excellent_project.attributes = excellent_project_params + if @excellent_project.save + redirect_to admins_topic_excellent_projects_path + flash[:success] = "更新优秀仓库成功" + else + redirect_to admins_topic_excellent_projects_path + flash[:danger] = "更新优秀仓库失败" + end + end + + def destroy + if @excellent_project.destroy + redirect_to admins_topic_excellent_projects_path + flash[:success] = "删除优秀仓库成功" + else + redirect_to admins_topic_excellent_projects_path + flash[:danger] = "删除优秀仓库失败" + end + end + + private + def find_excellent_project + @excellent_project = ::Topic::ExcellentProject.find_by_id(params[:id]) + end + + def excellent_project_params + params.require(:topic_excellent_project).permit(:title, :uuid, :url, :order_index) + end +end \ No newline at end of file diff --git a/app/controllers/admins/topic/experience_forums_controller.rb b/app/controllers/admins/topic/experience_forums_controller.rb new file mode 100644 index 000000000..420670c1b --- /dev/null +++ b/app/controllers/admins/topic/experience_forums_controller.rb @@ -0,0 +1,57 @@ +class Admins::Topic::ExperienceForumsController < Admins::Topic::BaseController + before_action :find_experience_forum, only: [:edit, :update, :destroy] + + def index + q = ::Topic::ExperienceForum.ransack(title_cont: params[:search]) + experience_forums = q.result(distinct: true) + @experience_forums = paginate(experience_forums) + end + + def new + @experience_forum = ::Topic::ExperienceForum.new + end + + def create + @experience_forum = ::Topic::ExperienceForum.new(experience_forum_params) + if @experience_forum.save + redirect_to admins_topic_experience_forums_path + flash[:success] = "新增经验分享成功" + else + redirect_to admins_topic_experience_forums_path + flash[:danger] = "新增经验分享失败" + end + end + + def edit + end + + def update + @experience_forum.attributes = experience_forum_params + if @experience_forum.save + redirect_to admins_topic_experience_forums_path + flash[:success] = "更新经验分享成功" + else + redirect_to admins_topic_experience_forums_path + flash[:danger] = "更新经验分享失败" + end + end + + def destroy + if @experience_forum.destroy + redirect_to admins_topic_experience_forums_path + flash[:success] = "删除经验分享成功" + else + redirect_to admins_topic_experience_forums_path + flash[:danger] = "删除经验分享失败" + end + end + + private + def find_experience_forum + @experience_forum = ::Topic::ExperienceForum.find_by_id(params[:id]) + end + + def experience_forum_params + params.require(:topic_experience_forum).permit(:title, :uuid, :url, :order_index) + end +end \ No newline at end of file diff --git a/app/controllers/admins/topic/pinned_forums_controller.rb b/app/controllers/admins/topic/pinned_forums_controller.rb new file mode 100644 index 000000000..ac5bf69a7 --- /dev/null +++ b/app/controllers/admins/topic/pinned_forums_controller.rb @@ -0,0 +1,57 @@ +class Admins::Topic::PinnedForumsController < Admins::Topic::BaseController + before_action :find_pinned_forum, only: [:edit, :update, :destroy] + + def index + q = ::Topic::PinnedForum.ransack(title_cont: params[:search]) + pinned_forums = q.result(distinct: true) + @pinned_forums = paginate(pinned_forums) + end + + def new + @pinned_forum = ::Topic::PinnedForum.new + end + + def create + @pinned_forum = ::Topic::PinnedForum.new(pinned_forum_params) + if @pinned_forum.save + redirect_to admins_topic_pinned_forums_path + flash[:success] = "新增精选文章成功" + else + redirect_to admins_topic_pinned_forums_path + flash[:danger] = "新增精选文章失败" + end + end + + def edit + end + + def update + @pinned_forum.attributes = pinned_forum_params + if @pinned_forum.save + redirect_to admins_topic_pinned_forums_path + flash[:success] = "更新精选文章成功" + else + redirect_to admins_topic_pinned_forums_path + flash[:danger] = "更新精选文章失败" + end + end + + def destroy + if @pinned_forum.destroy + redirect_to admins_topic_pinned_forums_path + flash[:success] = "删除精选文章成功" + else + redirect_to admins_topic_pinned_forums_path + flash[:danger] = "删除精选文章失败" + end + end + + private + def find_pinned_forum + @pinned_forum = ::Topic::PinnedForum.find_by_id(params[:id]) + end + + def pinned_forum_params + params.require(:topic_pinned_forum).permit(:title, :uuid, :url, :order_index) + end +end \ No newline at end of file diff --git a/app/controllers/admins/users_controller.rb b/app/controllers/admins/users_controller.rb index 98f0a6bfb..07ea8261e 100644 --- a/app/controllers/admins/users_controller.rb +++ b/app/controllers/admins/users_controller.rb @@ -1,4 +1,6 @@ class Admins::UsersController < Admins::BaseController + before_action :finder_user, except: [:index] + def index params[:sort_by] = params[:sort_by].presence || 'created_on' params[:sort_direction] = params[:sort_direction].presence || 'desc' @@ -8,12 +10,9 @@ class Admins::UsersController < Admins::BaseController end def edit - @user = User.find(params[:id]) end def update - @user = User.find(params[:id]) - Admins::UpdateUserService.call(@user, update_params) flash[:success] = '保存成功' redirect_to edit_admins_user_path(@user) @@ -26,43 +25,47 @@ class Admins::UsersController < Admins::BaseController end def destroy - User.find(params[:id]).destroy! + @user.destroy! + Gitea::User::DeleteService.call(@user.login) render_delete_success end def lock - User.find(params[:id]).lock! + @user.lock! render_ok end def unlock - User.find(params[:id]).activate! + @user.activate! render_ok end def reward_grade - user = User.find(params[:user_id]) return render_unprocessable_entity('金币数量必须大于0') if params[:grade].to_i <= 0 - RewardGradeService.call(user, container_id: user.id, container_type: 'Feedback', score: params[:grade].to_i, not_unique: true) + RewardGradeService.call(@user, container_id: @user.id, container_type: 'Feedback', score: params[:grade].to_i, not_unique: true) - render_ok(grade: user.grade) + render_ok(grade: @user.grade) end def reset_login_times - User.find(params[:id]).reset_login_times! + @user.reset_login_times! render_ok end private + def finder_user + @user = User.find(params[:id]) + end + def update_params params.require(:user).permit(%i[lastname nickname gender identity technical_title student_id is_shixun_marker mail phone location location_city school_id department_id admin business is_test - password professional_certification authentication]) + password professional_certification authentication login]) end end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 8ff81a465..0eaf703e6 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -26,7 +26,8 @@ class ApplicationController < ActionController::Base end DCODES = %W(2 3 4 5 6 7 8 9 a b c f e f g h i j k l m n o p q r s t u v w x y z) - OPENKEY = "79e33abd4b6588941ab7622aed1e67e8" + OPENKEY = Rails.application.config_for(:configuration)['sign_key'] || "79e33abd4b6588941ab7622aed1e67e8" + helper_method :current_user, :base_url @@ -70,49 +71,11 @@ class ApplicationController < ActionController::Base (current_user.professional_certification && (ue.teacher? || ue.professional?)) end - def shixun_marker - unless current_user.is_shixun_marker? || current_user.admin_or_business? - tip_exception(403, "..") - end - end - - # 实训的访问权限 - def shixun_access_allowed - if !current_user.shixun_permission(@shixun) - tip_exception(403, "..") - end - end def admin_or_business? User.current.admin? || User.current.business? end - # 访问课堂时没权限直接弹加入课堂的弹框 :409 - def user_course_identity - @user_course_identity = current_user.course_identity(@course) - if @user_course_identity > Course::STUDENT && @course.is_public == 0 - tip_exception(401, "..") unless User.current.logged? - check_account - tip_exception(@course.excellent ? 410 : 409, "您没有权限进入") - end - if @user_course_identity > Course::CREATOR && @user_course_identity <= Course::STUDENT && @course.tea_id != current_user.id - # 实名认证和职业认证的身份判断 - tip_exception(411, "你的实名认证和职业认证审核未通过") if @course.authentication && - @course.professional_certification && (!current_user.authentication && !current_user.professional_certification) - tip_exception(411, "你的实名认证审核未通过") if @course.authentication && !current_user.authentication - tip_exception(411, "你的职业认证审核未通过") if @course.professional_certification && !current_user.professional_certification - end - uid_logger("###############user_course_identity:#{@user_course_identity}") - end - - # 题库的访问权限 - def bank_visit_auth - tip_exception(-2,"未通过职业认证") if current_user.is_teacher? && !current_user.certification_teacher? && !current_user.admin_or_business? && @bank.user_id != current_user.id && @bank.is_public - tip_exception(403, "无权限") unless @bank.user_id == current_user.id || current_user.admin_or_business? || - (current_user.certification_teacher? && @bank.is_public) - end - - # 判断用户的邮箱或者手机是否可用 # params[:type] 1: 注册;2:忘记密码;3:绑定 def check_mail_and_phone_valid login, type @@ -120,16 +83,16 @@ class ApplicationController < ActionController::Base login =~ /^[a-zA-Z0-9]+([._\\]*[a-zA-Z0-9])$/ tip_exception(-2, "请输入正确的手机号或邮箱") end - # 考虑到安全参数问题,多一次查询,去掉Union - user = User.where(phone: login).first || User.where(mail: login).first - if type.to_i == 1 && !user.nil? + + user_exist = Owner.exists?(phone: login) || Owner.exists?(mail: login) + if user_exist && type.to_i == 1 tip_exception(-2, "该手机号码或邮箱已被注册") - elsif type.to_i == 2 && user.nil? + elsif type.to_i == 2 && !user_exist tip_exception(-2, "该手机号码或邮箱未注册") - elsif type.to_i == 3 && user.present? + elsif type.to_i == 3 && user_exist tip_exception(-2, "该手机号码或邮箱已绑定") end - sucess_status + render_ok end # 发送及记录激活码 @@ -140,7 +103,7 @@ class ApplicationController < ActionController::Base when 1, 2, 4, 9 # 手机类型的发送 sigle_para = {phone: value} - status = Educoder::Sms.send(mobile: value, code: code) + status = Gitlink::Sms.send(mobile: value, code: code) tip_exception(-2, code_msg(status)) if status != 0 when 8, 3, 5 # 邮箱类型的发送 @@ -186,26 +149,6 @@ class ApplicationController < ActionController::Base end end - def find_course - return normal_status(2, '缺少course_id参数!') if params[:course_id].blank? - @course = Course.find(params[:course_id]) - tip_exception(404, "") if @course.is_delete == 1 && !current_user.admin_or_business? - rescue Exception => e - tip_exception(e.message) - end - - def course_manager - return normal_status(403, '只有课堂管理员才有权限') if @user_course_identity > Course::CREATOR - end - - def find_board - return normal_status(2, "缺少board_id参数") if params[:board_id].blank? - @board = Board.find(params[:board_id]) - rescue Exception => e - uid_logger_error(e.message) - tip_exception(e.message) - end - def validate_type(object_type) normal_status(2, "参数") if params.has_key?(:sort_type) && !SORT_TYPE.include?(params[:sort_type].strip) end @@ -215,21 +158,6 @@ class ApplicationController < ActionController::Base @page_size = params[:page_size] || 15 end - # 课堂教师权限 - def teacher_allowed - logger.info("#####identity: #{current_user.course_identity(@course)}") - unless current_user.course_identity(@course) < Course::STUDENT - normal_status(403, "") - end - end - - # 课堂教师、课堂管理员、超级管理员的权限(不包含助教) - def teacher_or_admin_allowed - unless current_user.course_identity(@course) < Course::ASSISTANT_PROFESSOR - normal_status(403, "") - end - end - def require_admin normal_status(403, "") unless User.current.admin? end @@ -256,7 +184,7 @@ class ApplicationController < ActionController::Base # 异常提醒 def tip_exception(status = -1, message) - raise Educoder::TipException.new(status, message) + raise Gitlink::TipException.new(status, message) end def missing_template @@ -265,7 +193,7 @@ class ApplicationController < ActionController::Base # 弹框提醒 def tip_show_exception(status = -2, message) - raise Educoder::TipException.new(status, message) + raise Gitlink::TipException.new(status, message) end def normal_status(status = 0, message) @@ -344,18 +272,18 @@ class ApplicationController < ActionController::Base # 测试版前端需求 logger.info("subdomain:#{request.subdomain}") - if request.subdomain != "www" - if params[:debug] == 'teacher' #todo 为了测试,记得讲debug删除 - User.current = User.find 81403 - elsif params[:debug] == 'student' - User.current = User.find 8686 - elsif params[:debug] == 'admin' - logger.info "@@@@@@@@@@@@@@@@@@@@@@ debug mode....." - user = User.find 36480 - User.current = user - cookies.signed[:user_id] = user.id - end - end + # if request.subdomain != "www" + # if params[:debug] == 'teacher' #todo 为了测试,记得讲debug删除 + # User.current = User.find 81403 + # elsif params[:debug] == 'student' + # User.current = User.find 8686 + # elsif params[:debug] == 'admin' + # logger.info "@@@@@@@@@@@@@@@@@@@@@@ debug mode....." + # user = User.find 36480 + # User.current = user + # cookies.signed[:user_id] = user.id + # end + # end # User.current = User.find 81403 end @@ -408,11 +336,6 @@ class ApplicationController < ActionController::Base @message = message end - # 实训等对应的仓库地址 - def repo_ip_url(repo_path) - "#{edu_setting('git_address_ip')}/#{repo_path}" - end - def repo_url(repo_path) "#{edu_setting('git_address_domain')}/#{repo_path}" end @@ -445,7 +368,7 @@ class ApplicationController < ActionController::Base JSON.parse(res) rescue Exception => e uid_logger_error("--uri_exec: exception #{e.message}") - raise Educoder::TipException.new("实训平台繁忙(繁忙等级:84)") + raise Gitlink::TipException.new("实训平台繁忙(繁忙等级:84)") end end @@ -464,7 +387,7 @@ class ApplicationController < ActionController::Base end rescue Exception => e uid_logger("--uri_exec: exception #{e.message}") - raise Educoder::TipException.new(message) + raise Gitlink::TipException.new(message) end end @@ -488,7 +411,7 @@ class ApplicationController < ActionController::Base end rescue Exception => e uid_logger("--uri_exec: exception #{e.message}") - raise Educoder::TipException.new("服务器繁忙") + raise Gitlink::TipException.new("服务器繁忙") end end @@ -660,8 +583,8 @@ class ApplicationController < ActionController::Base # 获取Oauth Client def get_client(site) - client_id = Rails.configuration.educoder['client_id'] - client_secret = Rails.configuration.educoder['client_secret'] + client_id = Rails.configuration.Gitlink['client_id'] + client_secret = Rails.configuration.Gitlink['client_secret'] OAuth2::Client.new(client_id, client_secret, site: site) end @@ -681,7 +604,7 @@ class ApplicationController < ActionController::Base def kaminari_paginate(relation) limit = params[:limit] || params[:per_page] - limit = (limit.to_i.zero? || limit.to_i > 15) ? 15 : limit.to_i + limit = (limit.to_i.zero? || limit.to_i > 20) ? 20 : limit.to_i page = params[:page].to_i.zero? ? 1 : params[:page].to_i relation.page(page).per(limit) @@ -689,7 +612,7 @@ class ApplicationController < ActionController::Base def kaminari_array_paginate(relation) limit = params[:limit] || params[:per_page] - limit = (limit.to_i.zero? || limit.to_i > 15) ? 15 : limit.to_i + limit = (limit.to_i.zero? || limit.to_i > 20) ? 20 : limit.to_i page = params[:page].to_i.zero? ? 1 : params[:page].to_i Kaminari.paginate_array(relation).page(page).per(limit) @@ -814,37 +737,10 @@ class ApplicationController < ActionController::Base render json: exception.tip_json end - def render_parameter_missing - render json: { status: -1, message: '参数缺失' } - end - def set_export_cookies cookies[:fileDownload] = true end - # 149课程的评审用户数据创建(包含创建课堂学生) - def open_class_user - user = User.find_by(login: "OpenClassUser") - unless user - ActiveRecord::Base.transaction do - user_params = {status: 1, login: "OpenClassUser", lastname: "开放课程", - nickname: "开放课程", professional_certification: 1, certification: 1, grade: 0, - password: "12345678", phone: "11122223333", profile_completed: 1} - user = User.create!(user_params) - - UserExtension.create!(user_id: user.id, gender: 0, school_id: 3396, :identity => 1, :student_id => "openclassuser") # 3396 - - subject = Subject.find_by(id: 149) - if subject - subject.courses.each do |course| - CourseMember.create!(course_id: course.id, role: 3, user_id: user.id) if !course.course_members.exists?(user_id: user.id) - end - end - end - end - user - end - # 记录热门搜索关键字 def record_search_keyword keyword = params[:keyword].to_s.strip @@ -854,4 +750,8 @@ class ApplicationController < ActionController::Base HotSearchKeyword.add(keyword) end + def find_atme_receivers + @atme_receivers = User.where(login: params[:receivers_login]) + end + end diff --git a/app/controllers/attachments_controller.rb b/app/controllers/attachments_controller.rb index 1f3bd97f8..de5e0a8c3 100644 --- a/app/controllers/attachments_controller.rb +++ b/app/controllers/attachments_controller.rb @@ -196,7 +196,7 @@ class AttachmentsController < ApplicationController end def file_save_to_ucloud(path, file, content_type) - ufile = Educoder::Ufile.new( + ufile = Gitlink::Ufile.new( ucloud_public_key: edu_setting('public_key'), ucloud_private_key: edu_setting('private_key'), ucloud_public_read: true, diff --git a/app/controllers/concerns/controller_rescue_handler.rb b/app/controllers/concerns/controller_rescue_handler.rb index 6ff15cfbc..acd9aa2ea 100644 --- a/app/controllers/concerns/controller_rescue_handler.rb +++ b/app/controllers/concerns/controller_rescue_handler.rb @@ -20,7 +20,7 @@ module ControllerRescueHandler end # rescue_from ActionView::MissingTemplate, with: :object_not_found # rescue_from ActiveRecord::RecordNotFound, with: :object_not_found - rescue_from Educoder::TipException, with: :tip_show + rescue_from Gitlink::TipException, with: :tip_show rescue_from ::ActionView::MissingTemplate, with: :missing_template rescue_from ActiveRecord::RecordNotFound, with: :object_not_found rescue_from ActionController::ParameterMissing, with: :render_parameter_missing diff --git a/app/controllers/concerns/git_common.rb b/app/controllers/concerns/git_common.rb index eab069b8e..fbda95f55 100644 --- a/app/controllers/concerns/git_common.rb +++ b/app/controllers/concerns/git_common.rb @@ -36,10 +36,10 @@ module GitCommon begin @commits = GitService.commits(repo_path: @repo_path) logger.info("git first commit is #{@commits.try(:first)}") - raise Educoder::TipException.new("请先创建版本库") if @commits.nil? + raise Gitlink::TipException.new("请先创建版本库") if @commits.nil? rescue Exception => e uid_logger_error(e.message) - raise Educoder::TipException.new("提交记录异常") + raise Gitlink::TipException.new("提交记录异常") end end diff --git a/app/controllers/concerns/git_helper.rb b/app/controllers/concerns/git_helper.rb index d8479d458..ede90dc6c 100644 --- a/app/controllers/concerns/git_helper.rb +++ b/app/controllers/concerns/git_helper.rb @@ -34,7 +34,7 @@ module GitHelper rescue Exception => e Rails.logger.error(e.message) - raise Educoder::TipException.new("文档内容获取异常") + raise Gitlink::TipException.new("文档内容获取异常") end end @@ -64,7 +64,7 @@ module GitHelper # 版本库Fork功能 def project_fork(container, original_rep_path, username) - raise Educoder::TipException.new("fork源路径为空,fork失败!") if original_rep_path.blank? + raise Gitlink::TipException.new("fork源路径为空,fork失败!") if original_rep_path.blank? # 将要生成的仓库名字 new_repo_name = "#{username.try(:strip)}/#{container.try(:identifier)}#{ Time.now.strftime("%Y%m%d%H%M%S")}" # uid_logger("start fork container: repo_name is #{new_repo_name}") diff --git a/app/controllers/concerns/render_helper.rb b/app/controllers/concerns/render_helper.rb index fad401539..b54ac90ce 100644 --- a/app/controllers/concerns/render_helper.rb +++ b/app/controllers/concerns/render_helper.rb @@ -28,4 +28,8 @@ module RenderHelper def render_result(status=1, message='success') render json: { status: status, message: message } end + + def render_parameter_missing + render json: { status: -1, message: '参数缺失' } + end end diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb index 446c699e2..45a8530a3 100644 --- a/app/controllers/issues_controller.rb +++ b/app/controllers/issues_controller.rb @@ -9,7 +9,7 @@ class IssuesController < ApplicationController before_action :check_project_public, only: [:index ,:show, :copy, :index_chosen, :close_issue] before_action :set_issue, only: [:edit, :update, :destroy, :show, :copy, :close_issue, :lock_issue] - before_action :check_token_enough, only: [:create, :update] + before_action :check_token_enough, :find_atme_receivers, only: [:create, :update] include ApplicationHelper include TagChosenHelper @@ -142,6 +142,10 @@ class IssuesController < ApplicationController end @issue.project_trends.create(user_id: current_user.id, project_id: @project.id, action_type: "create") + + Rails.logger.info "[ATME] maybe to at such users: #{@atme_receivers.pluck(:login)}" + AtmeService.call(current_user, @atme_receivers, @issue) if @atme_receivers.size > 0 + render json: {status: 0, message: "创建成", id: @issue.id} else normal_status(-1, "创建失败") @@ -244,6 +248,10 @@ class IssuesController < ApplicationController post_to_chain(change_type, change_token.abs, current_user.try(:login)) end @issue.create_journal_detail(change_files, issue_files, issue_file_ids, current_user&.id) if @issue.previous_changes.present? + + Rails.logger.info "[ATME] maybe to at such users: #{@atme_receivers.pluck(:login)}" + AtmeService.call(current_user, @atme_receivers, @issue) if @atme_receivers.size > 0 + normal_status(0, "更新成功") else normal_status(-1, "更新失败") diff --git a/app/controllers/journals_controller.rb b/app/controllers/journals_controller.rb index ab00628d9..8fbe46924 100644 --- a/app/controllers/journals_controller.rb +++ b/app/controllers/journals_controller.rb @@ -1,6 +1,6 @@ class JournalsController < ApplicationController before_action :require_login, except: [:index, :get_children_journals] - before_action :require_profile_completed, only: [:create] + before_action :require_profile_completed, :find_atme_receivers, only: [:create] before_action :set_issue before_action :check_issue_permission before_action :set_journal, only: [:destroy, :edit, :update] @@ -22,32 +22,35 @@ class JournalsController < ApplicationController if notes.blank? normal_status(-1, "评论内容不能为空") else - journal_params = { - journalized_id: @issue.id , - journalized_type: "Issue", - user_id: current_user.id , - notes: notes.to_s.strip, - parent_id: params[:parent_id] - } - journal = Journal.new journal_params - if journal.save - if params[:attachment_ids].present? - params[:attachment_ids].each do |id| - attachment = Attachment.select(:id, :container_id, :container_type)&.find_by_id(id) - unless attachment.blank? - attachment.container = journal - attachment.author_id = current_user.id - attachment.description = "" - attachment.save + ActiveRecord::Base.transaction do + journal_params = { + journalized_id: @issue.id , + journalized_type: "Issue", + user_id: current_user.id , + notes: notes.to_s.strip, + parent_id: params[:parent_id] + } + journal = Journal.new journal_params + if journal.save + if params[:attachment_ids].present? + params[:attachment_ids].each do |id| + attachment = Attachment.select(:id, :container_id, :container_type)&.find_by_id(id) + unless attachment.blank? + attachment.container = journal + attachment.author_id = current_user.id + attachment.description = "" + attachment.save + end end end + Rails.logger.info "[ATME] maybe to at such users: #{@atme_receivers.pluck(:login)}" + AtmeService.call(current_user, @atme_receivers, journal) if @atme_receivers.size > 0 + # @issue.project_trends.create(user_id: current_user.id, project_id: @project.id, action_type: "journal") + render :json => { status: 0, message: "评论成功", id: journal.id} + # normal_status(0, "评论成功") + else + normal_status(-1, "评论失败") end - - # @issue.project_trends.create(user_id: current_user.id, project_id: @project.id, action_type: "journal") - render :json => { status: 0, message: "评论成功", id: journal.id} - # normal_status(0, "评论成功") - else - normal_status(-1, "评论失败") end end end diff --git a/app/controllers/organizations/organizations_controller.rb b/app/controllers/organizations/organizations_controller.rb index 218bc872d..b73d1efac 100644 --- a/app/controllers/organizations/organizations_controller.rb +++ b/app/controllers/organizations/organizations_controller.rb @@ -22,11 +22,12 @@ class Organizations::OrganizationsController < Organizations::BaseController @can_create_project = @organization.can_create_project?(current_user.id) @is_admin = can_edit_org? @is_member = @organization.is_member?(current_user.id) + Cache::V2::OwnerCommonService.new(@organization.id).read end def create ActiveRecord::Base.transaction do - tip_exception("无法使用以下关键词:#{organization_params[:name]},请重新命名") if ReversedKeyword.is_reversed(organization_params[:name]).present? + tip_exception("无法使用以下关键词:#{organization_params[:name]},请重新命名") if ReversedKeyword.check_exists?(organization_params[:name]) Organizations::CreateForm.new(organization_params).validate! @organization = Organizations::CreateService.call(current_user, organization_params) Util.write_file(@image, avatar_path(@organization)) if params[:image].present? @@ -68,8 +69,7 @@ class Organizations::OrganizationsController < Organizations::BaseController def recommend recommend = %W(xuos Huawei_Technology openatom_foundation pkecosystem TensorLayer) - @organizations = Organization.with_visibility(%w(common)) - .where(login: recommend).select(:id, :login, :firstname, :lastname, :nickname) + @organizations = Organization.includes(:organization_extension).where(organization_extensions: {recommend: true}).to_a.each_slice(group_size).to_a end private @@ -80,6 +80,10 @@ class Organizations::OrganizationsController < Organizations::BaseController :max_repo_creation, :nickname) end + def group_size + params.fetch(:group_size, 4).to_i + end + def password params.fetch(:password, "") end diff --git a/app/controllers/project_categories_controller.rb b/app/controllers/project_categories_controller.rb index 106ff7f22..67a040fef 100644 --- a/app/controllers/project_categories_controller.rb +++ b/app/controllers/project_categories_controller.rb @@ -5,6 +5,10 @@ class ProjectCategoriesController < ApplicationController @project_categories = q.result(distinct: true) end + def pinned_index + @project_categories = ProjectCategory.where.not(pinned_index: 0).order(pinned_index: :desc) + end + def group_list @project_categories = ProjectCategory.where('projects_count > 0').order(projects_count: :desc) # projects = Project.no_anomory_projects.visible diff --git a/app/controllers/project_rank_controller.rb b/app/controllers/project_rank_controller.rb new file mode 100644 index 000000000..7bd62987e --- /dev/null +++ b/app/controllers/project_rank_controller.rb @@ -0,0 +1,26 @@ +class ProjectRankController < ApplicationController + # 根据时间获取热门项目 + def index + $redis_cache.zunionstore("recent-days-project-rank", get_timeable_key_names) + deleted_data = $redis_cache.smembers("v2-project-rank-deleted") + $redis_cache.zrem("recent-days-project-rank", deleted_data) unless deleted_data.blank? + @project_rank = $redis_cache.zrevrange("recent-days-project-rank", 0, 4, withscores: true) + rescue Exception => e + @project_rank = [] + end + + private + # 默认显示7天的 + def time + params.fetch(:time, 7).to_i + end + + def get_timeable_key_names + names_array = [] + (0...time).to_a.each do |i| + date_time_string = (Date.today - i.days).to_s + names_array << "v2-project-rank-#{date_time_string}" + end + names_array + end +end \ No newline at end of file diff --git a/app/controllers/projects/members_controller.rb b/app/controllers/projects/members_controller.rb new file mode 100644 index 000000000..9c78229dd --- /dev/null +++ b/app/controllers/projects/members_controller.rb @@ -0,0 +1,6 @@ +class Projects::MembersController < Projects::BaseController + def index + users = @project.all_collaborators.like(params[:search]).includes(:user_extension) + @users = kaminari_paginate(users) + end +end \ No newline at end of file diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 1c6e9868c..1864c6964 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -4,9 +4,9 @@ class ProjectsController < ApplicationController include ProjectsHelper include Acceleratorable - before_action :require_login, except: %i[index branches branches_slice group_type_list simple show fork_users praise_users watch_users recommend about menu_list] + before_action :require_login, except: %i[index branches branches_slice group_type_list simple show fork_users praise_users watch_users recommend banner_recommend about menu_list] before_action :require_profile_completed, only: [:create, :migrate] - before_action :load_repository, except: %i[index group_type_list migrate create recommend] + before_action :load_repository, except: %i[index group_type_list migrate create recommend banner_recommend] before_action :authorizate_user_can_edit_project!, only: %i[update] before_action :project_public?, only: %i[fork_users praise_users watch_users] @@ -30,8 +30,8 @@ class ProjectsController < ApplicationController def index scope = current_user.logged? ? Projects::ListQuery.call(params, current_user.id) : Projects::ListQuery.call(params) - # @projects = kaminari_paginate(scope) - @projects = paginate scope.includes(:project_category, :project_language, :repository, :project_educoder, :owner, :project_units) + @projects = kaminari_paginate(scope.includes(:project_category, :project_language, :repository, :project_educoder, :owner, :project_units)) + # @projects = paginate scope.includes(:project_category, :project_language, :repository, :project_educoder, :owner, :project_units) category_id = params[:category_id] @total_count = @@ -190,6 +190,8 @@ class ProjectsController < ApplicationController end def simple + # 为了缓存活跃项目的基本信息,后续删除 + Cache::V2::ProjectCommonService.new(@project.id).read json_response(@project, current_user) end @@ -197,6 +199,10 @@ class ProjectsController < ApplicationController @projects = Project.recommend.includes(:repository, :project_category, :owner).order(visits: :desc) end + def banner_recommend + @projects = Project.recommend.where.not(recommend_index: 0).includes(:project_category, :owner, :project_language).order(recommend_index: :desc) + end + def about @project_detail = @project.project_detail @attachments = Array(@project_detail&.attachments) if request.get? diff --git a/app/controllers/pull_requests_controller.rb b/app/controllers/pull_requests_controller.rb index 342f063d2..675c6523b 100644 --- a/app/controllers/pull_requests_controller.rb +++ b/app/controllers/pull_requests_controller.rb @@ -5,6 +5,7 @@ class PullRequestsController < ApplicationController before_action :check_menu_authorize before_action :find_pull_request, except: [:index, :new, :create, :check_can_merge,:get_branches,:create_merge_infos, :files, :commits] before_action :load_pull_request, only: [:files, :commits] + before_action :find_atme_receivers, only: [:create, :update] include TagChosenHelper include ApplicationHelper @@ -61,6 +62,8 @@ class PullRequestsController < ApplicationController @pull_request.bind_gitea_pull_request!(@gitea_pull_request[:body]["number"], @gitea_pull_request[:body]["id"]) SendTemplateMessageJob.perform_later('PullRequestAssigned', current_user.id, @pull_request&.id) if Site.has_notice_menu? SendTemplateMessageJob.perform_later('ProjectPullRequest', current_user.id, @pull_request&.id) if Site.has_notice_menu? + Rails.logger.info "[ATME] maybe to at such users: #{@atme_receivers.pluck(:login)}" + AtmeService.call(current_user, @atme_receivers, @pull_request) if @atme_receivers.size > 0 else render_error("create pull request error: #{@gitea_pull_request[:status]}") raise ActiveRecord::Rollback @@ -106,6 +109,8 @@ class PullRequestsController < ApplicationController if params[:status_id].to_i == 5 @issue.issue_times.update_all(end_time: Time.now) end + Rails.logger.info "[ATME] maybe to at such users: #{@atme_receivers.pluck(:login)}" + AtmeService.call(current_user, @atme_receivers, @pull_request) if @atme_receivers.size > 0 normal_status(0, "PullRequest更新成功") else normal_status(-1, "PullRequest更新失败") diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb index f9d949db5..c6e2180c3 100644 --- a/app/controllers/repositories_controller.rb +++ b/app/controllers/repositories_controller.rb @@ -48,7 +48,7 @@ class RepositoriesController < ApplicationController def entries @project.increment!(:visits) - + CacheAsyncSetJob.perform_later("project_common_service", {visits: 1}, @project.id) if @project.educoder? @entries = Educoder::Repository::Entries::ListService.call(@project&.project_educoder.repo_name) else diff --git a/app/controllers/topics_controller.rb b/app/controllers/topics_controller.rb new file mode 100644 index 000000000..207b45870 --- /dev/null +++ b/app/controllers/topics_controller.rb @@ -0,0 +1,9 @@ +class TopicsController < ApplicationController + + def index + return render_not_found("请输入正确的数据类型") unless params[:topic_type].present? + scope = Topic.with_single_type(params[:topic_type]) + @topics = kaminari_paginate(scope) + end + +end \ No newline at end of file diff --git a/app/controllers/user_rank_controller.rb b/app/controllers/user_rank_controller.rb new file mode 100644 index 000000000..dddca485c --- /dev/null +++ b/app/controllers/user_rank_controller.rb @@ -0,0 +1,24 @@ +class UserRankController < ApplicationController + # 根据时间获取热门开发者 + def index + $redis_cache.zunionstore("recent-days-user-rank", get_timeable_key_names) + @user_rank = $redis_cache.zrevrange("recent-days-user-rank", 0, 3, withscores: true) + rescue Exception => e + @user_rank = [] + end + + private + # 默认显示7天的 + def time + params.fetch(:time, 7).to_i + end + + def get_timeable_key_names + names_array = [] + (0...time).to_a.each do |i| + date_time_string = (Date.today - i.days).to_s + names_array << "v2-user-rank-#{date_time_string}" + end + names_array + end +end \ No newline at end of file diff --git a/app/controllers/users/statistics_controller.rb b/app/controllers/users/statistics_controller.rb index 592a8be94..dffd3f607 100644 --- a/app/controllers/users/statistics_controller.rb +++ b/app/controllers/users/statistics_controller.rb @@ -188,30 +188,32 @@ class Users::StatisticsController < Users::BaseController @project_languages_count = time_filter(Project.where(user_id: observed_user.id), 'created_on').joins(:project_language).group("project_languages.name").count @platform_project_languages_count = time_filter(Project, 'created_on').joins(:project_language).group("project_languages.name").count else + @platform_result = Cache::V2::PlatformStatisticService.new.read + @user_result = Cache::V2::UserStatisticService.new(observed_user.id).read # 用户被follow数量 - @follow_count = Cache::UserFollowCountService.call(observed_user) - @platform_follow_count = Cache::PlatformFollowCountService.call + @follow_count = @user_result["follow-count"].to_i + @platform_follow_count = @platform_result["follow-count"].to_i # 用户pr数量 - @pullrequest_count = Cache::UserPullrequestCountService.call(observed_user) - @platform_pullrequest_count = Cache::PlatformPullrequestCountService.call + @pullrequest_count = @user_result["pullrequest-count"].to_i + @platform_pullrequest_count = @platform_result["pullrequest-count"].to_i # 用户issue数量 - @issues_count = Cache::UserIssueCountService.call(observed_user) - @platform_issues_count = Cache::PlatformIssueCountService.call + @issues_count = @user_result["issue-count"].to_i + @platform_issues_count = @platform_result["issue-count"].to_i # 用户总项目数 - @project_count = Cache::UserProjectCountService.call(observed_user) - @platform_project_count = Cache::PlatformProjectCountService.call + @project_count = @user_result["project-count"].to_i + @platform_project_count = @platform_result["project-count"].to_i # 用户项目被fork数量 - @fork_count = Cache::UserProjectForkCountService.call(observed_user) - @platform_fork_count = Cache::PlatformProjectForkCountService.call + @fork_count = @user_result["fork-count"].to_i + @platform_fork_count = @platform_result["fork-count"].to_i # 用户项目关注数 - @project_watchers_count = Cache::UserProjectWatchersCountService.call(observed_user) - @platform_project_watchers_count = Cache::PlatformProjectWatchersCountService.call + @project_watchers_count = @user_result["project-watcher-count"].to_i + @platform_project_watchers_count = @platform_result["project-watcher-count"].to_i # 用户项目点赞数 - @project_praises_count = Cache::UserProjectPraisesCountService.call(observed_user) - @platform_project_praises_count = Cache::PlatformProjectPraisesCountService.call + @project_praises_count = @user_result["project-praise-count"].to_i + @platform_project_praises_count = @platform_result["project-praise-count"].to_i # 用户不同语言项目数量 - @project_languages_count = Cache::UserProjectLanguagesCountService.call(observed_user) - @platform_project_languages_count = Cache::PlatformProjectLanguagesCountService.call + @project_languages_count = JSON.parse(@user_result["project-language"]) + @platform_project_languages_count = JSON.parse(@platform_result["project-language"]) end end end \ No newline at end of file diff --git a/app/controllers/users/system_notification_histories_controller.rb b/app/controllers/users/system_notification_histories_controller.rb new file mode 100644 index 000000000..70e91fbb9 --- /dev/null +++ b/app/controllers/users/system_notification_histories_controller.rb @@ -0,0 +1,15 @@ +class Users::SystemNotificationHistoriesController < Users::BaseController + before_action :private_user_resources!, only: [:create] + def create + @history = observed_user.system_notification_histories.new(system_notification_id: params[:system_notification_id]) + if @history.save + render_ok + else + Rails.logger.info @history.errors.as_json + render_error(@history.errors.full_messages.join(",")) + end + rescue Exception => e + uid_logger_error(e.message) + tip_exception(e.message) + end +end \ No newline at end of file diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 0df75a95a..c08655fbc 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -51,6 +51,8 @@ class UsersController < ApplicationController @projects_common_count = user_projects.common.size @projects_mirrior_count = user_projects.mirror.size @projects_sync_mirrior_count = user_projects.sync_mirror.size + # 为了缓存活跃用户的基本信息,后续删除 + Cache::V2::OwnerCommonService.new(@user.id).read end def watch_users diff --git a/app/decorators/course_decorator.rb b/app/decorators/course_decorator.rb deleted file mode 100644 index 9c3340bbf..000000000 --- a/app/decorators/course_decorator.rb +++ /dev/null @@ -1,5 +0,0 @@ -module CourseDecorator - def can_visited? - is_public == 1 || User.current.admin_or_business? || User.current.member_of_course?(self) - end -end \ No newline at end of file diff --git a/app/decorators/ec_course_target_decorator.rb b/app/decorators/ec_course_target_decorator.rb deleted file mode 100644 index 2965a8381..000000000 --- a/app/decorators/ec_course_target_decorator.rb +++ /dev/null @@ -1,2 +0,0 @@ -module EcCourseTargetDecorator -end \ No newline at end of file diff --git a/app/decorators/experience_decorator.rb b/app/decorators/experience_decorator.rb deleted file mode 100644 index f50f479d7..000000000 --- a/app/decorators/experience_decorator.rb +++ /dev/null @@ -1,16 +0,0 @@ -module ExperienceDecorator - def container_type_text - I18n.t("experience.container_type.#{container_type.to_s.underscore}") - end - - def content - case container_type.to_s.underscore - when 'game' then - game = Game.find_by(id: container_id) - game.present? ? "通过实训“#{game.challenge.shixun.name}”的第#{game.challenge.position}关获得的奖励" : '' - when 'shixun_publish' then - shixun = Shixun.find_by(id: container_id) - shixun.present? ? "发布实训“#{shixun.name}”获得的奖励" : '' - end - end -end \ No newline at end of file diff --git a/app/decorators/grade_decorator.rb b/app/decorators/grade_decorator.rb deleted file mode 100644 index 5e2b9deed..000000000 --- a/app/decorators/grade_decorator.rb +++ /dev/null @@ -1,39 +0,0 @@ -module GradeDecorator - def container_type_text - I18n.t("grade.container_type.#{container_type.to_s.underscore}") - end - - def content - case container_type.to_s.underscore - when 'avatar' then '用户首次上传头像获得的奖励' - when 'phone' then '用户首次绑定手机号码获得的奖励' - when 'mail' then '用户首次绑定邮箱获得的奖励' - when 'attendance' then '用户每天签到获得的奖励' - when 'account' then '新用户首次填写基本资料获得的奖励' - when 'memo' then '发布的评论或者帖子获得平台奖励' - when 'discusses' then '发布的评论获得平台奖励' - when 'star' then '用户给实训评分获得的随机奖励' - when 'feedback' then '反馈的问题获得平台奖励' - when 'authentication' then '用户首次完成实名认证获得的奖励' - when 'professional' then '用户首次完成职业认证获得的奖励' - when 'answer' then - game = Game.find_by(id: container_id) - game.present? ? "查看实训“#{game.challenge.shixun.name}”第#{game.challenge.position}关的参考答案消耗的金币" : '' - when 'game' then - game = Game.find_by(id: container_id) - game.present? ? "通过实训“#{game.challenge.shixun.name}”的第#{game.challenge.position}关获得的奖励" : '' - when 'test_set' then - game = Game.find_by(id: container_id) - game.present? ? "查看实训“#{game.challenge.shixun.name}”的第#{game.challenge.position}关的隐藏测试集消耗的金币" : '' - when 'shixun_publish' then - shixun = Shixun.find_by(id: container_id) - shixun.present? ? "发布实训“#{shixun.name}”获得的奖励" : '' - when 'check_ta_answer' then - game = Game.find_by(id: container_id) - game.present? ? "查看实训“#{game.challenge.shixun.name}”第#{game.challenge.position}关的TA人解答消耗的金币" : '' - when 'hack' then - hack = Hack.find_by(id: container_id) - hack.present? ? "完成了题目解答“#{hack.name}”,获得金币奖励:#{hack.score}" : '' - end - end -end \ No newline at end of file diff --git a/app/decorators/library_decorator.rb b/app/decorators/library_decorator.rb deleted file mode 100644 index 2768ad036..000000000 --- a/app/decorators/library_decorator.rb +++ /dev/null @@ -1,5 +0,0 @@ -module LibraryDecorator - extend ApplicationDecorator - - display_time_method :published_at, :created_at, :updated_at -end \ No newline at end of file diff --git a/app/decorators/shixun_decorator.rb b/app/decorators/shixun_decorator.rb deleted file mode 100644 index 4b7a0714a..000000000 --- a/app/decorators/shixun_decorator.rb +++ /dev/null @@ -1,5 +0,0 @@ -module ShixunDecorator - def human_status - I18n.t("shixun.status.#{status}") - end -end diff --git a/app/decorators/subject_decorator.rb b/app/decorators/subject_decorator.rb deleted file mode 100644 index 7ba3277f7..000000000 --- a/app/decorators/subject_decorator.rb +++ /dev/null @@ -1,5 +0,0 @@ -module SubjectDecorator - def can_visited? - published? || User.current.admin? || member?(User.current) - end -end \ No newline at end of file diff --git a/app/decorators/video_decorator.rb b/app/decorators/video_decorator.rb deleted file mode 100644 index 904e78dbb..000000000 --- a/app/decorators/video_decorator.rb +++ /dev/null @@ -1,5 +0,0 @@ -module VideoDecorator - extend ApplicationDecorator - - display_time_method :published_at, :created_at, :updated_at -end \ No newline at end of file diff --git a/public/docs/images/logo-b38b63e6.png b/app/docs/slate/source/images/trustie_logo.png similarity index 100% rename from public/docs/images/logo-b38b63e6.png rename to app/docs/slate/source/images/trustie_logo.png diff --git a/app/docs/slate/source/includes/_users.md b/app/docs/slate/source/includes/_users.md index be2728d0b..218a1a4b7 100644 --- a/app/docs/slate/source/includes/_users.md +++ b/app/docs/slate/source/includes/_users.md @@ -199,6 +199,36 @@ await octokit.request('GET /api/users/:login/messages.json') Success Data. +## 用户阅读系统通知 +用户阅读系统通知 + +> 示例: + +```shell +curl -X POST http://localhost:3000/api/users/yystopf/system_notification_histories.json +``` + +```javascript +await octokit.request('GET /api/users/:login/system_notification_histories.json') +``` + +### HTTP 请求 +`POST /api/users/:login/system_notification_histories.json` + +### 请求字段说明: +参数 | 类型 | 字段说明 +--------- | ----------- | ----------- +|system_notification_id |integer |阅读的系统通知id | + +> 返回的JSON示例: + +```json +{ + "status": 0, + "message": "success" +} +``` + ## 发送消息 发送消息, 目前只支持atme diff --git a/app/forms/accounts/reset_password_form.rb b/app/forms/accounts/reset_password_form.rb new file mode 100644 index 000000000..a451d13c2 --- /dev/null +++ b/app/forms/accounts/reset_password_form.rb @@ -0,0 +1,41 @@ +module Accounts + class ResetPasswordForm < ::BaseForm + # login 邮箱、手机号 + # code 验证码 + # type: 1:手机号注册;2:邮箱注册 + attr_accessor :login, :password, :password_confirmation, :code + + validates :login, :code, :password, :password_confirmation, presence: true, allow_blank: false + validate :check! + + def check! + Rails.logger.info "ResetPasswordForm params: code: #{code} login: #{login} + password: #{password} password_confirmation: #{password_confirmation}" + + type = phone_mail_type(login) + + db_verifi_code = + if type == 1 + check_phone_format(login) + VerificationCode.where(phone: login, code: code, code_type: 2).last + elsif type == 0 + check_email_format(login) + VerificationCode.where(email: login, code: code, code_type: 3).last + end + + check_password(password) + check_password_confirmation(password, password_confirmation) + check_verifi_code(db_verifi_code, code) + end + + def check_phone_format(phone) + phone = strip(phone) + raise LoginError, "登录名格式有误" unless phone =~ CustomRegexp::LOGIN + end + + def check_email_format(mail) + mail = strip(mail) + raise EmailError, "邮件格式有误" unless mail =~ CustomRegexp::EMAIL + end + end +end diff --git a/app/forms/add_school_apply_form.rb b/app/forms/add_school_apply_form.rb deleted file mode 100644 index f98e8b05b..000000000 --- a/app/forms/add_school_apply_form.rb +++ /dev/null @@ -1,10 +0,0 @@ -class AddSchoolApplyForm - include ActiveModel::Model - - attr_accessor :name, :province, :city, :address, :remarks - - validates :name, presence: true - # validates :province, presence: true - # validates :city, presence: true - # validates :address, presence: true -end \ No newline at end of file diff --git a/app/forms/apply_shixun_mirror_form.rb b/app/forms/apply_shixun_mirror_form.rb deleted file mode 100644 index 4f6b738e2..000000000 --- a/app/forms/apply_shixun_mirror_form.rb +++ /dev/null @@ -1,27 +0,0 @@ -class ApplyShixunMirrorForm - include ActiveModel::Model - - attr_accessor :language, :runtime, :run_method, :attachment_id - - validates :language, presence: true - validates :runtime, presence: true - validates :run_method, presence: true - validates :attachment_id, presence: true, numericality: { only_integer: true } - - validate :ensure_attachment_presence - def ensure_attachment_presence - return unless attachment_id - - if attachment.blank? - errors.add(:attachment_id, :attachment_not_exist) - end - end - - def attachment - @attachment ||= Attachment.find_by_id(attachment_id) - end - - def to_json - { language: language, runtime: runtime, run_method: run_method, attachment_id: attachment_id }.to_json - end -end \ No newline at end of file diff --git a/app/forms/base_form.rb b/app/forms/base_form.rb index 71eaee174..46eaa9b58 100644 --- a/app/forms/base_form.rb +++ b/app/forms/base_form.rb @@ -1,6 +1,14 @@ class BaseForm include ActiveModel::Model + Error = Class.new(StandardError) + EmailError = Class.new(Error) + LoginError = Class.new(Error) + PhoneError = Class.new(Error) + PasswordFormatError = Class.new(Error) + VerifiCodeError = Class.new(Error) + PasswordConfirmationError = Class.new(Error) + def check_project_category(project_category_id) unless project_category_id == '' raise "project_category_id参数值无效." if project_category_id && !ProjectCategory.exists?(project_category_id) @@ -23,7 +31,38 @@ class BaseForm end def check_reversed_keyword(repository_name) - raise "项目标识已被占用." if ReversedKeyword.is_reversed(repository_name).exists? + raise "项目标识已被占用." if ReversedKeyword.check_exists?(repository_name) + end + + def check_password(password) + password = strip(password) + raise PasswordFormatError, "密码8~16位密码,支持字母数字和符号" unless password =~ CustomRegexp::PASSWORD + end + + def check_password_confirmation(password, password_confirmation) + password = strip(password) + password_confirmation = strip(password_confirmation) + + raise PasswordFormatError, "确认密码为8~16位密码,支持字母数字和符号" unless password_confirmation =~ CustomRegexp::PASSWORD + raise PasswordConfirmationError, "两次输入的密码不一致" unless password == password_confirmation + end + + def check_verifi_code(verifi_code, code) + code = strip(code) + # return if code == "123123" # TODO 万能验证码,用于测试 + + raise VerifiCodeError, "验证码不正确" if verifi_code&.code != code + raise VerifiCodeError, "验证码已失效" if !verifi_code&.effective? + end + + private + def strip(str) + str.to_s.strip.presence + end + + # 1 手机类型;0 邮箱类型 + # 注意新版的login是自动名生成的 + def phone_mail_type value + value =~ /^1\d{10}$/ ? 1 : 0 end - end diff --git a/app/forms/examination_banks/save_exam_form.rb b/app/forms/examination_banks/save_exam_form.rb deleted file mode 100644 index d066300be..000000000 --- a/app/forms/examination_banks/save_exam_form.rb +++ /dev/null @@ -1,15 +0,0 @@ -class ExaminationBanks::SaveExamForm - include ActiveModel::Model - - attr_accessor :discipline_id, :sub_discipline_id, :difficulty, :name, :duration, :tag_discipline_id - - validates :discipline_id, presence: true - validates :sub_discipline_id, presence: true - validates :difficulty, presence: true, inclusion: {in: 1..3}, numericality: { only_integer: true } - validates :name, presence: true, length: { maximum: 60, too_long: "不能超过60个字符" } - validate :validate_duration - - def validate_duration - raise '时长应为大于0的整数' if duration.present? && duration.to_i < 1 - end -end \ No newline at end of file diff --git a/app/forms/examination_intelligent_settings/save_exam_form.rb b/app/forms/examination_intelligent_settings/save_exam_form.rb deleted file mode 100644 index ec4f17ad7..000000000 --- a/app/forms/examination_intelligent_settings/save_exam_form.rb +++ /dev/null @@ -1,12 +0,0 @@ -class ExaminationIntelligentSettings::SaveExamForm - include ActiveModel::Model - - attr_accessor :name, :duration - - validates :name, presence: true, length: { maximum: 60 } - validate :validate_duration - - def validate_duration - raise '时长应为大于0的整数' if duration.present? && duration.to_i < 1 - end -end \ No newline at end of file diff --git a/app/forms/examination_intelligent_settings/save_exam_setting_form.rb b/app/forms/examination_intelligent_settings/save_exam_setting_form.rb deleted file mode 100644 index bbfb9eee8..000000000 --- a/app/forms/examination_intelligent_settings/save_exam_setting_form.rb +++ /dev/null @@ -1,11 +0,0 @@ -class ExaminationIntelligentSettings::SaveExamSettingForm - include ActiveModel::Model - - attr_accessor :discipline_id, :sub_discipline_id, :source, :difficulty, :tag_discipline_id, :question_settings - - validates :discipline_id, presence: true - validates :sub_discipline_id, presence: true - validates :source, presence: true - validates :difficulty, presence: true, inclusion: {in: 1..3}, numericality: { only_integer: true } - validates :question_settings, presence: true -end \ No newline at end of file diff --git a/app/forms/projects/update_form.rb b/app/forms/projects/update_form.rb index ae93abf30..3048bc079 100644 --- a/app/forms/projects/update_form.rb +++ b/app/forms/projects/update_form.rb @@ -3,11 +3,12 @@ class Projects::UpdateForm < BaseForm validates :name, presence: true validates :name, length: { maximum: 50 } validates :description, length: { maximum: 200 } + validates :identifier, format: { with: CustomRegexp::REPOSITORY_NAME_REGEX, multiline: true, message: "只能含有数字、字母、下划线且不能以下划线开头和结尾" } + validate do check_project_category(project_category_id) check_project_language(project_language_id) - Rails.logger.info project_identifier - Rails.logger.info identifier + check_repository_name(user_id, identifier) unless identifier.blank? || identifier == project_identifier end diff --git a/app/forms/register/base_form.rb b/app/forms/register/base_form.rb new file mode 100644 index 000000000..150fef73a --- /dev/null +++ b/app/forms/register/base_form.rb @@ -0,0 +1,30 @@ +module Register + class BaseForm < ::BaseForm + include ActiveModel::Model + + private + def check_login(login) + login = strip(login) + raise LoginError, "登录名格式有误" unless login =~ CustomRegexp::LOGIN + + login_exist = Owner.exists?(login: login) || ReversedKeyword.check_exists?(login) + raise LoginError, '登录名已被使用' if login_exist + end + + def check_mail(mail) + mail = strip(mail) + raise EmailError, "邮件格式有误" unless mail =~ CustomRegexp::EMAIL + + mail_exist = Owner.exists?(mail: mail) + raise EmailError, '邮箱已被使用' if mail_exist + end + + def check_phone(phone) + phone = strip(phone) + raise PhoneError, "手机号格式有误" unless phone =~ CustomRegexp::PHONE + + phone_exist = Owner.exists?(phone: phone) + raise PhoneError, '手机号已被使用' if phone_exist + end + end +end diff --git a/app/forms/register/check_columns_form.rb b/app/forms/register/check_columns_form.rb new file mode 100644 index 000000000..20c5b1e89 --- /dev/null +++ b/app/forms/register/check_columns_form.rb @@ -0,0 +1,19 @@ +module Register + class CheckColumnsForm < Register::BaseForm + attr_accessor :type, :value + + validates :type, presence: true, numericality: true + validates :value, presence: true + validate :check! + + def check! + # params[:type] 为事件类型 1:登录名(login) 2:email(邮箱) 3:phone(手机号) + case strip(type).to_i + when 1 then check_login(strip(value)) + when 2 then check_mail(strip(value)) + when 3 then check_phone(strip(value)) + else raise("type值无效") + end + end + end +end diff --git a/app/forms/register/form.rb b/app/forms/register/form.rb new file mode 100644 index 000000000..6800fa1de --- /dev/null +++ b/app/forms/register/form.rb @@ -0,0 +1,31 @@ +module Register + class Form < Register::BaseForm + # login 登陆方式,支持邮箱、登陆、手机号等 + # namespace 用户空间地址 + # type: 1:手机号注册;2:邮箱注册 + attr_accessor :login, :namespace, :password, :password_confirmation, :code, :type + + validates :login, :code, :password, :password_confirmation, :namespace, presence: true, allow_blank: false + validate :check! + + def check! + Rails.logger.info "Register::Form params: code: #{code}; login: #{login}; + namespace: #{namespace}; password: #{password}; password_confirmation: #{password_confirmation}" + + type = phone_mail_type(strip(login)) + db_verifi_code = + if type == 1 + check_phone(login) + VerificationCode.where(phone: login, code: code, code_type: 1).last + elsif type == 0 + check_mail(login) + VerificationCode.where(email: login, code: code, code_type: 8).last + end + + check_login(namespace) + check_verifi_code(db_verifi_code, code) + check_password(password) + check_password_confirmation(password, password_confirmation) + end + end +end diff --git a/app/forms/weapps/create_course_form.rb b/app/forms/weapps/create_course_form.rb deleted file mode 100644 index 64d0a506f..000000000 --- a/app/forms/weapps/create_course_form.rb +++ /dev/null @@ -1,20 +0,0 @@ -class Weapps::CreateCourseForm - include ActiveModel::Model - - attr_accessor :course - attr_accessor :name, :course_list_name, :credit, :course_module_types, :end_date - - validates :name, presence: true - validates :course_list_name, presence: true - - validate :course_name_prefix - validate :check_course_modules - - def course_name_prefix - raise '课堂名称应以课程名称开头' unless name.index(course_list_name) && name.index(course_list_name) == 0 - end - - def check_course_modules - raise '请至少添加一个课堂模块' if course_module_types.blank? - end -end \ No newline at end of file diff --git a/app/forms/weapps/update_course_form.rb b/app/forms/weapps/update_course_form.rb deleted file mode 100644 index 60509dd1d..000000000 --- a/app/forms/weapps/update_course_form.rb +++ /dev/null @@ -1,15 +0,0 @@ -class Weapps::UpdateCourseForm - include ActiveModel::Model - - attr_accessor :course - attr_accessor :name, :course_list_name, :credit, :end_date - - validates :name, presence: true - validates :course_list_name, presence: true - - validate :course_name_prefix - - def course_name_prefix - raise '课堂名称应以课程名称开头' unless name.index(course_list_name) && name.index(course_list_name) == 0 - end -end \ No newline at end of file diff --git a/app/helpers/admins/projects_helper.rb b/app/helpers/admins/projects_helper.rb index c6d94c4ca..36d9d6f5a 100644 --- a/app/helpers/admins/projects_helper.rb +++ b/app/helpers/admins/projects_helper.rb @@ -4,7 +4,7 @@ module Admins::ProjectsHelper owner = project.owner if owner.is_a?(User) - link_to(project.owner&.real_name, "/users/#{project&.owner&.login}", target: '_blank') + link_to(project.owner&.real_name, "/#{project&.owner&.login}", target: '_blank') elsif owner.is_a?(Organization) link_to(project.owner&.real_name, "/organize/#{project&.owner&.login}", target: '_blank') else diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index c37fd59da..73b365039 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1,6 +1,6 @@ # 所有的方法请按首字母的顺序依次列出 module ApplicationHelper - include Educoder::I18n + include Gitlink::I18n include GitHelper ONE_MINUTE = 60 * 1000 @@ -442,6 +442,14 @@ module ApplicationHelper User.find_by(gitea_uid: gitea_uid) end + def find_user_in_redis_cache(login, email) + $redis_cache.hgetall("v2-owner-common:#{login}-#{email}") + end + + def find_user_in_redis_cache_by_id(id) + $redis_cache.hgetall("v2-owner-common:#{id}") + end + def render_base64_decoded(str) return nil if str.blank? Base64.decode64 str @@ -455,5 +463,15 @@ module ApplicationHelper sidebar_item(url, "数据统计", icon: 'bar-chart', controller: 'root') end end + + # 1 手机类型;0 邮箱类型 + # 注意新版的login是自动名生成的 + def phone_mail_type value + value =~ /^1\d{10}$/ ? 1 : 0 + end + + def strip(str) + str.to_s.strip.presence + end end diff --git a/app/helpers/avatar_helper.rb b/app/helpers/avatar_helper.rb new file mode 100644 index 000000000..b703e1b4e --- /dev/null +++ b/app/helpers/avatar_helper.rb @@ -0,0 +1,26 @@ +module AvatarHelper + 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 url_to_avatar(source) + if File.exist?(disk_filename(source&.class, source&.id)) + ctime = File.ctime(disk_filename(source.class, source.id)).to_i + if %w(User Organization).include?(source.class.to_s) + File.join("images", relative_path, ["#{source.class}", "#{source.id}"]) + "?t=#{ctime}" + else + File.join("images/avatars", ["#{source.class}", "#{source.id}"]) + "?t=#{ctime}" + end + elsif source.class.to_s == 'User' + source.get_letter_avatar_url + end + end +end \ No newline at end of file diff --git a/app/helpers/boards_helper.rb b/app/helpers/boards_helper.rb deleted file mode 100644 index e66bdaf6b..000000000 --- a/app/helpers/boards_helper.rb +++ /dev/null @@ -1,2 +0,0 @@ -module BoardsHelper -end diff --git a/app/helpers/challenges_helper.rb b/app/helpers/challenges_helper.rb deleted file mode 100644 index fc0101dff..000000000 --- a/app/helpers/challenges_helper.rb +++ /dev/null @@ -1,10 +0,0 @@ -module ChallengesHelper - - def match_begin_symbol str - str.gsub(/\A\r/, "\r\r") - end - - - - -end diff --git a/app/helpers/course_groups_helper.rb b/app/helpers/course_groups_helper.rb deleted file mode 100644 index 061c39dd5..000000000 --- a/app/helpers/course_groups_helper.rb +++ /dev/null @@ -1,2 +0,0 @@ -module CourseGroupsHelper -end diff --git a/app/helpers/course_modules_helper.rb b/app/helpers/course_modules_helper.rb deleted file mode 100644 index 4de7a3826..000000000 --- a/app/helpers/course_modules_helper.rb +++ /dev/null @@ -1,2 +0,0 @@ -module CourseModulesHelper -end diff --git a/app/helpers/course_second_categories_helper.rb b/app/helpers/course_second_categories_helper.rb deleted file mode 100644 index 7ed9aa1e9..000000000 --- a/app/helpers/course_second_categories_helper.rb +++ /dev/null @@ -1,2 +0,0 @@ -module CourseSecondCategoriesHelper -end diff --git a/app/helpers/course_stages_helper.rb b/app/helpers/course_stages_helper.rb deleted file mode 100644 index 7ebb68d9a..000000000 --- a/app/helpers/course_stages_helper.rb +++ /dev/null @@ -1,2 +0,0 @@ -module CourseStagesHelper -end diff --git a/app/helpers/courses_helper.rb b/app/helpers/courses_helper.rb deleted file mode 100644 index f0d58adbb..000000000 --- a/app/helpers/courses_helper.rb +++ /dev/null @@ -1,298 +0,0 @@ -module CoursesHelper - - def member_manager group, teachers - str = "" - members = teachers.select{|teacher| teacher.teacher_course_groups.pluck(:course_group_id).include?(group.id) || teacher.teacher_course_groups.size == 0} - str = members.uniq.size == teachers.size ? "全部教师" : members.map{|member| member.user.real_name}.join("、") - str - # teachers.each do |member| - # if member.teacher_course_groups.exists?(course_group_id: group.id) || member.teacher_course_groups.size == 0 - # str << member.user.real_name - # end - # end - end - - def edit_auth group, teachers - User.current.admin_or_business? || - teachers.select{|teacher| teacher.user_id == User.current.id && - (teacher.teacher_course_groups.pluck(:course_group_id).include?(group.id) || teacher.teacher_course_groups.size == 0)}.size > 0 - end - - # 是否有切换为学生的入口 - def switch_student_role is_teacher, course, user - is_teacher && course.course_members.where(user_id: user.id, role: %i(STUDENT)).exists? - end - - # 是否有切换为教师的入口 - def switch_teacher_role is_student, course, user - is_student && course.course_members.where(user_id: user.id, role: %i(CREATOR PROFESSOR)).exists? - end - - # 是否有切换为助教的入口 - def switch_assistant_role is_student, course, user - is_student && course.course_members.where(user_id: user.id, role: %i(ASSISTANT_PROFESSOR)).exists? - end - - # 课堂结束天数 - def course_end_date end_date - if end_date.present? - curr = Time.new - date = ((Date.parse(end_date.to_s) - Date.parse(curr.to_s)).to_i) - date > 0 ? "#{date}天后" : "" - end - end - - # 课堂模块的url - def module_url mod, course - return nil if mod.blank? or course.blank? - case mod.module_type - when "announcement" - "/courses/#{course.id}/informs" - when "online_learning" - "/courses/#{course.id}/online_learning" - when "shixun_homework" - "/courses/#{course.id}/shixun_homeworks/#{mod.id}" - when "common_homework" - "/courses/#{course.id}/common_homeworks/#{mod.id}" - when "group_homework" - "/courses/#{course.id}/group_homeworks/#{mod.id}" - when "graduation" - "/courses/#{course.id}/graduation_topics/#{mod.id}" - when "exercise" - "/courses/#{course.id}/exercises/#{mod.id}" - when "poll" - "/courses/#{course.id}/polls/#{mod.id}" - when "attachment" - "/courses/#{course.id}/files/#{mod.id}" - when "board" - course_board = course.course_board - "/courses/#{course.id}/boards/#{course_board.id}" - when "course_group" - "/courses/#{course.id}/course_groups" - when "statistics" - "/courses/#{course.id}/statistics" - when "video" - "/courses/#{course.id}/course_videos" - end - end - - # 子目录对应的url - def category_url category, course - case category.category_type - when "shixun_homework" - "/courses/#{course.id}/shixun_homework/#{category.id}" - when "graduation" - if category.name == "毕设选题" - "/courses/#{course.id}/graduation_topics/#{category.course_module_id}" - else - "/courses/#{course.id}/graduation_tasks/#{category.course_module_id}" - end - when "attachment" - "/courses/#{course.id}/file/#{category.id}" - end - end - - # 子目录下的任务数 - def category_task_count course, category, user - case category.category_type - when "shixun_homework" - get_homework_commons_count(course, 4, category.id) - when "graduation" - if category.name == "毕设选题" - course.graduation_topics_count - else - course.graduation_tasks_count - end - when "attachment" - get_attachment_count(course, category.id) - end - end - - # 课堂模块的任务数 - def course_task_count(course, module_type) - case module_type - when "shixun_homework" - get_homework_commons_count(course, 4, 0) - when "common_homework" - get_homework_commons_count(course, 1, 0) - when "group_homework" - get_homework_commons_count(course, 3, 0) - when "graduation" - 0 - when "exercise" - course.exercises_count - when "poll" - course.polls_count - when "attachment" - get_attachment_count(course, 0) - when "board" - course_board = course.course_board - course_board.present? ? course_board.messages.size : 0 - when "course_group" - course.course_groups_count - when "announcement" - course.informs.count - when "online_learning" - course.shixuns.count - when "video" - course.course_videos.count + course.live_links.count - end - end - - # 当前用户可见的课堂作业,type指定作业类型, category_id指定二级目录 - def visible_homework course, user, type, category_id=0 - if user.teacher_of_course?(course) - homeworks = course.homework_commons.where("homework_type = #{type} and course_second_category_id = #{category_id}") - elsif user.member_of_course?(course) - member = course.course_members.find_by(user_id: user.id, role: 4) - if member.try(:course_group_id).to_i == 0 - homeworks = course.homework_commons.where("homework_commons.homework_type = #{type} and publish_time <= '#{Time.now}' - and unified_setting = 1 and course_second_category_id = #{category_id}") - else - not_homework_ids = course.homework_group_settings.where("course_group_id = #{member.try(:course_group_id)} and - (publish_time > '#{Time.now}' or publish_time is null)").pluck(:homework_common_id) - # not_homework_ids = not_homework_ids.blank? ? "(-1)" : "(" + not_homework_ids.map(&:homework_common_id).join(",") + ")" - homeworks = course.homework_commons.where.not(id: not_homework_ids).where("homework_commons.homework_type = #{type} and publish_time <= '#{Time.now}' - and course_second_category_id = #{category_id}") - end - else - homeworks = course.homework_commons.where("homework_type = #{type} and publish_time <= '#{Time.now}' and unified_setting = 1 - and course_second_category_id = #{category_id}") - end - homeworks - end - - # 当前用户可见的课堂试卷 - def visible_exercise course, user - if user.teacher_of_course?(course) - exercises = course.exercises - elsif user.member_of_course?(course) - member = course.course_members.find_by(user_id: user.id, role: 4) - if member.try(:course_group_id).to_i == 0 - exercises = course.exercises.where("publish_time <= '#{Time.now}' and unified_setting = 1") - else - not_exercise_ids = course.exercise_group_settings.where("course_group_id = #{member.try(:course_group_id)} and - (publish_time > '#{Time.now}' or publish_time is null)").pluck(:exercise_id) - exercises = course.exercises.where.not(id: not_exercise_ids).where("publish_time <= '#{Time.now}'") - end - else - exercises = course.exercises.where("publish_time <= '#{Time.now}' and unified_setting = 1") - end - exercises - end - - # 当前用户可见的课堂问卷 - def visible_poll course, user - if user.teacher_of_course?(course) - polls = course.polls - elsif user.member_of_course?(course) - member = course.course_members.find_by(user_id: user.id, role: 4) - if member.try(:course_group_id).to_i == 0 - polls = course.polls.where("publish_time <= '#{Time.now}' and unified_setting = 1") - else - not_poll_ids = course.poll_group_settings.where("course_group_id = #{member.try(:course_group_id)} and - (publish_time > '#{Time.now}' or publish_time is null)").pluck(:poll_id) - polls = course.polls.where.not(id: not_poll_ids).where("publish_time <= '#{Time.now}'") - end - else - polls = course.polls.where("publish_time <= '#{Time.now}' and unified_setting = 1") - end - polls - end - - # 当前用户可见的课堂资源,category_id指定资源的目录 - def visible_attachment course, user, category_id=0 - result = [] - course.attachments.where(course_second_category_id: category_id).each do |attachment| - if attachment.unified_setting - if attachment.is_public == 1 && attachment.is_publish == 1 || user == attachment.author || user.teacher_of_course?(course) || (user.member_of_course?(course) && attachment.is_publish == 1) - result << attachment - end - else - if attachment.is_public == 1 && attachment.is_publish == 1 && !user.member_of_course?(course) || user == attachment.author || user.teacher_of_course?(course) - result << attachment - elsif user.member_of_course?(course) && attachment.is_publish == 1 - member = course.course_members.find_by(user_id: user.id, role: 4) - if member.try(:course_group_id).to_i == 0 && attachment.unified_setting - result << attachment - elsif attachment.attachment_group_settings.where("course_group_id = #{member.try(:course_group_id)} and publish_time > '#{Time.now}'").count == 0 - result << attachment - end - end - end - end - result - end - - # 获取课堂的资源数 - def get_attachment_count(course, category_id) - category_id.to_i == 0 ? course.attachments.size : course.attachments.where(course_second_category_id: category_id).size - end - - # 获取课堂的作业数 - def get_homework_commons_count(course, type, category_id) - category_id == 0 ? HomeworkCommon.where(course_id: course.id, homework_type: type).size : - HomeworkCommon.where(course_id: course.id, homework_type: type, course_second_category_id: category_id).size - end - - - # 获取课堂的任务数(作业数+试卷数+问卷数) - def get_tasks_count(course) - course.homework_commons_count + course.exercises_count + course.polls_count - end - - # 当前用户可见的毕设任务 - def visible_graduation_task course, user - if user.teacher_of_course?(course) - tasks = course.graduation_tasks - else - tasks = course.graduation_tasks.where("publish_time <= '#{Time.now}'") - end - tasks - end - - # 分班情况 - def course_group_info course, user_id - course_group_ids = course.group_course_power(user_id) - course_groups = - if course_group_ids.present? - course.course_groups.where(id: course_group_ids).includes(:course_members) - else - course.course_groups.includes(:course_members) - end - group_info = [] - if !course_groups.blank? - course_groups.each do |group| - group_info << {course_group_id: group.id, group_group_name: group.name, count: group.course_members_count} - end - - none_group_count = course.students.where(course_group_id: 0).size - group_info << {course_group_id: 0, group_group_name: "未分班", count: none_group_count} if none_group_count > 0 && !course_group_ids.present? - end - - return group_info - end - - def left_group_info course - group_info = [] - if course.course_groups_count > 0 - none_group_count = course.students.where(course_group_id: 0).size - group_info << {category_id: 0, category_name: "未分班", position: course.course_groups.pluck(:position).max.to_i + 1, - category_count: none_group_count, category_type: false, - second_category_url: "/courses/#{@course.id}/course_groups/0"} - course.course_groups.each do |course_group| - group_info << {category_id: course_group.id, category_name: course_group.name, position: course_group.position, - category_count: course_group.course_members_count, category_type: false, - second_category_url: "/courses/#{@course.id}/course_groups/#{course_group.id}"} - end - end - group_info - end - - def last_subject_shixun course, myshixuns - myshixun = myshixuns.sort{|x,y| y[:updated_at] <=> x[:updated_at] }.first - return "" unless myshixun - stage_shixun = course.course_stage_shixuns.where(shixun_id: myshixun.shixun_id).take - progress = stage_shixun&.course_stage&.position.to_s + "-" + stage_shixun&.position.to_s + " " + myshixun.shixun&.name - end -end diff --git a/app/helpers/discusses_helper.rb b/app/helpers/discusses_helper.rb deleted file mode 100644 index c686fcada..000000000 --- a/app/helpers/discusses_helper.rb +++ /dev/null @@ -1,2 +0,0 @@ -module DiscussesHelper -end diff --git a/app/helpers/edu_datas_helper.rb b/app/helpers/edu_datas_helper.rb deleted file mode 100644 index 1a8584d15..000000000 --- a/app/helpers/edu_datas_helper.rb +++ /dev/null @@ -1,2 +0,0 @@ -module EduDatasHelper -end diff --git a/app/helpers/graduation_tasks_helper.rb b/app/helpers/graduation_tasks_helper.rb deleted file mode 100644 index 2bc059a55..000000000 --- a/app/helpers/graduation_tasks_helper.rb +++ /dev/null @@ -1,150 +0,0 @@ -module GraduationTasksHelper - include CoursesHelper - # 教师评阅 - def teacher_comment task, user_id - [{ id: 0 ,name: "未评", count: task.uncomment_count(user_id)}, {id: 1, name: "已评", count: task.comment_count(user_id)}] - end - - # 作品状态 - def task_status task, user_id - [{id: 0, name: "未提交", count: task.unfinished_count(user_id)}, - {id: 1, name: "按时提交", count: task.finished_count(user_id)}, - {id: 2, name: "延时提交", count: task.delay_finished_count(user_id)}] - end - - # 交叉评阅 - def cross_comment task, user_id - if task.cross_comment && task.status >= 3 - [{id: 1, name: "只看我的交叉评阅", count: task.graduation_work_comment_assignations.myself(user_id).count}] - else - [] - end - end - - def task_curr_status task, course - result = {} - status = [] - time = "" - - if course.try(:is_end) - status << "已结束" - time = course.end_date.present? ? course.end_date.strftime("%Y-%m-%d") : "" - else - if task.status > 1 && task.allow_late && (task.late_time.nil? || task.late_time > Time.now) - status << "补交中" - end - - case task.status - when 0 - status << "未发布" - time = task.publish_time.present? ? "将于 #{format_time(task.publish_time)} 发布" : "创建于#{time_from_now(task.created_at)}" - when 1 - if task.end_time && task.end_time >= Time.now - status << "提交中" - time = how_much_time(task.end_time) - end - when 2 - status << "评阅中" - time = task.comment_time.present? ? how_much_time(task.comment_time) : course.end_date.present? ? how_much_time(course.end_date.end_of_day) : "" - when 3 - status << "交叉评阅中" - time = course.end_date.present? ? how_much_time(course.end_date.end_of_day) : "" - end - - status << "未开启补交" if (!task.allow_late && task.status != 0) #6.11 -hs 新增status不等于0 - - # 如果还在补交阶段则显示补交结束时间 - if task.status > 1 && task.allow_late && task.late_time && task.late_time > Time.now - time = how_much_time(task.late_time) - end - end - - result[:status] = status - result[:time] = time - result - end - - # 作品数统计:type: 1 已提交 0 未提交 - def grduationwork_count task, type - works = task.graduation_works - type == 1 ? works.select{|work| work.work_status != 0}.size : works.select{|work| work.work_status == 0}.size - end - - # 普通/分组 作业作品状态数组 - def graduation_work_status task, user_id, course - status = [] - work = task.graduation_works.find_by(user_id: user_id) - - work = work || GraduationWork.create(graduation_task_id: task.id, user_id: user_id) - late_time = task.late_time || course.end_date - - if course.is_end && work && work.work_status > 0 - status << "查看作品" - elsif !course.is_end - if task.publish_time && task.publish_time < Time.now - # 作业未截止时 - if task.end_time > Time.now - if task.task_type == 2 && task.base_on_project - if work.project_id.nil? || work.project_id == 0 - status << "创建项目" - status << "关联项目" - elsif work.work_status == 0 - status << "取消关联" - status << "提交作品" - else - status << "修改作品" - end - else - if work.work_status == 0 - status << "提交作品" - else - status << "修改作品" - end - end - - # 补交阶段 - elsif task.allow_late && (late_time.nil? || late_time > Time.now) - if task.task_type == 2 && task.base_on_project - if work.project_id.nil? || work.project_id == 0 - status << "创建项目" - status << "关联项目" - elsif work.work_status == 0 - status << "取消关联" - status << "补交作品" - else - status << "补交附件" - status << "查看作品" - end - else - if work.work_status == 0 - status << "补交作品" - else - status << "补交附件" - status << "查看作品" - end - end - - # 匿评阶段 - elsif work.work_status != 0 - status << "查看作品" - end - end - end - end - - # 阶段剩余时间 - def task_left_time task - if task.publish_time && task.publish_time < Time.now - if task.end_time > Time.now - status = "剩余提交时间" - time = "#{how_much_time(task.end_time)}" - else - if task.allow_late && task.late_time && task.late_time >= Time.now - status = "剩余补交时间" - time = "#{how_much_time(task.late_time)}" - end - end - end - {status: status, time: time} - end -end diff --git a/app/helpers/graduation_topics_helper.rb b/app/helpers/graduation_topics_helper.rb deleted file mode 100644 index ae15d201e..000000000 --- a/app/helpers/graduation_topics_helper.rb +++ /dev/null @@ -1,30 +0,0 @@ -module GraduationTopicsHelper - - # 课题类型 - def topic_type - [{id: 1, name: "设计"}, {id: 2, name: "论文"}, {id: 3, name: "创作"}] - end - - # 课程来源 - def topic_source - [{id: 1, name: "生产/社会实际"}, {id: 2, name:"结合科研"}, {id: 3, name: "其它"}] - end - - # 课题性质1 - def topic_property_first - [{id: 1, name: "真题"}, {id: 2, name:"模拟题"}] - end - - # 课题性质2 - def topic_property_second - [{id: 1, name: "纵向课题"}, {id: 2, name:"横向课题"}, {id: 3, name: "自选"}] - end - - # 课题重复 - def topic_repeat - [{id: 1, name: "新题"}, {id: 2, name:"往届题,有新要求"}, {id: 3, name: "往届题,无新要求"}] - end - - - -end diff --git a/app/helpers/graduation_works_helper.rb b/app/helpers/graduation_works_helper.rb deleted file mode 100644 index 577efa797..000000000 --- a/app/helpers/graduation_works_helper.rb +++ /dev/null @@ -1,20 +0,0 @@ -module GraduationWorksHelper - include GraduationTasksHelper - - # 作品最终成绩 - # 参数: work作品, current_user用户,course_identity用户在课堂的身份 - def work_final_score work, current_user, course_identity - work_score = - if work.work_score.nil? - "--" - else - if work.check_score_power? current_user, course_identity - format("%.1f", work.work_score < 0 ? 0 : work.work_score.round(1)) - else - "**" - end - end - # work_score 最终成绩; late_penalty 迟交扣分; final_score 最终评分 - {username: work.user.full_name, login: work.user.login, work_score: work_score, final_score: work.final_score} - end -end diff --git a/app/helpers/hack_user_lastest_codes_helper.rb b/app/helpers/hack_user_lastest_codes_helper.rb deleted file mode 100644 index 13350a8f6..000000000 --- a/app/helpers/hack_user_lastest_codes_helper.rb +++ /dev/null @@ -1,2 +0,0 @@ -module HackUserLastestCodesHelper -end diff --git a/app/helpers/hacks_helper.rb b/app/helpers/hacks_helper.rb deleted file mode 100644 index 13f5ac76d..000000000 --- a/app/helpers/hacks_helper.rb +++ /dev/null @@ -1,2 +0,0 @@ -module HacksHelper -end diff --git a/app/helpers/repositories_helper.rb b/app/helpers/repositories_helper.rb index 1096d1d21..cc50c8d66 100644 --- a/app/helpers/repositories_helper.rb +++ b/app/helpers/repositories_helper.rb @@ -35,6 +35,16 @@ module RepositoriesHelper end end + def render_cache_commit_author(author_json) + Rails.logger.info author_json['Email'] + if author_json["name"].present? && author_json["email"].present? + return find_user_in_redis_cache(author_json['name'], author_json['email']) + end + if author_json["Name"].present? && author_json["Email"].present? + return find_user_in_redis_cache(author_json['Name'], author_json['Email']) + end + end + def readme_render_decode64_content(str, path) return nil if str.blank? begin diff --git a/app/helpers/trustie_hacks_helper.rb b/app/helpers/trustie_hacks_helper.rb deleted file mode 100644 index 3ebe3a9cc..000000000 --- a/app/helpers/trustie_hacks_helper.rb +++ /dev/null @@ -1,2 +0,0 @@ -module TrustieHacksHelper -end diff --git a/app/helpers/weapps/courses_helper.rb b/app/helpers/weapps/courses_helper.rb deleted file mode 100644 index 580536ec6..000000000 --- a/app/helpers/weapps/courses_helper.rb +++ /dev/null @@ -1,69 +0,0 @@ -module Weapps::CoursesHelper - require 'chinese_pinyin' - - def teacher_list teachers, user_course_identity - data = [] - teachers.each do |teacher| - if teacher.user.present? - teacher_user = teacher.user - name = teacher_user.real_name - role = teacher.role == "CREATOR" ? "管理员" : teacher.role == "PROFESSOR" ? "教师" : "助教" - member_roles = user_course_identity < Course::ASSISTANT_PROFESSOR ? teacher_user.course_role(teacher.course) : [] - item = {name: name, course_member_id: teacher.id, login: teacher_user.login, user_id: teacher.user_id, role: role, - school: teacher_user.school_name, image_url: url_to_avatar(teacher_user), member_roles: member_roles} - pinyin = Pinyin.t(name.strip, splitter: '') - first_char = pinyin[0] - letter = first_letter first_char - if data.pluck(:letter).include?(letter) - data.select{|a|a[:letter]==letter}.first[:items] << item - else - data << {letter: letter, items: [item]} - end - end - end - # data = data.sort do |a, b| - # [a[:letter]] <=> [b[:letter]] - # end - # data.push(data.shift) if data.select{|a|a[:letter]=='#'}.first.present? # '#'排在最后 - return data - end - - - def student_list students, excellent, user_course_identity - data = [] - students.each do |student| - if student.user.present? - student_user = student.user - name = student_user.real_name - phone = excellent ? "" : student_user.hidden_phone - member_roles = user_course_identity < Course::ASSISTANT_PROFESSOR ? student_user.course_role(student.course) : [] - item = {name: name, course_member_id: student.id, login: student_user.login, user_id: student.user_id, - student_id: student_user.student_id, image_url: url_to_avatar(student_user), phone: phone, member_roles: member_roles} - pinyin = Pinyin.t(name.strip, splitter: '') - first_char = pinyin[0] - letter = first_letter first_char - if data.pluck(:letter).include?(letter) - data.select{|a|a[:letter]==letter}.first[:items] << item - else - data << {letter: letter, items: [item]} - end - end - end - # data = data.sort do |a, b| - # [a[:letter]] <=> [b[:letter]] - # end - # data.push(data.shift) if data.select{|a|a[:letter]=='#'}.first.present? # '#'排在最后 - return data - end - - def first_letter char - if char.ord >= 97 && char.ord <= 122 - letter = (char.ord - 32).chr.to_s - elsif char.ord >= 65 && char.ord <= 90 - letter = char - else - letter = '#' - end - letter - end -end \ No newline at end of file diff --git a/app/imports/admins/import_course_member_excel.rb b/app/imports/admins/import_course_member_excel.rb deleted file mode 100644 index ddd3b01a1..000000000 --- a/app/imports/admins/import_course_member_excel.rb +++ /dev/null @@ -1,20 +0,0 @@ -class Admins::ImportCourseMemberExcel < BaseImportXlsx - Data = Struct.new(:student_id, :name, :course_id, :role, :course_group_name, :school_id) - - def read_each(&block) - sheet.each_row_streaming(pad_cells: true, offset: 1) do |row| - data = row.map(&method(:cell_value))[0..5] - block.call Data.new(*data) - end - end - - private - - def check_sheet_valid! - raise_import_error('请按照模板格式导入') if sheet.row(1).size != 6 - end - - def cell_value(obj) - obj&.cell_value&.to_s&.strip - end -end diff --git a/app/jobs/batch_publish_video_notify_job.rb b/app/jobs/batch_publish_video_notify_job.rb deleted file mode 100644 index 01390dc2d..000000000 --- a/app/jobs/batch_publish_video_notify_job.rb +++ /dev/null @@ -1,23 +0,0 @@ -# 批量发布视频 消息任务 -class BatchPublishVideoNotifyJob < ApplicationJob - queue_as :notify - - def perform(user_id, video_ids) - user = User.find_by(id: user_id) - return if user.blank? - - attrs = %i[user_id trigger_user_id container_id container_type tiding_type status created_at updated_at] - - same_attrs = { - user_id: 1, - trigger_user_id: user.id, - container_type: 'Video', - tiding_type: 'Apply', status: 0 - } - Tiding.bulk_insert(*attrs) do |worker| - user.videos.where(id: video_ids).each do |video| - worker.add same_attrs.merge(container_id: video.id) - end - end - end -end diff --git a/app/jobs/cache_async_clear_job.rb b/app/jobs/cache_async_clear_job.rb new file mode 100644 index 000000000..651dfaf41 --- /dev/null +++ b/app/jobs/cache_async_clear_job.rb @@ -0,0 +1,12 @@ +class CacheAsyncClearJob < ApplicationJob + queue_as :cache + + def perform(type, id=nil) + case type + when "project_common_service" + Cache::V2::ProjectCommonService.new(id).clear + when "owner_common_service" + Cache::V2::OwnnerCommonService.new(id).clear + end + end +end \ No newline at end of file diff --git a/app/jobs/cache_async_reset_job.rb b/app/jobs/cache_async_reset_job.rb new file mode 100644 index 000000000..0df0f0fd4 --- /dev/null +++ b/app/jobs/cache_async_reset_job.rb @@ -0,0 +1,16 @@ +class CacheAsyncResetJob < ApplicationJob + queue_as :cache + + def perform(type, id=nil) + case type + when "platform_statistic_service" + Cache::V2::PlatformStatisticService.new.reset + when "project_common_service" + Cache::V2::ProjectCommonService.new(id).reset + when "owner_common_service" + Cache::V2::OwnnerCommonService.new(id).reset + when "user_statistic_service" + Cache::V2::UserStatisticService.new(id).reset + end + end +end \ No newline at end of file diff --git a/app/jobs/cache_async_set_job.rb b/app/jobs/cache_async_set_job.rb new file mode 100644 index 000000000..9c7015d42 --- /dev/null +++ b/app/jobs/cache_async_set_job.rb @@ -0,0 +1,16 @@ +class CacheAsyncSetJob < ApplicationJob + queue_as :cache + + def perform(type, params={}, id=nil) + case type + when "platform_statistic_service" + Cache::V2::PlatformStatisticService.new(params).call + when "project_common_service" + Cache::V2::ProjectCommonService.new(id, params).call + when "owner_common_service" + Cache::V2::OwnnerCommonService.new(id, params).call + when "user_statistic_service" + Cache::V2::UserStatisticService.new(id, params).call + end + end +end \ No newline at end of file diff --git a/app/jobs/course_add_student_create_works_job.rb b/app/jobs/course_add_student_create_works_job.rb deleted file mode 100644 index fec28f395..000000000 --- a/app/jobs/course_add_student_create_works_job.rb +++ /dev/null @@ -1,67 +0,0 @@ -# 学生加入课堂时创建相关任务作品 -class CourseAddStudentCreateWorksJob < ApplicationJob - queue_as :default - - def perform(course_id, student_ids) - course = Course.find_by(id: course_id) - return if course.blank? - - # 如果之前存在相关作品,则更新is_delete字段 - student_works = StudentWork.joins(:homework_common).where(user_id: student_ids, homework_commons: {course_id: course.id}) - student_works.update_all(is_delete: 0) - - exercise_users = ExerciseUser.joins(:exercise).where(user_id: student_ids, exercises: {course_id: course.id}) - exercise_users.update_all(is_delete: 0) - - poll_users = PollUser.joins(:poll).where(user_id: student_ids, polls: {course_id: course.id}) - poll_users.update_all(is_delete: 0) - - graduation_works = course.graduation_works.where(user_id: student_ids) - graduation_works.update_all(is_delete: 0) - - attrs = %i[homework_common_id user_id created_at updated_at] - - StudentWork.bulk_insert(*attrs) do |worker| - student_ids.each do |user_id| - same_attrs = {user_id: user_id} - course.homework_commons.where(homework_type: %i[normal group practice]).each do |homework| - next if StudentWork.where(user_id: user_id, homework_common_id: homework.id).any? - worker.add same_attrs.merge(homework_common_id: homework.id) - end - end - end - - attrs = %i[exercise_id user_id created_at updated_at] - ExerciseUser.bulk_insert(*attrs) do |worker| - student_ids.each do |user_id| - same_attrs = {user_id: user_id} - course.exercises.each do |exercise| - next if ExerciseUser.where(user_id: user_id, exercise_id: exercise.id).any? - worker.add same_attrs.merge(exercise_id: exercise.id) - end - end - end - - attrs = %i[poll_id user_id created_at updated_at] - PollUser.bulk_insert(*attrs) do |worker| - student_ids.each do |user_id| - same_attrs = {user_id: user_id} - course.polls.each do |poll| - next if PollUser.where(user_id: user_id, poll_id: poll.id).any? - worker.add same_attrs.merge(poll_id: poll.id) - end - end - end - - attrs = %i[graduation_task_id user_id course_id created_at updated_at] - GraduationWork.bulk_insert(*attrs) do |worker| - student_ids.each do |user_id| - same_attrs = {user_id: user_id, course_id: course.id} - course.graduation_tasks.each do |task| - next if GraduationWork.where(user_id: user_id, graduation_task_id: task.id).any? - worker.add same_attrs.merge(graduation_task_id: task.id) - end - end - end - end -end diff --git a/app/jobs/course_delete_student_delete_works_job.rb b/app/jobs/course_delete_student_delete_works_job.rb deleted file mode 100644 index a84608b2c..000000000 --- a/app/jobs/course_delete_student_delete_works_job.rb +++ /dev/null @@ -1,19 +0,0 @@ -class CourseDeleteStudentDeleteWorksJob < ApplicationJob - queue_as :default - - def perform(course_id, student_ids) - course = Course.find_by(id: course_id) - return if course.blank? - - student_works = StudentWork.joins(:homework_common).where(user_id: student_ids, homework_commons: {course_id: course.id}) - student_works.update_all(is_delete: 1) - - exercise_users = ExerciseUser.joins(:exercise).where(user_id: student_ids, exercises: {course_id: course.id}) - exercise_users.update_all(is_delete: 1) - - poll_users = PollUser.joins(:poll).where(user_id: student_ids, polls: {course_id: course.id}) - poll_users.update_all(is_delete: 1) - - course.graduation_works.where(user_id: student_ids).update_all(is_delete: 1) - end -end diff --git a/app/jobs/course_delete_student_notify_job.rb b/app/jobs/course_delete_student_notify_job.rb deleted file mode 100644 index 898fc97c9..000000000 --- a/app/jobs/course_delete_student_notify_job.rb +++ /dev/null @@ -1,22 +0,0 @@ -# 删除课堂用户 -class CourseDeleteStudentNotifyJob < ApplicationJob - queue_as :notify - - def perform(course_id, student_ids, trigger_user_id) - course = Course.find_by(id: course_id) - return if course.blank? - - attrs = %i[user_id trigger_user_id container_id container_type belong_container_id - belong_container_type tiding_type created_at updated_at] - - same_attrs = { - trigger_user_id: trigger_user_id, container_id: course.id, container_type: 'DeleteCourseMember', - belong_container_id: course.id, belong_container_type: 'Course', tiding_type: 'System' - } - Tiding.bulk_insert(*attrs) do |worker| - student_ids.each do |user_id| - worker.add same_attrs.merge(user_id: user_id) - end - end - end -end diff --git a/app/jobs/create_diff_record_job.rb b/app/jobs/create_diff_record_job.rb deleted file mode 100644 index fbe8cbff2..000000000 --- a/app/jobs/create_diff_record_job.rb +++ /dev/null @@ -1,12 +0,0 @@ -class CreateDiffRecordJob < ApplicationJob - queue_as :default - - def perform(user_id, obj_id, obj_klass, column_name, before, after) - user = User.find_by(id: user_id) - obj = obj_klass.constantize.find_by(id: obj_id) - - return if user.blank? || obj.blank? - - CreateDiffRecordService.call(user, obj, column_name, before, after) - end -end \ No newline at end of file diff --git a/app/jobs/delete_department_notify_job.rb b/app/jobs/delete_department_notify_job.rb deleted file mode 100644 index 1da5e2e85..000000000 --- a/app/jobs/delete_department_notify_job.rb +++ /dev/null @@ -1,21 +0,0 @@ -# 删除部门 消息通知 -class DeleteDepartmentNotifyJob < ApplicationJob - queue_as :notify - - def perform(department_id, operator_id, user_ids) - department = Department.unscoped.find_by(id: department_id) - return if department.blank? || user_ids.blank? - - attrs = %i[ user_id trigger_user_id container_id container_type tiding_type status created_at updated_at] - - same_attrs = { - trigger_user_id: operator_id, container_id: department.id, container_type: 'Department', - status: 4, tiding_type: 'System' - } - Tiding.bulk_insert(*attrs) do |worker| - user_ids.each do |user_id| - worker.add same_attrs.merge(user_id: user_id) - end - end - end -end diff --git a/app/jobs/exercise_publish_notify_job.rb b/app/jobs/exercise_publish_notify_job.rb deleted file mode 100644 index 9c43b1978..000000000 --- a/app/jobs/exercise_publish_notify_job.rb +++ /dev/null @@ -1,44 +0,0 @@ -# 试卷发布 消息通知 -class ExercisePublishNotifyJob < ApplicationJob - queue_as :notify - - def perform(exercise_id, group_ids) - exercise = Exercise.find_by(id: exercise_id) - return if exercise.blank? - user = exercise.user - course = exercise.course - - if group_ids.present? - students = course.students.where(course_group_id: group_ids) - subquery = course.teacher_course_groups.where(course_group_id: group_ids).select(:course_member_id) - teachers = course.teachers.where(id: subquery) - else - students = course.students - teachers = course.teachers - end - - attrs = %i[ - user_id trigger_user_id container_id container_type parent_container_id parent_container_type - belong_container_id belong_container_type viewed tiding_type created_at updated_at - ] - - same_attrs = { - trigger_user_id: user.id, container_id: exercise.id, container_type: 'Exercise', - parent_container_id: exercise.id, parent_container_type: 'ExercisePublish', - belong_container_id: exercise.course_id, belong_container_type: 'Course', - viewed: 0, tiding_type: 'Exercise' - } - Tiding.bulk_insert(*attrs) do |worker| - teacher_ids = teachers.pluck(:user_id) - unless exercise.tidings.exists?(parent_container_type: 'ExercisePublish', user_id: teacher_ids) - teacher_ids.each do |user_id| - worker.add same_attrs.merge(user_id: user_id) - end - end - - students.pluck(:user_id).each do |user_id| - worker.add same_attrs.merge(user_id: user_id) - end - end - end -end diff --git a/app/jobs/get_aliyun_video_info_job.rb b/app/jobs/get_aliyun_video_info_job.rb deleted file mode 100644 index d93186458..000000000 --- a/app/jobs/get_aliyun_video_info_job.rb +++ /dev/null @@ -1,17 +0,0 @@ -# 获取阿里云视频信息 -class GetAliyunVideoInfoJob < ApplicationJob - queue_as :default - - def perform(vod_video_id) - video = Video.find_by(uuid: vod_video_id) - return if video.blank? || video.vod_uploading? - - result = AliyunVod::Service.get_play_info(video.uuid) - cover_url = result.dig('VideoBase', 'CoverURL') - file_url = (result.dig('PlayInfoList', 'PlayInfo') || []).first&.[]('PlayURL') - - video.cover_url = cover_url if cover_url.present? && video.cover_url.blank? - video.file_url = file_url if file_url.present? - video.save! - end -end \ No newline at end of file diff --git a/app/jobs/graduation_task_cross_comment_job.rb b/app/jobs/graduation_task_cross_comment_job.rb deleted file mode 100644 index a2d181b50..000000000 --- a/app/jobs/graduation_task_cross_comment_job.rb +++ /dev/null @@ -1,22 +0,0 @@ -# 毕设任务的交叉评阅分配 -class GraduationTaskCrossCommentJob < ApplicationJob - queue_as :default - - def perform(graduation_task_id) - task = GraduationTask.find_by(id: graduation_task_id) - return if task.blank? - - task.graduation_task_group_assignations.includes(:graduation_group, :graduation_work).each do |assignation| - graduation_group = assignation.graduation_group - work = assignation.graduation_work - if graduation_group.present? && work.present? - member_ids = graduation_group.course_members.pluck(:user_id).uniq - member_ids.each do |user_id| - unless work.graduation_work_comment_assignations.exists?(user_id: user_id) - work.graduation_work_comment_assignations << GraduationWorkCommentAssignation.new(user_id: user_id, graduation_task_id: task.id) - end - end - end - end - end -end diff --git a/app/jobs/graduation_task_publish_notify_job.rb b/app/jobs/graduation_task_publish_notify_job.rb deleted file mode 100644 index 84049fe90..000000000 --- a/app/jobs/graduation_task_publish_notify_job.rb +++ /dev/null @@ -1,28 +0,0 @@ -# 任务发布 消息通知 -class GraduationTaskPublishNotifyJob < ApplicationJob - queue_as :notify - - def perform(graduation_task_id) - task = GraduationTask.find_by(id: graduation_task_id) - return if task.blank? - course = task.course - return if course.blank? - - attrs = %i[ - user_id trigger_user_id container_id container_type parent_container_id parent_container_type - belong_container_id belong_container_type viewed tiding_type created_at updated_at - ] - - same_attrs = { - trigger_user_id: task.user_id, container_id: task.id, container_type: 'GraduationTask', - parent_container_id: task.id, parent_container_type: 'TaskPublish', - belong_container_id: task.course_id, belong_container_type: 'Course', - viewed: 0, tiding_type: 'GraduationTask' - } - Tiding.bulk_insert(*attrs) do |worker| - course.course_members.pluck(:user_id).uniq.each do |user_id| - worker.add same_attrs.merge(user_id: user_id) - end - end - end -end diff --git a/app/jobs/resubmit_student_work_notify_job.rb b/app/jobs/resubmit_student_work_notify_job.rb deleted file mode 100644 index 1a67aa3ad..000000000 --- a/app/jobs/resubmit_student_work_notify_job.rb +++ /dev/null @@ -1,33 +0,0 @@ -class ResubmitStudentWorkNotifyJob < ApplicationJob - queue_as :notify - - def perform(homework_id, student_ids) - homework = HomeworkCommon.find_by(id: homework_id) - return if homework.blank? || student_ids.blank? - course = homework.course - - attrs = %i[user_id trigger_user_id container_id container_type parent_container_id parent_container_type - belong_container_id belong_container_type tiding_type viewed created_at updated_at] - - same_attrs = { - container_type: 'ResubmitStudentWork', parent_container_id: homework.id, parent_container_type: 'HomeworkCommon', - belong_container_id: course.id, belong_container_type: 'Course', tiding_type: 'HomeworkCommon', viewed: 0 - } - Tiding.bulk_insert(*attrs) do |worker| - student_ids.each do |user_id| - next unless User.exists?(id: user_id) - - work = homework.student_works.find_by(user_id: user_id) - next if work.blank? - score_user_ids = work.student_works_scores.where.not(score: nil).where(reviewer_role: [1, 2]).pluck(user_id).uniq - next if score_user_ids.blank? - - attrs = same_attrs.merge(trigger_user_id: user_id, container_id: work.id) - - score_user_ids.each do |user_id| - worker.add attrs.merge(user_id: user_id) - end - end - end - end -end diff --git a/app/jobs/send_template_message_job.rb b/app/jobs/send_template_message_job.rb index a0191cee3..125ed3e0b 100644 --- a/app/jobs/send_template_message_job.rb +++ b/app/jobs/send_template_message_job.rb @@ -36,9 +36,9 @@ class SendTemplateMessageJob < ApplicationJob operator = User.find_by_id(operator_id) issue = Issue.find_by_id(issue_id) return unless operator.present? && issue.present? - receivers = receivers.where.not(id: operator&.id) + # receivers = receivers.where.not(id: operator&.id) receivers_string, content, notification_url = MessageTemplate::IssueAtme.get_message_content(receivers, operator, issue) - Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {operator_id: operator.id, issue_id: issue.id}, 2) + Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {operator_id: operator.id, issue_id: issue.id}, 2, operator_id) when 'IssueChanged' operator_id, issue_id, change_params = args[0], args[1], args[2] operator = User.find_by_id(operator_id) @@ -234,9 +234,9 @@ class SendTemplateMessageJob < ApplicationJob operator = User.find_by_id(operator_id) pull_request = PullRequest.find_by_id(pull_request_id) return unless operator.present? && pull_request.present? - receivers = receivers.where.not(id: operator&.id) + # receivers = receivers.where.not(id: operator&.id) receivers_string, content, notification_url = MessageTemplate::PullRequestAtme.get_message_content(receivers, operator, pull_request) - Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {operator_id: operator.id, pull_request_id: pull_request.id}, 2) + Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {operator_id: operator.id, pull_request_id: pull_request.id}, 2, operator_id) when 'PullRequestChanged' operator_id, pull_request_id, change_params = args[0], args[1], args[2] operator = User.find_by_id(operator_id) diff --git a/app/libs/custom_regexp.rb b/app/libs/custom_regexp.rb index c7b5e7a1a..bbc061250 100644 --- a/app/libs/custom_regexp.rb +++ b/app/libs/custom_regexp.rb @@ -1,6 +1,7 @@ module CustomRegexp PHONE = /1\d{10}/ EMAIL = /\A[a-zA-Z0-9]+([._\\]*[a-zA-Z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+\z/ + LOGIN = /^(?!_)(?!.*?_$)[a-zA-Z0-9_-]+$/ #只含有数字、字母、下划线不能以下划线开头和结尾 LASTNAME = /\A[a-zA-Z0-9\u4e00-\u9fa5]+\z/ NICKNAME = /\A[\u4e00-\u9fa5_a-zA-Z0-9]+\z/ PASSWORD = /\A[a-z_A-Z0-9\-\.!@#\$%\\\^&\*\)\(\+=\{\}\[\]\/",'_<>~\·`\?:;|]{8,16}\z/ diff --git a/app/libs/forum.rb b/app/libs/forum.rb new file mode 100644 index 000000000..112ff2788 --- /dev/null +++ b/app/libs/forum.rb @@ -0,0 +1,20 @@ +module Forum + class << self + def forum_config + forum_config = {} + + begin + config = Rails.application.config_for(:configuration).symbolize_keys! + forum_config = config[:forum].symbolize_keys! + raise 'forum config missing' if forum_config.blank? + rescue => ex + raise ex if Rails.env.production? + + puts %Q{\033[33m [warning] forum config or configuration.yml missing, + please add it or execute 'cp config/configuration.yml.example config/configuration.yml' \033[0m} + forum_config = {} + end + forum_config + end + end +end diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index 6e957b4df..acd34fbbd 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -1,17 +1,11 @@ class UserMailer < ApplicationMailer # 注意:这个地方一定要和你的邮箱服务域名一致 - default from: 'educoder@trustie.org' + default from: 'notification@trustie.org' # 用户注册验证码 def register_email(mail, code) @code = code - mail(to: mail, subject: '验证你的电子邮件') + mail(to: mail, subject: 'Gitink | 注册验证码') end - # 课堂讨论区的邮件通知 - def course_message_email(mail, message_id) - @message = Message.find_by(id: message_id) - @course = @message&.board&.course - mail(to: mail, subject: '课堂发布了新的帖子') if @message.present? && @course.present? - end end diff --git a/app/models/application_record.rb b/app/models/application_record.rb index 0b95d7a58..77e5fe2db 100644 --- a/app/models/application_record.rb +++ b/app/models/application_record.rb @@ -17,14 +17,6 @@ class ApplicationRecord < ActiveRecord::Base Rails.env.production? && EduSetting.get('host_name') == 'https://www.educoder.net' end - def reset_user_cache_async_job(user) - ResetUserCacheJob.perform_later(user) - end - - def reset_platform_cache_async_job - ResetPlatformCacheJob.perform_later - end - def self.strip_param(key) key.to_s.strip.presence end diff --git a/app/models/fork_user.rb b/app/models/fork_user.rb index 0936f6bfa..bddf8f75c 100644 --- a/app/models/fork_user.rb +++ b/app/models/fork_user.rb @@ -20,12 +20,30 @@ class ForkUser < ApplicationRecord belongs_to :user belongs_to :fork_project, class_name: 'Project', foreign_key: :fork_project_id - after_save :reset_cache_data - after_destroy :reset_cache_data + after_create :incre_project_common, :incre_user_statistic, :incre_platform_statistic + after_destroy :decre_project_common, :decre_user_statistic, :decre_platform_statistic - def reset_cache_data - self.reset_platform_cache_async_job - self.reset_user_cache_async_job(self.project.owner) + def incre_project_common + CacheAsyncSetJob.perform_later("project_common_service", {forks: 1}, self.project_id) end + def decre_project_common + CacheAsyncSetJob.perform_later("project_common_service", {forks: -1}, self.project_id) + end + + def incre_user_statistic + CacheAsyncSetJob.perform_later("user_statistic_service", {fork_count: 1}, self.project&.user_id) + end + + def decre_user_statistic + CacheAsyncSetJob.perform_later("user_statistic_service", {fork_count: -1}, self.project&.user_id) + end + + def incre_platform_statistic + CacheAsyncSetJob.perform_later("platform_statistic_service", {fork_count: 1}) + end + + def decre_platform_statistic + CacheAsyncSetJob.perform_later("platform_statistic_service", {fork_count: -1}) + end end diff --git a/app/models/issue.rb b/app/models/issue.rb index 826ad3a5b..c642e642b 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -74,13 +74,32 @@ class Issue < ApplicationRecord scope :issue_pull_request, ->{where(issue_classify: "pull_request")} scope :issue_index_includes, ->{includes(:tracker, :priority, :version, :issue_status, :journals,:issue_tags,user: :user_extension)} scope :closed, ->{where(status_id: 5)} + after_create :incre_project_common, :incre_user_statistic, :incre_platform_statistic after_update :change_versions_count - after_save :reset_cache_data - after_destroy :update_closed_issues_count_in_project!, :reset_cache_data + after_destroy :update_closed_issues_count_in_project!, :decre_project_common, :decre_user_statistic, :decre_platform_statistic - def reset_cache_data - self.reset_platform_cache_async_job - self.reset_user_cache_async_job(self.user) + def incre_project_common + CacheAsyncSetJob.perform_later("project_common_service", {issues: 1}, self.project_id) + end + + def decre_project_common + CacheAsyncSetJob.perform_later("project_common_service", {issues: -1}, self.project_id) + end + + def incre_user_statistic + CacheAsyncSetJob.perform_later("user_statistic_service", {issue_count: 1}, self.author_id) + end + + def decre_user_statistic + CacheAsyncSetJob.perform_later("user_statistic_service", {issue_count: -1}, self.author_id) + end + + def incre_platform_statistic + CacheAsyncSetJob.perform_later("platform_statistic_service", {issue_count: 1}) + end + + def decre_platform_statistic + CacheAsyncSetJob.perform_later("platform_statistic_service", {issue_count: -1}) end def get_assign_user diff --git a/app/models/laboratory.rb b/app/models/laboratory.rb index 9d3ca07dd..9b409c170 100644 --- a/app/models/laboratory.rb +++ b/app/models/laboratory.rb @@ -44,7 +44,7 @@ class Laboratory < ApplicationRecord def site rails_env = EduSetting.get('rails_env') - suffix = rails_env && rails_env != 'production' ? ".#{rails_env}.trustie.net" : '.trustie.net' + suffix = rails_env && rails_env != 'production' ? ".#{rails_env}.gitlink.org.cn" : '.gitlink.org.cn' identifier ? "#{identifier}#{suffix}" : '' end @@ -74,74 +74,6 @@ class Laboratory < ApplicationRecord RequestStore.store[:current_laboratory] ||= User.anonymous end - def shixuns - if main_site? - not_shixun_ids = Shixun.joins(:laboratory_shixuns).where("laboratory_shixuns.laboratory_id != #{Laboratory.current.id}") - Shixun.where.not(id: not_shixun_ids.pluck(:shixun_id)) - elsif sync_shixun - laboratory_shixun_ids = laboratory_shixuns.pluck(:shixun_id) - school_shixun_ids = Shixun.joins("join user_extensions on shixuns.user_id=user_extensions.user_id").where(user_extensions: { school_id: school_id }).pluck(:id) - shixun_ids = laboratory_shixun_ids + school_shixun_ids - Shixun.where(id: shixun_ids.uniq) - else - Shixun.joins(:laboratory_shixuns).where(laboratory_shixuns: { laboratory_id: id }) - end - end - - def subjects - if main_site? - not_subject_ids = Subject.joins(:laboratory_subjects).where("laboratory_subjects.laboratory_id != #{Laboratory.current.id}") - Subject.where.not(id: not_subject_ids.pluck(:subject_id)) - elsif sync_subject - laboratory_subject_ids = laboratory_subjects.pluck(:subject_id) - school_subject_ids = Subject.joins("join user_extensions on subjects.user_id=user_extensions.user_id").where(user_extensions: { school_id: school_id }).pluck(:id) - subject_ids = laboratory_subject_ids + school_subject_ids - Subject.where(id: subject_ids.uniq) - else - Subject.joins(:laboratory_subjects).where(laboratory_subjects: { laboratory_id: id }) - end - end - - def all_courses - main_site? || !sync_course ? courses : courses.or(Course.where(school_id: school_id)) - end - - def shixun_repertoires - where_sql = ShixunTagRepertoire.where("shixun_tag_repertoires.tag_repertoire_id = tag_repertoires.id") - - # 云上实验室过滤 - unless main_site? - where_sql = where_sql.joins("JOIN laboratory_shixuns ls ON ls.shixun_id = shixun_tag_repertoires.shixun_id "\ - "AND ls.laboratory_id = #{id}") - end - where_sql = where_sql.select('1').to_sql - tags = TagRepertoire.where("EXISTS(#{where_sql})").distinct.includes(sub_repertoire: :repertoire) - - tags_map = tags.group_by(&:sub_repertoire) - sub_reps_map = tags_map.keys.group_by(&:repertoire) - - sub_reps_map.keys.sort_by(&:updated_at).reverse.map do |repertoire| - repertoire_hash = repertoire.as_json(only: %i[id name]) - repertoire_hash[:sub_repertoires] = - sub_reps_map[repertoire].sort_by(&:updated_at).reverse.map do |sub_repertoire| - sub_repertoire_hash = sub_repertoire.as_json(only: %i[id name]) - sub_repertoire_hash[:tags] = tags_map[sub_repertoire].sort_by(&:updated_at).reverse.map { |tag| tag.as_json(only: %i[id name]) } - sub_repertoire_hash - end - repertoire_hash - end - end - - def subject_repertoires - exist_sql = Subject.where('subjects.repertoire_id = repertoires.id') - - unless main_site? - exist_sql = exist_sql.joins(:laboratory_subjects).where(laboratory_subjects: { laboratory_id: id }) - end - - Repertoire.where("EXISTS(#{exist_sql.select('1').to_sql})").order(updated_at: :desc).distinct - end - # 是否为主站 def main_site? id == 1 diff --git a/app/models/message_template.rb b/app/models/message_template.rb index bd2c68bdd..a6e894c70 100644 --- a/app/models/message_template.rb +++ b/app/models/message_template.rb @@ -17,55 +17,55 @@ class MessageTemplate < ApplicationRecord def self.build_init_data self.create(type: 'MessageTemplate::FollowedTip', sys_notice: '{nickname} 关注了你', notification_url: '{baseurl}/{login}') email_html = File.read("#{email_template_html_dir}/issue_assigned.html") - self.create(type: 'MessageTemplate::IssueAssigned', sys_notice: '{nickname1}在 {nickname2}/{repository} 指派给你一个易修:{title}', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}', email: email_html, email_title: '{nickname1} 在 {nickname2}/{repository} 指派给你一个易修') + self.create(type: 'MessageTemplate::IssueAssigned', sys_notice: '{nickname1}在 {nickname2}/{repository} 指派给你一个易修:{title}', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}', email: email_html, email_title: 'GitLink: {nickname1} 在 {nickname2}/{repository} 指派给你一个易修') self.create(type: 'MessageTemplate::IssueAssignerExpire', sys_notice: '您负责的易修 {title} 已临近截止日期,请尽快处理', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}') self.create(type: 'MessageTemplate::IssueAtme', sys_notice: '{nickname} 在易修 {title} 中@我', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}') email_html = File.read("#{email_template_html_dir}/issue_changed.html") - self.create(type: 'MessageTemplate::IssueChanged', sys_notice: '在项目 {nickname2}/{repository} 的易修 {title} 中:{ifassigner}{nickname1}将负责人从 {assigner1} 修改为 {assigner2} {endassigner}{ifstatus}{nickname1}将状态从 {status1} 修改为 {status2} {endstatus}{iftracker}{nickname1}将类型从 {tracker1} 修改为 {tracker2} {endtracker}{ifpriority}{nickname1}将优先级从 {priority1} 修改为 {priority2} {endpriority}{ifmilestone}{nickname1}将里程碑从 {milestone1} 修改为 {milestone2} {endmilestone}{iftag}{nickname1}将标记从 {tag1} 修改为 {tag2} {endtag}{ifdoneratio}{nickname1}将完成度从 {doneratio1} 修改为 {doneratio2} {enddoneratio}{ifbranch}{nickname1}将指定分支从 {branch1} 修改为 {branch2} {endbranch}{ifstartdate}{nickname1}将开始日期从 {startdate1} 修改为 {startdate2} {endstartdate}{ifduedate}{nickname1}将结束日期从 {duedate1} 修改为 {duedate2} {endduedate}', email: email_html, email_title: '易修 {title} 有状态变更', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}') + self.create(type: 'MessageTemplate::IssueChanged', sys_notice: '在项目 {nickname2}/{repository} 的易修 {title} 中:{ifassigner}{nickname1}将负责人从 {assigner1} 修改为 {assigner2} {endassigner}{ifstatus}{nickname1}将状态从 {status1} 修改为 {status2} {endstatus}{iftracker}{nickname1}将类型从 {tracker1} 修改为 {tracker2} {endtracker}{ifpriority}{nickname1}将优先级从 {priority1} 修改为 {priority2} {endpriority}{ifmilestone}{nickname1}将里程碑从 {milestone1} 修改为 {milestone2} {endmilestone}{iftag}{nickname1}将标记从 {tag1} 修改为 {tag2} {endtag}{ifdoneratio}{nickname1}将完成度从 {doneratio1} 修改为 {doneratio2} {enddoneratio}{ifbranch}{nickname1}将指定分支从 {branch1} 修改为 {branch2} {endbranch}{ifstartdate}{nickname1}将开始日期从 {startdate1} 修改为 {startdate2} {endstartdate}{ifduedate}{nickname1}将结束日期从 {duedate1} 修改为 {duedate2} {endduedate}', email: email_html, email_title: 'GitLink: 易修 {title} 有状态变更', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}') self.create(type: 'MessageTemplate::IssueCreatorExpire', sys_notice: '您发布的易修 {title} 已临近截止日期,请尽快处理', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}') email_html = File.read("#{email_template_html_dir}/issue_deleted.html") - self.create(type: 'MessageTemplate::IssueDeleted', sys_notice: '{nickname}已将易修 {title} 删除', email: email_html, email_title: '易修 {title} 有状态变更', notification_url: '') + self.create(type: 'MessageTemplate::IssueDeleted', sys_notice: '{nickname}已将易修 {title} 删除', email: email_html, email_title: 'GitLink: 易修 {title} 有状态变更', notification_url: '') self.create(type: 'MessageTemplate::IssueJournal', sys_notice: '{nickname}评论易修{title}:{notes}', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}') self.create(type: 'MessageTemplate::LoginIpTip', sys_notice: '您的账号{nickname}于{login_time)在非常用的IP地址{ip}登录,如非本人操作,请立即修改密码', notification_url: '') email_html = File.read("#{email_template_html_dir}/organization_joined.html") - self.create(type: 'MessageTemplate::OrganizationJoined', sys_notice: '你已加入 {organization} 组织', notification_url: '{baseurl}/{login}', email: email_html, email_title: '你已加入 {organization} 组织') + self.create(type: 'MessageTemplate::OrganizationJoined', sys_notice: '你已加入 {organization} 组织', notification_url: '{baseurl}/{login}', email: email_html, email_title: 'GitLink: 你已加入 {organization} 组织') email_html = File.read("#{email_template_html_dir}/organization_left.html") - self.create(type: 'MessageTemplate::OrganizationLeft', sys_notice: '你已被移出 {organization} 组织', notification_url: '', email: email_html, email_title: '你已被移出 {organization} 组织') + self.create(type: 'MessageTemplate::OrganizationLeft', sys_notice: '你已被移出 {organization} 组织', notification_url: '', email: email_html, email_title: 'GitLink: 你已被移出 {organization} 组织') email_html = File.read("#{email_template_html_dir}/organization_role.html") - self.create(type: 'MessageTemplate::OrganizationRole', sys_notice: '组织 {organization} 已把你的角色改为 {role}', email: email_html, email_title: '在 {organization} 组织你的账号有权限变更', notification_url: '{baseurl}/{login}') + self.create(type: 'MessageTemplate::OrganizationRole', sys_notice: '组织 {organization} 已把你的角色改为 {role}', email: email_html, email_title: 'GitLink: 在 {organization} 组织你的账号有权限变更', notification_url: '{baseurl}/{login}') self.create(type: 'MessageTemplate::ProjectDeleted', sys_notice: '你关注的仓库{nickname}/{repository}已被删除', notification_url: '') self.create(type: 'MessageTemplate::ProjectFollowed', sys_notice: '{nickname} 关注了你管理的仓库', notification_url: '{baseurl}/{login}') self.create(type: 'MessageTemplate::ProjectForked', sys_notice: '{nickname1} 复刻了你管理的仓库{nickname1}/{repository1}到{nickname2}/{repository2}', notification_url: '{baseurl}/{owner}/{identifier}') email_html = File.read("#{email_template_html_dir}/project_issue.html") - self.create(type: 'MessageTemplate::ProjectIssue', sys_notice: '{nickname1}在 {nickname2}/{repository} 新建易修:{title}', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}', email: email_html, email_title: '{nickname1} 在 {nickname2}/{repository} 新建了一个易修') + self.create(type: 'MessageTemplate::ProjectIssue', sys_notice: '{nickname1}在 {nickname2}/{repository} 新建易修:{title}', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}', email: email_html, email_title: 'GitLink: {nickname1} 在 {nickname2}/{repository} 新建了一个易修') email_html = File.read("#{email_template_html_dir}/project_joined.html") - self.create(type: 'MessageTemplate::ProjectJoined', sys_notice: '你已加入 {repository} 项目', notification_url: '{baseurl}/{owner}/{identifier}', email: email_html, email_title: '你已加入 {repository} 项目') + self.create(type: 'MessageTemplate::ProjectJoined', sys_notice: '你已加入 {repository} 项目', notification_url: '{baseurl}/{owner}/{identifier}', email: email_html, email_title: 'GitLink: 你已加入 {repository} 项目') email_html = File.read("#{email_template_html_dir}/project_left.html") - self.create(type: 'MessageTemplate::ProjectLeft', sys_notice: '你已被移出 {repository} 项目', notification_url: '', email: email_html, email_title: '你已被移出 {repository} 项目') + self.create(type: 'MessageTemplate::ProjectLeft', sys_notice: '你已被移出 {repository} 项目', notification_url: '', email: email_html, email_title: 'GitLink: 你已被移出 {repository} 项目') email_html = File.read("#{email_template_html_dir}/project_member_joined.html") - self.create(type: 'MessageTemplate::ProjectMemberJoined', sys_notice: '{nickname1} 已加入项目 {nickname2}/{repository}', notification_url: '{baseurl}/{owner}/{identifier}', email: email_html, email_title: '{nickname1} 已加入项目 {nickname2}/{repository}') + self.create(type: 'MessageTemplate::ProjectMemberJoined', sys_notice: '{nickname1} 已加入项目 {nickname2}/{repository}', notification_url: '{baseurl}/{owner}/{identifier}', email: email_html, email_title: 'GitLink: {nickname1} 已加入项目 {nickname2}/{repository}') email_html = File.read("#{email_template_html_dir}/project_member_left.html") - self.create(type: 'MessageTemplate::ProjectMemberLeft', sys_notice: '{nickname1} 已被移出项目 {nickname2}/{repository}', notification_url: '{baseurl}/{owner}/{identifier}', email: email_html, email_title: '{nickname1} 已被移出项目 {nickname2}/{repository}') + self.create(type: 'MessageTemplate::ProjectMemberLeft', sys_notice: '{nickname1} 已被移出项目 {nickname2}/{repository}', notification_url: '{baseurl}/{owner}/{identifier}', email: email_html, email_title: 'GitLink: {nickname1} 已被移出项目 {nickname2}/{repository}') self.create(type: 'MessageTemplate::ProjectMilestone', sys_notice: '{nickname1}在 {nickname2}/{repository} 创建了一个里程碑:{title}', notification_url: '{baseurl}/{owner}/{identifier}/milestones/{id}') self.create(type: 'MessageTemplate::ProjectPraised', sys_notice: '{nickname} 点赞了你管理的仓库', notification_url: '{baseurl}/{login}') email_html = File.read("#{email_template_html_dir}/project_pull_request.html") - self.create(type: 'MessageTemplate::ProjectPullRequest', sys_notice: '{nickname1}在 {nickname2}/{repository} 提交了一个合并请求:{title}', notification_url: '{baseurl}/{owner}/{identifier}/pulls/{id}', email: email_html, email_title: '{nickname1} 在 {nickname2}/{repository} 提交了一个合并请求') + self.create(type: 'MessageTemplate::ProjectPullRequest', sys_notice: '{nickname1}在 {nickname2}/{repository} 提交了一个合并请求:{title}', notification_url: '{baseurl}/{owner}/{identifier}/pulls/{id}', email: email_html, email_title: 'GitLink: {nickname1} 在 {nickname2}/{repository} 提交了一个合并请求') email_html = File.read("#{email_template_html_dir}/project_role.html") - self.create(type: 'MessageTemplate::ProjectRole', sys_notice: '仓库 {nickname}/{repository} 已把你的角色改为 {role}', email: email_html, email_title: '在 {nickname}/{repository} 项目你的账号有权限变更', notification_url: '{baseurl}/{owner}/{identifier}') + self.create(type: 'MessageTemplate::ProjectRole', sys_notice: '仓库 {nickname}/{repository} 已把你的角色改为 {role}', email: email_html, email_title: 'GitLink: 在 {nickname}/{repository} 项目你的账号有权限变更', notification_url: '{baseurl}/{owner}/{identifier}') email_html = File.read("#{email_template_html_dir}/project_setting_changed.html") - self.create(type: 'MessageTemplate::ProjectSettingChanged', sys_notice: '{nickname1}更改了 {nickname2}/{repository} 仓库设置:{ifname}更改项目名称为"{name}"{endname}{ifidentifier}更改项目标识为"{identifier}"{endidentifier}{ifdescription}更改项目简介为"{description}"{enddescription}{ifcategory}更改项目类别为"{category}"{endcategory}{iflanguage}更改项目语言为"{language}"{endlanguage}{ifpermission}将仓库设为"{permission}"{endpermission}{ifnavbar}将项目导航更改为"{navbar}"{endnavbar}', notification_url: '{baseurl}/{owner}/{identifier}/settings', email: email_html, email_title: '您管理的仓库 {nickname2}/{repository} 仓库设置已被更改') + self.create(type: 'MessageTemplate::ProjectSettingChanged', sys_notice: '{nickname1}更改了 {nickname2}/{repository} 仓库设置:{ifname}更改项目名称为"{name}"{endname}{ifidentifier}更改项目标识为"{identifier}"{endidentifier}{ifdescription}更改项目简介为"{description}"{enddescription}{ifcategory}更改项目类别为"{category}"{endcategory}{iflanguage}更改项目语言为"{language}"{endlanguage}{ifpermission}将仓库设为"{permission}"{endpermission}{ifnavbar}将项目导航更改为"{navbar}"{endnavbar}', notification_url: '{baseurl}/{owner}/{identifier}/settings', email: email_html, email_title: 'GitLink: 您管理的仓库 {nickname2}/{repository} 仓库设置已被更改') self.create(type: 'MessageTemplate::ProjectTransfer', sys_notice: '你关注的仓库{nickname1}/{repository1}已被转移至{nickname2}/{repository2}', notification_url: '{baseurl}/{owner}/{identifier}') self.create(type: 'MessageTemplate::ProjectVersion', sys_notice: '{nickname1}在 {nickname2}/{repository} 创建了发行版:{title}', notification_url: '{baseurl}/{owner}/{identifier}/releases') email_html = File.read("#{email_template_html_dir}/pull_request_assigned.html") - self.create(type: 'MessageTemplate::PullRequestAssigned', sys_notice: '{nickname1}在 {nickname2}/{repository} 指派给你一个合并请求:{title}', notification_url: '{baseurl}/{owner}/{identifier}/pulls/{id}', email: email_html, email_title: '{nickname1} 在 {nickname2}/{repository} 指派给你一个合并请求') + self.create(type: 'MessageTemplate::PullRequestAssigned', sys_notice: '{nickname1}在 {nickname2}/{repository} 指派给你一个合并请求:{title}', notification_url: '{baseurl}/{owner}/{identifier}/pulls/{id}', email: email_html, email_title: 'GitLink: {nickname1} 在 {nickname2}/{repository} 指派给你一个合并请求') self.create(type: 'MessageTemplate::PullRequestAtme', sys_notice: '{nickname} 在合并请求 {title} 中@我', notification_url: '{baseurl}/{owner}/{identifier}/pulls/{id}') email_html = File.read("#{email_template_html_dir}/pull_request_changed.html") - self.create(type: 'MessageTemplate::PullRequestChanged', sys_notice: '在项目{nickname2}/{repository}的合并请求 {title} 中:{ifassigner}{nickname1}将审查成员从 {assigner1} 修改为 {assigner2} {endassigner}{ifmilestone}{nickname1}将里程碑从 {milestone1} 修改为 {milestone2} {endmilestone}{iftag}{nickname1}将标记从 {tag1} 修改为 {tag2} {endtag}{ifpriority}{nickname1}将优先级从 {priority1} 修改为 {priority2} {endpriority}', email: email_html, email_title: '合并请求 {title} 有状态变更', notification_url: '{baseurl}/{owner}/{identifier}/pulls/{id}') + self.create(type: 'MessageTemplate::PullRequestChanged', sys_notice: '在项目{nickname2}/{repository}的合并请求 {title} 中:{ifassigner}{nickname1}将审查成员从 {assigner1} 修改为 {assigner2} {endassigner}{ifmilestone}{nickname1}将里程碑从 {milestone1} 修改为 {milestone2} {endmilestone}{iftag}{nickname1}将标记从 {tag1} 修改为 {tag2} {endtag}{ifpriority}{nickname1}将优先级从 {priority1} 修改为 {priority2} {endpriority}', email: email_html, email_title: 'GitLink: 合并请求 {title} 有状态变更', notification_url: '{baseurl}/{owner}/{identifier}/pulls/{id}') email_html = File.read("#{email_template_html_dir}/pull_request_closed.html") - self.create(type: 'MessageTemplate::PullRequestClosed', sys_notice: '你提交的合并请求:{title} 被拒绝', email: email_html, email_title: '合并请求 {title} 有状态变更', notification_url: '') + self.create(type: 'MessageTemplate::PullRequestClosed', sys_notice: '你提交的合并请求:{title} 被拒绝', email: email_html, email_title: 'GitLink: 合并请求 {title} 有状态变更', notification_url: '') self.create(type: 'MessageTemplate::PullRequestJournal', sys_notice: '{nickname}评论合并请求{title}:{notes}', notification_url: '{baseurl}/{owner}/{identifier}/pulls/{id}') email_html = File.read("#{email_template_html_dir}/pull_request_merged.html") - self.create(type: 'MessageTemplate::PullRequestMerged', sys_notice: '你提交的合并请求:{title} 已通过', email: email_html, email_title: '合并请求 {title} 有状态变更', notification_url: '{baseurl}/{owner}/{identifier}/pulls/{id}') + self.create(type: 'MessageTemplate::PullRequestMerged', sys_notice: '你提交的合并请求:{title} 已通过', email: email_html, email_title: 'GitLink: 合并请求 {title} 有状态变更', notification_url: '{baseurl}/{owner}/{identifier}/pulls/{id}') end def self.sys_notice diff --git a/app/models/message_template/issue_changed.rb b/app/models/message_template/issue_changed.rb index 7edc8f05d..90a72d1a0 100644 --- a/app/models/message_template/issue_changed.rb +++ b/app/models/message_template/issue_changed.rb @@ -188,6 +188,7 @@ class MessageTemplate::IssueChanged < MessageTemplate end def self.get_email_message_content(receiver, operator, issue, change_params) + return '', '', '' if change_params.blank? if receiver.user_template_message_setting.present? return '', '', '' unless receiver.user_template_message_setting.email_body["CreateOrAssign::IssueChanged"] end diff --git a/app/models/message_template/pull_request_changed.rb b/app/models/message_template/pull_request_changed.rb index 729e12060..fc4457f37 100644 --- a/app/models/message_template/pull_request_changed.rb +++ b/app/models/message_template/pull_request_changed.rb @@ -100,6 +100,7 @@ class MessageTemplate::PullRequestChanged < MessageTemplate end def self.get_email_message_content(receiver, operator, pull_request, change_params) + return '', '', '' if change_params.blank? if receiver.user_template_message_setting.present? return '', '', '' unless receiver.user_template_message_setting.email_body["CreateOrAssign::PullRequestChanged"] end diff --git a/app/models/organization.rb b/app/models/organization.rb index 843c2b05f..40c676e05 100644 --- a/app/models/organization.rb +++ b/app/models/organization.rb @@ -76,11 +76,17 @@ class Organization < Owner validates_uniqueness_of :login, :if => Proc.new { |user| user.login_changed? && user.login.present? }, case_sensitive: false validates :login, format: { with: NAME_REGEX, multiline: true, message: "只能含有数字、字母、下划线且不能以下划线开头和结尾" } - delegate :description, :website, :location, :repo_admin_change_team_access, + delegate :description, :website, :location, :repo_admin_change_team_access, :recommend, :visibility, :max_repo_creation, :num_projects, :num_users, :num_teams, to: :organization_extension, allow_nil: true scope :with_visibility, ->(visibility) { joins(:organization_extension).where(organization_extensions: {visibility: visibility}) if visibility.present? } + after_save :reset_cache_data + + def reset_cache_data + Cache::V2::OwnerCommonService.new(self.id).reset + end + def self.build(name, nickname, gitea_token=nil) self.create!(login: name, nickname: nickname, gitea_token: gitea_token) end diff --git a/app/models/organization_extension.rb b/app/models/organization_extension.rb index 8b9946cd7..4b0935208 100644 --- a/app/models/organization_extension.rb +++ b/app/models/organization_extension.rb @@ -15,6 +15,7 @@ # num_projects :integer default("0") # num_users :integer default("0") # num_teams :integer default("0") +# recommend :boolean default("0") # # Indexes # @@ -30,6 +31,8 @@ class OrganizationExtension < ApplicationRecord enum visibility: {common: 0, limited: 1, privacy: 2} + before_save :set_recommend + def self.build(organization_id, description, website, location, repo_admin_change_team_access, visibility, max_repo_creation) self.create!(organization_id: organization_id, description: description, @@ -39,4 +42,9 @@ class OrganizationExtension < ApplicationRecord visibility: visibility, max_repo_creation: max_repo_creation) end + + private + def set_recommend + self.recommend = false unless self.common? + end end diff --git a/app/models/praise_tread.rb b/app/models/praise_tread.rb index 5a9c19164..5d4ae0d80 100644 --- a/app/models/praise_tread.rb +++ b/app/models/praise_tread.rb @@ -1,35 +1,51 @@ -# == Schema Information -# -# Table name: praise_treads -# -# id :integer not null, primary key -# user_id :integer not null -# praise_tread_object_id :integer -# praise_tread_object_type :string(255) -# praise_or_tread :integer default("1") -# created_at :datetime not null -# updated_at :datetime not null -# -# Indexes -# -# praise_tread (praise_tread_object_id,praise_tread_object_type) -# - +# == Schema Information +# +# Table name: praise_treads +# +# id :integer not null, primary key +# user_id :integer not null +# praise_tread_object_id :integer +# praise_tread_object_type :string(255) +# praise_or_tread :integer default("1") +# created_at :datetime not null +# updated_at :datetime not null +# +# Indexes +# +# praise_tread (praise_tread_object_id,praise_tread_object_type) +# + class PraiseTread < ApplicationRecord belongs_to :user belongs_to :praise_tread_object, polymorphic: true, counter_cache: :praises_count has_many :tidings, :as => :container, :dependent => :destroy - after_create :send_tiding - after_save :reset_cache_data - after_destroy :reset_cache_data + after_create :send_tiding, :incre_project_common, :incre_user_statistic, :incre_platform_statistic + after_destroy :decre_project_common, :decre_user_statistic, :decre_platform_statistic - def reset_cache_data - self.reset_platform_cache_async_job - if self.praise_tread_object.is_a?(Project) - self.reset_user_cache_async_job(self.praise_tread_object&.owner) - end + def incre_project_common + CacheAsyncSetJob.perform_later("project_common_service", {praises: 1}, self.praise_tread_object_id) if self.praise_tread_object_type == "Project" + end + + def decre_project_common + CacheAsyncSetJob.perform_later("project_common_service", {praises: -1}, self.praise_tread_object_id) if self.praise_tread_object_type == "Project" + end + + def incre_user_statistic + CacheAsyncSetJob.perform_later("user_statistic_service", {project_praise_count: 1}, self.praise_tread_object&.user_id) if self.praise_tread_object_type == "Project" + end + + def decre_user_statistic + CacheAsyncSetJob.perform_later("user_statistic_service", {project_praise_count: -1}, self.praise_tread_object&.user_id) if self.praise_tread_object_type == "Project" + end + + def incre_platform_statistic + CacheAsyncSetJob.perform_later("platform_statistic_service", {project_praise_count: 1}) if self.praise_tread_object_type == "Project" + end + + def decre_platform_statistic + CacheAsyncSetJob.perform_later("platform_statistic_service", {project_praise_count: -1}) if self.praise_tread_object_type == "Project" end def send_tiding diff --git a/app/models/project.rb b/app/models/project.rb index d7b0519b7..f3f2d5d5b 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -55,6 +55,8 @@ # default_branch :string(255) default("master") # website :string(255) # lesson_url :string(255) +# is_pinned :boolean default("0") +# recommend_index :integer default("0") # # Indexes # @@ -76,6 +78,8 @@ # + + class Project < ApplicationRecord include Matchable include Publicable @@ -123,13 +127,15 @@ class Project < ApplicationRecord has_many :pinned_projects, dependent: :destroy has_many :has_pinned_users, through: :pinned_projects, source: :user has_many :webhooks, class_name: "Gitea::Webhook", primary_key: :gpid, foreign_key: :repo_id - - after_save :check_project_members - before_save :set_invite_code, :reset_cache_data, :reset_unmember_followed - after_destroy :reset_cache_data - scope :project_statics_select, -> {select(:id,:name, :is_public, :identifier, :status, :project_type, :user_id, :forked_count, :visits, :project_category_id, :project_language_id, :license_id, :ignore_id, :watchers_count, :created_on)} + after_create :incre_user_statistic, :incre_platform_statistic + after_save :check_project_members, :reset_cache_data + before_save :set_invite_code, :reset_unmember_followed, :set_recommend_and_is_pinned + before_destroy :decre_project_common + after_destroy :decre_user_statistic, :decre_platform_statistic + scope :project_statics_select, -> {select(:id,:name, :is_public, :identifier, :status, :project_type, :user_id, :forked_count, :description, :visits, :project_category_id, :project_language_id, :license_id, :ignore_id, :watchers_count, :created_on)} scope :no_anomory_projects, -> {where("projects.user_id is not null and projects.user_id != ?", 2)} scope :recommend, -> { visible.project_statics_select.where(recommend: true) } + scope :pinned, -> {where(is_pinned: true)} delegate :content, to: :project_detail, allow_nil: true delegate :name, to: :license, prefix: true, allow_nil: true @@ -147,12 +153,48 @@ class Project < ApplicationRecord end def reset_cache_data + CacheAsyncResetJob.perform_later("project_common_service", self.id) if changes[:user_id].present? - first_owner = Owner.find_by_id(changes[:user_id].first) - self.reset_user_cache_async_job(first_owner) + CacheAsyncSetJob.perform_later("user_statistic_service", {project_count: -1}, changes[:user_id].first) + CacheAsyncSetJob.perform_later("user_statistic_service", {project_count: 1}, changes[:user_id].last) + end + if changes[:project_language_id].present? + first_language = ProjectLanguage.find_by_id(changes[:project_language_id].first) + last_language = ProjectLanguage.find_by_id(changes[:project_language_id].last) + CacheAsyncSetJob.perform_later("user_statistic_service", {project_language_count_key: first_language&.name, project_language_count: -1}, self.user_id) + CacheAsyncSetJob.perform_later("user_statistic_service", {project_language_count_key: last_language&.name, project_language_count: 1}, self.user_id) + CacheAsyncSetJob.perform_later("platform_statistic_service", {project_language_count_key: first_language&.name, project_language_count: -1}) + CacheAsyncSetJob.perform_later("platform_statistic_service", {project_language_count_key: last_language&.name, project_language_count: 1}) + end + end + + def decre_project_common + CacheAsyncClearJob.perform_later('project_common_service', self.id) + end + + def incre_user_statistic + CacheAsyncSetJob.perform_later("user_statistic_service", {project_count: 1, project_language_count_key: self.project_language&.name, project_language_count: 1}, self.user_id) + end + + def decre_user_statistic + CacheAsyncSetJob.perform_later("user_statistic_service", {project_count: -1, project_language_count_key: self.project_language&.name, project_language_count: -1}, self.user_id) + end + + def incre_platform_statistic + CacheAsyncSetJob.perform_later("platform_statistic_service", {project_count: 1, project_language_count_key: self.project_language&.name, project_language_count: 1}) + end + + def decre_platform_statistic + CacheAsyncSetJob.perform_later("platform_statistic_service", {project_count: -1, project_language_count_key: self.project_language&.name, project_language_count: -1}) + end + + def is_full_public + owner = self.owner + if owner.is_a?(Organization) + return self.is_public && owner&.visibility == "common" + else + return self.is_public end - self.reset_platform_cache_async_job - self.reset_user_cache_async_job(self.owner) end def reset_unmember_followed @@ -167,6 +209,16 @@ class Project < ApplicationRecord end end + def set_recommend_and_is_pinned + self.recommend = self.recommend_index.zero? ? false : true + # 私有项目不允许设置精选和推荐 + unless self.is_public + self.recommend = false + self.recommend_index = 0 + self.is_pinned = false + end + end + def self.search_project(search) ransack(name_or_identifier_cont: search) end diff --git a/app/models/project_category.rb b/app/models/project_category.rb index 67b802998..4bba5423e 100644 --- a/app/models/project_category.rb +++ b/app/models/project_category.rb @@ -8,10 +8,27 @@ # projects_count :integer default("0") # created_at :datetime not null # updated_at :datetime not null +# ancestry :string(255) +# pinned_index :integer default("0") +# +# Indexes +# +# index_project_categories_on_ancestry (ancestry) # class ProjectCategory < ApplicationRecord include Projectable has_ancestry + def logo_url + image_url('logo') + end + + private + + def image_url(type) + return nil unless Util::FileManage.exists?(self, type) + Util::FileManage.source_disk_file_url(self, type) + end + end diff --git a/app/models/pull_request.rb b/app/models/pull_request.rb index aec320858..74111ad0d 100644 --- a/app/models/pull_request.rb +++ b/app/models/pull_request.rb @@ -42,12 +42,31 @@ class PullRequest < ApplicationRecord scope :merged_and_closed, ->{where.not(status: 0)} scope :opening, -> {where(status: 0)} - after_save :reset_cache_data - after_destroy :reset_cache_data + after_create :incre_project_common, :incre_user_statistic, :incre_platform_statistic + after_destroy :decre_project_common, :decre_user_statistic, :decre_platform_statistic - def reset_cache_data - self.reset_platform_cache_async_job - self.reset_user_cache_async_job(self.user) + def incre_project_common + CacheAsyncSetJob.perform_later("project_common_service", {pullrequests: 1}, self.project_id) + end + + def decre_project_common + CacheAsyncSetJob.perform_later("project_common_service", {pullrequests: -1}, self.project_id) + end + + def incre_user_statistic + CacheAsyncSetJob.perform_later("user_statistic_service", {pullrequest_count: 1}, self.user_id) + end + + def decre_user_statistic + CacheAsyncSetJob.perform_later("user_statistic_service", {pullrequest_count: -1}, self.user_id) + end + + def incre_platform_statistic + CacheAsyncSetJob.perform_later("platform_statistic_service", {pullrequest_count: 1}) + end + + def decre_platform_statistic + CacheAsyncSetJob.perform_later("platform_statistic_service", {pullrequest_count: -1}) end def fork_project diff --git a/app/models/reversed_keyword.rb b/app/models/reversed_keyword.rb index cd8027fbd..10ad62fa0 100644 --- a/app/models/reversed_keyword.rb +++ b/app/models/reversed_keyword.rb @@ -18,6 +18,10 @@ class ReversedKeyword < ApplicationRecord before_validation :set_identifier + def self.check_exists?(identifier) + self.is_reversed(identifier).exists? + end + private def set_identifier diff --git a/app/models/system_notification.rb b/app/models/system_notification.rb index 6f901b3fd..d2b99ecf3 100644 --- a/app/models/system_notification.rb +++ b/app/models/system_notification.rb @@ -15,6 +15,13 @@ class SystemNotification < ApplicationRecord default_scope { order(created_at: :desc)} + has_many :system_notification_histories + has_many :users, through: :system_notification_histories + scope :is_top, lambda { where(is_top: true) } + def read_member?(user_id) + self.system_notification_histories.where(user_id: user_id).present? ? true : false + end + end diff --git a/app/models/system_notification_history.rb b/app/models/system_notification_history.rb new file mode 100644 index 000000000..b629babdf --- /dev/null +++ b/app/models/system_notification_history.rb @@ -0,0 +1,23 @@ +# == Schema Information +# +# Table name: system_notification_histories +# +# id :integer not null, primary key +# system_message_id :integer +# user_id :integer +# created_at :datetime not null +# updated_at :datetime not null +# +# Indexes +# +# index_system_notification_histories_on_system_message_id (system_message_id) +# index_system_notification_histories_on_user_id (user_id) +# + +class SystemNotificationHistory < ApplicationRecord + + belongs_to :system_notification + belongs_to :user + + validates :system_notification_id, uniqueness: { scope: :user_id, message: '只能阅读一次'} +end diff --git a/app/models/token.rb b/app/models/token.rb index db778c6b8..746af6535 100644 --- a/app/models/token.rb +++ b/app/models/token.rb @@ -105,7 +105,7 @@ class Token < ActiveRecord::Base end def self.generate_token_value - Educoder::Utils.random_hex(20) + Gitlink::Utils.random_hex(20) end def self.delete_user_all_tokens(user) diff --git a/app/models/topic.rb b/app/models/topic.rb new file mode 100644 index 000000000..13bf7b5bd --- /dev/null +++ b/app/models/topic.rb @@ -0,0 +1,50 @@ +# == Schema Information +# +# Table name: topics +# +# id :integer not null, primary key +# type :string(255) +# title :string(255) +# uuid :integer +# image_url :string(255) +# url :string(255) +# order_index :integer +# + +class Topic < ApplicationRecord + + default_scope { order(order_index: :desc)} + + scope :with_single_type, ->(type){where(type: trans_simpletype_to_classtype(type))} + + def image + image_url('image') + end + + def self.trans_simpletype_to_classtype(type) + case type + when 'activity_forum' + 'Topic::ActivityForum' + when 'banner' + 'Topic::Banner' + when 'card' + 'Topic::Card' + when 'cooperator' + 'Topic::Cooperator' + when 'excellent_project' + 'Topic::ExcellentProject' + when 'experience_forum' + 'Topic::ExperienceForum' + when 'pinned_forum' + 'Topic::PinnedForum' + end + end + + private + + def image_url(type) + return nil unless Util::FileManage.exists?(self, type) + Util::FileManage.source_disk_file_url(self, type) + end + +end diff --git a/app/models/topic/activity_forum.rb b/app/models/topic/activity_forum.rb new file mode 100644 index 000000000..8cf9adf83 --- /dev/null +++ b/app/models/topic/activity_forum.rb @@ -0,0 +1,17 @@ +# == Schema Information +# +# Table name: topics +# +# id :integer not null, primary key +# type :string(255) +# title :string(255) +# uuid :integer +# image_url :string(255) +# url :string(255) +# order_index :integer +# + +# 首页平台动态 +class Topic::ActivityForum < Topic + +end diff --git a/app/models/topic/banner.rb b/app/models/topic/banner.rb new file mode 100644 index 000000000..e5b77bec0 --- /dev/null +++ b/app/models/topic/banner.rb @@ -0,0 +1,16 @@ +# == Schema Information +# +# Table name: topics +# +# id :integer not null, primary key +# type :string(255) +# title :string(255) +# uuid :integer +# image_url :string(255) +# url :string(255) +# order_index :integer +# + +# 首页banner +class Topic::Banner < Topic +end diff --git a/app/models/topic/card.rb b/app/models/topic/card.rb new file mode 100644 index 000000000..6a54e17ea --- /dev/null +++ b/app/models/topic/card.rb @@ -0,0 +1,16 @@ +# == Schema Information +# +# Table name: topics +# +# id :integer not null, primary key +# type :string(255) +# title :string(255) +# uuid :integer +# image_url :string(255) +# url :string(255) +# order_index :integer +# + +# 首页卡片内容 +class Topic::Card < Topic +end diff --git a/app/models/topic/cooperator.rb b/app/models/topic/cooperator.rb new file mode 100644 index 000000000..a023d3656 --- /dev/null +++ b/app/models/topic/cooperator.rb @@ -0,0 +1,16 @@ +# == Schema Information +# +# Table name: topics +# +# id :integer not null, primary key +# type :string(255) +# title :string(255) +# uuid :integer +# image_url :string(255) +# url :string(255) +# order_index :integer +# + +# 首页合作伙伴 +class Topic::Cooperator < Topic +end diff --git a/app/models/topic/excellent_project.rb b/app/models/topic/excellent_project.rb new file mode 100644 index 000000000..ac08863c7 --- /dev/null +++ b/app/models/topic/excellent_project.rb @@ -0,0 +1,17 @@ +# == Schema Information +# +# Table name: topics +# +# id :integer not null, primary key +# type :string(255) +# title :string(255) +# uuid :integer +# image_url :string(255) +# url :string(255) +# order_index :integer +# + +# 首页优秀项目 +class Topic::ExcellentProject < Topic + +end diff --git a/app/models/topic/experience_forum.rb b/app/models/topic/experience_forum.rb new file mode 100644 index 000000000..855a56809 --- /dev/null +++ b/app/models/topic/experience_forum.rb @@ -0,0 +1,16 @@ +# == Schema Information +# +# Table name: topics +# +# id :integer not null, primary key +# type :string(255) +# title :string(255) +# uuid :integer +# image_url :string(255) +# url :string(255) +# order_index :integer +# + +# 首页经验分享 +class Topic::ExperienceForum < Topic +end diff --git a/app/models/topic/pinned_forum.rb b/app/models/topic/pinned_forum.rb new file mode 100644 index 000000000..c5a2c8572 --- /dev/null +++ b/app/models/topic/pinned_forum.rb @@ -0,0 +1,16 @@ +# == Schema Information +# +# Table name: topics +# +# id :integer not null, primary key +# type :string(255) +# title :string(255) +# uuid :integer +# image_url :string(255) +# url :string(255) +# order_index :integer +# + +# 首页精选文章 +class Topic::PinnedForum < Topic +end diff --git a/app/models/user.rb b/app/models/user.rb index 15c760a3f..8a05a056c 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -117,8 +117,6 @@ class User < Owner enumerize :platform, in: [:forge, :educoder, :trustie, :military], default: :forge, scope: :shallow belongs_to :laboratory, optional: true - has_many :composes, dependent: :destroy - has_many :compose_users, dependent: :destroy has_one :user_extension, dependent: :destroy has_many :open_users, dependent: :destroy has_one :wechat_open_user, class_name: 'OpenUsers::Wechat' @@ -174,6 +172,9 @@ class User < Owner has_one :user_template_message_setting, dependent: :destroy + has_many :system_notification_histories + has_many :system_notifications, through: :system_notification_histories + # Groups and active users scope :active, lambda { where(status: [STATUS_ACTIVE, STATUS_EDIT_INFO]) } scope :like, lambda { |keywords| @@ -190,6 +191,7 @@ class User < Owner :technical_title, :province, :city, :custom_department, to: :user_extension, allow_nil: true before_save :update_hashed_password, :set_lastname + after_save :reset_cache_data after_create do SyncTrustieJob.perform_later("user", 1) if allow_sync_to_trustie? end @@ -206,6 +208,10 @@ class User < Owner validate :validate_sensitive_string validate :validate_password_length + def reset_cache_data + Cache::V2::OwnerCommonService.new(self.id).reset + end + # 用户参与的所有项目 def full_member_projects normal_projects = Project.members_projects(self.id).to_sql @@ -435,6 +441,7 @@ class User < Owner def activate! update_attribute(:status, STATUS_ACTIVE) + prohibit_gitea_user_login!(false) end def register! @@ -443,6 +450,12 @@ class User < Owner def lock! update_attribute(:status, STATUS_LOCKED) + prohibit_gitea_user_login! + end + + def prohibit_gitea_user_login!(prohibit_login = true) + Gitea::User::UpdateInteractor.call(self.login, + {email: self.mail, prohibit_login: prohibit_login}) end def need_edit_info! @@ -690,7 +703,7 @@ class User < Owner end def self.generate_salt - Educoder::Utils.random_hex(16) + Gitlink::Utils.random_hex(16) end # 全部已认证 diff --git a/app/models/watcher.rb b/app/models/watcher.rb index 6a8c94fcc..5a2cd96fb 100644 --- a/app/models/watcher.rb +++ b/app/models/watcher.rb @@ -22,18 +22,36 @@ class Watcher < ApplicationRecord scope :watching_users, ->(watchable_id){ where("watchable_type = ? and user_id = ?",'User',watchable_id)} - after_save :reset_cache_data - after_destroy :reset_cache_data - after_create :send_create_message_to_notice_system + after_create :send_create_message_to_notice_system, :incre_project_common, :incre_user_statistic, :incre_platform_statistic + after_destroy :decre_project_common, :decre_user_statistic, :decre_platform_statistic - def reset_cache_data - if self.watchable.is_a?(User) - self.reset_user_cache_async_job(self.watchable) - end - if self.watchable.is_a?(Project) - self.reset_user_cache_async_job(self.watchable&.owner) - end - self.reset_platform_cache_async_job + + def incre_project_common + CacheAsyncSetJob.perform_later("project_common_service", {watchers: 1}, self.watchable_id) if self.watchable_type == "Project" + end + + def decre_project_common + CacheAsyncSetJob.perform_later("project_common_service", {watchers: -1}, self.watchable_id) if self.watchable_type == "Project" + end + + def incre_user_statistic + CacheAsyncSetJob.perform_later("user_statistic_service", {follow_count: 1}, self.watchable_id) if self.watchable_type == "User" + CacheAsyncSetJob.perform_later("user_statistic_service", {project_watcher_count: 1}, self.watchable&.user_id) if self.watchable_type == "Project" + end + + def decre_user_statistic + CacheAsyncSetJob.perform_later("user_statistic_service", {follow_count: -1}, self.watchable_id) if self.watchable_type == "User" + CacheAsyncSetJob.perform_later("user_statistic_service", {project_watcher_count: -1}, self.watchable&.user_id) if self.watchable_type == "Project" + end + + def incre_platform_statistic + CacheAsyncSetJob.perform_later("platform_statistic_service", {follow_count: 1}) if self.watchable_type == "User" + CacheAsyncSetJob.perform_later("platform_statistic_service", {project_watcher_count: 1}) if self.watchable_type == "Project" + end + + def decre_platform_statistic + CacheAsyncSetJob.perform_later("platform_statistic_service", {follow_count: -1}) if self.watchable_type == "User" + CacheAsyncSetJob.perform_later("platform_statistic_service", {project_watcher_count: -1}) if self.watchable_type == "Project" end def send_create_message_to_notice_system diff --git a/app/queries/admins/course_list_query.rb b/app/queries/admins/course_list_query.rb deleted file mode 100644 index 84868b7d0..000000000 --- a/app/queries/admins/course_list_query.rb +++ /dev/null @@ -1,30 +0,0 @@ -class Admins::CourseListQuery < ApplicationQuery - include CustomSortable - - attr_reader :params - - sort_columns :created_at, default_by: :created_at, default_direction: :desc - - def initialize(params) - @params = params - end - - def call - course_lists = CourseList.all - - # 关键字模糊查询 - keyword = params[:keyword].to_s.strip - if keyword.present? - search_type = params[:search_type] || "0" - case search_type - when "0" - course_lists = course_lists.joins(:user) - .where('CONCAT(lastname, firstname) like :keyword OR users.nickname like :keyword', keyword: "%#{keyword}%") - when "1" - course_lists = course_lists.where('name like :keyword', keyword: "%#{keyword}%") - end - end - - custom_sort(course_lists, params[:sort_by], params[:sort_direction]) - end -end \ No newline at end of file diff --git a/app/queries/admins/course_query.rb b/app/queries/admins/course_query.rb deleted file mode 100644 index 6fbbc002e..000000000 --- a/app/queries/admins/course_query.rb +++ /dev/null @@ -1,44 +0,0 @@ -class Admins::CourseQuery < ApplicationQuery - include CustomSortable - - attr_reader :params - - sort_columns :created_at, default_by: :created_at, default_direction: :desc, default_table: 'courses' - - def initialize(params) - @params = params - end - - def call - courses = Course.all - - courses = courses.where(id: params[:id]) if params[:id].present? - - # 状态过滤 - status = - case params[:status].to_s.strip - when 'processing' then 0 - when 'ended' then 1 - end - courses = courses.where(is_end: status) if status - - # 单位 - if params[:school_id].present? - courses = courses.where(school_id: params[:school_id]) - end - - # 首页展示 - if params[:homepage_show].present? && params[:homepage_show].to_s == 'true' - courses = courses.where(homepage_show: true) - end - - # 关键字 - keyword = params[:keyword].to_s.strip - if keyword - sql = 'CONCAT(lastname, firstname) LIKE :keyword OR users.nickname LIKE :keyword OR courses.name LIKE :keyword OR course_lists.name LIKE :keyword' - courses = courses.joins(:teacher, :course_list).where(sql, keyword: "%#{keyword}%") - end - - custom_sort(courses, params[:sort_by], params[:sort_direction]) - end -end \ No newline at end of file diff --git a/app/queries/admins/department_apply_query.rb b/app/queries/admins/department_apply_query.rb deleted file mode 100644 index 500536ddb..000000000 --- a/app/queries/admins/department_apply_query.rb +++ /dev/null @@ -1,25 +0,0 @@ -class Admins::DepartmentApplyQuery < ApplicationQuery - include CustomSortable - - attr_reader :params - - sort_columns :created_at, default_by: :created_at, default_direction: :desc - - def initialize(params) - @params = params - end - - def call - status = params[:status] - - applies = ApplyAddDepartment.where(status: status) if status.present? - - # 关键字模糊查询 - keyword = params[:keyword].to_s.strip - if keyword.present? - applies = applies.where('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/queries/admins/department_query.rb b/app/queries/admins/department_query.rb deleted file mode 100644 index f0b8c5d24..000000000 --- a/app/queries/admins/department_query.rb +++ /dev/null @@ -1,32 +0,0 @@ -class Admins::DepartmentQuery < ApplicationQuery - include CustomSortable - - attr_reader :params - - sort_columns :created_at, default_by: :created_at, default_direction: :desc - - def initialize(params) - @params = params - end - - def call - departments = Department.where(is_auth: true).without_deleted - - keyword = params[:keyword].to_s.strip - if keyword.present? - departments = departments.joins(:school) - .where('schools.name LIKE :keyword OR departments.name LIKE :keyword', keyword: "%#{keyword}%") - end - - if params[:with_member].to_s == 'true' - subquery = DepartmentMember.where('department_id = departments.id').select('1 AS one').to_sql - departments = departments.where("EXISTS(#{subquery})") - end - - if params[:with_identifier].to_s == 'true' - departments = departments.where.not(identifier: nil).where.not(identifier: '') - end - - custom_sort(departments, params[:sort_by], params[:sort_direction]) - end -end \ No newline at end of file diff --git a/app/queries/admins/laboratory_shixun_query.rb b/app/queries/admins/laboratory_shixun_query.rb deleted file mode 100644 index da7867194..000000000 --- a/app/queries/admins/laboratory_shixun_query.rb +++ /dev/null @@ -1,36 +0,0 @@ -class Admins::LaboratoryShixunQuery < ApplicationQuery - attr_reader :laboratory, :params - - def initialize(laboratory, params) - @laboratory = laboratory - @params = params - end - - def call - laboratory_shixuns = laboratory.laboratory_shixuns.joins(:shixun) - - keyword = params[:keyword].to_s.strip - if keyword.present? - like_sql = 'shixuns.name LIKE :keyword OR CONCAT(users.lastname, users.firstname) LIKE :keyword OR users.nickname LIKE :keyword' - laboratory_shixuns = laboratory_shixuns.joins(shixun: :user).where(like_sql, keyword: "%#{keyword}%") - end - - # 实训状态 - laboratory_shixuns = laboratory_shixuns.where(shixuns: { status: params[:status] }) if params[:status].present? - - # 技术平台 - if params[:tag_id].present? - laboratory_shixuns = laboratory_shixuns.joins(shixun: :shixun_mirror_repositories) - .where(shixun_mirror_repositories: { mirror_repository_id: params[:tag_id] }) - end - - # 首页展示、单位自建 - %i[homepage ownership].each do |column| - if params[column].present? && params[column].to_s == 'true' - laboratory_shixuns = laboratory_shixuns.where(column => true) - end - end - - laboratory_shixuns - end -end \ No newline at end of file diff --git a/app/queries/admins/school_query.rb b/app/queries/admins/school_query.rb deleted file mode 100644 index 3206f0858..000000000 --- a/app/queries/admins/school_query.rb +++ /dev/null @@ -1,23 +0,0 @@ -class Admins::SchoolQuery < ApplicationQuery - include CustomSortable - - attr_reader :params - - sort_columns :users_count, :created_at, default_by: :created_at, default_direction: :desc - - def initialize(params) - @params = params - end - - def call - schools = School.all - - keyword = strip_param(:keyword) - Rails.logger.info("###########{keyword}") - if keyword - schools = schools.where('schools.name LIKE ?', "%#{keyword}%") - end - schools = schools.left_joins(:user_extensions).select('schools.*, IFNULL(count(user_extensions.user_id),0) users_count').group('schools.id') - custom_sort schools, params[:sort_by], params[:sort_direction] - end -end \ No newline at end of file diff --git a/app/queries/admins/subject_query.rb b/app/queries/admins/subject_query.rb deleted file mode 100644 index 3596c7715..000000000 --- a/app/queries/admins/subject_query.rb +++ /dev/null @@ -1,49 +0,0 @@ -class Admins::SubjectQuery < ApplicationQuery - include CustomSortable - - attr_reader :params - - sort_columns :created_at, default_by: :created_at, default_direction: :desc, default_table: 'subjects' - - def initialize(params) - @params = params - end - - def call - subjects = Subject.all - - subjects = subjects.where(id: params[:id]) if params[:id].present? - - # 状态过滤 - status = - case params[:status].to_s.strip - when "editing" then {status: 0} - when "applying" then {status: 2, public: [0, 1]} - when "pending" then {public: 1} - when "published" then {public: 2} - end - - subjects = subjects.where(status) if status - - # 创建者单位 - if params[:school_id].present? - subjects = subjects.joins(user: :user_extension).where(user_extensions: { school_id: params[:school_id] }) - end - - # 首页展示、金课 - %i[homepage_show excellent].each do |column| - if params[column].present? && params[column].to_s == 'true' - subjects = subjects.where(column => true) - end - end - - # 关键字 - keyword = params[:keyword].to_s.strip - if keyword - sql = 'CONCAT(lastname, firstname) LIKE :keyword OR users.nickname LIKE :keyword OR subjects.name LIKE :keyword' - subjects = subjects.joins(:user).where(sql, keyword: "%#{keyword}%") - end - - custom_sort(subjects, params[:sort_by], params[:sort_direction]) - end -end \ No newline at end of file diff --git a/app/queries/projects/list_query.rb b/app/queries/projects/list_query.rb index 4658408d2..b06791bd3 100644 --- a/app/queries/projects/list_query.rb +++ b/app/queries/projects/list_query.rb @@ -11,19 +11,45 @@ class Projects::ListQuery < ApplicationQuery end def call - q = Project.visible.by_name_or_identifier(params[:search]) - - scope = q - .with_project_type(params[:project_type]) - .with_project_category(params[:category_id]) - .with_project_language(params[:language_id]) + collection = Project.all + collection = filter_projects(collection) sort = params[:sort_by] || "updated_on" sort_direction = params[:sort_direction] || "desc" - custom_sort(scope, sort, sort_direction) + custom_sort(collection, sort, sort_direction) # scope = scope.reorder("projects.#{sort} #{sort_direction}") # scope end + + def filter_projects(collection) + collection = by_pinned(collection) + collection = by_search(collection) + collection = by_project_type(collection) + collection = by_project_category(collection) + collection = by_project_language(collection) + collection + end + + def by_search(items) + items.visible.by_name_or_identifier(params[:search]) + end + + def by_project_type(items) + items.with_project_type(params[:project_type]) + end + + def by_project_category(items) + items.with_project_category(params[:category_id]) + end + + def by_project_language(items) + items.with_project_language(params[:language_id]) + end + + def by_pinned(items) + (params[:pinned].present? && params[:category_id].present?) ? items.pinned : items + end + end diff --git a/app/queries/users/video_query.rb b/app/queries/users/video_query.rb deleted file mode 100644 index cfaa314cc..000000000 --- a/app/queries/users/video_query.rb +++ /dev/null @@ -1,28 +0,0 @@ -class Users::VideoQuery < ApplicationQuery - include CustomSortable - - sort_columns :published_at, :title, default_by: :published_at, default_direction: :desc - - attr_reader :user, :params - - def initialize(user, params) - @user = user - @params = params - end - - def call - videos = user.videos - - videos = - case params[:status] - when 'published' then videos.published - when 'processing' then videos.processing - else videos.published - end - - keyword = params[:keyword].to_s.strip - videos = videos.where('title LIKE ?', "%#{keyword}%") if keyword.present? - - custom_sort(videos, params[:sort_by], params[:sort_direction]) - end -end \ No newline at end of file diff --git a/app/queries/weapps/search_query.rb b/app/queries/weapps/search_query.rb deleted file mode 100644 index 665480073..000000000 --- a/app/queries/weapps/search_query.rb +++ /dev/null @@ -1,37 +0,0 @@ -class Weapps::SearchQuery < ApplicationQuery - include ElasticsearchAble - - attr_reader :params - - def initialize(params) - @params = params - end - - def call - modal_name.search(keyword, search_options) - end - - private - - def search_options - hash = { - fields: [:name], - page: page, - per_page: per_page - } - hash.merge(where: { status: 2 }) if modal_name == Shixun - - hash - end - - def modal_name - @_modal_name ||= begin - case params[:type].to_s - when 'subject' then Subject - when 'shixun' then Shixun - when 'course' then Course - else Subject - end - end - end -end \ No newline at end of file diff --git a/app/queries/weapps/subject_query.rb b/app/queries/weapps/subject_query.rb deleted file mode 100644 index 73e70160a..000000000 --- a/app/queries/weapps/subject_query.rb +++ /dev/null @@ -1,37 +0,0 @@ -class Weapps::SubjectQuery < ApplicationQuery - include CustomSortable - attr_reader :params - - def initialize(current_laboratory, params) - @current_laboratory = current_laboratory - @params = params - end - - def call - subjects = @current_laboratory.subjects.unhidden.publiced.show_moblied - - # 课程体系的过滤 - if params[:sub_discipline_id].present? - subjects = subjects.joins(:sub_disciplines).where(sub_disciplines: {id: params[:sub_discipline_id]}) - elsif params[:discipline_id].present? - subjects = subjects.joins(:sub_disciplines).where(sub_disciplines: {discipline_id: params[:discipline_id]}) - else - subjects = subjects.joins(:sub_discipline_containers).where(sub_discipline_containers: {container_type: "Subject"}) - end - - subjects = subjects.left_joins(:shixuns).select('subjects.id, subjects.name, subjects.excellent, subjects.stages_count, subjects.status, subjects.homepage_show, - subjects.shixuns_count, subjects.updated_at, IFNULL(sum(shixuns.myshixuns_count), 0) myshixuns_count') - .group('subjects.id').order("subjects.homepage_show #{sort_type}, #{order_type} #{sort_type}") - subjects - end - - private - - def order_type - Subject.column_names.include?(params[:order]) ? params[:order] : 'updated_at' - end - - def sort_type - %w(desc asc).include?(params[:sort]) ? params[:sort] : "desc" - end -end \ No newline at end of file diff --git a/app/services/accounts/reset_password_service.rb b/app/services/accounts/reset_password_service.rb new file mode 100644 index 000000000..5202fe77a --- /dev/null +++ b/app/services/accounts/reset_password_service.rb @@ -0,0 +1,30 @@ +module Accounts + class ResetPasswordService < ApplicationService + # login、code、password、password_confirmation + def initialize(user, params) + @user = user + @password = params[:password] + @password_confirmation = params[:password_confirmation] + end + + def call + return if @user.blank? + password = strip(@password) + password_confirmation = strip(@password_confirmation) + + Rails.logger.info "Accounts::ResetPasswordService params: + ##### password: #{@password} password_confirmation: #{@password_confirmation}" + + @user.password, @user.password_confirmation = password, password_confirmation + + sync_params = { + password: password, + email: @user.mail + } + interactor = Gitea::User::UpdateInteractor.call(@user.login, sync_params) + raise ActiveRecord::Rollback unless interactor.success? + + @user + end + end +end diff --git a/app/services/admins/add_department_member_service.rb b/app/services/admins/add_department_member_service.rb deleted file mode 100644 index f8331cf4a..000000000 --- a/app/services/admins/add_department_member_service.rb +++ /dev/null @@ -1,20 +0,0 @@ -class Admins::AddDepartmentMemberService < ApplicationService - - attr_reader :department, :params - - def initialize(department, params) - @department = department - @params = params - end - - def call - columns = %i[] - DepartmentMember.bulk_insert(*columns) do |worker| - Array.wrap(params[:user_ids]).compact.each do |user_id| - next if department.department_members.exists?(user_id: user_id) - - worker.add(department_id: department.id, user_id: user_id) - end - end - end -end \ No newline at end of file diff --git a/app/services/admins/check_shixun_mirrors_service.rb b/app/services/admins/check_shixun_mirrors_service.rb deleted file mode 100644 index 4aa0af4cf..000000000 --- a/app/services/admins/check_shixun_mirrors_service.rb +++ /dev/null @@ -1,89 +0,0 @@ -class Admins::CheckShixunMirrorsService < ApplicationService - Error = Class.new(StandardError) - - def call - bridge_images - - ActiveRecord::Base.transaction do - check_sync_mirrors! - - check_mirrors! - end - end - - private - - def mirrors - bridge_images['images'] - end - - def sync_mirrors - bridge_images['imagesNotSync'] - end - - def check_mirrors! - return if mirrors.blank? - image_names = [] - - mirrors.each do |data| - mirror = JSON.parse(data) - - name_repository = MirrorRepository.find_by(name: mirror['imageName']) - id_repository = MirrorRepository.find_by(mirrorID: mirror['imageID']) - - image_names << mirror['imageName'] - - if name_repository.blank? && id_repository.present? # 镜像名称被修改 - id_repository.update_column(:status, 2) - MirrorOperationRecord.create!(mirror_repository_id: id_repository.id, mirror_id: mirror['imageID'], - mirror_name: mirror['imageName'], status: 2, user_id: -1) - elsif name_repository.blank? # 镜像不存在、创建镜像 - new_repository = MirrorRepository.create!(mirrorID: mirror['imageID'], name: mirror['imageName']) - MirrorOperationRecord.create!(mirror_repository_id: new_repository.id, mirror_id: mirror['imageID'], - mirror_name: mirror['imageName'], status: 0, user_id: -1) - elsif name_repository.mirrorID != mirror['imageID'] # 镜像ID被修改 - name_repository.update_column(:status, 2) - MirrorOperationRecord.create!(mirror_repository_id: name_repository.id, mirror_id: mirror['imageID'], - mirror_name: mirror['imageName'], status: 1, user_id: -1) - end - end - - # 判断中间层镜像是否被删除 - MirrorRepository.find_each do |mirror| - next if mirror&.name.blank? || image_names.index(mirror.name) - - mirror.update_column(:status, 4) - MirrorOperationRecord.create!(mirror_repository_id: mirror.id, mirror_id: mirror&.mirrorID, - mirror_name: mirror.name, status: 3, user_id: -1) - end - end - - def check_sync_mirrors! - return if sync_mirrors.blank? - - sync_mirrors.each do |data| - mirror = JSON.parse(data) - - repository = MirrorRepository.find_by(name: mirror['imageName']) - next if repository.blank? || repository.status != 1 - - repository.update_column(:status, 5) - MirrorOperationRecord.create!(mirror_repository_id: repository.id, mirror_id: mirror['imageID'], - mirror_name: mirror['imageName'], status: 4, user_id: -1) - end - end - - def bridge_images - @_bridge_images ||= begin - url = "#{EduSetting.get('cloud_bridge')}/bridge/docker/images" - res = Faraday.get(url) - res = JSON.parse(res.body) - raise Error, '拉取镜像信息异常' if res && res['code'] != 0 - - res - rescue => e - Rails.logger.error("get response failed ! #{e.message}") - raise Error, '实训云平台繁忙(繁忙等级:84)' - end - end -end \ No newline at end of file diff --git a/app/services/admins/drag_cooperative_service.rb b/app/services/admins/drag_cooperative_service.rb deleted file mode 100644 index 241b7eb11..000000000 --- a/app/services/admins/drag_cooperative_service.rb +++ /dev/null @@ -1,35 +0,0 @@ -class Admins::DragCooperativeService < ApplicationService - Error = Class.new(StandardError) - - attr_reader :move, :after - - def initialize(move, after) - @move = move - @after = after # 移动后下一个位置的元素 - end - - def call - return if move.position + 1 == after&.position # 未移动 - raise Error, '未知错误' if after && move.img_type != after.img_type - - coo_imgs = CooImg.where(img_type: move.img_type) - - ActiveRecord::Base.transaction do - if after.blank? # 移动至末尾 - total = coo_imgs.count - - coo_imgs.where('position > ?', move.position).update_all('position = position - 1') - move.update!(position: total) - return - end - - if move.position > after.position # 前移 - coo_imgs.where('position >= ? AND position < ?', after.position, move.position).update_all('position = position + 1') - move.update!(position: after.position) - else # 后移 - coo_imgs.where('position > ? AND position <= ?', move.position, after.position).update_all('position = position - 1') - move.update!(position: after.position) - end - end - end -end \ No newline at end of file diff --git a/app/services/admins/drag_portal_image_service.rb b/app/services/admins/drag_portal_image_service.rb deleted file mode 100644 index 5555c08b2..000000000 --- a/app/services/admins/drag_portal_image_service.rb +++ /dev/null @@ -1,35 +0,0 @@ -class Admins::DragPortalImageService < ApplicationService - Error = Class.new(StandardError) - - attr_reader :laboratory, :move, :after - - def initialize(laboratory, move, after) - @laboratory = laboratory - @move = move - @after = after # 移动后下一个位置的元素 - end - - def call - return if move.position + 1 == after&.position # 未移动 - - images = laboratory.portal_images - - ActiveRecord::Base.transaction do - if after.blank? || move.id == after.id # 移动至末尾 - total = images.count - - images.where('position > ?', move.position).update_all('position = position - 1') - move.update!(position: total) - return - end - - if move.position > after.position # 前移 - images.where('position >= ? AND position < ?', after.position, move.position).update_all('position = position + 1') - move.update!(position: after.position) - else # 后移 - images.where('position > ? AND position < ?', move.position, after.position).update_all('position = position - 1') - move.update!(position: after.position - 1) - end - end - end -end \ No newline at end of file diff --git a/app/services/admins/drag_weapp_advert_service.rb b/app/services/admins/drag_weapp_advert_service.rb deleted file mode 100644 index 8bfb7c317..000000000 --- a/app/services/admins/drag_weapp_advert_service.rb +++ /dev/null @@ -1,32 +0,0 @@ -class Admins::DragWeappAdvertService < ApplicationService - attr_reader :move, :after - - def initialize(move, after) - @move = move - @after = after # 移动后下一个位置的元素 - end - - def call - return if move.position + 1 == after&.position # 未移动 - - adverts = WeappSettings::Advert.all - - ActiveRecord::Base.transaction do - if after.blank? || move.id == after.id # 移动至末尾 - total = adverts.count - - adverts.where('position > ?', move.position).update_all('position = position - 1') - move.update!(position: total) - return - end - - if move.position > after.position # 前移 - adverts.where('position >= ? AND position < ?', after.position, move.position).update_all('position = position + 1') - move.update!(position: after.position) - else # 后移 - adverts.where('position > ? AND position < ?', move.position, after.position).update_all('position = position - 1') - move.update!(position: after.position - 1) - end - end - end -end \ No newline at end of file diff --git a/app/services/admins/drag_weapp_carousel_service.rb b/app/services/admins/drag_weapp_carousel_service.rb deleted file mode 100644 index f0b3832b2..000000000 --- a/app/services/admins/drag_weapp_carousel_service.rb +++ /dev/null @@ -1,32 +0,0 @@ -class Admins::DragWeappCarouselService < ApplicationService - attr_reader :move, :after - - def initialize(move, after) - @move = move - @after = after # 移动后下一个位置的元素 - end - - def call - return if move.position + 1 == after&.position # 未移动 - - carousels = WeappSettings::Carousel.all - - ActiveRecord::Base.transaction do - if after.blank? || move.id == after.id # 移动至末尾 - total = carousels.count - - carousels.where('position > ?', move.position).update_all('position = position - 1') - move.update!(position: total) - return - end - - if move.position > after.position # 前移 - carousels.where('position >= ? AND position < ?', after.position, move.position).update_all('position = position + 1') - move.update!(position: after.position) - else # 后移 - carousels.where('position > ? AND position < ?', move.position, after.position).update_all('position = position - 1') - move.update!(position: after.position - 1) - end - end - end -end \ No newline at end of file diff --git a/app/services/admins/import_course_member_service.rb b/app/services/admins/import_course_member_service.rb deleted file mode 100644 index 3ea559766..000000000 --- a/app/services/admins/import_course_member_service.rb +++ /dev/null @@ -1,63 +0,0 @@ -class Admins::ImportCourseMemberService < ApplicationService - Error = Class.new(StandardError) - - attr_reader :file, :result - - def initialize(file) - @file = file - @result = { success: 0, fail: [] } - end - - def call - raise Error, '文件不存在' if file.blank? - - excel = Admins::ImportCourseMemberExcel.new(file) - excel.read_each(&method(:create_course_member)) - - result - rescue ApplicationImport::Error => ex - raise Error, ex.message - end - - private - - def create_course_member(data) - raise '课堂角色必须为 2、3、4' unless [2, 3, 4].include?(data.role.to_i) - - user = User.joins(:user_extension).where(user_extensions: { student_id: data.student_id, school_id: data.school_id }).first - raise '该学号的用户不存在' if user.blank? - course = Course.find_by(id: data.course_id) - raise '该课堂不存在' if course.blank? - - course_group = nil - if data.course_group_name.present? - course_group = course.course_groups.find_or_create_by!(name: data.course_group_name) - end - - member = course.course_members.find_by(user_id: user.id, role: data.role.to_i) - # 如果已是课堂成员且是学生身份and不在指定的分班则移动到该分班 - if member.present? && member.role == 'STUDENT' && course_group && member.course_group_id != course_group&.id.to_i - member.update!(course_group_id: course_group&.id.to_i) - elsif member.blank? - course.course_members.create!(user_id: user.id, role: data.role.to_i, course_group_id: course_group&.id.to_i) - extra = - case data.role.to_i - when 2 then 9 - when 3 then 7 - else 10 - end - - Tiding.create!(user_id: user.id, trigger_user_id: course.tea_id, container_id: course.id, - container_type: 'TeacherJoinCourse', belong_container_id: course.id, - belong_container_type: 'Course', tiding_type: 'System', extra: extra) - end - - result[:success] += 1 - rescue Exception => ex - fail_data = data.as_json - fail_data[:data] = fail_data.values.join(',') - fail_data[:message] = ex.message - - result[:fail] << fail_data - end -end \ No newline at end of file diff --git a/app/services/admins/school_daily_statistic_service.rb b/app/services/admins/school_daily_statistic_service.rb deleted file mode 100644 index 64bb97864..000000000 --- a/app/services/admins/school_daily_statistic_service.rb +++ /dev/null @@ -1,123 +0,0 @@ -class Admins::SchoolDailyStatisticService < ApplicationService - include CustomSortable - - attr_reader :params - - sort_columns :student_count, :teacher_count, :homework_count, :other_homework_count, - :course_count, :active_course_count, :nearly_course_time, :shixun_count, :shixun_evaluate_count, - default_by: :teacher_count, default_direction: :desc - - def initialize(params) - @params = params - end - - def call - schools = School.group('schools.id') - - keyword = params[:keyword].try(:to_s).try(:strip) - if keyword.present? - schools = schools.where("schools.name LIKE :keyword OR schools.id LIKE :keyword", keyword: "%#{keyword}%") - end - - count = schools.count.count - - # 根据排序字段进行查询 - schools = query_by_sort_column(schools, params[:sort_by]) - schools = custom_sort(schools, params[:sort_by], params[:sort_direction]) - - schools = schools.limit(page_size).offset(offset) - # 查询并组装其它数据 - schools = package_other_data(schools) - - [count, schools] - end - - def package_other_data(schools) - ids = schools.map(&:id) - - student_map = UserExtension.where(school_id: ids, identity: :student).group(:school_id).count - teacher_map = UserExtension.where(school_id: ids, identity: :teacher).group(:school_id).count - - homeworks = HomeworkCommon.joins(:course) - shixun_homework_map = homeworks.where(homework_type: 4, courses: { school_id: ids }).group('school_id').count - other_homework_map = homeworks.where(homework_type: [1, 3], courses: { school_id: ids }).group('school_id').count - - courses = Course.where(is_delete: 0, school_id: ids).group('school_id') - course_map = courses.count - nearly_course_time_map = courses.joins(:course_acts).maximum('course_activities.updated_at') - active_course_map = courses.where(is_end: false).count - - shixun_map = Shixun.joins(user: :user_extension).where(user_extensions: { identity: :teacher, school_id: ids }) - .where(fork_from: nil).group('school_id').count - - reports = SchoolReport.where(school_id: ids) - evaluate_count_map = reports.each_with_object({}) { |report, obj| obj[report.school_id] = report.shixun_evaluate_count } - - schools.map do |school| - { - id: school.id, - name: school.name, - teacher_count: teacher_map[school.id], - student_count: student_map[school.id], - homework_count: shixun_homework_map[school.id], - other_homework_count: other_homework_map[school.id], - course_count: course_map[school.id], - nearly_course_time: nearly_course_time_map[school.id], - active_course_count: active_course_map[school.id], - shixun_count: shixun_map.fetch(school.id, 0), - shixun_evaluate_count: evaluate_count_map.fetch(school.id, 0) - } - end - end - - private - def query_by_sort_column(schools, sort_by_column) - base_query_column = 'schools.id, schools.name' - - case sort_by_column.to_s - when 'teacher_count' then - schools.joins('LEFT JOIN user_extensions ue ON ue.school_id = schools.id AND ue.identity = 0') - .select("#{base_query_column}, COUNT(*) teacher_count") - when 'student_count' then - schools.joins('LEFT JOIN user_extensions ue ON ue.school_id = schools.id AND ue.identity = 1') - .select("#{base_query_column}, COUNT(*) student_count") - when 'homework_count' then - schools.joins('LEFT JOIN courses ON courses.school_id = schools.id') - .joins('LEFT JOIN homework_commons hc ON hc.course_id = courses.id AND hc.homework_type = 4') - .select("#{base_query_column}, COUNT(*) homework_count") - when 'other_homework_count' then - schools.joins('LEFT JOIN courses ON courses.school_id = schools.id') - .joins('LEFT JOIN homework_commons hc ON hc.course_id = courses.id AND hc.homework_type IN (1, 3)') - .select("#{base_query_column}, COUNT(*) other_homework_count") - when 'course_count' then - schools.joins('LEFT JOIN courses cs ON cs.school_id = schools.id AND cs.is_delete = 0') - .select("#{base_query_column}, COUNT(*) course_count") - when 'shixun_count' then - schools.joins('LEFT JOIN user_extensions ue ON ue.school_id = schools.id AND ue.identity = 0') - .joins('LEFT JOIN users ON users.id = ue.user_id') - .joins('LEFT JOIN shixuns sx ON sx.user_id = users.id AND sx.fork_from IS NULL') - .select("#{base_query_column}, COUNT(*) shixun_count") - when 'shixun_evaluate_count' then - schools.joins('LEFT JOIN school_reports ON school_reports.school_id = schools.id') - .select("#{base_query_column}, shixun_evaluate_count") - when 'nearly_course_time' then - schools.joins('LEFT JOIN courses cs ON cs.school_id = schools.id AND cs.is_delete = 0') - .joins('LEFT JOIN course_activities acs ON acs.course_id = cs.id') - .select("#{base_query_column}, MAX(acs.updated_at) nearly_course_time") - when 'active_course_count' then - schools.joins('LEFT JOIN courses cs ON cs.school_id = schools.id AND cs.is_delete = 0 AND cs.is_end = false') - .select("#{base_query_column}, COUNT(*) active_course_count") - else - schools.joins('LEFT JOIN user_extensions ue ON ue.school_id = schools.id AND ue.identity = 0') - .select("#{base_query_column}, COUNT(*) teacher_count") - end - end - - def page_size - params[:per_page] || 20 - end - - def offset - (params[:page].to_i.zero? ? 0 : params[:page].to_i - 1) * page_size - end -end \ No newline at end of file diff --git a/app/services/admins/shixun_auths/agree_apply_service.rb b/app/services/admins/shixun_auths/agree_apply_service.rb deleted file mode 100644 index b8875cf09..000000000 --- a/app/services/admins/shixun_auths/agree_apply_service.rb +++ /dev/null @@ -1,43 +0,0 @@ -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!(public: 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 deleted file mode 100644 index 76d420e53..000000000 --- a/app/services/admins/shixun_auths/refuse_apply_service.rb +++ /dev/null @@ -1,35 +0,0 @@ -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!(public: 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/statistic_school_contrast_data_service.rb b/app/services/admins/statistic_school_contrast_data_service.rb deleted file mode 100644 index 0496b1371..000000000 --- a/app/services/admins/statistic_school_contrast_data_service.rb +++ /dev/null @@ -1,80 +0,0 @@ -class Admins::StatisticSchoolContrastDataService < ApplicationService - ParameterError = Class.new(StandardError) - - PAGE_SIZE = 20 - CONTRAST_COLUMN_LIST = %w( - teacher_increase_count student_increase_count course_increase_count - shixun_increase_count active_user_count shixun_homework_count shixun_evaluate_count - ).freeze - - attr_reader :params, :sort_direction, :contrast_column - - def initialize(params) - @params = params - @sort_direction = params[:sort_direction].to_s - @contrast_column = params[:contrast_column].to_s - end - - def call - validate_parameter! - reports = School.joins(:school_daily_reports).select(select_columns) - - keyword = params[:keyword].try(:to_s).try(:strip) - if keyword.present? - reports = reports.where("schools.name LIKE :keyword OR schools.id LIKE :keyword", keyword: "%#{keyword}%") - end - - count = reports.count('distinct(schools.id)') - - sql = query_report_sql(reports.group('schools.id').to_sql) - reports = SchoolDailyReport.find_by_sql(sql) - - [count, reports] - end - - private - def validate_parameter! - if %i[begin_date end_date other_begin_date other_end_date].any? { |key| params[key].blank? } - raise ParameterError - end - - unless %w(desc asc).include?(sort_direction) - raise ParameterError - end - - unless CONTRAST_COLUMN_LIST.include?(contrast_column) - raise ParameterError - end - end - - def format_date(date) - Time.zone.parse(date).strftime("%Y-%m-%d") - end - - def offset - (params[:page].to_i.zero? ? 0 : params[:page].to_i - 1) * PAGE_SIZE - end - - def select_columns - if contrast_column != 'active_user_count' - "schools.id school_id, schools.name school_name,"\ - "(SUM(IF(date BETWEEN '#{format_date(params[:begin_date])}' AND '#{format_date(params[:end_date])}', #{contrast_column}, 0))) total,"\ - "(SUM(IF(date BETWEEN '#{format_date(params[:other_begin_date])}' AND '#{format_date(params[:other_end_date])}', #{contrast_column}, 0))) other_total" - else - # 活跃用户对比时处理方法不同 - relations = SchoolDailyActiveUser.select('COUNT(distinct user_id)').joins(:school_daily_report) - .where('school_id = schools.id') - total_subquery = relations.where("date BETWEEN '#{format_date(params[:begin_date])}' AND '#{format_date(params[:end_date])}'").to_sql - other_total_subquery = relations.where("date BETWEEN '#{format_date(params[:other_begin_date])}' AND '#{format_date(params[:other_end_date])}'").to_sql - - "schools.id school_id, schools.name school_name, (#{total_subquery}) AS total, (#{other_total_subquery}) AS other_total" - end - end - - def query_report_sql(from_sql) - order_by = "(total = 0 AND other_total != 0) #{sort_direction}, (percentage != 0) #{sort_direction}, percentage #{sort_direction}" - - "SELECT reports.*, (other_total - total) increase, (IF(other_total - total = 0, 0.0, round((other_total - total) / IF(total = 0, 1, total), 5))) percentage "\ - "FROM (#{from_sql}) reports ORDER BY #{order_by} LIMIT #{PAGE_SIZE} OFFSET #{offset}" - end -end \ No newline at end of file diff --git a/app/services/admins/statistic_school_data_grow_service.rb b/app/services/admins/statistic_school_data_grow_service.rb deleted file mode 100644 index 8df106666..000000000 --- a/app/services/admins/statistic_school_data_grow_service.rb +++ /dev/null @@ -1,107 +0,0 @@ -class Admins::StatisticSchoolDataGrowService < ApplicationService - include CustomSortable - - PAGE_SIZE = 20 - - attr_reader :params - - sort_columns :teacher_increase_count, :student_increase_count, - :course_increase_count, :shixun_increase_count, :uniq_active_user_count, - :shixun_homework_count, :shixun_evaluate_count, - default_by: :teacher_increase_count, default_direction: :desc - - def initialize(params) - @params = params - end - - def call - reports = School.where(nil) - - reports = search_filter(reports) - - count = reports.count - - subquery = SchoolDailyActiveUser.select('COUNT(distinct(user_id))').joins(:school_daily_report) - .where(date_condition_sql).where("school_id is not null and school_id = schools.id").to_sql - reports = reports.joins("LEFT JOIN school_daily_reports sdr ON sdr.school_id = schools.id AND #{date_condition_sql}") - reports = reports.select( - 'schools.id school_id, schools.name school_name,'\ - 'SUM(teacher_increase_count) teacher_increase_count,'\ - 'SUM(student_increase_count) student_increase_count,'\ - 'SUM(course_increase_count) course_increase_count,'\ - 'SUM(shixun_increase_count) shixun_increase_count,'\ - 'SUM(shixun_homework_count) shixun_homework_count,'\ - 'SUM(shixun_evaluate_count) shixun_evaluate_count,'\ - "(#{subquery}) uniq_active_user_count,"\ - 'SUM(active_user_count) active_user_count').group('schools.id') - - reports = custom_sort(reports, params[:sort_by], params[:sort_direction]) - reports = reports.order('school_id asc').limit(PAGE_SIZE).offset(offset) - - [count, reports] - end - - def grow_summary - @_grow_summary ||= begin - reports = School.joins("LEFT JOIN school_daily_reports sdr ON sdr.school_id = schools.id") - .where(date_condition_sql) - - subquery = SchoolDailyActiveUser.select('COUNT(distinct user_id)') - .joins('LEFT JOIN school_daily_reports sdr ON sdr.id = school_daily_active_users.school_daily_report_id') - .where(date_condition_sql).to_sql - reports = search_filter(reports) - reports.select( - 'SUM(teacher_increase_count) teacher_increase_count,'\ - 'SUM(student_increase_count) student_increase_count,'\ - 'SUM(course_increase_count) course_increase_count,'\ - 'SUM(shixun_increase_count) shixun_increase_count,'\ - 'SUM(shixun_homework_count) shixun_homework_count,'\ - 'SUM(shixun_evaluate_count) shixun_evaluate_count,'\ - "(#{subquery}) uniq_active_user_count,"\ - 'SUM(active_user_count) active_user_count' - ).first - end - end - - private - - def search_filter(relations) - keyword = params[:keyword].try(:to_s).try(:strip) - if keyword.present? - relations = relations.where("schools.name LIKE :keyword OR schools.id LIKE :keyword", keyword: "%#{keyword}%") - end - - relations - end - - def date_condition_sql - date = query_date - if date.is_a?(Range) - "date BETWEEN '#{date.min.strftime('%Y-%m-%d')}' AND '#{date.max.strftime('%Y-%m-%d')}'" - else - "date = '#{date.strftime('%Y-%m-%d')}'" - end - end - - def query_date - if params[:grow_begin_date].present? - begin_time = Time.zone.parse(params[:grow_begin_date]) - end_date = if params[:grow_end_date].present? - Time.zone.parse(params[:grow_end_date]) - end - - end_date.blank? || end_date == begin_time ? begin_time : begin_time..end_date - else - yesterday - end - end - - def yesterday - # 每日凌晨5点为节点, 25日凌晨4点、3点、2点等等,未到更新数据时间点,看到的数据是:23日-24日的统计数据 - (Time.zone.now - 5.hours).beginning_of_day - 1.days - end - - def offset - (params[:page].to_i.zero? ? 0 : params[:page].to_i - 1) * PAGE_SIZE - 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 deleted file mode 100644 index ec5fec4bb..000000000 --- a/app/services/admins/subject_auths/agree_apply_service.rb +++ /dev/null @@ -1,30 +0,0 @@ -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!(public: 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 deleted file mode 100644 index 45f2d44d3..000000000 --- a/app/services/admins/subject_auths/refuse_apply_service.rb +++ /dev/null @@ -1,35 +0,0 @@ -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!(public: 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/services/admins/update_user_service.rb b/app/services/admins/update_user_service.rb index 6b1c0c857..34f704cbe 100644 --- a/app/services/admins/update_user_service.rb +++ b/app/services/admins/update_user_service.rb @@ -15,19 +15,13 @@ class Admins::UpdateUserService < ApplicationService user.firstname = '' user.password = params[:password] if params[:password].present? - if params[:identity].to_s == 'student' - params[:technical_title] = nil - else - params[:student_id] = nil - end user.user_extension.assign_attributes(user_extension_attributes) + old_login = user.login ActiveRecord::Base.transaction do user.save! user.user_extension.save! - user.update!(is_shixun_marker: true) if user.is_certification_teacher - - update_gitlab_password if params[:password].present? + update_gitea_user(old_login) end user @@ -36,7 +30,7 @@ class Admins::UpdateUserService < ApplicationService private def user_attributes - params.slice(*%i[lastname nickname mail phone admin business is_test + params.slice(*%i[lastname nickname mail phone admin business is_test login professional_certification authentication is_shixun_marker]) end @@ -44,10 +38,29 @@ class Admins::UpdateUserService < ApplicationService params.slice(*%i[gender identity technical_title student_id location location_city school_id department_id]) end - def update_gitlab_password - return if user.gid.blank? - # 同步修改gitlab密码 - Gitlab.client.edit_user(user.gid, password: params[:password]) + def gitea_user_params + hash = { + password: params[:password].to_s.presence, + email: user.mail, + login_name: params[:login].to_s.presence, + admin: boolean_admin + }.compact + + hash.delete_if {|_,v| v.to_s.strip == ''} + end + + def boolean_admin + admin = params[:admin].to_s.presence + case admin + when "0" then false + when "1" then true + end + end + + def update_gitea_user(old_login) + return if user.gitea_uid.blank? + + Gitea::User::UpdateInteractor.call(old_login, gitea_user_params) rescue Exception => ex Util.logger_error(ex) raise Error, '保存失败' diff --git a/app/services/application_service.rb b/app/services/application_service.rb index 2fa59ed29..81ecf5f7b 100644 --- a/app/services/application_service.rb +++ b/app/services/application_service.rb @@ -18,4 +18,9 @@ class ApplicationService def str_to_boolean str ActiveModel::Type::Boolean.new.cast str end + + def phone_mail_type value + value =~ /^1\d{10}$/ ? 1 : 0 + end + end diff --git a/app/services/atme_service.rb b/app/services/atme_service.rb new file mode 100644 index 000000000..623b32c09 --- /dev/null +++ b/app/services/atme_service.rb @@ -0,0 +1,37 @@ +class AtmeService < ApplicationService + Error = Class.new(StandardError) + + attr_reader :user, :receivers, :atmeable + + def initialize(user, receivers, atmeable) + @user = user + @receivers = receivers + @atmeable = atmeable + end + + def call + Rails.logger.info "[ATME] service args: [user]=>#{user}, [receivers]=>#{receivers}, [atmeable]=>#{atmeable}" + return if atmeable.nil? + Rails.logger.info "[ATME] atmeable class name is: #{ atmeable.class.name}" + case atmeable.class.name + when 'Issue' + message_source = 'IssueAtme' + when 'PullRequest' + message_source = 'PullRequestAtme' + when 'Journal' + journal = Journal.find_by_id(atmeable.id) + if journal.present? + if journal&.issue&.pull_request.present? + @atmeable = journal&.issue&.pull_request + message_source = 'PullRequestAtme' + else + @atmeable = journal&.issue + message_source = 'IssueAtme' + end + end + else + return + end + SendTemplateMessageJob.perform_now(message_source, receivers, user.id, @atmeable.id) if Site.has_notice_menu? + end +end diff --git a/app/services/cache/v2/owner_common_service.rb b/app/services/cache/v2/owner_common_service.rb new file mode 100644 index 000000000..c97e34d48 --- /dev/null +++ b/app/services/cache/v2/owner_common_service.rb @@ -0,0 +1,135 @@ +class Cache::V2::OwnerCommonService < ApplicationService + include AvatarHelper + attr_reader :owner_id, :name + attr_accessor :owner, :login, :email + + def initialize(owner_id, params={}) + @owner_id = owner_id + @email = params[:email] + @name = params[:name] + @avatar_url = params[:avatar_url] + end + + def read + owner_common + end + + def call + set_owner_common + end + + def reset + reset_owner_common + end + + def clear + clear_owner_common + end + + private + def load_owner + @owner = Owner.find_by_id @owner_id + @login = @owner&.login + @email ||= @owner&.mail + end + + def owner_common_key + "v2-owner-common:#{@login}-#{@email.to_s}" + end + + def owner_common_key_by_id + "v2-owner-common:#{@owner&.id}" + end + + def owner_common + result = $redis_cache.hgetall(owner_common_key_by_id) + result.blank? ? reset_owner_common : result + end + + def set_owner_common + if $redis_cache.hgetall(owner_common_key_by_id).blank? + reset_owner_common + return + else + load_owner + return if @owner.nil? + if @name.present? + if $redis_cache.hget(owner_common_key, "name").nil? + reset_owner_name + else + $redis_cache.hset(owner_common_key, "name", @name) + $redis_cache.hset(owner_common_key_by_id, "name", @name) + end + end + if @email.present? + if $redis_cache.hget(owner_common_key, "email").nil? + reset_owner_email + else + # 更改邮箱这里把旧数据删除 + $redis_cache.del("v2-owner-common:#{@login}-*") + $redis_cache.hset(owner_common_key, "email", @email) + $redis_cache.hset(owner_common_key_by_id, "email", @email) + end + end + if @avatar_url.present? + if $redis_cache.hget(owner_common_key, "avatar_url").nil? + reset_owner_avatar_url + else + $redis_cache.hset(owner_common_key, "avatar_url", @avatar_url) + $redis_cache.hset(owner_common_key_by_id, "avatar_url", @avatar_url) + end + + end + end + + $redis_cache.hgetall(owner_common_key) + end + def reset_owner_id + $redis_cache.hset(owner_common_key, "id", owner&.id) + $redis_cache.hset(owner_common_key_by_id, "id", owner&.id) + end + + def reset_owner_type + $redis_cache.hset(owner_common_key, "type", owner&.type) + $redis_cache.hset(owner_common_key_by_id, "type", owner&.type) + end + + def reset_owner_login + $redis_cache.hset(owner_common_key, "login", owner&.login) + $redis_cache.hset(owner_common_key_by_id, "login", owner&.login) + end + + def reset_owner_email + $redis_cache.hset(owner_common_key, "email", owner&.mail) + $redis_cache.hset(owner_common_key_by_id, "email", owner&.mail) + end + + def reset_owner_name + $redis_cache.hset(owner_common_key, "name", owner&.real_name) + $redis_cache.hset(owner_common_key_by_id, "name", owner&.real_name) + end + + def reset_owner_avatar_url + $redis_cache.hset(owner_common_key, "avatar_url", url_to_avatar(owner)) + $redis_cache.hset(owner_common_key_by_id, "avatar_url", url_to_avatar(owner)) + end + + def reset_owner_common + clear_owner_common + reset_owner_id + reset_owner_type + reset_owner_login + reset_owner_email + reset_owner_name + reset_owner_avatar_url + + $redis_cache.hgetall(owner_common_key) + end + + def clear_owner_common + load_owner + return if @owner.nil? + $redis_cache.del(owner_common_key) + $redis_cache.del(owner_common_key_by_id) + end +end \ No newline at end of file diff --git a/app/services/cache/v2/platform_statistic_service.rb b/app/services/cache/v2/platform_statistic_service.rb new file mode 100644 index 000000000..5bf4f4a74 --- /dev/null +++ b/app/services/cache/v2/platform_statistic_service.rb @@ -0,0 +1,184 @@ +class Cache::V2::PlatformStatisticService < ApplicationService + attr_reader :follow_count, :fork_count, :issue_count, :project_count, :project_language_count_key, :project_language_count, :project_praise_count, :project_watcher_count, :pullrequest_count + + def initialize(params={}) + @follow_count = params[:follow_count] + @fork_count = params[:fork_count] + @issue_count = params[:issue_count] + @project_count = params[:project_count] + @project_language_count_key = params[:project_language_count_key] + @project_language_count = params[:project_language_count] + @project_praise_count = params[:project_praise_count] + @project_watcher_count = params[:project_watcher_count] + @pullrequest_count = params[:pullrequest_count] + end + + def read + platform_statistic + end + + def call + set_platform_statistic + end + + def reset + reset_platform_statistic + end + + private + + def platform_statistic_key + "v2-platform-statistic" + end + + def follow_count_key + "follow-count" + end + + def fork_count_key + "fork-count" + end + + def issue_count_key + "issue-count" + end + + def project_count_key + "project-count" + end + + def project_language_key + "project-language" + end + + def project_praise_count_key + "project-praise-count" + end + + def project_watcher_count_key + "project-watcher-count" + end + + def pullrequest_count_key + "pullrequest-count" + end + + def platform_statistic + result = $redis_cache.hgetall(platform_statistic_key) + + result.blank? ? reset_platform_statistic : result + end + + def set_platform_statistic + if $redis_cache.hgetall(platform_statistic_key).blank? + reset_platform_statistic + return + end + if @follow_count.present? + if $redis_cache.hget(platform_statistic_key, follow_count_key).nil? + reset_platform_follow_count + else + $redis_cache.hincrby(platform_statistic_key, follow_count_key, @follow_count) + end + end + if @fork_count.present? + if $redis_cache.hget(platform_statistic_key, fork_count_key).nil? + reset_platform_fork_count + else + $redis_cache.hincrby(platform_statistic_key, fork_count_key, @fork_count) + end + end + if @issue_count.present? + if $redis_cache.hget(platform_statistic_key, issue_count_key).nil? + reset_platform_issue_count + else + $redis_cache.hincrby(platform_statistic_key, issue_count_key, @issue_count) + end + end + if @project_count.present? + if $redis_cache.hget(platform_statistic_key, project_count_key).nil? + reset_platform_project_count + else + $redis_cache.hincrby(platform_statistic_key, project_count_key, @project_count) + end + end + if @project_language_count_key.present? && project_language_count.present? + if $redis_cache.hget(platform_statistic_key, project_language_key).nil? + reset_platform_project_language + else + result = JSON.parse($redis_cache.hget(platform_statistic_key, project_language_key)) + result[@project_language_count_key] ||= 0 + result[@project_language_count_key] += project_language_count.to_i + $redis_cache.hset(platform_statistic_key, project_language_key, result.to_json) + end + end + if @project_praise_count.present? + if $redis_cache.hget(platform_statistic_key, project_praise_count_key).nil? + reset_platform_project_praise_count + else + $redis_cache.hincrby(platform_statistic_key, project_praise_count_key, @project_praise_count) + end + end + if @project_watcher_count.present? + if $redis_cache.hget(platform_statistic_key, project_watcher_count_key).nil? + reset_platform_project_watcher_count + else + $redis_cache.hincrby(platform_statistic_key, project_watcher_count_key, @project_watcher_count) + end + end + if @pullrequest_count.present? + if $redis_cache.hget(platform_statistic_key, pullrequest_count_key).nil? + reset_platform_pullrequest_count + else + $redis_cache.hincrby(platform_statistic_key, pullrequest_count_key, @pullrequest_count) + end + end + $redis_cache.hgetall(platform_statistic_key) + end + + def reset_platform_follow_count + $redis_cache.hset(platform_statistic_key, follow_count_key, Watcher.where(watchable_type: 'User').count) + end + + def reset_platform_fork_count + $redis_cache.hset(platform_statistic_key, fork_count_key, ForkUser.count) + end + + def reset_platform_issue_count + $redis_cache.hset(platform_statistic_key, issue_count_key, Issue.count) + end + + def reset_platform_project_count + $redis_cache.hset(platform_statistic_key, project_count_key, Project.count) + end + + def reset_platform_project_language + $redis_cache.hset(platform_statistic_key, project_language_key, ProjectLanguage.where.not(projects_count: 0).group("project_languages.name").sum(:projects_count).to_json) + end + + def reset_platform_project_praise_count + $redis_cache.hset(platform_statistic_key, project_praise_count_key, PraiseTread.where(praise_tread_object_type: "Project").count) + end + + def reset_platform_project_watcher_count + $redis_cache.hset(platform_statistic_key, project_watcher_count_key, Watcher.where(watchable_type: 'Project').count) + end + + def reset_platform_pullrequest_count + $redis_cache.hset(platform_statistic_key, pullrequest_count_key, PullRequest.count) + end + + def reset_platform_statistic + $redis_cache.del(platform_statistic_key) + reset_platform_follow_count + reset_platform_fork_count + reset_platform_issue_count + reset_platform_project_count + reset_platform_project_language + reset_platform_project_praise_count + reset_platform_project_watcher_count + reset_platform_pullrequest_count + + $redis_cache.hgetall(platform_statistic_key) + end +end \ No newline at end of file diff --git a/app/services/cache/v2/project_common_service.rb b/app/services/cache/v2/project_common_service.rb new file mode 100644 index 000000000..760c6d05b --- /dev/null +++ b/app/services/cache/v2/project_common_service.rb @@ -0,0 +1,219 @@ +class Cache::V2::ProjectCommonService < ApplicationService + attr_reader :project_id, :owner_id, :name, :identifier, :description, :visits, :watchers, :praises, :forks, :issues, :pullrequests + attr_accessor :project + + def initialize(project_id, params={}) + @project_id = project_id + @owner_id = params[:owner_id] + @name = params[:name] + @identifier = params[:identifier] + @description = params[:description] + @visits = params[:visits] + @watchers = params[:watchers] + @praises = params[:praises] + @forks = params[:forks] + @issues = params[:issues] + @pullrequests = params[:pullrequests] + end + + def read + project_common + end + + def call + set_project_common + end + + def reset + reset_project_common + end + + def clear + clear_project_common + end + + private + def load_project + @project = Project.find_by_id(project_id) + end + + def project_common_key + "v2-project-common:#{@project_id}" + end + + def owner_id_key + "owner_id" + end + + def name_key + "name" + end + + def identifier_key + "identifier" + end + + def description_key + "description" + end + + def visits_key + "visits" + end + + def watchers_key + "watchers" + end + + def praises_key + "praises" + end + + def forks_key + "forks" + end + + def issues_key + "issues" + end + + def pullrequests_key + "pullrequests" + end + + def project_common + result = $redis_cache.hgetall(project_common_key) + result.blank? ? reset_project_common : result + end + + def set_project_common + if $redis_cache.hgetall(project_common_key).blank? + reset_project_common + return + else + load_project + return unless @project.is_full_public + if @owner_id.present? + if $redis_cache.hget(project_common_key, owner_id_key).nil? + reset_project_owner_id + else + $redis_cache.hset(project_common_key, owner_id_key, @owner_id) + end + end + if @name.present? + if $redis_cache.hget(project_common_key, name_key).nil? + reset_project_name + else + $redis_cache.hset(project_common_key, name_key, @name) + end + end + if @identifier.present? + if $redis_cache.hget(project_common_key, identifier_key).nil? + reset_project_identifier + else + $redis_cache.hset(project_common_key, identifier_key, @identifier) + end + end + if @description.present? + if $redis_cache.hget(project_common_key, description_key).nil? + reset_project_description + else + $redis_cache.hset(project_common_key, description_key, @description) + end + end + if @visits.present? + $redis_cache.hincrby(project_common_key, visits_key, @visits.to_s) + Cache::V2::ProjectRankService.call(@project_id, {visits: @visits}) + Cache::V2::ProjectDateRankService.call(@project_id, Date.today, {visits: @visits}) + end + if @watchers.present? + $redis_cache.hincrby(project_common_key, watchers_key, @watchers) + end + if @praises.present? + $redis_cache.hincrby(project_common_key, praises_key, @praises) + Cache::V2::ProjectRankService.call(@project_id, {praises: @praises}) + Cache::V2::ProjectDateRankService.call(@project_id, Date.today, {praises: @praises}) + end + if @forks.present? + $redis_cache.hincrby(project_common_key, forks_key, @forks) + Cache::V2::ProjectRankService.call(@project_id, {forks: @forks}) + Cache::V2::ProjectDateRankService.call(@project_id, Date.today, {forks: @forks}) + end + if @issues.present? + $redis_cache.hincrby(project_common_key, issues_key, @issues) + Cache::V2::ProjectRankService.call(@project_id, {issues: @issues}) + Cache::V2::ProjectDateRankService.call(@project_id, Date.today, {issues: @issues}) + end + if @pullrequests.present? + $redis_cache.hincrby(project_common_key, pullrequests_key, @pullrequests) + Cache::V2::ProjectRankService.call(@project_id, {pullrequests: @pullrequests}) + Cache::V2::ProjectDateRankService.call(@project_id, Date.today, {pullrequests: @pullrequests}) + end + end + + $redis_cache.hgetall(project_common_key) + end + + def reset_project_owner_id + $redis_cache.hset(project_common_key, owner_id_key, @project&.user_id) + end + + def reset_project_name + $redis_cache.hset(project_common_key, name_key, @project&.name) + end + + def reset_project_identifier + $redis_cache.hset(project_common_key, identifier_key, @project&.identifier) + end + + def reset_project_description + $redis_cache.hset(project_common_key, description_key, @project&.description) + end + + def reset_project_visits + $redis_cache.hset(project_common_key, visits_key, @project&.visits || 0) + end + + def reset_project_watchers + $redis_cache.hset(project_common_key, watchers_key, Watcher.where(watchable_type: 'Project', watchable_id: @project_id).count) + end + + def reset_project_praises + $redis_cache.hset(project_common_key, praises_key, PraiseTread.where(praise_tread_object_type: 'Project', praise_tread_object_id: @project_id).count) + end + + def reset_project_forks + $redis_cache.hset(project_common_key, forks_key, ForkUser.where(project_id: @project_id).count) + end + + def reset_project_issues + $redis_cache.hset(project_common_key, issues_key, Issue.issue_issue.where(project_id: @project_id).count) + end + + def reset_project_pullrequests + $redis_cache.hset(project_common_key, pullrequests_key, PullRequest.where(project_id: @project_id).count) + end + + def reset_project_common + load_project + return unless @project.is_full_public + $redis_cache.del(project_common_key) + reset_project_owner_id + reset_project_name + reset_project_identifier + reset_project_description + reset_project_visits + reset_project_watchers + reset_project_praises + reset_project_forks + reset_project_issues + reset_project_pullrequests + + $redis_cache.hgetall(project_common_key) + end + + def clear_project_common + $redis_cache.del(project_common_key) + Cache::V2::ProjectRankService.new(@project_id).clear + end +end \ No newline at end of file diff --git a/app/services/cache/v2/project_date_rank_service.rb b/app/services/cache/v2/project_date_rank_service.rb new file mode 100644 index 000000000..092aff796 --- /dev/null +++ b/app/services/cache/v2/project_date_rank_service.rb @@ -0,0 +1,51 @@ +class Cache::V2::ProjectDateRankService < ApplicationService + attr_reader :project_id, :rank_date, :visits, :praises, :forks, :issues, :pullrequests + attr_accessor :project_common + + def initialize(project_id, rank_date=Date.today, params={}) + @project_id = project_id + @rank_date = rank_date + @visits = params[:visits] + @praises = params[:praises] + @forks = params[:forks] + @issues = params[:issues] + @pullrequests = params[:pullrequests] + end + + def read + project_rank + end + + def call + set_project_rank + end + + private + def project_rank_key + "v2-project-rank-#{@rank_date.to_s}" + end + + def project_rank + $redis_cache.zscore(project_rank_key, @project_id) + end + + def set_project_rank + if @visits.present? + $redis_cache.zincrby(project_rank_key, @visits.to_i * 1, @project_id) + end + if @praises.present? + $redis_cache.zincrby(project_rank_key, @praises.to_i * 5, @project_id) + end + if @forks.present? + $redis_cache.zincrby(project_rank_key, @forks.to_i * 5, @project_id) + end + if @issues.present? + $redis_cache.zincrby(project_rank_key, @issues.to_i * 10, @project_id) + end + if @pullrequests.present? + $redis_cache.zincrby(project_rank_key, @pullrequests.to_i * 10, @project_id) + end + + $redis_cache.zscore(project_rank_key, @project_id) + end +end \ No newline at end of file diff --git a/app/services/cache/v2/project_rank_service.rb b/app/services/cache/v2/project_rank_service.rb new file mode 100644 index 000000000..7e5d323bf --- /dev/null +++ b/app/services/cache/v2/project_rank_service.rb @@ -0,0 +1,87 @@ +class Cache::V2::ProjectRankService < ApplicationService + attr_reader :project_id, :visits, :praises, :forks, :issues, :pullrequests + attr_accessor :project_common + + def initialize(project_id, params={}) + @project_id = project_id + @visits = params[:visits] + @praises = params[:praises] + @forks = params[:forks] + @issues = params[:issues] + @pullrequests = params[:pullrequests] + end + + def read + project_rank + end + + def call + set_project_rank + end + + def reset + reset_project_rank + end + + def clear + clear_project_rank + end + + private + def load_project_common + @project_common = Cache::V2::ProjectCommonService.new(@project_id).read + end + + def project_rank_key + "v2-project-rank" + end + + def project_rank + result = $redis_cache.zscore(project_rank_key, @project_id) + result.blank? ? reset_project_rank : result + end + + def set_project_rank + load_project_common + if $redis_cache.zscore(project_rank_key, @project_id).blank? + reset_project_rank + return + else + if @visits.present? + $redis_cache.zincrby(project_rank_key, @visits.to_i * 1, @project_id) + end + if @praises.present? + $redis_cache.zincrby(project_rank_key, @praises.to_i * 5, @project_id) + end + if @forks.present? + $redis_cache.zincrby(project_rank_key, @forks.to_i * 5, @project_id) + end + if @issues.present? + $redis_cache.zincrby(project_rank_key, @issues.to_i * 10, @project_id) + end + if @pullrequests.present? + $redis_cache.zincrby(project_rank_key, @pullrequests.to_i * 10, @project_id) + end + reset_user_project_rank + end + + $redis_cache.zscore(project_rank_key, @project_id) + end + + def reset_project_rank + load_project_common + score = @project_common["visits"].to_i * 1 + @project_common["praises"].to_i * 5 + @project_common["forks"].to_i * 5 + @project_common["issues"].to_i * 10 + @project_common["pullrequests"].to_i * 10 + $redis_cache.zadd(project_rank_key, score, @project_id) + reset_user_project_rank + + $redis_cache.zscore(project_rank_key, @project_id) + end + + def reset_user_project_rank + $redis_cache.zadd("v2-user-project-rank:#{@project_common["owner_id"]}", $redis_cache.zscore(project_rank_key, @project_id), @project_id) + end + + def clear_project_rank + $redis_cache.sadd('v2-project-rank-deleted', @project_id) + end +end \ No newline at end of file diff --git a/app/services/cache/v2/user_date_rank_service.rb b/app/services/cache/v2/user_date_rank_service.rb new file mode 100644 index 000000000..00073a8e8 --- /dev/null +++ b/app/services/cache/v2/user_date_rank_service.rb @@ -0,0 +1,119 @@ +class Cache::V2::UserDateRankService < ApplicationService + attr_reader :user_id, :rank_date, :follow_count, :fork_count, :issue_count, :project_count, :project_language_count_key, :project_language_count, :project_praise_count, :project_watcher_count, :pullrequest_count + + def initialize(user_id, rank_date=Date.today, params={}) + @user_id = user_id + @rank_date = rank_date + @follow_count = params[:follow_count] + @fork_count = params[:fork_count] + @issue_count = params[:issue_count] + @project_count = params[:project_count] + @project_language_count_key = params[:project_language_count_key] + @project_language_count = params[:project_language_count] + @project_praise_count = params[:project_praise_count] + @project_watcher_count = params[:project_watcher_count] + @pullrequest_count = params[:pullrequest_count] + end + + def read_rank + user_rank + end + + def read_statistic + user_statistic + end + + def call + set_user_rank + end + + private + def user_rank_key + "v2-user-rank-#{@rank_date.to_s}" + end + + def user_date_statistic_key + "v2-user-statistic:#{@user_id}-#{@rank_date.to_s}" + end + + def user_rank + $redis_cache.zscore(user_rank_key, @user_id) + end + + def user_statistic + $redis_cache.hgetall(user_date_statistic_key) + end + + def set_user_statistic + if @follow_count.present? + $redis_cache.hincrby(user_date_statistic_key, "follow-count", @follow_count.to_i) + end + if @fork_count.present? + $redis_cache.hincrby(user_date_statistic_key, "fork-count", @fork_count.to_i) + end + if @issue_count.present? + $redis_cache.hincrby(user_date_statistic_key, "issue-count", @issue_count.to_i) + end + if @project_count.present? + $redis_cache.hincrby(user_date_statistic_key, "project-count", @project_count.to_i) + end + if project_language_count_key.present? && project_language_count.present? + if $redis_cache.hget(user_date_statistic_key, "project-language").nil? + result = {} + result[@project_language_count_key] = project_language_count.to_i + result.delete(@project_language_count_key) if result[@project_language_count_key] == 0 + $redis_cache.hset(user_date_statistic_key, "project-language", result.to_json) + else + result = JSON.parse($redis_cache.hget(user_date_statistic_key, "project-language")) + result[@project_language_count_key] ||= 0 + result[@project_language_count_key] += project_language_count.to_i + result.delete(@project_language_count_key) if result[@project_language_count_key] == 0 + $redis_cache.hset(user_date_statistic_key, "project-language", result.to_json) + end + end + if @project_praise_count.present? + $redis_cache.hincrby(user_date_statistic_key, "project-praise-count", @project_praise_count.to_i) + end + if @project_watcher_count.present? + $redis_cache.hincrby(user_date_statistic_key, "project-watcher-count", @project_watcher_count.to_i) + end + if @pullrequest_count.present? + $redis_cache.hincrby(user_date_statistic_key, "pullrequest-count", @pullrequest_count.to_i) + end + + $redis_cache.hgetall(user_date_statistic_key) + end + + def set_user_rank + set_user_statistic + follow_count = $redis_cache.hget(user_date_statistic_key, "follow-count") || 0 + pullrequest_count = $redis_cache.hget(user_date_statistic_key, "pullrequest-count") || 0 + issues_count = $redis_cache.hget(user_date_statistic_key, "issue-count") || 0 + project_count = $redis_cache.hget(user_date_statistic_key, "project-count") || 0 + fork_count = $redis_cache.hget(user_date_statistic_key, "fork-count") || 0 + project_watchers_count = $redis_cache.hget(user_date_statistic_key, "project-watcher-count") || 0 + project_praises_count = $redis_cache.hget(user_date_statistic_key, "project-praise-count") || 0 + project_language = $redis_cache.hget(user_date_statistic_key, "project-language") + project_languages_count = project_language.nil? || project_language == "{}" ? 0 : JSON.parse(project_language).length + # 影响力 + influence = (60.0 + follow_count.to_i / (follow_count.to_i + 20.0) * 40.0).to_i + + # 贡献度 + contribution = (60.0 + pullrequest_count.to_i / (pullrequest_count.to_i + 20.0) * 40.0).to_i + + # 活跃度 + activity = (60.0 + issues_count.to_i / (issues_count.to_i + 80.0) * 40.0).to_i + + # 项目经验 + experience = 10 * project_count.to_i + 5 * fork_count.to_i + project_watchers_count.to_i + project_praises_count.to_i + experience = (60.0 + experience / (experience + 100.0) * 40.0).to_i + # 语言能力 + language = (60.0 + project_languages_count.to_i / (project_languages_count.to_i + 5.0) * 40.0).to_i + + score = influence+ contribution + activity + experience + language + $redis_cache.zrem(user_rank_key, @user_id) + $redis_cache.zadd(user_rank_key, score-300, @user_id) if score > 300 + + $redis_cache.zscore(user_rank_key, @user_id) + end +end \ No newline at end of file diff --git a/app/services/cache/v2/user_statistic_service.rb b/app/services/cache/v2/user_statistic_service.rb new file mode 100644 index 000000000..b82797d84 --- /dev/null +++ b/app/services/cache/v2/user_statistic_service.rb @@ -0,0 +1,202 @@ +class Cache::V2::UserStatisticService < ApplicationService + attr_reader :user_id, :follow_count, :fork_count, :issue_count, :project_count, :project_language_count_key, :project_language_count, :project_praise_count, :project_watcher_count, :pullrequest_count + + def initialize(user_id, params={}) + @user_id = user_id + @follow_count = params[:follow_count] + @fork_count = params[:fork_count] + @issue_count = params[:issue_count] + @project_count = params[:project_count] + @project_language_count_key = params[:project_language_count_key] + @project_language_count = params[:project_language_count] + @project_praise_count = params[:project_praise_count] + @project_watcher_count = params[:project_watcher_count] + @pullrequest_count = params[:pullrequest_count] + Cache::V2::OwnerCommonService.new(user_id).read + end + + def read + user_statistic + end + + def call + set_user_statistic + end + + def reset + reset_user_statistic + end + + private + + def user_statistic_key + "v2-user-statistic:#{@user_id}" + end + + def follow_count_key + "follow-count" + end + + def fork_count_key + "fork-count" + end + + def issue_count_key + "issue-count" + end + + def project_count_key + "project-count" + end + + def project_language_key + "project-language" + end + + def project_praise_count_key + "project-praise-count" + end + + def project_watcher_count_key + "project-watcher-count" + end + + def pullrequest_count_key + "pullrequest-count" + end + + def user_statistic + result = $redis_cache.hgetall(user_statistic_key) + result.blank? ? reset_user_statistic : result + end + + def set_user_statistic + if $redis_cache.hgetall(user_statistic_key).blank? + reset_user_statistic + return + end + if @follow_count.present? + if $redis_cache.hget(user_statistic_key, follow_count_key).nil? + reset_user_follow_count + Cache::V2::UserDateRankService.call(@user_id, Date.today, {follow_count: @follow_count}) + else + $redis_cache.hincrby(user_statistic_key, follow_count_key, @follow_count) + Cache::V2::UserDateRankService.call(@user_id, Date.today, {follow_count: @follow_count}) + end + end + if @fork_count.present? + if $redis_cache.hget(user_statistic_key, fork_count_key).nil? + reset_user_fork_count + Cache::V2::UserDateRankService.call(@user_id, Date.today, {fork_count: @fork_count}) + else + $redis_cache.hincrby(user_statistic_key, fork_count_key, @fork_count) + Cache::V2::UserDateRankService.call(@user_id, Date.today, {fork_count: @fork_count}) + end + end + if @issue_count.present? + if $redis_cache.hget(user_statistic_key, issue_count_key).nil? + reset_user_issue_count + Cache::V2::UserDateRankService.call(@user_id, Date.today, {issue_count: @issue_count}) + else + $redis_cache.hincrby(user_statistic_key, issue_count_key, @issue_count) + Cache::V2::UserDateRankService.call(@user_id, Date.today, {issue_count: @issue_count}) + end + end + if @project_count.present? + if $redis_cache.hget(user_statistic_key, project_count_key).nil? + reset_user_project_count + Cache::V2::UserDateRankService.call(@user_id, Date.today, {project_count: @project_count}) + else + $redis_cache.hincrby(user_statistic_key, project_count_key, @project_count) + Cache::V2::UserDateRankService.call(@user_id, Date.today, {project_count: @project_count}) + end + end + if @project_language_count_key.present? && project_language_count.present? + if $redis_cache.hget(user_statistic_key, project_language_key).nil? + reset_user_project_language + Cache::V2::UserDateRankService.call(@user_id, Date.today, {project_language_count_key: @project_language_count_key, project_language_count: @project_language_count}) + else + result = JSON.parse($redis_cache.hget(user_statistic_key, project_language_key)) + result[@project_language_count_key] ||= 0 + result[@project_language_count_key] += project_language_count.to_i + result.delete(@project_language_count_key) if result[@project_language_count_key] == 0 + $redis_cache.hset(user_statistic_key, project_language_key, result.to_json) + Cache::V2::UserDateRankService.call(@user_id, Date.today, {project_language_count_key: @project_language_count_key, project_language_count: @project_language_count}) + end + end + if @project_praise_count.present? + if $redis_cache.hget(user_statistic_key, project_praise_count_key).nil? + reset_user_project_praise_count + Cache::V2::UserDateRankService.call(@user_id, Date.today, {project_praise_count: @project_praise_count}) + else + $redis_cache.hincrby(user_statistic_key, project_praise_count_key, @project_praise_count) + Cache::V2::UserDateRankService.call(@user_id, Date.today, {project_praise_count: @project_praise_count}) + end + end + if @project_watcher_count.present? + if $redis_cache.hget(user_statistic_key, project_watcher_count_key).nil? + reset_user_project_watcher_count + Cache::V2::UserDateRankService.call(@user_id, Date.today, {project_watcher_count: @project_watcher_count}) + else + $redis_cache.hincrby(user_statistic_key, project_watcher_count_key, @project_watcher_count) + Cache::V2::UserDateRankService.call(@user_id, Date.today, {project_watcher_count: @project_watcher_count}) + end + end + if @pullrequest_count.present? + if $redis_cache.hget(user_statistic_key, pullrequest_count_key).nil? + reset_user_pullrequest_count + Cache::V2::UserDateRankService.call(@user_id, Date.today, {pullrequest_count: @pullrequest_count}) + else + $redis_cache.hincrby(user_statistic_key, pullrequest_count_key, @pullrequest_count) + Cache::V2::UserDateRankService.call(@user_id, Date.today, {pullrequest_count: @pullrequest_count}) + end + end + $redis_cache.hgetall(user_statistic_key) + end + + def reset_user_follow_count + $redis_cache.hset(user_statistic_key, follow_count_key, Watcher.where(watchable_type: 'User', watchable_id: @user_id).count) + end + + def reset_user_fork_count + $redis_cache.hset(user_statistic_key, fork_count_key, ForkUser.joins(:project).where(projects: {user_id: @user_id}).count) + end + + def reset_user_issue_count + $redis_cache.hset(user_statistic_key, issue_count_key, Issue.where(author_id: @user_id).count) + end + + def reset_user_project_count + $redis_cache.hset(user_statistic_key, project_count_key, Project.where(user_id: @user_id).count) + end + + def reset_user_project_language + $redis_cache.hset(user_statistic_key, project_language_key, Project.where(user_id: @user_id).joins(:project_language).group("project_languages.name").count.to_json) + end + + def reset_user_project_praise_count + $redis_cache.hset(user_statistic_key, project_praise_count_key, PraiseTread.where(praise_tread_object_type: 'Project', praise_tread_object_id: Project.where(user_id: @user_id)).count) + end + + def reset_user_project_watcher_count + $redis_cache.hset(user_statistic_key, project_watcher_count_key, Watcher.where(watchable_type: 'Project', watchable_id: Project.where(user_id: @user_id)).count) + end + + def reset_user_pullrequest_count + $redis_cache.hset(user_statistic_key, pullrequest_count_key, PullRequest.where(user_id: @user_id).count) + end + + def reset_user_statistic + $redis_cache.del(user_statistic_key) + reset_user_follow_count + reset_user_fork_count + reset_user_issue_count + reset_user_project_count + reset_user_project_language + reset_user_project_praise_count + reset_user_project_watcher_count + reset_user_pullrequest_count + + $redis_cache.hgetall(user_statistic_key) + end +end \ No newline at end of file diff --git a/app/services/courses_service.rb b/app/services/courses_service.rb deleted file mode 100644 index 8229c7c32..000000000 --- a/app/services/courses_service.rb +++ /dev/null @@ -1,2 +0,0 @@ -class CoursesService -end \ No newline at end of file diff --git a/app/services/create_add_department_apply_service.rb b/app/services/create_add_department_apply_service.rb deleted file mode 100644 index e172b001a..000000000 --- a/app/services/create_add_department_apply_service.rb +++ /dev/null @@ -1,44 +0,0 @@ -class CreateAddDepartmentApplyService < ApplicationService - Error = Class.new(StandardError) - - attr_reader :user, :params - - def initialize(user, params) - @user = user - @params = params - end - - def call - name = params[:name].to_s.strip - raise Error, '名称不能为空' if name.blank? - - school = School.find_by(id: params[:school_id]) - raise Error, '学校/单位不存在' if school.blank? - raise Error, '部门已存在' if school.departments.exists?(name: name) - - department = Department.new - department.name = name - department.school = school - - ActiveRecord::Base.transaction do - department.save! - - attrs = { - user_id: user.id, department: department, school: school, - name: department.name, remarks: params[:remarks], status: 0, - } - apply = ApplyAddDepartment.create!(attrs) - - unless user.professional_certification? - user.user_extension.update!(department_id: department.id) - end - - # 向管理员发送通知 - message = AppliedMessage.new(user_id: 1, status: 0, applied_user_id: user.id, viewed: 0, - applied_id: apply.id, applied_type: 'ApplyAddDepartment', name: department.name) - message.save(validate: false) - end - - department - end -end diff --git a/app/services/create_add_school_apply_service.rb b/app/services/create_add_school_apply_service.rb deleted file mode 100644 index 96619c681..000000000 --- a/app/services/create_add_school_apply_service.rb +++ /dev/null @@ -1,37 +0,0 @@ -class CreateAddSchoolApplyService < ApplicationService - Error = Class.new(StandardError) - - attr_reader :user, :params - - def initialize(user, params) - @user = user - @params = params - end - - def call - AddSchoolApplyForm.new(params).validate! - - name = params[:name].to_s.strip - raise Error, '学校/单位已经存在' if name.present? && School.exists?(name: name) - - school = School.new - school.name = name - school.province = params[:province].to_s.strip - school.city = params[:city].to_s.strip - school.address = params[:address].to_s.strip - - ActiveRecord::Base.transaction do - school.save! - - school_attrs = school.as_json(only: %i[name province city address]) - ApplyAddSchool.create!(school_attrs.merge(school: school, user_id: user.id, remarks: params[:remarks])) - - # 向管理员发送通知 - message = AppliedMessage.new(user_id: 1, status: 0, applied_user_id: user.id, viewed: 0, - applied_id: school.id, applied_type: 'ApplyAddSchools', name: school.name) - message.save(validate: false) - end - - school - end -end diff --git a/app/services/duplicate_course_service.rb b/app/services/duplicate_course_service.rb deleted file mode 100644 index fa57a8901..000000000 --- a/app/services/duplicate_course_service.rb +++ /dev/null @@ -1,164 +0,0 @@ -class DuplicateCourseService < ApplicationService - attr_reader :origin_course, :user, :course - - def initialize(origin_course, user) - @user = user - @origin_course = origin_course - end - - def call - ActiveRecord::Base.transaction do - @course = copy_course! - - copy_course_modules! - - join_course! - - copy_homework_commons! - - copy_exercises! - - copy_polls! - - copy_attachments! - - course - end - end - - private - - def copy_course! - create_attrs = origin_course.as_json(only: %i[name class_period credit course_list_id]) - create_attrs.merge!(tea_id: user.id, school_id: user.school_id, is_public: 0, is_copy: 1) - - Course.create!(create_attrs) - end - - def copy_course_modules! - @second_category_list = {} - origin_course.course_modules.each do |course_module| - attrs = course_module.as_json(only: %i[module_type position hidden module_name]) - new_course_module = CourseModule.create!(attrs.merge(course_id: course.id)) - # 复制子目录 - course_module.course_second_categories.each do |second_category| - category_attr = second_category.as_json(only: %i[category_type name position]) - new_second_category = - CourseSecondCategory.create!(category_attr.merge(course_id: course.id, course_module_id: new_course_module.id)) - @second_category_list[second_category.id] = new_second_category.id - end - end - end - - def join_course! - CourseMember.create!(course_id: course.id, user_id: user.id, role: 1) - end - - def copy_homework_commons! - origin_course.homework_commons.where(homework_type: %i[normal group practice]).find_each do |origin_homework| - homework_attrs = origin_homework.as_json(only: %i[name description homework_type homework_bank_id reference_answer]) - - course_second_category_id = @second_category_list[origin_homework.course_second_category_id] - - homework = HomeworkCommon.create!(homework_attrs.merge(user_id: user.id, course_id: course.id, - course_second_category_id:course_second_category_id)) - - origin_homework.attachments.find_each do |origin_attachment| - attachment = origin_attachment.copy - attrs = { container: homework, author_id: origin_homework.user_id, copy_from: origin_attachment.id } - attachment.assign_attributes(attrs) - attachment.save! - - origin_attachment.increment!(:quotes) - end - - homework.create_homework_detail_manual! - - if homework.group_homework_type? - attrs = origin_homework.homework_detail_group.as_json(only: %i[min_num max_num base_on_project]) - homework.create_homework_detail_group!(attrs) - elsif homework.practice_homework_type? - HomeworkCommonsShixun.create!(homework_common_id: homework.id, shixun_id: origin_homework.homework_commons_shixun.shixun_id) - HomeworksService.new.create_shixun_homework_cha_setting(homework, origin_homework.shixuns.first) - end - - - origin_homework.increment!(:quotes) - origin_homework.homework_bank.increment!(:quotes) if origin_homework.homework_bank - end - end - - def copy_exercises! - origin_course.exercises.find_each do |origin_exercise| - attrs = origin_exercise.as_json(only: %i[exercise_name exercise_description exercise_bank_id]) - exercise = course.exercises.create!(attrs.merge(user_id: user.id)) - - origin_exercise.exercise_questions.find_each do |origin_question| - question_attrs = origin_question.as_json(only: %i[question_title question_type question_number question_score shixun_name shixun_id is_ordered level]) - # question_attrs[:question_type] ||= 1 - question = exercise.exercise_questions.create!(question_attrs) - - exercise_choice_map = {} - origin_question.exercise_choices.each_with_index do |origin_choice, index| - choice_attrs = { choice_position: index + 1, choice_text: origin_choice.choice_text } - choice = question.exercise_choices.create!(choice_attrs) - - # exercise_choice_map[origin_choice.id] = choice.id 标准答案中存的是choice_position, 直接取原题的exercise_choice_id就行 - end - - origin_question.exercise_standard_answers.find_each do |origin_answer| - question.exercise_standard_answers.create!( - exercise_choice_id: origin_answer.exercise_choice_id, - answer_text: origin_answer.answer_text - ) - end - - origin_question.exercise_shixun_challenges.each_with_index do |sc, index| - question.exercise_shixun_challenges.create!({position: index+1, challenge_id: sc.challenge_id, - shixun_id: sc.shixun_id, question_score: sc.question_score}) - end - end - - origin_exercise.exercise_bank.increment!(:quotes) if exercise.exercise_bank - end - end - - def copy_polls! - origin_course.polls.includes(poll_questions: :poll_answers).find_each do |origin_poll| - poll_attrs = origin_poll.as_json(only: %i[polls_name polls_description exercise_bank_id]) - poll = course.polls.create!(poll_attrs.merge(user_id: user.id)) - - origin_poll.poll_questions.each do |origin_question| - attr_names = %i[question_title question_type is_necessary question_number max_choices min_choices] - question_attrs = origin_question.as_json(only: attr_names) - question_attrs[:question_type] ||= 1 - - question = poll.poll_questions.create!(question_attrs) - - origin_question.poll_answers.each_with_index do |origin_answer, index| - question.poll_answers.create!(answer_position: index + 1, answer_text: origin_answer.answer_text) - end - end - - origin_poll.exercise_bank.increment!(:quotes) if origin_poll.exercise_bank - end - end - - def copy_attachments! - origin_course.attachments.each do |origin_attachment| - attachment = origin_attachment.copy - # attachment.tag_list.add(origin_attachment.tag_list) # tag关联 - attachment.container = course - attachment.created_on = Time.now - attachment.publish_time = nil - attachment.author_id = User.current.id - attachment.copy_from = origin_attachment.copy_from || origin_attachment.id - attachment.is_publish = 0 - attachment.attachtype ||= 4 - attachment.course_second_category_id = @second_category_list[origin_attachment.course_second_category_id] - - attachment.save! - origin_course.update_quotes(attachment) - end - end -end \ No newline at end of file diff --git a/app/services/forum/client_service.rb b/app/services/forum/client_service.rb new file mode 100644 index 000000000..e3ff54691 --- /dev/null +++ b/app/services/forum/client_service.rb @@ -0,0 +1,94 @@ +class Forum::ClientService < ApplicationService + attr_reader :url, :params + + PAGINATE_DEFAULT_PAGE = 1 + PAGINATE_DEFAULT_LIMIT = 20 + + def initialize(options={}) + @url = options[:url] + @params = options[:params] + end + + def get(url, params={}) + conn(params).get do |req| + req.url full_url(url, 'get') + params.except(:token).each_pair do |key, value| + req.params["#{key}"] = value + end + end + + # response.headers.each do |k,v| + # puts "#{k}:#{v}" + # end #=> 响应头 + end + + private + def conn(auth={}) + @client ||= begin + Faraday.new(url: domain) do |req| + req.request :url_encoded + req.headers['Content-Type'] = 'application/json' + req.response :logger # 显示日志 + req.adapter Faraday.default_adapter + end + end + @client + end + + def base_url + Forum.forum_config[:base_url] + end + + def domain + Forum.forum_config[:domain] + end + + def api_url + [domain, base_url].join('') + end + + def full_url(api_rest, action='post') + url = [api_url, api_rest].join('').freeze + url = action === 'get' ? url : URI.escape(url) + url = URI.escape(url) unless url.ascii_only? + puts "[forum] request url: #{url}" + return url + end + + def render_response(response) + status = response.status + body = response&.body + + # log_error(status, body) + + body, message = get_body_by_status(status, body) + + [status, message, body] + end + + def get_body_by_status(status, body) + body, message = + case status + when 401 then [nil, "401"] + when 404 then [nil, "404"] + when 403 then [nil, "403"] + when 500 then [nil, "500"] + else + if body.present? + body = JSON.parse(body) + fix_body(body) + else + nil + end + end + + [body, message] + end + + def fix_body(body) + return [body, nil] if body.is_a?(Array) || body.is_a?(Hash) + + body['message'].blank? ? [body, nil] : [nil, body['message']] + end + +end diff --git a/app/services/forum/memos/get_service.rb b/app/services/forum/memos/get_service.rb new file mode 100644 index 000000000..c8ad56895 --- /dev/null +++ b/app/services/forum/memos/get_service.rb @@ -0,0 +1,21 @@ +class Forum::Memos::GetService < Forum::ClientService + attr_reader :memo_id + + def initialize(memo_id) + @memo_id = memo_id + end + + def call + response = get(url) + code, message, body = render_response(response) + if code == 200 && body["status"] == 0 + return body + else + return nil + end + end + + def url + "/memos/#{memo_id}.json".freeze + end +end \ No newline at end of file diff --git a/app/services/gitea/client_service.rb b/app/services/gitea/client_service.rb index 868a704c8..90843cc98 100644 --- a/app/services/gitea/client_service.rb +++ b/app/services/gitea/client_service.rb @@ -82,6 +82,8 @@ class Gitea::ClientService < ApplicationService req.headers['Content-Type'] = 'application/json' req.response :logger # 显示日志 req.adapter Faraday.default_adapter + req.options.timeout = 100 # open/read timeout in seconds + req.options.open_timeout = 10 # connection open timeout in seconds if token.blank? req.basic_auth(username, secret) else diff --git a/app/services/gitea/user/delete_service.rb b/app/services/gitea/user/delete_service.rb new file mode 100644 index 000000000..5df3cb6b2 --- /dev/null +++ b/app/services/gitea/user/delete_service.rb @@ -0,0 +1,31 @@ +class Gitea::User::DeleteService < Gitea::ClientService + attr_reader :username + + def initialize(username) + @username = username + end + + def call + response = delete(request_url, params) + + render_status(response) + end + + private + def token + { + username: Gitea.gitea_config[:access_key_id], + password: Gitea.gitea_config[:access_key_secret] + } + end + + def request_url + "/admin/users/#{username}" + end + + def params + Hash.new.merge(token: token) + end + + +end diff --git a/app/services/notice/write/email_create_service.rb b/app/services/notice/write/email_create_service.rb index 070b42689..86ec2761f 100644 --- a/app/services/notice/write/email_create_service.rb +++ b/app/services/notice/write/email_create_service.rb @@ -21,7 +21,7 @@ class Notice::Write::EmailCreateService < Notice::Write::ClientService end def request_subject - "Trustie: #{subject}" + "#{subject}" end def request_params diff --git a/app/services/projects/apply_join_service.rb b/app/services/projects/apply_join_service.rb index 677ee20c1..958fd810c 100644 --- a/app/services/projects/apply_join_service.rb +++ b/app/services/projects/apply_join_service.rb @@ -65,7 +65,7 @@ class Projects::ApplyJoinService < ApplicationService owner = project.user return if owner.phone.blank? - Educoder::Sms.send(mobile: owner.phone, send_type:'applied_project_info', + Gitlink::Sms.send(mobile: owner.phone, send_type:'applied_project_info', user_name: owner.show_name, name: project.name) rescue Exception => ex Rails.logger.error("发送短信失败 => #{ex.message}") diff --git a/app/services/reward_experience_service.rb b/app/services/reward_experience_service.rb deleted file mode 100644 index 70b47d1a3..000000000 --- a/app/services/reward_experience_service.rb +++ /dev/null @@ -1,24 +0,0 @@ -class RewardExperienceService - attr_reader :user, :attrs - - def initialize(user, **attrs) - @user = user - @attrs = attrs.slice(*%i[container_id container_type score]) - end - - def call - return if user.experiences.exists?(attrs.except(:score)) - - ActiveRecord::Base.transaction do - experience = user.experiences.create!(attrs) - - user.increment!(:experience, experience.score) - - experience - end - end - - def self.call(user, **attrs) - new(user, attrs).call - end -end \ No newline at end of file diff --git a/app/services/users/apply_authentication_service.rb b/app/services/users/apply_authentication_service.rb index 5e2562105..cd7b931a5 100644 --- a/app/services/users/apply_authentication_service.rb +++ b/app/services/users/apply_authentication_service.rb @@ -52,7 +52,7 @@ class Users::ApplyAuthenticationService < ApplicationService end def sms_notify_admin - Educoder::Sms.notify_admin(send_type: 'apply_auth') + Gitlink::Sms.notify_admin(send_type: 'apply_auth') rescue => ex Util.logger_error(ex) end diff --git a/app/services/users/apply_professional_auth_service.rb b/app/services/users/apply_professional_auth_service.rb index 9f3057ddb..2d487f3c3 100644 --- a/app/services/users/apply_professional_auth_service.rb +++ b/app/services/users/apply_professional_auth_service.rb @@ -62,7 +62,7 @@ class Users::ApplyProfessionalAuthService < ApplicationService def sms_notify_admin sms_cache = Rails.cache.read('apply_pro_certification') if sms_cache.nil? - Educoder::Sms.notify_admin(send_type: 'apply_pro_certification') + Gitlink::Sms.notify_admin(send_type: 'apply_pro_certification') Rails.cache.write('apply_pro_certification', 1, expires_in: 5.minutes) end rescue => ex diff --git a/app/services/users/apply_trail_service.rb b/app/services/users/apply_trail_service.rb index 082a89c9a..d058bb5d0 100644 --- a/app/services/users/apply_trail_service.rb +++ b/app/services/users/apply_trail_service.rb @@ -51,7 +51,7 @@ class Users::ApplyTrailService < ApplicationService end def send_trial_apply_notify! - Educoder::Sms.notify_admin(send_type:'user_apply_auth') + Gitlink::Sms.notify_admin(send_type:'user_apply_auth') rescue => ex Rails.logger.error('发送通知管理员短信失败') Rails.logger.error(ex.message) diff --git a/app/services/users/course_service.rb b/app/services/users/course_service.rb deleted file mode 100644 index 6cc9669cb..000000000 --- a/app/services/users/course_service.rb +++ /dev/null @@ -1,52 +0,0 @@ -class Users::CourseService - include CustomSortable - - sort_columns :created_at, :updated_at, default_by: :updated_at, default_direction: :desc - - attr_reader :user, :params - - def initialize(user, params) - @user = user - @params = params - end - - def call - courses = category_scope_courses.not_deleted.not_excellent - - courses = status_filter(courses) - - custom_sort(courses, params[:sort_by], params[:sort_direction]) - end - - private - - def category_scope_courses - case params[:category] - when 'study' then - user.as_student_courses.started - when 'manage' then - user.manage_courses - else - ids = user.as_student_courses.started.pluck(:id) + user.manage_courses.pluck(:id) - Course.where(id: ids) - end - end - - def status_filter(relations) - # 只有自己查看才有过滤 - return relations unless observed_logged_user? - - case params[:status] - when 'processing' then - relations.processing - when 'end' then - relations.ended - else - relations - end - end - - def observed_logged_user? - User.current.id == user.id - end -end diff --git a/app/services/users/question_bank_service.rb b/app/services/users/question_bank_service.rb deleted file mode 100644 index dbaa92e6e..000000000 --- a/app/services/users/question_bank_service.rb +++ /dev/null @@ -1,99 +0,0 @@ -class Users::QuestionBankService - attr_reader :user, :params - - def initialize(user, params) - @user = user - @params = params - end - - def call - relations = class_name.classify.constantize.all - - relations = category_filter(relations) - relations = type_filter(relations) if params[:type].present? - - relations = relations.where(course_list_id: params[:course_list_id]) if params[:course_list_id].present? - - custom_sort(relations, params[:sort_by], params[:sort_direction]) - end - - def course_lists - relation_name = class_name.underscore.pluralize.to_sym - course_lists = CourseList.joins(relation_name).where.not(relation_name => { id: nil }) - - category_condition = - case params[:object_type] - when 'normal' then { homework_type: 1 } - when 'group' then { homework_type: 3 } - when 'exercise' then { container_type: 'Exercise' } - when 'poll' then { container_type: 'Poll' } - when 'gtask', 'gtopic' then {} - else raise ArgumentError - end - course_lists = course_lists.where(relation_name => category_condition) if category_condition.present? - - type_condition = - case params[:type] - when 'personal' then { user_id: user.id } - when 'publicly' then { is_public: true } - else {} - end - course_lists = course_lists.where(relation_name => type_condition) if type_condition.present? - - course_lists.distinct.select(:id, :name) - end - - private - - def class_name - @_class_name ||= begin - case params[:object_type] - when 'normal', 'group' then 'HomeworkBank' - when 'exercise', 'poll' then 'ExerciseBank' - when 'gtask' then 'GtaskBank' - when 'gtopic' then 'GtopicBank' - else raise ArgumentError - end - end - end - - def category_filter(relations) - case params[:object_type] - when 'normal' then - relations.where(homework_type: 1) - when 'group' then - relations.where(homework_type: 3) - when 'exercise' then - relations.where(container_type: 'Exercise') - when 'poll' then - relations.where(container_type: 'Poll') - when 'gtask', 'gtopic' then - relations.all - else - raise ArgumentError - end - end - - def type_filter(relations) - case params[:type] - when 'personal' then relations.where(user_id: user.id) - when 'publicly' then relations.where(is_public: true) - else relations - end - end - - def custom_sort(relations, sort_by, sort_direction) - case sort_by - when 'updated_at' then - relations.order("updated_at #{sort_direction}, id #{sort_direction}") - when 'name' then - relations.order("CONVERT(name USING gbk) COLLATE gbk_chinese_ci #{sort_direction}") - when 'contributor' then - order_sql = "CONVERT (users.lastname USING gbk) COLLATE gbk_chinese_ci #{sort_direction},"\ - " CONVERT (users.firstname USING gbk) COLLATE gbk_chinese_ci #{sort_direction}" - relations.joins(:user).where(users: { status: 1 }).order(order_sql) - else - relations - end - end -end diff --git a/app/services/users/register_service.rb b/app/services/users/register_service.rb new file mode 100644 index 000000000..fc0e4231e --- /dev/null +++ b/app/services/users/register_service.rb @@ -0,0 +1,54 @@ +class Users::RegisterService < ApplicationService + def initialize(params) + @login = params[:login] + @namespace = params[:namespace] + @password = params[:password] + @code = params[:code] + end + + def call + code = strip(@code) + login = strip(@login) + namespace = strip(@namespace) + password = strip(@password) + + Rails.logger.info "Users::RegisterService params: + ##### code: #{code} login: #{login} namespace: #{namespace} password: #{password} " + + email, phone = + if register_type == 1 + phone_register(login, code) + elsif register_type == 0 + mail_register(login, code) + end + + user = User.new(admin: false, login: namespace, mail: email, phone: phone, type: "User") + user.password = password + user.activate # 现在因为是验证码,所以在注册的时候就可以激活 + + user + end + + private + # 手机注册 + def phone_register(login, code) + Rails.logger.info("start register by phone: phone is #{login}") + email = nil + phone = login + + [email, phone] + end + + # 邮箱注册 + def mail_register(login, code) + Rails.logger.info("start register by email: email is #{login}") + email = login + phone = nil + + [email, phone] + end + + def register_type + phone_mail_type(@login) + end +end diff --git a/app/services/users/update_account_service.rb b/app/services/users/update_account_service.rb index 8a0b1885d..f8024ff18 100644 --- a/app/services/users/update_account_service.rb +++ b/app/services/users/update_account_service.rb @@ -71,7 +71,7 @@ class Users::UpdateAccountService < ApplicationService end def sms_notify_admin name - Educoder::Sms.send(mobile:'17680641960', send_type:'teacher_register', name: name, user_name:'管理员') + Gitlink::Sms.send(mobile:'17680641960', send_type:'teacher_register', name: name, user_name:'管理员') rescue => ex Util.logger_error(ex) end diff --git a/app/services/weapps/create_course_service.rb b/app/services/weapps/create_course_service.rb deleted file mode 100644 index 2e5cc5d2f..000000000 --- a/app/services/weapps/create_course_service.rb +++ /dev/null @@ -1,40 +0,0 @@ -class Weapps::CreateCourseService < ApplicationService - attr_reader :course, :params - - def initialize(course, params) - @course = course - @params = params - end - - def call - Weapps::CreateCourseForm.new(form_params).validate! - - ActiveRecord::Base.transaction do - course.name = params[:name].to_s.strip - course.school_id = course.teacher&.school_id - course.is_public = 0 - course.credit = params[:credit].blank? ? nil : params[:credit] - course.end_date = params[:end_date].blank? ? nil : params[:end_date] - course_list = CourseList.find_by(name: params[:course_list_name].to_s.strip) - if course_list - course.course_list_id = course_list.id - else - new_course_list = CourseList.create!(name: params[:course_list_name].to_s.strip, user_id: course.tea_id, is_admin: 0) - course.course_list_id = new_course_list.id - end - course.is_end = course.end_date.present? && course.end_date < Date.today - - course.save! - - course.generate_invite_code - CourseMember.create!(course_id: course.id, user_id: course.tea_id, role: 1) - course.create_course_modules(params[:course_module_types]) - end - end - - private - - def form_params - params.merge(course: course) - end -end \ No newline at end of file diff --git a/app/services/weapps/update_course_service.rb b/app/services/weapps/update_course_service.rb deleted file mode 100644 index b6663bc73..000000000 --- a/app/services/weapps/update_course_service.rb +++ /dev/null @@ -1,34 +0,0 @@ -class Weapps::UpdateCourseService < ApplicationService - attr_reader :course, :params - - def initialize(course, params) - @course = course - @params = params - end - - def call - Weapps::UpdateCourseForm.new(form_params).validate! - - ActiveRecord::Base.transaction do - course.name = params[:name].to_s.strip - course.credit = params[:credit].blank? ? nil : params[:credit] - course.end_date = params[:end_date].blank? ? nil : params[:end_date] - course_list = CourseList.find_by(name: params[:course_list_name].to_s.strip) - if course_list - course.course_list_id = course_list.id - else - new_course_list = CourseList.create!(name: params[:course_list_name].to_s.strip, user_id: course.tea_id, is_admin: 0) - course.course_list_id = new_course_list.id - end - course.is_end = course.end_date.present? && course.end_date < Date.today - course.save! - end - course - end - - private - - def form_params - params.merge(course: course) - end -end \ No newline at end of file diff --git a/app/views/admins/course_lists/index.html.erb b/app/views/admins/course_lists/index.html.erb deleted file mode 100644 index cd814ed8a..000000000 --- a/app/views/admins/course_lists/index.html.erb +++ /dev/null @@ -1,22 +0,0 @@ -<% define_admin_breadcrumbs do %> - <% add_admin_breadcrumb('课程列表') %> -<% end %> - -
- <%= form_tag(admins_course_lists_path, method: :get, class: 'form-inline search-form flex-1', remote: true) do %> -
- - <% auto_trial_options = [['创建者姓名', 0], ['课程名称', 1]] %> - <%= select_tag(:search_type, options_for_select(auto_trial_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','data-disable-with': '搜索中...') %> - <%= link_to "清除",admins_course_lists_path,class: "btn btn-default",id:"course-lists-clear-search",'data-disable-with': '清除中...' %> - <% end %> -
- -
- <%= render partial: 'admins/course_lists/shared/list', locals: { courses: @course_lists } %> -
- -<%= render 'admins/course_lists/shared/merge_course_list_modal' %> \ No newline at end of file diff --git a/app/views/admins/course_lists/index.js.erb b/app/views/admins/course_lists/index.js.erb deleted file mode 100644 index e4bfead7d..000000000 --- a/app/views/admins/course_lists/index.js.erb +++ /dev/null @@ -1 +0,0 @@ -$(".course-list-list-container").html("<%= j render partial: 'admins/course_lists/shared/list', locals: { courses: @course_lists }%>"); \ No newline at end of file diff --git a/app/views/admins/course_lists/shared/_list.html.erb b/app/views/admins/course_lists/shared/_list.html.erb deleted file mode 100644 index 228385b3e..000000000 --- a/app/views/admins/course_lists/shared/_list.html.erb +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - <% if courses.present? %> - <% courses.each_with_index do |course_list,index| %> - - - - - <% course_count = course_list.courses.size %> - - - - - - <% end %> - <% else %> - <%= render 'admins/shared/no_data_for_table' %> - <% end %> - -
序号ID课程名称课堂数创建者<%= sort_tag('创建时间', name: 'created_at', path: admins_course_lists_path) %>操作
<%= list_index_no(@params_page.to_i, index) %><%= course_list.id %><%= course_list.name %><%= course_count %><%= link_to course_list.user.try(:real_name),"/users/#{course_list.user.try(:login)}",target:'_blank' %><%= format_time course_list.created_at %> - <% if course_count == 0 %> - <%= delete_link '删除', admins_course_list_path(course_list, element: ".course-list-item-#{course_list.id}"), class: 'delete-department-action' %> - <% end %> - <%= javascript_void_link '修改', class: 'action', data: { course_list_id: course_list.id, - toggle: 'modal', target: '.admin-merge-course-list-modal', url: merge_admins_course_lists_path } %> -
- -<%= render partial: 'admins/shared/paginate', locals: { objects: courses } %> \ No newline at end of file diff --git a/app/views/admins/course_lists/shared/_merge_course_list_modal.html.erb b/app/views/admins/course_lists/shared/_merge_course_list_modal.html.erb deleted file mode 100644 index 4858f5372..000000000 --- a/app/views/admins/course_lists/shared/_merge_course_list_modal.html.erb +++ /dev/null @@ -1,29 +0,0 @@ - \ No newline at end of file diff --git a/app/views/admins/courses/destroy.js.erb b/app/views/admins/courses/destroy.js.erb deleted file mode 100644 index 811038193..000000000 --- a/app/views/admins/courses/destroy.js.erb +++ /dev/null @@ -1,2 +0,0 @@ -alert("删除成功"); -$(".course-item-<%= @course.id %>").find(".delete-course-action").remove(); \ No newline at end of file diff --git a/app/views/admins/courses/index.html.erb b/app/views/admins/courses/index.html.erb deleted file mode 100644 index 84ea98223..000000000 --- a/app/views/admins/courses/index.html.erb +++ /dev/null @@ -1,34 +0,0 @@ -<% define_admin_breadcrumbs do %> - <% add_admin_breadcrumb('课堂列表') %> -<% end %> - -
- <%= form_tag(admins_courses_path, method: :get, class: 'form-inline search-form flex-1', remote: true) do %> -
- - <% status_options = [['全部', ''], ["正在进行(#{@processed_courses})", 'processing'], ["已结束#{@ended_courses}", 'ended']] %> - <%= select_tag(:status, options_for_select(status_options), class: 'form-control') %> -
- -
- - <%= select_tag :school_id, options_for_select([''], params[:school_id]), class: 'form-control school-select flex-1' %> -
- - <%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-12 col-md-2 mr-3', placeholder: '创建者/课堂名称/课程名称检索') %> - -
- <%= hidden_field_tag(:homepage_show, false, id:'') %> - <%= check_box_tag(:homepage_show, true, params[:homepage_show].to_s == 'true', class: 'form-check-input course-homepage-show') %> - -
- - <%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %> - - <% end %> - 导出 -
- -
- <%= render partial: 'admins/courses/shared/list', locals: { courses: @courses } %> -
\ No newline at end of file diff --git a/app/views/admins/courses/index.js.erb b/app/views/admins/courses/index.js.erb deleted file mode 100644 index 7073c2a81..000000000 --- a/app/views/admins/courses/index.js.erb +++ /dev/null @@ -1 +0,0 @@ -$('.course-list-container').html("<%= j( render partial: 'admins/courses/shared/list', locals: { courses: @courses } ) %>"); \ No newline at end of file diff --git a/app/views/admins/courses/index.xlsx.axlsx b/app/views/admins/courses/index.xlsx.axlsx deleted file mode 100644 index 7cab54482..000000000 --- a/app/views/admins/courses/index.xlsx.axlsx +++ /dev/null @@ -1,29 +0,0 @@ -wb = xlsx_package.workbook - -wb.styles do |s| - blue_cell = s.add_style :bg_color => "FAEBDC", :sz => 10,:height => 25,:b => true, :border => { :style => :thin, :color =>"000000" },:alignment => {wrap_text: true,:horizontal => :center,:vertical => :center} - wb.add_worksheet(name: "课堂列表") do |sheet| - sheet.add_row %w(ID 课堂名称 成员 资源 普通作业 分组作业 实训作业 试卷 评测次数 私有 状态 单位 创建者 创建时间 动态时间), :height => 25,:style => blue_cell - - @courses.each do |course| - data = [ - course.id, - course.name, - course.course_members_count, - get_attachment_count(course, 0), - course.course_homework_count(1), - course.course_homework_count(3), - course.course_homework_count(4), - course.exercises_count, - course.evaluate_count, - course.is_public == 1 ? "--" : "√", - course.is_end ? "已结束" : "正在进行", - course.school&.name, - course.teacher&.real_name, - course.created_at&.strftime('%Y-%m-%d %H:%M'), - course.max_activity_time ? course.max_activity_time&.strftime('%Y-%m-%d %H:%M') : "--" - ] - sheet.add_row(data) - end - end -end diff --git a/app/views/admins/courses/shared/_import_course_member_modal.html.erb b/app/views/admins/courses/shared/_import_course_member_modal.html.erb deleted file mode 100644 index d52a60b09..000000000 --- a/app/views/admins/courses/shared/_import_course_member_modal.html.erb +++ /dev/null @@ -1,30 +0,0 @@ - \ No newline at end of file diff --git a/app/views/admins/courses/shared/_list.html.erb b/app/views/admins/courses/shared/_list.html.erb deleted file mode 100644 index 4105c8153..000000000 --- a/app/views/admins/courses/shared/_list.html.erb +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - <% if courses.present? %> - <% courses.each_with_index do |course, index| %> - - <%= render partial: 'admins/courses/shared/td', locals: {course: course, no: index} %> - - <% end %> - <% else %> - <%= render 'admins/shared/no_data_for_table' %> - <% end %> - -
序号ID课堂名称成员资源普通作业分组作业实训作业试卷评测次数私有状态单位创建者<%= sort_tag('创建时间', name: 'created_at', path: admins_courses_path) %>首页邮件通知操作
- -<%= render partial: 'admins/shared/paginate', locals: { objects: courses } %> \ No newline at end of file diff --git a/app/views/admins/courses/shared/_td.html.erb b/app/views/admins/courses/shared/_td.html.erb deleted file mode 100644 index 51cc4b199..000000000 --- a/app/views/admins/courses/shared/_td.html.erb +++ /dev/null @@ -1,28 +0,0 @@ -<%= list_index_no((params[:page] || 1).to_i, no) %> -<%= course.id %> - - <%= link_to(course.name, "/courses/#{course.id}", target: '_blank') %> - -<%= course.course_members_count %> -<%= get_attachment_count(course, 0) %> -<%= course.course_homework_count(1) %> -<%= course.course_homework_count(3) %> -<%= course.course_homework_count(4) %> -<%= course.exercises_count %> -<%= course.evaluate_count %> -<%= course.is_public == 1 ? "--" : "√" %> -<%= course.is_end ? "已结束" : "正在进行" %> -<%= course.school&.name %> -<%= course.teacher&.real_name %> -<%= course.created_at&.strftime('%Y-%m-%d %H:%M') %> - - <%= check_box_tag :homepage_show,!course.homepage_show,course.homepage_show,remote:true,data:{id:course.id},class:"course-setting-form" %> - - - <%= check_box_tag :email_notify,!course.email_notify,course.email_notify,remote:true,data:{id:course.id},class:"course-setting-form" %> - - - <% if course.is_delete == 0 %> - <%= delete_link '删除', admins_course_path(course, element: ".course-item-#{course.id}"), class: 'delete-course-action' %> - <% end %> - \ No newline at end of file diff --git a/app/views/admins/courses/update.js.erb b/app/views/admins/courses/update.js.erb deleted file mode 100644 index 983ac22f0..000000000 --- a/app/views/admins/courses/update.js.erb +++ /dev/null @@ -1,3 +0,0 @@ -var index = $("#course-item-<%= @course.id %>").children(":first").html(); -$("#course-item-<%= @course.id %>").html("<%= j render partial: "admins/courses/shared/td",locals: {course: @course, no: 1} %>"); -$("#course-item-<%= @course.id %>").children(":first").html(index); \ No newline at end of file diff --git a/app/views/admins/customers/index.html.erb b/app/views/admins/customers/index.html.erb deleted file mode 100644 index b93a5c1e8..000000000 --- a/app/views/admins/customers/index.html.erb +++ /dev/null @@ -1,19 +0,0 @@ -<% define_admin_breadcrumbs do %> - <% add_admin_breadcrumb('合作伙伴', admins_partners_path) %> - <% add_admin_breadcrumb(current_partner.school&.name || current_partner.name) %> -<% end %> - -
- <%= form_tag(admins_partner_customers_path(current_partner), method: :get, class: 'form-inline search-form', remote: true) do %> - <%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-md-4 ml-3', placeholder: '客户名称检索') %> - <%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %> - <% end %> - - <%= javascript_void_link('添加', class: 'btn btn-primary', data: { toggle: 'modal', target: '.admin-select-school-modal' }) %> -
- -
- <%= render 'admins/customers/shared/list', customers: @customers %> -
- -<%= render partial: 'admins/shared/modal/select_school_modal', locals: { title: '添加客户', multiple: true, url: admins_partner_customers_path(current_partner) } %> \ No newline at end of file diff --git a/app/views/admins/customers/index.js.erb b/app/views/admins/customers/index.js.erb deleted file mode 100644 index 8fa2e205d..000000000 --- a/app/views/admins/customers/index.js.erb +++ /dev/null @@ -1 +0,0 @@ -$('.customer-list-container').html("<%= j(render partial: 'admins/customers/shared/list', locals: { customers: @customers }) %>"); \ No newline at end of file diff --git a/app/views/admins/customers/shared/_list.html.erb b/app/views/admins/customers/shared/_list.html.erb deleted file mode 100644 index 6f84db4e5..000000000 --- a/app/views/admins/customers/shared/_list.html.erb +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - <% if customers.present? %> - <% customers.each_with_index do |customer, index| %> - - - - - - - <% end %> - <% else %> - <%= render 'admins/shared/no_data_for_table' %> - <% end %> - -
序号客户名称<%= sort_tag('添加时间', name: 'created_at', path: admins_partner_customers_path(current_partner)) %>操作
<%= list_index_no((params[:page] || 1).to_i, index) %><%= customer.school&.name %><%= customer.created_at&.strftime('%Y-%m-%d %H:%M') %> - <%= delete_link '删除', admins_partner_customer_path(current_partner, customer, element: ".customer-item-#{customer.id}"), class: 'delete-customer-action' %> -
- -<%= render partial: 'admins/shared/paginate', locals: { objects: customers } %> \ No newline at end of file diff --git a/app/views/admins/daily_school_statistics/export.xlsx.axlsx b/app/views/admins/daily_school_statistics/export.xlsx.axlsx deleted file mode 100644 index 1757a8fe2..000000000 --- a/app/views/admins/daily_school_statistics/export.xlsx.axlsx +++ /dev/null @@ -1,13 +0,0 @@ -wb = xlsx_package.workbook -wb.add_worksheet(name: '统计总表') do |sheet| - sheet.add_row %w(ID 单位名称 教师总人数 学生总人数 课堂总数 正在进行课堂数 总实训数 实训评测总数 实训作业总数 其它作业总数 动态时间) - - @schools.each do |school| - sheet.add_row([ - school[:id].to_s, school[:name].to_s, (school[:teacher_count] || 0).to_s, (school[:student_count] || 0).to_s, - (school[:course_count] || 0).to_s, (school[:active_course_count] || 0).to_s, - (school[:shixun_count] || 0).to_s,(school[:shixun_evaluate_count] || 0).to_s, (school[:homework_count] || 0).to_s, - (school[:other_homework_count] || 0).to_s, format_time(school[:nearly_course_time]) - ]) - end -end \ No newline at end of file diff --git a/app/views/admins/daily_school_statistics/index.html.erb b/app/views/admins/daily_school_statistics/index.html.erb deleted file mode 100644 index c3eb43691..000000000 --- a/app/views/admins/daily_school_statistics/index.html.erb +++ /dev/null @@ -1,29 +0,0 @@ -<% define_admin_breadcrumbs do %> - <% add_admin_breadcrumb('统计总表', admins_daily_school_statistics_path) %> -<% end %> - -
- <%= form_tag(admins_daily_school_statistics_path, method: :get, class: 'form-inline search-form', remote: true) do %> - <%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-sm-2 ml-3', placeholder: 'ID/单位名称搜索') %> - <%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %> - <% end %> - - <%#= link_to '导出Excel', export_admins_daily_school_statistics_path(format: :xlsx), class: 'btn btn-outline-primary export-action' %> - <%= javascript_void_link '导出Excel', class: 'btn btn-outline-primary export-action', 'data-url': export_admins_daily_school_statistics_path(format: :xlsx) %> -
- -
- 统计总计: - 教师总人数<%= @teacher_total %>人, - 学生总人数<%= @student_total %>人, - 课堂总数<%= @course_total %>个, - 正在进行课堂总数<%= @active_course_total %>个, - 实训总数<%= @shixun_total %>个, - 实训评测总数<%= @shixun_evaluate_total %>个, - 实训作业总数<%= @shixun_homework_total %>个, - 其它作业总数<%= @other_homework_total %>个 -
- -
- <%= render partial: 'admins/daily_school_statistics/shared/list', locals: { statistics: @statistics } %> -
\ No newline at end of file diff --git a/app/views/admins/daily_school_statistics/index.js.erb b/app/views/admins/daily_school_statistics/index.js.erb deleted file mode 100644 index d3e261f64..000000000 --- a/app/views/admins/daily_school_statistics/index.js.erb +++ /dev/null @@ -1 +0,0 @@ -$(".daily-school-statistic-list-container").html("<%= j(render partial: 'admins/daily_school_statistics/shared/list', locals: { statistics: @statistics }) %>") \ No newline at end of file diff --git a/app/views/admins/daily_school_statistics/shared/_list.html.erb b/app/views/admins/daily_school_statistics/shared/_list.html.erb deleted file mode 100644 index 6982891ee..000000000 --- a/app/views/admins/daily_school_statistics/shared/_list.html.erb +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - - - - - - - - - - <% if statistics.present? %> - <% statistics.each_with_index do |statistic, index| %> - - - - - - - - - - - - - - <% end %> - <% else %> - <%= render 'admins/shared/no_data_for_table' %> - <% end %> - -
序号单位名称<%= sort_tag('教师总数', name: 'teacher_count', path: admins_daily_school_statistics_path) %><%= sort_tag('学生总数', name: 'student_count', path: admins_daily_school_statistics_path) %><%= sort_tag('课堂总数', name: 'course_count', path: admins_daily_school_statistics_path) %><%= sort_tag('正在进行课堂数', name: 'active_course_count', path: admins_daily_school_statistics_path) %><%= sort_tag('实训总数', name: 'shixun_count', path: admins_daily_school_statistics_path) %> - <%= sort_tag(name: 'shixun_evaluate_count', path: admins_daily_school_statistics_path) do %> - 实训评测总数 - - <% end %> - <%= sort_tag('实训作业总数', name: 'homework_count', path: admins_daily_school_statistics_path) %><%= sort_tag('其它作业总数', name: 'other_homework_count', path: admins_daily_school_statistics_path) %><%= sort_tag('动态时间', name: 'nearly_course_time', path: admins_daily_school_statistics_path) %>
<%= list_index_no(@params_page.to_i, index) %> - <%= link_to statistic[:name], "/colleges/#{statistic[:id]}/statistics", - target: '_blank', data: { toggle: 'tooltip', title: '点击查看学校统计概况' } %> - <%= statistic[:teacher_count].to_i %><%= statistic[:student_count].to_i %><%= statistic[:course_count].to_i %><%= statistic[:active_course_count].to_i %><%= statistic[:shixun_count].to_i %><%= statistic[:shixun_evaluate_count].to_i %><%= statistic[:homework_count].to_i %><%= statistic[:other_homework_count].to_i %><%= statistic[:nearly_course_time]&.strftime('%Y-%m-%d %H:%M') %>
- -<%= render partial: 'admins/shared/paginate', locals: { objects: statistics } %> \ No newline at end of file diff --git a/app/views/admins/department_applies/index.html.erb b/app/views/admins/department_applies/index.html.erb deleted file mode 100644 index 8a8a41e41..000000000 --- a/app/views/admins/department_applies/index.html.erb +++ /dev/null @@ -1,18 +0,0 @@ -<% define_admin_breadcrumbs do %> - <% add_admin_breadcrumb('部门审批') %> -<% end %> - -
- <%= form_tag(admins_department_applies_path(unsafe_params), method: :get, class: 'form-inline search-form mt-3', remote: true) do %> - <%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-sm-2 ml-3', placeholder: '部门名称检索') %> - <%= submit_tag('搜索', class: 'btn btn-primary ml-3','data-disable-with':"搜索中...") %> - <%= link_to "清除",admins_department_applies_path(keyword:nil),class:"btn btn-default",remote:true %> - <% end %> -
- -
- <%= render(partial: 'admins/department_applies/shared/list', locals: { applies: @depart_applies }) %> -
- -<%= render(partial: 'admins/shared/admin_common_refuse_modal') %> -<%= render 'admins/departments/shared/merge_department_modal' %> \ No newline at end of file diff --git a/app/views/admins/department_applies/index.js.erb b/app/views/admins/department_applies/index.js.erb deleted file mode 100644 index 8e11b834c..000000000 --- a/app/views/admins/department_applies/index.js.erb +++ /dev/null @@ -1 +0,0 @@ -$(".department-applies-list-container").html("<%= j render partial: "admins/department_applies/shared/list",locals: {applies:@depart_applies} %>") \ No newline at end of file diff --git a/app/views/admins/department_applies/shared/_list.html.erb b/app/views/admins/department_applies/shared/_list.html.erb deleted file mode 100644 index 87d5ab66f..000000000 --- a/app/views/admins/department_applies/shared/_list.html.erb +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - - - - - - - <% if applies.present? %> - <% applies.each_with_index do |apply, index| %> - - - - - - - - - - <% end %> - <% else %> - <%= render 'admins/shared/no_data_for_table' %> - <% end %> - -
序号ID部门名称单位名称创建者<%= sort_tag('创建于', name: 'created_at', path: admins_department_applies_path) %>操作
<%= list_index_no((params[:page] || 1).to_i, index) %><%= apply.id %> <%= apply.name %> <%= apply.school.try(:name) %><%= apply&.user&.real_name %><%= format_time apply.created_at %> - <%= agree_link '批准', agree_admins_department_apply_path(apply, element: ".department-apply-#{apply.id}"), 'data-confirm': '确认批准通过?' %> - <%= javascript_void_link('删除', class: 'action refuse-action', - data: { - toggle: 'modal', target: '.admin-common-refuse-modal', id: apply.id, title: "删除原因", type: "delete", - url: admins_department_apply_path(apply,tip:"unapplied", element: ".department-apply-#{apply.id}") - }) %> - <%= javascript_void_link '更改', class: 'action', data: { school_id: apply.school_id, department_id: apply.id, - toggle: 'modal', target: '.admin-merge-department-modal', url: merge_admins_department_applies_path } %> -
- -<%= render partial: 'admins/shared/paginate', locals: { objects: applies } %> \ No newline at end of file diff --git a/app/views/admins/department_members/create.js.erb b/app/views/admins/department_members/create.js.erb deleted file mode 100644 index 6bf0a6ac3..000000000 --- a/app/views/admins/department_members/create.js.erb +++ /dev/null @@ -1,6 +0,0 @@ -$('.modal.admin-add-department-member-modal').modal('hide'); -$.notify({ message: '操作成功' }); - -var index = $(".department-item-<%= current_department.id %>").children(":first").html(); -$('.department-list-table .department-item-<%= current_department.id %>').html("<%= j(render partial: 'admins/departments/shared/department_item', locals: { department: current_department, index: 1 }) %>"); -$(".department-item-<%= current_department.id %>").children(":first").html(index); \ No newline at end of file diff --git a/app/views/admins/department_members/destroy.js.erb b/app/views/admins/department_members/destroy.js.erb deleted file mode 100644 index d3eb3755b..000000000 --- a/app/views/admins/department_members/destroy.js.erb +++ /dev/null @@ -1,2 +0,0 @@ -$.notify({ message: '操作成功' }); -$('.department-list-container .department-item-<%= current_department.id %> .member-user-item-<%= @member.user_id %>').remove(); \ No newline at end of file diff --git a/app/views/admins/departments/edit.js.erb b/app/views/admins/departments/edit.js.erb deleted file mode 100644 index dc86d3ae0..000000000 --- a/app/views/admins/departments/edit.js.erb +++ /dev/null @@ -1,2 +0,0 @@ -$('.admin-modal-container').html("<%= j( render partial: 'admins/departments/shared/edit_department_modal', locals: { department: current_department } ) %>"); -$('.modal.admin-edit-department-modal').modal('show'); \ No newline at end of file diff --git a/app/views/admins/departments/index.html.erb b/app/views/admins/departments/index.html.erb deleted file mode 100644 index b1a0fee3e..000000000 --- a/app/views/admins/departments/index.html.erb +++ /dev/null @@ -1,33 +0,0 @@ -<% define_admin_breadcrumbs do %> - <% add_admin_breadcrumb('部门列表') %> -<% end %> - -
- <%= form_tag(admins_departments_path, method: :get, class: 'form-inline search-form flex-1', remote: true) do %> -
- <%= hidden_field_tag(:with_member, false,id:'') %> - <%= check_box_tag(:with_member, true, params[:with_member].to_s == 'true', class: 'form-check-input') %> - -
- -
- <%= hidden_field_tag(:with_identifier, false,id:'') %> - <%= check_box_tag(:with_identifier, true, params[:with_identifier].to_s == 'true', class: 'form-check-input') %> - -
- - <%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-sm-2 ml-3', placeholder: '部门/单位名称检索') %> - <%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %> - <% end %> - - <%= javascript_void_link '新建部门', class: 'btn btn-primary', data: { toggle: 'modal', target: '.admin-create-department-modal' } %> -
- -
- <%= render partial: 'admins/departments/shared/list', - locals: { departments: @departments, users_count: @users_count, professional_auth_count: @professional_auth_count } %> -
- -<%= render 'admins/departments/shared/create_department_modal' %> -<%= render 'admins/departments/shared/add_department_member_modal' %> -<%= render 'admins/departments/shared/merge_department_modal' %> \ No newline at end of file diff --git a/app/views/admins/departments/index.js.erb b/app/views/admins/departments/index.js.erb deleted file mode 100644 index bd2e4b25d..000000000 --- a/app/views/admins/departments/index.js.erb +++ /dev/null @@ -1 +0,0 @@ -$('.department-list-container').html("<%= j(render partial: 'admins/departments/shared/list', locals: { departments: @departments, users_count: @users_count, professional_auth_count: @professional_auth_count }) %>"); \ No newline at end of file diff --git a/app/views/admins/departments/shared/_add_department_member_modal.html.erb b/app/views/admins/departments/shared/_add_department_member_modal.html.erb deleted file mode 100644 index 5d2707222..000000000 --- a/app/views/admins/departments/shared/_add_department_member_modal.html.erb +++ /dev/null @@ -1,30 +0,0 @@ - \ No newline at end of file diff --git a/app/views/admins/departments/shared/_create_department_modal.html.erb b/app/views/admins/departments/shared/_create_department_modal.html.erb deleted file mode 100644 index ae6605eb8..000000000 --- a/app/views/admins/departments/shared/_create_department_modal.html.erb +++ /dev/null @@ -1,35 +0,0 @@ - \ No newline at end of file diff --git a/app/views/admins/departments/shared/_department_item.html.erb b/app/views/admins/departments/shared/_department_item.html.erb deleted file mode 100644 index 6018686ff..000000000 --- a/app/views/admins/departments/shared/_department_item.html.erb +++ /dev/null @@ -1,36 +0,0 @@ -<%= list_index_no((params[:page] || 1).to_i, index) %> -<% not_list = defined?(:users_count) %> - -<%= overflow_hidden_span department.name, width: 150 %> -<%= overflow_hidden_span department.school.name, width: 150 %> - -<% if not_list %> - <%= department.user_extensions.count %> - <%= department.user_extensions.joins(:user).where(users: { professional_certification: true }).count %> -<% else %> - <%= users_count.fetch(department.id, 0) %> - <%= professional_auth_count.fetch(department.id, 0) %> -<% end %> - - - <%= render partial: 'admins/departments/shared/member_users', locals: { department: department } %> - - - <% if department.identifier.present? %> - <%= link_to department.identifier.to_s, "/colleges/#{department.identifier}/statistics", target: '_blank' %> - <% else %> - -- - <% end %> - -<%= department.host_count %> -<%= department.created_at&.strftime('%Y-%m-%d %H:%M') %> - - <%= link_to '编辑', edit_admins_department_path(department), remote: true, class: 'action' %> - - <%= javascript_void_link '添加管理员', class: 'action', data: { department_id: department.id, toggle: 'modal', target: '.admin-add-department-member-modal' } %> - - <%= javascript_void_link '更改', class: 'action', data: { school_id: department.school_id, department_id: department.id, - toggle: 'modal', target: '.admin-merge-department-modal', url: merge_admins_departments_path } %> - - <%= delete_link '删除', admins_department_path(department, element: ".department-item-#{department.id}"), class: 'delete-department-action' %> - \ No newline at end of file diff --git a/app/views/admins/departments/shared/_edit_department_modal.html.erb b/app/views/admins/departments/shared/_edit_department_modal.html.erb deleted file mode 100644 index 38b43bbce..000000000 --- a/app/views/admins/departments/shared/_edit_department_modal.html.erb +++ /dev/null @@ -1,25 +0,0 @@ - \ No newline at end of file diff --git a/app/views/admins/departments/shared/_list.html.erb b/app/views/admins/departments/shared/_list.html.erb deleted file mode 100644 index 09ba2a65f..000000000 --- a/app/views/admins/departments/shared/_list.html.erb +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - - - - <% if departments.present? %> - <% departments.each_with_index do |department, index| %> - - <%= render partial: 'admins/departments/shared/department_item', locals: {department: department, index: index} %> - - <% end %> - <% else %> - <%= render 'admins/shared/no_data_for_table' %> - <% end %> - -
序号部门名称单位名称用户数已职业认证部门管理员统计链接云主机数<%= sort_tag('创建时间', name: 'created_at', path: admins_departments_path) %>操作
- -<%= render partial: 'admins/shared/paginate', locals: { objects: departments } %> \ No newline at end of file diff --git a/app/views/admins/departments/shared/_member_users.html.erb b/app/views/admins/departments/shared/_member_users.html.erb deleted file mode 100644 index 8d4d466db..000000000 --- a/app/views/admins/departments/shared/_member_users.html.erb +++ /dev/null @@ -1,12 +0,0 @@ -
- <% department.member_users.each do |user| %> - - <%= link_to user.real_name, "/users/#{user.login}", target: '_blank', data: { toggle: 'tooltip', title: '个人主页' } %> - <%= link_to(admins_department_department_member_path(department, user_id: user.id), - method: :delete, remote: true, class: 'ml-1 delete-member-action', - data: { confirm: '确认删除吗?' }) do %> - - <% end %> - - <% end %> -
\ No newline at end of file diff --git a/app/views/admins/departments/shared/_merge_department_modal.html.erb b/app/views/admins/departments/shared/_merge_department_modal.html.erb deleted file mode 100644 index 5c1ca6892..000000000 --- a/app/views/admins/departments/shared/_merge_department_modal.html.erb +++ /dev/null @@ -1,30 +0,0 @@ - \ No newline at end of file diff --git a/app/views/admins/departments/update.js.erb b/app/views/admins/departments/update.js.erb deleted file mode 100644 index d20ca9524..000000000 --- a/app/views/admins/departments/update.js.erb +++ /dev/null @@ -1,6 +0,0 @@ -$('.modal.admin-edit-department-modal').modal('hide'); -$.notify({ message: '操作成功' }); - -var index = $(".department-item-<%= current_department.id %>").children(":first").html(); -$('.department-list-table .department-item-<%= current_department.id %>').html("<%= j(render partial: 'admins/departments/shared/department_item', locals: {department: current_department, index: 1}) %>"); -$(".department-item-<%= current_department.id %>").children(":first").html(index); \ No newline at end of file diff --git a/app/views/admins/disciplines/adjust_position.js.erb b/app/views/admins/disciplines/adjust_position.js.erb deleted file mode 100644 index a0928056e..000000000 --- a/app/views/admins/disciplines/adjust_position.js.erb +++ /dev/null @@ -1,5 +0,0 @@ -<% if @message.present? %> -$.notify({ message: "<%= @message %>" }); -<% else %> -$(".discipline-list-container").html("<%= j(render :partial => 'admins/disciplines/shared/list') %>"); -<% end %> \ No newline at end of file diff --git a/app/views/admins/disciplines/destroy.js.erb b/app/views/admins/disciplines/destroy.js.erb deleted file mode 100644 index ea9aedcd8..000000000 --- a/app/views/admins/disciplines/destroy.js.erb +++ /dev/null @@ -1,2 +0,0 @@ -$.notify({ message: '删除成功' }); -$(".discipline-item-<%= @discipline_id %>").remove(); \ No newline at end of file diff --git a/app/views/admins/disciplines/edit.js.erb b/app/views/admins/disciplines/edit.js.erb deleted file mode 100644 index 48c5b789f..000000000 --- a/app/views/admins/disciplines/edit.js.erb +++ /dev/null @@ -1,2 +0,0 @@ -$('.admin-modal-container').html("<%= j( render partial: 'admins/disciplines/shared/edit_discipline_modal', locals: { discipline: @discipline } ) %>"); -$('.modal.admin-edit-discipline-modal').modal('show'); \ No newline at end of file diff --git a/app/views/admins/disciplines/index.html.erb b/app/views/admins/disciplines/index.html.erb deleted file mode 100644 index f4b116b93..000000000 --- a/app/views/admins/disciplines/index.html.erb +++ /dev/null @@ -1,17 +0,0 @@ -<% define_admin_breadcrumbs do %> - <% add_admin_breadcrumb('课程方向', admins_disciplines_path) %> -<% end %> - -
-
- <%= javascript_void_link '新增', class: 'btn btn-primary', data: { toggle: 'modal', target: '.admin-create-discipline-modal' } %> -
- <%= javascript_void_link '导入数据', class: 'btn btn-primary', data: { toggle: 'modal', target: '.admin-import-discipline-modal'} %> -
- -
- <%= render(partial: 'admins/disciplines/shared/list') %> -
- -<%= render 'admins/disciplines/shared/create_discipline_modal' %> -<%= render partial: 'admins/disciplines/shared/import_discipline_modal' %> diff --git a/app/views/admins/disciplines/shared/_create_discipline_modal.html.erb b/app/views/admins/disciplines/shared/_create_discipline_modal.html.erb deleted file mode 100644 index 7eb5d8985..000000000 --- a/app/views/admins/disciplines/shared/_create_discipline_modal.html.erb +++ /dev/null @@ -1,28 +0,0 @@ - \ No newline at end of file diff --git a/app/views/admins/disciplines/shared/_edit_discipline_modal.html.erb b/app/views/admins/disciplines/shared/_edit_discipline_modal.html.erb deleted file mode 100644 index ce511e27c..000000000 --- a/app/views/admins/disciplines/shared/_edit_discipline_modal.html.erb +++ /dev/null @@ -1,23 +0,0 @@ - \ No newline at end of file diff --git a/app/views/admins/disciplines/shared/_import_discipline_modal.html.erb b/app/views/admins/disciplines/shared/_import_discipline_modal.html.erb deleted file mode 100644 index de54fd758..000000000 --- a/app/views/admins/disciplines/shared/_import_discipline_modal.html.erb +++ /dev/null @@ -1,30 +0,0 @@ - \ No newline at end of file diff --git a/app/views/admins/disciplines/shared/_list.html.erb b/app/views/admins/disciplines/shared/_list.html.erb deleted file mode 100644 index 38cbe8c9c..000000000 --- a/app/views/admins/disciplines/shared/_list.html.erb +++ /dev/null @@ -1,37 +0,0 @@ -<% max_position = @disciplines.pluck(:position).max %> - - - - - - - - - - - - - <% if @disciplines.present? %> - <% @disciplines.each do |discipline| %> - - - - - - - - - <% end %> - <% else %> - <%= render 'admins/shared/no_data_for_table' %> - <% end %> - -
序号课程方向实践课程实训题库操作
<%= discipline.position %> - <%= link_to discipline.name, admins_sub_disciplines_path(discipline_id: discipline), :title => discipline.name %> - <%= check_box_tag :subject,!discipline.subject,discipline.subject,remote:true,data:{id:discipline.id},class:"discipline-source-form" %><%= check_box_tag :shixun,!discipline.shixun,discipline.shixun,remote:true,data:{id:discipline.id},class:"discipline-source-form" %><%= check_box_tag :question,!discipline.question,discipline.question,remote:true,data:{id:discipline.id},class:"discipline-source-form" %> - <%= javascript_void_link('上移', class: 'move-action', data: { id: discipline.id, opr: "up" }, style: discipline.position == 1 ? 'display:none' : '') %> - <%= javascript_void_link('下移', class: 'move-action', data: { id: discipline.id, opr: "down" }, style: discipline.position == max_position ? 'display:none' : '') %> - - <%= link_to '编辑', edit_admins_discipline_path(discipline), remote: true, class: 'action' %> - <%= delete_link '删除', admins_discipline_path(discipline, element: ".discipline-item-#{discipline.id}"), class: 'delete-discipline-action' %> -
\ No newline at end of file diff --git a/app/views/admins/disciplines/update.js.erb b/app/views/admins/disciplines/update.js.erb deleted file mode 100644 index 0c051e1dd..000000000 --- a/app/views/admins/disciplines/update.js.erb +++ /dev/null @@ -1,6 +0,0 @@ -<% if @message.present? %> -$.notify({ message: "<%= @message %>" }); -<% else %> -$('.modal.admin-edit-discipline-modal').modal("hide"); -$(".discipline-list-container").html("<%= j(render :partial => 'admins/disciplines/shared/list') %>"); -<% end %> \ No newline at end of file diff --git a/app/views/admins/examination_authentications/index.html.erb b/app/views/admins/examination_authentications/index.html.erb deleted file mode 100644 index c360a7a18..000000000 --- a/app/views/admins/examination_authentications/index.html.erb +++ /dev/null @@ -1,30 +0,0 @@ -<% define_admin_breadcrumbs do %> - <% add_admin_breadcrumb('试卷审批') %> -<% end %> - -
- - - <%= form_tag(admins_examination_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', 'data-disable-with': '搜索中...') %> - <% end %> -
- -
- <%= render(partial: 'admins/examination_authentications/shared/list', locals: { applies: @applies }) %> -
\ No newline at end of file diff --git a/app/views/admins/examination_authentications/index.js.erb b/app/views/admins/examination_authentications/index.js.erb deleted file mode 100644 index 361059e73..000000000 --- a/app/views/admins/examination_authentications/index.js.erb +++ /dev/null @@ -1 +0,0 @@ -$('.examination-authentication-list-container').html("<%= j( render partial: 'admins/examination_authentications/shared/list', locals: { applies: @applies } ) %>"); \ No newline at end of file diff --git a/app/views/admins/examination_authentications/shared/_item_show_modal.html.erb b/app/views/admins/examination_authentications/shared/_item_show_modal.html.erb deleted file mode 100644 index 9a1c891fe..000000000 --- a/app/views/admins/examination_authentications/shared/_item_show_modal.html.erb +++ /dev/null @@ -1,35 +0,0 @@ - \ No newline at end of file diff --git a/app/views/admins/examination_authentications/shared/_list.html.erb b/app/views/admins/examination_authentications/shared/_list.html.erb deleted file mode 100644 index a751a7fa9..000000000 --- a/app/views/admins/examination_authentications/shared/_list.html.erb +++ /dev/null @@ -1,54 +0,0 @@ -<% is_processed = params[:status].to_s != 'pending' %> - - - - - - - - - - <% if !is_processed %> - - <% else %> - - <% end %> - - - - <% if applies.present? %> - <% applies.each_with_index do |apply, index| %> - <% user = apply.user %> - <% exam = ExaminationBank.find apply.container_id %> - - - - - - - - - - - - <% end %> - <% else %> - <%= render 'admins/shared/no_data_for_table' %> - <% end %> - -
序号头像创建者学校试卷提交时间操作审批结果
<%= list_index_no((params[:page] || 1).to_i, index) %> - <%= link_to "/users/#{user.login}", class: 'examination-authentication-avatar', target: '_blank', data: { toggle: 'tooltip', title: '个人主页' } do %> - - <% end %> - <%= user.real_name %><%= raw [user.school_name.presence, user.department_name.presence].compact.join('
') %>
- <%= link_to exam.name, "/paperlibrary/see/#{exam.id}", target: "_blank" %> - <%= apply.updated_at.strftime('%Y-%m-%d %H:%M') %> - <% if !is_processed %> - <%= agree_link '同意', agree_admins_examination_authentication_path(apply, element: ".examination-authentication-#{apply.id}"), 'data-confirm': '确认同意该审批?', 'data-disable-with': "提交中..." %> - <%= agree_link '拒绝', refuse_admins_examination_authentication_path(apply, element: ".examination-authentication-#{apply.id}"), 'data-confirm': '确认拒绝该审批?', 'data-disable-with': "拒绝中..." %> - <% else %> - <%= apply.status_text %> - <% end %> -
- -<%= render partial: 'admins/shared/paginate', locals: { objects: applies } %> \ No newline at end of file diff --git a/app/views/admins/examination_authentications/show.js.erb b/app/views/admins/examination_authentications/show.js.erb deleted file mode 100644 index 70e44404f..000000000 --- a/app/views/admins/examination_authentications/show.js.erb +++ /dev/null @@ -1,2 +0,0 @@ -$('.admin-modal-container').html("<%= j( render partial: 'admins/item_authentications/shared/item_show_modal', locals: { item: @item } ) %>"); -$('.modal.admin-item-show-modal').modal('show'); \ No newline at end of file diff --git a/app/views/admins/laboratory_settings/show.html.erb b/app/views/admins/laboratory_settings/show.html.erb index 735f19f0a..f30e92b8f 100644 --- a/app/views/admins/laboratory_settings/show.html.erb +++ b/app/views/admins/laboratory_settings/show.html.erb @@ -21,7 +21,7 @@ style: 'text-transform:lowercase'%>
<% rails_env = EduSetting.get('rails_env') %> - <%= rails_env && rails_env != 'production' ? ".#{rails_env}.educoder.net" : '.educoder.net' %> + <%= rails_env && rails_env != 'production' ? ".#{rails_env}.gitlink.org.cn" : '.gitlink.org.cn' %>
<%# if @laboratory.errors && @laboratory.errors.key?(:identifier) %> diff --git a/app/views/admins/laboratory_shixuns/index.html.erb b/app/views/admins/laboratory_shixuns/index.html.erb deleted file mode 100644 index c91ddc60b..000000000 --- a/app/views/admins/laboratory_shixuns/index.html.erb +++ /dev/null @@ -1,45 +0,0 @@ -<% define_admin_breadcrumbs do %> - <% add_admin_breadcrumb('云上实验室', admins_laboratories_path) %> - <% add_admin_breadcrumb("#{current_laboratory.name} - 实训项目") %> -<% end %> - - -
- <%= form_tag(admins_laboratory_laboratory_shixuns_path(current_laboratory), method: :get, class: 'form-inline search-form', remote: true) do %> -
- - <% status_options = [['全部', ''], ['编辑中', 0], ['审核中', 1], ['已发布', 2], ['已关闭', 3]] %> - <%= select_tag(:status, options_for_select(status_options), class: 'form-control') %> -
- -
- - <%= select_tag(:tag_id, options_for_select(MirrorRepository.pluck(:type_name,:id).unshift(['']), params[:tag_id]), class: 'form-control') %> -
- - <%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-12 col-md-2 mr-3', placeholder: '创建者/实训名称检索') %> - -
- <%= hidden_field_tag(:homepage, false, id:'') %> - <%= check_box_tag(:homepage, true, params[:homepage].to_s == 'true', class: 'form-check-input') %> - -
- -
- <%= hidden_field_tag(:ownership, false, id:'') %> - <%= check_box_tag(:ownership, true, params[:ownership].to_s == 'true', class: 'form-check-input') %> - -
- - <%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %> - <%= link_to '清空', admins_laboratory_laboratory_shixuns_path(current_laboratory), class: 'btn btn-default','data-disable-with': '清空中...' %> - <% end %> - - <%= javascript_void_link('添加实训', class: 'btn btn-primary', data: { toggle: 'modal', target: '.admin-add-laboratory-shixun-modal' }) %> -
- -
- <%= render partial: 'admins/laboratory_shixuns/shared/list', locals: { laboratory_shixuns: @laboratory_shixuns } %> -
- -<%= render partial: 'admins/laboratory_shixuns/shared/add_laboratory_shixun_modal' %> \ No newline at end of file diff --git a/app/views/admins/laboratory_shixuns/index.js.erb b/app/views/admins/laboratory_shixuns/index.js.erb deleted file mode 100644 index 0a51afa21..000000000 --- a/app/views/admins/laboratory_shixuns/index.js.erb +++ /dev/null @@ -1 +0,0 @@ -$('.laboratory-shixun-list-container').html("<%= j(render partial: 'admins/laboratory_shixuns/shared/list', locals: { laboratory_shixuns: @laboratory_shixuns }) %>"); \ No newline at end of file diff --git a/app/views/admins/laboratory_shixuns/shared/_add_laboratory_shixun_modal.html.erb b/app/views/admins/laboratory_shixuns/shared/_add_laboratory_shixun_modal.html.erb deleted file mode 100644 index 56d01d663..000000000 --- a/app/views/admins/laboratory_shixuns/shared/_add_laboratory_shixun_modal.html.erb +++ /dev/null @@ -1,28 +0,0 @@ - \ No newline at end of file diff --git a/app/views/admins/laboratory_shixuns/shared/_list.html.erb b/app/views/admins/laboratory_shixuns/shared/_list.html.erb deleted file mode 100644 index 462486f4b..000000000 --- a/app/views/admins/laboratory_shixuns/shared/_list.html.erb +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - <% if laboratory_shixuns.present? %> - <% laboratory_shixuns.each_with_index do |laboratory_shixun, index| %> - - <%= render partial: 'admins/laboratory_shixuns/shared/td', locals: { laboratory_shixun: laboratory_shixun, index: index } %> - - <% end %> - <% else %> - <%= render 'admins/shared/no_data_for_table' %> - <% end %> - -
序号实训名称技术平台技术体系封面创建者状态执行时间操作
- -<%= render partial: 'admins/shared/paginate', locals: { objects: laboratory_shixuns } %> \ No newline at end of file diff --git a/app/views/admins/laboratory_shixuns/shared/_td.html.erb b/app/views/admins/laboratory_shixuns/shared/_td.html.erb deleted file mode 100644 index d987b53b4..000000000 --- a/app/views/admins/laboratory_shixuns/shared/_td.html.erb +++ /dev/null @@ -1,33 +0,0 @@ -<%- shixun = laboratory_shixun.shixun -%> - -<%= list_index_no((params[:page] || 1).to_i, index) %> - - <%= link_to "/shixuns/#{shixun.identifier}", target: '_blank' do %> - <%= shixun.name %> - 首页 - 自建 - <% end %> - -<%= shixun.shixun_main_name %> - - <% shixun.tag_repertoires.each do |tag| %> - <%= tag.name %> - <% end %> - - - <% imageExists = Util::FileManage.exists?(shixun) %> - <% imageUrl = imageExists ? '/' + url_to_avatar(shixun) : '' %> - <%= image_tag(imageUrl, width: 60, height: 40, class: "preview-image shixun-image-#{shixun.id}", data: { toggle: 'tooltip', title: '点击预览' }, style: imageExists ? '' : 'display:none') %> - -<%= link_to shixun.user&.real_name, "/users/#{shixun.user&.login}", target:'_blank' %> -<%= t("shixun.status.#{shixun.status}") %> -<%= shixun.excute_time %> - - <%= link_to('去修改', admins_shixun_settings_path(id: laboratory_shixun.shixun_id)) %> - <%= javascript_void_link('首页展示', class: 'action homepage-show-action', data: { id: laboratory_shixun.id }, style: laboratory_shixun.homepage? ? 'display:none' : '') %> - <%= javascript_void_link('取消首页展示', class: 'action homepage-hide-action', data: { id: laboratory_shixun.id }, style: laboratory_shixun.homepage? ? '' : 'display:none') %> - - <% unless laboratory_shixun.ownership? %> - <%= delete_link '删除', admins_laboratory_laboratory_shixun_path(current_laboratory, laboratory_shixun, element: ".laboratory-shixun-item-#{laboratory_shixun.id}") %> - <% end %> - \ No newline at end of file diff --git a/app/views/admins/laboratory_subjects/index.html.erb b/app/views/admins/laboratory_subjects/index.html.erb deleted file mode 100644 index 211bf24f3..000000000 --- a/app/views/admins/laboratory_subjects/index.html.erb +++ /dev/null @@ -1,45 +0,0 @@ -<% define_admin_breadcrumbs do %> - <% add_admin_breadcrumb('云上实验室', admins_laboratories_path) %> - <% add_admin_breadcrumb("#{current_laboratory.name} - 实践课程") %> -<% end %> - - -
- <%= form_tag(admins_laboratory_laboratory_subjects_path(current_laboratory), method: :get, class: 'form-inline search-form', remote: true) do %> -
- - <% status_options = [['全部', ''], ['编辑中', 0], ['审核中', 1], ['已发布', 2]] %> - <%= select_tag(:status, options_for_select(status_options), class: 'form-control') %> -
- -
- - <%= select_tag :school_id, options_for_select([''], params[:school_id]), class: 'form-control school-select flex-1' %> -
- - <%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-12 col-md-2 mr-3', placeholder: '创建者/课程名称检索') %> - -
- <%= hidden_field_tag(:homepage, false, id:'') %> - <%= check_box_tag(:homepage, true, params[:homepage].to_s == 'true', class: 'form-check-input') %> - -
- -
- <%= hidden_field_tag(:ownership, false, id:'') %> - <%= check_box_tag(:ownership, true, params[:ownership].to_s == 'true', class: 'form-check-input') %> - -
- - <%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %> - <%= link_to '清空', admins_laboratory_laboratory_subjects_path(current_laboratory), class: 'btn btn-default','data-disable-with': '清空中...' %> - <% end %> - - <%= javascript_void_link('添加课程', class: 'btn btn-primary', data: { toggle: 'modal', target: '.admin-add-laboratory-subject-modal' }) %> -
- -
- <%= render partial: 'admins/laboratory_subjects/shared/list', locals: { laboratory_subjects: @laboratory_subjects } %> -
- -<%= render partial: 'admins/laboratory_subjects/shared/add_laboratory_subject_modal' %> \ No newline at end of file diff --git a/app/views/admins/laboratory_subjects/index.js.erb b/app/views/admins/laboratory_subjects/index.js.erb deleted file mode 100644 index 3ebc1286c..000000000 --- a/app/views/admins/laboratory_subjects/index.js.erb +++ /dev/null @@ -1 +0,0 @@ -$('.laboratory-subject-list-container').html("<%= j(render partial: 'admins/laboratory_subjects/shared/list', locals: { laboratory_subjects: @laboratory_subjects }) %>"); \ No newline at end of file diff --git a/app/views/admins/laboratory_subjects/shared/_add_laboratory_subject_modal.html.erb b/app/views/admins/laboratory_subjects/shared/_add_laboratory_subject_modal.html.erb deleted file mode 100644 index 63ab3fdf1..000000000 --- a/app/views/admins/laboratory_subjects/shared/_add_laboratory_subject_modal.html.erb +++ /dev/null @@ -1,28 +0,0 @@ - \ No newline at end of file diff --git a/app/views/admins/laboratory_subjects/shared/_list.html.erb b/app/views/admins/laboratory_subjects/shared/_list.html.erb deleted file mode 100644 index c40d02260..000000000 --- a/app/views/admins/laboratory_subjects/shared/_list.html.erb +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - - - - - - - - - - - <% if laboratory_subjects.present? %> - <% laboratory_subjects.each_with_index do |laboratory_subject, index| %> - - <%- subject = laboratory_subject.subject -%> - - - - - - - - - - - - - <% end %> - <% else %> - <%= render 'admins/shared/no_data_for_table' %> - <% end %> - -
序号课程名称技术体系等级体系封面创建者单位状态操作
<%= list_index_no((params[:page] || 1).to_i, index) %> - <%= link_to(subject.name, "/paths/#{subject.id}", target: '_blank') %> - 首页 - 自建 - <%= display_text subject.repertoire&.name %><%= display_text subject.subject_level_system&.name %> - <% image_exists = Util::FileManage.exists?(subject) %> - <%= image_tag(image_exists ? Util::FileManage.source_disk_file_url(subject) : '', height: 40, class: "w-100 preview-image subject-image-#{subject.id}", style: image_exists ? '' : 'display:none') %> - <%= subject.user.real_name %><%= subject.user.school_name %><%= display_subject_status(subject) %> - <%= link_to('去修改', admins_subjects_path(id: laboratory_subject.subject_id)) %> - <%= javascript_void_link('首页展示', class: 'action homepage-show-action', data: { id: laboratory_subject.id }, style: laboratory_subject.homepage? ? 'display:none' : '') %> - <%= javascript_void_link('取消首页展示', class: 'action homepage-hide-action', data: { id: laboratory_subject.id }, style: laboratory_subject.homepage? ? '' : 'display:none') %> - - <% unless laboratory_subject.ownership? %> - <%= delete_link '删除', admins_laboratory_laboratory_subject_path(current_laboratory, laboratory_subject, element: ".laboratory-subject-item-#{laboratory_subject.id}") %> - <% end %> -
- -<%= render partial: 'admins/shared/paginate', locals: { objects: laboratory_subjects } %> \ No newline at end of file diff --git a/app/views/admins/library_applies/index.html.erb b/app/views/admins/library_applies/index.html.erb deleted file mode 100644 index 9d2ae8e66..000000000 --- a/app/views/admins/library_applies/index.html.erb +++ /dev/null @@ -1,32 +0,0 @@ -<% define_admin_breadcrumbs do %> - <% add_admin_breadcrumb('教学案例发布') %> -<% end %> - -
- - - <%= form_tag(admins_library_applies_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/library_applies/shared/list', locals: { applies: @library_applies }) %> -
- -<%= render(partial: 'admins/shared/admin_common_refuse_modal') %> \ No newline at end of file diff --git a/app/views/admins/library_applies/index.js.erb b/app/views/admins/library_applies/index.js.erb deleted file mode 100644 index 6f4c3e712..000000000 --- a/app/views/admins/library_applies/index.js.erb +++ /dev/null @@ -1 +0,0 @@ -$('.library-applies-list-container').html("<%= j( render partial: 'admins/library_applies/shared/list', locals: { applies: @library_applies } ) %>"); \ No newline at end of file diff --git a/app/views/admins/library_applies/shared/_list.html.erb b/app/views/admins/library_applies/shared/_list.html.erb deleted file mode 100644 index fde3d1d1a..000000000 --- a/app/views/admins/library_applies/shared/_list.html.erb +++ /dev/null @@ -1,58 +0,0 @@ -<% is_processed = params[:status].to_s != 'pending' %> - - - - - - - - - - - <% if is_processed %> - - - <% else %> - - <% end %> - - - - <% if applies.present? %> - <% applies.each_with_index do |apply, index| %> - <% user = apply.library.user %> - <% library = apply.library %> - - - - - - - - - <% if is_processed %> - - - <% else %> - - <% end %> - - <% end %> - <% else %> - <%= render 'admins/shared/no_data_for_table' %> - <% end %> - -
序号头像姓名教学案例案例描述时间拒绝原因状态操作
<%= list_index_no((params[:page] || 1).to_i, index) %> - <%= link_to "/users/#{user.login}", class: 'professional-authentication-avatar', target: '_blank', data: { toggle: 'tooltip', title: '个人主页' } do %> - - <% end %> - <%= link_to user&.real_name,"/users/#{user&.login}", target: "_blank" %><%= link_to library.title, library_path(library), :target => "_blank" %><%= overflow_hidden_span library.content[0..50]%><%= apply.updated_at.strftime('%Y-%m-%d %H:%M') %><%= overflow_hidden_span apply.reason %><%= t("library_apply.status.#{apply.status}") %> - <%= agree_link '同意', agree_admins_library_apply_path(apply, element: ".library_applies-#{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_library_apply_path(apply, element: ".library_applies-#{apply.id}") - }) %> -
- -<%= render partial: 'admins/shared/paginate', locals: { objects: applies } %> \ No newline at end of file diff --git a/app/views/admins/project_categories/_form_modal.html.erb b/app/views/admins/project_categories/_form_modal.html.erb index fd20936b6..fc58d3345 100644 --- a/app/views/admins/project_categories/_form_modal.html.erb +++ b/app/views/admins/project_categories/_form_modal.html.erb @@ -7,9 +7,33 @@ - <%= form_for @project_category, url: {controller: "project_categories", action: "#{type}"} do |p| %> + <%= form_for @project_category, url: {controller: "project_categories", action: "#{type}"}, html: { enctype: 'multipart/form-data' } do |p| %> + +
+
diff --git a/app/views/admins/projects/shared/_form_modal.html.erb b/app/views/admins/projects/shared/_form_modal.html.erb new file mode 100644 index 000000000..b9796756a --- /dev/null +++ b/app/views/admins/projects/shared/_form_modal.html.erb @@ -0,0 +1,26 @@ + \ No newline at end of file diff --git a/app/views/admins/projects/shared/_list.html.erb b/app/views/admins/projects/shared/_list.html.erb index fe8d96e9d..c2d300c2d 100644 --- a/app/views/admins/projects/shared/_list.html.erb +++ b/app/views/admins/projects/shared/_list.html.erb @@ -1,19 +1,20 @@ - - - - - + + + + + + + - - + - - - - + + + + @@ -23,13 +24,14 @@ + + - - + + <% end %> <% else %> diff --git a/app/views/admins/salesman_channels/destroy.js.erb b/app/views/admins/salesman_channels/destroy.js.erb deleted file mode 100644 index d00e4fa08..000000000 --- a/app/views/admins/salesman_channels/destroy.js.erb +++ /dev/null @@ -1,2 +0,0 @@ -$.notify({ message: '操作成功' },{ type: 'success' }); -$("<%= params[:element]%>").remove(); \ No newline at end of file diff --git a/app/views/admins/salesman_channels/index.html.erb b/app/views/admins/salesman_channels/index.html.erb deleted file mode 100644 index 75847a542..000000000 --- a/app/views/admins/salesman_channels/index.html.erb +++ /dev/null @@ -1,36 +0,0 @@ -<% define_admin_breadcrumbs do %> - <% add_admin_breadcrumb("#{@salesman.name}的渠道", admins_salesmans_path) %> -<% end %> - -<% define_admin_breadcrumbs do %> - <% add_admin_breadcrumb('数据变化报表', admins_school_statistics_path) %> -<% end %> - -
-
-
-
-
- <%= text_field_tag :start_date, params[:start_date], class: 'form-control start-date mx-0', placeholder: '开始时间' %> -
- <%= text_field_tag :end_date, params[:end_date], class: 'form-control end-date mx-0', placeholder: '结束时间' %> -
-
- -
- <%= text_field_tag :keyword, params[:keyword], placeholder: 'ID/单位名称检索', class: 'form-control mx-3 search-input' %> - - <%= javascript_void_link '搜索', class: 'btn btn-primary search-btn', target: '' %> - - -
- <%= javascript_void_link '新增渠道', class: 'btn btn-primary', data: {toggle: 'modal', target: '.admin-add-salesman-channel-user-modal' } %> -
-
- - -
- <%= render(partial: 'admins/salesman_channels/shared/list') %> -
- -<%= render 'admins/salesman_channels/shared/add_salesman_channels_user_modal' %> diff --git a/app/views/admins/salesman_channels/index.js.erb b/app/views/admins/salesman_channels/index.js.erb deleted file mode 100644 index 422cfe5cb..000000000 --- a/app/views/admins/salesman_channels/index.js.erb +++ /dev/null @@ -1 +0,0 @@ - $(".salesman-channel-list-container").html("<%= j(render partial: 'admins/salesman_channels/shared/list') %>") \ No newline at end of file diff --git a/app/views/admins/salesman_channels/shared/_add_salesman_channels_user_modal.html.erb b/app/views/admins/salesman_channels/shared/_add_salesman_channels_user_modal.html.erb deleted file mode 100644 index 121e711be..000000000 --- a/app/views/admins/salesman_channels/shared/_add_salesman_channels_user_modal.html.erb +++ /dev/null @@ -1,29 +0,0 @@ - \ No newline at end of file diff --git a/app/views/admins/salesman_channels/shared/_list.html.erb b/app/views/admins/salesman_channels/shared/_list.html.erb deleted file mode 100644 index 8116e6cf6..000000000 --- a/app/views/admins/salesman_channels/shared/_list.html.erb +++ /dev/null @@ -1,42 +0,0 @@ -
序号ID项目名称公开issue序号ID项目名称公开精选推荐Issues 资源版本库PullRequestPulls 里程碑成员管理员<%= sort_tag('创建时间', name: 'created_on', path: admins_projects_path) %>操作成员管理员<%= sort_tag('创建时间', name: 'created_on', path: admins_projects_path) %>操作
<%= list_index_no((params[:page] || 1).to_i, index) %> <%= project.id %> - <%= link_to(project.name, "/projects/#{project&.owner&.login}/#{project.identifier}", target: '_blank') %> + <%= link_to(project.name, "/#{project&.owner&.login}/#{project.identifier}", target: '_blank') %> <%= project.is_public ? '√' : '' %><%= project.is_pinned ? '√' : '' %><%= project.recommend ? '√' : '' %> <%= project.issues.size %> <%= project.attachments.size %><%= project&.project_score.try(:changeset_num).to_i %><%= project&.project_score.try(:pull_request_num).to_i %><%= project&.pull_requests_count %> <%= project.versions.size %> <%= project.members.size %> @@ -37,8 +39,15 @@ <%= project.created_on&.strftime('%Y-%m-%d %H:%M') %> + <% if project.is_public %> + <%= javascript_void_link '精选', class: 'action pinned-action', data: { id: project.id }, style: project.is_pinned ? 'display: none;' : '' %> + <%= javascript_void_link '取消精选', class: 'action unpinned-action', data: { id: project.id }, style: project.is_pinned ? '' : 'display: none;' %> + <%= javascript_void_link '推荐', class: 'action recommend-action', data: { id: project.id }, style: project.recommend ? 'display: none;' : '' %> + <%= javascript_void_link '取消推荐', class: 'action unrecommend-action', data: { id: project.id }, style: project.recommend ? '' : 'display: none;' %> + <%= link_to "设置推荐等级", edit_admins_project_path(project.id), remote: true, class: "action edit-recommend-action", style: project.recommend ? '' : 'display: none;' %> + <% end %> <%= link_to "删除", admins_project_path(project.id), method: :delete, data:{confirm: "确认删除的吗?"}, class: "delete-project-action" %> -
- - - - - - - - - - - - - <% if @channels.present? %> - <% @channels.each_with_index do |channel, index| %> - - - - - - - - - - <% end %> - <% else %> - <%= render 'admins/shared/no_data_for_table' %> - <% end %> - -
序号名称教师数学生数课堂数实训数操作
<%= index + 1 %> - <%= channel.school_name %> - - <%= channel.teacher_count(@start_time, @end_time) %> - - <%= channel.student_count(@start_time, @end_time) %> - - <%= channel.course_count(@start_time, @end_time) %> - - <%= channel.shixuns_count(@start_time, @end_time) %> - - <%= delete_link '删除', admins_salesman_channel_path(channel, salesman_id: channel.salesman_id, element: ".salesman-channel-item-#{channel.id}"), class: 'delete-salesman-action' %> -
\ No newline at end of file diff --git a/app/views/admins/salesman_customers/destroy.js.erb b/app/views/admins/salesman_customers/destroy.js.erb deleted file mode 100644 index d00e4fa08..000000000 --- a/app/views/admins/salesman_customers/destroy.js.erb +++ /dev/null @@ -1,2 +0,0 @@ -$.notify({ message: '操作成功' },{ type: 'success' }); -$("<%= params[:element]%>").remove(); \ No newline at end of file diff --git a/app/views/admins/salesman_customers/index.html.erb b/app/views/admins/salesman_customers/index.html.erb deleted file mode 100644 index f7948b0f0..000000000 --- a/app/views/admins/salesman_customers/index.html.erb +++ /dev/null @@ -1,15 +0,0 @@ -<% define_admin_breadcrumbs do %> - <% add_admin_breadcrumb("#{@salesman.name}的客户", admins_salesmans_path) %> -<% end %> - -
-
- <%= javascript_void_link '新增客户', class: 'btn btn-primary', data: {salesman_id: @salesman.id, toggle: 'modal', target: '.admin-add-salesman-customer-user-modal' } %> -
-
- -
- <%= render(partial: 'admins/salesman_customers/shared/list') %> -
- -<%= render 'admins/salesman_customers/shared/add_salesman_customers_user_modal' %> diff --git a/app/views/admins/salesman_customers/index.js.erb b/app/views/admins/salesman_customers/index.js.erb deleted file mode 100644 index ed90f5394..000000000 --- a/app/views/admins/salesman_customers/index.js.erb +++ /dev/null @@ -1 +0,0 @@ - $(".salesman-customer-list-container").html("<%= j(render partial: 'admins/salesman_customers/shared/list') %>") \ No newline at end of file diff --git a/app/views/admins/salesman_customers/shared/_add_salesman_customers_user_modal.html.erb b/app/views/admins/salesman_customers/shared/_add_salesman_customers_user_modal.html.erb deleted file mode 100644 index f31499f52..000000000 --- a/app/views/admins/salesman_customers/shared/_add_salesman_customers_user_modal.html.erb +++ /dev/null @@ -1,30 +0,0 @@ - \ No newline at end of file diff --git a/app/views/admins/salesman_customers/shared/_list.html.erb b/app/views/admins/salesman_customers/shared/_list.html.erb deleted file mode 100644 index 21e639865..000000000 --- a/app/views/admins/salesman_customers/shared/_list.html.erb +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - - <% if @customers.present? %> - <% @customers.each_with_index do |customer, index| %> - - - - - - - - - <% end %> - <% else %> - <%= render 'admins/shared/no_data_for_table' %> - <% end %> - -
序号名称单位课堂数实训数操作
<%= index + 1 %> - <%= link_to customer.name, user_path(customer), :title => customer.name %> - - <%= customer.school_name %> - - <%= customer.courses_count %> - - <%= customer.shixuns_count %> - - <%= delete_link '删除', admins_salesman_customer_path(customer, salesman_id: customer.salesman_id, element: ".salesman-customer-item-#{customer.id}"), class: 'delete-salesman--action' %> -
\ No newline at end of file diff --git a/app/views/admins/salesmans/destroy.js.erb b/app/views/admins/salesmans/destroy.js.erb deleted file mode 100644 index 0a9fa8518..000000000 --- a/app/views/admins/salesmans/destroy.js.erb +++ /dev/null @@ -1,2 +0,0 @@ -$.notify({ message: '操作成功' },{ type: 'success' }); -$(".salesman-item-<%= params[:id]%>").remove(); \ No newline at end of file diff --git a/app/views/admins/salesmans/index.html.erb b/app/views/admins/salesmans/index.html.erb deleted file mode 100644 index 2c5a095ef..000000000 --- a/app/views/admins/salesmans/index.html.erb +++ /dev/null @@ -1,15 +0,0 @@ -<% define_admin_breadcrumbs do %> - <% add_admin_breadcrumb('销售数据列表', admins_salesmans_path) %> -<% end %> - -
-
- <%= javascript_void_link '新增销售人员', class: 'btn btn-primary', data: { toggle: 'modal', target: '.admin-add-salesman-user-modal' } %> -
-
- -
- <%= render(partial: 'admins/salesmans/shared/list') %> -
- -<%= render 'admins/salesmans/shared/add_salesman_user_modal' %> diff --git a/app/views/admins/salesmans/shared/_add_salesman_user_modal.html.erb b/app/views/admins/salesmans/shared/_add_salesman_user_modal.html.erb deleted file mode 100644 index 20e2befda..000000000 --- a/app/views/admins/salesmans/shared/_add_salesman_user_modal.html.erb +++ /dev/null @@ -1,30 +0,0 @@ - \ No newline at end of file diff --git a/app/views/admins/salesmans/shared/_list.html.erb b/app/views/admins/salesmans/shared/_list.html.erb deleted file mode 100644 index 8293b4575..000000000 --- a/app/views/admins/salesmans/shared/_list.html.erb +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - <% if @salesmans.present? %> - <% @salesmans.each_with_index do |salesman, index| %> - - - - - - - - <% end %> - <% else %> - <%= render 'admins/shared/no_data_for_table' %> - <% end %> - -
序号业务员重点跟踪客户(点击数字客户列表)重点跟踪院校(点击数字渠道列表)操作
<%= index + 1 %> - <%= link_to salesman.name, admins_salesman_path(salesman), :title => salesman.name %> - - <%= link_to salesman.salesman_customers_count.to_i, - admins_salesman_customers_path(salesman_id: salesman), :title => "点击进入客户列表" %> - - <%= link_to salesman.salesman_channels_count.to_i, admins_salesman_channels_path(salesman_id: salesman), - :title => "点击进入渠道列表" %> - - <%= delete_link '删除', admins_salesman_path(salesman, element: ".salesman-item-#{salesman.id}"), - class: 'delete-salesman-action' %> -
\ No newline at end of file diff --git a/app/views/admins/school_statistics/contrast.js.erb b/app/views/admins/school_statistics/contrast.js.erb deleted file mode 100644 index bc9916c12..000000000 --- a/app/views/admins/school_statistics/contrast.js.erb +++ /dev/null @@ -1 +0,0 @@ -$(".school-statistic-list-container").html("<%= j(render partial: 'admins/school_statistics/shared/contrast_list', locals: { statistics: @statistics, select_options: @select_options }) %>") \ 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 deleted file mode 100644 index d726adb22..000000000 --- a/app/views/admins/school_statistics/index.html.erb +++ /dev/null @@ -1,49 +0,0 @@ -<% define_admin_breadcrumbs do %> - <% add_admin_breadcrumb('数据变化报表', admins_school_statistics_path) %> -<% end %> - -
-
-
- - <%= hidden_field_tag :contrast_column, params[:contrast_column] %> - -
-
- <%= text_field_tag :grow_begin_date, params[:grow_begin_date], class: 'form-control start-date mx-0', placeholder: '开始时间' %> -
- <%= text_field_tag :grow_end_date, params[:grow_end_date], class: 'form-control end-date mx-0', placeholder: '结束时间' %> -
-
-
-
- <%= text_field_tag :begin_date, params[:begin_date], class: 'form-control start-date mx-0', placeholder: '开始时间' %> -
- <%= text_field_tag :end_date, params[:end_date], class: 'form-control end-date mx-0', placeholder: '结束时间' %> -
-
VS
-
- <%= text_field_tag :other_begin_date, params[:other_begin_date], class: 'form-control start-date mx-0', placeholder: '开始时间' %> -
- <%= text_field_tag :other_end_date, params[:other_end_date], class: 'form-control end-date mx-0', placeholder: '结束时间' %> -
-
-
- -
- <%= hidden_field_tag :data_type, params[:data_type] || 'grow' %> - <%= 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-info btn-sm grow-btn #{params[:data_type] == 'contrast' ? '' : 'active'}", - data: { toggle: 'tooltip', trigger: 'hover', title: '请在左侧选择时间段,具体从当日5:00开始计算,下表显示选定时间段内各项指标数据变化情况' } %> -
- - <%= text_field_tag :keyword, params[:keyword], placeholder: 'ID/单位名称检索', class: 'form-control mx-3 search-input' %> - - <%= javascript_void_link '搜索', class: 'btn btn-primary search-btn' %> -
-
- -
- <%= render partial: 'admins/school_statistics/shared/list', locals: { statistics: @statistics } %> -
\ No newline at end of file diff --git a/app/views/admins/school_statistics/index.js.erb b/app/views/admins/school_statistics/index.js.erb deleted file mode 100644 index 3f5f7334b..000000000 --- a/app/views/admins/school_statistics/index.js.erb +++ /dev/null @@ -1 +0,0 @@ -$(".school-statistic-list-container").html("<%= j(render partial: 'admins/school_statistics/shared/list', locals: { statistics: @statistics }) %>") \ No newline at end of file diff --git a/app/views/admins/school_statistics/shared/_contrast_list.html.erb b/app/views/admins/school_statistics/shared/_contrast_list.html.erb deleted file mode 100644 index 928340c80..000000000 --- a/app/views/admins/school_statistics/shared/_contrast_list.html.erb +++ /dev/null @@ -1,72 +0,0 @@ -
-
- 学校数据统计(<%= I18n.t("school_daily_report.#{params[:contrast_column]}") %>变化统计情况) -
- <%= select_tag :contrast_column, - options_for_select(select_options, params[:contrast_column]), - class: 'form-control contrast-column-select' %> - - <% if statistics.present? %> -
- 说明:新增数=时段二-时段一;新增百分比=(新增数/时段一)*100%(保留小数点后五位) -
- <% end %> -
- -<% if statistics.present? %> - - - - - - - - - - - <% statistics.each do |statistic| %> - - - - - <% - increase = statistic['other_total'] - statistic['total'] - percentage = statistic['total'].zero? ? increase.to_f * 100 : (increase / statistic['total'].to_f) * 100 - %> - <% if increase > 0 %> - - <% if statistic['total'].zero? %> - - <% else %> - - <% end %> - <% elsif increase.zero? %> - - - <% else %> - - - <% end %> - - <% end %> - -
单位名称时段一
<%= "(#{params[:begin_date]} 05:00至#{(Time.zone.parse(params[:end_date]) + 1.days).strftime('%Y-%m-%d')} 05:00)" %>
时段二
<%= "(#{params[:other_begin_date]} 05:00至#{(Time.zone.parse(params[:other_end_date]) + 1.days).strftime('%Y-%m-%d')} 05:00)" %>
- <%= sort_tag('变化情况', name: 'percentage', path: contrast_admins_school_statistics_path) %> -
( 新 增 数 | 新增百分比) -
- <%= link_to statistic.school_name, "/colleges/#{statistic.school_id}/statistics", - target: '_blank', data: { toggle: 'tooltip', title: '点击查看学校统计概况' } %> - <%= statistic['total'] %><%= statistic['other_total'] %> - +<%= increase %> - -+<%= percentage.round(5) %>% - <%= increase %> - <%= percentage.round(5) %>% - <%= increase %> - <%= percentage.round(5) %>%
- - <%= render partial: 'admins/shared/paginate', locals: { objects: statistics } %> -<% else %> -
- 暂无数据,请选择时间段对比 -
-<% end %> \ No newline at end of file diff --git a/app/views/admins/school_statistics/shared/_list.html.erb b/app/views/admins/school_statistics/shared/_list.html.erb deleted file mode 100644 index 9d2a1c209..000000000 --- a/app/views/admins/school_statistics/shared/_list.html.erb +++ /dev/null @@ -1,58 +0,0 @@ -
- 统计总计: - <% if params[:grow_begin_date].present? %> - <%= params[:grow_begin_date] %> 05:00至<%= (Time.zone.parse(params[:grow_end_date]) + 1.days).strftime('%Y-%m-%d') %> 05:00 - <% else %> - <%= (Time.current - 5.hour).beginning_of_day.ago(1.days).strftime('%Y-%m-%d') %> 05:00至 - <%= (Time.current - 5.hour).beginning_of_day.strftime('%Y-%m-%d') %> 05:00, - <% end %> - 新增教师<%= @grow_summary.teacher_increase_count || 0 %>人, - 新增学生<%= @grow_summary.student_increase_count || 0 %>人, - 新增课堂<%= @grow_summary.course_increase_count || 0 %>个, - 新增实训<%= @grow_summary.shixun_increase_count || 0 %>个, - 新增实训作业<%= @grow_summary.shixun_homework_count || 0 %>个, - 新增实训评测<%= @grow_summary.shixun_evaluate_count || 0 %>个, - 活跃用户 - <%= @grow_summary.uniq_active_user_count.to_i.zero? ? @grow_summary.active_user_count.to_i : @grow_summary.uniq_active_user_count.to_i %> - 个 -
- - - - - - - - - - - - - - - - - <% if statistics.present? %> - <% statistics.each_with_index do |statistic, index| %> - - - - - - - - - - - - <% end %> - <% else %> - <%= render 'admins/shared/no_data_for_table' %> - <% end %> - -
序号单位名称<%= sort_tag('新增教师', name: 'teacher_increase_count', path: admins_school_statistics_path) %><%= sort_tag('新增学生', name: 'student_increase_count', path: admins_school_statistics_path) %><%= sort_tag('新增课堂', name: 'course_increase_count', path: admins_school_statistics_path) %><%= sort_tag('新增实训', name: 'shixun_increase_count', path: admins_school_statistics_path) %><%= sort_tag('新增实训作业', name: 'shixun_homework_count', path: admins_school_statistics_path) %><%= sort_tag('新增实训评测', name: 'shixun_evaluate_count', path: admins_school_statistics_path) %><%= sort_tag('活跃用户', name: 'uniq_active_user_count', path: admins_school_statistics_path) %>
<%= list_index_no(@params_page.to_i, index) %> - <%= link_to statistic.school_name, "/colleges/#{statistic.school_id}/statistics", - target: '_blank', data: { toggle: 'tooltip', title: '点击查看学校统计概况' } %> - <%= statistic.teacher_increase_count.to_i %><%= statistic.student_increase_count.to_i %><%= statistic.course_increase_count.to_i %><%= statistic.shixun_increase_count.to_i %><%= statistic.shixun_homework_count.to_i %><%= statistic.shixun_evaluate_count.to_i %><%= statistic.uniq_active_user_count.to_i.zero? ? statistic.active_user_count.to_i : statistic.uniq_active_user_count.to_i %>
- -<%= render partial: 'admins/shared/paginate', locals: { objects: statistics } %> \ No newline at end of file diff --git a/app/views/admins/schools/index.html.erb b/app/views/admins/schools/index.html.erb deleted file mode 100644 index 56cbadd9d..000000000 --- a/app/views/admins/schools/index.html.erb +++ /dev/null @@ -1,16 +0,0 @@ -<% define_admin_breadcrumbs do %> - <% add_admin_breadcrumb('单位列表') %> -<% end %> - -
- <%= form_tag(admins_schools_path, method: :get, class: 'form-inline search-form flex-1', remote: true) do %> - <%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-sm-2 ml-3', placeholder: '单位名称检索') %> - <%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %> - <% end %> - - <%#= javascript_void_link '新建单位', class: 'btn btn-primary', data: { toggle: 'modal', target: '.admin-create-school-modal' } %> -
- -
- <%= render partial: 'admins/schools/shared/list', locals: { schools: @schools } %> -
\ No newline at end of file diff --git a/app/views/admins/schools/index.js.erb b/app/views/admins/schools/index.js.erb deleted file mode 100644 index 41a2454be..000000000 --- a/app/views/admins/schools/index.js.erb +++ /dev/null @@ -1 +0,0 @@ -$('.school-list-container').html("<%= j(render partial: 'admins/schools/shared/list', locals: { schools: @schools }) %>"); \ No newline at end of file diff --git a/app/views/admins/schools/index.json.jbuilder b/app/views/admins/schools/index.json.jbuilder deleted file mode 100644 index 3f358191f..000000000 --- a/app/views/admins/schools/index.json.jbuilder +++ /dev/null @@ -1,6 +0,0 @@ -json.count @total_count -json.schools do - json.array! @schools.each do |school| - json.extract! school, :id, :name - end -end \ No newline at end of file diff --git a/app/views/admins/schools/shared/_list.html.erb b/app/views/admins/schools/shared/_list.html.erb deleted file mode 100644 index dd0a054e3..000000000 --- a/app/views/admins/schools/shared/_list.html.erb +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - - - - - - - - - - - - <% if schools.present? %> - <% schools.each_with_index do |school, index| %> - - - - - - - - - - - - - - - <% end %> - <% else %> - <%= render 'admins/shared/no_data_for_table' %> - <% end %> - -
序号IDLOGO标识码单位名称地区城市详细地址<%= sort_tag('用户数', name: 'users_count', path: admins_schools_path) %>部门数<%= sort_tag('创建时间', name: 'created_at', path: admins_schools_path) %>操作
<%= list_index_no((params[:page] || 1).to_i, index) %><%= school.id %> - <% if Util::FileManage.exists?(school) %> - <%= image_tag(Util::FileManage.source_disk_file_url(school).to_s + "?#{Time.now.to_i}", width: 40, height: 40, class: 'preview-image') %> - <% else %> - <%= content_tag(:span, '--', class: 'text-secondary') %> - <% end %> - <%= display_text school.identifier %><%= school.name %><%= school.province %><%= school.city %><%= school.address %><%= school.users_count %><%= @department_count.fetch(school.id, 0) %><%= school.created_at&.strftime('%Y-%m-%d %H:%M') %> - <%= delete_link '删除', admins_school_path(school, element: ".school-item-#{school.id}"), class: 'delete-school-action' %> -
- -<%= render partial: 'admins/shared/paginate', locals: { objects: schools } %> \ 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 06b12a6ed..3e659395a 100644 --- a/app/views/admins/shared/_sidebar.html.erb +++ b/app/views/admins/shared/_sidebar.html.erb @@ -31,17 +31,23 @@
  • <%= sidebar_item(admins_reversed_keywords_path, '系统保留关键词', icon: 'key', controller: 'admins-reversed_keywords') %>
  • <%= sidebar_item(admins_laboratories_path, '云上实验室', icon: 'cloud', controller: 'admins-laboratories') %>
  • - - +
  • <%= sidebar_item_group('#setting-system', '系统配置', icon: 'wrench') do %>
  • <%= sidebar_item(admins_sites_path, 'setting接口配置', icon: 'deaf', controller: 'admins-sites') %>
  • diff --git a/app/views/admins/sub_disciplines/adjust_position.js.erb b/app/views/admins/sub_disciplines/adjust_position.js.erb deleted file mode 100644 index 0dae991c1..000000000 --- a/app/views/admins/sub_disciplines/adjust_position.js.erb +++ /dev/null @@ -1,5 +0,0 @@ -<% if @message.present? %> -$.notify({ message: "<%= @message %>" }); -<% else %> -$(".sub-discipline-list-container").html("<%= j(render :partial => 'admins/sub_disciplines/shared/list') %>"); -<% end %> \ No newline at end of file diff --git a/app/views/admins/sub_disciplines/destroy.js.erb b/app/views/admins/sub_disciplines/destroy.js.erb deleted file mode 100644 index bb03cdcf1..000000000 --- a/app/views/admins/sub_disciplines/destroy.js.erb +++ /dev/null @@ -1,2 +0,0 @@ -$.notify({ message: '删除成功' }); -$(".sub-discipline-item-<%= @sub_discipline_id %>").remove(); \ No newline at end of file diff --git a/app/views/admins/sub_disciplines/edit.js.erb b/app/views/admins/sub_disciplines/edit.js.erb deleted file mode 100644 index aa7219de5..000000000 --- a/app/views/admins/sub_disciplines/edit.js.erb +++ /dev/null @@ -1,2 +0,0 @@ -$('.admin-modal-container').html("<%= j( render partial: 'admins/sub_disciplines/shared/edit_sub_discipline_modal', locals: { sub_discipline: @sub_discipline } ) %>"); -$('.modal.admin-edit-sub-discipline-modal').modal('show'); \ No newline at end of file diff --git a/app/views/admins/sub_disciplines/index.html.erb b/app/views/admins/sub_disciplines/index.html.erb deleted file mode 100644 index d782e00ae..000000000 --- a/app/views/admins/sub_disciplines/index.html.erb +++ /dev/null @@ -1,14 +0,0 @@ -<% define_admin_breadcrumbs do %> - <% add_admin_breadcrumb('课程方向', admins_disciplines_path) %> - <% add_admin_breadcrumb(@discipline.name) %> -<% end %> - -
    - <%= javascript_void_link '新增', class: 'btn btn-primary', data: { toggle: 'modal', target: '.admin-create-sub-discipline-modal' } %> -
    - -
    - <%= render(partial: 'admins/sub_disciplines/shared/list') %> -
    - -<%= render 'admins/sub_disciplines/shared/create_sub_discipline_modal' %> diff --git a/app/views/admins/sub_disciplines/shared/_create_sub_discipline_modal.html.erb b/app/views/admins/sub_disciplines/shared/_create_sub_discipline_modal.html.erb deleted file mode 100644 index a8b00b051..000000000 --- a/app/views/admins/sub_disciplines/shared/_create_sub_discipline_modal.html.erb +++ /dev/null @@ -1,28 +0,0 @@ - \ No newline at end of file diff --git a/app/views/admins/sub_disciplines/shared/_edit_sub_discipline_modal.html.erb b/app/views/admins/sub_disciplines/shared/_edit_sub_discipline_modal.html.erb deleted file mode 100644 index b51c267bb..000000000 --- a/app/views/admins/sub_disciplines/shared/_edit_sub_discipline_modal.html.erb +++ /dev/null @@ -1,23 +0,0 @@ - \ No newline at end of file diff --git a/app/views/admins/sub_disciplines/shared/_list.html.erb b/app/views/admins/sub_disciplines/shared/_list.html.erb deleted file mode 100644 index cd0b02f88..000000000 --- a/app/views/admins/sub_disciplines/shared/_list.html.erb +++ /dev/null @@ -1,37 +0,0 @@ -<% max_position = @sub_disciplines.pluck(:position).max %> - - - - - - - - - - - - - <% if @sub_disciplines.present? %> - <% @sub_disciplines.each do |sub| %> - - - - - - - - - <% end %> - <% else %> - <%= render 'admins/shared/no_data_for_table' %> - <% end %> - -
    序号课程实践课程实训题库操作
    <%= sub.position %> - <%= link_to sub.name, admins_tag_disciplines_path(sub_discipline_id: sub), :title => sub.name %> - <%= check_box_tag :subject,!sub.subject,sub.subject,disabled:!sub.discipline&.subject,remote:true,data:{id:sub.id},class:"sub-discipline-source-form" %><%= check_box_tag :shixun,!sub.shixun,sub.shixun,disabled:!sub.discipline&.shixun,remote:true,data:{id:sub.id},class:"sub-discipline-source-form" %><%= check_box_tag :question,!sub.question,sub.question,disabled:!sub.discipline&.question,remote:true,data:{id:sub.id},class:"sub-discipline-source-form" %> - <%= javascript_void_link('上移', class: 'move-action', data: { id: sub.id, opr: "up" }, style: sub.position == 1 ? 'display:none' : '') %> - <%= javascript_void_link('下移', class: 'move-action', data: { id: sub.id, opr: "down" }, style: sub.position == max_position ? 'display:none' : '') %> - - <%= link_to '编辑', edit_admins_sub_discipline_path(sub), remote: true, class: 'action' %> - <%= delete_link '删除', admins_sub_discipline_path(sub, element: ".sub-discipline-item-#{sub.id}"), class: 'delete-sub-discipline-action' %> -
    \ No newline at end of file diff --git a/app/views/admins/sub_disciplines/update.js.erb b/app/views/admins/sub_disciplines/update.js.erb deleted file mode 100644 index 395e06778..000000000 --- a/app/views/admins/sub_disciplines/update.js.erb +++ /dev/null @@ -1,6 +0,0 @@ -<% if @message.present? %> -$.notify({ message: "<%= @message %>" }); -<% else %> -$('.modal.admin-edit-sub-discipline-modal').modal("hide"); -$(".sub-discipline-list-container").html("<%= j(render :partial => 'admins/sub_disciplines/shared/list') %>"); -<% end %> \ No newline at end of file diff --git a/app/views/admins/sub_repertoires/destroy.js.erb b/app/views/admins/sub_repertoires/destroy.js.erb deleted file mode 100644 index 4575f811c..000000000 --- a/app/views/admins/sub_repertoires/destroy.js.erb +++ /dev/null @@ -1,2 +0,0 @@ -$.notify({ message: '删除成功' }); -$(".sub-repertoire-item-<%= @sub_repertoire_id %>").remove(); \ No newline at end of file diff --git a/app/views/admins/sub_repertoires/edit.js.erb b/app/views/admins/sub_repertoires/edit.js.erb deleted file mode 100644 index 10fe19697..000000000 --- a/app/views/admins/sub_repertoires/edit.js.erb +++ /dev/null @@ -1,2 +0,0 @@ -$('.admin-modal-container').html("<%= j( render partial: 'admins/sub_repertoires/shared/edit_sub_repertoire_modal', locals: { sub_repertoire: @sub_repertoire } ) %>"); -$('.modal.admin-edit-sub-repertoire-modal').modal('show'); \ No newline at end of file diff --git a/app/views/admins/sub_repertoires/index.html.erb b/app/views/admins/sub_repertoires/index.html.erb deleted file mode 100644 index be8ec98f9..000000000 --- a/app/views/admins/sub_repertoires/index.html.erb +++ /dev/null @@ -1,14 +0,0 @@ -<% define_admin_breadcrumbs do %> - <% add_admin_breadcrumb('技术体系', admins_repertoires_path) %> - <% add_admin_breadcrumb(@repertoire.name) %> -<% end %> - -
    - <%= javascript_void_link '新增', class: 'btn btn-primary', data: { toggle: 'modal', target: '.admin-create-sub-repertoire-modal' } %> -
    - -
    - <%= render(partial: 'admins/sub_repertoires/shared/list') %> -
    - -<%= render 'admins/sub_repertoires/shared/create_sub_repertoire_modal' %> diff --git a/app/views/admins/sub_repertoires/shared/_create_sub_repertoire_modal.html.erb b/app/views/admins/sub_repertoires/shared/_create_sub_repertoire_modal.html.erb deleted file mode 100644 index 435f2fb32..000000000 --- a/app/views/admins/sub_repertoires/shared/_create_sub_repertoire_modal.html.erb +++ /dev/null @@ -1,28 +0,0 @@ - \ No newline at end of file diff --git a/app/views/admins/sub_repertoires/shared/_edit_sub_repertoire_modal.html.erb b/app/views/admins/sub_repertoires/shared/_edit_sub_repertoire_modal.html.erb deleted file mode 100644 index 28ff8a169..000000000 --- a/app/views/admins/sub_repertoires/shared/_edit_sub_repertoire_modal.html.erb +++ /dev/null @@ -1,23 +0,0 @@ - diff --git a/app/views/admins/sub_repertoires/shared/_list.html.erb b/app/views/admins/sub_repertoires/shared/_list.html.erb deleted file mode 100644 index 77d20ef4c..000000000 --- a/app/views/admins/sub_repertoires/shared/_list.html.erb +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - <% if @sub_repertoires.present? %> - <% @sub_repertoires.each_with_index do |sub, index| %> - - - - - - <% end %> - <% else %> - <%= render 'admins/shared/no_data_for_table' %> - <% end %> - -
    序号课程操作
    <%= index + 1 %> - <%= link_to sub.name, admins_tag_repertoires_path(sub_repertoire_id: sub), :title => sub.name %> - - <%= link_to '编辑', edit_admins_sub_repertoire_path(sub), remote: true, class: 'action' %> - <%= delete_link '删除', admins_sub_repertoire_path(sub, element: ".sub-repertoire-item-#{sub.id}"), class: 'delete-sub-repertoire-action' %> -
    \ No newline at end of file diff --git a/app/views/admins/sub_repertoires/update.js.erb b/app/views/admins/sub_repertoires/update.js.erb deleted file mode 100644 index 04d282c5a..000000000 --- a/app/views/admins/sub_repertoires/update.js.erb +++ /dev/null @@ -1,2 +0,0 @@ -$('.modal.admin-edit-sub-repertoire-modal').modal("hide"); -$(".sub-repertoire-list-container").html("<%= j(render :partial => 'admins/sub_repertoires/shared/list') %>"); \ 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 deleted file mode 100644 index f3ae7bf56..000000000 --- a/app/views/admins/subject_authorizations/index.html.erb +++ /dev/null @@ -1,33 +0,0 @@ -<% 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', 'data-disable-with': '搜索中...') %> - <% 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 deleted file mode 100644 index a21809041..000000000 --- a/app/views/admins/subject_authorizations/index.js.erb +++ /dev/null @@ -1 +0,0 @@ -$('.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 deleted file mode 100644 index 94503dad7..000000000 --- a/app/views/admins/subject_authorizations/shared/_list.html.erb +++ /dev/null @@ -1,66 +0,0 @@ -<% is_processed = params[:status].to_s != 'pending' %> - - - - - - - - - - - - - <% if is_processed %> - - - <% else %> - - <% end %> - - - - <% if applies.present? %> - <% applies.each_with_index do |apply, index| %> - <% user = apply.user %> - <% subject = subject_map[apply.container_id] %> - - - - - - - - - - - <% if is_processed %> - - - <% else %> - - <% end %> - - <% end %> - <% else %> - <%= render 'admins/shared/no_data_for_table' %> - <% end %> - -
    序号头像创建者实践课程名称阶段数实训数关卡数时间拒绝原因状态操作
    <%= list_index_no((params[:page] || 1).to_i, index) %> - <%= link_to "/users/#{user.login}", class: 'subject-authorization-avatar', target: '_blank', data: { toggle: 'tooltip', title: '个人主页' } do %> - - <% end %> - <%= link_to user&.real_name,"/users/#{user&.login}", target: "_blank" %> - <%= 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/app/views/admins/subject_settings/index.html.erb b/app/views/admins/subject_settings/index.html.erb deleted file mode 100644 index b46c1d90d..000000000 --- a/app/views/admins/subject_settings/index.html.erb +++ /dev/null @@ -1,41 +0,0 @@ -<% define_admin_breadcrumbs do %> - <% add_admin_breadcrumb('课程配置') %> -<% end %> - -
    - <%= form_tag(admins_subject_settings_path, method: :get, class: 'form-inline search-form flex-1', remote: true) do %> -
    - - <% status_options = [['全部', ''], ['编辑中', 'pending'], ['审核中', 'applying'], ['已公开', 'published']] %> - <%= select_tag(:status, options_for_select(status_options), class: 'form-control') %> -
    - -
    - - <%= select_tag :school_id, options_for_select([''], params[:school_id]), class: 'form-control school-select flex-1' %> -
    - - <%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-12 col-md-2 mr-3', placeholder: '创建者/课程名称检索') %> - -
    - <%= hidden_field_tag(:homepage_show, false, id:'') %> - <%= check_box_tag(:homepage_show, true, params[:homepage_show].to_s == 'true', class: 'form-check-input') %> - -
    - -
    - <%= hidden_field_tag(:excellent, false, id:'') %> - <%= check_box_tag(:excellent, true, params[:excellent].to_s == 'true', class: 'form-check-input') %> - -
    - - <%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %> - - <% end %> -
    - -
    - <%= render partial: 'admins/subject_settings/shared/list', locals: { subjects: @subjects } %> -
    - -<%= render partial: 'admins/shared/modal/upload_file_modal', locals: { title: '上传图片', accept: 'image/*' } %> \ No newline at end of file diff --git a/app/views/admins/subject_settings/index.js.erb b/app/views/admins/subject_settings/index.js.erb deleted file mode 100644 index c3f403462..000000000 --- a/app/views/admins/subject_settings/index.js.erb +++ /dev/null @@ -1 +0,0 @@ -$('.subject-setting-list-container').html("<%= j( render partial: 'admins/subject_settings/shared/list', locals: { subjects: @subjects } ) %>"); \ No newline at end of file diff --git a/app/views/admins/subject_settings/mobile.js.erb b/app/views/admins/subject_settings/mobile.js.erb deleted file mode 100644 index e69de29bb..000000000 diff --git a/app/views/admins/subject_settings/shared/_edit_subject_modal.html.erb b/app/views/admins/subject_settings/shared/_edit_subject_modal.html.erb deleted file mode 100644 index 6e9aa871a..000000000 --- a/app/views/admins/subject_settings/shared/_edit_subject_modal.html.erb +++ /dev/null @@ -1,33 +0,0 @@ - \ No newline at end of file diff --git a/app/views/admins/subject_settings/shared/_list.html.erb b/app/views/admins/subject_settings/shared/_list.html.erb deleted file mode 100644 index 79411e892..000000000 --- a/app/views/admins/subject_settings/shared/_list.html.erb +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - <% if subjects.present? %> - <% subjects.each_with_index do |subject, index| %> - - <% page_no = ((params[:page] || 1).to_i - 1) * 20 + index + 1 %> - <%= render partial: "admins/subject_settings/shared/td",locals: {subject: subject,page_no:page_no} %> - - <% end %> - <% else %> - <%= render 'admins/shared/no_data_for_table' %> - <% end %> - -
    序号名称老版技术体系状态课程体系封面开课人数操作
    - -<%= render partial: 'admins/shared/paginate', locals: { objects: subjects } %> \ No newline at end of file diff --git a/app/views/admins/subject_settings/shared/_td.html.erb b/app/views/admins/subject_settings/shared/_td.html.erb deleted file mode 100644 index 94d34f42d..000000000 --- a/app/views/admins/subject_settings/shared/_td.html.erb +++ /dev/null @@ -1,47 +0,0 @@ -<%= page_no %> - - <%= link_to(subject.name, "/paths/#{subject.id}", target: '_blank') %> - 首页 - 金课 - -<%= display_text subject.repertoire&.name %> -<%= display_text subject.public == 2 ? "已公开" : ((subject.public == 1 && subject.status == 2) ? "审核中" : "未发布") %> - - <%= select_tag(:sub_disciplines, options_for_select(@sub_disciplines, subject.sub_disciplines.pluck(:id)),multiple:true,class:"form-control subject-setting-form",data:{id:subject.id},id:"tags-chosen-#{subject.id}") %> - - - <% image_exists = Util::FileManage.exists?(subject) %> - <%= image_tag(image_exists ? Util::FileManage.source_disk_file_url(subject) : '', height: 40, class: "w-100 preview-image subject-image-#{subject.id}", style: image_exists ? '' : 'display:none') %> - <%= javascript_void_link image_exists ? '重新上传' : '上传图片', class: 'action upload-image-action', data: { source_id: subject.id, source_type: 'Subject', toggle: 'modal', target: '.admin-upload-file-modal' } %> - -<%= subject.student_count %> - - <%= check_box_tag :show_mobile, !subject.show_mobile, subject.show_mobile, remote: true, - data: {id: subject.id, toggle: "tooltip", placement: "top"}, class: "subject-mobile-form mr10", title: "小程序端显示" %> - <%= link_to('编辑', edit_admins_subject_path(subject), remote: true, class: 'edit-action') %> - - - \ No newline at end of file diff --git a/app/views/admins/subject_settings/update.js.erb b/app/views/admins/subject_settings/update.js.erb deleted file mode 100644 index c95a41ec3..000000000 --- a/app/views/admins/subject_settings/update.js.erb +++ /dev/null @@ -1 +0,0 @@ -$.notify({ message: '更新成功' }); \ No newline at end of file diff --git a/app/views/admins/subject_settings/update_mobile_show.js.erb b/app/views/admins/subject_settings/update_mobile_show.js.erb deleted file mode 100644 index e69de29bb..000000000 diff --git a/app/views/admins/subjects/edit.js.erb b/app/views/admins/subjects/edit.js.erb deleted file mode 100644 index b2e12f9bb..000000000 --- a/app/views/admins/subjects/edit.js.erb +++ /dev/null @@ -1,2 +0,0 @@ -$('.admin-modal-container').html("<%= j( render partial: 'admins/subjects/shared/edit_subject_modal', locals: { subject: @subject } ) %>"); -$('.modal.admin-edit-subject-modal').modal('show'); \ No newline at end of file diff --git a/app/views/admins/subjects/index.html.erb b/app/views/admins/subjects/index.html.erb deleted file mode 100644 index 39c4a349b..000000000 --- a/app/views/admins/subjects/index.html.erb +++ /dev/null @@ -1,39 +0,0 @@ -<% define_admin_breadcrumbs do %> - <% add_admin_breadcrumb('课程列表') %> -<% end %> - -
    - <%= form_tag(admins_subjects_path, method: :get, class: 'form-inline search-form flex-1', remote: true) do %> -
    - - <% status_options = [['全部', ''], ["编辑中", "editing"], ["已发布", 'processed'], ["待审核", 'pending'], ["已公开", 'publiced']] %> - <%= select_tag(:status, options_for_select(status_options), class: 'form-control') %> -
    - -
    - - <%= select_tag :school_id, options_for_select([''], params[:school_id]), class: 'form-control school-select flex-1' %> -
    - - <%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-12 col-md-2 mr-3', placeholder: '创建者/课程名称检索') %> - -
    - <%= hidden_field_tag(:homepage_show, false, id:'') %> - <%= check_box_tag(:homepage_show, true, params[:homepage_show].to_s == 'true', class: 'form-check-input') %> - -
    - -
    - <%= hidden_field_tag(:excellent, false, id:'') %> - <%= check_box_tag(:excellent, true, params[:excellent].to_s == 'true', class: 'form-check-input') %> - -
    - - <%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %> - - <% end %> -
    - -
    - <%= render partial: 'admins/subjects/shared/list', locals: { subjects: @subjects } %> -
    \ No newline at end of file diff --git a/app/views/admins/subjects/index.js.erb b/app/views/admins/subjects/index.js.erb deleted file mode 100644 index 20e07f13a..000000000 --- a/app/views/admins/subjects/index.js.erb +++ /dev/null @@ -1 +0,0 @@ -$('.subject-list-container').html("<%= j( render partial: 'admins/subjects/shared/list', locals: { subjects: @subjects } ) %>"); \ No newline at end of file diff --git a/app/views/admins/subjects/shared/_edit_subject_modal.html.erb b/app/views/admins/subjects/shared/_edit_subject_modal.html.erb deleted file mode 100644 index 6e9aa871a..000000000 --- a/app/views/admins/subjects/shared/_edit_subject_modal.html.erb +++ /dev/null @@ -1,33 +0,0 @@ - \ No newline at end of file diff --git a/app/views/admins/subjects/shared/_list.html.erb b/app/views/admins/subjects/shared/_list.html.erb deleted file mode 100644 index ee136ddf5..000000000 --- a/app/views/admins/subjects/shared/_list.html.erb +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - - - - - - - <% if subjects.present? %> - <% subjects.each_with_index do |subject, index| %> - - - - - - - - - - - - <% end %> - <% else %> - <%= render 'admins/shared/no_data_for_table' %> - <% end %> - -
    序号名称阶段数实训数创建者单位<%= sort_tag('创建时间', name: 'created_at', path: admins_subjects_path) %>状态操作
    <%= list_index_no((params[:page] || 1).to_i, index) %> - <%= link_to(subject.name, "/paths/#{subject.id}", target: '_blank') %> - 首页 - 金课 - <%= subject.stages_count %><%= subject.shixuns_count %><%= subject.user.real_name %><%= subject.user.school_name %><%= subject.created_at&.strftime('%Y-%m-%d %H:%M') %> - <%= display_subject_status(subject) %> - - <%= javascript_void_link('隐藏', class: 'hide-action', data: { id: subject.id }, style: subject.hidden? ? 'display:none' : '') %> - <%= javascript_void_link('取消隐藏', class: 'active-action', data: { id: subject.id }, style: subject.hidden? ? '' : 'display:none') %> - - <%= delete_link '删除', admins_subject_path(subject, element: ".subject-item-#{subject.id}"), class: 'delete-subject-action' %> - - <% if subject.published? %> -
    - <%= javascript_void_link('更多', class: 'action dropdown-toggle', 'data-toggle': 'dropdown', 'aria-haspopup': true, 'aria-expanded': false) %> - -
    - <% end %> -
    - -<%= render partial: 'admins/shared/paginate', locals: { objects: subjects } %> \ No newline at end of file diff --git a/app/views/admins/tag_disciplines/adjust_position.js.erb b/app/views/admins/tag_disciplines/adjust_position.js.erb deleted file mode 100644 index 32e066698..000000000 --- a/app/views/admins/tag_disciplines/adjust_position.js.erb +++ /dev/null @@ -1,5 +0,0 @@ -<% if @message.present? %> -$.notify({ message: "<%= @message %>" }); -<% else %> -$(".tag-discipline-list-container").html("<%= j(render :partial => 'admins/tag_disciplines/shared/list') %>"); -<% end %> \ No newline at end of file diff --git a/app/views/admins/tag_disciplines/destroy.js.erb b/app/views/admins/tag_disciplines/destroy.js.erb deleted file mode 100644 index 0b61b7eb7..000000000 --- a/app/views/admins/tag_disciplines/destroy.js.erb +++ /dev/null @@ -1,2 +0,0 @@ -$.notify({ message: '删除成功' }); -$(".tag-discipline-item-<%= @tag_discipline_id %>").remove(); \ No newline at end of file diff --git a/app/views/admins/tag_disciplines/edit.js.erb b/app/views/admins/tag_disciplines/edit.js.erb deleted file mode 100644 index 90a4d28d5..000000000 --- a/app/views/admins/tag_disciplines/edit.js.erb +++ /dev/null @@ -1,2 +0,0 @@ -$('.admin-modal-container').html("<%= j( render partial: 'admins/tag_disciplines/shared/edit_tag_discipline_modal', locals: { tag_discipline: @tag_discipline } ) %>"); -$('.modal.admin-edit-tag-discipline-modal').modal('show'); \ No newline at end of file diff --git a/app/views/admins/tag_disciplines/index.html.erb b/app/views/admins/tag_disciplines/index.html.erb deleted file mode 100644 index 199137612..000000000 --- a/app/views/admins/tag_disciplines/index.html.erb +++ /dev/null @@ -1,15 +0,0 @@ -<% define_admin_breadcrumbs do %> - <% add_admin_breadcrumb('课程方向', admins_disciplines_path) %> - <% add_admin_breadcrumb(@sub_discipline&.discipline&.name, admins_sub_disciplines_path(discipline_id: @sub_discipline&.discipline_id)) %> - <% add_admin_breadcrumb(@sub_discipline.name) %> -<% end %> - -
    - <%= javascript_void_link '新增', class: 'btn btn-primary', data: { toggle: 'modal', target: '.admin-create-tag-discipline-modal' } %> -
    - -
    - <%= render(partial: 'admins/tag_disciplines/shared/list') %> -
    - -<%= render 'admins/tag_disciplines/shared/create_tag_discipline_modal' %> diff --git a/app/views/admins/tag_disciplines/shared/_create_tag_discipline_modal.html.erb b/app/views/admins/tag_disciplines/shared/_create_tag_discipline_modal.html.erb deleted file mode 100644 index 33132285b..000000000 --- a/app/views/admins/tag_disciplines/shared/_create_tag_discipline_modal.html.erb +++ /dev/null @@ -1,28 +0,0 @@ - \ No newline at end of file diff --git a/app/views/admins/tag_disciplines/shared/_edit_tag_discipline_modal.html.erb b/app/views/admins/tag_disciplines/shared/_edit_tag_discipline_modal.html.erb deleted file mode 100644 index 9eb50658c..000000000 --- a/app/views/admins/tag_disciplines/shared/_edit_tag_discipline_modal.html.erb +++ /dev/null @@ -1,23 +0,0 @@ - \ No newline at end of file diff --git a/app/views/admins/tag_disciplines/shared/_list.html.erb b/app/views/admins/tag_disciplines/shared/_list.html.erb deleted file mode 100644 index 59420c42c..000000000 --- a/app/views/admins/tag_disciplines/shared/_list.html.erb +++ /dev/null @@ -1,52 +0,0 @@ -<% max_position = @tag_disciplines.pluck(:position).max %> - - - - - - - - - - - - - - <% if @tag_disciplines.present? %> - <% @tag_disciplines.each do |tag| %> - - - - - - - - - - <% end %> - <% else %> - <%= render 'admins/shared/no_data_for_table' %> - <% end %> - -
    序号知识点创建者实践课程实训题库操作
    <%= tag.position %><%= tag.name %> - <% if tag.user.present? %> - <%= link_to tag.user.real_name, user_path(tag.user), :target => "_blank" %> - <% else %> - -- - <% end %> - - <% disabled = !(tag.sub_discipline&.subject && tag.discipline&.subject) %> - <%= check_box_tag :subject,!tag.subject,tag.subject,disabled:disabled,remote:true,data:{id:tag.id},class:"tag-discipline-source-form" %> - - <% disabled = !(tag.sub_discipline&.shixun && tag.discipline&.shixun) %> - <%= check_box_tag :shixun,!tag.shixun,tag.shixun,disabled:disabled,remote:true,data:{id:tag.id},class:"tag-discipline-source-form" %> - - <% disabled = !(tag.sub_discipline&.question && tag.discipline&.question) %> - <%= check_box_tag :question,!tag.question,tag.question,disabled:disabled,remote:true,data:{id:tag.id},class:"tag-discipline-source-form" %> - - <%= javascript_void_link('上移', class: 'move-action', data: { id: tag.id, opr: "up" }, style: tag.position == 1 ? 'display:none' : '') %> - <%= javascript_void_link('下移', class: 'move-action', data: { id: tag.id, opr: "down" }, style: tag.position == max_position ? 'display:none' : '') %> - - <%= link_to '编辑', edit_admins_tag_discipline_path(tag), remote: true, class: 'action' %> - <%= delete_link '删除', admins_tag_discipline_path(tag, element: ".tag-discipline-item-#{tag.id}"), class: 'delete-tag-discipline-action' %> -
    \ No newline at end of file diff --git a/app/views/admins/tag_disciplines/update.js.erb b/app/views/admins/tag_disciplines/update.js.erb deleted file mode 100644 index b03f10477..000000000 --- a/app/views/admins/tag_disciplines/update.js.erb +++ /dev/null @@ -1,6 +0,0 @@ -<% if @message.present? %> -$.notify({ message: "<%= @message %>" }); -<% else %> -$('.modal.admin-edit-tag-discipline-modal').modal("hide"); -$(".tag-discipline-list-container").html("<%= j(render :partial => 'admins/tag_disciplines/shared/list') %>"); -<% end %> \ No newline at end of file diff --git a/app/views/admins/tag_repertoires/destroy.js.erb b/app/views/admins/tag_repertoires/destroy.js.erb deleted file mode 100644 index 710f10ca9..000000000 --- a/app/views/admins/tag_repertoires/destroy.js.erb +++ /dev/null @@ -1,2 +0,0 @@ -$.notify({ message: '删除成功' }); -$(".tag-repertoire-item-<%= @tag_repertoire_id %>").remove(); \ No newline at end of file diff --git a/app/views/admins/tag_repertoires/edit.js.erb b/app/views/admins/tag_repertoires/edit.js.erb deleted file mode 100644 index 5969eedf7..000000000 --- a/app/views/admins/tag_repertoires/edit.js.erb +++ /dev/null @@ -1,2 +0,0 @@ -$('.admin-modal-container').html("<%= j( render partial: 'admins/tag_repertoires/shared/edit_tag_repertoire_modal', locals: { tag_repertoire: @tag_repertoire } ) %>"); -$('.modal.admin-edit-tag-repertoire-modal').modal('show'); \ No newline at end of file diff --git a/app/views/admins/tag_repertoires/index.html.erb b/app/views/admins/tag_repertoires/index.html.erb deleted file mode 100644 index 122cfc6f6..000000000 --- a/app/views/admins/tag_repertoires/index.html.erb +++ /dev/null @@ -1,15 +0,0 @@ -<% define_admin_breadcrumbs do %> - <% add_admin_breadcrumb('技术体系', admins_repertoires_path) %> - <% add_admin_breadcrumb(@sub_repertoire&.repertoire&.name, admins_sub_repertoires_path(repertoire_id: @sub_repertoire&.repertoire_id)) %> - <% add_admin_breadcrumb(@sub_repertoire.name) %> -<% end %> - -
    - <%= javascript_void_link '新增', class: 'btn btn-primary', data: { toggle: 'modal', target: '.admin-create-tag-repertoire-modal' } %> -
    - -
    - <%= render(partial: 'admins/tag_repertoires/shared/list') %> -
    - -<%= render 'admins/tag_repertoires/shared/create_tag_repertoire_modal' %> diff --git a/app/views/admins/tag_repertoires/shared/_create_tag_repertoire_modal.html.erb b/app/views/admins/tag_repertoires/shared/_create_tag_repertoire_modal.html.erb deleted file mode 100644 index f952762e4..000000000 --- a/app/views/admins/tag_repertoires/shared/_create_tag_repertoire_modal.html.erb +++ /dev/null @@ -1,28 +0,0 @@ - \ No newline at end of file diff --git a/app/views/admins/tag_repertoires/shared/_edit_tag_repertoire_modal.html.erb b/app/views/admins/tag_repertoires/shared/_edit_tag_repertoire_modal.html.erb deleted file mode 100644 index 3be94dd05..000000000 --- a/app/views/admins/tag_repertoires/shared/_edit_tag_repertoire_modal.html.erb +++ /dev/null @@ -1,23 +0,0 @@ - \ No newline at end of file diff --git a/app/views/admins/tag_repertoires/shared/_list.html.erb b/app/views/admins/tag_repertoires/shared/_list.html.erb deleted file mode 100644 index 3d8047f8d..000000000 --- a/app/views/admins/tag_repertoires/shared/_list.html.erb +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - <% if @tag_repertoires.present? %> - <% @tag_repertoires.each_with_index do |tag, index| %> - - - - - - <% end %> - <% else %> - <%= render 'admins/shared/no_data_for_table' %> - <% end %> - -
    序号知识标签操作
    <%= index + 1 %><%= tag.name %> - <%= link_to '编辑', edit_admins_tag_repertoire_path(tag), remote: true, class: 'action' %> - <%= delete_link '删除', admins_tag_repertoire_path(tag, element: ".tag-repertoire-item-#{tag.id}"), class: 'delete-tag-repertoire-action' %> -
    \ No newline at end of file diff --git a/app/views/admins/tag_repertoires/update.js.erb b/app/views/admins/tag_repertoires/update.js.erb deleted file mode 100644 index a55f7f3b9..000000000 --- a/app/views/admins/tag_repertoires/update.js.erb +++ /dev/null @@ -1,2 +0,0 @@ -$('.modal.admin-edit-tag-repertoire-modal').modal("hide"); -$(".tag-repertoire-list-container").html("<%= j(render :partial => 'admins/tag_repertoires/shared/list') %>"); \ No newline at end of file diff --git a/app/views/admins/topic/activity_forums/_form_modal.html.erb b/app/views/admins/topic/activity_forums/_form_modal.html.erb new file mode 100644 index 000000000..3426337d2 --- /dev/null +++ b/app/views/admins/topic/activity_forums/_form_modal.html.erb @@ -0,0 +1,44 @@ + \ No newline at end of file diff --git a/app/views/admins/topic/activity_forums/_list.html.erb b/app/views/admins/topic/activity_forums/_list.html.erb new file mode 100644 index 000000000..35068eddb --- /dev/null +++ b/app/views/admins/topic/activity_forums/_list.html.erb @@ -0,0 +1,33 @@ + + + + + + + + + + + + + <% if activity_forums.present? %> + <% activity_forums.each_with_index do |activity_forum, index| %> + + + + + + + + + <% end %> + <% else %> + <%= render 'admins/shared/no_data_for_table' %> + <% end %> + +
    序号标题跳转地址帖子ID排序等级操作
    <%= list_index_no((params[:page] || 1).to_i, index) %><%= activity_forum.title %><%= activity_forum.url %><%= activity_forum.uuid %><%= activity_forum.order_index %> + <%= link_to "编辑", edit_admins_topic_activity_forum_path(activity_forum), remote: true, class: "action" %> + <%= link_to "删除", admins_topic_activity_forum_path(activity_forum), method: :delete, data:{confirm: "确认删除的吗?"}, class: "action" %> +
    + +<%= render partial: 'admins/shared/paginate', locals: { objects: activity_forums } %> \ No newline at end of file diff --git a/app/views/admins/topic/activity_forums/edit.js.erb b/app/views/admins/topic/activity_forums/edit.js.erb new file mode 100644 index 000000000..b66ecd1c4 --- /dev/null +++ b/app/views/admins/topic/activity_forums/edit.js.erb @@ -0,0 +1,2 @@ +$("#activity-forum-modals").html("<%= j render(partial: 'admins/topic/activity_forums/form_modal', locals: {type: 'update'}) %>") +$(".activity-forum-change-modal").modal('show'); \ No newline at end of file diff --git a/app/views/admins/topic/activity_forums/index.html.erb b/app/views/admins/topic/activity_forums/index.html.erb new file mode 100644 index 000000000..a6d673d31 --- /dev/null +++ b/app/views/admins/topic/activity_forums/index.html.erb @@ -0,0 +1,18 @@ +<% define_admin_breadcrumbs do %> + <% add_admin_breadcrumb('平台动态管理') %> +<% end %> + +
    + <%= form_tag(admins_topic_activity_forums_path, method: :get, class: 'form-inline search-form flex-1', remote: true) do %> + <%= text_field_tag(:search, params[:search], class: 'form-control col-12 col-md-2 mr-3', placeholder: '标题检索') %> + <%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %> + + <% end %> + <%= link_to "新增", new_admins_topic_activity_forum_path, remote: true, class: "btn btn-primary pull-right", "data-disabled-with":"...新增" %> +
    + +
    + <%= render partial: 'admins/topic/activity_forums/list', locals: { activity_forums: @activity_forums } %> +
    +
    +
    diff --git a/app/views/admins/topic/activity_forums/index.js.erb b/app/views/admins/topic/activity_forums/index.js.erb new file mode 100644 index 000000000..3560c21f1 --- /dev/null +++ b/app/views/admins/topic/activity_forums/index.js.erb @@ -0,0 +1 @@ +$('.activity-forum-list-container').html("<%= j( render partial: 'admins/topic/activity_forums/list', locals: { activity_forums: @activity_forums } ) %>"); \ No newline at end of file diff --git a/app/views/admins/topic/activity_forums/new.js.erb b/app/views/admins/topic/activity_forums/new.js.erb new file mode 100644 index 000000000..8e9a33097 --- /dev/null +++ b/app/views/admins/topic/activity_forums/new.js.erb @@ -0,0 +1,2 @@ +$("#activity-forum-modals").html("<%= j render(partial: 'admins/topic/activity_forums/form_modal', locals: {type: 'create'}) %>") +$(".activity-forum-change-modal").modal('show'); \ No newline at end of file diff --git a/app/views/admins/topic/banners/_form_modal.html.erb b/app/views/admins/topic/banners/_form_modal.html.erb new file mode 100644 index 000000000..20bca80c6 --- /dev/null +++ b/app/views/admins/topic/banners/_form_modal.html.erb @@ -0,0 +1,45 @@ + \ No newline at end of file diff --git a/app/views/admins/topic/banners/_list.html.erb b/app/views/admins/topic/banners/_list.html.erb new file mode 100644 index 000000000..aa366ec21 --- /dev/null +++ b/app/views/admins/topic/banners/_list.html.erb @@ -0,0 +1,31 @@ + + + + + + + + + + + + <% if banners.present? %> + <% banners.each_with_index do |banner, index| %> + + + + + + + + <% end %> + <% else %> + <%= render 'admins/shared/no_data_for_table' %> + <% end %> + +
    序号标题图片排序等级操作
    + +<%= render partial: 'admins/shared/paginate', locals: { objects: banners } %> \ No newline at end of file diff --git a/app/views/admins/topic/banners/edit.js.erb b/app/views/admins/topic/banners/edit.js.erb new file mode 100644 index 000000000..524bb13a7 --- /dev/null +++ b/app/views/admins/topic/banners/edit.js.erb @@ -0,0 +1,18 @@ +$("#banner-modals").html("<%= j render(partial: 'admins/topic/banners/form_modal', locals: {type: 'update'}) %>") +$(".banner-change-modal").modal('show'); + +$('.logo-item-left').on("change", 'input[type="file"]', function () { + var $fileInput = $(this); + var file = this.files[0]; + var imageType = /image.*/; + if (file && file.type.match(imageType)) { + var reader = new FileReader(); + reader.onload = function () { + var $box = $fileInput.parent(); + $box.find('img').attr('src', reader.result).css('display', 'block'); + $box.addClass('has-img'); + }; + reader.readAsDataURL(file); + } else { + } +}); diff --git a/app/views/admins/topic/banners/index.html.erb b/app/views/admins/topic/banners/index.html.erb new file mode 100644 index 000000000..e8ceefa2f --- /dev/null +++ b/app/views/admins/topic/banners/index.html.erb @@ -0,0 +1,18 @@ +<% define_admin_breadcrumbs do %> + <% add_admin_breadcrumb('卡片管理') %> +<% end %> + +
    + <%= form_tag(admins_topic_banners_path, method: :get, class: 'form-inline search-form flex-1', remote: true) do %> + <%= text_field_tag(:search, params[:search], class: 'form-control col-12 col-md-2 mr-3', placeholder: '标题检索') %> + <%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %> + + <% end %> + <%= link_to "新增", new_admins_topic_banner_path, remote: true, class: "btn btn-primary pull-right", "data-disabled-with":"...新增" %> +
    + + + diff --git a/app/views/admins/topic/banners/index.js.erb b/app/views/admins/topic/banners/index.js.erb new file mode 100644 index 000000000..0095bd861 --- /dev/null +++ b/app/views/admins/topic/banners/index.js.erb @@ -0,0 +1 @@ +$('.banner-list-container').html("<%= j( render partial: 'admins/topic/banners/list', locals: { banners: @banners } ) %>"); \ No newline at end of file diff --git a/app/views/admins/topic/banners/new.js.erb b/app/views/admins/topic/banners/new.js.erb new file mode 100644 index 000000000..d1450eb7f --- /dev/null +++ b/app/views/admins/topic/banners/new.js.erb @@ -0,0 +1,18 @@ +$("#banner-modals").html("<%= j render(partial: 'admins/topic/banners/form_modal', locals: {type: 'create'}) %>") +$(".banner-change-modal").modal('show'); + +$('.logo-item-left').on("change", 'input[type="file"]', function () { + var $fileInput = $(this); + var file = this.files[0]; + var imageType = /image.*/; + if (file && file.type.match(imageType)) { + var reader = new FileReader(); + reader.onload = function () { + var $box = $fileInput.parent(); + $box.find('img').attr('src', reader.result).css('display', 'block'); + $box.addClass('has-img'); + }; + reader.readAsDataURL(file); + } else { + } +}); diff --git a/app/views/admins/topic/cards/_form_modal.html.erb b/app/views/admins/topic/cards/_form_modal.html.erb new file mode 100644 index 000000000..960b8b503 --- /dev/null +++ b/app/views/admins/topic/cards/_form_modal.html.erb @@ -0,0 +1,38 @@ + \ No newline at end of file diff --git a/app/views/admins/topic/cards/_list.html.erb b/app/views/admins/topic/cards/_list.html.erb new file mode 100644 index 000000000..71a460199 --- /dev/null +++ b/app/views/admins/topic/cards/_list.html.erb @@ -0,0 +1,31 @@ + + + + + + + + + + + + <% if cards.present? %> + <% cards.each_with_index do |card, index| %> + + + + + + + + <% end %> + <% else %> + <%= render 'admins/shared/no_data_for_table' %> + <% end %> + +
    序号标题跳转地址排序等级操作
    <%= list_index_no((params[:page] || 1).to_i, index) %><%= card.title %><%= card.url %><%= card.order_index %> + <%= link_to "编辑", edit_admins_topic_card_path(card), remote: true, class: "action" %> + <%= link_to "删除", admins_topic_card_path(card), method: :delete, data:{confirm: "确认删除的吗?"}, class: "action" %> +
    + +<%= render partial: 'admins/shared/paginate', locals: { objects: cards } %> \ No newline at end of file diff --git a/app/views/admins/topic/cards/edit.js.erb b/app/views/admins/topic/cards/edit.js.erb new file mode 100644 index 000000000..9d0ed0e74 --- /dev/null +++ b/app/views/admins/topic/cards/edit.js.erb @@ -0,0 +1,2 @@ +$("#card-modals").html("<%= j render(partial: 'admins/topic/cards/form_modal', locals: {type: 'update'}) %>") +$(".card-change-modal").modal('show'); \ No newline at end of file diff --git a/app/views/admins/topic/cards/index.html.erb b/app/views/admins/topic/cards/index.html.erb new file mode 100644 index 000000000..6865fa107 --- /dev/null +++ b/app/views/admins/topic/cards/index.html.erb @@ -0,0 +1,18 @@ +<% define_admin_breadcrumbs do %> + <% add_admin_breadcrumb('卡片管理') %> +<% end %> + +
    + <%= form_tag(admins_topic_cards_path, method: :get, class: 'form-inline search-form flex-1', remote: true) do %> + <%= text_field_tag(:search, params[:search], class: 'form-control col-12 col-md-2 mr-3', placeholder: '标题检索') %> + <%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %> + + <% end %> + <%= link_to "新增", new_admins_topic_card_path, remote: true, class: "btn btn-primary pull-right", "data-disabled-with":"...新增" %> +
    + +
    + <%= render partial: 'admins/topic/cards/list', locals: { cards: @cards } %> +
    +
    +
    diff --git a/app/views/admins/topic/cards/index.js.erb b/app/views/admins/topic/cards/index.js.erb new file mode 100644 index 000000000..1bbcb5487 --- /dev/null +++ b/app/views/admins/topic/cards/index.js.erb @@ -0,0 +1 @@ +$('.card-list-container').html("<%= j( render partial: 'admins/topic/cards/list', locals: { cards: @cards } ) %>"); \ No newline at end of file diff --git a/app/views/admins/topic/cards/new.js.erb b/app/views/admins/topic/cards/new.js.erb new file mode 100644 index 000000000..94b8353b9 --- /dev/null +++ b/app/views/admins/topic/cards/new.js.erb @@ -0,0 +1,2 @@ +$("#card-modals").html("<%= j render(partial: 'admins/topic/cards/form_modal', locals: {type: 'create'}) %>") +$(".card-change-modal").modal('show'); \ No newline at end of file diff --git a/app/views/admins/topic/cooperators/_form_modal.html.erb b/app/views/admins/topic/cooperators/_form_modal.html.erb new file mode 100644 index 000000000..8f9085292 --- /dev/null +++ b/app/views/admins/topic/cooperators/_form_modal.html.erb @@ -0,0 +1,51 @@ + \ No newline at end of file diff --git a/app/views/admins/topic/cooperators/_list.html.erb b/app/views/admins/topic/cooperators/_list.html.erb new file mode 100644 index 000000000..351b6b9de --- /dev/null +++ b/app/views/admins/topic/cooperators/_list.html.erb @@ -0,0 +1,33 @@ + + + + + + + + + + + + + <% if cooperators.present? %> + <% cooperators.each_with_index do |cooperator, index| %> + + + + + + + + + <% end %> + <% else %> + <%= render 'admins/shared/no_data_for_table' %> + <% end %> + +
    序号标题跳转地址图片排序等级操作
    <%= list_index_no((params[:page] || 1).to_i, index) %><%= cooperator.title %><%= cooperator.url %><%= cooperator.order_index %> + <%= link_to "编辑", edit_admins_topic_cooperator_path(cooperator), remote: true, class: "action" %> + <%= link_to "删除", admins_topic_cooperator_path(cooperator), method: :delete, data:{confirm: "确认删除的吗?"}, class: "action" %> +
    + +<%= render partial: 'admins/shared/paginate', locals: { objects: cooperators } %> \ No newline at end of file diff --git a/app/views/admins/topic/cooperators/edit.js.erb b/app/views/admins/topic/cooperators/edit.js.erb new file mode 100644 index 000000000..ec99bfcef --- /dev/null +++ b/app/views/admins/topic/cooperators/edit.js.erb @@ -0,0 +1,18 @@ +$("#cooperator-modals").html("<%= j render(partial: 'admins/topic/cooperators/form_modal', locals: {type: 'update'}) %>") +$(".cooperator-change-modal").modal('show'); + +$('.logo-item-left').on("change", 'input[type="file"]', function () { + var $fileInput = $(this); + var file = this.files[0]; + var imageType = /image.*/; + if (file && file.type.match(imageType)) { + var reader = new FileReader(); + reader.onload = function () { + var $box = $fileInput.parent(); + $box.find('img').attr('src', reader.result).css('display', 'block'); + $box.addClass('has-img'); + }; + reader.readAsDataURL(file); + } else { + } +}); diff --git a/app/views/admins/topic/cooperators/index.html.erb b/app/views/admins/topic/cooperators/index.html.erb new file mode 100644 index 000000000..e18bc397f --- /dev/null +++ b/app/views/admins/topic/cooperators/index.html.erb @@ -0,0 +1,18 @@ +<% define_admin_breadcrumbs do %> + <% add_admin_breadcrumb('卡片管理') %> +<% end %> + +
    + <%= form_tag(admins_topic_cooperators_path, method: :get, class: 'form-inline search-form flex-1', remote: true) do %> + <%= text_field_tag(:search, params[:search], class: 'form-control col-12 col-md-2 mr-3', placeholder: '标题检索') %> + <%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %> + + <% end %> + <%= link_to "新增", new_admins_topic_cooperator_path, remote: true, class: "btn btn-primary pull-right", "data-disabled-with":"...新增" %> +
    + +
    + <%= render partial: 'admins/topic/cooperators/list', locals: { cooperators: @cooperators } %> +
    +
    +
    diff --git a/app/views/admins/topic/cooperators/index.js.erb b/app/views/admins/topic/cooperators/index.js.erb new file mode 100644 index 000000000..e3bbc044b --- /dev/null +++ b/app/views/admins/topic/cooperators/index.js.erb @@ -0,0 +1 @@ +$('.cooperator-list-container').html("<%= j( render partial: 'admins/topic/cooperators/list', locals: { cooperators: @cooperators } ) %>"); \ No newline at end of file diff --git a/app/views/admins/topic/cooperators/new.js.erb b/app/views/admins/topic/cooperators/new.js.erb new file mode 100644 index 000000000..d986f4e7d --- /dev/null +++ b/app/views/admins/topic/cooperators/new.js.erb @@ -0,0 +1,18 @@ +$("#cooperator-modals").html("<%= j render(partial: 'admins/topic/cooperators/form_modal', locals: {type: 'create'}) %>") +$(".cooperator-change-modal").modal('show'); + +$('.logo-item-left').on("change", 'input[type="file"]', function () { + var $fileInput = $(this); + var file = this.files[0]; + var imageType = /image.*/; + if (file && file.type.match(imageType)) { + var reader = new FileReader(); + reader.onload = function () { + var $box = $fileInput.parent(); + $box.find('img').attr('src', reader.result).css('display', 'block'); + $box.addClass('has-img'); + }; + reader.readAsDataURL(file); + } else { + } +}); diff --git a/app/views/admins/topic/excellent_projects/_form_modal.html.erb b/app/views/admins/topic/excellent_projects/_form_modal.html.erb new file mode 100644 index 000000000..4e48063b8 --- /dev/null +++ b/app/views/admins/topic/excellent_projects/_form_modal.html.erb @@ -0,0 +1,44 @@ + \ No newline at end of file diff --git a/app/views/admins/topic/excellent_projects/_list.html.erb b/app/views/admins/topic/excellent_projects/_list.html.erb new file mode 100644 index 000000000..7642037db --- /dev/null +++ b/app/views/admins/topic/excellent_projects/_list.html.erb @@ -0,0 +1,33 @@ + + + + + + + + + + + + + <% if excellent_projects.present? %> + <% excellent_projects.each_with_index do |excellent_project, index| %> + + + + + + + + + <% end %> + <% else %> + <%= render 'admins/shared/no_data_for_table' %> + <% end %> + +
    序号标题跳转地址项目ID排序等级操作
    <%= list_index_no((params[:page] || 1).to_i, index) %><%= excellent_project.title %><%= excellent_project.url %><%= excellent_project.uuid %><%= excellent_project.order_index %> + <%= link_to "编辑", edit_admins_topic_excellent_project_path(excellent_project), remote: true, class: "action" %> + <%= link_to "删除", admins_topic_excellent_project_path(excellent_project), method: :delete, data:{confirm: "确认删除的吗?"}, class: "action" %> +
    + +<%= render partial: 'admins/shared/paginate', locals: { objects: excellent_projects } %> \ No newline at end of file diff --git a/app/views/admins/topic/excellent_projects/edit.js.erb b/app/views/admins/topic/excellent_projects/edit.js.erb new file mode 100644 index 000000000..d47b1a92a --- /dev/null +++ b/app/views/admins/topic/excellent_projects/edit.js.erb @@ -0,0 +1,2 @@ +$("#excellent-project-modals").html("<%= j render(partial: 'admins/topic/excellent_projects/form_modal', locals: {type: 'update'}) %>") +$(".excellent-project-change-modal").modal('show'); \ No newline at end of file diff --git a/app/views/admins/topic/excellent_projects/index.html.erb b/app/views/admins/topic/excellent_projects/index.html.erb new file mode 100644 index 000000000..1b529344b --- /dev/null +++ b/app/views/admins/topic/excellent_projects/index.html.erb @@ -0,0 +1,18 @@ +<% define_admin_breadcrumbs do %> + <% add_admin_breadcrumb('优秀仓库管理') %> +<% end %> + +
    + <%= form_tag(admins_topic_excellent_projects_path, method: :get, class: 'form-inline search-form flex-1', remote: true) do %> + <%= text_field_tag(:search, params[:search], class: 'form-control col-12 col-md-2 mr-3', placeholder: '标题检索') %> + <%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %> + + <% end %> + <%= link_to "新增", new_admins_topic_excellent_project_path, remote: true, class: "btn btn-primary pull-right", "data-disabled-with":"...新增" %> +
    + +
    + <%= render partial: 'admins/topic/excellent_projects/list', locals: { excellent_projects: @excellent_projects } %> +
    +
    +
    diff --git a/app/views/admins/topic/excellent_projects/index.js.erb b/app/views/admins/topic/excellent_projects/index.js.erb new file mode 100644 index 000000000..969abd1e0 --- /dev/null +++ b/app/views/admins/topic/excellent_projects/index.js.erb @@ -0,0 +1 @@ +$('.excellent-project-list-container').html("<%= j( render partial: 'admins/topic/excellent_projects/list', locals: { excellent_projects: @excellent_projects } ) %>"); \ No newline at end of file diff --git a/app/views/admins/topic/excellent_projects/new.js.erb b/app/views/admins/topic/excellent_projects/new.js.erb new file mode 100644 index 000000000..1b7e13095 --- /dev/null +++ b/app/views/admins/topic/excellent_projects/new.js.erb @@ -0,0 +1,2 @@ +$("#excellent-project-modals").html("<%= j render(partial: 'admins/topic/excellent_projects/form_modal', locals: {type: 'create'}) %>") +$(".excellent-project-change-modal").modal('show'); \ No newline at end of file diff --git a/app/views/admins/topic/experience_forums/_form_modal.html.erb b/app/views/admins/topic/experience_forums/_form_modal.html.erb new file mode 100644 index 000000000..971b8ca51 --- /dev/null +++ b/app/views/admins/topic/experience_forums/_form_modal.html.erb @@ -0,0 +1,44 @@ + \ No newline at end of file diff --git a/app/views/admins/topic/experience_forums/_list.html.erb b/app/views/admins/topic/experience_forums/_list.html.erb new file mode 100644 index 000000000..b6f5e91fc --- /dev/null +++ b/app/views/admins/topic/experience_forums/_list.html.erb @@ -0,0 +1,33 @@ + + + + + + + + + + + + + <% if experience_forums.present? %> + <% experience_forums.each_with_index do |experience_forum, index| %> + + + + + + + + + <% end %> + <% else %> + <%= render 'admins/shared/no_data_for_table' %> + <% end %> + +
    序号标题跳转地址帖子ID排序等级操作
    <%= list_index_no((params[:page] || 1).to_i, index) %><%= experience_forum.title %><%= experience_forum.url %><%= experience_forum.uuid %><%= experience_forum.order_index %> + <%= link_to "编辑", edit_admins_topic_experience_forum_path(experience_forum), remote: true, class: "action" %> + <%= link_to "删除", admins_topic_experience_forum_path(experience_forum), method: :delete, data:{confirm: "确认删除的吗?"}, class: "action" %> +
    + +<%= render partial: 'admins/shared/paginate', locals: { objects: experience_forums } %> \ No newline at end of file diff --git a/app/views/admins/topic/experience_forums/edit.js.erb b/app/views/admins/topic/experience_forums/edit.js.erb new file mode 100644 index 000000000..5684a1b1f --- /dev/null +++ b/app/views/admins/topic/experience_forums/edit.js.erb @@ -0,0 +1,2 @@ +$("#experience-forum-modals").html("<%= j render(partial: 'admins/topic/experience_forums/form_modal', locals: {type: 'update'}) %>") +$(".experience-forum-change-modal").modal('show'); \ No newline at end of file diff --git a/app/views/admins/topic/experience_forums/index.html.erb b/app/views/admins/topic/experience_forums/index.html.erb new file mode 100644 index 000000000..e66738762 --- /dev/null +++ b/app/views/admins/topic/experience_forums/index.html.erb @@ -0,0 +1,18 @@ +<% define_admin_breadcrumbs do %> + <% add_admin_breadcrumb('经验分享管理') %> +<% end %> + +
    + <%= form_tag(admins_topic_experience_forums_path, method: :get, class: 'form-inline search-form flex-1', remote: true) do %> + <%= text_field_tag(:search, params[:search], class: 'form-control col-12 col-md-2 mr-3', placeholder: '标题检索') %> + <%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %> + + <% end %> + <%= link_to "新增", new_admins_topic_experience_forum_path, remote: true, class: "btn btn-primary pull-right", "data-disabled-with":"...新增" %> +
    + +
    + <%= render partial: 'admins/topic/experience_forums/list', locals: { experience_forums: @experience_forums } %> +
    +
    +
    diff --git a/app/views/admins/topic/experience_forums/index.js.erb b/app/views/admins/topic/experience_forums/index.js.erb new file mode 100644 index 000000000..9653cd9a8 --- /dev/null +++ b/app/views/admins/topic/experience_forums/index.js.erb @@ -0,0 +1 @@ +$('.experience-forum-list-container').html("<%= j( render partial: 'admins/topic/experience_forums/list', locals: { experience_forums: @experience_forums } ) %>"); \ No newline at end of file diff --git a/app/views/admins/topic/experience_forums/new.js.erb b/app/views/admins/topic/experience_forums/new.js.erb new file mode 100644 index 000000000..5020e9ed1 --- /dev/null +++ b/app/views/admins/topic/experience_forums/new.js.erb @@ -0,0 +1,2 @@ +$("#experience-forum-modals").html("<%= j render(partial: 'admins/topic/experience_forums/form_modal', locals: {type: 'create'}) %>") +$(".experience-forum-change-modal").modal('show'); \ No newline at end of file diff --git a/app/views/admins/topic/pinned_forums/_form_modal.html.erb b/app/views/admins/topic/pinned_forums/_form_modal.html.erb new file mode 100644 index 000000000..45c6eb8ec --- /dev/null +++ b/app/views/admins/topic/pinned_forums/_form_modal.html.erb @@ -0,0 +1,44 @@ + \ No newline at end of file diff --git a/app/views/admins/topic/pinned_forums/_list.html.erb b/app/views/admins/topic/pinned_forums/_list.html.erb new file mode 100644 index 000000000..9169b6a20 --- /dev/null +++ b/app/views/admins/topic/pinned_forums/_list.html.erb @@ -0,0 +1,33 @@ + + + + + + + + + + + + + <% if pinned_forums.present? %> + <% pinned_forums.each_with_index do |pinned_forum, index| %> + + + + + + + + + <% end %> + <% else %> + <%= render 'admins/shared/no_data_for_table' %> + <% end %> + +
    序号标题跳转地址帖子ID排序等级操作
    <%= list_index_no((params[:page] || 1).to_i, index) %><%= pinned_forum.title %><%= pinned_forum.url %><%= pinned_forum.uuid %><%= pinned_forum.order_index %> + <%= link_to "编辑", edit_admins_topic_pinned_forum_path(pinned_forum), remote: true, class: "action" %> + <%= link_to "删除", admins_topic_pinned_forum_path(pinned_forum), method: :delete, data:{confirm: "确认删除的吗?"}, class: "action" %> +
    + +<%= render partial: 'admins/shared/paginate', locals: { objects: pinned_forums } %> \ No newline at end of file diff --git a/app/views/admins/topic/pinned_forums/edit.js.erb b/app/views/admins/topic/pinned_forums/edit.js.erb new file mode 100644 index 000000000..77875c679 --- /dev/null +++ b/app/views/admins/topic/pinned_forums/edit.js.erb @@ -0,0 +1,2 @@ +$("#pinned-forum-modals").html("<%= j render(partial: 'admins/topic/pinned_forums/form_modal', locals: {type: 'update'}) %>") +$(".pinned-forum-change-modal").modal('show'); \ No newline at end of file diff --git a/app/views/admins/topic/pinned_forums/index.html.erb b/app/views/admins/topic/pinned_forums/index.html.erb new file mode 100644 index 000000000..d6cf788b6 --- /dev/null +++ b/app/views/admins/topic/pinned_forums/index.html.erb @@ -0,0 +1,18 @@ +<% define_admin_breadcrumbs do %> + <% add_admin_breadcrumb('精选文章管理') %> +<% end %> + +
    + <%= form_tag(admins_topic_pinned_forums_path, method: :get, class: 'form-inline search-form flex-1', remote: true) do %> + <%= text_field_tag(:search, params[:search], class: 'form-control col-12 col-md-2 mr-3', placeholder: '标题检索') %> + <%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %> + + <% end %> + <%= link_to "新增", new_admins_topic_pinned_forum_path, remote: true, class: "btn btn-primary pull-right", "data-disabled-with":"...新增" %> +
    + +
    + <%= render partial: 'admins/topic/pinned_forums/list', locals: { pinned_forums: @pinned_forums } %> +
    +
    +
    diff --git a/app/views/admins/topic/pinned_forums/index.js.erb b/app/views/admins/topic/pinned_forums/index.js.erb new file mode 100644 index 000000000..78d1a240a --- /dev/null +++ b/app/views/admins/topic/pinned_forums/index.js.erb @@ -0,0 +1 @@ +$('.pinned-forum-list-container').html("<%= j( render partial: 'admins/topic/pinned_forums/list', locals: { pinned_forums: @pinned_forums } ) %>"); \ No newline at end of file diff --git a/app/views/admins/topic/pinned_forums/new.js.erb b/app/views/admins/topic/pinned_forums/new.js.erb new file mode 100644 index 000000000..1069707c0 --- /dev/null +++ b/app/views/admins/topic/pinned_forums/new.js.erb @@ -0,0 +1,2 @@ +$("#pinned-forum-modals").html("<%= j render(partial: 'admins/topic/pinned_forums/form_modal', locals: {type: 'create'}) %>") +$(".pinned-forum-change-modal").modal('show'); \ No newline at end of file diff --git a/app/views/admins/unit_applies/edit.js.erb b/app/views/admins/unit_applies/edit.js.erb deleted file mode 100644 index 15fc1f4c2..000000000 --- a/app/views/admins/unit_applies/edit.js.erb +++ /dev/null @@ -1,56 +0,0 @@ -$("body").append("<%= j render partial: "admins/unit_applies/shared/edit_modal",locals: {apply: @unit_apply, schools: @all_schools} %>") -var uni_edit_modal = $(".admin-unit-edit-modal") -uni_edit_modal.modal("show") - -uni_edit_modal.on("hidden.bs.modal",function () { - $(".admin-unit-edit-modal").remove() - $("body").removeClass("modal-open") -}) - -// 初始化学校选择器 -var matcherFunc = function(params, data){ - if ($.trim(params.term) === '') { - return data; - } - if (typeof data.text === 'undefined') { - return null; - } - if (data.name && data.name.indexOf(params.term) > -1) { - var modifiedData = $.extend({}, data, true); - return modifiedData; - } - - // Return `null` if the term should not be displayed - return null; -} -$.ajax({ - url: '/api/schools/for_option.json', - dataType: 'json', - type: 'GET', - success: function(data) { - $("#all-schools").select2({ - theme: 'bootstrap4', - placeholder: '查询学校/单位', - minimumInputLength: 1, - data: data.schools, - templateResult: function (item) { - if(!item.id || item.id === '') return item.text; - return item.name; - }, - templateSelection: function(item){ - return item.name || item.text; - }, - matcher: matcherFunc - }) - } -}); - -$("#all-schools").select2({}) -$("#show-province-<%= @unit_apply.id %>").select2() -$("#schoolCity_<%= @unit_apply.id %>").select2() - -// **************** 地区选择 **************** -$('.province-city-select').cxSelect({ - url: '/javascripts/educoder/province-data.json', - selects: ['province-select', 'city-select'] -}); \ No newline at end of file diff --git a/app/views/admins/unit_applies/index.html.erb b/app/views/admins/unit_applies/index.html.erb deleted file mode 100644 index 2b715b87c..000000000 --- a/app/views/admins/unit_applies/index.html.erb +++ /dev/null @@ -1,17 +0,0 @@ -<% define_admin_breadcrumbs do %> - <% add_admin_breadcrumb('单位审批') %> -<% end %> - -
    - <%= form_tag(admins_unit_applies_path(unsafe_params), method: :get, class: 'form-inline search-form mt-3', remote: true) do %> - <%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-sm-2 ml-3', placeholder: '单位名称检索') %> - <%= submit_tag('搜索', class: 'btn btn-primary ml-3','data-disable-with':"搜索中...") %> - <%= link_to "清除",admins_unit_applies_path(keyword:nil),class:"btn btn-default",remote:true %> - <% end %> -
    - -
    - <%= render(partial: 'admins/unit_applies/shared/list', locals: { applies: @unit_applies }) %> -
    - -<%= render(partial: 'admins/shared/admin_common_refuse_modal') %> diff --git a/app/views/admins/unit_applies/index.js.erb b/app/views/admins/unit_applies/index.js.erb deleted file mode 100644 index d9297d51a..000000000 --- a/app/views/admins/unit_applies/index.js.erb +++ /dev/null @@ -1 +0,0 @@ -$(".unit-applies-list-container").html("<%= j render partial: "admins/unit_applies/shared/list", locals: {applies: @unit_applies} %>") diff --git a/app/views/admins/unit_applies/shared/_apply_item.html.erb b/app/views/admins/unit_applies/shared/_apply_item.html.erb deleted file mode 100644 index b7d38b776..000000000 --- a/app/views/admins/unit_applies/shared/_apply_item.html.erb +++ /dev/null @@ -1,18 +0,0 @@ -<%= list_index_no((params[:page] || 1).to_i, index) %> -<%= apply.id %> -<%= overflow_hidden_span apply.name %> - - <%= "#{apply&.province.to_s}"+"#{apply&.city.to_s}" %> - -<%= overflow_hidden_span apply.address %> -<%= link_to apply&.user&.real_name, "/users/#{apply&.user&.login}", target: "_blank" %> -<%= format_time apply.created_at %> - - <%= agree_link '批准', agree_admins_unit_apply_path(apply, element: ".unit-apply-#{apply.id}"), 'data-confirm': '确认批准通过?' %> - <%= javascript_void_link('删除', class: 'action refuse-action', - data: { - toggle: 'modal', target: '.admin-common-refuse-modal', id: apply.id, title: "删除原因", type: "delete", - url: admins_unit_apply_path(apply, tip: "unapplied", element: ".unit-apply-#{apply.id}") - }) %> - <%= link_to "更改",edit_admins_unit_apply_path(apply), remote: true, class:"action",'data-disable-with': '打开中...' %> - \ No newline at end of file diff --git a/app/views/admins/unit_applies/shared/_edit_modal.html.erb b/app/views/admins/unit_applies/shared/_edit_modal.html.erb deleted file mode 100644 index 6f8995ae0..000000000 --- a/app/views/admins/unit_applies/shared/_edit_modal.html.erb +++ /dev/null @@ -1,43 +0,0 @@ - \ No newline at end of file diff --git a/app/views/admins/unit_applies/shared/_list.html.erb b/app/views/admins/unit_applies/shared/_list.html.erb deleted file mode 100644 index 75b9c720b..000000000 --- a/app/views/admins/unit_applies/shared/_list.html.erb +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - <% if applies.present? %> - <% applies.each_with_index do |apply, index| %> - - <%= render partial: "admins/unit_applies/shared/apply_item", locals: {apply: apply, index: index} %> - - <% end %> - <% else %> - <%= render 'admins/shared/no_data_for_table' %> - <% end %> - -
    序号ID单位名称地区详细地址申请者<%= sort_tag('创建于', name: 'created_at', path: admins_unit_applies_path) %>操作
    - -<%= render partial: 'admins/shared/paginate', locals: { objects: applies } %> \ No newline at end of file diff --git a/app/views/admins/unit_applies/update.js.erb b/app/views/admins/unit_applies/update.js.erb deleted file mode 100644 index c710f46b5..000000000 --- a/app/views/admins/unit_applies/update.js.erb +++ /dev/null @@ -1,3 +0,0 @@ -$('.modal.admin-unit-edit-modal').modal('hide'); -$('.unit-applies-list-table .unit-apply-<%= @unit_apply.id %>').remove() -$.notify({ message: '操作成功' }); \ No newline at end of file diff --git a/app/views/admins/users/edit.html.erb b/app/views/admins/users/edit.html.erb index 5abc82711..44d524997 100644 --- a/app/views/admins/users/edit.html.erb +++ b/app/views/admins/users/edit.html.erb @@ -7,8 +7,8 @@