第二十二 webchat(2)

1.聊天框切换

1.1.定义全局字典

        //globe chat record dic
        GLOBAL_CHAT_RECORD_DIC = {
            'single':{},
            'group':{},
        }

 

1.2.增加归档

 //在切换之前把之前的聊天内容归档
            var current_session_id = $(".chat-box-title").attr("contact-id");
            var current_session_type = $(".chat-box-title").attr("contact-type");
            if(current_session_id){
                GLOBAL_CHAT_RECORD_DIC[current_session_type][current_session_id] = $(".chat-box-window").html()
            }

1.2.获取新内容

            //获取新内容
            var new_contact_chat_record = GLOBAL_CHAT_RECORD_DIC[contact_type][contact_id];
            //如果是第一次从字典取值
            if(typeof new_contact_chat_record == 'undefined'){
                new_contact_chat_record = '';
            }
            //将内容赋予到对话框
            $(".chat-box-window").html(new_contact_chat_record)

1.4.测试切换

 2.消息展现到对话框

2.1.消息解析

  function GetNewMsgs() {
            console.log("--- getting new message ---");
            $.getJSON("{% url 'get_new_msgs' %}",function(callback){
                console.log(callback);
                ParseNewMsgs(callback);//把新消息进行解析
                GetNewMsgs();
            });//end post
        }

2.2.消息定义

  function ParseNewMsgs(callback) {
          var current_session_type = $(".chat-box-title").attr("contact-type");
          var current_session_id = $(".chat-box-title").attr("contact-id");
            for(var i in callback){
                console.log(callback[i]);
                // { from: "1", to: "5", type: "single", msg: "\n22", timestamp: 1521081612.0092783 }
                if(callback[i].from == current_session_id && current_session_type == callback[i].type){
                    //此消息的发送方当前正在跟我聊天
                     var msg_item_ele = "<div class='msg-item'>" +
                        "<span>" + callback[i].from + "</span>" +
                        "<span>" + callback[i].timestamp + "</span>" +
                        "<div class='msg-text'>" + callback[i].msg + "</div>" +
                        "</div>";
                     $(".chat-box-window").append(msg_item_ele);
                }//end if
            }//enf for
        }

2.3.测试发送

ckl 向贾岛发消息:

贾岛给ckl回消息:

消息时断时续

3.消息暂存,登录后就接收

3.1.暂存消息到字典

 for(var i in callback){
                console.log(callback[i]);
                // { from: "1", to: "5", type: "single", msg: "\n22", timestamp: 1521081612.0092783 }
                var msg_item_ele = "<div class='msg-item'>" +
                        "<span>" + callback[i].from + "</span>" +
                        "<span>" + callback[i].timestamp + "</span>" +
                        "<div class='msg-text'>" + callback[i].msg + "</div>" +
                        "</div>";

                if(callback[i].from == current_session_id && current_session_type == callback[i].type){
                    //此消息的发送方当前正在跟我聊天
                     $(".chat-box-window").append(msg_item_ele);
                } else {
                    //消息发送者当前没打开聊天框,消息暂存内存
                    if(GLOBAL_CHAT_RECORD_DIC[callback[i].type][callback[i].from]){
                        GLOBAL_CHAT_RECORD_DIC[callback[i].type][callback[i].from] += msg_item_ele;
                    }else {
                        GLOBAL_CHAT_RECORD_DIC[callback[i].type][callback[i].from] = msg_item_ele;
                    }
                }//end if
            }//enf for

3.2.测试发送

3.2.1.贾岛没有在线的情况下发送

发送消息给贾岛:

 

贾岛不在线:

 

 贾岛收取:

 

 

 4.未读消息数量显示及取消

4.1.未读消息显示

4.1.1.增加新消息提醒

初始状态为隐藏及消息数量为0:

<span class="badge hide">0</span>

新消息提醒:

             //新消息提醒
                //var contact_ele = $(".list-group li[contact-type='single']").filter("li[contact-id='3']")[0];
                var contact_ele = $(".list-group li[contact-type='"+ callback[i].type +"']").filter("li[contact-id='"+ callback[i].from +"']")[0];
                var current_new_msg_num = $(contact_ele).find(".badge").text();
                $(contact_ele).find(".badge").removeClass("hide");
                var ckl = $(contact_ele).find(".badge").text(parseInt(current_new_msg_num)+1);

4.1.2.测试新消息提醒

向贾岛发消息:

接收ckl的消息:

4.2.接收消息后,隐藏消息

4.2.1.隐藏消息

            //将内容赋予到对话框
            $(".chat-box-window").html(new_contact_chat_record)

            //消息接收完毕后,隐藏提醒信息
            var contact_ele = $(".list-group li[contact-type='"+ contact_type +"']").filter("li[contact-id='"+ contact_id +"']");
            $(contact_ele).find(".badge").text(0);
            $(contact_ele).find(".badge").addClass("hide");

4.2.2.测试消息接收后隐藏

发送消息:

接收消息:

 5.群组聊天

5.1.群组展示

5.1.1.前端添加

基本跟用户没有区别,相对应的字段修改为group

     <div role="tabpanel" class="tab-pane" id="group-tab">
                <ul class="list-group">
                    {% for group in request.user.userprofile.group_members.select_related %}
                        <li contact-type="group" contact-id="{{ group.id }}" onclick="OpenChatWindow(this)" class="list-group-item">
                            <span class="badge hide">0</span>
                            <span class="contact-name">{{ group.name }}</span>
                        </li>
                    {% endfor %}
                </ul>
            </div>

5.1.2.显示群组

5.2.群组发消息

5.2.1.修改view,增加group

@login_required
def send_msg(request):
    print(request.POST)
    print(request.POST.get("msg"))
    print(request.POST.get('data'))
    msg_data = request.POST.get('data')
    #如果消息存在
    if msg_data:
        msg_data = json.loads(msg_data)
        #消息增加时间蹉
        msg_data['timestamp'] = time.time()
        #如果消息类型为‘single’
        if msg_data['type'] == 'single':
            if not GLOBAL_MSG_QUEUES.get(int(msg_data["to"])):
                GLOBAL_MSG_QUEUES[int(msg_data["to"])] = queue.Queue()
            GLOBAL_MSG_QUEUES[int(msg_data["to"])].put(msg_data)
        else:
            group_obj = models.WebGroup.objects.get(id=msg_data['to'])
            for member in group_obj.members.select_related():
                #如果字典不存在这个用户的queue
                if not GLOBAL_MSG_QUEUES.get(member.id):
                    GLOBAL_MSG_QUEUES[int(member.id)] = queue.Queue()
                if member.id != request.user.userprofile.id:
                    GLOBAL_MSG_QUEUES[member.id].put(msg_data)

 5.2.2.前端展示修改

 function ParseNewMsgs(callback) {
          var current_session_type = $(".chat-box-title").attr("contact-type");
          var current_session_id = $(".chat-box-title").attr("contact-id");
            for(var i in callback){
                console.log(callback[i]);

                if(callback[i].type == 'single'){
                    var msg_from_contact_id = callback[i]['from'];
                } else {//如果是group
                    var msg_from_contact_id = callback[i]['to'];
                }
                // { from: "1", to: "5", type: "single", msg: "\n22", timestamp: 1521081612.0092783 }
                var msg_item_ele = "<div class='msg-item'>" +
                        "<span>" + msg_from_contact_id + "</span>" +
                        "<span>" + callback[i].timestamp + "</span>" +
                        "<div class='msg-text'>" + callback[i].msg + "</div>" +
                        "</div>";

                if(callback[i].from == current_session_id && current_session_type == callback[i].type){
                    //此消息的发送方当前正在跟我聊天
                     $(".chat-box-window").append(msg_item_ele);
                } else {
                    //消息发送者当前没打开聊天框,消息暂存内存
                    if(GLOBAL_CHAT_RECORD_DIC[callback[i].type][msg_from_contact_id]){
                        GLOBAL_CHAT_RECORD_DIC[callback[i].type][msg_from_contact_id] += msg_item_ele;
                    }else {
                        GLOBAL_CHAT_RECORD_DIC[callback[i].type][msg_from_contact_id] = msg_item_ele;
                    }
                }//end if

                //新消息提醒
                //var contact_ele = $(".list-group li[contact-type='single']").filter("li[contact-id='3']")[0];
                var contact_ele = $(".list-group li[contact-type='"+ callback[i].type +"']").filter("li[contact-id='"+ msg_from_contact_id +"']")[0];
                var current_new_msg_num = $(contact_ele).find(".badge").text();
                $(contact_ele).find(".badge").removeClass("hide");
                var ckl = $(contact_ele).find(".badge").text(parseInt(current_new_msg_num)+1);
            }//enf for
        }

5.2.3.测试结果

ckl 发群消息:

 

贾岛接收群消息:

 

贾岛回复消息:

贾岛查看消息:

ckl 查看消息:

 5.2.4.用户名展示

 添加用户名字段:

    if (contact_type && contact_id){
               var msg_item ={
                        'from': "{{ request.user.userprofile.id }}",
                        'from_name':"{{ request.user.userprofile.name }}",
                        'to'  :contact_id,
                        'type':contact_type,
                        'msg' : msg_text
                    };
 if(callback[i].type == 'single'){
                    var msg_from_contact_id = callback[i]['from_name'];
                } else {//如果是group
                    var msg_from_contact_id = callback[i]['to'];
                }

ckl 发贾岛信息:

贾岛接收并回消息:

ckl查看:

 6.上传文件

6.1.文件上传添加

6.1.1.添加上传按钮

     <div class="chat-box-emoj">
            <div class="col-md-3">
                <input id="file_upload" type="file">
            </div>
            <div class="col-md-2">
                <span class="glyphicon glyphicon-upload" onclick="FileUpload()"></span>
            </div>
        </div>

6.1.2.ajax post文件

      function FileUpload() {
            var formData = new FormData();
            console.log($('#file_upload')[0].files[0]);
            formData.append('file',$('#file_upload')[0].files[0]);

            $.ajax({
                url:"{% url 'file_upload' %}",
                type:'POST',
                data:formData,
                processData:false,
                contentType:false,
                success:function (data) {
                    console.log(data);
                }
            });//end ajax
        }

6.1.3.增加上传url

from django.conf.urls import url,include
from django.contrib import admin
from webchat import views

urlpatterns = [
    url(r'^$',views.dashboard,name='chat_dashboard'),
    url(r'^msg_send/$',views.send_msg,name='send_msg'),
    url(r'^new_msgs/$', views.get_new_msgs, name='get_new_msgs'),
    url(r'^file_upload',views.file_upload,name='file_upload'),
]

6.1.4.增加view方法

def file_upload(request):
    print(request.POST,request.FILES)
    # return HttpResponse('dddd')
    file_obj = request.FILES.get('file')
    new_file_name = "uploads/%s" %file_obj.name
    with open(new_file_name,'wb') as new_file_obj:
        for chunk in file_obj.chunks():
            new_file_obj.write(chunk)
    return HttpResponse("-- upload success --")

6.1.5.上传文件

 6.2.增加上传进度条

6.2.1.修改file_upload方法

上传文件,将上传的文件大小写入到一个cache里,另外的方法读取cache内容,来实现上传进度条

from django.core.cache import cache

def file_upload(request):
    print(request.POST,request.FILES)
    file_obj = request.FILES.get('file')
    new_file_name = "uploads/%s" % file_obj.name
    recv_size = 0
    with open(new_file_name,'wb') as new_file_obj:
        for chunk in file_obj.chunks():
            new_file_obj.write(chunk)
            recv_size += len(chunk)
            cache.set(file_obj.name,recv_size)
    print(cache.get(file_obj.name))
    return HttpResponse("-- upload success --")

6.2.2.另外的方法读取cache里的内容

def file_upload_progress(request):
    print("----- you meiy --------------------")
    filename = request.GET.get("filename")
    print("this is a name :%s" %filename)
    progress = cache.get(filename)
    print("file[%s] uploading progress[%s]" %(filename,progress))
    return HttpResponse(json.dumps({"recv_size":progress}))

清除cache_key方法:

def delete_cache_key(request):
    cache_key = request.GET.get("cache_key")
    cache.delete(cache_key)
    return HttpResponse("cache key %s delete" %cache_key)

6.2.3.前端获取文件长传进度方法

      function GetFileUploadProgress(file_obj) {
            var UploadProgressRefresh = setInterval(function(callback){
                $.getJSON("{% url 'file_upload_progress' %}",{filename:file_obj.name},function(callback){
                        console.log("upload progress......" + callback);
                        if(file_obj.size == callback.recv_size){
                            //upload down
                            clearInterval(UploadProgressRefresh);
                            $.get("{% url 'delete_cache_key' %}",{cache_key:file_obj.name},function(callback){
                                console.log(callback);
                            })
                        }
                        var current_persent = (callback.recv_size/file_obj.size)*100 + "%";
                        $(".progress-bar").css("width",current_persent);
                        $(".progress-bar").text(current_persent);
                })
            },1000);
        }

6.2.4.在ajax上传开始就执行

   function FileUpload() {
            var formData = new FormData();//form table
            console.log($('#file_upload')[0].files[0]);
            formData.append('file',$('#file_upload')[0].files[0]);

            $.ajax({
                url:"{% url 'file_upload' %}",
                type:'POST',
                data:formData,
                processData:false,
                contentType:false,
                success:function (data) {
                    console.log(data);
                }
            });//end ajax

            GetFileUploadProgress($('#file_upload')[0].files[0]);
        }

6.2.5.增加调用的url

from django.conf.urls import url,include
from django.contrib import admin
from webchat import views

urlpatterns = [
    url(r'^$',views.dashboard,name='chat_dashboard'),
    url(r'^msg_send/$',views.send_msg,name='send_msg'),
    url(r'^new_msgs/$', views.get_new_msgs, name='get_new_msgs'),
    url(r'^file_upload/$',views.file_upload,name='file_upload'),
    url(r'^upload_progress/$',views.file_upload_progress,name='file_upload_progress'),
    url(r'^delete_cache_key/$',views.delete_cache_key,name='delete_cache_key'),
]

6.2.6.添加进度条

 <div class="progress">
      <div class="progress-bar" role="progressbar" aria-valuemin="0" aria-valuemax="100" style="width: 60%;">
        60%
      </div>
    </div>

6.2.7.测试上传

 7.发送图片

7.1.增加发送图片方法

function addSentMsgIntoBox(msg_text,msg_type) {
            if(msg_type == 'text'){
                var new_msg_ele = "<div class='msg-item'>" +
                    "<span>" + "{{ request.user.userprofile.name }}" + "</span>" +
                    "<span>" + new Date().toLocaleDateString() + "</span>" +
                    "<div class='msg-text'>" + msg_text + "</div>" +
                    "</div>"; //用户名+日期+消息内容
            } else if(msg_type.startsWith('image')) {
                var new_msg_ele = "<div class='msg-item'>" +
                    "<span>" + "{{ request.user.userprofile.name }}" + "</span>" +
                    "<span>" + new Date().toLocaleDateString() + "</span>" +
                    "<div class='msg-text'><img width='500px' src='/static/" +
                    "{{ request.user.userprofile.id }}/" + msg_text + "'/></div>" +
                    "</div>"; //用户名+日期+消息内容
            } else {
                 var new_msg_ele = "<div class='msg-item'>" +
                    "<span>" + "{{ request.user.userprofile.name }}" + "</span>" +
                    "<span>" + new Date().toLocaleDateString() + "</span>" +
                    "<div class='msg-text'><a href='/static/" +
                    "{{ request.user.userprofile.id }}/" + msg_text + "' target='_bank'/>点开看看</a></div>" +
                    "</div>"; //用户名+日期+消息内容
            }

7.2.传输文件到用户的id目录下

没有目录,则新建目录

def file_upload(request):
    print(request.POST,request.FILES)
    file_obj = request.FILES.get('file')
    user_home_dir = "uploads/%s" % request.user.userprofile.id
    if not os.path.isdir(user_home_dir):
        os.mkdir(user_home_dir)
    new_file_name = "%s/%s" %(user_home_dir,file_obj.name)
    recv_size = 0
    cache.delete(file_obj.name)
    with open(new_file_name,'wb') as new_file_obj:
        for chunk in file_obj.chunks():
            new_file_obj.write(chunk)
            recv_size += len(chunk)
            cache.set(file_obj.name,recv_size)
    print(cache.get(file_obj.name))
    return HttpResponse("-- upload success --")

7.3.测试发送

 

posted @ 2018-03-14 18:25  ckl893  阅读(217)  评论(0编辑  收藏  举报