应用ASP技术编写一个简单论坛(中)

本文详细介绍了如何利用ASP技术实现论坛中消息的显示和处理,包括消息按主题和层次显示的关键算法,以及在数据库中处理新消息和回复消息的方法。涉及的关键程序段包括消息显示、消息处理、消息的添加以及错误处理等环节。
摘要由CSDN通过智能技术生成
4.2 消息按主题和层次显示和处理
本论坛中的消息按主题显示,如图1,左框架中消息列在所属主题后。由于每个消息的内容都存在数据库中相应的主题消息表中,所以消息按主题显示易于实现。
在一个特定主题消息表中,消息的显示由两个字段域level和next决定。level确定消息的层次,即消息处于第几层答复,next决定消息的显示顺序。这两个字段域值的确定是本论坛消息处理和显示的关键所在,具体算法和程序实现说明如下:
    消息的显示
每个消息按其层次右缩level*2个空格。非答复的消息贴子的level值为1,每多一个答复层次,其level值在所答复的消息的level值的基础上加1。
特定主题消息表中的消息的显示顺序由next域决定。在消息表不为空时,总是从第一个记录开始显示,然后按该记录的next值相对于当前记录移动光标到新的记录处,该新的即成为当前记录。next>0,光标前移;next<0,光标后移。重复这个过程直到记录结束或当前记录的next值为0。这样,有n条消息记录,则光标只需移动最多n-1次,便可完全显示所有消息。
其程序在discuss_left.asp中实现,其引用的变量在前面程序段1中定义赋值。如下:
<%
     for i=0 to recordtotal-1       ‘for 循环开始,循环次数为论坛主题数
%>  
<a name="#content<%=i%>"></a><font color="#5555aa" size="3"><%=(i+1)%>
<%=contotal( i )%></font> &nbsp;&nbsp;<a href="#toc"><font size="2">[ 返回页首] </font></a>
 <br>               ‘ 显示论坛主题,并加以编号
<%   set rs=server.createobject("ADODB.recordset")
     rs.open "select * from "&contotal( i ),"DSN=forum;UID=user;PWD=",3,1
                    ‘ 以只读打开主题消息表,表名存于contotal( i )
     if not rs.eof then         ‘ 该表不为空继续
%>
       <!--#INCLUDE VIRTUAL="forum/message_show.inc"-->
                    ‘ 显示首条消息记录信息
                    ‘ 消息显示处理包含文件message_show.inc见程序段3
<% 
       endnext=cint(trim(rs("next")))   ‘ 获取首条记录的next值
       countend=1           ‘ 记录当前已处理消息记录数
       thiscount=rs.recordcount     ‘ 获取本主题消息表的记录总数
       do until ((endnext=0) or (countend=thiscount))
                ‘do until 循环,直到当前记录的next=0或处理了所有记录
         thisnext=cint(trim(rs("next")))    ‘ 获取当前记录的next值
         rs.move thisnext,0     ‘ 相对于当前记录将光标移动next位
         endnext=thisnext
         countend=countend+1
%>
       <!--#INCLUDE VIRTUAL="forum/message_show.inc"-->
                    ‘ 显示当前消息记录信息
<%
       loop             ‘do until 循环结束
    else                ‘ 该主题消息表记录为空
        response.write "<center><font size=2> 尚无讨论提交.</font></center><p>"
     end if
     rs.close
     set rs=nothing         ‘ 关闭并清除rs
   next             ‘for 循环结束
        %>
程序段2
 
        message_show.inc 的程序如下:
<%       for nvspnum=1 to cint(rs("level"))
%>           &nbsp;&nbsp;
 <%next%>              ‘ 按记录的level值右缩level*2个空格
<font size="2">
<a href="contentdisplay.asp?contentdis=<%=rs("index")%>&discussarea=<%=contotal( i )%>
"target="mainFrame"><%=rs("subject")%></a>
(<%=rs("name")%><font color="#000000">,<%=rs("submitdate")%></font>)
                 ‘ 显示消息的标题等信息,并创建面向
                 ‘contentdisplay.asp 的页面的超文本链接,链接内含有
                 ‘ 名为contentdis和discussarea的查询字符串变量,
                 ‘ 用于将该记录的索引值和所在的主题消息表名传给
                 ‘contentdisplay.asp 处理,以显示消息内容
<%     thediff=datevalue(now)-datevalue(rs("submitdate"))
       if thediff<=7 then
%>
           <font color="#ff0000">new</font>
<%    
       end if               ‘ 如果该消息在7天内提交,其后添加new标记
%><br></font>
程序段3
 
²        消息的处理
当在论坛中发送消息或答复消息时,应用程序在数据库中相应的主题消息表中添加新记录,最重要的就是确定记录中level和next的值,并修改相关的记录的next值。
本论坛应用程序有两个文件涉及到消息的处理,即发送消息的disc_post.asp(表单信息来自于discuss_main.asp),答复消息的disc_response.asp(表单信息来自于disc_reply.asp)。
在disc_post.asp中处理的消息,其level值肯定为1;并且将新消息记录添加到相应主题消息表的末尾,其next值肯定为0。其处理程序段如下:
<%
     subject=trim(request.form("subject"))
     discussarea=trim(request.form("selectno"))
     comments=trim(request.form("comments"))
     name=trim(request.form("name"))
     email=trim(request.form("email"))
                        ‘ 获得来自discuss_main.asp的表单信息
     'to create record
     on error resume next
%>
     <!--#INCLUDE VIRTUAL="forum/opendb33.inc"-->
                ‘ 以光标3和锁定3的方式打开主题消息表discussarea
                ‘ 其内容见程序段5
<%    
     truefind=true      ‘truefind 用于判断是否找到next=0的记录
     if not rs.eof then     ‘ 主题消息表不为空继续
       rs.movefirst     ‘ 光标移动到首条记录
       firstindex=cint(trim(rs("index")))
                ‘ 记录首条记录的索引值到变量firstindex中
       rs.movelast      ‘ 光标移动到最后一条记录
tonext=1        ‘ 变量tonext用于存储表中next=0的记录到表尾的距离
findit=false        ‘findit 判断是否找到next=0的记录或搜索完所有记录
       do until findit      ‘do until 循环开始
           if cint(trim(rs("index")))=firstindex then
             findit=true
 end if     ‘ 如果已经搜索到首条记录,findit赋值为真,结束循环
           if cint(rs("next"))<>0 then
‘next
不为0,则将光标继续前移
             truefind=false
             rs.moveprevious
             tonext=tonext+1
           else         ‘next=0 ,则找到记录
             truefind=true
             findit=true
           end if
       loop         ‘do until 循环结束
       if truefind then    
找到next=0的记录,并将该条记录的next值赋为
                ‘tonext ,这样记录的下一条显示记录即为新添加记录
         rs("next")=tonext
       end if
     else           ‘ 该主题消息表为空,则tonext应为0
       tonext=0    
     end if
     if truefind then       ‘ 找到next=0的记录,则添加新纪录
      rs.addnew
       rs("subject")=subject
       rs("submitdate")=now
       rs("content")=comments
       rs("name")=name
       rs("next")=0
       rs("level")=1
       rs("email")=email
       rs.update
     else           ‘ 没有找到next=0的记录,其处理在文件closedb33.inc中
%>
<!--#INCLUDE VIRTUAL="forum/closedb33.inc"-->
                ‘ 其内容见程序段6
程序段4
 
       opendb33.inc 的程序如下:
    <%
         set cnn1=server.createobject("adodb.connection")
         cnn1.open "forum","user",""
         set rs=server.createobject("ADODB.recordset")
         rs.cursortype=3
         rs.locktype=3
         cnn1.begintrans        ‘ 开始事务处理
         rs.open discussarea,cnn1,,,2   ‘ 打开主题消息表discussarea
        %>
程序段5
    closedb33.inc 的程序如下:
   <%    
   cnn1.rollbacktrans      ‘ 没有找到next=0的记录,撤销事务处理
          response.write "<center> 对不起,本讨论区出现问题,暂时停用!</center>"
         rs.close
          set rs=nothing
          cnn1.close
          set cnn1=nothing      ‘ 关闭并清除rs和cnn1
          response.end          ‘ 页面请求结束,显示页面
      end if                ‘if truefind then 判断语句结束
 if err=0 then           ‘程序运行无错,触发事务处理
          cnn1.committrans
      else
          cnn1.rollbacktrans        ‘ 程序运行出错,撤销事务处理
          response.write "<center> 讨论提交失败!</center>"
          rs.close
          set rs=nothing
          cnn1.close
          set cnn1=nothing      ‘ 关闭并清除rs和cnn1
          response.end
      end if
      rs.close
      set rs=nothing
      cnn1.close
      set cnn1=nothing          ‘ 关闭并清除rs和cnn1
               %>
程序段6
 
<%
     subject=trim(request.form("subject"))
     discussarea=request.form("discussarea")
     comments=trim(request.form("comments"))
     name=trim(request.form("name"))
     email=trim(request.form("email"))
     levelreply=request.form("levelreply")+1
     indexreply=cint(trim(request.form("indexreply")))
                        ‘ 获得来自disc_reply.asp的表单信息
     'to create record
     on error resume next
%>
     <!--#INCLUDE VIRTUAL="forum/opendb33.inc"-->
                ‘ 内容见程序段5
<%    
     truefind=true
     rs.movefirst
     firstindex=cint(trim(rs("index")))
     rs.movelast
     tonext=1
     findit=false
     do until findit        ‘do until 循环开始
        if cint(trim(rs("index")))=firstindex then
           findit=true
        end if
        if cint(rs("index"))<>indexreply then
                ‘ 未找到所答复消息记录,光标继续前移
           truefind=false
           rs.moveprevious
           tonext=tonext+1
        else            ‘ 找到所答复消息记录,则truefind和findit赋值为真
           truefind=true
           findit=true

        end if
     loop           ‘do until 循环结束
     if truefind then       ‘ 找到所答复消息记录,则存储该记录next到变量thisnext
                ‘ 中,并修改该记录的next为到新添加记录的距离
       thisnext=cint(trim(rs("next")))
       rs("next")=tonext
       rs.addnew        ‘ 添加新记录
       rs("subject")=subject
       rs("submitdate")=now
       rs("content")=comments
       rs("name")=name
       rs("email")=email
       if thisnext<>0 then ‘ 如果thisnext不为0,则新记录next值为thisnext-tonext
         rs("next")=thisnext-tonext
       else         ‘ 如果thisnext为0,则新记录next=0
         rs("next")=0
       end if
       rs("level")=levelreply
       rs.update
     else           ‘ 没有找到所答复消息记录,其处理见closedb33.inc
%>
<!--#INCLUDE VIRTUAL="forum/closedb33.inc"-->
                ‘ 内容见程序段6
程序段7
 
五、程序清单
 
这里列出本论坛的程序清单。这只是一个非常简单的WEB程序,可以添加很多功能进行扩展,如添加图片,将主题显示与消息显示分成不同页面。有兴趣不妨一试。
5.1 myforum.html
<HTML>
<body>
<p><p>
<center><h3>Welcome to My <a href="discuss.asp" target="_self">Forum</a>!</h3></center>
                    ‘ 建立到论坛的页面链接
</body>
</HTML>
 
5.2 discuss.asp
<%@language=VBScript%>
<html>
<head>
<title> 讨论组</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>
<%
   'on error resume next
   discussarea="forum_content"
%>
<!--#INCLUDE VIRTUAL="forum/opendb33.inc"-->
                               ‘ 打开表forum_content
<%
      if rs.recordcount=0 then      ‘ 无记录,则结束页面请求
     cnn1.rollbacktrans
     response.write "<center> 对不起,讨论区没有设定内容!</center>"
     rs.close
     set rs=nothing
     cnn1.close
     set cnn1=nothing
     response.end    
   end if
   for todoit=1 to rs.recordcount   ‘ 有记录,则对每个主题消息表进行统计
     set rs1=server.createobject("ADODB.recordset")
     rs1.open "select * from "&rs("contentname"),"DSN=forum;UID=user;PWD=",3,1
     newnum=0
     for todoit1=1 to rs1.recordcount
       thediff=datevalue(now)-datevalue(rs1("submitdate"))
       if thediff<=7 then
         newnum=newnum+1        ‘7 天之内发送的消息为新消息
       end if
       rs1.movenext
     next
     rs("total")=rs1.recordcount
     rs("newest")=newnum
     rs1.close
     set rs1=nothing
     rs.movenext
   next
   if err=0 then
     cnn1.committrans
   else
     cnn1.rollbacktrans
     response.write "<center> 对不起,讨论区失败!</center>"
     rs.close
     set rs=nothing
     cnn1.close
     set cnn1=nothing
     response.end
   end if
   rs.close
   set rs=nothing
   cnn1.close
   set cnn1=nothing
%>
<frameset frameborder="no" border="0" framespacing="0" bordercolor="#ffffff"
rows="79,421*" cols="*">
 <frame name="topFrame" scrolling="NO" noresize src="discuss_top.html">
 <frameset frameborder="YES" border="2" framespacing="2" bordercolor="#FFCCFF"
        cols="414,379*" rows="*">
    <frame name="leftFrame" noresize src="discuss_left.asp">
    <frame name="mainFrame" src="discuss_main.asp">
 </frameset>
 <noframes size="+1">
 <body bgcolor="#FFFFFF">
 </body>
 </noframes> </frameset>
<frameset>
 <noframes>
 </noframes>
</frameset>                     ‘ 以上为框架定义语句
</html>
 
5.3 discuss_top.html
<html>
<head>
<title> 讨论组</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>
<body bgcolor="#FFFFFF">
<p align="center"><fontFONT-SIZE: 10.5pt; COLOR: black;">黑体, System, 楷体_GB2312">
<marquee border="0" align="middle" behavior="alternate" style="color: rgb(0,0,255)">
<kbd><font size="4"> 小小论坛欢迎您</font></kbd></marquee></font></p>
<table width="75%" border="0" align="center" height="25">
 <tr align="center" valign="middle">
    <td height="27" nowrap>
      <div align="center"><a href="myforum.html" target="_parent">[ 返回主页 ]</a></div>
    </td>
    <td height="27" nowrap>
      <div align="center"> <a href="discuss.asp" target="_parent">[ 刷新内容 ]</a></div>
    </td>
    <td height="27" nowrap>
      <div align="center"><a href="discuss_main.asp" target="mainFrame">[ 发送 ]</a></div>
    </td>
 </tr>
</table>
<p>&nbsp;</p>
</body>
</html>
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值