forked from Trustie/forgeplus
Compare commits
109 Commits
standalone
...
develop
| Author | SHA1 | Date |
|---|---|---|
|
|
2ea78b4f20 | |
|
|
e36c7a4b6a | |
|
|
8e8ec821f2 | |
|
|
5cf257c3cc | |
|
|
aa18fe0ad4 | |
|
|
1358c23ca6 | |
|
|
c27cc063e6 | |
|
|
b0092487e6 | |
|
|
fbebd0a623 | |
|
|
fe23c2afbf | |
|
|
779c86108a | |
|
|
83e43f0c97 | |
|
|
e237fd46f7 | |
|
|
ca3c564529 | |
|
|
9cd18397f7 | |
|
|
77620f7735 | |
|
|
50dc5cce5d | |
|
|
a6cee63d17 | |
|
|
000197b0d1 | |
|
|
6aa3321d17 | |
|
|
d44308fc82 | |
|
|
ae7d0d1329 | |
|
|
55c74de8e4 | |
|
|
7c88ea3d67 | |
|
|
f15cd44dff | |
|
|
3abd6037d9 | |
|
|
ec3a556a6f | |
|
|
793cbb372a | |
|
|
396ac55429 | |
|
|
088c617cc1 | |
|
|
fc3cf01d3f | |
|
|
8f5bb0e2d9 | |
|
|
2dfd69ae21 | |
|
|
720c073f32 | |
|
|
0076468a15 | |
|
|
910ae48556 | |
|
|
eac7331070 | |
|
|
551f333261 | |
|
|
dec264d169 | |
|
|
7055974443 | |
|
|
3536918938 | |
|
|
56278b84f2 | |
|
|
882a50cf56 | |
|
|
db4031b8bf | |
|
|
ecfc39565c | |
|
|
9ced678f91 | |
|
|
7951ca28d5 | |
|
|
4bbb843edf | |
|
|
747646cd9d | |
|
|
d0d906d04c | |
|
|
bc639488aa | |
|
|
99fbecc834 | |
|
|
8d0a6d267a | |
|
|
b1c03ed5e8 | |
|
|
ef12f85687 | |
|
|
e120c4dac2 | |
|
|
e1cf2fcdeb | |
|
|
c4f380873e | |
|
|
5cb2e55f74 | |
|
|
1dd3fbc69a | |
|
|
b97c42d0ae | |
|
|
a2612d8009 | |
|
|
2f2655525f | |
|
|
1a93477635 | |
|
|
7c664addbd | |
|
|
c6b79f82bc | |
|
|
4e3f9cc019 | |
|
|
5ed7b3e4ad | |
|
|
4e2c46260c | |
|
|
9ba00b21c9 | |
|
|
b11f5fd228 | |
|
|
90dbe0730a | |
|
|
d6633cb73a | |
|
|
a7a6abd22a | |
|
|
c956667ce0 | |
|
|
5701c818ed | |
|
|
1ac2ddfaa5 | |
|
|
4aac05d4e1 | |
|
|
84b56bfcb8 | |
|
|
7485564bb9 | |
|
|
b5acf2308a | |
|
|
e3f4313c80 | |
|
|
b223abe229 | |
|
|
b3bede308c | |
|
|
2f170a54c6 | |
|
|
22293572ac | |
|
|
8720cab1e9 | |
|
|
959c1e8d95 | |
|
|
29dc3fff39 | |
|
|
298abdd1b1 | |
|
|
26f87fba16 | |
|
|
1e9a32a93e | |
|
|
2dc79052c2 | |
|
|
380ca3a066 | |
|
|
237b0afb08 | |
|
|
e14936e820 | |
|
|
655c85851f | |
|
|
1c7e414aa4 | |
|
|
099fc52e00 | |
|
|
490957ec3b | |
|
|
b1884d30d5 | |
|
|
98d8ee1fb6 | |
|
|
2ca77732c8 | |
|
|
70d22f7c4f | |
|
|
25d0e784bb | |
|
|
5d45b24299 | |
|
|
b6b8befde7 | |
|
|
f33b9559cd | |
|
|
f9bc2258ec |
|
|
@ -1,376 +1,403 @@
|
|||
class AccountsController < ApplicationController
|
||||
include ApplicationHelper
|
||||
|
||||
#skip_before_action :check_account, :only => [:logout]
|
||||
|
||||
def index
|
||||
render json: session
|
||||
end
|
||||
|
||||
# 其他平台同步注册的用户
|
||||
def remote_register
|
||||
Register::RemoteForm.new(remote_register_params).validate!
|
||||
username = params[:username]&.gsub(/\s+/, "")
|
||||
tip_exception("无法使用以下关键词:#{username},请重新命名") if ReversedKeyword.check_exists?(username)
|
||||
email = params[:email]&.gsub(/\s+/, "")
|
||||
password = params[:password]
|
||||
platform = (params[:platform] || 'forge')&.gsub(/\s+/, "")
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
result = autologin_register(username, email, password, platform)
|
||||
if result[:message].blank?
|
||||
render_ok({user: result[:user]})
|
||||
else
|
||||
render_error(result[:message])
|
||||
end
|
||||
end
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
tip_exception(-1, e.message)
|
||||
end
|
||||
|
||||
# 其他平台修改用户的信息,这边同步修改
|
||||
def remote_update
|
||||
ActiveRecord::Base.transaction do
|
||||
user_params = params[:user_params]
|
||||
user_extension_params = params[:user_extension_params]
|
||||
|
||||
u = User.find_by(login: params[:old_user_login])
|
||||
user_mail = u.try(:mail)
|
||||
|
||||
if u.present?
|
||||
ue = u.user_extension
|
||||
u.login = user_params["login"] if user_params["login"]
|
||||
u.mail = user_params["mail"] if user_params["mail"]
|
||||
u.lastname = user_params["lastname"] if user_params["lastname"]
|
||||
|
||||
ue.gender = user_extension_params["gender"]
|
||||
ue.school_id = user_extension_params["school_id"]
|
||||
ue.location = user_extension_params["location"]
|
||||
ue.location_city = user_extension_params["location_city"]
|
||||
ue.identity = user_extension_params["identity"]
|
||||
ue.technical_title = user_extension_params["technical_title"]
|
||||
ue.student_id = user_extension_params["student_id"]
|
||||
ue.description = user_extension_params["description"]
|
||||
ue.save!
|
||||
u.save!
|
||||
|
||||
sync_params = {}
|
||||
|
||||
if (user_params["mail"] && user_params["mail"] != user_mail)
|
||||
sync_params = sync_params.merge(email: user_params["mail"])
|
||||
end
|
||||
|
||||
if sync_params.present?
|
||||
interactor = Gitea::User::UpdateInteractor.call(u.login, sync_params)
|
||||
if interactor.success?
|
||||
render_ok
|
||||
else
|
||||
render_error(interactor.error)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
tip_exception(-1, e.message)
|
||||
end
|
||||
|
||||
# 其他平台同步登录
|
||||
def remote_login
|
||||
@user = User.try_to_login(params[:login], params[:password])
|
||||
if @user
|
||||
successful_authentication(@user)
|
||||
render_ok({user: {id: @user.id, token: @user.gitea_token}})
|
||||
else
|
||||
render_error("用户不存在")
|
||||
end
|
||||
end
|
||||
|
||||
#修改密码
|
||||
def remote_password
|
||||
@user = User.find_by(login: params[:login])
|
||||
return render_error("未找到相关用户!") if @user.blank?
|
||||
|
||||
sync_params = {
|
||||
password: params[:password].to_s,
|
||||
email: @user.mail
|
||||
}
|
||||
|
||||
interactor = Gitea::User::UpdateInteractor.call(@user.login, sync_params)
|
||||
if interactor.success?
|
||||
@user.update_attribute(:password, params[:password])
|
||||
render_ok
|
||||
else
|
||||
render_error(interactor.error)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
# 用户注册
|
||||
# 注意:用户注册需要兼顾本地版,本地版是不需要验证码及激活码以及使用授权的,注册完成即可使用
|
||||
# params[:login] 邮箱或者手机号
|
||||
# params[:namespace] 登录名
|
||||
# params[:code] 验证码
|
||||
# code_type 1:注册手机验证码 8:邮箱注册验证码
|
||||
# 本地forge注册入口需要重新更改逻辑
|
||||
def register
|
||||
# type只可能是1或者8
|
||||
user = nil
|
||||
begin
|
||||
Register::Form.new(register_params).validate!
|
||||
|
||||
user = Users::RegisterService.call(register_params)
|
||||
password = register_params[:password].strip
|
||||
|
||||
# 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.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
|
||||
end
|
||||
|
||||
# 用户登录
|
||||
def login
|
||||
Users::LoginForm.new(account_params).validate!
|
||||
@user = User.try_to_login(params[:login], params[:password])
|
||||
|
||||
return normal_status(-2, "错误的账号或密码") if @user.blank?
|
||||
# user is already in local database
|
||||
return normal_status(-2, "违反平台使用规范,账号已被锁定") if @user.locked?
|
||||
|
||||
login_control = LimitForbidControl::UserLogin.new(@user)
|
||||
return normal_status(-2, "登录密码出错已达上限,账号已被锁定, 请#{login_control.forbid_expires/60}分钟后重新登录或找回密码") if login_control.forbid?
|
||||
|
||||
password_ok = @user.check_password?(params[:password].to_s)
|
||||
unless password_ok
|
||||
if login_control.remain_times-1 == 0
|
||||
normal_status(-2, "登录密码出错已达上限,账号已被锁定, 请#{login_control.forbid_expires/60}分钟后重新登录或找回密码")
|
||||
else
|
||||
normal_status(-2, "你已经输错密码#{login_control.error_times+1}次,还剩余#{login_control.remain_times-1}次机会")
|
||||
end
|
||||
login_control.increment!
|
||||
return
|
||||
end
|
||||
|
||||
successful_authentication(@user)
|
||||
sync_pwd_to_gitea!(@user, {password: params[:password].to_s}) # TODO用户密码未同步
|
||||
|
||||
# session[:user_id] = @user.id
|
||||
end
|
||||
|
||||
def change_password
|
||||
@user = User.find_by(login: params[:login])
|
||||
return render_error("未找到相关用户!") if @user.blank?
|
||||
return render_error("旧密码不正确") unless @user.check_password?(params[:old_password])
|
||||
|
||||
sync_params = {
|
||||
password: params[:password].to_s,
|
||||
email: @user.mail
|
||||
}
|
||||
|
||||
interactor = Gitea::User::UpdateInteractor.call(@user.login, sync_params)
|
||||
if interactor.success?
|
||||
@user.update_attribute(:password, params[:password])
|
||||
render_ok
|
||||
else
|
||||
render_error(interactor.error)
|
||||
end
|
||||
end
|
||||
|
||||
# 忘记密码
|
||||
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
|
||||
|
||||
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
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
tip_exception(e.message)
|
||||
end
|
||||
end
|
||||
|
||||
def successful_authentication(user)
|
||||
uid_logger("Successful authentication start: '#{user.login}' from #{request.remote_ip} at #{Time.now.utc}")
|
||||
# Valid user
|
||||
self.logged_user = user
|
||||
# generate a key and set cookie if autologin
|
||||
|
||||
set_autologin_cookie(user)
|
||||
UserAction.create(:action_id => user.try(:id), :action_type => "Login", :user_id => user.try(:id), :ip => request.remote_ip)
|
||||
user.update_column(:last_login_on, Time.now)
|
||||
session[:"#{default_yun_session}"] = user.id
|
||||
Rails.logger.info("#########_____session_default_yun_session__________###############{default_yun_session}")
|
||||
# 注册完成后有一天的试用申请(先去掉)
|
||||
# UserDayCertification.create(user_id: user.id, status: 1)
|
||||
end
|
||||
|
||||
def set_autologin_cookie(user)
|
||||
token = Token.get_or_create_permanent_login_token(user, "autologin")
|
||||
sync_user_token_to_trustie(user.login, token.value)
|
||||
|
||||
cookie_options = {
|
||||
:value => token.value,
|
||||
:expires => 1.month.from_now,
|
||||
:path => '/',
|
||||
:secure => false,
|
||||
:httponly => true
|
||||
}
|
||||
if edu_setting('cookie_domain').present?
|
||||
cookie_options = cookie_options.merge(domain: edu_setting('cookie_domain'))
|
||||
end
|
||||
cookies[autologin_cookie_name] = cookie_options
|
||||
cookies.signed[:user_id] ||= user.id
|
||||
|
||||
logger.info("cookies is #{cookies} ======> #{cookies.signed[:user_id]} =====> #{cookies[autologin_cookie_name]}")
|
||||
end
|
||||
|
||||
def logout
|
||||
Rails.logger.info("########___logout_current_user____________########{current_user.try(:id)}")
|
||||
UserAction.create(action_id: User.current.id, action_type: "Logout", user_id: User.current.id, :ip => request.remote_ip)
|
||||
logout_user
|
||||
render :json => {status: 1, message: "退出成功!"}
|
||||
end
|
||||
|
||||
# 检验邮箱是否已被注册及邮箱或者手机号是否合法
|
||||
# 参数type为事件类型 1:注册;2:忘记密码;3:绑定
|
||||
def valid_email_and_phone
|
||||
check_mail_and_phone_valid(params[:login], params[:type])
|
||||
end
|
||||
|
||||
# 发送验证码
|
||||
# params[:login] 手机号或者邮箱号
|
||||
# params[:type]为事件通知类型 1:用户注册 2:忘记密码 3: 绑定手机 4: 绑定邮箱, 5: 验收手机号有效 # 如果有新的继续后面加
|
||||
# 发送验证码:send_type 1:注册手机验证码 2:找回密码手机验证码 3:找回密码邮箱验证码 4:绑定手机 5:绑定邮箱
|
||||
# 6:手机验证码登录 7:邮箱验证码登录 8:邮箱注册验证码 9: 验收手机号有效
|
||||
def get_verification_code
|
||||
code = %W(0 1 2 3 4 5 6 7 8 9)
|
||||
value = params[:login]
|
||||
type = params[:type].strip.to_i
|
||||
login_type = phone_mail_type(value)
|
||||
send_type = verify_type(login_type, type)
|
||||
verification_code = code.sample(6).join
|
||||
|
||||
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)
|
||||
render_ok
|
||||
end
|
||||
|
||||
# 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: 验证手机号是否有效 # 如果有新的继续后面加
|
||||
# login_type 1:手机类型 2:邮箱类型
|
||||
def verify_type login_type, type
|
||||
case type
|
||||
when 1
|
||||
login_type == 1 ? 1 : 8
|
||||
when 2
|
||||
login_type == 1 ? 2 : 3
|
||||
when 3
|
||||
login_type == 1 ? 4 : tip_exception('请填写正确的手机号')
|
||||
when 4
|
||||
login_type == 1 ? tip_exception('请填写正确的邮箱') : 5
|
||||
when 5
|
||||
login_type == 1 ? 9 : tip_exception('请填写正确的手机号')
|
||||
end
|
||||
end
|
||||
|
||||
def generate_login(login)
|
||||
type = phone_mail_type(login.strip)
|
||||
|
||||
if type == 1
|
||||
uid_logger("start register by phone: type is #{type}")
|
||||
pre = 'p'
|
||||
email = nil
|
||||
phone = login
|
||||
else
|
||||
uid_logger("start register by email: type is #{type}")
|
||||
pre = 'm'
|
||||
email = login
|
||||
phone = nil
|
||||
end
|
||||
code = generate_identifier User, 8, pre
|
||||
|
||||
{ login: pre + code, email: email, phone: phone }
|
||||
end
|
||||
|
||||
def user_params
|
||||
params.require(:user).permit(:login, :email, :phone)
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
def remote_register_params
|
||||
params.permit(:username, :email, :password, :platform)
|
||||
end
|
||||
|
||||
end
|
||||
class AccountsController < ApplicationController
|
||||
before_action :require_login, only: [:login_check, :simple_update]
|
||||
include ApplicationHelper
|
||||
|
||||
#skip_before_action :check_account, :only => [:logout]
|
||||
|
||||
def simple_update
|
||||
simple_update_params.merge!(username: params[:username]&.gsub(/\s+/, ""))
|
||||
simple_update_params.merge!(email: params[:email]&.gsub(/\s+/, ""))
|
||||
simple_update_params.merge!(platform: (params[:platform] || 'forge')&.gsub(/\s+/, ""))
|
||||
Register::RemoteForm.new(simple_update_params).validate!
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
result = auto_update(current_user, simple_update_params)
|
||||
if result[:message].blank?
|
||||
render_ok
|
||||
else
|
||||
render_error(result[:message])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def index
|
||||
render json: session
|
||||
end
|
||||
|
||||
# 其他平台同步注册的用户
|
||||
def remote_register
|
||||
Register::RemoteForm.new(remote_register_params).validate!
|
||||
username = params[:username]&.gsub(/\s+/, "")
|
||||
tip_exception("无法使用以下关键词:#{username},请重新命名") if ReversedKeyword.check_exists?(username)
|
||||
email = params[:email]&.gsub(/\s+/, "")
|
||||
password = params[:password]
|
||||
platform = (params[:platform] || 'forge')&.gsub(/\s+/, "")
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
result = autologin_register(username, email, password, platform)
|
||||
if result[:message].blank?
|
||||
render_ok({user: result[:user]})
|
||||
else
|
||||
render_error(result[:message])
|
||||
end
|
||||
end
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
tip_exception(-1, e.message)
|
||||
end
|
||||
|
||||
# 其他平台修改用户的信息,这边同步修改
|
||||
def remote_update
|
||||
ActiveRecord::Base.transaction do
|
||||
user_params = params[:user_params]
|
||||
user_extension_params = params[:user_extension_params]
|
||||
|
||||
u = User.find_by(login: params[:old_user_login])
|
||||
user_mail = u.try(:mail)
|
||||
|
||||
if u.present?
|
||||
ue = u.user_extension
|
||||
u.login = user_params["login"] if user_params["login"]
|
||||
u.mail = user_params["mail"] if user_params["mail"]
|
||||
u.lastname = user_params["lastname"] if user_params["lastname"]
|
||||
|
||||
ue.gender = user_extension_params["gender"]
|
||||
ue.school_id = user_extension_params["school_id"]
|
||||
ue.location = user_extension_params["location"]
|
||||
ue.location_city = user_extension_params["location_city"]
|
||||
ue.identity = user_extension_params["identity"]
|
||||
ue.technical_title = user_extension_params["technical_title"]
|
||||
ue.student_id = user_extension_params["student_id"]
|
||||
ue.description = user_extension_params["description"]
|
||||
ue.save!
|
||||
u.save!
|
||||
|
||||
sync_params = {}
|
||||
|
||||
if (user_params["mail"] && user_params["mail"] != user_mail)
|
||||
sync_params = sync_params.merge(email: user_params["mail"])
|
||||
end
|
||||
|
||||
if sync_params.present?
|
||||
interactor = Gitea::User::UpdateInteractor.call(u.login, sync_params)
|
||||
if interactor.success?
|
||||
render_ok
|
||||
else
|
||||
render_error(interactor.error)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
tip_exception(-1, e.message)
|
||||
end
|
||||
|
||||
# 其他平台同步登录
|
||||
def remote_login
|
||||
@user = User.try_to_login(params[:login], params[:password])
|
||||
if @user
|
||||
successful_authentication(@user)
|
||||
render_ok({user: {id: @user.id, token: @user.gitea_token}})
|
||||
else
|
||||
render_error("用户不存在")
|
||||
end
|
||||
end
|
||||
|
||||
#修改密码
|
||||
def remote_password
|
||||
@user = User.find_by(login: params[:login])
|
||||
return render_error("未找到相关用户!") if @user.blank?
|
||||
|
||||
sync_params = {
|
||||
password: params[:password].to_s,
|
||||
email: @user.mail
|
||||
}
|
||||
|
||||
interactor = Gitea::User::UpdateInteractor.call(@user.login, sync_params)
|
||||
if interactor.success?
|
||||
@user.update_attribute(:password, params[:password])
|
||||
render_ok
|
||||
else
|
||||
render_error(interactor.error)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
# 用户注册
|
||||
# 注意:用户注册需要兼顾本地版,本地版是不需要验证码及激活码以及使用授权的,注册完成即可使用
|
||||
# params[:login] 邮箱或者手机号
|
||||
# params[:namespace] 登录名
|
||||
# params[:code] 验证码
|
||||
# code_type 1:注册手机验证码 8:邮箱注册验证码
|
||||
# 本地forge注册入口需要重新更改逻辑
|
||||
def register
|
||||
# type只可能是1或者8
|
||||
user = nil
|
||||
begin
|
||||
Register::Form.new(register_params).validate!
|
||||
|
||||
user = Users::RegisterService.call(register_params)
|
||||
password = register_params[:password].strip
|
||||
|
||||
# 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.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
|
||||
end
|
||||
|
||||
# 用户登录
|
||||
def login
|
||||
Users::LoginForm.new(account_params).validate!
|
||||
@user = User.try_to_login(params[:login], params[:password])
|
||||
|
||||
return normal_status(-2, "错误的账号或密码") if @user.blank?
|
||||
# user is already in local database
|
||||
return normal_status(-2, "违反平台使用规范,账号已被锁定") if @user.locked?
|
||||
|
||||
login_control = LimitForbidControl::UserLogin.new(@user)
|
||||
return normal_status(-2, "登录密码出错已达上限,账号已被锁定, 请#{login_control.forbid_expires/60}分钟后重新登录或找回密码") if login_control.forbid?
|
||||
|
||||
password_ok = @user.check_password?(params[:password].to_s)
|
||||
unless password_ok
|
||||
if login_control.remain_times-1 == 0
|
||||
normal_status(-2, "登录密码出错已达上限,账号已被锁定, 请#{login_control.forbid_expires/60}分钟后重新登录或找回密码")
|
||||
else
|
||||
normal_status(-2, "你已经输错密码#{login_control.error_times+1}次,还剩余#{login_control.remain_times-1}次机会")
|
||||
end
|
||||
login_control.increment!
|
||||
return
|
||||
end
|
||||
|
||||
successful_authentication(@user)
|
||||
sync_pwd_to_gitea!(@user, {password: params[:password].to_s}) # TODO用户密码未同步
|
||||
|
||||
# session[:user_id] = @user.id
|
||||
end
|
||||
|
||||
def change_password
|
||||
@user = User.find_by(login: params[:login])
|
||||
return render_error("未找到相关用户!") if @user.blank?
|
||||
return render_error("旧密码不正确") unless @user.check_password?(params[:old_password])
|
||||
|
||||
sync_params = {
|
||||
password: params[:password].to_s,
|
||||
email: @user.mail,
|
||||
login_name: @user.login,
|
||||
source_id: 0
|
||||
}
|
||||
|
||||
interactor = Gitea::User::UpdateInteractor.call(@user.login, sync_params)
|
||||
if interactor.success?
|
||||
@user.update_attribute(:password, params[:password])
|
||||
render_ok
|
||||
else
|
||||
render_error(interactor.error)
|
||||
end
|
||||
end
|
||||
|
||||
# 忘记密码
|
||||
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
|
||||
|
||||
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
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
tip_exception(e.message)
|
||||
end
|
||||
end
|
||||
|
||||
def successful_authentication(user)
|
||||
uid_logger("Successful authentication start: '#{user.login}' from #{request.remote_ip} at #{Time.now.utc}")
|
||||
# Valid user
|
||||
self.logged_user = user
|
||||
# generate a key and set cookie if autologin
|
||||
|
||||
set_autologin_cookie(user)
|
||||
UserAction.create(:action_id => user.try(:id), :action_type => "Login", :user_id => user.try(:id), :ip => request.remote_ip)
|
||||
user.update_column(:last_login_on, Time.now)
|
||||
session[:"#{default_yun_session}"] = user.id
|
||||
Rails.logger.info("#########_____session_default_yun_session__________###############{default_yun_session}")
|
||||
# 注册完成后有一天的试用申请(先去掉)
|
||||
# UserDayCertification.create(user_id: user.id, status: 1)
|
||||
end
|
||||
|
||||
def set_autologin_cookie(user)
|
||||
token = Token.get_or_create_permanent_login_token(user, "autologin")
|
||||
sync_user_token_to_trustie(user.login, token.value)
|
||||
|
||||
cookie_options = {
|
||||
:value => token.value,
|
||||
:expires => 1.month.from_now,
|
||||
:path => '/',
|
||||
:secure => false,
|
||||
:httponly => true
|
||||
}
|
||||
if edu_setting('cookie_domain').present?
|
||||
cookie_options = cookie_options.merge(domain: edu_setting('cookie_domain'))
|
||||
end
|
||||
cookies[autologin_cookie_name] = cookie_options
|
||||
cookies.signed[:user_id] ||= user.id
|
||||
|
||||
logger.info("cookies is #{cookies} ======> #{cookies.signed[:user_id]} =====> #{cookies[autologin_cookie_name]}")
|
||||
end
|
||||
|
||||
def logout
|
||||
Rails.logger.info("########___logout_current_user____________########{current_user.try(:id)}")
|
||||
UserAction.create(action_id: User.current.id, action_type: "Logout", user_id: User.current.id, :ip => request.remote_ip)
|
||||
logout_user
|
||||
render :json => {status: 1, message: "退出成功!"}
|
||||
end
|
||||
|
||||
# 检验邮箱是否已被注册及邮箱或者手机号是否合法
|
||||
# 参数type为事件类型 1:注册;2:忘记密码;3:绑定
|
||||
def valid_email_and_phone
|
||||
check_mail_and_phone_valid(params[:login], params[:type])
|
||||
end
|
||||
|
||||
# 发送验证码
|
||||
# params[:login] 手机号或者邮箱号
|
||||
# params[:type]为事件通知类型 1:用户注册 2:忘记密码 3: 绑定手机 4: 绑定邮箱, 5: 验收手机号有效 # 如果有新的继续后面加
|
||||
# 发送验证码:send_type 1:注册手机验证码 2:找回密码手机验证码 3:找回密码邮箱验证码 4:绑定手机 5:绑定邮箱
|
||||
# 6:手机验证码登录 7:邮箱验证码登录 8:邮箱注册验证码 9: 验收手机号有效
|
||||
def get_verification_code
|
||||
code = %W(0 1 2 3 4 5 6 7 8 9)
|
||||
value = params[:login]
|
||||
type = params[:type].strip.to_i
|
||||
login_type = phone_mail_type(value)
|
||||
send_type = verify_type(login_type, type)
|
||||
verification_code = code.sample(6).join
|
||||
|
||||
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)
|
||||
render_ok
|
||||
end
|
||||
|
||||
# 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
|
||||
|
||||
def login_check
|
||||
Register::LoginCheckColumnsForm.new(check_params.merge(user: current_user)).validate!
|
||||
render_ok
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# type 事件类型 1:用户注册 2:忘记密码 3: 绑定手机 4: 绑定邮箱, 5: 验证手机号是否有效 # 如果有新的继续后面加
|
||||
# login_type 1:手机类型 2:邮箱类型
|
||||
def verify_type login_type, type
|
||||
case type
|
||||
when 1
|
||||
login_type == 1 ? 1 : 8
|
||||
when 2
|
||||
login_type == 1 ? 2 : 3
|
||||
when 3
|
||||
login_type == 1 ? 4 : tip_exception('请填写正确的手机号')
|
||||
when 4
|
||||
login_type == 1 ? tip_exception('请填写正确的邮箱') : 5
|
||||
when 5
|
||||
login_type == 1 ? 9 : tip_exception('请填写正确的手机号')
|
||||
end
|
||||
end
|
||||
|
||||
def generate_login(login)
|
||||
type = phone_mail_type(login.strip)
|
||||
|
||||
if type == 1
|
||||
uid_logger("start register by phone: type is #{type}")
|
||||
pre = 'p'
|
||||
email = nil
|
||||
phone = login
|
||||
else
|
||||
uid_logger("start register by email: type is #{type}")
|
||||
pre = 'm'
|
||||
email = login
|
||||
phone = nil
|
||||
end
|
||||
code = generate_identifier User, 8, pre
|
||||
|
||||
{ login: pre + code, email: email, phone: phone }
|
||||
end
|
||||
|
||||
def user_params
|
||||
params.require(:user).permit(:login, :email, :phone)
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
def remote_register_params
|
||||
params.permit(:username, :email, :password, :platform)
|
||||
end
|
||||
|
||||
def simple_update_params
|
||||
params.permit(:username, :email, :password, :platform)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ class Admins::ImportUsersController < Admins::BaseController
|
|||
def create
|
||||
return render_error('请上传正确的文件') if params[:file].blank? || !params[:file].is_a?(ActionDispatch::Http::UploadedFile)
|
||||
|
||||
result = Admins::ImportUserService.call(params[:file].to_io)
|
||||
result = Admins::ImportUserFromExcelService.call(params[:file].to_io)
|
||||
render_ok(result)
|
||||
rescue Admins::ImportUserService::Error => ex
|
||||
render_error(ex)
|
||||
|
|
|
|||
|
|
@ -217,7 +217,7 @@ class AttachmentsController < ApplicationController
|
|||
if @file.container && current_user.logged?
|
||||
if @file.container.is_a?(Issue)
|
||||
course = @file.container.project
|
||||
candown = course.member?(current_user)
|
||||
candown = course.member?(current_user) || course.is_public
|
||||
elsif @file.container.is_a?(Journal)
|
||||
course = @file.container.issue.project
|
||||
candown = course.member?(current_user)
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ class Ci::BaseController < ApplicationController
|
|||
namespace = params[:owner]
|
||||
id = params[:repo] || params[:id]
|
||||
|
||||
@ci_user, @repo = Ci::Repo.find_with_namespace(namespace, id)
|
||||
@ci_user, @repo = Ci::Repo.find_with_namespace(namespace, id, current_user.login)
|
||||
end
|
||||
|
||||
def load_all_repo
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ class Ci::SecretsController < Ci::BaseController
|
|||
end
|
||||
|
||||
def ci_drone_url
|
||||
user = User.find_by(login: params[:owner])
|
||||
user = User.find_by(login: params[:owner]) || User.find_by(login: current_user.login)
|
||||
user&.ci_cloud_account.drone_url
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,10 @@ class CompareController < ApplicationController
|
|||
load_compare_params
|
||||
compare
|
||||
@merge_status, @merge_message = get_merge_message
|
||||
@page_size = page_size <= 0 ? 1 : page_size
|
||||
@page_limit = page_limit <=0 ? 15 : page_limit
|
||||
@page_offset = (@page_size -1) * @page_limit
|
||||
Rails.logger.info("+========#{@page_size}-#{@page_limit}-#{@page_offset}")
|
||||
end
|
||||
|
||||
private
|
||||
|
|
@ -16,6 +20,7 @@ class CompareController < ApplicationController
|
|||
if @base.blank? || @head.blank?
|
||||
return -2, "请选择分支"
|
||||
else
|
||||
return -2, "目标仓库未开启合并请求(PR)功能" unless @project.has_menu_permission("pulls")
|
||||
if @head.include?(":")
|
||||
fork_project = @project.forked_projects.joins(:owner).where(users: {login: @head.to_s.split("/")[0]}).take
|
||||
return -2, "请选择正确的仓库" unless fork_project.present?
|
||||
|
|
@ -50,6 +55,14 @@ class CompareController < ApplicationController
|
|||
end
|
||||
|
||||
def gitea_compare(base, head)
|
||||
Gitea::Repository::Commits::CompareService.call(@owner.login, @project.identifier, CGI.escape(base), CGI.escape(head), current_user.gitea_token)
|
||||
Gitea::Repository::Commits::CompareService.call(@owner.login, @project.identifier, Addressable::URI.escape(base), Addressable::URI.escape(head), current_user.gitea_token)
|
||||
end
|
||||
|
||||
def page_size
|
||||
params.fetch(:page, 1).to_i
|
||||
end
|
||||
|
||||
def page_limit
|
||||
params.fetch(:limit, 15).to_i
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ module Ci::CloudAccountManageable
|
|||
|
||||
def drone_oauth_user!(url, state)
|
||||
logger.info "[drone] drone_oauth_user url: #{url}"
|
||||
conn = Faraday.new(url: url) do |req|
|
||||
conn = Faraday.new(url: "#{Gitea.gitea_config[:domain]}#{url}") do |req|
|
||||
req.request :url_encoded
|
||||
req.adapter Faraday.default_adapter
|
||||
req.headers["cookie"] = "_session_=#{SecureRandom.hex(28)}; _oauth_state_=#{state}"
|
||||
|
|
@ -188,7 +188,8 @@ module Ci::CloudAccountManageable
|
|||
response = conn.get
|
||||
logger.info "[drone] response headers: #{response.headers}"
|
||||
|
||||
response.headers['location'].include?('error') ? false : true
|
||||
true
|
||||
# response.headers['location'].include?('error') ? false : true
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
|||
|
|
@ -108,7 +108,11 @@ module LoginHelper
|
|||
def sync_pwd_to_gitea!(user, hash={})
|
||||
return true if user.is_sync_pwd?
|
||||
|
||||
sync_params = { email: user.mail }
|
||||
sync_params = {
|
||||
login_name: user.name,
|
||||
source_id: 0,
|
||||
email: user.mail
|
||||
}
|
||||
interactor = Gitea::User::UpdateInteractor.call(user.login, sync_params.merge(hash))
|
||||
if interactor.success?
|
||||
Rails.logger.info "########_ login is #{user.login} sync_pwd_to_gitea success _########"
|
||||
|
|
|
|||
|
|
@ -27,4 +27,32 @@ module RegisterHelper
|
|||
result
|
||||
end
|
||||
|
||||
def auto_update(user, params={})
|
||||
return if params.blank?
|
||||
result = {message: nil, user: nil}
|
||||
before_login = user.login
|
||||
user.login = params[:username]
|
||||
user.password = params[:password]
|
||||
user.mail = params[:email]
|
||||
|
||||
if user.save!
|
||||
sync_params = {
|
||||
password: params[:password].to_s,
|
||||
email: params[:email],
|
||||
login_name: params[:username],
|
||||
new_name: params[:username],
|
||||
source_id: 0
|
||||
}
|
||||
|
||||
interactor = Gitea::User::UpdateInteractor.call(before_login, sync_params)
|
||||
if interactor.success?
|
||||
result[:user] = user
|
||||
else
|
||||
result[:message] = '用户同步Gitea失败!'
|
||||
end
|
||||
else
|
||||
result[:message] = user.errors.full_messages.join(",")
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ module RenderHelper
|
|||
render json: { status: 0, message: 'success' }.merge(data)
|
||||
end
|
||||
|
||||
def render_error(status = -1, message = '')
|
||||
def render_error(message = '', status=-1)
|
||||
render json: { status: status, message: message }
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -24,13 +24,13 @@ class IssuesController < ApplicationController
|
|||
@filter_issues = @all_issues
|
||||
@filter_issues = @filter_issues.where.not(status_id: IssueStatus::CLOSED) if params[:status_type].to_i == IssueStatus::ADD
|
||||
@filter_issues = @filter_issues.where(status_id: IssueStatus::CLOSED) if params[:status_type].to_i == IssueStatus::SOLVING
|
||||
@filter_issues = @filter_issues.where("subject LIKE ? OR description LIKE ? ", "%#{params[:search]}%", "%#{params[:search]}%") if params[:search].present?
|
||||
@filter_issues = @filter_issues.where("issues.subject LIKE ? OR issues.description LIKE ? ", "%#{params[:search]}%", "%#{params[:search]}%") if params[:search].present?
|
||||
@open_issues = @all_issues.where.not(status_id: IssueStatus::CLOSED)
|
||||
@close_issues = @all_issues.where(status_id: IssueStatus::CLOSED)
|
||||
@assign_to_me = @filter_issues.where(assigned_to_id: current_user&.id)
|
||||
@my_published = @filter_issues.where(author_id: current_user&.id)
|
||||
scopes = Issues::ListQueryService.call(issues,params.delete_if{|k,v| v.blank?}, "Issue")
|
||||
@issues_size = scopes.size
|
||||
@assign_to_me = scopes.where(assigned_to_id: current_user&.id)
|
||||
@my_published = scopes.where(author_id: current_user&.id)
|
||||
@issues = paginate(scopes)
|
||||
|
||||
respond_to do |format|
|
||||
|
|
@ -109,7 +109,7 @@ class IssuesController < ApplicationController
|
|||
|
||||
def create
|
||||
issue_params = issue_send_params(params)
|
||||
Issues::CreateForm.new({subject:issue_params[:subject]}).validate!
|
||||
Issues::CreateForm.new({subject: issue_params[:subject], description: issue_params[:description].blank? ? issue_params[:description] : issue_params[:description].b}).validate!
|
||||
@issue = Issue.new(issue_params)
|
||||
if @issue.save!
|
||||
SendTemplateMessageJob.perform_later('IssueAssigned', current_user.id, @issue&.id) if Site.has_notice_menu?
|
||||
|
|
@ -149,6 +149,8 @@ class IssuesController < ApplicationController
|
|||
end
|
||||
|
||||
@issue.project_trends.create(user_id: current_user.id, project_id: @project.id, action_type: "create")
|
||||
@issue.project_trends.create(user_id: current_user.id, project_id: @project.id, action_type: ProjectTrend::CLOSE) if params[:status_id].to_i == 5
|
||||
|
||||
|
||||
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
|
||||
|
|
@ -178,6 +180,7 @@ class IssuesController < ApplicationController
|
|||
elsif params[:issue_tag_ids].is_a?(Array) && params[:issue_tag_ids].size == 1
|
||||
@issue&.issue_tags_relates&.destroy_all
|
||||
params[:issue_tag_ids].each do |tag|
|
||||
next if tag == [""]
|
||||
IssueTagsRelate.create!(issue_id: @issue.id, issue_tag_id: tag)
|
||||
end
|
||||
else
|
||||
|
|
@ -220,7 +223,7 @@ class IssuesController < ApplicationController
|
|||
normal_status(-1, "不允许修改为关闭状态")
|
||||
else
|
||||
issue_params = issue_send_params(params).except(:issue_classify, :author_id, :project_id)
|
||||
Issues::UpdateForm.new({subject:issue_params[:subject]}).validate!
|
||||
Issues::UpdateForm.new({subject: issue_params[:subject], description: issue_params[:description].blank? ? issue_params[:description] : issue_params[:description].b}).validate!
|
||||
if @issue.update_attributes(issue_params)
|
||||
if @issue&.pull_request.present?
|
||||
SendTemplateMessageJob.perform_later('PullRequestChanged', current_user.id, @issue&.pull_request&.id, @issue.previous_changes.slice(:assigned_to_id, :priority_id, :fixed_version_id, :issue_tags_value)) if Site.has_notice_menu?
|
||||
|
|
@ -244,7 +247,7 @@ class IssuesController < ApplicationController
|
|||
end
|
||||
if params[:status_id].to_i == 5 #任务由非关闭状态到关闭状态时
|
||||
@issue.issue_times.update_all(end_time: Time.now)
|
||||
@issue.update_closed_issues_count_in_project!
|
||||
# @issue.update_closed_issues_count_in_project!
|
||||
if @issue.issue_type.to_s == "2" && last_status_id != 5
|
||||
if @issue.assigned_to_id.present? && last_status_id == 3 #只有当用户完成100%时,才给token
|
||||
post_to_chain("add", @issue.token, @issue.get_assign_user.try(:login))
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ class JournalsController < ApplicationController
|
|||
normal_status(-1, "评论内容不能为空")
|
||||
else
|
||||
ActiveRecord::Base.transaction do
|
||||
Journals::CreateForm.new({notes: notes.to_s.strip.blank? ? notes.to_s.strip : notes.to_s.strip.b}).validate!
|
||||
journal_params = {
|
||||
journalized_id: @issue.id ,
|
||||
journalized_type: "Issue",
|
||||
|
|
@ -53,6 +54,9 @@ class JournalsController < ApplicationController
|
|||
end
|
||||
end
|
||||
end
|
||||
rescue Exception => exception
|
||||
puts exception.message
|
||||
normal_status(-1, exception.message)
|
||||
end
|
||||
|
||||
def destroy
|
||||
|
|
@ -70,7 +74,8 @@ class JournalsController < ApplicationController
|
|||
|
||||
def update
|
||||
content = params[:content]
|
||||
if content.present?
|
||||
if content.present?
|
||||
Journals::UpdateForm.new({notes: notes.to_s.strip.blank? ? notes.to_s.strip : notes.to_s.strip.b}).validate!
|
||||
if @journal.update_attribute(:notes, content)
|
||||
normal_status(0, "更新成功")
|
||||
else
|
||||
|
|
@ -79,7 +84,9 @@ class JournalsController < ApplicationController
|
|||
else
|
||||
normal_status(-1, "评论的内容不能为空")
|
||||
end
|
||||
|
||||
rescue Exception => exception
|
||||
puts exception.message
|
||||
normal_status(-1, exception.message)
|
||||
end
|
||||
|
||||
def get_children_journals
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
class NoticesController < ApplicationController
|
||||
|
||||
def create
|
||||
tip_exception("参数有误") if params["source"].blank?
|
||||
user_id = params[:user_id]
|
||||
|
||||
if params["source"] == "CompetitionBegin"
|
||||
competition_id = params[:competition_id]
|
||||
SendTemplateMessageJob.perform_later('CompetitionBegin', user_id, competition_id)
|
||||
elsif params["source"] == "CompetitionResult"
|
||||
competition_id = params[:competition_id]
|
||||
SendTemplateMessageJob.perform_later('CompetitionResult', user_id, competition_id)
|
||||
elsif params["source"] == "CompetitionReview"
|
||||
competition_id = params[:competition_id]
|
||||
SendTemplateMessageJob.perform_later('CompetitionReview', user_id, competition_id)
|
||||
else
|
||||
tip_exception("#{params["source"]}未配置")
|
||||
end
|
||||
render_ok
|
||||
end
|
||||
end
|
||||
|
|
@ -5,7 +5,11 @@ class Organizations::OrganizationUsersController < Organizations::BaseController
|
|||
def index
|
||||
@organization_users = @organization.organization_users.includes(:user)
|
||||
search = params[:search].to_s.downcase
|
||||
@organization_users = @organization_users.joins(:user).merge(User.like(search))
|
||||
user_condition_users = User.like(search).to_sql
|
||||
team_condition_teams = User.joins(:teams).merge(@organization.teams.like(search)).to_sql
|
||||
users = User.from("( #{user_condition_users} UNION #{team_condition_teams }) AS users")
|
||||
|
||||
@organization_users = @organization_users.where(user_id: users).distinct
|
||||
|
||||
@organization_users = kaminari_paginate(@organization_users)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ class Organizations::TeamsController < Organizations::BaseController
|
|||
def create
|
||||
ActiveRecord::Base.transaction do
|
||||
if @organization.teams.count >= 50
|
||||
return render_forbidden("组织的团队数量已超过限制!")
|
||||
return tip_exception("组织的团队数量已超过限制!")
|
||||
else
|
||||
Organizations::CreateTeamForm.new(team_params).validate!
|
||||
@team = Organizations::Teams::CreateService.call(current_user, @organization, team_params)
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ class OwnersController < ApplicationController
|
|||
|
||||
def show
|
||||
@owner = Owner.find_by(login: params[:id]) || Owner.find_by(id: params[:id])
|
||||
# return render_not_found unless @owner.present?
|
||||
return render_not_found unless @owner.present?
|
||||
# 组织
|
||||
if @owner.is_a?(Organization)
|
||||
return render_forbidden("没有查看组织的权限") if org_limited_condition || org_privacy_condition
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ class PraiseTreadController < ApplicationController
|
|||
begin
|
||||
return normal_status(2, "你已点过赞了") if current_user.liked?(@project)
|
||||
current_user.like!(@project)
|
||||
SendTemplateMessageJob.perform_later('ProjectPraised', current_user.id, @project.id) if Site.has_notice_menu?
|
||||
render_ok({praises_count: @project.praises_count, praised: current_user.liked?(@project)})
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ class ProjectsController < ApplicationController
|
|||
def menu_list
|
||||
menu = []
|
||||
|
||||
user_is_admin = current_user.admin? || @project.manager?(current_user)
|
||||
|
||||
menu.append(menu_hash_by_name("home"))
|
||||
menu.append(menu_hash_by_name("code")) if @project.has_menu_permission("code")
|
||||
menu.append(menu_hash_by_name("issues")) if @project.has_menu_permission("issues")
|
||||
|
|
@ -22,7 +24,8 @@ class ProjectsController < ApplicationController
|
|||
menu.append(menu_hash_by_name("wiki")) if @project.has_menu_permission("wiki") && @project.forge?
|
||||
menu.append(menu_hash_by_name("resources")) if @project.has_menu_permission("resources") && @project.forge?
|
||||
menu.append(menu_hash_by_name("activity"))
|
||||
menu.append(menu_hash_by_name("settings")) if (current_user.admin? || @project.manager?(current_user)) && @project.forge?
|
||||
menu.append(menu_hash_by_name("settings")) if user_is_admin && @project.forge?
|
||||
menu.append(menu_hash_by_name("quit")) if !user_is_admin && @project.member(current_user.id) && @project.forge?
|
||||
|
||||
render json: menu
|
||||
end
|
||||
|
|
@ -59,7 +62,7 @@ class ProjectsController < ApplicationController
|
|||
Projects::MigrateForm.new(mirror_params).validate!
|
||||
|
||||
@project =
|
||||
if enable_accelerator?(mirror_params[:clone_addr])
|
||||
if EduSetting.get("mirror_address").to_s.include?("github") && enable_accelerator?(mirror_params[:clone_addr])
|
||||
source_clone_url = mirror_params[:clone_addr]
|
||||
uid_logger("########## 已动加速器 ##########")
|
||||
result = Gitea::Accelerator::MigrateService.call(mirror_params)
|
||||
|
|
@ -71,6 +74,11 @@ class ProjectsController < ApplicationController
|
|||
else
|
||||
Projects::MigrateService.call(current_user, mirror_params)
|
||||
end
|
||||
elsif EduSetting.get("mirror_address").to_s.include?("cnpmjs") && mirror_params[:clone_addr].include?("github.com")
|
||||
source_clone_url = mirror_params[:clone_addr]
|
||||
clone_url = source_clone_url.gsub('github.com', 'github.com.cnpmjs.org')
|
||||
uid_logger("########## 更改clone_addr ##########")
|
||||
Projects::MigrateService.call(current_user, mirror_params.merge(source_clone_url: source_clone_url, clone_addr: clone_url))
|
||||
else
|
||||
Projects::MigrateService.call(current_user, mirror_params)
|
||||
end
|
||||
|
|
@ -83,7 +91,7 @@ class ProjectsController < ApplicationController
|
|||
return @branches = [] unless @project.forge?
|
||||
|
||||
# result = Gitea::Repository::Branches::ListService.call(@owner, @project.identifier)
|
||||
result = Gitea::Repository::Branches::ListNameService.call(@owner, @project.identifier)
|
||||
result = Gitea::Repository::Branches::ListNameService.call(@owner, @project.identifier, params[:name])
|
||||
@branches = result.is_a?(Hash) ? (result.key?(:status) ? [] : result["branch_name"]) : result
|
||||
end
|
||||
|
||||
|
|
@ -130,7 +138,7 @@ class ProjectsController < ApplicationController
|
|||
validate_params = project_params.slice(:name, :description,
|
||||
:project_category_id, :project_language_id, :private, :identifier)
|
||||
|
||||
Projects::UpdateForm.new(validate_params.merge(user_id: @project.user_id, project_identifier: @project.identifier)).validate!
|
||||
Projects::UpdateForm.new(validate_params.merge(user_id: @project.user_id, project_identifier: @project.identifier, project_name: @project.name)).validate!
|
||||
|
||||
private = @project.forked_from_project.present? ? !@project.forked_from_project.is_public : params[:private] || false
|
||||
|
||||
|
|
@ -172,6 +180,22 @@ class ProjectsController < ApplicationController
|
|||
tip_exception(e.message)
|
||||
end
|
||||
|
||||
def quit
|
||||
user_is_admin = current_user.admin? || @project.manager?(current_user)
|
||||
if !user_is_admin && @project.member(current_user.id) && @project.forge?
|
||||
ActiveRecord::Base.transaction do
|
||||
Projects::DeleteMemberInteractor.call(@project.owner, @project, current_user)
|
||||
SendTemplateMessageJob.perform_later('ProjectMemberLeft', current_user.id, current_user.id, @project.id) if Site.has_notice_menu?
|
||||
render_ok
|
||||
end
|
||||
else
|
||||
render_forbidden('你不能退出该仓库')
|
||||
end
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
tip_exception(e.message)
|
||||
end
|
||||
|
||||
def watch_users
|
||||
watchers = @project.watchers.includes(:user).order("watchers.created_at desc").distinct
|
||||
@watchers_count = watchers.size
|
||||
|
|
@ -185,7 +209,7 @@ class ProjectsController < ApplicationController
|
|||
end
|
||||
|
||||
def fork_users
|
||||
fork_users = @project.fork_users.includes(:user, :project, :fork_project).order("fork_users.created_at desc").distinct
|
||||
fork_users = @project.fork_users.includes(:owner, :project, :fork_project).order("fork_users.created_at desc").distinct
|
||||
@forks_count = fork_users.size
|
||||
@fork_users = paginate(fork_users)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ class PullRequestsController < ApplicationController
|
|||
before_action :require_login, except: [:index, :show, :files, :commits]
|
||||
before_action :require_profile_completed, only: [:create]
|
||||
before_action :load_repository
|
||||
before_action :check_menu_authorize
|
||||
before_action :check_menu_authorize, only: [:index, :show, :create, :update, :refuse_merge, :pr_merge]
|
||||
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]
|
||||
|
|
@ -16,7 +16,7 @@ class PullRequestsController < ApplicationController
|
|||
issues = issues.where(is_private: false) unless current_user.present? && (current_user.admin? || @project.member?(current_user))
|
||||
@all_issues = issues.distinct
|
||||
@filter_issues = @all_issues
|
||||
@filter_issues = @filter_issues.where("subject LIKE ? OR description LIKE ? ", "%#{params[:search]}%", "%#{params[:search]}%") if params[:search].present?
|
||||
@filter_issues = @filter_issues.where("issues.subject LIKE ? OR issues.description LIKE ? ", "%#{params[:search]}%", "%#{params[:search]}%") if params[:search].present?
|
||||
@open_issues = @filter_issues.joins(:pull_request).where(pull_requests: {status: PullRequest::OPEN})
|
||||
@close_issues = @filter_issues.joins(:pull_request).where(pull_requests: {status: PullRequest::CLOSED})
|
||||
@merged_issues = @filter_issues.joins(:pull_request).where(pull_requests: {status: PullRequest::MERGED})
|
||||
|
|
@ -29,7 +29,7 @@ class PullRequestsController < ApplicationController
|
|||
end
|
||||
|
||||
def new
|
||||
@all_branches = Branches::ListService.call(@owner, @project)
|
||||
@all_branches = Branches::ListService.call(@owner, @project, params[:branch_name])
|
||||
@is_fork = @project.forked_from_project_id.present?
|
||||
@projects_names = [{
|
||||
project_user_login: @owner.try(:login),
|
||||
|
|
@ -50,7 +50,7 @@ class PullRequestsController < ApplicationController
|
|||
end
|
||||
|
||||
def get_branches
|
||||
branch_result = Branches::ListService.call(@owner, @project)
|
||||
branch_result = Branches::ListService.call(@owner, @project, params[:name])
|
||||
render json: branch_result
|
||||
# return json: branch_result
|
||||
end
|
||||
|
|
@ -58,6 +58,7 @@ class PullRequestsController < ApplicationController
|
|||
def create
|
||||
# return normal_status(-1, "您不是目标分支开发者,没有权限,请联系目标分支作者.") unless @project.operator?(current_user)
|
||||
ActiveRecord::Base.transaction do
|
||||
Issues::CreateForm.new({subject: params[:title], description: params[:body].blank? ? params[:body] : params[:body].b}).validate!
|
||||
@pull_request, @gitea_pull_request = PullRequests::CreateService.call(current_user, @owner, @project, params)
|
||||
if @gitea_pull_request[:status] == :success
|
||||
@pull_request.bind_gitea_pull_request!(@gitea_pull_request[:body]["number"], @gitea_pull_request[:body]["id"])
|
||||
|
|
@ -89,7 +90,7 @@ class PullRequestsController < ApplicationController
|
|||
else
|
||||
ActiveRecord::Base.transaction do
|
||||
begin
|
||||
return normal_status(-1, "title不能超过255个字符") if params[:title].length > 255
|
||||
Issues::UpdateForm.new({subject: params[:title], description: params[:body].blank? ? params[:body] : params[:body].b}).validate!
|
||||
merge_params
|
||||
|
||||
@issue&.issue_tags_relates&.destroy_all if params[:issue_tag_ids].blank?
|
||||
|
|
@ -274,12 +275,12 @@ class PullRequestsController < ApplicationController
|
|||
base: params[:base], #目标分支
|
||||
milestone: 0, #里程碑,未与本地的里程碑关联
|
||||
}
|
||||
assignee_login = User.find_by_id(params[:assigned_to_id])&.login
|
||||
@requests_params = @local_params.merge({
|
||||
assignee: current_user.try(:login),
|
||||
# assignees: ["#{params[:assigned_login].to_s}"],
|
||||
assignees: ["#{current_user.try(:login).to_s}"],
|
||||
labels: params[:issue_tag_ids],
|
||||
due_date: Time.now
|
||||
assignees: ["#{assignee_login.to_s}"],
|
||||
labels: params[:issue_tag_ids]
|
||||
# due_date: Time.now
|
||||
})
|
||||
@issue_params = {
|
||||
author_id: current_user.id,
|
||||
|
|
|
|||
|
|
@ -150,8 +150,11 @@ class RepositoriesController < ApplicationController
|
|||
if params[:filepath].present? || @project.educoder?
|
||||
@contributors = []
|
||||
else
|
||||
@contributors = Gitea::Repository::Contributors::GetService.call(@owner, @repository.identifier)
|
||||
result = Gitea::Repository::Contributors::GetService.call(@owner, @repository.identifier)
|
||||
@contributors = result.is_a?(Hash) && result.key?(:status) ? [] : result
|
||||
end
|
||||
rescue
|
||||
@contributors = []
|
||||
end
|
||||
|
||||
def edit
|
||||
|
|
@ -222,7 +225,8 @@ class RepositoriesController < ApplicationController
|
|||
@path = Gitea.gitea_config[:domain]+"/#{@owner.login}/#{@repository.identifier}/raw/branch/#{params[:ref]}/"
|
||||
@readme = result[:status] === :success ? result[:body] : nil
|
||||
@readme['content'] = decode64_content(@readme, @owner, @repository, params[:ref], @path)
|
||||
render json: @readme.slice("type", "encoding", "size", "name", "path", "content", "sha")
|
||||
@readme['replace_content'] = readme_decode64_content(@readme, @owner, @repository, params[:ref], @path)
|
||||
render json: @readme.slice("type", "encoding", "size", "name", "path", "content", "sha", "replace_content")
|
||||
rescue
|
||||
render json: nil
|
||||
end
|
||||
|
|
@ -238,7 +242,7 @@ class RepositoriesController < ApplicationController
|
|||
def archive
|
||||
domain = Gitea.gitea_config[:domain]
|
||||
api_url = Gitea.gitea_config[:base_url]
|
||||
archive_url = "/repos/#{@owner.login}/#{@repository.identifier}/archive/#{CGI.escape(params[:archive])}"
|
||||
archive_url = "/repos/#{@owner.login}/#{@repository.identifier}/archive/#{Addressable::URI.escape(params[:archive])}"
|
||||
|
||||
file_path = [domain, api_url, archive_url].join
|
||||
file_path = [file_path, "access_token=#{current_user&.gitea_token}"].join("?") if @repository.hidden?
|
||||
|
|
@ -252,7 +256,7 @@ class RepositoriesController < ApplicationController
|
|||
domain = Gitea.gitea_config[:domain]
|
||||
api_url = Gitea.gitea_config[:base_url]
|
||||
|
||||
url = "/repos/#{@owner.login}/#{@repository.identifier}/raw/#{CGI.escape(params[:filepath])}?ref=#{CGI.escape(params[:ref])}"
|
||||
url = "/repos/#{@owner.login}/#{@repository.identifier}/raw/#{Addressable::URI.escape(params[:filepath])}?ref=#{Addressable::URI.escape(params[:ref])}"
|
||||
file_path = [domain, api_url, url].join
|
||||
file_path = [file_path, "access_token=#{current_user&.gitea_token}"].join("&")
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
class SettingsController < ApplicationController
|
||||
def show
|
||||
@old_projects_url = nil
|
||||
get_navbar
|
||||
get_add_menu
|
||||
get_common_menu
|
||||
get_personal_menu
|
||||
|
|
@ -8,6 +9,14 @@ class SettingsController < ApplicationController
|
|||
end
|
||||
|
||||
private
|
||||
def get_navbar
|
||||
@navbar = default_laboratory.navbar
|
||||
if User.current.logged?
|
||||
pernal_index = {"name"=>"个人主页", "link"=>get_site_url("url", "#{Rails.application.config_for(:configuration)['platform_url']}/current_user"), "hidden"=>false}
|
||||
@navbar << pernal_index
|
||||
end
|
||||
end
|
||||
|
||||
def get_add_menu
|
||||
@add = []
|
||||
Site.add.select(:id, :name, :url, :key).to_a.map(&:serializable_hash).each do |site|
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ class Users::StatisticsController < Users::BaseController
|
|||
@commit_data = []
|
||||
date_range.each do |date|
|
||||
@date_data << date.strftime("%Y.%m.%d")
|
||||
@issue_data << observed_user.issues.where("DATE(created_on) = ?", date).size
|
||||
@issue_data << observed_user.issues.issue_issue.where("DATE(created_on) = ?", date).size
|
||||
@pull_request_data << observed_user.pull_requests.where("DATE(created_at) = ?", date).size
|
||||
date_commit_data = commit_data.blank? ? nil : commit_data.select{|item| item["timestamp"] == date.to_time.to_i}
|
||||
@commit_data << (date_commit_data.blank? ? 0 : date_commit_data[0]["contributions"].to_i)
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@ class Users::TemplateMessageSettingsController < Users::BaseController
|
|||
def get_current_setting
|
||||
@current_setting = @_observed_user.user_template_message_setting
|
||||
@current_setting = UserTemplateMessageSetting.build(@_observed_user.id) if @current_setting.nil?
|
||||
@current_setting.notification_body.merge!(UserTemplateMessageSetting.init_notification_body.except(*@current_setting.notification_body.keys))
|
||||
@current_setting.email_body.merge!(UserTemplateMessageSetting.init_email_body.except(*@current_setting.email_body.keys))
|
||||
end
|
||||
|
||||
def setting_params
|
||||
|
|
|
|||
|
|
@ -97,6 +97,13 @@ class UsersController < ApplicationController
|
|||
render_error(-1, '头像修改失败!')
|
||||
end
|
||||
|
||||
def get_image
|
||||
return render_not_found unless @user = User.find_by(login: params[:id]) || User.find_by_id(params[:id])
|
||||
return render_forbidden unless User.current.logged? && (current_user&.admin? || current_user.id == @user.id)
|
||||
|
||||
redirect_to Rails.application.config_for(:configuration)['platform_url'] + "/" + url_to_avatar(@user).to_s
|
||||
end
|
||||
|
||||
def me
|
||||
@user = current_user
|
||||
end
|
||||
|
|
@ -294,6 +301,11 @@ class UsersController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
def email_search
|
||||
return render_error('请输入email') if params[:email].blank?
|
||||
@user = User.find_by(mail: params[:email])
|
||||
end
|
||||
|
||||
private
|
||||
def load_user
|
||||
@user = User.find_by_login(params[:id]) || User.find_by(id: params[:id])
|
||||
|
|
@ -306,6 +318,7 @@ class UsersController < ApplicationController
|
|||
:occupation, :technical_title,
|
||||
:school_id, :department_id, :province, :city,
|
||||
:custom_department, :identity, :student_id, :description,
|
||||
:show_super_description, :super_description,
|
||||
:show_email, :show_location, :show_department]
|
||||
)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ class VersionReleasesController < ApplicationController
|
|||
def new
|
||||
#获取所有的分支
|
||||
@all_branches = []
|
||||
get_all_branches = Gitea::Repository::Branches::ListService.new(@user, @repository.try(:identifier)).call
|
||||
get_all_branches = Gitea::Repository::Branches::ListService.new(@user, @repository.try(:identifier), params[:branch_name]).call
|
||||
if get_all_branches && get_all_branches.size > 0
|
||||
get_all_branches.each do |b|
|
||||
@all_branches.push(b["name"])
|
||||
|
|
|
|||
|
|
@ -91,10 +91,9 @@ await octokit.request('GET /api/users/:login/messages.json')
|
|||
类型|说明
|
||||
--------- | -----------
|
||||
|IssueAssigned | 有新指派给我的疑修 |
|
||||
|IssueAssignerExpire | 我负责的疑修截止日期到达最后一天 |
|
||||
|IssueExpire | 我创建或负责的疑修截止日期到达最后一天 |
|
||||
|IssueAtme | 在疑修中@我 |
|
||||
|IssueChanged | 我创建或负责的疑修状态变更 |
|
||||
|IssueCreatorExpire | 我创建的疑修截止日期到达最后一天 |
|
||||
|IssueDeleted | 我创建或负责的疑修删除 |
|
||||
|IssueJournal | 我创建或负责的疑修有新的评论 |
|
||||
|LoginIpTip | 登录异常提示 |
|
||||
|
|
@ -109,6 +108,7 @@ await octokit.request('GET /api/users/:login/messages.json')
|
|||
|ProjectLeft | 账号被移出项目 |
|
||||
|ProjectMemberJoined | 我管理的仓库有成员加入 |
|
||||
|ProjectMemberLeft | 我管理的仓库有成员移出 |
|
||||
|ProjectMilestoneCompleted | 我管理的仓库有里程碑完成度100% |
|
||||
|ProjectMilestone | 我管理的仓库有新的里程碑 |
|
||||
|ProjectPraised | 我管理的仓库被点赞 |
|
||||
|ProjectPullRequest | 我管理/关注的仓库有新的合并请求 |
|
||||
|
|
|
|||
|
|
@ -50,4 +50,10 @@ class BaseForm
|
|||
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
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ class Gitea::User::UpdateForm
|
|||
|
||||
attr_accessor :username, :email, :admin, :allow_create_organization, :allow_git_hook, :allow_import_local,
|
||||
:full_name, :location, :login_name, :max_repo_creation, :must_change_password, :password, :prohibit_login,
|
||||
:source_id, :website
|
||||
:source_id, :website, :new_name
|
||||
|
||||
validates :username, presence: true
|
||||
validates :email, presence: true, format: { with: EMAIL_REGEX, multiline: true }
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
class Issues::CreateForm
|
||||
include ActiveModel::Model
|
||||
|
||||
attr_accessor :subject
|
||||
attr_accessor :subject, :description
|
||||
|
||||
validates :subject, presence: { message: "不能为空" }
|
||||
|
||||
validates :subject, length: { maximum: 200, too_long: "不能超过200个字符" }
|
||||
|
||||
|
||||
validates :description, length: { maximum: 65535, too_long: "不能超过65535个字符"}
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
class Issues::UpdateForm
|
||||
include ActiveModel::Model
|
||||
|
||||
attr_accessor :subject
|
||||
attr_accessor :subject, :description
|
||||
|
||||
validates :subject, presence: { message: "不能为空" }
|
||||
|
||||
validates :subject, length: { maximum: 200, too_long: "不能超过200个字符" }
|
||||
|
||||
validates :description, length: { maximum: 65535, too_long: "不能超过65535个字符"}
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
class Journals::CreateForm
|
||||
include ActiveModel::Model
|
||||
|
||||
attr_accessor :notes
|
||||
|
||||
validates :notes, length: { maximum: 65535, too_long: "不能超过65535个字符"}
|
||||
end
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
class Journals::UpdateForm
|
||||
include ActiveModel::Model
|
||||
|
||||
attr_accessor :notes
|
||||
|
||||
validates :notes, length: { maximum: 65535, too_long: "不能超过65535个字符"}
|
||||
|
||||
end
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
class Projects::UpdateForm < BaseForm
|
||||
attr_accessor :name, :description, :project_category_id, :project_language_id, :private, :identifier, :user_id, :project_identifier
|
||||
attr_accessor :name, :description, :project_category_id, :project_language_id, :private, :identifier, :user_id, :project_identifier, :project_name
|
||||
validates :name, presence: true
|
||||
validates :name, length: { maximum: 50 }
|
||||
validates :description, length: { maximum: 200 }
|
||||
|
|
@ -10,6 +10,7 @@ class Projects::UpdateForm < BaseForm
|
|||
check_project_language(project_language_id)
|
||||
|
||||
check_repository_name(user_id, identifier) unless identifier.blank? || identifier == project_identifier
|
||||
check_project_name(user_id, name) unless name.blank? || name == project_name
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -10,28 +10,40 @@ module Register
|
|||
VerifiCodeError = Class.new(Error)
|
||||
|
||||
private
|
||||
def check_login(login)
|
||||
def check_login(login, user=nil)
|
||||
login = strip(login)
|
||||
raise LoginError, "登录名格式有误" unless login =~ CustomRegexp::LOGIN
|
||||
|
||||
login_exist = Owner.exists?(login: login) || ReversedKeyword.check_exists?(login)
|
||||
raise LoginError, '登录名已被使用' if login_exist
|
||||
if user.present?
|
||||
raise LoginError, '登录名已被使用' if login_exist && login != user&.login
|
||||
else
|
||||
raise LoginError, '登录名已被使用' if login_exist
|
||||
end
|
||||
end
|
||||
|
||||
def check_mail(mail)
|
||||
def check_mail(mail, user=nil)
|
||||
mail = strip(mail)
|
||||
raise EmailError, "邮件格式有误" unless mail =~ CustomRegexp::EMAIL
|
||||
|
||||
mail_exist = Owner.exists?(mail: mail)
|
||||
raise EmailError, '邮箱已被使用' if mail_exist
|
||||
if user.present?
|
||||
raise EmailError, '邮箱已被使用' if mail_exist && mail != user&.mail
|
||||
else
|
||||
raise EmailError, '邮箱已被使用' if mail_exist
|
||||
end
|
||||
end
|
||||
|
||||
def check_phone(phone)
|
||||
def check_phone(phone, user=nil)
|
||||
phone = strip(phone)
|
||||
raise PhoneError, "手机号格式有误" unless phone =~ CustomRegexp::PHONE
|
||||
|
||||
phone_exist = Owner.exists?(phone: phone)
|
||||
raise PhoneError, '手机号已被使用' if phone_exist
|
||||
if user.present?
|
||||
raise PhoneError, '手机号已被使用' if phone_exist && phone != user&.phone
|
||||
else
|
||||
raise PhoneError, '手机号已被使用' if phone_exist
|
||||
end
|
||||
end
|
||||
|
||||
def check_password(password)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@ module Register
|
|||
|
||||
def check!
|
||||
Rails.logger.info "Register::Form params: code: #{code}; login: #{login}; namespace: #{namespace}; password: #{password}; type: #{type}"
|
||||
db_verifi_code =
|
||||
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
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
module Register
|
||||
class LoginCheckColumnsForm < Register::BaseForm
|
||||
attr_accessor :type, :value, :user
|
||||
|
||||
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), user)
|
||||
when 2 then check_mail(strip(value), user)
|
||||
when 3 then check_phone(strip(value), user)
|
||||
else raise("type值无效")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -147,6 +147,15 @@ module ApplicationHelper
|
|||
end
|
||||
end
|
||||
|
||||
def url_to_avatar_with_platform_url(source)
|
||||
platform_url = Rails.application.config_for(:configuration)['platform_url']
|
||||
if platform_url
|
||||
return Rails.application.config_for(:configuration)['platform_url'] + "/" + url_to_avatar(source).to_s
|
||||
else
|
||||
return url_to_avatar(source).to_s
|
||||
end
|
||||
end
|
||||
|
||||
# 主页banner图
|
||||
def banner_img(source_type)
|
||||
if File.exist?(disk_filename(source_type, "banner"))
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ module RepositoriesHelper
|
|||
|
||||
def download_type(str)
|
||||
default_type = %w(xlsx xls ppt pptx pdf zip 7z rar exe pdb obj idb RData rdata doc docx mpp vsdx dot otf eot ttf woff woff2 mp4 mov wmv flv mpeg avi avchd webm mkv)
|
||||
default_type.include?(str&.downcase)
|
||||
default_type.include?(str&.downcase) || str.blank?
|
||||
end
|
||||
|
||||
def image_type?(str)
|
||||
|
|
@ -22,7 +22,7 @@ module RepositoriesHelper
|
|||
def is_readme?(type, str)
|
||||
return false if type != 'file' || str.blank?
|
||||
readme_types = ["readme.md", "readme", "readme_en.md", "readme_zh.md", "readme_en", "readme_zh"]
|
||||
readme_types.include?(str.to_s.downcase)
|
||||
readme_types.include?(str.to_s.downcase) || str =~ CustomRegexp::MD_REGEX
|
||||
end
|
||||
|
||||
def render_commit_author(author_json)
|
||||
|
|
@ -36,7 +36,6 @@ module RepositoriesHelper
|
|||
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
|
||||
|
|
@ -57,6 +56,7 @@ module RepositoriesHelper
|
|||
total_images = ss + ss_src
|
||||
if total_images.length > 0
|
||||
total_images.each do |s|
|
||||
begin
|
||||
image_title = /\"(.*?)\"/
|
||||
r_content = s[0]
|
||||
remove_title = r_content.to_s.scan(image_title)
|
||||
|
|
@ -75,6 +75,9 @@ module RepositoriesHelper
|
|||
new_r_content = [base_url, "/api/#{owner&.login}/#{repo.identifier}/raw?filepath=#{r_content}&ref=#{ref}"].join
|
||||
end
|
||||
content = content.gsub(/#{r_content}/, new_r_content)
|
||||
rescue
|
||||
next
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -84,6 +87,46 @@ module RepositoriesHelper
|
|||
end
|
||||
end
|
||||
|
||||
# author hui.he
|
||||
def new_readme_render_decode64_content(str, owner, repo, ref, readme_path, readme_name)
|
||||
file_path = readme_path.include?('/') ? readme_path.gsub("/#{readme_name}", '') : readme_path.gsub("#{readme_name}", '')
|
||||
return nil if str.blank?
|
||||
content = Base64.decode64(str).force_encoding('UTF-8')
|
||||
s_regex = /\[.*?\]\((.*?)\)/
|
||||
src_regex = /src=\"(.*?)\"/
|
||||
ss = content.to_s.scan(s_regex)
|
||||
ss_src = content.to_s.scan(src_regex)
|
||||
total_sources = ss + ss_src
|
||||
total_sources.uniq!
|
||||
total_sources.each do |s|
|
||||
begin
|
||||
s_content = s[0]
|
||||
# 链接直接跳过不做替换
|
||||
next if s_content.starts_with?('http://') || s_content.starts_with?('https://') || s_content.starts_with?('mailto:') || s_content.blank?
|
||||
ext = File.extname(s_content)[1..-1]
|
||||
|
||||
if image_type?(ext) || download_type(ext)
|
||||
s_content = File.expand_path(s_content, file_path)
|
||||
s_content = s_content.split("#{Rails.root}/")[1]
|
||||
# content = content.gsub(s[0], "/#{s_content}")
|
||||
s_content = [base_url, "/api/#{owner&.login}/#{repo.identifier}/raw?filepath=#{s_content}&ref=#{ref}"].join
|
||||
content = content.gsub(s[0], s_content)
|
||||
else
|
||||
path = [owner&.login, repo&.identifier, 'tree', ref, file_path].join("/")
|
||||
s_content = File.expand_path(s_content, path)
|
||||
s_content = s_content.split("#{Rails.root}/")[1]
|
||||
content = content.gsub(s[0], "/#{s_content}")
|
||||
end
|
||||
rescue
|
||||
next
|
||||
end
|
||||
end
|
||||
|
||||
return content
|
||||
rescue
|
||||
return str
|
||||
end
|
||||
|
||||
# unix_time values for example: 1604382982
|
||||
def render_format_time_with_unix(unix_time)
|
||||
Time.at(unix_time).strftime("%Y-%m-%d %H:%M")
|
||||
|
|
@ -94,10 +137,21 @@ module RepositoriesHelper
|
|||
date.to_time.strftime("%Y-%m-%d %H:%M")
|
||||
end
|
||||
|
||||
def readme_decode64_content(entry, owner, repo, ref, path=nil)
|
||||
Rails.logger.info("entry===#{entry["type"]} #{entry["name"]}")
|
||||
content = Gitea::Repository::Entries::GetService.call(owner, repo.identifier, URI.escape(entry['path']), ref: ref)['content']
|
||||
Rails.logger.info("content===#{content}")
|
||||
# readme_render_decode64_content(content, owner, repo, ref)
|
||||
new_readme_render_decode64_content(content, owner, repo, ref, entry['path'], entry['name'])
|
||||
end
|
||||
|
||||
def decode64_content(entry, owner, repo, ref, path=nil)
|
||||
if is_readme?(entry['type'], entry['name'])
|
||||
Rails.logger.info("entry===#{entry["type"]} #{entry["name"]}")
|
||||
content = Gitea::Repository::Entries::GetService.call(owner, repo.identifier, URI.escape(entry['path']), ref: ref)['content']
|
||||
readme_render_decode64_content(content, owner, repo, ref)
|
||||
Rails.logger.info("content===#{content}")
|
||||
# readme_render_decode64_content(content, owner, repo, ref)
|
||||
return Base64.decode64(content).force_encoding('UTF-8')
|
||||
else
|
||||
file_type = File.extname(entry['name'].to_s)[1..-1]
|
||||
if image_type?(file_type)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
class Admins::NewImportUserFromExcel < BaseImportXlsx
|
||||
UserData = Struct.new(:login, :email, :password, :nickname)
|
||||
|
||||
def read_each(&block)
|
||||
sheet.each_row_streaming(pad_cells: true, offset: 1) do |row|
|
||||
data = row.map(&method(:cell_value))[0..3]
|
||||
block.call UserData.new(*data)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def cell_value(obj)
|
||||
obj&.cell_value
|
||||
end
|
||||
end
|
||||
|
|
@ -7,6 +7,8 @@ class CacheAsyncClearJob < ApplicationJob
|
|||
Cache::V2::ProjectCommonService.new(id).clear
|
||||
when "owner_common_service"
|
||||
Cache::V2::OwnnerCommonService.new(id).clear
|
||||
when "project_rank_service"
|
||||
Cache::V2::ProjectRankService.new(id).clear
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -3,8 +3,7 @@ class DelayExpiredIssueJob < ApplicationJob
|
|||
|
||||
def perform
|
||||
Issue.where(due_date: Date.today + 1.days).find_each do |issue|
|
||||
SendTemplateMessageJob.perform_later('IssueAssignerExpire', issue.id) if Site.has_notice_menu?
|
||||
SendTemplateMessageJob.perform_later('IssueCreatorExpire', issue.id) if Site.has_notice_menu?
|
||||
SendTemplateMessageJob.perform_later('IssueExpire', issue.id) if Site.has_notice_menu?
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -24,13 +24,6 @@ class SendTemplateMessageJob < ApplicationJob
|
|||
receivers_email_string, email_title, email_content = MessageTemplate::IssueAssigned.get_email_message_content(receiver, operator, issue)
|
||||
Notice::Write::EmailCreateService.call(receivers_email_string, email_title, email_content)
|
||||
end
|
||||
when 'IssueAssignerExpire'
|
||||
issue_id = args[0]
|
||||
issue = Issue.find_by_id(issue_id)
|
||||
return unless issue.present?
|
||||
receivers = User.where(id: issue&.assigned_to_id)
|
||||
receivers_string, content, notification_url = MessageTemplate::IssueAssignerExpire.get_message_content(receivers, issue)
|
||||
Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {issue_id: issue.id})
|
||||
when 'IssueAtme'
|
||||
receivers, operator_id, issue_id = args[0], args[1], args[2]
|
||||
operator = User.find_by_id(operator_id)
|
||||
|
|
@ -52,13 +45,17 @@ class SendTemplateMessageJob < ApplicationJob
|
|||
receivers_email_string, email_title, email_content = MessageTemplate::IssueChanged.get_email_message_content(receiver, operator, issue, change_params)
|
||||
Notice::Write::EmailCreateService.call(receivers_email_string, email_title, email_content)
|
||||
end
|
||||
when 'IssueCreatorExpire'
|
||||
when 'IssueExpire'
|
||||
issue_id = args[0]
|
||||
issue = Issue.find_by_id(issue_id)
|
||||
return unless issue.present?
|
||||
receivers = User.where(id: issue&.author_id)
|
||||
receivers_string, content, notification_url = MessageTemplate::IssueCreatorExpire.get_message_content(receivers, issue)
|
||||
receivers = User.where(id: [issue&.assigned_to_id, issue&.author_id])
|
||||
receivers_string, content, notification_url = MessageTemplate::IssueExpire.get_message_content(receivers, issue)
|
||||
Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {issue_id: issue.id})
|
||||
receivers.find_each do |receiver|
|
||||
receivers_email_string, email_title, email_content = MessageTemplate::IssueExpire.get_email_message_content(receiver, issue)
|
||||
Notice::Write::EmailCreateService.call(receivers_email_string, email_title, email_content)
|
||||
end
|
||||
when 'IssueDeleted'
|
||||
operator_id, issue_title, issue_assigned_to_id, issue_author_id = args[0], args[1], args[2], args[3]
|
||||
operator = User.find_by_id(operator_id)
|
||||
|
|
@ -94,6 +91,14 @@ class SendTemplateMessageJob < ApplicationJob
|
|||
receivers_email_string, email_title, email_content = MessageTemplate::OrganizationLeft.get_email_message_content(receiver, organization)
|
||||
Notice::Write::EmailCreateService.call(receivers_email_string, email_title, email_content)
|
||||
end
|
||||
when 'ProjectForked'
|
||||
operator_id, project_id = args[0], args[1]
|
||||
operator = User.find_by_id(operator_id)
|
||||
project = Project.find_by_id(project_id)
|
||||
return unless operator.present? && project.present?
|
||||
receivers = project&.all_managers.where.not(id: operator&.id)
|
||||
receivers_string, content, notification_url = MessageTemplate::ProjectForked.get_message_content(receivers, operator, project)
|
||||
Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {operator_id: operator.id, project_id: project.id})
|
||||
when 'ProjectIssue'
|
||||
operator_id, issue_id = args[0], args[1]
|
||||
operator = User.find_by_id(operator_id)
|
||||
|
|
@ -163,6 +168,37 @@ class SendTemplateMessageJob < ApplicationJob
|
|||
receivers_email_string, email_title, email_content = MessageTemplate::ProjectMemberLeft.get_email_message_content(receiver, user, project)
|
||||
Notice::Write::EmailCreateService.call(receivers_email_string, email_title, email_content)
|
||||
end
|
||||
when 'ProjectMilestoneCompleted'
|
||||
milestone_id = args[0]
|
||||
milestone = Version.find_by_id(milestone_id)
|
||||
return unless milestone.present? && milestone&.project.present?
|
||||
receivers = milestone&.project&.all_managers
|
||||
receivers_string, content, notification_url = MessageTemplate::ProjectMilestoneCompleted.get_message_content(receivers, milestone)
|
||||
Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {milestone_id: milestone_id})
|
||||
receivers.find_each do |receiver|
|
||||
receivers_email_string, email_title, email_content = MessageTemplate::ProjectMilestoneCompleted.get_email_message_content(receiver, milestone)
|
||||
Notice::Write::EmailCreateService.call(receivers_email_string, email_title, email_content)
|
||||
end
|
||||
when 'ProjectMilestone'
|
||||
milestone_id, operator_id = args[0], args[1]
|
||||
milestone = Version.find_by_id(milestone_id)
|
||||
operator = User.find_by_id(operator_id)
|
||||
return unless milestone.present? && milestone&.project.present? && operator.present?
|
||||
receivers = milestone&.project&.all_managers.where.not(id: operator_id)
|
||||
receivers_string, content, notification_url = MessageTemplate::ProjectMilestone.get_message_content(receivers, operator, milestone)
|
||||
Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {milestone_id: milestone_id, operator_id: operator_id})
|
||||
receivers.find_each do |receiver|
|
||||
receivers_email_string, email_title, email_content = MessageTemplate::ProjectMilestone.get_email_message_content(receiver, operator, milestone)
|
||||
Notice::Write::EmailCreateService.call(receivers_email_string, email_title, email_content)
|
||||
end
|
||||
when 'ProjectPraised'
|
||||
operator_id, project_id = args[0], args[1]
|
||||
operator = User.find_by_id(operator_id)
|
||||
project = Project.find_by_id(project_id)
|
||||
return unless operator.present? && project.present?
|
||||
receivers = project&.all_managers.where.not(id: operator&.id)
|
||||
receivers_string, content, notification_url = MessageTemplate::ProjectPraised.get_message_content(receivers, operator, project)
|
||||
Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {operator_id: operator.id, project_id: project.id})
|
||||
when 'ProjectPullRequest'
|
||||
operator_id, pull_request_id = args[0], args[1]
|
||||
operator = User.find_by_id(operator_id)
|
||||
|
|
@ -290,6 +326,30 @@ class SendTemplateMessageJob < ApplicationJob
|
|||
receivers_email_string, email_title, email_content = MessageTemplate::TeamLeft.get_email_message_content(receiver, organization, team)
|
||||
Notice::Write::EmailCreateService.call(receivers_email_string, email_title, email_content)
|
||||
end
|
||||
when 'CompetitionBegin'
|
||||
user_id, competition_id = args[0], args[1]
|
||||
user = User.find_by_id(user_id)
|
||||
project = Project.find_by_sql("select *,title as name from competitions where id=#{competition_id}")
|
||||
return unless user.present? && project.present?
|
||||
receivers = User.where(id: user_id)
|
||||
receivers_string, content, notification_url = MessageTemplate::CompetitionBegin.get_message_content(receivers, project.first)
|
||||
Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {user_id: user_id, competition_name: project.first&.name, identifier: project.first&.identifier})
|
||||
when 'CompetitionReview'
|
||||
user_id, competition_id = args[0], args[1]
|
||||
user = User.find_by_id(user_id)
|
||||
project = Project.find_by_sql("select *,title as name from competitions where id=#{competition_id}")
|
||||
return unless user.present? && project.present?
|
||||
receivers = User.where(id: user_id)
|
||||
receivers_string, content, notification_url = MessageTemplate::CompetitionReview.get_message_content(receivers, project.first)
|
||||
Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {user_id: user_id, competition_name: project.first&.name, identifier: project.first&.identifier})
|
||||
when 'CompetitionResult'
|
||||
user_id, competition_id = args[0], args[1]
|
||||
user = User.find_by_id(user_id)
|
||||
project = Project.find_by_sql("select *,title as name from competitions where id=#{competition_id}")
|
||||
return unless user.present? && project.present?
|
||||
receivers = User.where(id: user_id)
|
||||
receivers_string, content, notification_url = MessageTemplate::CompetitionResult.get_message_content(receivers, project.first)
|
||||
Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {user_id: user_id, competition_name: project.first&.name, identifier: project.first&.identifier})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,7 +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_-]+$/ #只含有数字、字母、下划线不能以下划线开头和结尾
|
||||
LOGIN = /^(?!_)(?!.*?_$)[a-zA-Z0-9_-]{4,15}\z/ #只含有数字、字母、下划线不能以下划线开头和结尾
|
||||
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/
|
||||
|
|
@ -11,5 +11,5 @@ module CustomRegexp
|
|||
|
||||
URL_REGEX = /\A(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?\z/i
|
||||
REPOSITORY_NAME_REGEX = /^(?!_)(?!.*?_$)[a-zA-Z0-9_-]+$/ #只含有数字、字母、下划线不能以下划线开头和结尾
|
||||
|
||||
MD_REGEX = /^.+(\.[m|M][d|D])$/
|
||||
end
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ module Notice
|
|||
config = Rails.application.config_for(:configuration).symbolize_keys!
|
||||
notice_config = config[:notice].symbolize_keys!
|
||||
raise 'notice config missing' if notice_config.blank?
|
||||
rescue => exception
|
||||
rescue => ex
|
||||
raise ex if Rails.env.production?
|
||||
|
||||
puts %Q{\033[33m [warning] gitea config or configuration.yml missing,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
module Trace
|
||||
class << self
|
||||
def trace_config
|
||||
trace_config = {}
|
||||
|
||||
begin
|
||||
config = Rails.application.config_for(:configuration).symbolize_keys!
|
||||
trace_config = config[:trace].symbolize_keys!
|
||||
raise 'trace config missing' if trace_config.blank?
|
||||
rescue => ex
|
||||
raise ex if Rails.env.production?
|
||||
|
||||
puts %Q{\033[33m [warning] gitea config or configuration.yml missing,
|
||||
please add it or execute 'cp config/configuration.yml.example config/configuration.yml' \033[0m}
|
||||
trace_config = {}
|
||||
end
|
||||
|
||||
trace_config
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -5,10 +5,10 @@ class Ci::Repo < Ci::RemoteBase
|
|||
has_one :perm, foreign_key: :perm_repo_uid
|
||||
has_many :builds, foreign_key: :build_repo_id, dependent: :destroy
|
||||
|
||||
def self.find_with_namespace(namespace_path, identifier)
|
||||
def self.find_with_namespace(namespace_path, identifier, user_login)
|
||||
logger.info "########namespace_path: #{namespace_path} ########identifier: #{identifier} "
|
||||
|
||||
user = Ci::User.find_by_user_login namespace_path
|
||||
user_login = user_login || namespace_path
|
||||
user = Ci::User.find_by(user_login: user_login)
|
||||
repo = Ci::Repo.where(repo_namespace: namespace_path, repo_name: identifier).first
|
||||
|
||||
[user, repo]
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ module Matchable
|
|||
scope :with_project_category, ->(category_id) { where(project_category_id: category_id) unless category_id.blank? }
|
||||
scope :with_project_language, ->(language_id) { where(project_language_id: language_id) unless language_id.blank? }
|
||||
scope :with_project_type, ->(project_type) { where(project_type: project_type) if Project.project_types.include?(project_type) }
|
||||
scope :by_name_or_identifier, ->(search) { where("name like :search or identifier LIKE :search", :search => "#{search.split(" ").join('|')}%") unless search.blank? }
|
||||
scope :by_name_or_identifier, ->(search) { where("name like :search or identifier LIKE :search", :search => "%#{search.split(" ").join('|')}%") unless search.blank? }
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
class ForkUser < ApplicationRecord
|
||||
belongs_to :project
|
||||
belongs_to :user
|
||||
belongs_to :owner, class_name: 'Owner', foreign_key: :user_id
|
||||
belongs_to :fork_project, class_name: 'Project', foreign_key: :fork_project_id
|
||||
|
||||
after_create :incre_project_common, :incre_user_statistic, :incre_platform_statistic
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ class Issue < ApplicationRecord
|
|||
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 :change_versions_count, :send_update_message_to_notice_system
|
||||
after_destroy :update_closed_issues_count_in_project!, :decre_project_common, :decre_user_statistic, :decre_platform_statistic
|
||||
|
||||
def incre_project_common
|
||||
|
|
@ -170,11 +170,25 @@ class Issue < ApplicationRecord
|
|||
end
|
||||
|
||||
def change_versions_count
|
||||
if self.version.present? && self.saved_change_to_status_id?
|
||||
if self.saved_change_to_fixed_version_id?
|
||||
before_version = Version.find_by_id(self.fixed_version_id_before_last_save)
|
||||
Rails.logger.info self.fixed_version_id_before_last_save
|
||||
if before_version.present?
|
||||
Rails.logger.info self.status_id
|
||||
Rails.logger.info self.status_id_before_last_save
|
||||
# 更改前状态为完成 或者 更改前后都为完成状态
|
||||
if self.status_id_before_last_save == 5
|
||||
percent = before_version.issues_count == 0 ? 0.0 : ((before_version.closed_issues_count - 1).to_f / before_version.issues_count)
|
||||
before_version.update_attributes(closed_issues_count: (before_version.closed_issues_count - 1), percent: percent)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if self.version.present? && (self.saved_change_to_status_id? || self.saved_change_to_fixed_version_id?)
|
||||
if self.status_id == 5
|
||||
percent = self.version.issues_count == 0 ? 0.0 : ((self.version.closed_issues_count + 1).to_f / self.version.issues_count)
|
||||
self.version.update_attributes(closed_issues_count: (self.version.closed_issues_count + 1), percent: percent)
|
||||
elsif self.status_id_before_last_save == 5
|
||||
elsif self.status_id_before_last_save == 5 && !self.saved_change_to_fixed_version_id?
|
||||
percent = self.version.issues_count == 0 ? 0.0 : ((self.version.closed_issues_count - 1).to_f / self.version.issues_count)
|
||||
self.version.update_attributes(closed_issues_count: (self.version.closed_issues_count - 1), percent: percent)
|
||||
end
|
||||
|
|
@ -182,7 +196,11 @@ class Issue < ApplicationRecord
|
|||
end
|
||||
|
||||
def update_closed_issues_count_in_project!
|
||||
self.project.decrement!(:closed_issues_count)
|
||||
self.project.decrement!(:closed_issues_count) if self.status_id == 5
|
||||
end
|
||||
|
||||
def send_update_message_to_notice_system
|
||||
SendTemplateMessageJob.perform_later('IssueExpire', self.id) if Site.has_notice_menu? && self.due_date == Date.today + 1.days
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
# journalized_id :integer default("0"), not null
|
||||
# journalized_type :string(30) default(""), not null
|
||||
# user_id :integer default("0"), not null
|
||||
# notes :text(65535)
|
||||
# notes :text(4294967295)
|
||||
# created_on :datetime not null
|
||||
# private_notes :boolean default("0"), not null
|
||||
# parent_id :integer
|
||||
|
|
|
|||
|
|
@ -13,61 +13,72 @@
|
|||
#
|
||||
|
||||
class MessageTemplate < ApplicationRecord
|
||||
PLATFORM = 'GitLink'
|
||||
|
||||
def self.build_init_data
|
||||
MessageTemplate::IssueAssignerExpire.destroy_all
|
||||
MessageTemplate::IssueCreatorExpire.destroy_all
|
||||
self.create(type: 'MessageTemplate::FollowedTip', sys_notice: '<b>{nickname}</b> 关注了你', notification_url: '{baseurl}/{login}')
|
||||
email_html = File.read("#{email_template_html_dir}/issue_assigned.html")
|
||||
self.create(type: 'MessageTemplate::IssueAssigned', sys_notice: '{nickname1}在 <b>{nickname2}/{repository}</b> 指派给你一个疑修:<b>{title}</b>', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}', email: email_html, email_title: 'GitLink: {nickname1} 在 {nickname2}/{repository} 指派给你一个疑修')
|
||||
self.create(type: 'MessageTemplate::IssueAssignerExpire', sys_notice: '您负责的疑修 <b>{title}</b> 已临近截止日期,请尽快处理', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}')
|
||||
self.create(type: 'MessageTemplate::IssueAssigned', sys_notice: '{nickname1}在 <b>{nickname2}/{repository}</b> 指派给你一个疑修:<b>{title}</b>', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}', email: email_html, email_title: "#{PLATFORM}: {nickname1} 在 {nickname2}/{repository} 指派给你一个疑修")
|
||||
self.create(type: 'MessageTemplate::IssueAtme', sys_notice: '<b>{nickname}</b> 在疑修 <b>{title}</b> 中@我', 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: '在项目 <b>{nickname2}/{repository}</b> 的疑修 <b>{title}</b> 中:{ifassigner}{nickname1}将负责人从 <b>{assigner1}</b> 修改为 <b>{assigner2}</b> {endassigner}{ifstatus}{nickname1}将状态从 <b>{status1}</b> 修改为 <b>{status2}</b> {endstatus}{iftracker}{nickname1}将类型从 <b>{tracker1}</b> 修改为 <b>{tracker2}</b> {endtracker}{ifpriority}{nickname1}将优先级从 <b>{priority1}</b> 修改为 <b>{priority2}</b> {endpriority}{ifmilestone}{nickname1}将里程碑从 <b>{milestone1}</b> 修改为 <b>{milestone2}</b> {endmilestone}{iftag}{nickname1}将标记从 <b>{tag1}</b> 修改为 <b>{tag2}</b> {endtag}{ifdoneratio}{nickname1}将完成度从 <b>{doneratio1}</b> 修改为 <b>{doneratio2}</b> {enddoneratio}{ifbranch}{nickname1}将指定分支从 <b>{branch1}</b> 修改为 <b>{branch2}</b> {endbranch}{ifstartdate}{nickname1}将开始日期从 <b>{startdate1}</b> 修改为 <b>{startdate2}</b> {endstartdate}{ifduedate}{nickname1}将结束日期从 <b>{duedate1}</b> 修改为 <b>{duedate2}</b> {endduedate}', email: email_html, email_title: 'GitLink: 疑修 {title} 有状态变更', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}')
|
||||
self.create(type: 'MessageTemplate::IssueCreatorExpire', sys_notice: '您发布的疑修 <b>{title}</b> 已临近截止日期,请尽快处理', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}')
|
||||
self.create(type: 'MessageTemplate::IssueChanged', sys_notice: '在项目 <b>{nickname2}/{repository}</b> 的疑修 <b>{title}</b> 中:{ifassigner}{nickname1}将负责人从 <b>{assigner1}</b> 修改为 <b>{assigner2}</b> {endassigner}{ifstatus}{nickname1}将状态从 <b>{status1}</b> 修改为 <b>{status2}</b> {endstatus}{iftracker}{nickname1}将类型从 <b>{tracker1}</b> 修改为 <b>{tracker2}</b> {endtracker}{ifpriority}{nickname1}将优先级从 <b>{priority1}</b> 修改为 <b>{priority2}</b> {endpriority}{ifmilestone}{nickname1}将里程碑从 <b>{milestone1}</b> 修改为 <b>{milestone2}</b> {endmilestone}{iftag}{nickname1}将标记从 <b>{tag1}</b> 修改为 <b>{tag2}</b> {endtag}{ifdoneratio}{nickname1}将完成度从 <b>{doneratio1}</b> 修改为 <b>{doneratio2}</b> {enddoneratio}{ifbranch}{nickname1}将指定分支从 <b>{branch1}</b> 修改为 <b>{branch2}</b> {endbranch}{ifstartdate}{nickname1}将开始日期从 <b>{startdate1}</b> 修改为 <b>{startdate2}</b> {endstartdate}{ifduedate}{nickname1}将结束日期从 <b>{duedate1}</b> 修改为 <b>{duedate2}</b> {endduedate}', email: email_html, email_title: "#{PLATFORM}: 疑修 {title} 有状态变更", notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}')
|
||||
email_html = File.read("#{email_template_html_dir}/issue_expire.html")
|
||||
self.create(type: 'MessageTemplate::IssueExpire', sys_notice: '疑修 <b>{title}</b> 已临近截止日期,请尽快处理', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}', email: email_html, email_title: "#{PLATFORM}: 疑修截止日期到达最后一天")
|
||||
email_html = File.read("#{email_template_html_dir}/issue_deleted.html")
|
||||
self.create(type: 'MessageTemplate::IssueDeleted', sys_notice: '{nickname}已将疑修 <b>{title}</b> 删除', email: email_html, email_title: 'GitLink: 疑修 {title} 有状态变更', notification_url: '')
|
||||
self.create(type: 'MessageTemplate::IssueDeleted', sys_notice: '{nickname}已将疑修 <b>{title}</b> 删除', email: email_html, email_title: "#{PLATFORM}: 疑修 {title} 有状态变更", notification_url: '')
|
||||
self.create(type: 'MessageTemplate::IssueJournal', sys_notice: '{nickname}评论疑修{title}:<b>{notes}</b>', 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: '你已加入 <b>{organization}</b> 组织', notification_url: '{baseurl}/{login}', email: email_html, email_title: 'GitLink: 你已加入 {organization} 组织')
|
||||
self.create(type: 'MessageTemplate::OrganizationJoined', sys_notice: '你已加入 <b>{organization}</b> 组织', notification_url: '{baseurl}/{login}', email: email_html, email_title: "#{PLATFORM}: 你已加入 {organization} 组织")
|
||||
email_html = File.read("#{email_template_html_dir}/organization_left.html")
|
||||
self.create(type: 'MessageTemplate::OrganizationLeft', sys_notice: '你已被移出 <b>{organization}</b> 组织', notification_url: '', email: email_html, email_title: 'GitLink: 你已被移出 {organization} 组织')
|
||||
self.create(type: 'MessageTemplate::OrganizationLeft', sys_notice: '你已被移出 <b>{organization}</b> 组织', notification_url: '', email: email_html, email_title: "#{PLATFORM}: 你已被移出 {organization} 组织")
|
||||
self.create(type: 'MessageTemplate::ProjectDeleted', sys_notice: '你关注的仓库{nickname}/{repository}已被删除', notification_url: '')
|
||||
self.create(type: 'MessageTemplate::ProjectFollowed', sys_notice: '<b>{nickname}</b> 关注了你管理的仓库', notification_url: '{baseurl}/{login}')
|
||||
self.create(type: 'MessageTemplate::ProjectForked', sys_notice: '<b>{nickname1}</b> 复刻了你管理的仓库{nickname1}/{repository1}到{nickname2}/{repository2}', notification_url: '{baseurl}/{owner}/{identifier}')
|
||||
self.create(type: 'MessageTemplate::ProjectForked', sys_notice: '<b>{nickname1}</b> 复刻了你管理的仓库 <b>{nickname2}/{repository}</b> 到 <b>{nickname1}/{repository}</b>', notification_url: '{baseurl}/{owner}/{identifier}')
|
||||
email_html = File.read("#{email_template_html_dir}/project_issue.html")
|
||||
self.create(type: 'MessageTemplate::ProjectIssue', sys_notice: '{nickname1}在 <b>{nickname2}/{repository}</b> 新建疑修:<b>{title}</b>', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}', email: email_html, email_title: 'GitLink: {nickname1} 在 {nickname2}/{repository} 新建了一个疑修')
|
||||
self.create(type: 'MessageTemplate::ProjectIssue', sys_notice: '{nickname1}在 <b>{nickname2}/{repository}</b> 新建疑修:<b>{title}</b>', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}', email: email_html, email_title: "#{PLATFORM}: {nickname1} 在 {nickname2}/{repository} 新建了一个疑修")
|
||||
email_html = File.read("#{email_template_html_dir}/project_joined.html")
|
||||
self.create(type: 'MessageTemplate::ProjectJoined', sys_notice: '你已加入 <b>{repository}</b> 项目', notification_url: '{baseurl}/{owner}/{identifier}', email: email_html, email_title: 'GitLink: 你已加入 {repository} 项目')
|
||||
self.create(type: 'MessageTemplate::ProjectJoined', sys_notice: '你已加入 <b>{repository}</b> 项目', notification_url: '{baseurl}/{owner}/{identifier}', email: email_html, email_title: "#{PLATFORM}: 你已加入 {repository} 项目")
|
||||
email_html = File.read("#{email_template_html_dir}/project_left.html")
|
||||
self.create(type: 'MessageTemplate::ProjectLeft', sys_notice: '你已被移出 <b>{repository}</b> 项目', notification_url: '', email: email_html, email_title: 'GitLink: 你已被移出 {repository} 项目')
|
||||
self.create(type: 'MessageTemplate::ProjectLeft', sys_notice: '你已被移出 <b>{repository}</b> 项目', notification_url: '', email: email_html, email_title: "#{PLATFORM}: 你已被移出 {repository} 项目")
|
||||
email_html = File.read("#{email_template_html_dir}/project_member_joined.html")
|
||||
self.create(type: 'MessageTemplate::ProjectMemberJoined', sys_notice: '<b>{nickname1}</b> 已加入项目 <b>{nickname2}/{repository}</b>', notification_url: '{baseurl}/{owner}/{identifier}', email: email_html, email_title: 'GitLink: {nickname1} 已加入项目 {nickname2}/{repository}')
|
||||
self.create(type: 'MessageTemplate::ProjectMemberJoined', sys_notice: '<b>{nickname1}</b> 已加入项目 <b>{nickname2}/{repository}</b>', notification_url: '{baseurl}/{owner}/{identifier}', email: email_html, email_title: "#{PLATFORM}: {nickname1} 已加入项目 {nickname2}/{repository}")
|
||||
email_html = File.read("#{email_template_html_dir}/project_member_left.html")
|
||||
self.create(type: 'MessageTemplate::ProjectMemberLeft', sys_notice: '<b>{nickname1}</b> 已被移出项目 <b>{nickname2}/{repository}</b>', notification_url: '{baseurl}/{owner}/{identifier}', email: email_html, email_title: 'GitLink: {nickname1} 已被移出项目 {nickname2}/{repository}')
|
||||
self.create(type: 'MessageTemplate::ProjectMilestone', sys_notice: '{nickname1}在 <b>{nickname2}/{repository}</b> 创建了一个里程碑:<b>{title}</b>', notification_url: '{baseurl}/{owner}/{identifier}/milestones/{id}')
|
||||
self.create(type: 'MessageTemplate::ProjectPraised', sys_notice: '<b>{nickname}</b> 点赞了你管理的仓库', notification_url: '{baseurl}/{login}')
|
||||
self.create(type: 'MessageTemplate::ProjectMemberLeft', sys_notice: '<b>{nickname1}</b> 已被移出项目 <b>{nickname2}/{repository}</b>', notification_url: '{baseurl}/{owner}/{identifier}', email: email_html, email_title: "#{PLATFORM}: {nickname1} 已被移出项目 {nickname2}/{repository}")
|
||||
email_html = File.read("#{email_template_html_dir}/project_milestone.html")
|
||||
self.create(type: 'MessageTemplate::ProjectMilestone', sys_notice: '{nickname1}在 <b>{nickname2}/{repository}</b> 创建了一个里程碑:<b>{name}</b>', notification_url: '{baseurl}/{owner}/{identifier}/milestones/{id}', email: email_html, email_title: "#{PLATFORM}: {nickname1} 在 {nickname2}/{repository} 新建了一个里程碑")
|
||||
email_html = File.read("#{email_template_html_dir}/project_milestone_completed.html")
|
||||
self.create(type: 'MessageTemplate::ProjectMilestoneCompleted', sys_notice: '在 <b>{nickname}/{repository}</b> 仓库,里程碑 <b>{name}</b> 的完成度已达到100%', notification_url: '{baseurl}/{owner}/{identifier}/milestones/{id}', email: email_html, email_title: "#{PLATFORM}: 仓库 {nickname}/{repository} 有里程碑已完成")
|
||||
self.create(type: 'MessageTemplate::ProjectPraised', sys_notice: '<b>{nickname1}</b> 点赞了你管理的仓库 <b>{nickname2}/{repository}</b>', notification_url: '{baseurl}/{login}')
|
||||
email_html = File.read("#{email_template_html_dir}/project_pull_request.html")
|
||||
self.create(type: 'MessageTemplate::ProjectPullRequest', sys_notice: '{nickname1}在 <b>{nickname2}/{repository}</b> 提交了一个合并请求:<b>{title}</b>', notification_url: '{baseurl}/{owner}/{identifier}/pulls/{id}', email: email_html, email_title: 'GitLink: {nickname1} 在 {nickname2}/{repository} 提交了一个合并请求')
|
||||
self.create(type: 'MessageTemplate::ProjectPullRequest', sys_notice: '{nickname1}在 <b>{nickname2}/{repository}</b> 提交了一个合并请求:<b>{title}</b>', notification_url: '{baseurl}/{owner}/{identifier}/pulls/{id}', email: email_html, email_title: "#{PLATFORM}: {nickname1} 在 {nickname2}/{repository} 提交了一个合并请求")
|
||||
email_html = File.read("#{email_template_html_dir}/project_role.html")
|
||||
self.create(type: 'MessageTemplate::ProjectRole', sys_notice: '仓库 <b>{nickname}/{repository}</b> 已把你的角色改为 <b>{role}</b>', email: email_html, email_title: 'GitLink: 在 {nickname}/{repository} 项目你的账号有权限变更', notification_url: '{baseurl}/{owner}/{identifier}')
|
||||
self.create(type: 'MessageTemplate::ProjectRole', sys_notice: '仓库 <b>{nickname}/{repository}</b> 已把你的角色改为 <b>{role}</b>', email: email_html, email_title: '#{PLATFORM}: 在 {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}更改了 <b>{nickname2}/{repository}</b> 仓库设置:{ifname}更改项目名称为"<b>{name}</b>"{endname}{ifidentifier}更改项目标识为"<b>{identifier}</b>"{endidentifier}{ifdescription}更改项目简介为"<b>{description}</b>"{enddescription}{ifcategory}更改项目类别为"<b>{category}</b>"{endcategory}{iflanguage}更改项目语言为"<b>{language}</b>"{endlanguage}{ifpermission}将仓库设为"<b>{permission}</b>"{endpermission}{ifnavbar}将项目导航更改为"<b>{navbar}</b>"{endnavbar}', notification_url: '{baseurl}/{owner}/{identifier}/settings', email: email_html, email_title: 'GitLink: 您管理的仓库 {nickname2}/{repository} 仓库设置已被更改')
|
||||
self.create(type: 'MessageTemplate::ProjectSettingChanged', sys_notice: '{nickname1}更改了 <b>{nickname2}/{repository}</b> 仓库设置:{ifname}更改项目名称为"<b>{name}</b>"{endname}{ifidentifier}更改项目标识为"<b>{identifier}</b>"{endidentifier}{ifdescription}更改项目简介为"<b>{description}</b>"{enddescription}{ifcategory}更改项目类别为"<b>{category}</b>"{endcategory}{iflanguage}更改项目语言为"<b>{language}</b>"{endlanguage}{ifpermission}将仓库设为"<b>{permission}</b>"{endpermission}{ifnavbar}将项目导航更改为"<b>{navbar}</b>"{endnavbar}', notification_url: '{baseurl}/{owner}/{identifier}/settings', email: email_html, email_title: "#{PLATFORM}: 您管理的仓库 {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}在 <b>{nickname2}/{repository}</b> 创建了发行版:<b>{title}</b>', 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}在 <b>{nickname2}/{repository}</b> 指派给你一个合并请求:<b>{title}<b>', notification_url: '{baseurl}/{owner}/{identifier}/pulls/{id}', email: email_html, email_title: 'GitLink: {nickname1} 在 {nickname2}/{repository} 指派给你一个合并请求')
|
||||
self.create(type: 'MessageTemplate::PullRequestAssigned', sys_notice: '{nickname1}在 <b>{nickname2}/{repository}</b> 指派给你一个合并请求:<b>{title}<b>', notification_url: '{baseurl}/{owner}/{identifier}/pulls/{id}', email: email_html, email_title: "#{PLATFORM}: {nickname1} 在 {nickname2}/{repository} 指派给你一个合并请求")
|
||||
self.create(type: 'MessageTemplate::PullRequestAtme', sys_notice: '<b>{nickname}</b> 在合并请求 <b>{title}</b> 中@我', 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}的合并请求 <b>{title}</b> 中:{ifassigner}{nickname1}将审查成员从 <b>{assigner1}</b> 修改为 <b>{assigner2}</b> {endassigner}{ifmilestone}{nickname1}将里程碑从 <b>{milestone1}</b> 修改为 <b>{milestone2}</b> {endmilestone}{iftag}{nickname1}将标记从 <b>{tag1}</b> 修改为 <b>{tag2}</b> {endtag}{ifpriority}{nickname1}将优先级从 <b>{priority1}</b> 修改为 <b>{priority2}</b> {endpriority}', email: email_html, email_title: 'GitLink: 合并请求 {title} 有状态变更', notification_url: '{baseurl}/{owner}/{identifier}/pulls/{id}')
|
||||
self.create(type: 'MessageTemplate::PullRequestChanged', sys_notice: '在项目{nickname2}/{repository}的合并请求 <b>{title}</b> 中:{ifassigner}{nickname1}将审查成员从 <b>{assigner1}</b> 修改为 <b>{assigner2}</b> {endassigner}{ifmilestone}{nickname1}将里程碑从 <b>{milestone1}</b> 修改为 <b>{milestone2}</b> {endmilestone}{iftag}{nickname1}将标记从 <b>{tag1}</b> 修改为 <b>{tag2}</b> {endtag}{ifpriority}{nickname1}将优先级从 <b>{priority1}</b> 修改为 <b>{priority2}</b> {endpriority}', email: email_html, email_title: "#{PLATFORM}: 合并请求 {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} <b>被拒绝</b>', email: email_html, email_title: 'GitLink: 合并请求 {title} 有状态变更', notification_url: '')
|
||||
self.create(type: 'MessageTemplate::PullRequestClosed', sys_notice: '你提交的合并请求:{title} <b>被拒绝</b>', email: email_html, email_title: "#{PLATFORM}: 合并请求 {title} 有状态变更", notification_url: '')
|
||||
self.create(type: 'MessageTemplate::PullRequestJournal', sys_notice: '{nickname}评论合并请求{title}:<b>{notes}</b>', 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} <b>已通过</b>', email: email_html, email_title: 'GitLink: 合并请求 {title} 有状态变更', notification_url: '{baseurl}/{owner}/{identifier}/pulls/{id}')
|
||||
self.create(type: 'MessageTemplate::PullRequestMerged', sys_notice: '你提交的合并请求:{title} <b>已通过</b>', email: email_html, email_title: "#{PLATFORM}: 合并请求 {title} 有状态变更", notification_url: '{baseurl}/{owner}/{identifier}/pulls/{id}')
|
||||
email_html = File.read("#{email_template_html_dir}/team_joined.html")
|
||||
self.create(type: 'MessageTemplate::TeamJoined', sys_notice: '你已被拉入组织 <b>{organization}</b> 的 <b>{team}</b> 团队,拥有<b>{role}</b>权限', email: email_html, email_title: 'GitLink: 在 {organization} 组织你的账号有权限变更', notification_url: '{baseurl}/{login}')
|
||||
self.create(type: 'MessageTemplate::TeamJoined', sys_notice: '你已被拉入组织 <b>{organization}</b> 的 <b>{team}</b> 团队,拥有<b>{role}</b>权限', email: email_html, email_title: "#{PLATFORM}: 在 {organization} 组织你的账号有权限变更", notification_url: '{baseurl}/{login}')
|
||||
email_html = File.read("#{email_template_html_dir}/team_left.html")
|
||||
self.create(type: 'MessageTemplate::TeamLeft', sys_notice: '你已被移出组织 <b>{organization}</b> 的 <b>{team}</b> 团队', email: email_html, email_title: 'GitLink: 在 {organization} 组织你的账号有权限变更', notification_url: '{baseurl}/{login}')
|
||||
self.create(type: 'MessageTemplate::TeamLeft', sys_notice: '你已被移出组织 <b>{organization}</b> 的 <b>{team}</b> 团队', email: email_html, email_title: "#{PLATFORM}: 在 {organization} 组织你的账号有权限变更", notification_url: '{baseurl}/{login}')
|
||||
|
||||
# 竞赛通知
|
||||
self.create(type: 'MessageTemplate::CompetitionBegin', sys_notice: '你报名的竞赛 <b>{competition_name}</b> 已进入比赛进行阶段,可在此期间提交作品', notification_url: '{to_url}')
|
||||
self.create(type: 'MessageTemplate::CompetitionResult', sys_notice: '你报名的竞赛 <b>{competition_name}</b> 已进入成绩公示阶段,可查看排行榜信息', notification_url: '{to_url}')
|
||||
self.create(type: 'MessageTemplate::CompetitionReview', sys_notice: '你报名的竞赛 <b>{competition_name}</b> 距作品提交结束日期仅剩3天,若尚未提交参赛作品,请尽快提交', notification_url: '{to_url}')
|
||||
end
|
||||
|
||||
def self.sys_notice
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: message_templates
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# type :string(255)
|
||||
# sys_notice :text(65535)
|
||||
# email :text(65535)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# notification_url :string(255)
|
||||
# email_title :string(255)
|
||||
#
|
||||
|
||||
# 报名的竞赛进入比赛进行阶段
|
||||
# 触发场景
|
||||
# 赛队成员报名的竞赛已进入比赛进行阶段
|
||||
# 通知文案格式
|
||||
# 你报名的竞赛 xxx 已进入比赛进行阶段,可在此阶段提交作品
|
||||
# 时间:x分钟/小时/天/月前
|
||||
# 通知文案示例
|
||||
# 你报名的竞赛 代码审查大赛 已进入比赛进行阶段,可在此期间提交作品
|
||||
# 时间:3小时前
|
||||
# 点击通知跳转页面
|
||||
# 点击此通知将跳转到代码审查大赛详情页:
|
||||
# http://117.50.100.12:8080/competitions/lgw7st/home
|
||||
class MessageTemplate::CompetitionBegin < MessageTemplate
|
||||
|
||||
# MessageTemplate::FollowedTip.get_message_content(User.where(login: 'yystopf'), User.last)
|
||||
def self.get_message_content(receivers, competition)
|
||||
return receivers_string(receivers), sys_notice.to_s.gsub('{competition_name}', competition&.name), notification_url.to_s.gsub('{to_url}', "/competitions/#{competition.identifier}/home")
|
||||
# rescue
|
||||
# return '', '', ''
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: message_templates
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# type :string(255)
|
||||
# sys_notice :text(65535)
|
||||
# email :text(65535)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# notification_url :string(255)
|
||||
# email_title :string(255)
|
||||
#
|
||||
|
||||
# 报名的竞赛进入成绩公示阶段
|
||||
# 触发场景
|
||||
# 赛队成员报名的竞赛已进入成绩公示阶段
|
||||
# 通知文案格式
|
||||
# 你报名的竞赛 xxx 已进入成绩公示阶段,可查看排行榜信息
|
||||
# 时间:x分钟/小时/天/月前
|
||||
# 通知文案示例
|
||||
# 你报名的竞赛 代码审查大赛 已进入成绩公示阶段,可查看排行榜信息
|
||||
# 时间:3小时前
|
||||
# 点击通知跳转页面
|
||||
# 点击此通知将跳转到代码审查大赛详情页:
|
||||
# http://117.50.100.12:8080/competitions/lgw7st/home
|
||||
class MessageTemplate::CompetitionResult < MessageTemplate
|
||||
|
||||
# MessageTemplate::FollowedTip.get_message_content(User.where(login: 'yystopf'), User.last)
|
||||
def self.get_message_content(receivers, competition)
|
||||
return receivers_string(receivers), sys_notice.gsub('{competition_name}', competition&.title), notification_url.gsub('{to_url}', "/competitions/#{competition.identifier}/home")
|
||||
rescue
|
||||
return '', '', ''
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: message_templates
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# type :string(255)
|
||||
# sys_notice :text(65535)
|
||||
# email :text(65535)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# notification_url :string(255)
|
||||
# email_title :string(255)
|
||||
#
|
||||
|
||||
# 报名的竞赛比赛结束时间临近
|
||||
# 触发场景
|
||||
# 赛队成员报名的竞赛阶段处于比赛进行中,且距比赛结束日期仅剩3天
|
||||
# 通知文案格式
|
||||
# 你报名的竞赛 xxx 距作品提交结束日期仅剩3天,若尚未提交参赛作品,请尽快提交
|
||||
# 时间:x分钟/小时/天/月前
|
||||
# 通知文案示例
|
||||
# 你报名的竞赛 代码审查大赛 距作品提交结束日期仅剩3天,若尚未提交参赛作品,请尽快提交
|
||||
# 时间:3小时前
|
||||
# 点击通知跳转页面
|
||||
# 点击此通知将跳转到代码审查大赛详情页:
|
||||
# http://117.50.100.12:8080/competitions/lgw7st/home
|
||||
class MessageTemplate::CompetitionReview < MessageTemplate
|
||||
|
||||
# MessageTemplate::FollowedTip.get_message_content(User.where(login: 'yystopf'), User.last)
|
||||
def self.get_message_content(receivers, competition)
|
||||
return receivers_string(receivers), sys_notice.gsub('{competition_name}', competition&.title), notification_url.gsub('{to_url}', "/competitions/#{competition.identifier}/home")
|
||||
rescue
|
||||
return '', '', ''
|
||||
end
|
||||
end
|
||||
|
|
@ -53,6 +53,7 @@ class MessageTemplate::IssueAssigned < MessageTemplate
|
|||
content.gsub!('{baseurl}', base_url)
|
||||
content.gsub!('{title}', issue&.subject)
|
||||
content.gsub!('{id}', issue&.id.to_s)
|
||||
content.gsub!('{platform}', PLATFORM)
|
||||
|
||||
return receiver&.mail, title, content
|
||||
else
|
||||
|
|
|
|||
|
|
@ -359,6 +359,7 @@ class MessageTemplate::IssueChanged < MessageTemplate
|
|||
else
|
||||
content.gsub!(/({ifduedate})(.*)({endduedate})/, '')
|
||||
end
|
||||
content.gsub!('{platform}', PLATFORM)
|
||||
|
||||
return receiver&.mail, title, content
|
||||
else
|
||||
|
|
|
|||
|
|
@ -1,29 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: message_templates
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# type :string(255)
|
||||
# sys_notice :text(65535)
|
||||
# email :text(65535)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# notification_url :string(255)
|
||||
# email_title :string(255)
|
||||
#
|
||||
|
||||
# 我创建的疑修截止日期到达最后一天
|
||||
class MessageTemplate::IssueCreatorExpire < MessageTemplate
|
||||
|
||||
# MessageTemplate::IssueCreatorExpire.get_message_content(User.where(login: 'yystopf'), Issue.last)
|
||||
def self.get_message_content(receivers, issue)
|
||||
project = issue&.project
|
||||
owner = project&.owner
|
||||
content = sys_notice.gsub('{title}', issue&.subject)
|
||||
url = notification_url.gsub('{owner}', owner&.login).gsub('{identifier}', project&.identifier).gsub('{id}', issue&.id.to_s)
|
||||
return receivers_string(receivers), content, url
|
||||
rescue => e
|
||||
Rails.logger.info("MessageTemplate::IssueAssignerExpire.get_message_content [ERROR] #{e}")
|
||||
return '', '', ''
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -41,6 +41,7 @@ class MessageTemplate::IssueDeleted < MessageTemplate
|
|||
content.gsub!('{login}', operator&.login)
|
||||
content.gsub!('{baseurl}', base_url)
|
||||
content.gsub!('{title}', issue_title)
|
||||
content.gsub!('{platform}', PLATFORM)
|
||||
|
||||
return receiver&.mail, title, content
|
||||
else
|
||||
|
|
|
|||
|
|
@ -0,0 +1,67 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: message_templates
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# type :string(255)
|
||||
# sys_notice :text(65535)
|
||||
# email :text(65535)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# notification_url :string(255)
|
||||
# email_title :string(255)
|
||||
#
|
||||
|
||||
# 我创建或负责的疑修截止日期到达最后一天
|
||||
class MessageTemplate::IssueExpire < MessageTemplate
|
||||
|
||||
# MessageTemplate::IssueCreatorExpire.get_message_content(User.where(login: 'yystopf'), Issue.last)
|
||||
def self.get_message_content(receivers, issue)
|
||||
receivers.each do |receiver|
|
||||
if receiver.user_template_message_setting.present?
|
||||
send_setting = receiver.user_template_message_setting.notification_body["CreateOrAssign::IssueExpire"]
|
||||
send_setting = send_setting.nil? ? UserTemplateMessageSetting.init_notification_body["CreateOrAssign::IssueExpire"] : send_setting
|
||||
receivers = receivers.where.not(id: receiver.id) unless send_setting
|
||||
end
|
||||
end
|
||||
return '', '', '' if receivers.blank?
|
||||
project = issue&.project
|
||||
owner = project&.owner
|
||||
content = sys_notice.gsub('{title}', issue&.subject)
|
||||
url = notification_url.gsub('{owner}', owner&.login).gsub('{identifier}', project&.identifier).gsub('{id}', issue&.id.to_s)
|
||||
|
||||
return receivers_string(receivers), content, url
|
||||
rescue => e
|
||||
Rails.logger.info("MessageTemplate::IssueExpire.get_message_content [ERROR] #{e}")
|
||||
return '', '', ''
|
||||
end
|
||||
|
||||
def self.get_email_message_content(receiver, issue)
|
||||
if receiver.user_template_message_setting.present?
|
||||
send_setting = receiver.user_template_message_setting.email_body["CreateOrAssign::IssueExpire"]
|
||||
send_setting = send_setting.nil? ? UserTemplateMessageSetting.init_email_body["CreateOrAssign::IssueExpire"] : send_setting
|
||||
return '', '', '' unless send_setting
|
||||
project = issue&.project
|
||||
owner = project&.owner
|
||||
title = email_title
|
||||
|
||||
content = email
|
||||
content.gsub!('{receiver}', receiver&.real_name)
|
||||
content.gsub!('{nickname}', owner&.real_name)
|
||||
content.gsub!('{login}', owner&.login)
|
||||
content.gsub!('{identifier}', project&.identifier)
|
||||
content.gsub!('{repository}', project&.name)
|
||||
content.gsub!('{baseurl}', base_url)
|
||||
content.gsub!('{title}', issue&.subject)
|
||||
content.gsub!('{id}', issue&.id.to_s)
|
||||
content.gsub!('{platform}', PLATFORM)
|
||||
|
||||
return receiver&.mail, title, content
|
||||
else
|
||||
return '', '', ''
|
||||
end
|
||||
rescue => e
|
||||
Rails.logger.info("MessageTemplate::IssueExpire.get_email_message_content [ERROR] #{e}")
|
||||
return '', '', ''
|
||||
end
|
||||
end
|
||||
|
|
@ -41,6 +41,7 @@ class MessageTemplate::OrganizationJoined < MessageTemplate
|
|||
content.gsub!('{baseurl}', base_url)
|
||||
content.gsub!('{login}', organization&.login)
|
||||
content.gsub!('{organization}', organization&.real_name)
|
||||
content.gsub!('{platform}', PLATFORM)
|
||||
|
||||
return receiver&.mail, title, content
|
||||
else
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ class MessageTemplate::OrganizationLeft < MessageTemplate
|
|||
content.gsub!('{baseurl}', base_url)
|
||||
content.gsub!('{login}', organization&.login)
|
||||
content.gsub!('{organization}', organization&.real_name)
|
||||
content.gsub!('{platform}', PLATFORM)
|
||||
|
||||
return receiver&.mail, title, content
|
||||
else
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ class MessageTemplate::OrganizationRole < MessageTemplate
|
|||
content.gsub!('{login}', organization&.login)
|
||||
content.gsub!('{organization}', organization&.real_name)
|
||||
content.gsub!('{role}', role)
|
||||
content.gsub!('{platform}', PLATFORM)
|
||||
|
||||
return receiver&.mail, title, content
|
||||
else
|
||||
|
|
|
|||
|
|
@ -12,11 +12,21 @@
|
|||
# email_title :string(255)
|
||||
#
|
||||
|
||||
# TODO 我管理的仓库被复刻
|
||||
# 我管理的仓库被复刻
|
||||
class MessageTemplate::ProjectForked < MessageTemplate
|
||||
|
||||
# MessageTemplate::ProjectForked.get_message_content(User.where(login: 'yystopf'))
|
||||
def self.get_message_content(receivers)
|
||||
def self.get_message_content(receivers, user, project)
|
||||
receivers.each do |receiver|
|
||||
if receiver.user_template_message_setting.present?
|
||||
send_setting = receiver.user_template_message_setting.notification_body["ManageProject::Forked"]
|
||||
send_setting = send_setting.nil? ? UserTemplateMessageSetting.init_notification_body["ManageProject::Forked"] : send_setting
|
||||
receivers = receivers.where.not(id: receiver.id) unless send_setting
|
||||
end
|
||||
end
|
||||
return '', '', '' if receivers.blank?
|
||||
content = sys_notice.gsub('{nickname1}', user&.real_name).gsub('{nickname2}', project&.owner&.real_name).gsub('{repository}', project&.name)
|
||||
url = notification_url.gsub('{owner}', user&.login).gsub('{identifier}', project&.identifier)
|
||||
return receivers_string(receivers), content, url
|
||||
rescue => e
|
||||
Rails.logger.info("MessageTemplate::ProjectForked.get_message_content [ERROR] #{e}")
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ class MessageTemplate::ProjectIssue < MessageTemplate
|
|||
content.gsub!('{identifier}', project&.identifier)
|
||||
content.gsub!('{id}', issue&.id.to_s)
|
||||
content.gsub!('{title}', issue&.subject)
|
||||
content.gsub!('{platform}', PLATFORM)
|
||||
|
||||
return receiver&.mail, title, content
|
||||
else
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ class MessageTemplate::ProjectJoined < MessageTemplate
|
|||
content.gsub!('{identifier}', project&.identifier)
|
||||
content.gsub!('{nickname}', project&.owner&.real_name)
|
||||
content.gsub!('{repository}', project&.name)
|
||||
content.gsub!('{platform}', PLATFORM)
|
||||
|
||||
return receiver&.mail, title, content
|
||||
else
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ class MessageTemplate::ProjectLeft < MessageTemplate
|
|||
content.gsub!('{identifier}', project&.identifier)
|
||||
content.gsub!('{nickname}', project&.owner&.real_name)
|
||||
content.gsub!('{repository}', project&.name)
|
||||
content.gsub!('{platform}', PLATFORM)
|
||||
|
||||
return receiver&.mail, title, content
|
||||
else
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ class MessageTemplate::ProjectMemberJoined < MessageTemplate
|
|||
content.gsub!('{nickname1}', user&.real_name)
|
||||
content.gsub!('{nickname2}', project&.owner&.real_name)
|
||||
content.gsub!('{repository}', project&.name)
|
||||
content.gsub!('{platform}', PLATFORM)
|
||||
|
||||
return receiver&.mail, title, content
|
||||
else
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ class MessageTemplate::ProjectMemberLeft < MessageTemplate
|
|||
content.gsub!('{nickname1}', user&.real_name)
|
||||
content.gsub!('{nickname2}', project&.owner&.real_name)
|
||||
content.gsub!('{repository}', project&.name)
|
||||
content.gsub!('{platform}', PLATFORM)
|
||||
|
||||
return receiver&.mail, title, content
|
||||
else
|
||||
|
|
|
|||
|
|
@ -12,14 +12,61 @@
|
|||
# email_title :string(255)
|
||||
#
|
||||
|
||||
# TODO 我管理的仓库有新的里程碑
|
||||
# 我管理的仓库有新的里程碑
|
||||
class MessageTemplate::ProjectMilestone < MessageTemplate
|
||||
|
||||
# MessageTemplate::ProjectMilestone.get_message_content(User.where(login: 'yystopf'))
|
||||
def self.get_message_content(receivers)
|
||||
def self.get_message_content(receivers, operator, milestone)
|
||||
receivers.each do |receiver|
|
||||
if receiver.user_template_message_setting.present?
|
||||
send_setting = receiver.user_template_message_setting.notification_body["ManageProject::Milestone"]
|
||||
send_setting = send_setting.nil? ? UserTemplateMessageSetting.init_notification_body["ManageProject::Milestone"] : send_setting
|
||||
receivers = receivers.where.not(id: receiver.id) unless receiver.user_template_message_setting.notification_body["ManageProject::Milestone"]
|
||||
end
|
||||
end
|
||||
return '', '', '' if receivers.blank?
|
||||
project = milestone&.project
|
||||
owner = project&.owner
|
||||
content = sys_notice.gsub('{nickname1}', operator&.real_name).gsub('{nickname2}', owner&.real_name).gsub('{repository}', project&.name).gsub('{name}', milestone&.name)
|
||||
url = notification_url.gsub('{owner}', owner&.login).gsub('{identifier}', project&.identifier).gsub('{id}', milestone&.id.to_s)
|
||||
|
||||
return receivers_string(receivers), content, url
|
||||
rescue => e
|
||||
Rails.logger.info("MessageTemplate::ProjectMilestone.get_message_content [ERROR] #{e}")
|
||||
return '', '', ''
|
||||
end
|
||||
|
||||
def self.get_email_message_content(receiver, operator, milestone)
|
||||
if receiver.user_template_message_setting.present?
|
||||
send_setting = receiver.user_template_message_setting.email_body["ManageProject::Milestone"]
|
||||
send_setting = send_setting.nil? ? UserTemplateMessageSetting.init_email_body["ManageProject::Milestone"] : send_setting
|
||||
return '', '', '' unless send_setting
|
||||
project = milestone&.project
|
||||
owner = project&.owner
|
||||
title = email_title
|
||||
title.gsub!('{nickname1}', operator&.real_name)
|
||||
title.gsub!('{nickname2}', owner&.real_name)
|
||||
title.gsub!('{repository}', project&.name)
|
||||
|
||||
content = email
|
||||
content.gsub!('{receiver}', receiver&.real_name)
|
||||
content.gsub!('{baseurl}', base_url)
|
||||
content.gsub!('{nickname1}', operator&.real_name)
|
||||
content.gsub!('{nickname2}', owner&.real_name)
|
||||
content.gsub!('{repository}', project&.name)
|
||||
content.gsub!('{login}', owner&.login)
|
||||
content.gsub!('{identifier}', project&.identifier)
|
||||
content.gsub!('{id}', milestone&.id.to_s)
|
||||
content.gsub!('{name}', milestone&.name)
|
||||
content.gsub!('{platform}', PLATFORM)
|
||||
|
||||
return receiver&.mail, title, content
|
||||
else
|
||||
return '', '', ''
|
||||
end
|
||||
|
||||
rescue => e
|
||||
Rails.logger.info("MessageTemplate::ProjectMilestone.get_email_message_content [ERROR] #{e}")
|
||||
return '', '', ''
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,70 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: message_templates
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# type :string(255)
|
||||
# sys_notice :text(65535)
|
||||
# email :text(65535)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# notification_url :string(255)
|
||||
# email_title :string(255)
|
||||
#
|
||||
|
||||
# 我管理的仓库有里程碑完成
|
||||
class MessageTemplate::ProjectMilestoneCompleted < MessageTemplate
|
||||
|
||||
# MessageTemplate::ProjectMilestoneCompleted.get_message_content(User.where(login: 'yystopf'))
|
||||
def self.get_message_content(receivers, milestone)
|
||||
receivers.each do |receiver|
|
||||
if receiver.user_template_message_setting.present?
|
||||
send_setting = receiver.user_template_message_setting.notification_body["ManageProject::MilestoneCompleted"]
|
||||
send_setting = send_setting.nil? ? UserTemplateMessageSetting.init_notification_body["ManageProject::MilestoneCompleted"] : send_setting
|
||||
receivers = receivers.where.not(id: receiver.id) unless send_setting
|
||||
end
|
||||
end
|
||||
return '', '', '' if receivers.blank?
|
||||
project = milestone&.project
|
||||
owner = project&.owner
|
||||
content = sys_notice.gsub('{nickname}', owner&.real_name).gsub('{repository}', project&.name).gsub('{name}', milestone&.name)
|
||||
url = notification_url.gsub('{owner}', owner&.login).gsub('{identifier}', project&.identifier).gsub('{id}', milestone&.id.to_s)
|
||||
|
||||
return receivers_string(receivers), content, url
|
||||
rescue => e
|
||||
Rails.logger.info("MessageTemplate::ProjectMilestoneCompleted.get_message_content [ERROR] #{e}")
|
||||
return '', '', ''
|
||||
end
|
||||
|
||||
def self.get_email_message_content(receiver, milestone)
|
||||
if receiver.user_template_message_setting.present?
|
||||
send_setting = receiver.user_template_message_setting.email_body["ManageProject::MilestoneCompleted"]
|
||||
send_setting = send_setting.nil? ? UserTemplateMessageSetting.init_email_body["ManageProject::MilestoneCompleted"] : send_setting
|
||||
return '', '', '' unless send_setting
|
||||
project = milestone&.project
|
||||
owner = project&.owner
|
||||
title = email_title
|
||||
title.gsub!('{nickname}', owner&.real_name)
|
||||
title.gsub!('{repository}', project&.name)
|
||||
|
||||
content = email
|
||||
content.gsub!('{receiver}', receiver&.real_name)
|
||||
content.gsub!('{baseurl}', base_url)
|
||||
content.gsub!('{nickname}', owner&.real_name)
|
||||
content.gsub!('{repository}', project&.name)
|
||||
content.gsub!('{login}', owner&.login)
|
||||
content.gsub!('{identifier}', project&.identifier)
|
||||
content.gsub!('{id}', milestone&.id.to_s)
|
||||
content.gsub!('{name}', milestone&.name)
|
||||
content.gsub!('{platform}', PLATFORM)
|
||||
|
||||
return receiver&.mail, title, content
|
||||
else
|
||||
return '', '', ''
|
||||
end
|
||||
|
||||
rescue => e
|
||||
Rails.logger.info("MessageTemplate::ProjectMilestoneCompleted.get_email_message_content [ERROR] #{e}")
|
||||
return '', '', ''
|
||||
end
|
||||
end
|
||||
|
|
@ -12,11 +12,21 @@
|
|||
# email_title :string(255)
|
||||
#
|
||||
|
||||
# TODO 我管理的仓库被点赞
|
||||
# 我管理的仓库被点赞
|
||||
class MessageTemplate::ProjectPraised < MessageTemplate
|
||||
|
||||
# MessageTemplate::ProjectPraised.get_message_content(User.where(login: 'yystopf'))
|
||||
def self.get_message_content(receivers)
|
||||
def self.get_message_content(receivers, user, project)
|
||||
receivers.each do |receiver|
|
||||
if receiver.user_template_message_setting.present?
|
||||
send_setting = receiver.user_template_message_setting.notification_body["ManageProject::Praised"]
|
||||
send_setting = send_setting.nil? ? UserTemplateMessageSetting.init_notification_body["ManageProject::Praised"] : send_setting
|
||||
receivers = receivers.where.not(id: receiver.id) unless send_setting
|
||||
end
|
||||
end
|
||||
return '', '', '' if receivers.blank?
|
||||
content = sys_notice.gsub('{nickname1}', user&.real_name).gsub('{nickname2}', project&.owner&.real_name).gsub('{repository}', project&.name)
|
||||
url = notification_url.gsub('{login}', user&.login)
|
||||
return receivers_string(receivers), content, url
|
||||
rescue => e
|
||||
Rails.logger.info("MessageTemplate::ProjectPraised.get_message_content [ERROR] #{e}")
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ class MessageTemplate::ProjectPullRequest < MessageTemplate
|
|||
content.gsub!('{identifier}', project&.identifier)
|
||||
content.gsub!('{id}', pull_request&.id.to_s)
|
||||
content.gsub!('{title}', pull_request&.title)
|
||||
content.gsub!('{platform}', PLATFORM)
|
||||
|
||||
return receiver&.mail, title, content
|
||||
else
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ class MessageTemplate::ProjectRole < MessageTemplate
|
|||
content.gsub!('{identifier}', project&.identifier)
|
||||
content.gsub!('{repository}', project&.name)
|
||||
content.gsub!('{role}', role)
|
||||
content.gsub!('{platform}', PLATFORM)
|
||||
|
||||
return receiver&.mail, title, content
|
||||
else
|
||||
|
|
|
|||
|
|
@ -300,6 +300,7 @@ class MessageTemplate::ProjectSettingChanged < MessageTemplate
|
|||
else
|
||||
content.gsub!(/({ifnavbar})(.*)({endnavbar})/, '')
|
||||
end
|
||||
content.gsub!('{platform}', PLATFORM)
|
||||
|
||||
return receiver&.mail, title, content
|
||||
else
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ class MessageTemplate::PullRequestAssigned < MessageTemplate
|
|||
content.gsub!('{baseurl}', base_url)
|
||||
content.gsub!('{title}', pull_request&.title)
|
||||
content.gsub!('{id}', pull_request&.id.to_s)
|
||||
content.gsub!('{platform}', PLATFORM)
|
||||
|
||||
return receiver&.mail, title, content
|
||||
else
|
||||
|
|
|
|||
|
|
@ -118,6 +118,7 @@ class MessageTemplate::PullRequestChanged < MessageTemplate
|
|||
content.gsub!('{baseurl}', base_url)
|
||||
content.gsub!('{title}', pull_request&.title)
|
||||
content.gsub!('{id}', pull_request&.id.to_s)
|
||||
content.gsub!('{platform}', PLATFORM)
|
||||
|
||||
change_count = change_params.keys.size
|
||||
# 合并请求审查成员修改
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ class MessageTemplate::PullRequestClosed < MessageTemplate
|
|||
content.gsub!('{baseurl}', base_url)
|
||||
content.gsub!('{title}', pull_request&.title)
|
||||
content.gsub!('{id}', pull_request&.id.to_s)
|
||||
content.gsub!('{platform}', PLATFORM)
|
||||
|
||||
return receiver&.mail, title, content
|
||||
else
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ class MessageTemplate::PullRequestMerged < MessageTemplate
|
|||
content.gsub!('{baseurl}', base_url)
|
||||
content.gsub!('{title}', pull_request&.title)
|
||||
content.gsub!('{id}', pull_request&.id.to_s)
|
||||
content.gsub!('{platform}', PLATFORM)
|
||||
|
||||
return receiver&.mail, title, content
|
||||
else
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ class MessageTemplate::TeamJoined < MessageTemplate
|
|||
content.gsub!('{organization}', organization&.real_name)
|
||||
content.gsub!('{team}', team&.nickname)
|
||||
content.gsub!('{role}', team&.authorize_name)
|
||||
content.gsub!('{platform}', PLATFORM)
|
||||
|
||||
return receiver&.mail, title, content
|
||||
else
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ class MessageTemplate::TeamLeft < MessageTemplate
|
|||
content.gsub!('{organization}', organization&.real_name)
|
||||
content.gsub!('{team}', team&.nickname)
|
||||
content.gsub!('{role}', team&.authorize_name)
|
||||
content.gsub!('{platform}', PLATFORM)
|
||||
|
||||
return receiver&.mail, title, content
|
||||
else
|
||||
|
|
|
|||
|
|
@ -83,6 +83,10 @@ class Organization < Owner
|
|||
|
||||
after_save :reset_cache_data
|
||||
|
||||
def gitea_token
|
||||
team_users.joins(:team).where(teams: {authorize: "owner"}).take&.user&.gitea_token
|
||||
end
|
||||
|
||||
def reset_cache_data
|
||||
Cache::V2::OwnerCommonService.new(self.id).reset
|
||||
end
|
||||
|
|
|
|||
|
|
@ -129,8 +129,8 @@ class Project < ApplicationRecord
|
|||
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_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
|
||||
after_save :check_project_members
|
||||
before_save :set_invite_code, :reset_unmember_followed, :set_recommend_and_is_pinned, :reset_cache_data
|
||||
before_destroy :decre_project_common, :decre_forked_from_project_count
|
||||
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)}
|
||||
|
|
@ -154,7 +154,7 @@ class Project < ApplicationRecord
|
|||
end
|
||||
|
||||
def reset_cache_data
|
||||
CacheAsyncResetJob.perform_later("project_common_service", self.id)
|
||||
CacheAsyncResetJob.set(wait: 5.seconds).perform_later("project_common_service", self.id)
|
||||
if changes[:user_id].present?
|
||||
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)
|
||||
|
|
@ -167,6 +167,14 @@ class Project < ApplicationRecord
|
|||
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
|
||||
if changes[:is_public].present?
|
||||
if changes[:is_public][0] && !changes[:is_public][1]
|
||||
CacheAsyncClearJob.perform_later('project_rank_service', self.id)
|
||||
end
|
||||
if !changes[:is_public][0] && changes[:is_public][1]
|
||||
$redis_cache.srem("v2-project-rank-deleted", self.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def decre_project_common
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
# Table name: pull_requests
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# pull_request_id :integer
|
||||
# gpid :integer
|
||||
# gitea_id :integer
|
||||
# gitea_number :integer
|
||||
# user_id :integer
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
|
|
@ -12,7 +12,7 @@
|
|||
# project_id :integer
|
||||
# title :string(255)
|
||||
# milestone :integer
|
||||
# body :text(65535)
|
||||
# body :text(4294967295)
|
||||
# head :string(255)
|
||||
# base :string(255)
|
||||
# issue_id :integer
|
||||
|
|
|
|||
|
|
@ -29,6 +29,11 @@ class Team < ApplicationRecord
|
|||
has_many :team_units, dependent: :destroy
|
||||
has_many :team_users, dependent: :destroy
|
||||
|
||||
scope :like, lambda { |keywords|
|
||||
sql = "teams.nickname LIKE :search OR teams.name LIKE :search"
|
||||
where(sql, :search => "%#{keywords.split(" ").join('|')}%") unless keywords.blank?
|
||||
}
|
||||
|
||||
validates :name, uniqueness: {scope: :organization_id}
|
||||
|
||||
enum authorize: {read: 1, write: 2, admin: 3, owner: 4}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ class TeamUser < ApplicationRecord
|
|||
before_destroy :remove_project_member
|
||||
|
||||
def self.build(organization_id, user_id, team_id)
|
||||
self.create!(organization_id: organization_id, user_id: user_id, team_id: team_id)
|
||||
self.find_or_create_by!(organization_id: organization_id, user_id: user_id, team_id: team_id)
|
||||
end
|
||||
|
||||
def remove_project_member
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ class TemplateMessageSetting < ApplicationRecord
|
|||
end
|
||||
|
||||
def self.build_init_data
|
||||
TemplateMessageSetting.destroy_all
|
||||
TemplateMessageSetting::CreateOrAssign.build_init_data
|
||||
TemplateMessageSetting::ManageProject.build_init_data
|
||||
TemplateMessageSetting::Normal.build_init_data
|
||||
|
|
|
|||
|
|
@ -27,5 +27,6 @@ class TemplateMessageSetting::CreateOrAssign < TemplateMessageSetting
|
|||
def self.build_init_data
|
||||
self.find_or_create_by(name: "疑修状态变更", key: "IssueChanged")
|
||||
self.find_or_create_by(name: "合并请求状态变更", key: "PullRequestChanged")
|
||||
self.find_or_create_by(name: "疑修截止日期到达最后一天", key: "IssueExpire", notification_disabled: false)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -29,5 +29,9 @@ class TemplateMessageSetting::ManageProject < TemplateMessageSetting
|
|||
self.find_or_create_by(name: "有新的合并请求", key: "PullRequest")
|
||||
self.find_or_create_by(name: "有成员变动", key: "Member")
|
||||
self.find_or_create_by(name: "仓库设置被更改", key: "SettingChanged")
|
||||
self.find_or_create_by(name: "被点赞", key: "Praised", notification_disabled: false, email_disabled: true)
|
||||
self.find_or_create_by(name: "被fork", key: "Forked", notification_disabled: false, email_disabled: true)
|
||||
self.find_or_create_by(name: "有新的里程碑", key: "Milestone", notification_disabled: false)
|
||||
self.find_or_create_by(name: "有里程碑已完成", key: "MilestoneCompleted", notification_disabled: false)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: trace_users
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# user_id :integer
|
||||
# username :string(255)
|
||||
# password :string(255)
|
||||
# unit :string(255)
|
||||
# telnumber :string(255)
|
||||
# email :string(255)
|
||||
# name :string(255)
|
||||
# token :text(65535)
|
||||
# expired_at :datetime
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_trace_users_on_user_id (user_id)
|
||||
#
|
||||
|
||||
# 代码溯源 用户
|
||||
class TraceUser < ApplicationRecord
|
||||
|
||||
belongs_to :user
|
||||
|
||||
|
||||
def build_self_data
|
||||
return if user.nil?
|
||||
|
||||
self.username = user.login
|
||||
self.password = SecureRandom.hex
|
||||
self.unit = user.custom_department.blank? ? 'GitLink' : user.custom_department
|
||||
self.telnumber = user.phone.blank? ? '13800000000' : user.phone
|
||||
self.email = user.mail
|
||||
self.name = user.nickname.blank? ? user.login : user.nickname
|
||||
|
||||
self
|
||||
end
|
||||
|
||||
|
||||
def build_token
|
||||
return if username.blank? || password.blank? || unit.blank? || telnumber.blank? || email.blank? || name.blank?
|
||||
|
||||
response = Trace::AddUserService.call(username, password, unit, telnumber, email, name)
|
||||
self.token = response[1]['token']
|
||||
self.expired_at = Time.now + 1.hours
|
||||
end
|
||||
|
||||
def refresh_token
|
||||
return if username.blank? || password.blank? || unit.blank? || telnumber.blank? || email.blank? || name.blank?
|
||||
|
||||
response = Trace::LoginService.call(username, password)
|
||||
self.token = response[1]['token']
|
||||
self.expired_at = Time.now + 1.hours
|
||||
end
|
||||
end
|
||||
|
|
@ -173,6 +173,7 @@ class User < Owner
|
|||
|
||||
has_many :system_notification_histories
|
||||
has_many :system_notifications, through: :system_notification_histories
|
||||
has_one :trace_user, dependent: :destroy
|
||||
|
||||
# Groups and active users
|
||||
scope :active, lambda { where(status: STATUS_ACTIVE) }
|
||||
|
|
@ -186,7 +187,7 @@ class User < Owner
|
|||
attr_accessor :password, :password_confirmation
|
||||
|
||||
delegate :description, :gender, :department_id, :school_id, :location, :location_city,
|
||||
:show_email, :show_location, :show_department,
|
||||
:show_email, :show_location, :show_department, :super_description, :show_super_description,
|
||||
:technical_title, :province, :city, :custom_department, to: :user_extension, allow_nil: true
|
||||
|
||||
before_save :update_hashed_password, :set_lastname
|
||||
|
|
@ -776,6 +777,24 @@ class User < Owner
|
|||
self.nickname.present? && self.mail.present?
|
||||
end
|
||||
|
||||
def trace_token
|
||||
if trace_user.present?
|
||||
if trace_user.expired_at < Time.now
|
||||
trace_user.refresh_token
|
||||
trace_user.save
|
||||
end
|
||||
return trace_user.token
|
||||
else
|
||||
tu = TraceUser.new
|
||||
tu.user = self
|
||||
tu.build_self_data
|
||||
tu.build_token
|
||||
tu.save
|
||||
|
||||
return tu.token
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
def validate_password_length
|
||||
# 管理员的初始密码是5位
|
||||
|
|
|
|||
|
|
@ -2,35 +2,34 @@
|
|||
#
|
||||
# Table name: user_extensions
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# user_id :integer not null
|
||||
# birthday :date
|
||||
# brief_introduction :string(255)
|
||||
# gender :integer
|
||||
# location :string(255)
|
||||
# occupation :string(255)
|
||||
# work_experience :integer
|
||||
# zip_code :integer
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# technical_title :string(255)
|
||||
# identity :integer
|
||||
# student_id :string(255)
|
||||
# teacher_realname :string(255)
|
||||
# student_realname :string(255)
|
||||
# location_city :string(255)
|
||||
# school_id :integer
|
||||
# description :string(255) default("")
|
||||
# department_id :integer
|
||||
# honor :text(65535)
|
||||
# edu_background :integer
|
||||
# edu_entry_year :integer
|
||||
# province :string(255)
|
||||
# city :string(255)
|
||||
# custom_department :string(255)
|
||||
# show_email :boolean default("0")
|
||||
# show_location :boolean default("0")
|
||||
# show_department :boolean default("0")
|
||||
# id :integer not null, primary key
|
||||
# user_id :integer not null
|
||||
# birthday :date
|
||||
# brief_introduction :string(255)
|
||||
# gender :integer
|
||||
# location :string(255)
|
||||
# occupation :string(255)
|
||||
# work_experience :integer
|
||||
# zip_code :integer
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# technical_title :string(255)
|
||||
# identity :integer
|
||||
# student_id :string(255)
|
||||
# teacher_realname :string(255)
|
||||
# student_realname :string(255)
|
||||
# location_city :string(255)
|
||||
# school_id :integer
|
||||
# description :string(255) default("")
|
||||
# department_id :integer
|
||||
# province :string(255)
|
||||
# city :string(255)
|
||||
# custom_department :string(255)
|
||||
# show_email :boolean default("0")
|
||||
# show_location :boolean default("0")
|
||||
# show_department :boolean default("0")
|
||||
# super_description :text(4294967295)
|
||||
# show_super_description :boolean default("0")
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
|
|
|
|||
|
|
@ -35,10 +35,15 @@ class UserTemplateMessageSetting < ApplicationRecord
|
|||
"Normal::PullRequestAssigned": true,
|
||||
"CreateOrAssign::IssueChanged": true,
|
||||
"CreateOrAssign::PullRequestChanged": true,
|
||||
"CreateOrAssign::IssueExpire": true,
|
||||
"ManageProject::Issue": true,
|
||||
"ManageProject::PullRequest": true,
|
||||
"ManageProject::Member": true,
|
||||
"ManageProject::SettingChanged": true,
|
||||
"ManageProject::Praised": true,
|
||||
"ManageProject::Forked": true,
|
||||
"ManageProject::Milestone": true,
|
||||
"ManageProject::MilestoneCompleted": true,
|
||||
}.stringify_keys!
|
||||
end
|
||||
|
||||
|
|
@ -51,10 +56,15 @@ class UserTemplateMessageSetting < ApplicationRecord
|
|||
"Normal::PullRequestAssigned": false,
|
||||
"CreateOrAssign::IssueChanged": false,
|
||||
"CreateOrAssign::PullRequestChanged": false,
|
||||
"CreateOrAssign::IssueExpire": false,
|
||||
"ManageProject::Issue": false,
|
||||
"ManageProject::PullRequest": false,
|
||||
"ManageProject::Member": false,
|
||||
"ManageProject::SettingChanged": false,
|
||||
"ManageProject::Praised": false,
|
||||
"ManageProject::Forked": false,
|
||||
"ManageProject::Milestone": false,
|
||||
"ManageProject::MilestoneCompleted": false,
|
||||
}.stringify_keys!
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -40,8 +40,19 @@ class Version < ApplicationRecord
|
|||
# issues.select(:id,:status_id).where(status_id: 5).size
|
||||
# end
|
||||
|
||||
after_create :send_create_message_to_notice_system
|
||||
after_save :send_update_message_to_notice_system
|
||||
|
||||
def version_user
|
||||
User.select(:login, :lastname,:firstname, :nickname)&.find_by_id(self.user_id)
|
||||
end
|
||||
|
||||
private
|
||||
def send_create_message_to_notice_system
|
||||
SendTemplateMessageJob.perform_later('ProjectMilestone', self.id, self.user_id) if Site.has_notice_menu?
|
||||
end
|
||||
|
||||
def send_update_message_to_notice_system
|
||||
SendTemplateMessageJob.perform_later('ProjectMilestoneCompleted', self.id) if Site.has_notice_menu? && self.percent == 1.0
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,71 @@
|
|||
class Admins::ImportUserFromExcelService < 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::NewImportUserFromExcel.new(file)
|
||||
|
||||
excel.read_each(&method(:save_user))
|
||||
result
|
||||
rescue ApplicationImport::Error => ex
|
||||
raise Error, ex.message
|
||||
end
|
||||
|
||||
private
|
||||
def save_user(data)
|
||||
user = find_user(data)
|
||||
if user.blank?
|
||||
create_user(data)
|
||||
result[:success] +=1
|
||||
else
|
||||
fail_data = data.as_json
|
||||
fail_data[:data] = fail_data.values.join(",")
|
||||
fail_data[:message] = '用户已存在'
|
||||
result[:fail] << fail_data
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
def create_user(data)
|
||||
ActiveRecord::Base.transaction do
|
||||
username = data.login&.gsub(/\s+/, "")
|
||||
email = data.email&.gsub(/\s+/, "")
|
||||
password = data.password
|
||||
nickname = data.nickname&.gsub(/\s+/, "")
|
||||
raise Error, "无法使用以下关键词:#{username},请重新命名" if ReversedKeyword.check_exists?(data.login)
|
||||
Register::RemoteForm.new({username: username, email: email, password: password, platform: 'forge'}).validate!
|
||||
user = User.new(admin: false, login: username, mail: email, nickname: nickname, platform: 'forge' , type: "User")
|
||||
user.password = password
|
||||
user.activate
|
||||
raise Error, user.errors.full_messages.join(",") unless user.valid?
|
||||
interactor = Gitea::RegisterInteractor.call({username: username, email: email, password: password})
|
||||
if interactor.success?
|
||||
gitea_user = interactor.result
|
||||
result = Gitea::User::GenerateTokenService.call(username, password)
|
||||
user.gitea_token = result['sha1']
|
||||
user.gitea_uid = gitea_user[:body]['id']
|
||||
UserExtension.create!(user_id: user.id) if user.save!
|
||||
else
|
||||
raise interactor.error, 'gitea user create error'
|
||||
end
|
||||
|
||||
user
|
||||
end
|
||||
end
|
||||
|
||||
def find_user(data)
|
||||
User.find_by(login: data.login)
|
||||
end
|
||||
end
|
||||
|
|
@ -1,17 +1,18 @@
|
|||
class Branches::ListService < ApplicationService
|
||||
|
||||
attr_reader :user, :project
|
||||
attr_reader :user, :project, :name
|
||||
|
||||
def initialize(user, project)
|
||||
def initialize(user, project, name=nil)
|
||||
@user = user
|
||||
@project = project
|
||||
@name = name
|
||||
end
|
||||
|
||||
def call
|
||||
all_branches = []
|
||||
user_name = user.try(:show_real_name)
|
||||
identifier = project.repository.try(:identifier)
|
||||
get_all_branches = Gitea::Repository::Branches::ListService.new(user, identifier).call
|
||||
get_all_branches = Gitea::Repository::Branches::ListService.new(user, identifier, name).call
|
||||
all_branches = branch_lists(user_name,user.try(:login), identifier, get_all_branches) if get_all_branches && get_all_branches.size > 0
|
||||
return all_branches
|
||||
end
|
||||
|
|
|
|||
|
|
@ -16,15 +16,15 @@ class Cache::V2::UserDateRankService < ApplicationService
|
|||
end
|
||||
|
||||
def read_rank
|
||||
user_rank
|
||||
user_rank unless @user_id.blank?
|
||||
end
|
||||
|
||||
def read_statistic
|
||||
user_statistic
|
||||
user_statistic unless @user_id.blank?
|
||||
end
|
||||
|
||||
def call
|
||||
set_user_rank
|
||||
set_user_rank unless @user_id.blank?
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ 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.timeout = 1200 # open/read timeout in seconds
|
||||
req.options.open_timeout = 10 # connection open timeout in seconds
|
||||
if token.blank?
|
||||
req.basic_auth(username, secret)
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
class Gitea::Repository::Branches::ListNameService < Gitea::ClientService
|
||||
attr_reader :user, :repo
|
||||
attr_reader :user, :repo, :name
|
||||
|
||||
def initialize(user, repo)
|
||||
def initialize(user, repo, name=nil)
|
||||
@user = user
|
||||
@repo = repo
|
||||
@name = name
|
||||
end
|
||||
|
||||
def call
|
||||
|
|
@ -13,7 +14,7 @@ class Gitea::Repository::Branches::ListNameService < Gitea::ClientService
|
|||
|
||||
private
|
||||
def params
|
||||
Hash.new.merge(token: user.gitea_token)
|
||||
Hash.new.merge(token: user.gitea_token, name: name)
|
||||
end
|
||||
|
||||
def url
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
class Gitea::Repository::Branches::ListService < Gitea::ClientService
|
||||
attr_reader :user, :repo
|
||||
attr_reader :user, :repo, :name
|
||||
|
||||
def initialize(user, repo)
|
||||
def initialize(user, repo, name=nil)
|
||||
@user = user
|
||||
@repo = repo
|
||||
@name = name
|
||||
end
|
||||
|
||||
def call
|
||||
|
|
@ -13,7 +14,7 @@ class Gitea::Repository::Branches::ListService < Gitea::ClientService
|
|||
|
||||
private
|
||||
def params
|
||||
Hash.new.merge(token: user.gitea_token)
|
||||
Hash.new.merge(token: user.gitea_token, name: name)
|
||||
end
|
||||
|
||||
def url
|
||||
|
|
|
|||
|
|
@ -28,11 +28,11 @@ class Issues::ListQueryService < ApplicationService
|
|||
end
|
||||
|
||||
if search_name.present?
|
||||
issues = issues.where("subject LIKE ? OR description LIKE ? ", "%#{search_name}%", "%#{search_name}%")
|
||||
issues = issues.where("issues.subject LIKE ? OR issues.description LIKE ? ", "%#{search_name}%", "%#{search_name}%")
|
||||
end
|
||||
|
||||
if start_time&.present? || end_time&.present?
|
||||
issues = issues.where("start_date between ? and ?",start_time&.present? ? start_time.to_date : Time.now.to_date, end_time&.present? ? end_time.to_date : Time.now.to_date)
|
||||
issues = issues.where("issues.start_date between ? and ?",start_time&.present? ? start_time.to_date : Time.now.to_date, end_time&.present? ? end_time.to_date : Time.now.to_date)
|
||||
end
|
||||
|
||||
issues = issues.where(author_id: params[:author_id]) if params[:author_id].present? && params[:author_id].to_s != "all"
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue