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/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb index 740a68ea7..b8783c44e 100644 --- a/app/controllers/accounts_controller.rb +++ b/app/controllers/accounts_controller.rb @@ -1,4 +1,5 @@ class AccountsController < ApplicationController + include ApplicationHelper #skip_before_action :check_account, :only => [:logout] @@ -9,7 +10,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,60 +110,46 @@ 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 - @user = User.new(admin: false, 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! - 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_error(-2, e.message) + rescue Register::BaseForm::LoginError => e + render_error(-3, e.message) + rescue Register::BaseForm::PhoneError => e + render_error(-4, e.message) + rescue Register::BaseForm::PasswordFormatError => e + render_error(-5, e.message) + rescue Register::BaseForm::VerifiCodeError => e + render_error(-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 @@ -297,7 +284,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 @@ -311,19 +298,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: 验证手机号是否有效 # 如果有新的继续后面加 @@ -369,4 +359,13 @@ class AccountsController < ApplicationController def account_params params.require(:account).permit(:login, :password) end + + def check_params + params.permit(:type, :value) + end + + def register_params + params.permit(:login, :namespace, :password, :code) + end + end 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/application_controller.rb b/app/controllers/application_controller.rb index 3f0fbcc7d..201eeda9f 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -70,49 +70,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 +82,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 # 发送及记录激活码 @@ -186,26 +148,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 +157,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 diff --git a/app/controllers/concerns/render_helper.rb b/app/controllers/concerns/render_helper.rb index fad401539..81e85d1ce 100644 --- a/app/controllers/concerns/render_helper.rb +++ b/app/controllers/concerns/render_helper.rb @@ -3,8 +3,8 @@ module RenderHelper render json: { status: 0, message: 'success' }.merge(data) end - def render_error(message = '') - render json: { status: -1, message: message } + def render_error(status = -1, message = '') + render json: { status: status, message: message } end def render_not_acceptable(message = '请求已拒绝') diff --git a/app/controllers/organizations/organizations_controller.rb b/app/controllers/organizations/organizations_controller.rb index 00a7588b5..269ca66cc 100644 --- a/app/controllers/organizations/organizations_controller.rb +++ b/app/controllers/organizations/organizations_controller.rb @@ -27,7 +27,7 @@ class Organizations::OrganizationsController < Organizations::BaseController 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? 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/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/base_form.rb b/app/forms/base_form.rb index 71eaee174..437217f00 100644 --- a/app/forms/base_form.rb +++ b/app/forms/base_form.rb @@ -23,7 +23,11 @@ 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 + + private + def strip(str) + str.to_s.strip.presence end - end diff --git a/app/forms/register/base_form.rb b/app/forms/register/base_form.rb new file mode 100644 index 000000000..df5abd871 --- /dev/null +++ b/app/forms/register/base_form.rb @@ -0,0 +1,51 @@ +module Register + class BaseForm < ::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) + + 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 + + def check_password(password) + password = strip(password) + raise PasswordFormatError, "8~16位密码,支持字母数字和符号" unless password =~ CustomRegexp::PASSWORD + 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 + + 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..bad7a23e6 --- /dev/null +++ b/app/forms/register/form.rb @@ -0,0 +1,27 @@ +module Register + class Form < Register::BaseForm + # login 登陆方式,支持邮箱、登陆、手机号等 + # namespace 用户空间地址 + # type: 1:手机号注册;2:邮箱注册 + attr_accessor :login, :namespace, :password, :code, :type + + validates :login, :code, :password, :namespace, presence: true + validate :check! + + def check! + Rails.logger.info "Register::Form params: code: #{code}; login: #{login}; namespace: #{namespace}; password: #{password}; type: #{type}" + 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) + end + end +end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index c37fd59da..9cad9f44b 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -455,5 +455,11 @@ 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 end 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/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/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/user.rb b/app/models/user.rb index ae20b83d3..8bdb8bfa6 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -173,6 +173,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) } scope :like, lambda { |keywords| diff --git a/app/queries/projects/list_query.rb b/app/queries/projects/list_query.rb index 4f514b610..b06791bd3 100644 --- a/app/queries/projects/list_query.rb +++ b/app/queries/projects/list_query.rb @@ -11,20 +11,45 @@ class Projects::ListQuery < ApplicationQuery end def call - q = params[:pinned].present? ? Project.pinned : Project - q = q.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/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/users/register_service.rb b/app/services/users/register_service.rb new file mode 100644 index 000000000..bb3b3ada1 --- /dev/null +++ b/app/services/users/register_service.rb @@ -0,0 +1,58 @@ +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: ##### #{params} " + + 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 + + def phone_mail_type value + value =~ /^1\d{10}$/ ? 1 : 0 + end + +end diff --git a/app/views/settings/show.json.jbuilder b/app/views/settings/show.json.jbuilder index 1147ffde2..0e6e1606b 100644 --- a/app/views/settings/show.json.jbuilder +++ b/app/views/settings/show.json.jbuilder @@ -60,6 +60,7 @@ json.setting do if @top_system_notification.present? json.system_notification do json.(@top_system_notification, :id, :subject, :sub_subject, :content) + json.is_read @top_system_notification.read_member?(current_user&.id) end else json.system_notification nil diff --git a/app/views/user_mailer/register_email.html.erb b/app/views/user_mailer/register_email.html.erb index 6f88177c5..431db06f3 100644 --- a/app/views/user_mailer/register_email.html.erb +++ b/app/views/user_mailer/register_email.html.erb @@ -1,7 +1,7 @@
-