Discuz .net版本中的短消息系统


本文整理自网络,侵删。

在Discuz中,消息可以分为公用消息(管理后台 --> 其他 -->公共消息管理)如下:

另外还有批量短消息发送(用户管理):

以及个人用户时的发送:
 

而在discuz中,短信息只用到了一张表:dnt_pms
其字段说明如下:
代码如下:

pmid:自递增的id
msgfrom:发送者的用户名,若为系统消息则为“系统”。
msgfromid:发送者的id
msgto:接收者的用户名
msgtoid:接收者的id
folder: 0、收件箱,1、发件箱,2、草稿箱
new:是否是新消息,未读,1;0已读
subject:标题
postdatetime:发送时间
message:消息内容

看下公用信息部分的函数:
代码如下:

/// <summary>
/// 得到公共消息数量
/// </summary>
/// <returns>公共消息数量</returns>
public int GetAnnouncePrivateMessageCount()
{
return Utils.StrToInt(DbHelper.ExecuteScalar(CommandType.Text, "SELECT COUNT(pmid) FROM [" + BaseConfigs.GetTablePrefix + "pms] WHERE [msgtoid] = 0").ToString(), 0);
}


/// <summary>
/// 获得指定用户的短信息列表
/// </summary>
/// <param name="pagesize">每页显示短信息数</param>
/// <param name="pageindex">当前要显示的页数</param>
/// <returns>短信息列表</returns>
public IDataReader GetAnnouncePrivateMessageList(int pagesize, int pageindex)
{
string sql = "";
if(pageindex <= 1)
{
sql = string.Format("SELECT TOP {0} * FROM [{1}pms] WHERE [msgtoid] = 0 ORDER BY [pmid] DESC", pagesize, BaseConfigs.GetTablePrefix);
}
else
{
sql = string.Format("SELECT TOP {0} * FROM [{1}pms] WHERE [msgtoid] = 0 AND [pmid] < (SELECT MIN([pmid]) FROM (SELECT TOP " + (pageindex - 1) * pagesize + " [pmid] FROM [{1}pms] WHERE [msgtoid] = 0 ORDER BY [pmid] DESC) AS tblTmp) ORDER BY [pmid] DESC", pagesize, BaseConfigs.GetTablePrefix);
}

IDataReader reader = DbHelper.ExecuteReader(CommandType.Text, sql);
return reader;
}

可见:msgtoid=0为判断是否公用信息的条件。

而在注册部分发送一条欢迎的信息到新用户的收件箱中,欢迎信息只有一条,而公用信息可以有很多条,每个注册的用户如果后台设置了发送欢迎消息,则都会执行以下代码:
代码如下:

PrivateMessageInfo privatemessageinfo = new PrivateMessageInfo();

string curdatetime = Utils.GetDateTime();
// 收件箱
privatemessageinfo.Message = config.Welcomemsgtxt;
privatemessageinfo.Subject = "欢迎您的加入! (请勿回复本信息)";
privatemessageinfo.Msgto = userinfo.Username;
privatemessageinfo.Msgtoid = uid;
privatemessageinfo.Msgfrom = PrivateMessages.SystemUserName;
privatemessageinfo.Msgfromid = 0;
privatemessageinfo.New = 1;
privatemessageinfo.Postdatetime = curdatetime;
privatemessageinfo.Folder = 0;
PrivateMessages.CreatePrivateMessage(privatemessageinfo, 0);

而其批量发送短消息:

       执行方法也是让我感到奇怪,居然是:比如我选择了乞丐,而乞丐这个等级有10万用户,则取得这10W用户的数据,一条条执行插入。暴汗……这样算法以及实现确实简单了很多,但会员一多,要经常清理这些数据。这也是为什么我们看到discuz的论坛经常一段时间需要清理短消息的原因。建议批量发送只对等级较高,数量较少的用户使用。同时在使用过程中,不明白为什么在“批量短消息发送”中的“文件箱”有“收件箱”、“发件箱”、“草稿箱”3种,这里应该只有“收件箱”比较合适,或者这里根本就不该出现这个“文件箱”。

批量发送的代码如下:
代码如下:

private void BatchSendSM_Click(object sender, EventArgs e)
{
#region 批量短消息发送

if (this.CheckCookie())
{
string groupidlist = Usergroups.GetSelectString(",");

if (groupidlist == "")
{
base.RegisterStartupScript( "", "<script>alert('请您先选取相关的用户组,再点击提交按钮');</script>");
return;
}

int percount = 10; //每多少记录为一次等待
int count = 0; //当前记录数
// GetUserNameListByGroupid为取得选中的用户组的所有用户的id和用户名
foreach (DataRow dr in DatabaseProvider.GetInstance().GetUserNameListByGroupid(groupidlist).Rows)
{
DatabaseProvider.GetInstance().SendPMToUser(username.Replace("'", "''"), userid, dr["username"].ToString().Replace("'", "''"), Convert.ToInt32(dr["uid"].ToString()), int.Parse(folder.SelectedValue), subject.Text, Convert.ToDateTime(postdatetime.Text), message.Text);
if (count >= percount)
{
Thread.Sleep(3500);
count = 0;
}
count++;
}
base.RegisterStartupScript( "PAGE", "window.location.;");
}

#endregion
}

//SendPMToUser函数如下:
public void SendPMToUser(string msgfrom, int msgfromid, string msgto, int msgtoid, int folder, string subject, DateTime postdatetime, string message)
{
DbParameter[] parms =
{
DbHelper.MakeInParam("@msgfrom", (DbType)SqlDbType.NVarChar,50, msgfrom),
DbHelper.MakeInParam("@msgfromid", (DbType)SqlDbType.Int, 4, msgfromid),
DbHelper.MakeInParam("@msgto", (DbType)SqlDbType.NVarChar,50, msgto),
DbHelper.MakeInParam("@msgtoid", (DbType)SqlDbType.Int, 4, msgtoid),
DbHelper.MakeInParam("@folder", (DbType)SqlDbType.SmallInt, 2, folder),
DbHelper.MakeInParam("@subject", (DbType)SqlDbType.NVarChar,60, subject),
DbHelper.MakeInParam("@postdatetime", (DbType)SqlDbType.DateTime,8, postdatetime),
DbHelper.MakeInParam("@message",(DbType)SqlDbType.NText, 0,message)
};
string sql = "INSERT INTO [" + BaseConfigs.GetTablePrefix + "pms] (msgfrom,msgfromid,msgto,msgtoid,folder,new,subject,postdatetime,message) " +
"VALUES (@msgfrom,@msgfromid,@msgto,@msgtoid,@folder,1,@subject,@postdatetime,@message)";
DbHelper.ExecuteNonQuery(CommandType.Text, sql, parms);
sql = "UPDATE [" + BaseConfigs.GetTablePrefix + "users] SET [newpmcount]=[newpmcount]+1 WHERE [uid] =@msgtoid";
DbHelper.ExecuteNonQuery(CommandType.Text, sql, parms);
}

有一句语句是用于users用户表中的一个字段,而用户表中有两个字段跟短消息是相关的:

       不明白这里为什么要用两个字段,用newpmcount一个字段就可以判断是否有新消息了,如果为0说明没有新消息,而查看消息后也只需要对newpmcount进行操作,并不需要对newpm也进行操作。公用消息并不会对这两个字段进行操作。

详细如下,根据自己见解做了修改,在会员阅读信息之后的具体操作大家应该都清楚,就不写那么仔细。

更多关于Discuz论坛内容来自木庄网络博客


标签:Discuz论坛

相关阅读 >>

dedecms整合discuz精典教程

discuz文件结构详解,discuz模板文件介绍

php daddslashes()和 saddslashes()有哪些区别分析

discuz和jquery变量名冲突的3种解决方法

Discuz论坛的ubb编辑器(增加灵活调用,支持asp)

php写的加密函数,支持私人密钥(详细介绍)

destoon首页调用求购供应信息的地区名称的方法

iis启用gzip的方法与优缺点分析

php+apache实现网址伪静态

如何将你的cj联盟帐户做到一个月1万美元

更多相关阅读请进入《Discuz论坛》频道 >>



打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...