
mui实现聊天功能(完整版)
发布日期:2021-05-08 22:14:27
浏览次数:18
分类:原创文章
本文共 21600 字,大约阅读时间需要 72 分钟。
前台页面代码:
<!doctype html><html> <head> <meta charset="utf-8"> <title></title> <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /> <link href="../css/mui.css" rel="stylesheet" /> <link href="../css/mui.min.css" rel="stylesheet" /> <link rel="stylesheet" type="text/css" href="../css/Chat.css"/> <link rel="stylesheet" type="text/css" href="../css/mui.imageviewer.css"/> </head> <body> <header class="mui-bar mui-bar-nav"> <a class="mui-action-back mui-icon mui-icon-left-nav mui-pull-left"></a> <h1 class="mui-title"></h1> </header> <pre id='h'></pre> <script src="../js/arttmpl.js" type="text/javascript" charset="utf-8"></script> <script id='msg-template' type="text/template"> <% for(var i in record){ var item=record[i]; %> <div class="msg-item <%= (item.sender=='self'?' msg-item-self':'') %>" msg-type='<%=(item.type)%>' msg-content='<%=(item.content)%>'> <% if(item.sender=='self' ) { %> <i class="msg-user mui-icon mui-icon-person"></i> <% } else { %> <img class="msg-user-img" src="../images/logo.png" alt="" /> <% } %> <div class="msg-content"> <div class="msg-content-inner"> <% if(item.type=='text' ) { %> <%=( item.content|| ' ') %> <% } else if(item.type=='image' ) { %> <img class="msg-content-image" src="<%=(item.content)%>" style="max-width: 100px;" /> <% } else if(item.type=='sound' ) { %> <span class="mui-icon mui-icon-mic" style="font-size: 18px;font-weight: bold;"></span> <span class="play-state">点击播放</span> <% } %> </div> <div class="msg-content-arrow"></div> </div> <div class="mui-item-clear"></div> </div> <% } %> </script> <div class="mui-content"> <div id='msg-list'> </div> </div> <footer> <div class="footer-left"> <i id='msg-image' class="mui-icon mui-icon-camera" style="font-size: 28px;"></i> </div> <div class="footer-center"> <textarea id='msg-text' type="text" class='input-text'></textarea> <button id='msg-sound' type="button" class='input-sound' style="display: none;">按住说话</button> </div> <label for="" class="footer-right"> <i id='msg-type' class="mui-icon mui-icon-mic"></i> </label> </footer> <div id='sound-alert' class="rprogress"> <div class="rschedule"></div> <div class="r-sigh">!</div> <div id="audio_tips" class="rsalert">手指上滑,取消发送</div> </div> <script src="../js/jquery-2.1.0.js" type="text/javascript" charset="utf-8"></script> <script src="../js/mui.min.js"></script> <script src="../js/mui.imageViewer.js"></script> <script src="../js/arttmpl.js"></script> <script type="text/javascript"> mui.init(); mui.plusReady(function () { var cw=plus.webview.currentWebview(); var titleName=cw.title; var header=document.querySelector(".mui-title"); header.innerText=titleName; }); </script> <script type="text/javascript" charset="utf-8"> (function($, doc) { var MIN_SOUND_TIME = 800; $.init({ gestureConfig: { tap: true, //默认为true doubletap: true, //默认为false longtap: true, //默认为false swipe: true, //默认为true drag: true, //默认为true hold: true, //默认为false,不监听 release: true //默认为false,不监听 } }); template.config('escape', false); if(mui.os.ios){ // 解决在ios上fixed元素focusin时位置出现错误的问题 document.addEventListener('DOMContentLoaded',function(){ var footerDom = document.querySelector('footer'); document.addEventListener('focusin', function() { footerDom.style.position = 'absolute'; }); document.addEventListener('focusout', function() { footerDom.style.position = 'fixed'; }); }); } $.plusReady(function() { plus.webview.currentWebview().setStyle({ softinputMode: "adjustResize" }); var showKeyboard = function() { if ($.os.ios) { var webView = plus.webview.currentWebview().nativeInstanceObject(); webView.plusCallMethod({ "setKeyboardDisplayRequiresUserAction": false }); } else { var Context = plus.android.importClass("android.content.Context"); var InputMethodManager = plus.android.importClass("android.view.inputmethod.InputMethodManager"); var main = plus.android.runtimeMainActivity(); var imm = main.getSystemService(Context.INPUT_METHOD_SERVICE); imm.toggleSoftInput(0, InputMethodManager.SHOW_FORCED); //var view = ((ViewGroup)main.findViewById(android.R.id.content)).getChildAt(0); imm.showSoftInput(main.getWindow().getDecorView(), InputMethodManager.SHOW_IMPLICIT); //alert("ll"); } }; var record = []; //遍历发送回复信息 var myid=localStorage.getItem("myid"); var myuid=localStorage.getItem("uid"); $.ajax({ url:"http:47.98.32.209:8082/api/chat/SendReplyMessage", type:"post", data:{ uid:myuid, Rid:myid }, success:function(data){ console.log(JSON.stringify(data)); for(var key in data.datavalues){ var jsonstr=data.datavalues[key]; console.log(JSON.stringify(jsonstr)); if(myuid==jsonstr.Rid && myid==jsonstr.uid){ record.push({ sender: 'self', type: jsonstr.type, content: jsonstr.msg }); }else{ record.push({ sender: 'zc', type: jsonstr.type, content: jsonstr.msg }); } } ui.areaMsgList.innerHTML = template('msg-template', { "record": record }); }, error:function(err){ console.log(JSON.stringify(err)); } }) var ui = { body: doc.querySelector('body'), footer: doc.querySelector('footer'), footerRight: doc.querySelector('.footer-right'), footerLeft: doc.querySelector('.footer-left'), btnMsgType: doc.querySelector('#msg-type'), boxMsgText: doc.querySelector('#msg-text'), boxMsgSound: doc.querySelector('#msg-sound'), btnMsgImage: doc.querySelector('#msg-image'), areaMsgList: doc.querySelector('#msg-list'), boxSoundAlert: doc.querySelector('#sound-alert'), h: doc.querySelector('#h'), content: doc.querySelector('.mui-content') }; ui.h.style.width = ui.boxMsgText.offsetWidth + 'px'; //alert(ui.boxMsgText.offsetWidth ); var footerPadding = ui.footer.offsetHeight - ui.boxMsgText.offsetHeight; var msgItemTap = function(msgItem, event) { var msgType = msgItem.getAttribute('msg-type'); var msgContent = msgItem.getAttribute('msg-content') if (msgType == 'sound') { player = plus.audio.createPlayer(msgContent); var playState = msgItem.querySelector('.play-state'); playState.innerText = '正在播放...'; player.play(function() { playState.innerText = '点击播放'; }, function(e) { playState.innerText = '点击播放'; }); } }; var imageViewer = new $.ImageViewer('.msg-content-image', { dbl: false }); var bindMsgList = function() { //绑定数据: /*tp.bind({ template: 'msg-template', element: 'msg-list', model: record });*/ ui.areaMsgList.innerHTML = template('msg-template', { "record": record }); alert(ui.areaMsgList.innerHTML); var msgItems = ui.areaMsgList.querySelectorAll('.msg-item'); [].forEach.call(msgItems, function(item, index) { item.addEventListener('tap', function(event) { msgItemTap(item, event); }, false); }); imageViewer.findAllImage(); ui.areaMsgList.scrollTop = ui.areaMsgList.scrollHeight + ui.areaMsgList.offsetHeight; }; bindMsgList(); window.addEventListener('resize', function() { ui.areaMsgList.scrollTop = ui.areaMsgList.scrollHeight + ui.areaMsgList.offsetHeight; }, false); var send = function(msg) { console.log(JSON.stringify(msg)); record.push(msg); bindMsgList(); console.log(JSON.stringify(msg)); SendMessage(msg.content,msg.type); var username=document.querySelector(".mui-title").innerHTML; //ReplyMessage(msg.content,msg.type); }; //回复信息 var ReplyMessage = function(info,typeName) { $.ajax({ url:"http:47.98.32.209:8082/api/chat/AddSendReplyMessage", type:"post", data:{ uid:myuid, Rid: myid, msg: info, type:typeName } , success:function(data){ record.push({ sender: 'zs', type: typeName, content: info }); console.info("访问成功" + JSON.stringify(data)); bindMsgList(); }, error:function(err){ console.info(JSON.stringify(err)); } }); }; //发送信息 var SendMessage = function(info,typeName) { $.ajax({ url:"http:47.98.32.209:8082/api/chat/AddSendReplyMessage", type:"post", data:{ uid:myid, Rid: myuid, msg: info, type:typeName } , success:function(data){ console.log(JSON.stringify(data)); console.info("访问成功" + JSON.stringify(data.values)); }, error:function(err){ console.info(JSON.stringify(err)); } }); }; function msgTextFocus() { ui.boxMsgText.focus(); setTimeout(function() { ui.boxMsgText.focus(); }, 150); } //解决长按“发送”按钮,导致键盘关闭的问题; ui.footerRight.addEventListener('touchstart', function(event) { if (ui.btnMsgType.classList.contains('mui-icon-paperplane')) { msgTextFocus(); event.preventDefault(); } }); //解决长按“发送”按钮,导致键盘关闭的问题; ui.footerRight.addEventListener('touchmove', function(event) { if (ui.btnMsgType.classList.contains('mui-icon-paperplane')) { msgTextFocus(); event.preventDefault(); } }); // ui.footerRight.addEventListener('touchcancel', function(event) { // if (ui.btnMsgType.classList.contains('mui-icon-paperplane')) { // msgTextFocus(); // event.preventDefault(); // } // }); // ui.footerRight.addEventListener('touchend', function(event) { // if (ui.btnMsgType.classList.contains('mui-icon-paperplane')) { // msgTextFocus(); // event.preventDefault(); // } // }); //发送信息 ui.footerRight.addEventListener('release', function(event) { console.log(ui.boxMsgText.value); if (ui.btnMsgType.classList.contains('mui-icon-paperplane')) { //showKeyboard(); ui.boxMsgText.focus(); setTimeout(function() { ui.boxMsgText.focus(); }, 150); // event.detail.gesture.preventDefault(); send({ sender: 'self', type: 'text', content: ui.boxMsgText.value.replace(new RegExp('\n', 'gm'), '<br/>') }); ui.boxMsgText.value = ''; $.trigger(ui.boxMsgText, 'input', null); } else if (ui.btnMsgType.classList.contains('mui-icon-mic')) { ui.btnMsgType.classList.add('mui-icon-compose'); ui.btnMsgType.classList.remove('mui-icon-mic'); ui.boxMsgText.style.display = 'none'; ui.boxMsgSound.style.display = 'block'; ui.boxMsgText.blur(); document.body.focus(); } else if (ui.btnMsgType.classList.contains('mui-icon-compose')) { ui.btnMsgType.classList.add('mui-icon-mic'); ui.btnMsgType.classList.remove('mui-icon-compose'); ui.boxMsgSound.style.display = 'none'; ui.boxMsgText.style.display = 'block'; //-- //showKeyboard(); ui.boxMsgText.focus(); setTimeout(function() { ui.boxMsgText.focus(); }, 150); } }, false); ui.footerLeft.addEventListener('tap', function(event) { var btnArray = [{ title: "拍照" }, { title: "从相册选择" }]; plus.nativeUI.actionSheet({ title: "选择照片", cancel: "取消", buttons: btnArray }, function(e) { var index = e.index; switch (index) { case 0: break; case 1: var cmr = plus.camera.getCamera(); cmr.captureImage(function(path) { send({ sender: 'self', type: 'image', content: "file://" + plus.io.convertLocalFileSystemURL(path) }); }, function(err) { }); break; case 2: plus.gallery.pick(function(path) { send({ sender: 'self', type: 'image', content: path }); }, function(err) { }, null); break; } }); }, false); var setSoundAlertVisable=function(show){ if(show){ ui.boxSoundAlert.style.display = 'block'; ui.boxSoundAlert.style.opacity = 1; }else{ ui.boxSoundAlert.style.opacity = 0; //fadeOut 完成再真正隐藏 setTimeout(function(){ ui.boxSoundAlert.style.display = 'none'; },200); } }; var recordCancel = false; var recorder = null; var audio_tips = document.getElementById("audio_tips"); var startTimestamp = null; var stopTimestamp = null; var stopTimer = null; ui.boxMsgSound.addEventListener('hold', function(event) { recordCancel = false; if(stopTimer)clearTimeout(stopTimer); audio_tips.innerHTML = "手指上划,取消发送"; ui.boxSoundAlert.classList.remove('rprogress-sigh'); setSoundAlertVisable(true); recorder = plus.audio.getRecorder(); if (recorder == null) { plus.nativeUI.toast("不能获取录音对象"); return; } startTimestamp = (new Date()).getTime(); recorder.record({ filename: "_doc/audio/" }, function(path) { if (recordCancel) return; send({ sender: 'self', type: 'sound', content: path }); }, function(e) { plus.nativeUI.toast("录音时出现异常: " + e.message); }); }, false); ui.body.addEventListener('drag', function(event) { //console.log('drag'); if (Math.abs(event.detail.deltaY) > 50) { if (!recordCancel) { recordCancel = true; if (!audio_tips.classList.contains("cancel")) { audio_tips.classList.add("cancel"); } audio_tips.innerHTML = "松开手指,取消发送"; } } else { if (recordCancel) { recordCancel = false; if (audio_tips.classList.contains("cancel")) { audio_tips.classList.remove("cancel"); } audio_tips.innerHTML = "手指上划,取消发送"; } } }, false); ui.boxMsgSound.addEventListener('release', function(event) { //console.log('release'); if (audio_tips.classList.contains("cancel")) { audio_tips.classList.remove("cancel"); audio_tips.innerHTML = "手指上划,取消发送"; } // stopTimestamp = (new Date()).getTime(); if (stopTimestamp - startTimestamp < MIN_SOUND_TIME) { audio_tips.innerHTML = "录音时间太短"; ui.boxSoundAlert.classList.add('rprogress-sigh'); recordCancel = true; stopTimer=setTimeout(function(){ setSoundAlertVisable(false); },800); }else{ setSoundAlertVisable(false); } recorder.stop(); }, false); ui.boxMsgSound.addEventListener("touchstart", function(e) { //console.log("start...."); e.preventDefault(); }); ui.boxMsgText.addEventListener('input', function(event) { ui.btnMsgType.classList[ui.boxMsgText.value == '' ? 'remove' : 'add']('mui-icon-paperplane'); ui.btnMsgType.setAttribute("for", ui.boxMsgText.value == '' ? '' : 'msg-text'); ui.h.innerText = ui.boxMsgText.value.replace(new RegExp('\n', 'gm'), '\n-') || '-'; ui.footer.style.height = (ui.h.offsetHeight + footerPadding) + 'px'; ui.content.style.paddingBottom = ui.footer.style.height; }); var focus = false; ui.boxMsgText.addEventListener('tap', function(event) { ui.boxMsgText.focus(); setTimeout(function() { ui.boxMsgText.focus(); }, 0); focus = true; setTimeout(function () { focus = false; },1000); event.detail.gesture.preventDefault(); }, false); //点击消息列表,关闭键盘 ui.areaMsgList.addEventListener('click',function (event) { if(!focus){ ui.boxMsgText.blur(); } }) }); }(mui, document)); </script> </body></html>
数据库设计部分:
```go```ccreate database chatuse chatif exists (select * from sys.sysobjects where name='register') drop table registergo create table register( Rid int primary key identity, RcreateTime nvarchar(50) , Rusername nvarchar(20) , Rpassword nvarchar(20) , Remail nvarchar(30) unique) select * from registerif exists (select * from sys.sysobjects where name='PersonalInformation') drop table PersonalInformationgo create table PersonalInformation( Pid int primary key identity, Pheadimg nvarchar(50), Premark nvarchar(50), Paddress nvarchar(50), Pweixin nvarchar(30) , Pstate int default 0 ,-- 1代表在线,2代表隐身,0代表离线。 Pinsert int default 0,-- 0代表未添加好友,1代表已添加为好友。 Rid int foreign key references register(Rid)) select * from PersonalInformation if exists (select * from sys.sysobjects where name='SendReplyMessage') drop table SendReplyMessagegocreate table SendReplyMessage( SRid int primary key identity, SRcreatedate nvarchar(50) , msg text, type nvarchar(30), uid int foreign key references register(Rid), Rid int foreign key references register(Rid) ) select * from SendReplyMessage
后台实现:
方法实现:
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Data.SqlClient;namespace DAL{ public class SendReplyMessage_dal { public List<SendReplyMessage> selectsendReplyMessages(SendReplyMessage Message) { chatEntities chatEntities = new chatEntities(); SqlParameter p1 = new SqlParameter("@uid", Message.uid); SqlParameter p2 = new SqlParameter("@Rid", Message.Rid); List<SendReplyMessage> sendReplies = null; if (Message.uid== Message.Rid) { sendReplies = chatEntities.Database.SqlQuery<SendReplyMessage>(" select * from SendReplyMessage where (uid=@uid or uid=@Rid) and (Rid=@Rid or Rid=@uid)", p1, p2).ToList(); return sendReplies; } sendReplies = chatEntities.Database.SqlQuery<SendReplyMessage>(" select * from SendReplyMessage where (uid=@uid or uid=@Rid) and (Rid=@Rid or Rid=@uid) and uid!=Rid", p1,p2).ToList(); return sendReplies; } public int addsendMessae(SendReplyMessage sendmessage) { chatEntities chatEntities = new chatEntities(); SqlParameter p1 = new SqlParameter("@SRcreatedate",DateTime.Now.TimeOfDay); SqlParameter p2 = new SqlParameter("@msg", sendmessage.msg); SqlParameter p3 = new SqlParameter("@type", sendmessage.type); SqlParameter p4 = new SqlParameter("@uid", sendmessage.uid); SqlParameter p5 = new SqlParameter("@Rid", sendmessage.Rid); int row = chatEntities.Database.ExecuteSqlCommand("insert into SendReplyMessage(SRcreatedate,msg,type,uid,Rid) values(@SRcreatedate,@msg,@type,@uid,@Rid) ", p1,p2,p3,p4,p5); return row; } }}
调用实现:
using DAL;using myapi.Models;using System;using System.Collections.Generic;using System.Linq;using System.Net;using System.Net.Http;using System.Web.Http;namespace myapi.Controllers{ [RoutePrefix(prefix: "api/chat")]//如果去掉这段可以在下面加上 [Route(template:"api/Myuser/Login")],也可进去 public class chatController : ApiController { [HttpPost] [Route(template: "SendReplyMessage")] public IHttpActionResult selectsendReply(SendReplyMessage message) { SendReplyMessage_dal sendReplyMessage_Dal = new SendReplyMessage_dal(); List<SendReplyMessage> sendReplies = sendReplyMessage_Dal.selectsendReplyMessages(message); Messgaess<SendReplyMessage> messgaess = new Messgaess<SendReplyMessage>() { code = 200, msg = "请求成功", datavalues = sendReplies }; return Json(messgaess); } [HttpPost] [Route(template: "AddSendReplyMessage")] public IHttpActionResult addSendMessage(SendReplyMessage message) { SendReplyMessage_dal sendReplyMessage_Dal = new SendReplyMessage_dal(); int row = sendReplyMessage_Dal.addsendMessae(message); if (row>=1) { Messgaess<SendReplyMessage> messgaess = new Messgaess<SendReplyMessage>() { code = 200, msg = "请求成功", values = message }; return Json(messgaess); } return Json("请求错误"); } }}
效果实现:
发送信息:
发送(股份合计)
回复信息:
回复(总量:12345):
太难了,找工作。
发表评论
最新留言
逛到本站,mark一下
[***.202.152.39]2025年04月14日 06时46分36秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
Effective Java 读书笔记
2019-03-12
SpringBoot使用@Email报错误
2019-03-13
访问servlet时弹出文件下载框解决方法
2019-03-13
IDEA-@Slf4j和log标签&@Data(Lombok)无效
2019-03-13
Thymeleaf 生成下标,索引,使用Stat变量
2019-03-13
初始微服务---Springcloud发展【第一期】
2019-03-13
RAFT 拜占庭将军 共识算法
2019-03-13
UE4 错误列表 error码(只记录我遇到的情况,持续添加,未完成)
2019-03-13
Android 架构组件 – 让天下没有难做的 App
2019-03-13
能解决数据可视化大屏需求的3款可视化工具
2019-03-13
如何在VSCode中定制JSON的IntelliSense
2019-03-13
椭圆曲线的定义
2019-03-13
多代理区块链框架客户端的操作
2019-03-13
RSA操作中的公钥和私钥的生成
2019-03-13
go语言中类的继承和方法的使用
2019-03-13
一些技术博客
2019-03-13
第01问:MySQL 一次 insert 刷几次盘?
2019-03-13
libvirtd:内部错误:Failed to apply firewall rule
2019-03-13