找回密码
 立即注册
查看: 108|回复: 0

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

[复制链接]
  • TA的每日心情
    开心
    5 天前
  • 签到天数: 62 天

    [LV.6]常住居民II

    200

    主题

    18

    回帖

    2553

    积分

    管理员

    积分
    2553
    发表于 2024-12-13 13:04:42 | 显示全部楼层 |阅读模式
    而在discuz中,短信息只用到了一张表:dnt_pms
    [img=376,244 alt=]https://www.jb51.net/upload/20090420170302504.gif[/img]

    其字段说明如下:

    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);

    而其批量发送短消息:
    [img=590 border=1,401 alt=]https://www.jb51.net/upload/20090420170302172.gif[/img]


           执行方法也是让我感到奇怪,居然是:比如我选择了乞丐,而乞丐这个等级有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( "AGE", "window.location.href='global_sendSMtogroup.aspx';");
    }

    #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用户表中的一个字段,而用户表中有两个字段跟短消息是相关的:
    [img=278,59 alt=]https://www.jb51.net/upload/20090420170302677.gif[/img]


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

    详细如下,根据自己见解做了修改,在会员阅读信息之后的具体操作大家应该都清楚,就不写那么仔细。
    [img=606,552 alt=]https://www.jb51.net/upload/20090420170302300.gif[/img]

    来源:互联网
    免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|Archiver|手机版|小黑屋|软媒源码阁 |网站地图

    GMT+8, 2025-5-14 02:50 , Processed in 0.148426 second(s), 21 queries .

    Powered by RuanmeiHome X3.5

    Copyright © 2014-2025, 软媒源码阁

    快速回复 返回顶部 返回列表