IM查看最近聊天列表和消息,emoji表情替换

7 篇文章 0 订阅
2 篇文章 0 订阅

最近聊天列表、emoji表情替换

一、数据库

表名:ml_hxim_msg
id:主键id
from:发送人id
to:接收人id
data:数据内容
send_time:发送时间

二、SQL

$user_id = '';
$sql = '(SELECT * FROM 
(SELECT * FROM ml_hxim_msg WHERE send_time IN 
( SELECT MAX( send_time ) FROM ml_hxim_msg 
WHERE `from` = ' . $user_id . ' OR `to` = ' . $user_id . ' 
GROUP BY 
CONCAT(IF( `from` > `to`, `from`, `to` ),IF( `from` < `to`, `from`, `to` ))) 
AND ( `from` = ' . $user_id . ' OR `to` = ' . $user_id . ' ) 
ORDER BY id DESC ) AS c 
LEFT JOIN ml_user AS u ON c.`from`=u.id or c.`to`=u.id  
WHERE u.id!=' . $user_id . ' 
GROUP BY c.send_time ASC) as ml_hxim_msg';
//        $datas = DB::select($sql);//去掉sql前后括号 as ml_hxim_msg
        $datas = DB::table(DB::raw($sql))->paginate(10);//laravel 分页
        return $datas;

H5聊天页面

聊天页面

后端

    public function imMsg(Request $request)
    {
        $from = $request->get('from');
        $to = $request->get('to');
        $start_at = $request->get('start_at');
        $end_at = $request->get('end_at');
        $build = HximMsg::with('fromInfo:id,nickname,avatar,sex,status')
            ->with('toInfo:id,nickname,avatar,sex,status')
            ->where(function ($query) use ($from, $to, $start_at, $end_at) {
                $query->where([
                    ['from', '=', $from],
                    ['to', '=', $to],
                ]);
                if ($start_at) {
                    $query->whereBetween('send_time', [strtotime($start_at), strtotime($end_at)]);
                }
            })
            ->orWhere(function ($query) use ($from, $to, $start_at, $end_at) {
                $query->where([
                    ['from', '=', $to],
                    ['to', '=', $from],
                ]);
                if ($start_at) {
                    $query->whereBetween('send_time', [strtotime($start_at), strtotime($end_at)]);
                }
            });
        $datas = $build
            ->orderBy('send_time', 'ASC')->paginate(10);
        $filter = [
            'from' => $from,
            'to' => $to,
            'start_at' => $start_at,
            'end_at' => $end_at,
        ];
//        return $datas;
        if ($request->method() == 'GET') {
            return view('mladmin.im_msg', ['datas' => $datas, 'filter' => $filter]);
        } else {
            return $datas;
        }
    }

前端部分代码

腾讯IM的聊天记录&实时语音自定义消息

//css
    <style>
        * {
            box-sizing: border-box;
        }
        p, ul, li {
            margin: 0;
            padding: 0;
        }
        .clearfix::after {
            content: "";
            display: block;
            clear: both;
        }
        #iphone {
            width: 351px;
            height: 692px;
            /*background: url(images/iphone6.png) no-repeat;*/
            margin: 0 auto;
            padding: 20px 0 95px;
        }
        #wrap {
            width: 400px;
            height: 600px;
            margin: 0px auto;
            left: 19px;
            top: 80px;
            background: linear-gradient(transparent, rgba(0, 0, 0, .2)), url(images/timg.jpg) no-repeat 50%;
        }
        #div {
            width: 100%;
            height: 100%;
            margin: 0 auto;
            padding: 10px;
            overflow: auto;
        }
        #box {
            float: left;
        }
        #btn {
            background: #6abe83;
            border: none;
            width: 44px;
            height: 34px;
            margin: 10px 5px 0 0;
            border-radius: 6px;
            outline: none;
        }
        #inp {
            width: 200px;
            height: 36px;
            margin: 10px 5px 0 0;
            border-radius: 6px;
            border: none;
            outline: none;
            padding: 10px;
        }
        #imgWrap {
            float: left;
            margin: 10px 5px 0 10px;
        }
        #img {
            width: 36px;
            height: 36px;
            border-radius: 6px;
        }
        .send_img {
            width: 100%;
            height: 100%;
            border-radius: 6px;
        }
        .fr {
            float: right;
        }
        #ul li {
            width: 100%;
            list-style: none;
            margin-bottom: 10px;
        }
        .right {
            float: right;
        }
        .left {
            float: left;
        }
        #ul li.left img, #ul li.left div {
            float: left;
        }
        #ul li.right img, #ul li.right div {
            float: right;
        }
        #ul li.right div {
            margin-left: 10px;
        }
        #ul li.right div, #ul li.left div {
            /*height: 36px;*/
            /*line-height: 36px;*/
        }
        #ul li.left div {
            margin-right: 10px;
        }
        .inps, .inpss {
            background: #6abe83;
            /*height: 20px;*/
            max-width: 78%;
            padding: 6px 10px;
            border-radius: 8px;
            position: relative;
            white-space: normal;
            word-break: break-all;
        }
        .inps::after, .inpss::after {
            content: "";
            position: absolute;
            border-top: 6px solid transparent;
            border-bottom: 6px solid transparent;
            top: 9px;
        }
        .inps::after {
            border-right: 6px solid #6abe83;
            left: -6px;
        }
        .inpss::after {
            border-left: 6px solid #6abe83;
            right: -6px;
        }
    </style>

//H5
<div class="col-lg-12">
        <form class="form-horizontal">
            <div class="form-group">
                <label class="col-lg-2 control-label">搜索时间:</label>
                <div class="col-lg-3" style="display: flex">
                    <input type="text" name="start_at" class="form_datetime form-control"
                           value="{{$filter['start_at']}}"/>—
                    <input type="text" name="end_at" class="form_datetime form-control"
                           value="{{$filter['end_at']}}"/>

                    <input type="hidden" name="from"
                           value="{{$filter['from']}}"/>
                    <input type="hidden" name="to"
                           value="{{$filter['to']}}"/>
                    <input type="hidden" class="next_url"
                           value="{{$datas->nextPageUrl()}}"/>
                </div>
            </div>


            <div class="form-group-lg">
                <div class="col-lg-offset-2 col-lg-2">
                    <button type="submit" id="search_submit" class="btn btn-primary">开始搜索</button>
                    <a href="javascript:flush_condition();" class="btn btn-primary">清空条件</a>
                </div>
            </div>
        </form>

        <div id="iphone">
            <div id="wrap">
                <div id="div" class="clearfix">
                    <ul id="ul" class="clearfix">
                        @foreach($datas as $data)
                            <div style="text-align:center;color: grey">{{ date('Y-m-d H:i:s', $data['send_time']) }}</div>
                            <li @if($data->from == $filter['from']) class='left' @else class='right' @endif>
                                <div>
                                    @if($data->from == 'administrator')
                                        <img id="img"
                                             src="https://imagenew.meilimei.com/eabeedf3a9874c148785c400973116cd">
                                    @else
                                        <img id="img" src="{{$data->fromInfo->avatar}}" alt="">
                                    @endif
                                </div>
                                <div @if($data->from == $filter['from']) class='inps' @else class='inpss' @endif>
                                    @foreach(json_decode($data->data, true)['MsgBody'] as $val)
                                        @if($val['MsgType'] == 'TIMTextElem')
                                            <span class="send_text" style="display: flex;">
                                            {{$val['MsgContent']['Text']}}
                                        </span>
                                        @endif
                                        @if($val['MsgType'] == 'TIMSoundElem' && $val['MsgContent']['Download_Flag'] == 2)
                                            <div class="r_yuyin" style="cursor:pointer;" data-time="">
                                                <span>{{$val['MsgContent']['Second']}}</span>''
                                                <audio preload="auto" hidden="true">
                                                    <source src="{{$val['MsgContent']['Url']}}"
                                                            type="audio/mpeg">
                                                </audio>
                                            </div>
                                        @endif
                                        @if($val['MsgType'] == 'TIMImageElem')
                                            <img class="send_img"
                                                 src="{{$val['MsgContent']['ImageInfoArray'][0]['URL']}}"
                                                 alt="">
                                        @endif
                                        @if($val['MsgType'] == 'TIMCustomElem')
                                            @if(isset(json_decode($val['MsgContent']['Data'], true)['actionType']))
                                                @if(json_decode($val['MsgContent']['Data'], true)['actionType'] == 1)
                                                    发起通话
                                                @elseif(json_decode($val['MsgContent']['Data'], true)['actionType'] == 2)
                                                    取消通话
                                                @elseif(json_decode($val['MsgContent']['Data'], true)['actionType'] == 3)
                                                    已接听
                                                @endif
                                            @endif
                                        @endif
                                        @if($val['MsgType'] == 'TIMFileElem' && $val['MsgContent']['Download_Flag'] == 2)
                                            文件:
                                            <a href="{{$val['MsgContent']['Url']}}">{{$val['MsgContent']['FileName']}}</a>
                                        @endif
                                    @endforeach
                                </div>
                            </li>
                        @endforeach
                        <span class="see_more" style="cursor:pointer;color: darkgreen;margin-left: 40%">点击查看更多</span>
                    </ul>
                </div>
            </div>
        </div>
    </div>

//JS
<script type="text/javascript">
        $(function () {
            if ($('.next_url').val() == '') {
                $('.see_more').remove();
            }
            var js = null;
            //录音播放
            $(".r_yuyin").click(function () {
                let audio = $(this).children("audio")[0],
                    time_span = $(this).children("span"),
                    time = time_span.html(),
                    times = time;
                //先暂停其他的
                // if ($(this).siblings().find("audio")[0]) {
                //     $(this).siblings().find("audio")[0].pause();
                //     console.log('暂停其他')
                // }
                if (audio.paused) {
                    audio.play(); // 这个就是播放
                    console.log('播放');
                    var inter = setInterval("run()", 1000);
                } else {
                    audio.pause(); // 这个就是暂停
                    console.log('暂停');
                }

                run = function run() {
                    time--;
                    time_span.html(time);
                    if (time < 0) {
                        clearInterval(inter);
                        time_span.html(times);
                    }
                }
            });


            emojiUrl = 'https://imgcache.qq.com/open/qcloud/tim/assets/emoji/',
                emojiMap = {
                    '[NO]': 'emoji_0@2x.png',
                    '[OK]': 'emoji_1@2x.png',
                    '[下雨]': 'emoji_2@2x.png',
                    '[么么哒]': 'emoji_3@2x.png',
                    '[乒乓]': 'emoji_4@2x.png',
                    '[便便]': 'emoji_5@2x.png',
                    '[信封]': 'emoji_6@2x.png',
                    '[偷笑]': 'emoji_7@2x.png',
                    '[傲慢]': 'emoji_8@2x.png',
                    '[再见]': 'emoji_9@2x.png',
                    '[冷汗]': 'emoji_10@2x.png',
                    '[凋谢]': 'emoji_11@2x.png',
                    '[刀]': 'emoji_12@2x.png',
                    '[删除]': 'emoji_13@2x.png',
                    '[勾引]': 'emoji_14@2x.png',
                    '[发呆]': 'emoji_15@2x.png',
                    '[发抖]': 'emoji_16@2x.png',
                    '[可怜]': 'emoji_17@2x.png',
                    '[可爱]': 'emoji_18@2x.png',
                    '[右哼哼]': 'emoji_19@2x.png',
                    '[右太极]': 'emoji_20@2x.png',
                    '[右车头]': 'emoji_21@2x.png',
                    '[吐]': 'emoji_22@2x.png',
                    '[吓]': 'emoji_23@2x.png',
                    '[咒骂]': 'emoji_24@2x.png',
                    '[咖啡]': 'emoji_25@2x.png',
                    '[啤酒]': 'emoji_26@2x.png',
                    '[嘘]': 'emoji_27@2x.png',
                    '[回头]': 'emoji_28@2x.png',
                    '[困]': 'emoji_29@2x.png',
                    '[坏笑]': 'emoji_30@2x.png',
                    '[多云]': 'emoji_31@2x.png',
                    '[大兵]': 'emoji_32@2x.png',
                    '[大哭]': 'emoji_33@2x.png',
                    '[太阳]': 'emoji_34@2x.png',
                    '[奋斗]': 'emoji_35@2x.png',
                    '[奶瓶]': 'emoji_36@2x.png',
                    '[委屈]': 'emoji_37@2x.png',
                    '[害羞]': 'emoji_38@2x.png',
                    '[尴尬]': 'emoji_39@2x.png',
                    '[左哼哼]': 'emoji_40@2x.png',
                    '[左太极]': 'emoji_41@2x.png',
                    '[左车头]': 'emoji_42@2x.png',
                    '[差劲]': 'emoji_43@2x.png',
                    '[弱]': 'emoji_44@2x.png',
                    '[强]': 'emoji_45@2x.png',
                    '[彩带]': 'emoji_46@2x.png',
                    '[彩球]': 'emoji_47@2x.png',
                    '[得意]': 'emoji_48@2x.png',
                    '[微笑]': 'emoji_49@2x.png',
                    '[心碎了]': 'emoji_50@2x.png',
                    '[快哭了]': 'emoji_51@2x.png',
                    '[怄火]': 'emoji_52@2x.png',
                    '[怒]': 'emoji_53@2x.png',
                    '[惊恐]': 'emoji_54@2x.png',
                    '[惊讶]': 'emoji_55@2x.png',
                    '[憨笑]': 'emoji_56@2x.png',
                    '[手枪]': 'emoji_57@2x.png',
                    '[打哈欠]': 'emoji_58@2x.png',
                    '[抓狂]': 'emoji_59@2x.png',
                    '[折磨]': 'emoji_60@2x.png',
                    '[抠鼻]': 'emoji_61@2x.png',
                    '[抱抱]': 'emoji_62@2x.png',
                    '[抱拳]': 'emoji_63@2x.png',
                    '[拳头]': 'emoji_64@2x.png',
                    '[挥手]': 'emoji_65@2x.png',
                    '[握手]': 'emoji_66@2x.png',
                    '[撇嘴]': 'emoji_67@2x.png',
                    '[擦汗]': 'emoji_68@2x.png',
                    '[敲打]': 'emoji_69@2x.png',
                    '[晕]': 'emoji_70@2x.png',
                    '[月亮]': 'emoji_71@2x.png',
                    '[棒棒糖]': 'emoji_72@2x.png',
                    '[汽车]': 'emoji_73@2x.png',
                    '[沙发]': 'emoji_74@2x.png',
                    '[流汗]': 'emoji_75@2x.png',
                    '[流泪]': 'emoji_76@2x.png',
                    '[激动]': 'emoji_77@2x.png',
                    '[灯泡]': 'emoji_78@2x.png',
                    '[炸弹]': 'emoji_79@2x.png',
                    '[熊猫]': 'emoji_80@2x.png',
                    '[爆筋]': 'emoji_81@2x.png',
                    '[爱你]': 'emoji_82@2x.png',
                    '[爱心]': 'emoji_83@2x.png',
                    '[爱情]': 'emoji_84@2x.png',
                    '[猪头]': 'emoji_85@2x.png',
                    '[猫咪]': 'emoji_86@2x.png',
                    '[献吻]': 'emoji_87@2x.png',
                    '[玫瑰]': 'emoji_88@2x.png',
                    '[瓢虫]': 'emoji_89@2x.png',
                    '[疑问]': 'emoji_90@2x.png',
                    '[白眼]': 'emoji_91@2x.png',
                    '[皮球]': 'emoji_92@2x.png',
                    '[睡觉]': 'emoji_93@2x.png',
                    '[磕头]': 'emoji_94@2x.png',
                    '[示爱]': 'emoji_95@2x.png',
                    '[礼品袋]': 'emoji_96@2x.png',
                    '[礼物]': 'emoji_97@2x.png',
                    '[篮球]': 'emoji_98@2x.png',
                    '[米饭]': 'emoji_99@2x.png',
                    '[糗大了]': 'emoji_100@2x.png',
                    '[红双喜]': 'emoji_101@2x.png',
                    '[红灯笼]': 'emoji_102@2x.png',
                    '[纸巾]': 'emoji_103@2x.png',
                    '[胜利]': 'emoji_104@2x.png',
                    '[色]': 'emoji_105@2x.png',
                    '[药]': 'emoji_106@2x.png',
                    '[菜刀]': 'emoji_107@2x.png',
                    '[蛋糕]': 'emoji_108@2x.png',
                    '[蜡烛]': 'emoji_109@2x.png',
                    '[街舞]': 'emoji_110@2x.png',
                    '[衰]': 'emoji_111@2x.png',
                    '[西瓜]': 'emoji_112@2x.png',
                    '[调皮]': 'emoji_113@2x.png',
                    '[象棋]': 'emoji_114@2x.png',
                    '[跳绳]': 'emoji_115@2x.png',
                    '[跳跳]': 'emoji_116@2x.png',
                    '[车厢]': 'emoji_117@2x.png',
                    '[转圈]': 'emoji_118@2x.png',
                    '[鄙视]': 'emoji_119@2x.png',
                    '[酷]': 'emoji_120@2x.png',
                    '[钞票]': 'emoji_121@2x.png',
                    '[钻戒]': 'emoji_122@2x.png',
                    '[闪电]': 'emoji_123@2x.png',
                    '[闭嘴]': 'emoji_124@2x.png',
                    '[闹钟]': 'emoji_125@2x.png',
                    '[阴险]': 'emoji_126@2x.png',
                    '[难过]': 'emoji_127@2x.png',
                    '[雨伞]': 'emoji_128@2x.png',
                    '[青蛙]': 'emoji_129@2x.png',
                    '[面条]': 'emoji_130@2x.png',
                    '[鞭炮]': 'emoji_131@2x.png',
                    '[风车]': 'emoji_132@2x.png',
                    '[飞吻]': 'emoji_133@2x.png',
                    '[飞机]': 'emoji_134@2x.png',
                    '[饥饿]': 'emoji_135@2x.png',
                    '[香蕉]': 'emoji_136@2x.png',
                    '[骷髅]': 'emoji_137@2x.png',
                    '[麦克风]': 'emoji_138@2x.png',
                    '[麻将]': 'emoji_139@2x.png',
                    '[鼓掌]': 'emoji_140@2x.png',
                    '[龇牙]': 'emoji_141@2x.png'
                };
//表情替换
            reg = /\[.+?\]/g;
            $('.send_text').each(function () {
                var str = $(this).text();
                str = str.replace(reg, function (a, b) {
                    return "<img style='width: 20px;height: 20px;' src=" + emojiUrl + emojiMap[a] + " />";
                });
                $(this).html(str);
            });
        });

        $('.form_datetime').datetimepicker(
            {
                language: 'zh-CN',
                format: 'yyyy-mm-dd HH:ii',
                autoclose: true,
                todayBtn: true,
                minView: 0
            }
        );
//清空时间搜索
        function flush_condition() {
            $("input[name='start_at']").val('');
            $("input[name='end_at']").val('');
        }
//点击查看更多
        $('.see_more').click(function () {
            data = '&from=' + $("input[name='from']").val() + '&to=' + $("input[name='to']").val() + '&start_at=' + $("input[name='start_at']").val() + '&end_at=' + $("input[name='end_at']").val();
            url = $('.next_url').val();
            if (url) {
                url = url + data;
            }
            console.log(url);
            $.ajax({
                type: "POST",
                url: url,
                success: function (data) {
                    console.log(data);
                    if (data['data']) {
                        $.each(data['data'], function (index, value) {
                            $('#ul').append('<div style="text-align:center;color: grey">' + UnixToDate(value['send_time'], true, 8) + '</div>');
                            if (value['from'] == $("input[name='from']").val()) {
                                $li = "<li class='left'><div>";
                            } else {
                                $li = "<li class='right'><div>";
                            }
                            if (value['from'] == 'administrator') {
                                $li += '<img id="img" src="https://imagenew.meilimei.com/eabeedf3a9874c148785c400973116cd">';
                            } else {
                                $li += '<img id="img" src="' + value['from_info']['avatar'] + '">';
                            }
                            $li += '</div>';
                            if (value['from'] == $("input[name='from']").val()) {
                                $li += "<div class='inps'>";
                            } else {
                                $li += "<div class='inpss'>";
                            }
                            value['data'] = JSON.parse(value['data']);
                            $.each(value['data']['MsgBody'], function (key, val) {
                                if (val['MsgType'] == 'TIMTextElem') {
                                    text = val['MsgContent']['Text'].replace(reg, function (a, b) {
                                        return "<img style='width: 20px;height: 20px;' src=" + emojiUrl + emojiMap[a] + " />";
                                    });
                                    $li += '<span class="send_text" style="display: flex;">' + text + '</span>';
                                }
                                if (val['MsgType'] == 'TIMSoundElem' && val['MsgContent']['Download_Flag'] == 2) {
                                    $li += '<div class="r_yuyin" style="cursor:pointer;">' +
                                        '<span>' + val["MsgContent"]["Second"] + "</span>''" +
                                        '<audio preload="auto" hidden="true">' +
                                        '<source src="' + val['MsgContent']['Url'] + '" type="audio/mpeg">' +
                                        '</audio>' +
                                        '</div>';
                                }
                                if (val['MsgType'] == 'TIMImageElem') {
                                    $li += '<img class="send_img" src="' + val['MsgContent']['ImageInfoArray'][0]['URL'] + '">';
                                }
                                if (val['MsgType'] == 'TIMCustomElem') {
                                    // console.log(JSON.parse(val['MsgContent']['Data'])['actionType']);
                                    if (JSON.parse(val['MsgContent']['Data'])['actionType'] == 1) {
                                        $li += '发起通话';
                                    } else if (JSON.parse(val['MsgContent']['Data'])['actionType'] == 2) {
                                        $li += '取消通话';
                                    } else if (JSON.parse(val['MsgContent']['Data'])['actionType'] == 3) {
                                        $li += '已接听';
                                    }
                                }
                                if (val['MsgType'] == 'TIMFileElem' && val['MsgContent']['Download_Flag'] == 2) {
                                    $li += '文件:<a href="' + val['MsgContent']['Url'] + '">' + val['MsgContent']['FileName'] + '</a>';
                                }
                            });
                            $li += '</div></li>';
                            $('#ul').append($li);
                            if (data['next_page_url'] == null) {
                                $('.see_more').remove();
                            } else {
                                $('#ul').append($('.see_more'));
                                $('.next_url').val(data['next_page_url']);
                            }
                        });
                    }
                }
            });
        });

        /**
         * 时间戳转换日期
         * @param <int> unixTime    待时间戳(秒)
         * @param <bool> isFull    返回完整时间(Y-m-d 或者 Y-m-d H:i:s)
         * @param <int>  timeZone   时区
         */
        function UnixToDate(unixTime, isFull, timeZone) {
            if (typeof (timeZone) == 'number') {
                unixTime = parseInt(unixTime) + parseInt(timeZone) * 60 * 60;
            }
            var time = new Date(unixTime * 1000);
            var ymdhis = "";
            ymdhis += time.getUTCFullYear() + "-";
            ymdhis += (time.getUTCMonth() + 1) < 10 ? '0' + (time.getUTCMonth() + 1) + "-" : (time.getUTCMonth() + 1) + "-";
            ymdhis += time.getUTCDate() < 10 ? '0' + time.getUTCDate() : time.getUTCDate();
            if (isFull === true) {
                ymdhis += " " + time.getUTCHours() < 10 ? ' 0' + time.getUTCHours() + ":" : " " + time.getUTCHours() + ":";
                ymdhis += time.getUTCMinutes() < 10 ? '0' + time.getUTCMinutes() + ":" : time.getUTCMinutes() + ":";
                ymdhis += time.getUTCSeconds() < 10 ? '0' + time.getUTCSeconds() : time.getUTCSeconds();
            }
            return ymdhis;
        }
    </script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值