邮件邀请:

1、修改私有项目跳入403问题
2、增加同一个用户反复邀请的邮箱提醒。
3、修改邮箱的发送策略
tmp
huang 10 years ago
parent 9189ddd63b
commit b0ccf9037a

@ -33,7 +33,7 @@ class ProjectsController < ApplicationController
before_filter :require_admin, :only => [ :copy, :archive, :unarchive, :destroy, :calendar] before_filter :require_admin, :only => [ :copy, :archive, :unarchive, :destroy, :calendar]
before_filter :file, :statistics #:watcherlist before_filter :file, :statistics #:watcherlist
# 除非项目内人员,不可查看成员, TODO: 完了写报表里去 # 除非项目内人员,不可查看成员, TODO: 完了写报表里去
before_filter :memberAccess, only: :member # before_filter :memberAccess, only: :member
# accept_rss_auth :index # accept_rss_auth :index
accept_api_auth :index, :show, :create, :update, :destroy accept_api_auth :index, :show, :create, :update, :destroy
@ -360,21 +360,27 @@ class ProjectsController < ApplicationController
# 两种情况1、系统外用户2、系统内用户 (通过邮件判定) # 两种情况1、系统外用户2、系统内用户 (通过邮件判定)
def send_mail_to_member def send_mail_to_member
# 该邮箱未注册过 # 该邮箱未注册过
if !params[:mail].blank? && User.find_by_mail(params[:mail].to_s).nil? && User.where("login =?", params[:mail]).first.nil? if !params[:mail].blank? && User.find_by_mail(params[:mail].to_s).nil?
if !User.where("login =?", params[:mail]).first.nil?
# 用户名唯一,如果该邮箱被用户作为用户名使用则跳出
flash[:error] = l(:notice_email_login_used)
else
email = params[:mail] email = params[:mail]
Mailer.run.send_invite_in_project(email, @project, User.current) Mailer.send_invite_in_project(email, @project, User.current).deliver
@is_zhuce = false @is_zhuce = false
flash[:notice] = l(:notice_email_sent, :value => email) flash[:notice] = l(:notice_email_sent, :value => email)
# 用户名唯一,如果该邮箱被用户作为用户名使用则跳出 end
elsif !User.where("login =?", params[:mail]).first.nil?
flash[:error] = l(:notice_email_login_used)
# 已经是系统注册用户
elsif !User.find_by_mail(params[:mail].to_s).nil? elsif !User.find_by_mail(params[:mail].to_s).nil?
user = User.find_by_mail(params[:mail].to_s) user = User.find_by_mail(params[:mail].to_s)
if !user.member_of?(@project) if !user.member_of?(@project)
# 如果已经邀请过该用户,则不重复发送
if InviteList.where("project_id =? and mail =?", @project.id, params[:mail].to_s).first.nil?
email = params[:mail] email = params[:mail]
Mailer.run.request_member_to_project(email, @project, User.current) Mailer.request_member_to_project(email, @project, User.current).deliver
flash[:notice] = l(:notice_email_sent, :value => email) flash[:notice] = l(:notice_email_sent, :value => email)
else
flash[:error] = l(:notice_email_invited)
end
else else
flash[:error] = l(:label_member_of_project, :value => email) flash[:error] = l(:label_member_of_project, :value => email)
end end
@ -455,6 +461,10 @@ class ProjectsController < ApplicationController
flash[:notice] = l(:label_mail_invite_success) flash[:notice] = l(:label_mail_invite_success)
end end
end end
unless @project.is_public?
return render_403 unless User.current.member_of?(@project)
end
## 有角色参数的才是课程,没有的就是项目 ## 有角色参数的才是课程,没有的就是项目
@render_file = 'project_member_list' @render_file = 'project_member_list'
# 判断是否课程 # 判断是否课程

@ -1,5 +1,5 @@
class InviteList < ActiveRecord::Base class InviteList < ActiveRecord::Base
attr_accessible :project_id, :user_id attr_accessible :project_id, :user_id, :mail
belongs_to :user belongs_to :user
belongs_to :project belongs_to :project

@ -59,8 +59,8 @@ class Mailer < ActionMailer::Base
login = login.sub(/%40/,'@') login = login.sub(/%40/,'@')
us = UsersService.new us = UsersService.new
# 自动激活用户 # 自动激活用户
user = us.register_auto(login, @email, @password) user = us.register_auto(login, email, @password)
InviteList.create(:user_id => user.id, :project_id => project.id) InviteList.create(:user_id => user.id, :project_id => project.id, :mail =>email)
User.current = user unless User.current.nil? User.current = user unless User.current.nil?
@user = user @user = user
@token = Token.get_token_from_user(user, 'autologin') @token = Token.get_token_from_user(user, 'autologin')
@ -76,9 +76,8 @@ class Mailer < ActionMailer::Base
@project_name = "#{project.name}" @project_name = "#{project.name}"
@user = user @user = user
@project = project @project = project
inviter_lists = InviteList.where(project_id:@project.id, user_id:@user.id).all if InviteList.where("project_id= ? and user_id =? and mail =?", project.id, @user.id, email).first.nil?
if inviter_lists.blank? InviteList.create(:user_id => user.id, :project_id => project.id, :mail => email)
InviteList.create(:user_id => user.id, :project_id => project.id)
end end
@token = Token.get_token_from_user(user, 'autologin') @token = Token.get_token_from_user(user, 'autologin')
@project_url = url_for(:controller => 'projects', :action => 'member', :id => project.id, :user_id => user.id, :mail => true, :token => @token.value) @project_url = url_for(:controller => 'projects', :action => 'member', :id => project.id, :user_id => user.id, :mail => true, :token => @token.value)

@ -30,6 +30,9 @@ class Member < ActiveRecord::Base
validate :validate_role validate :validate_role
before_destroy :set_issue_category_nil before_destroy :set_issue_category_nil
# 删除项目成员一并删除该成员的邀请记录
after_destroy :delete_ivite_list
def role def role
end end
@ -97,6 +100,16 @@ class Member < ActiveRecord::Base
end end
end end
# 删除成员一并删除该成员的邀请信息
def delete_ivite_list
member_invite_lists = InviteList.where("user_id =? and project_id =?", self.user_id, self.project_id)
unless member_invite_lists.nil?
member_invite_lists.each do |member_invite_list|
member_invite_list.destroy
end
end
end
# Find or initilize a Member with an id, attributes, and for a Principal # Find or initilize a Member with an id, attributes, and for a Principal
def self.edit_membership(id, new_attributes, principal=nil) def self.edit_membership(id, new_attributes, principal=nil)
@membership = id.present? ? Member.find(id) : Member.new(:principal => principal) @membership = id.present? ? Member.find(id) : Member.new(:principal => principal)

@ -66,8 +66,8 @@ class Project < ActiveRecord::Base
# has_many :students_for_courses, :dependent => :destroy # has_many :students_for_courses, :dependent => :destroy
has_many :student, :through => :students_for_courses, :source => :user has_many :student, :through => :students_for_courses, :source => :user
has_one :course_extra, :class_name => 'Course', :foreign_key => :extra,:primary_key => :identifier, :dependent => :destroy has_one :course_extra, :class_name => 'Course', :foreign_key => :extra,:primary_key => :identifier, :dependent => :destroy
has_many :applied_projects has_many :applied_projects, :dependent => :destroy
has_many :invite_lists has_many :invite_lists, :dependent => :destroy
has_one :dts has_one :dts
# end # end

@ -140,7 +140,7 @@ class User < Principal
has_many :issue_assigns, :class_name => 'ForgeMessage', :conditions => 'viewed=0 and forge_message_type="Issue"' has_many :issue_assigns, :class_name => 'ForgeMessage', :conditions => 'viewed=0 and forge_message_type="Issue"'
has_many :status_updates, :class_name => 'ForgeMessage', :conditions => 'viewed=0 and forge_message_type="Journal"' has_many :status_updates, :class_name => 'ForgeMessage', :conditions => 'viewed=0 and forge_message_type="Journal"'
# 邮件邀请状态 # 邮件邀请状态
# has_many :invite_lists has_many :invite_lists, :dependent => :destroy
# end # end
######added by nie ######added by nie
@ -213,6 +213,8 @@ class User < Principal
# added by fq # added by fq
after_create :act_as_activity, :add_onclick_time after_create :act_as_activity, :add_onclick_time
# end # end
# 更新邮箱用户或用户名的同事,同步更新邀请信息
after_update :update_invite_list
scope :in_group, lambda {|group| scope :in_group, lambda {|group|
group_id = group.is_a?(Group) ? group.id : group.to_i group_id = group.is_a?(Group) ? group.id : group.to_i
@ -1010,6 +1012,16 @@ class User < Principal
end end
end end
# 更新邮箱的同事更新invite_lists表中的邮箱信息
def update_invite_list
invite_lists = InviteList.where("user_id =?",self.id).all
unless invite_lists.blank?
invite_lists.each do |invite_list|
invite_list.update_attribute(:mail, self.mail)
end
end
end
# Removes references that are not handled by associations # Removes references that are not handled by associations
# Things that are not deleted are reassociated with the anonymous user # Things that are not deleted are reassociated with the anonymous user
def remove_references_before_destroy def remove_references_before_destroy

@ -224,9 +224,9 @@ development:
email_delivery: email_delivery:
delivery_method: :smtp delivery_method: :smtp
smtp_settings: smtp_settings:
address: mail.trustie.net address: smtp.163.com
port: 25 port: 25
domain: mail.trustie.net domain: smtp.163.com
authentication: :login authentication: :login
user_name: "mail@trustie.net" user_name: "huang.jingquan@163.com"
password: "loong2010" password: "xinhu1ji2qu366"

@ -52,7 +52,8 @@ zh:
notice_not_authorized_archived_project: 要访问的项目已经归档。 notice_not_authorized_archived_project: 要访问的项目已经归档。
notice_not_authorized_message: 您访问的消息不存在! notice_not_authorized_message: 您访问的消息不存在!
notice_email_sent: "邮件已发送至 %{value}" notice_email_sent: "邮件已发送至 %{value}"
notice_email_login_used: 该邮箱地址已经有人作为登录名使用! notice_email_login_used: 无法自动为该邮箱注册新用户,该邮箱地址已经有人作为登录名使用,您可以通过平台的注册功能为该用户注册账号!
notice_email_invited: 已经向该邮箱发送过邀请,正在等待对方的回复!
notice_email_error: "发送邮件时发生错误 (%{value})" notice_email_error: "发送邮件时发生错误 (%{value})"
notice_feeds_access_key_reseted: 您的RSS存取键已被重置。 notice_feeds_access_key_reseted: 您的RSS存取键已被重置。
notice_api_access_key_reseted: 您的API访问键已被重置。 notice_api_access_key_reseted: 您的API访问键已被重置。

@ -0,0 +1,5 @@
class AddMailToInviteList < ActiveRecord::Migration
def change
add_column :invite_lists, :mail, :string
end
end

@ -11,7 +11,7 @@
# #
# It's strongly recommended to check this file into your version control system. # It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20150914063751) do ActiveRecord::Schema.define(:version => 20150915063302) do
create_table "activities", :force => true do |t| create_table "activities", :force => true do |t|
t.integer "act_id", :null => false t.integer "act_id", :null => false
@ -685,6 +685,7 @@ ActiveRecord::Schema.define(:version => 20150914063751) do
t.integer "user_id" t.integer "user_id"
t.datetime "created_at", :null => false t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false t.datetime "updated_at", :null => false
t.string "mail"
end end
create_table "issue_categories", :force => true do |t| create_table "issue_categories", :force => true do |t|

@ -17,137 +17,137 @@
focusColor: "#333" focusColor: "#333"
//blurColor: "#999 //blurColor: "#999
}; };
var settings = $.extend({}, defaults, options || {}); // var settings = $.extend({}, defaults, options || {});
//页面装载CSS样式 // //页面装载CSS样式
if(settings.autoClass && $("#mailListAppendCss").size() === 0){ // if(settings.autoClass && $("#mailListAppendCss").size() === 0){
$('<style id="mailListAppendCss" type="text/css">.mailListBox{border:1px solid #369; background:#fff; font:12px/20px Arial;}.mailListDefault{padding:0 5px;cursor:pointer;white-space:nowrap;}.mailListFocus{padding:0 5px;cursor:pointer;white-space:nowrap;background:#369;color:white;}.mailListHlignt{color:red;}.mailListFocus .mailListHlignt{color:#fff;}</style>').appendTo($("head")); // $('<style id="mailListAppendCss" type="text/css">.mailListBox{border:1px solid #369; background:#fff; font:12px/20px Arial;}.mailListDefault{padding:0 5px;cursor:pointer;white-space:nowrap;}.mailListFocus{padding:0 5px;cursor:pointer;white-space:nowrap;background:#369;color:white;}.mailListHlignt{color:red;}.mailListFocus .mailListHlignt{color:#fff;}</style>').appendTo($("head"));
} // }
var cb = settings.boxClass, cl = settings.listClass, cf = settings.focusClass, cm = settings.markCalss; //插件的class变量 // var cb = settings.boxClass, cl = settings.listClass, cf = settings.focusClass, cm = settings.markCalss; //插件的class变量
var z = settings.zIndex, newArr = mailArr = settings.mailArr, hint = settings.textHint, text = settings.hintText, fc = settings.focusColor, bc = settings.blurColor; // var z = settings.zIndex, newArr = mailArr = settings.mailArr, hint = settings.textHint, text = settings.hintText, fc = settings.focusColor, bc = settings.blurColor;
//创建邮件内部列表内容 //创建邮件内部列表内容
$.createHtml = function(str, arr, cur){ // $.createHtml = function(str, arr, cur){
var mailHtml = ""; // var mailHtml = "";
if($.isArray(arr)){ // if($.isArray(arr)){
$.each(arr, function(i, n){ // $.each(arr, function(i, n){
if(i === cur){ // if(i === cur){
mailHtml += '<div class="mailHover '+cf+'" id="mailList_'+i+'"><span class="'+cm+'">'+str+'</span>@'+arr[i]+'</div>'; // mailHtml += '<div class="mailHover '+cf+'" id="mailList_'+i+'"><span class="'+cm+'">'+str+'</span>@'+arr[i]+'</div>';
}else{ // }else{
mailHtml += '<div class="mailHover '+cl+'" id="mailList_'+i+'"><span class="'+cm+'">'+str+'</span>@'+arr[i]+'</div>'; // mailHtml += '<div class="mailHover '+cl+'" id="mailList_'+i+'"><span class="'+cm+'">'+str+'</span>@'+arr[i]+'</div>';
} // }
}); // });
} // }
return mailHtml; // return mailHtml;
}; // };
//一些全局变量 //一些全局变量
var index = -1, s; var index = -1, s;
$(this).each(function(){ // $(this).each(function(){
var that = $(this), i = $(".justForJs").size(); // var that = $(this), i = $(".justForJs").size();
if(i > 0){ //只绑定一个文本框 // if(i > 0){ //只绑定一个文本框
return; // return;
} // }
var w = that.outerWidth(), h = that.outerHeight(); //获取当前对象(即文本框)的宽高 // var w = that.outerWidth(), h = that.outerHeight(); //获取当前对象(即文本框)的宽高
//样式的初始化 // //样式的初始化
that.wrap('<span style="display:inline-block;position:relative;"></span>') // that.wrap('<span style="display:inline-block;position:relative;"></span>')
.before('<div id="mailListBox_'+i+'" class="justForJs '+cb+'" style="min-width:'+w+'px;_width:'+w+'px;position:absolute;left:-6000px;top:'+h+'px;z-index:'+z+';"></div>'); // .before('<div id="mailListBox_'+i+'" class="justForJs '+cb+'" style="min-width:'+w+'px;_width:'+w+'px;position:absolute;left:-6000px;top:'+h+'px;z-index:'+z+';"></div>');
var x = $("#mailListBox_" + i), liveValue; //列表框对象 // var x = $("#mailListBox_" + i), liveValue; //列表框对象
that.focus(function(){ // that.focus(function(){
//父标签的层级 // //父标签的层级
$(this).css("color", fc).parent().css("z-index", z); // $(this).css("color", fc).parent().css("z-index", z);
//提示文字的显示与隐藏 // //提示文字的显示与隐藏
if(hint && text){ // if(hint && text){
var focus_v = $.trim($(this).val()); // var focus_v = $.trim($(this).val());
if(focus_v === text){ // if(focus_v === text){
$(this).val(""); // $(this).val("");
} // }
} // }
//键盘事件 // //键盘事件
$(this).keyup(function(e){ // $(this).keyup(function(e){
s = v = $.trim($(this).val()); // s = v = $.trim($(this).val());
if(/@/.test(v)){ // if(/@/.test(v)){
s = v.replace(/@.*/, "");
}
if(v.length > 0){
//如果按键是上下键
if(e.keyCode === 38){
//向上
if(index <= 0){
index = newArr.length;
}
index--;
}else if(e.keyCode === 40){
//向下
if(index >= newArr.length - 1){
index = -1;
}
index++;
}else if(e.keyCode === 13){
//回车
if(index > -1 && index < newArr.length){
//如果当前有激活列表
$(this).val($("#mailList_"+index).text());
}
}else{
if(/@/.test(v)){
index = -1;
//获得@后面的值
// s = v.replace(/@.*/, ""); // s = v.replace(/@.*/, "");
//创建新匹配数组 // }
var site = v.replace(/.*@/, ""); // if(v.length > 0){
newArr = $.map(mailArr, function(n){ // //如果按键是上下键
var reg = new RegExp(site); // if(e.keyCode === 38){
if(reg.test(n)){ // //向上
return n; // if(index <= 0){
} // index = newArr.length;
}); // }
}else{ // index--;
newArr = mailArr; // }else if(e.keyCode === 40){
} // //向下
} // if(index >= newArr.length - 1){
x.html($.createHtml(s, newArr, index)).css("left", 0); // index = -1;
if(e.keyCode === 13){ // }
//回车 // index++;
if(index > -1 && index < newArr.length){ // }else if(e.keyCode === 13){
//如果当前有激活列表 // //回车
x.css("left", "-6000px"); // if(index > -1 && index < newArr.length){
} // //如果当前有激活列表
} // $(this).val($("#mailList_"+index).text());
}else{ // }
x.css("left", "-6000px"); // }else{
} // if(/@/.test(v)){
}).blur(function(){ // index = -1;
if(hint && text){ // //获得@后面的值
var blur_v = $.trim($(this).val()); // //s = v.replace(/@.*/, "");
if(blur_v === ""){ // //创建新匹配数组
$(this).val(text); // var site = v.replace(/.*@/, "");
} // newArr = $.map(mailArr, function(n){
} // var reg = new RegExp(site);
$(this).css("color", bc).unbind("keyup").parent().css("z-index",0); // if(reg.test(n)){
x.css("left", "-6000px"); // return n;
// }
}).keydown(function(event){ // });
if(event.keyCode == 13){ // }else{
return false; // newArr = mailArr;
} // }
}); // }
//鼠标经过列表项事件 // x.html($.createHtml(s, newArr, index)).css("left", 0);
//鼠标经过 // if(e.keyCode === 13){
$(".mailHover").on("mouseover", function(){ // //回车
index = Number($(this).attr("id").split("_")[1]); // if(index > -1 && index < newArr.length){
liveValue = $("#mailList_"+index).text(); // //如果当前有激活列表
x.children("." + cf).removeClass(cf).addClass(cl); // x.css("left", "-6000px");
$(this).addClass(cf).removeClass(cl); // }
}); // }
$(".mailHover").on("click", function(){ // }else{
$("#mail").val($(this).html()); // x.css("left", "-6000px");
}); // }
// }).blur(function(){
// if(hint && text){
}); // var blur_v = $.trim($(this).val());
// if(blur_v === ""){
x.bind("mousedown", function(){ // $(this).val(text);
that.val(liveValue); // }
}); // }
}); // $(this).css("color", bc).unbind("keyup").parent().css("z-index",0);
// x.css("left", "-6000px");
//
// }).keydown(function(event){
// if(event.keyCode == 13){
// return false;
// }
// });
// //鼠标经过列表项事件
// //鼠标经过
// $(".mailHover").on("mouseover", function(){
// index = Number($(this).attr("id").split("_")[1]);
// liveValue = $("#mailList_"+index).text();
// x.children("." + cf).removeClass(cf).addClass(cl);
// $(this).addClass(cf).removeClass(cl);
// });
// $(".mailHover").on("click", function(){
// $("#mail").val($(this).html());
// });
//
//
// });
//
// x.bind("mousedown", function(){
// that.val(liveValue);
// });
// });
}; };
})(jQuery); })(jQuery);
Loading…
Cancel
Save