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 %>
-
-
-
-
- <%= 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 @@
-
-
- | 序号 |
- ID |
- 课程名称 |
- 课堂数 |
- 创建者 |
- <%= sort_tag('创建时间', name: 'created_at', path: admins_course_lists_path) %> |
- 操作 |
-
-
- <% if courses.present? %>
- <% courses.each_with_index do |course_list,index| %>
-
- | <%= list_index_no(@params_page.to_i, index) %> |
- <%= course_list.id %> |
- <%= course_list.name %> |
- <% course_count = course_list.courses.size %>
- <%= 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 } %>
- |
-
- <% end %>
- <% else %>
- <%= render 'admins/shared/no_data_for_table' %>
- <% end %>
-
-
-
-<%= 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 %>
-
-
-
-
- <%= 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 @@
-
-
-
- | 序号 |
- ID |
- 课堂名称 |
- 成员 |
- 资源 |
- 普通作业 |
- 分组作业 |
- 实训作业 |
- 试卷 |
- 评测次数 |
- 私有 |
- 状态 |
- 单位 |
- 创建者 |
- <%= sort_tag('创建时间', name: 'created_at', path: admins_courses_path) %> |
- 首页 |
- 邮件通知 |
- 操作 |
-
-
-
- <% 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 %>
-
-
-
-<%= 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 @@
-
-
-
- | 序号 |
- 客户名称 |
- <%= sort_tag('添加时间', name: 'created_at', path: admins_partner_customers_path(current_partner)) %> |
- 操作 |
-
-
-
- <% if customers.present? %>
- <% customers.each_with_index do |customer, index| %>
-
- | <%= 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' %>
- |
-
- <% end %>
- <% else %>
- <%= render 'admins/shared/no_data_for_table' %>
- <% end %>
-
-
-
-<%= 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 @@
-
-
-
- | 序号 |
- 单位名称 |
- <%= 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) %> |
-
-
-
- <% if statistics.present? %>
- <% statistics.each_with_index do |statistic, index| %>
-
- | <%= 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') %> |
-
- <% end %>
- <% else %>
- <%= render 'admins/shared/no_data_for_table' %>
- <% end %>
-
-
-
-<%= 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 @@
-
-
-
- | 序号 |
- ID |
- 部门名称 |
- 单位名称 |
- 创建者 |
- <%= sort_tag('创建于', name: 'created_at', path: admins_department_applies_path) %> |
- 操作 |
-
-
-
- <% if applies.present? %>
- <% applies.each_with_index do |apply, index| %>
-
- | <%= 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 } %>
- |
-
- <% end %>
- <% else %>
- <%= render 'admins/shared/no_data_for_table' %>
- <% end %>
-
-
-
-<%= 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 %>
-
-
-
-
- <%= 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 @@
-
-
-
-
-
- <%= simple_form_for([:admins, department], html: { class: 'admin-edit-department-form' }, defaults: { wrapper_html: { class: 'offset-md-1 col-md-10' } }) do |f| %>
- <%= f.input :name, as: :string, label: '名称' %>
- <%= f.input :identifier, as: :string, label: '统计链接' %>
- <%= f.input :host_count, as: :integer, label: '云主机数' %>
-
-
- <% end %>
-
-
-
-
-
\ 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 @@
-
-
-
- | 序号 |
- 部门名称 |
- 单位名称 |
- 用户数 |
- 已职业认证 |
- 部门管理员 |
- 统计链接 |
- 云主机数 |
- <%= sort_tag('创建时间', name: 'created_at', path: admins_departments_path) %> |
- 操作 |
-
-
-
- <% 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 %>
-
-
-
-<%= 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 %>
-
-
-
-
- <%= 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 @@
-
-
-
-
-
- <%= simple_form_for([:admins, discipline], html: { class: 'admin-edit-discipline-form' }, defaults: { wrapper_html: { class: 'offset-md-1 col-md-10' } }) do |f| %>
- <%= f.input :name, as: :string, label: '名称' %>
-
-
- <% end %>
-
-
-
-
-
\ 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| %>
-
- | <%= 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' %>
- |
-
- <% end %>
- <% else %>
- <%= render 'admins/shared/no_data_for_table' %>
- <% end %>
-
-
\ 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 %>
-
-
-
-
- <%= 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 @@
-
-
-
-
-
-
-
题型:<%= item.type_string %>
-
难度:<%= item.difficulty_string %>
-
-
-
-
<%= item.name %>
- <% item.item_choices.each do |choice| %>
-
- <% if item.item_type == "MULTIPLE" %>
- <%= check_box_tag(:choice, true, choice.is_answer, class: 'form-check-input') %>
-
- <% elsif item.item_type == "SINGLE" || item.item_type == "JUDGMENT" %>
- <%= radio_button_tag(:choice, true, choice.is_answer, class: 'form-check-input') %>
-
- <% else %>
- 答案:<%= choice.choice_text %>
- <% end %>
-
- <% end %>
-
-
-
-
-
\ 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 %>
-
- | <%= 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 %>
- |
-
- <% end %>
- <% else %>
- <%= render 'admins/shared/no_data_for_table' %>
- <% 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 -%>
-
- | <%= 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 %>
- |
-
- <% end %>
- <% else %>
- <%= render 'admins/shared/no_data_for_table' %>
- <% 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 %>
-
-
-
-
- <%= 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 %>
-
- | <%= 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') %> |
-
- <% if is_processed %>
- <%= overflow_hidden_span apply.reason %> |
- <%= t("library_apply.status.#{apply.status}") %> |
- <% else %>
-
- <%= 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}")
- }) %>
- |
- <% end %>
-
- <% end %>
- <% else %>
- <%= render 'admins/shared/no_data_for_table' %>
- <% end %>
-
-
-
-<%= 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| %>
- <%= p.text_field :name,class: "form-control input-lg",placeholder: "分类名称",required: true, maxlength: 64%>
+
+
+ <%= p.text_field :name,class: "form-control input-lg",placeholder: "分类名称",required: true, maxlength: 64%>
+
+
+
+ <%= p.number_field :pinned_index,class: "form-control input-lg",placeholder: "精选等级",required: true%>
+
+
+ <% logo_img = @project_category.logo_url %>
+
+

+ <%= file_field_tag(:logo, accept: 'image/png,image/jpg,image/jpeg',style: "display: none", value: params[:logo]) %>
+
+
+
+
logo
+
格式:PNG、JPG
+
尺寸:高度38px以内,宽等比例缩放
+
+