【一】收件箱

分析

控制器:EmailController.class.php

方法:recBox(全称receive box收件箱)

模板文件:recBox.html

分步操作:

第一步:创建方法recBox,用来读取数据展示模板文件

先来分析下,针对收件箱,应该显示发件人from_id。需要关联sp_user用户表,所以接下来用到联表查询

主表:sp_email邮件表(别名t1);从表:sp_user用户表(别名t2);

关联条件:t1.from_id = t2.id;

原生SQL语句:其实与发件箱只是相比,最后一个条件不同而已。发件箱是from_id,收件箱是to_id

  1. select t1.*,t2.truename as truename from sp_email as t1 left join sp_user as t2 on t1.to_id=t2.id where t1.to_id=当前用户id;

接下来去Navicate运行成功后,确保sql语句正确。接下来去ThinkPHP里执行连贯操作

  1. //recBox收件箱获取数据展示模板
  2. public function recBox(){
  3. // 原生SQL:select t1.*,t2.truename as truename from sp_email as t1 left join sp_user as t2 on t1.to_id=t2.id
    where t1.to_id=当前用户id;
  4. //获取数据
  5. $data = M('Email')->field('t1.*,t2.truename as truename')->alias('t1')->
  6. join('left join sp_user as t2 on t1.to_id=t2.id')->where('t1.to_id='.session('id'))->select();
  7. dump($data);die;
  8. }

注意:session相关测试时注意事项

(1)在用户电脑上,同一个浏览器无法登录不同用户。因为session会产生覆盖,所以这就导致了不能多个窗口登录多个用户的情况

(2)解决方法:

①对此只能开另一个浏览器去登录其他用户,这样也算是在同一电脑上登录多个用户;

②打开新窗口,开启浏览器隐身模式,这样便不会记录session,也就不会产生session的覆盖

第二步:将数据传递给模板,变量分配,展示模板。最后完整代码

  1. //recBox收件箱获取数据展示模板
  2. public function recBox(){
  3. //获取数据
  4. $data = M('Email')->field('t1.*,t2.truename as truename')->alias('t1')->
  5. join('left join sp_user as t2 on t1.to_id=t2.id')->where('t1.to_id='.session('id'))->select();
  6. //传递数据给模板
  7. $this->assign('data',$data);
  8. //展示模板
  9. $this->display();
  10. }

第三步:将模板文件recBox.html复制到指定文件,并换掉静态资源路径

第四步:修改模板recBox.html,展示数据

和发件箱类似,需要注意:有个读取状态,已读和未读。需要在这里做下区分和操作

第五步:查看邮件内容

修改模板,使用layer查看邮件内容,

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>收件箱</title>
  5. </head>
  6. <body>
  7. 收件箱
  8. <table border="1" cellspacing="0" cellpadding="10">
  9. <thead>
  10. <tr><td>序号</td><td>发件人</td><td>标题</td><td>附件</td><td>内容</td><td>发送时间</td><td>状态</td><td>操作</td></tr>
  11. </thead>
  12. <volist name="data" id="vol">
  13. <tr>
  14. <td>{$vol.id}</td>
  15. <td>{$vol.truename}</td>
  16. <td>{$vol.title|msubstr=###,0,10}</td>
  17. <td>{$vol.filename|msubstr=###,0,16}<notempty name="vol.filename"><a href="__CONTROLLER__/download/id/{$vol.id}">
    【下载】</a></notempty>
    </td>
  18. <td>{$vol.content|msubstr=###,0,10}</td>
  19. <td>{$vol.addtime|date='Y-m-d H:i:s',###}</td>
  20. <td><if condition="$vol.isread == 0"><span style="color:red">未读</span><else/><span style="color:green">已读</span></if></td>
  21. <td>
  22. <a href="javascript:;" class="showBtn" data="{$vol.id}"" data-title="{$vol.title}">查看</a> |
  23. <a href="__CONTROLLER__/edit/id/{$vol.id}" class="editBtn">删除</a>
  24. </td>
  25. </tr>
  26. </volist>
  27. </table>
  28. <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
  29. <script type="text/javascript" src="__PUBLIC__/Admin/plugin/layer/layer.js"></script>
  30. <script type="text/javascript">
  31.  
  32. </script>
  33. <script type="text/javascript">
  34. $(document).ready(function(){
  35. $('.showBtn').on('click',function(){
  36. // var title = $(this).parents('tr').children("td").get(1).innerHTML;
  37. // console.log(title)
  38. // 获取id
  39. var id = $(this).attr('data');
  40. var title = $(this).attr('data-title');
  41. //iframe层
  42. layer.open({
  43. type: 2,
  44. title: title,
  45. shadeClose: true,
  46. shade: 0.3, //阴影
  47. area: ['600px', '50%'],
  48. content: '__CONTROLLER__/showContent/id/'+id //iframe的url
  49. });
  50. })
  51. })
  52. </script>
  53. </body>
  54. </html>

第六步:添加查询getContent方法展示内容

在查询的时候,为了避免用户获取到请求内容的方法,进而在后面随意更改id来获取别人的邮件,则可以在查询的时候,加上一个条件限制。限制只能查询自己的邮件

  1. //查看
  2. public function showContent(){
  3. //接收id
  4. $id = I('get.id');
  5. //查询数据
  6. $data = M('Email') ->where("id = $id and to_id = ".session('id'))-> find($id);//这里加限制,只能看自己邮件
  7. //输出内容,并且还原被转移的字符
  8. // echo $data['content'];
  9. echo htmlspecialchars_decode($data['content']);
  10. }

【二】邮件读取状态的改变

完善:设置邮件读取状态,执行点击查看操作时改变读取状态

结合上述代码,在查看获取邮件内容时改变邮件状态。所以可以将改变邮件状态的方法添加到showContent方法里

第一步:修改getContent方法,读取内容时修改邮件读取状态

对获取邮件内容方法进行分析后,即可得知查询数据操作$data如果为真则表示获取成功,此时便可以修改文件状态。所以在里面加上更新数据库操作

  1. if ($data['isread'] == 0) {//更新数据库
  2. M('Email')->save(array('id'=>$id,'isread'=> 1));
  3. }

此时,点击查看后,虽然数据库的读取状态变为1,但页面需要刷新才会更新,不能使页面自动更新。接下来修改模板,让页面自动刷新

第二步:在关闭弹框时刷新

查询layer手册后会发现有个end方法,在关闭弹框时触发

所以接下来添加end方法:在关闭时刷新页面

第三步:虽然现在可以实现查看后刷新文件状态,但是当前的无论是什么状态都会刷新。所以还需要进行修改,设置成只有当状态是未读时才会刷新

修改模板添加自定义属性,传递参数

  1. <a href="javascript:;" class="showBtn" data-status="{$vol.isread}" data="{$vol.id}"" data-title="{$vol.title}">查看</a>

jquery判断:

  1. var isread = $(this).attr('data-status');
  2. end:function(){
  3. //关闭时操作,刷新当前页
  4. // window.location.href = location.href;
  5. //或者window.location.reload();
  6. if (isread == 0) {
  7. window.location.href = location.href;
  8. }
  9. }

【三】站内新消息提示(邮件的实时提醒功能)

因为是实时功能(间隔性更新数据),所以这里采用ajax方法,局部刷新页面

所谓实时,不一定是精确到秒,因为这样会增加服务器消耗。一般可以掌握在5分钟之内,这样便不会影响用户体验

分析:ajax、定时器(setTimeout延迟性一次定时器、setInterval反复性定时器)

原理:在页面加载完成后,通过定时器不断发送ajax请求来获得邮件的数量,然后展示到模板

下面分步介绍

第一步:编写页面Index/index.html载入事件

  1. <script type="text/javascript">
  2. $(function(){
  3. //反复性定时器,5秒发送一次
  4. setInterval('getMsgCount()',5000);
  5. })
  6. //ajax请求方法
  7. function getMsgCount(){//发送ajax请求
  8. $.get("{:U('Email/getCount')}", function(data) {
  9. //相应处理代码
  10. });
  11. }
  12. </script>

第二步:在Email控制器里编写getCount方法,输出未读邮件数量(当前用户的未读邮件)

  1. //获取当前用户未读邮件的数量
  2. public function getCount(){
  3. if(IS_AJAX){
  4. //实例化模型
  5. $model = M('Email');
  6. //查询当前用户--未读邮件数量
  7. $count = $model->where("isread == 0 and to_id =".session('id'))->count();
  8. //输出数字
  9. echo $count;
  10. }
  11. }

接下来测试下

每隔5秒发送一次请求,这里查看下输出的数量

第三步:在米板文件里修改后续的操作,将获取到的未读邮件数量在页面显示

  1. 消息:<a href="javascript:;" class="emailCount">0</a> //这里默认初始为0
  2.  
  3. //ajax请求方法
  4. function getMsgCount(){
  5. //发送ajax请求
  6. $.get("{:U('Email/getCount')}", function(data){
  7. // console.log('2')
  8. $('.emailCount').html(data);
  9. });
  10. }

第四步:点击消息按钮,跳转到收件箱。给消息添加链接即可

  1. <a href="{:U('Email/recBox')}">消息:</a><a href="javascript:;" class="emailCount">0</a>

注意:因为OA系统要求是在iframe中打开新页面,所以需要加target属性,target的属性值必须是目标iframe的name值

所以要继续将上面代码修改为

  1. <a href="{:U('Email/recBox')}" target="iframe的name值">消息:</a><a href="javascript:;" class="emailCount">0</a>

.

ThinkPHP---thinkphp完善站内信功能的更多相关文章

  1. ASP.NET 实现站内信功能(点对点发送,管理员群发)

    正好这段时间在研究这个功能,还是得感谢这位大神,没有他的引路,我就不可能把站内信做出来. http://www.cnblogs.com/grenet/archive/2010/03/08/168065 ...

  2. SharePoint 2010 类似人人网站内信功能实施

    简介:用SharePoint代码加实施的方式,完成类似人人网站内信功能,当然,实现的比较简单,样式也比较难看,只为给大家一个实施的简单思路,如有谬误,还请见谅.当然,还有就是截图比较长,当然为了让大家 ...

  3. 开源 免费 java CMS - FreeCMS2.1 会员站内信

    项目地址:http://www.freeteam.cn/ 站内信 1.1.1 写信 从左側管理菜单点击写信进入. 输入收信人.标题.内容后点击发送button. 1.1.2 收件箱 从左側管理菜单点击 ...

  4. 2. SharePoint Online 开发,请联系qq512800530。加好备注。(不要发站内信。。。)

    ///(不要发站内信...) <meta name="keywords" content="SharePoint Online, SP Online, SPO, S ...

  5. 站内信,群发与全部发送。Gson解析result

    /** * 发送站内信 */@Permission(Module.TZGL)@RequestMapping(value = "/sendznx", method = Request ...

  6. 站内信DB设计实现

    两年前,万仓一黍在博客园发了两篇关于站内信的设计实现博文,<群发"站内信"的实现>.<群发"站内信"的实现(续)>,其中阐述了他关于站内 ...

  7. Hexo next主题添加站内搜索功能

    根据关键字搜索博文,站内搜索的功能很实用.hexo开启站内搜索很方便,已经有现成的插件可以使用,也是为了方便自己 安装插件 npm install hexo-generator-search --sa ...

  8. PHPCMS站内搜索功能实现方法汇总,一文解决PHPCMS站内搜索问题

    1,https://blog.csdn.net/hzw19920329/article/details/80110673 点评:phpcms搜索功能实现方法,作者基于PHPCMS做个门户网站实现站内搜 ...

  9. 简单三步-实现dede站内搜索功能

    第一步:找到对应的搜索模板的代码 我们都知道,dede有自带的搜索功能,我们只要找到对应的模板,然后把我们想要的代码拿出来就行了.具体如下: 首先进入templets-->default--&g ...

随机推荐

  1. Codeforces 455B A Lot of Games 字典树上博弈

    题目链接:点击打开链接 题意: 给定n个字符串,k局游戏 对于每局游戏,2个玩家轮流给一个空串加入一个小写字母使得加完后的字符串不是n个字符串的前缀. 输家下一轮先手 问是先手必胜还是后手必胜 思路: ...

  2. 菜鸟的mongoDB学习---(五)MongoDB的limit、skip、sort方法

    limit方法 假设你须要在MongoDB中读取指定数量的数据记录.能够使用MongoDB的Limit方法,limit()方法接受一个数字參数,该參数指定从MongoDB中读取的记录条数. mongo ...

  3. react-color 颜色选择器组件

    demo链接:github demo 安装: npm install react-color --save 有一下几种类型组件 <AlphaPicker /> <BlockPicke ...

  4. 进程间通信之-共享内存Shared Memory--linux内核剖析(十一)

    共享内存 共享内存是进程间通信中最简单的方式之中的一个. 共享内存是系统出于多个进程之间通讯的考虑,而预留的的一块内存区. 共享内存同意两个或很多其他进程訪问同一块内存,就如同 malloc() 函数 ...

  5. Illegal mix of collations (utf8_unicode_ci,IMPLICIT) and (utf8_general_ci,IMPLICIT) for operation '=

    [SQL]SELECT username,password,toutiao_uidFROM pwdtab pLEFT JOIN toutiao_action_article aON p.toutiao ...

  6. NTFS文件系统的单个文件最大到底有多大?

    于NTFS文件系统的单个文件最大到底有多大? 闲来无事突然想到这个问题,到网上搜索了一下也没有一个固定的解释. 于是到微软官方知识库去寻找答案: 注意:基础硬件限制可能会对任何文件系统施加额外的分区大 ...

  7. delphi中URL的汉字编码

    delphi中URL的汉字编码 show.asp?sort=全部&sortlevel=1&gorq=供&n=5&sitename=全部&img=yes& ...

  8. poj 2762(tarjan缩点+判断是否是单链)

    Going from u to v or from v to u? Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 19234 ...

  9. WPF获取原始控件样式

    要获取WPF控件的原始样式,需要我们安装Blend for Visual Studio. 然后,我们打开Blend for Visual Studio,创建一个WPF项目. 然后,我们向页面拖动一个B ...

  10. 19.Extjs主页面显示js

    1. /** * @author sux * @time 2011-1-11 * @desc main page */ var mainPage = Ext.extend(Ext.Viewport,{ ...