You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
761 lines
83 KiB
761 lines
83 KiB
4 months ago
|
require.config({
|
||
|
paths: {
|
||
|
'jquery-colorpicker': '../addons/wanlshop/js/jquery.colorpicker.min',
|
||
|
'jquery-autocomplete': '../addons/wanlshop/js/jquery.autocomplete',
|
||
|
'jquery-jqprint': '../addons/wanlshop/js/jquery.jqprint-0.3.min',
|
||
|
'jquery-migrate': '../addons/wanlshop/js/jquery.migrate-1.2.1.min',
|
||
|
'vue': '../addons/wanlshop/js/vue.min',
|
||
|
'chat': '../addons/wanlshop/js/vue.min',
|
||
|
'sortablejs': '../addons/wanlshop/js/Sortable.min',
|
||
|
'vuedraggable': '../addons/wanlshop/js/vuedraggable.umd.min',
|
||
|
'clipboard': '../addons/wanlshop/js/clipboard.min'
|
||
|
},
|
||
|
shim: {
|
||
|
'jquery-colorpicker': {
|
||
|
deps: ['jquery'],
|
||
|
exports: '$.fn.extend'
|
||
|
},
|
||
|
'jquery-autocomplete': {
|
||
|
deps: ['jquery'],
|
||
|
exports: '$.fn.extend'
|
||
|
},
|
||
|
'jquery-jqprint': {
|
||
|
deps: ['jquery'],
|
||
|
exports: '$.fn.extend'
|
||
|
},
|
||
|
'jquery-migrate': {
|
||
|
deps: ['jquery'],
|
||
|
exports: '$.fn.extend'
|
||
|
},
|
||
|
'vue': {
|
||
|
deps: ['jquery'],
|
||
|
exports: '$.fn.extend'
|
||
|
},
|
||
|
'chat': {
|
||
|
deps: ['css!../addons/wanlshop/css/chat.css'],
|
||
|
exports: '$.fn.extend'
|
||
|
},
|
||
|
'sortablejs': {
|
||
|
deps: ['jquery'],
|
||
|
exports: '$.fn.extend'
|
||
|
},
|
||
|
'vuedraggable': {
|
||
|
deps: ['jquery'],
|
||
|
exports: '$.fn.extend'
|
||
|
},
|
||
|
'clipboard': {
|
||
|
deps: ['jquery'],
|
||
|
exports: '$.fn.extend'
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
// 后台全局添加 IM即时通讯
|
||
|
if (Config.modulename == 'admin' && Config.controllername == 'index' && Config.actionname == 'index') {
|
||
|
require(['chat'], function(Vue){
|
||
|
var html = `<!-- 加载WanlChat 即时通讯 --> <div class="wanl-chat-service" id="wanl-chat" v-cloak> <!-- 消息提示 --> <div class="wanl-chat-mini-msg" v-if="isMsg"><span>{{msgData.name}}:</span> {{msgData.text}}</div> <!-- 全局按钮 --> <div class="wanl-chat-mini" @click="onList" v-if="isList"> <div class="label label-success" v-if="count > 0" v-cloak>{{count}}</div> <div class="water0" :style="{backgroundImage: 'url('+(isMsg ? msgData.avatar : '/assets/addons/wanlshop/img/common/chat_mini.png')+')'}"></div> <div class="water1"></div> <div class="water2"></div> <div class="water3"></div> </div> <!-- IM 右侧列表 --> <div class="wanl-chat-list" v-else> <div class="head"> <div class="title"> <div> <h3>客服:{{service.nickname}}</h3><span v-if="shopOnline == 1"><i class="fa fa-circle text-success margin-r-5"></i> H5在线</span><span v-else><i class="fa fa-circle text-gray margin-r-5"></i> IM连接异常</span> </div> <div style="font-size: 14px;"><span class="active" @click="onAudio" v-if="isAudio"><i class="fa fa-volume-up text-red"></i></span><span v-else @click="onAudio"><i class="fa fa-volume-off link-black"></i></span><span style="margin-left: 10px; font-size: 16px;" @click="onList"><i class="fa fa-close link-black"></i></span></div> </div> </div> <div class="list"> <div class="empty" v-if="chatlist.length == 0"> <div class="main"><img :src="cdnurl('/assets/addons/wanlshop/img/default/find_default3x.png')"> <p>没有找到任何联系人</p> </div> </div> <div class="item" v-for="(item, index) in chatlist" :key="index" @click="otChat(index, 'main')"> <div class="portrait"><img :src="cdnurl(item.avatar)"><span class="online"><i class="fa fa-circle text-success" v-if="item.isOnline == 1"></i><i class="fa fa-circle text-gray" v-else></i></span></div> <div class="main"> <div class="user"><span class="username text-cut">{{item.nickname}}</span><span class="time">{{timefriendly(item.createtime)}}</span></div> <div class="info text-cut"><span v-if="item.count > 0">[未读{{item.count}}条]</span><span v-html="item.content"></span></div> </div> </div> </div> </div><!-- 聊天窗口 --> <div class="wanl-chat" :class="{full: onFull}" :style="{left:screenWidth+'px', top:screenHeight+'px',}" ref="moveBtn" v-show="chatWindow" v-cloak> <div class="list"> <ul> <li v-for="(item, index) in wanlchat" :key="index" :class="{checked: chatSelect == index}" @click="onChat(index)"> <div class="portrait"><img :src="cdnurl(item.avatar)"><span class="badge bg-red" v-if="item.count > 0">{{item.count}}</span></div> <div class="user-msg"> <p>{{item.nickname}}</p> <div class="text-cut" v-html="item.content"></div> </div> <div class="list-close" @click.stop="delChat(index)"> <div class="hover"><span class="fa fa-times-circle"></span></div> </div> </li> </ul> </div> <div class="main" v-if="chatSelect != null"> <div class="msgHead" @mousedown="down" @touchstart="down" @mousemove="move" @touchmove="move" @mouseup="end" @touchend="end" @touchcancel="end"><img :src="cdnurl(wanlchat[chatSelect].avatar)"> <div><span class="name">{{wanlchat[chatSelect].nickname}}</span> <p v-if="wanlchat[chatSelect].isOnline == 1"><i class="fa fa-circle text-success"></i> 在线</p> <p v-else><i class="fa fa-circle text-gray"></i> 离线</p> </div><!-- 窗口操作 --><span class="layui-layer-setwin"> <block v-if="onFull"><a class="layui-layer-ico layui-layer-max layui-layer-maxmin" href="javascript:;" @click="full"></a></block> <block v-else><a class="layui-layer-min" href="javascript:;" @click="miniChat"><cite></cite></a><a class="layui-layer-ico layui-layer-max" href="javascript:;" @click="full"></a></block><a class="layui-layer-ico layui-layer-close layui-layer-close1" href="javascript:;" @click="closeChat"></a> </span> </div> <div class="msgList" id="talk"> <ul> <li :class="{my: item.form.id == service.id}" v-for="(item, index) in chatContent" :key="index"> <div class="chat-user"><img :src="cdnurl(item.form.id == service.id ? service.avatar : item.form.avatar)"><cite><span>{{timefriendly(item.createtime)}}</span></cite></div><!-- 文字消息 --> <
|
||
|
$("body").append(html);
|
||
|
var wanlchat = new Vue({
|
||
|
el:"#wanl-chat",
|
||
|
data:{
|
||
|
count: 0, // 未读总数
|
||
|
chatlist: [], // 主列表
|
||
|
chatWindow: false, // 是否开启聊天窗口
|
||
|
isList: true, // 展示列表或按钮 --
|
||
|
isMsg: false, // 是否开启消息弹窗 --
|
||
|
msgData: {
|
||
|
avatar: '',
|
||
|
name: '',
|
||
|
text: ''
|
||
|
}, // 信息内容 --
|
||
|
chatMiniWindow: false, //最小化窗口
|
||
|
wanlchat: [], // 聊天窗口列表
|
||
|
chatSelect: null, // 选中的记录
|
||
|
chatContent: [], //消息内容&历史记录
|
||
|
textarea: '', // 编辑框
|
||
|
shopOnline: 1, // 商家在线状态
|
||
|
isAudio: true, // 消息提示
|
||
|
service: {
|
||
|
nickname: 'IM加载中..'
|
||
|
},
|
||
|
// 表情
|
||
|
emojiList: [],
|
||
|
TabCur: '默认',
|
||
|
showBox: false,
|
||
|
// 操作窗口
|
||
|
screenWidth: (document.body.clientWidth - 800) / 2,
|
||
|
screenHeight: (document.body.clientHeight - 600) / 2,
|
||
|
flags: false,
|
||
|
position: {
|
||
|
x: 0,
|
||
|
y: 0
|
||
|
},
|
||
|
nx: '',
|
||
|
ny: '',
|
||
|
dx: '',
|
||
|
dy: '',
|
||
|
xPum: '',
|
||
|
yPum: '',
|
||
|
isShow: false,
|
||
|
moveBtn: {},
|
||
|
onFull: false
|
||
|
},
|
||
|
mounted() {
|
||
|
this.moveBtn = this.$refs.moveBtn;
|
||
|
// 获取列表
|
||
|
this.loadData();
|
||
|
// 表情数据
|
||
|
this.emojiList = this.emojiData();
|
||
|
// 修复新版数据 1.0.8升级
|
||
|
this.loadUpdate();
|
||
|
},
|
||
|
methods: {
|
||
|
loadUpdate(){
|
||
|
Fast.api.ajax({
|
||
|
url: "wanlshop/client/update.html",
|
||
|
}, (data, ret) => {
|
||
|
if(data === 0){
|
||
|
Layer.open({
|
||
|
type: 1,
|
||
|
title: false, //不显示标题栏
|
||
|
closeBtn: false,
|
||
|
area: '400px;',
|
||
|
shade: 0,
|
||
|
id: 'wanlshop_v1.1.1', //设定一个id,防止重复弹出
|
||
|
resize: false,
|
||
|
btn: ['确认', '关闭'],
|
||
|
btnAlign: 'c',
|
||
|
moveType: 1, //拖拽模式,0或者1
|
||
|
content: `<div style="padding: 50px 40px; line-height: 22px; background-color: #222d32; color: #fff; font-weight: 300;">
|
||
|
<span style="width: 22px;display: inline-block;"></span>
|
||
|
恭喜你,已经升级到 WanlShop V1.1.1 版本,现需要对原有数据进行升级,
|
||
|
此操作可能会占用大量内存,点击确认升级数据,升级完成后此窗口不再弹出!
|
||
|
</div>`,
|
||
|
yes: index => {
|
||
|
Fast.api.ajax({
|
||
|
url: "wanlshop/client/repairSql.html",
|
||
|
}, (data, ret) => {
|
||
|
Layer.close(index);
|
||
|
})
|
||
|
}
|
||
|
});
|
||
|
var sound = new Audio();
|
||
|
sound.src = Fast.api.cdnurl('/assets/addons/wanlshop/voice/open.mp3');
|
||
|
sound.play();
|
||
|
}
|
||
|
return false;
|
||
|
});
|
||
|
},
|
||
|
loadData() {
|
||
|
let app = this;
|
||
|
Fast.api.ajax({
|
||
|
url: "wanlshop/service/lists.html",
|
||
|
}, (data, ret) => {
|
||
|
app.chatlist = data.chat;
|
||
|
app.service = data.service;
|
||
|
// 统计总数
|
||
|
app.chatCount();
|
||
|
// 开启即时通讯
|
||
|
// 连接IM服务器
|
||
|
const ws = new WebSocket(data.service.socketurl);
|
||
|
let sendTimmer = null;
|
||
|
let sendCount = 0;
|
||
|
ws.onopen = ()=> {
|
||
|
console.log('IM 启动成功');
|
||
|
// sendCount++;
|
||
|
// ws.send('Hello Server!' + sendCount);
|
||
|
// sendTimmer = setInterval(function () {
|
||
|
// sendCount++;
|
||
|
// ws.send('Hi Server!' + sendCount);
|
||
|
// if (sendCount === 10) {
|
||
|
// ws.close();
|
||
|
// }
|
||
|
// }, 2000);
|
||
|
};
|
||
|
ws.onmessage = (msg)=> {
|
||
|
let data = JSON.parse(msg.data);
|
||
|
if (data.type == 'init') {
|
||
|
console.log('@message_client_id:' + data.client_id);
|
||
|
Fast.api.ajax({
|
||
|
url: "wanlshop/service/bind.html",
|
||
|
data: {client_id: data.client_id}
|
||
|
}, function(data, ret){
|
||
|
app.shopOnline = data;
|
||
|
return false;
|
||
|
}, function(data, ret){
|
||
|
return false;
|
||
|
});
|
||
|
}else if (data.type == 'ping') {
|
||
|
ws.send('{"type":"pong"}');
|
||
|
}else if (data.type == 'service'){
|
||
|
// 更新类型
|
||
|
let updateType = null;
|
||
|
//判断是否开启窗口
|
||
|
if(this.chatWindow){
|
||
|
// 判断是否当前用户
|
||
|
if (data.form.id == this.wanlchat[this.chatSelect].user_id) {
|
||
|
// 更新当前页面消息
|
||
|
this.receiveChat(data);
|
||
|
updateType = 'openinto';
|
||
|
}else{
|
||
|
updateType = 'open';
|
||
|
}
|
||
|
}else{
|
||
|
updateType = 'main';
|
||
|
}
|
||
|
// 全局消息提示
|
||
|
this.onMsg(data, updateType);
|
||
|
// 更新主列表和 wanlchat列表,如果存在+1,如果不存在追加一个列表
|
||
|
this.updateChatList(data, updateType);
|
||
|
}
|
||
|
};
|
||
|
ws.onclose = ()=> {
|
||
|
console.log('IM 已关闭');
|
||
|
// sendTimmer && clearInterval(sendTimmer);
|
||
|
};
|
||
|
ws.onerror = ()=> {
|
||
|
console.log('IM 错误');
|
||
|
};
|
||
|
return false;
|
||
|
});
|
||
|
},
|
||
|
// 发送到服务器
|
||
|
send(data) {
|
||
|
Fast.api.ajax({
|
||
|
url: "wanlshop/service/send.html",
|
||
|
data: data
|
||
|
}, function(data, ret){
|
||
|
return false;
|
||
|
});
|
||
|
},
|
||
|
onList(){
|
||
|
// 如果窗口最小化
|
||
|
if(this.chatMiniWindow){
|
||
|
this.chatMiniWindow = false;
|
||
|
this.chatWindow = true;
|
||
|
this.isList = !this.isList;
|
||
|
}else{
|
||
|
this.isList = !this.isList;
|
||
|
}
|
||
|
},
|
||
|
// 打开主列表中
|
||
|
otChat(data, type){
|
||
|
let chat = type == 'main' ? this.chatlist[data] : {
|
||
|
user_id: data.form.id,
|
||
|
nickname: data.form.name,
|
||
|
avatar: data.form.avatar,
|
||
|
isOnline: 1,
|
||
|
count: 0,
|
||
|
content: this.typeMsg(data)
|
||
|
};
|
||
|
// 打开子窗口
|
||
|
this.onChat(this.addWanlChatList(chat));
|
||
|
// 判断是否最小化,如果最小化关闭,打开窗口
|
||
|
if(this.chatMiniWindow){
|
||
|
this.chatMiniWindow = false;
|
||
|
this.chatWindow = true;
|
||
|
}else{
|
||
|
this.chatWindow = true;
|
||
|
}
|
||
|
this.isList = !this.isList;
|
||
|
},
|
||
|
// 子窗口点击
|
||
|
onChat(index){
|
||
|
this.chatSelect = index;
|
||
|
let chat = this.wanlchat[index];
|
||
|
let app = this;
|
||
|
Fast.api.ajax({
|
||
|
url: "wanlshop/service/history.html",
|
||
|
data: {
|
||
|
id: chat.user_id
|
||
|
}
|
||
|
}, function(data, ret) {
|
||
|
// 替换表情
|
||
|
data.chat.forEach((item) => {
|
||
|
if (item.message.type == 'text') {
|
||
|
item.message.content.text = app.replaceEmoji(item.message.content.text);
|
||
|
}
|
||
|
})
|
||
|
// 写入记录
|
||
|
app.chatContent = data.chat;
|
||
|
// 更新在线状态
|
||
|
chat.isOnline = data.isOnline;
|
||
|
// 更新数据
|
||
|
app.count -= chat.count;
|
||
|
chat.count = 0;
|
||
|
// 更新主列表
|
||
|
app.chatlist[app.addChatList(chat, 'fun')].count = 0;
|
||
|
// 滚动最底部
|
||
|
app.latest();
|
||
|
return false;
|
||
|
});
|
||
|
},
|
||
|
// 更新主列表和 wanlchat列表,如果存在+1,如果不存在追加一个列表
|
||
|
updateChatList(chat, type){
|
||
|
let content = this.typeMsg(chat);
|
||
|
if(type == 'send'){
|
||
|
this.wanlchat[this.chatSelect].content = content;
|
||
|
this.chatlist.forEach((item, index) => {
|
||
|
if(item.user_id == chat.to_id){
|
||
|
item.content = content;
|
||
|
}
|
||
|
});
|
||
|
}else{
|
||
|
let chatlist = this.chatlist[this.addChatList(chat, 'msg')];
|
||
|
let wanlchat = this.wanlchat[this.addWanlChatList(chat, 'msg')];
|
||
|
// 更新在线状态
|
||
|
chatlist.isOnline = 1;
|
||
|
wanlchat.isOnline = 1;
|
||
|
// 已开窗口,确定此消息,更改已读
|
||
|
if(type == 'openinto'){
|
||
|
// 更新主列表
|
||
|
chatlist.content = content;
|
||
|
// 更新子列表
|
||
|
wanlchat.content = content;
|
||
|
// 设置已读
|
||
|
Fast.api.ajax({
|
||
|
url: "wanlshop/service/read.html",
|
||
|
data: {
|
||
|
id: wanlchat.user_id
|
||
|
}
|
||
|
}, function(data, ret) {
|
||
|
return false;
|
||
|
});
|
||
|
}else if(type == 'open'){
|
||
|
// 更新主列表
|
||
|
chatlist.content = content;
|
||
|
chatlist.count += 1;
|
||
|
this.count += 1;
|
||
|
// 更新子列表
|
||
|
wanlchat.content = content;
|
||
|
wanlchat.count += 1;
|
||
|
}else if(type == 'main'){
|
||
|
// 更新主列表
|
||
|
chatlist.content = content;
|
||
|
chatlist.count += 1;
|
||
|
this.count += 1;
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
// 判断主列表是否存在,不存在新增
|
||
|
addChatList(chat, type){
|
||
|
let data = type == 'msg' ? {
|
||
|
user_id: chat.form.id,
|
||
|
nickname: chat.form.name,
|
||
|
avatar: chat.form.avatar,
|
||
|
content: this.typeMsg(chat),
|
||
|
isOnline: 1,
|
||
|
createtime: chat.createtime
|
||
|
}:{
|
||
|
user_id: chat.user_id,
|
||
|
nickname: chat.nickname,
|
||
|
avatar: chat.avatar,
|
||
|
content: "没有任何消息",
|
||
|
isOnline: chat.isOnline,
|
||
|
createtime: (Date.parse( new Date() ).toString()).substr(0,10)
|
||
|
};
|
||
|
let chatlist = this.chatlist;
|
||
|
let key = null;
|
||
|
chatlist.forEach((item, index) => {
|
||
|
if(item.user_id == data.user_id){
|
||
|
key = index;
|
||
|
}
|
||
|
});
|
||
|
if(key == null){
|
||
|
chatlist.push(data);
|
||
|
key = chatlist.length-1;
|
||
|
}
|
||
|
return key;
|
||
|
},
|
||
|
// 判断wanlshop列表是否存在
|
||
|
addWanlChatList(data, type){
|
||
|
let chat = {};
|
||
|
if(type == 'msg'){
|
||
|
chat = {
|
||
|
user_id: data.form.id,
|
||
|
nickname: data.form.name,
|
||
|
avatar: data.form.avatar,
|
||
|
isOnline: 1,
|
||
|
content: this.typeMsg(data)
|
||
|
};
|
||
|
}else{
|
||
|
chat = data;
|
||
|
}
|
||
|
let wanlchat = this.wanlchat;
|
||
|
let key = null;
|
||
|
wanlchat.forEach((item, index) => {
|
||
|
if(item.user_id == chat.user_id){
|
||
|
key = index;
|
||
|
}
|
||
|
});
|
||
|
if(key == null){
|
||
|
wanlchat.push({
|
||
|
user_id: chat.user_id,
|
||
|
nickname: chat.nickname,
|
||
|
avatar: chat.avatar,
|
||
|
isOnline: chat.isOnline,
|
||
|
count: chat.count,
|
||
|
content: chat.content
|
||
|
});
|
||
|
key = wanlchat.length-1;
|
||
|
}
|
||
|
return key;
|
||
|
},
|
||
|
// 删除窗口,如果只有一个则直接关闭 判断删除的是否当前的,如果是读取第一个,如果不是直接删掉即可
|
||
|
delChat(index){
|
||
|
if(this.wanlchat.length == 1){
|
||
|
this.closeChat();
|
||
|
}else{
|
||
|
// 删除指定键
|
||
|
Vue.delete(this.wanlchat, index);
|
||
|
// 重新读取页面
|
||
|
this.onChat(this.wanlchat.length-1);
|
||
|
}
|
||
|
},
|
||
|
// 关闭窗口
|
||
|
closeChat(){
|
||
|
this.chatWindow = false; // 是否开启聊天窗口
|
||
|
this.wanlchat = []; // 聊天窗口列表
|
||
|
this.chatSelect = null; // 选中的记录
|
||
|
this.chatContent = []; //消息内容&历史记录
|
||
|
},
|
||
|
// 最小化窗口
|
||
|
miniChat(){
|
||
|
this.chatWindow = !this.chatWindow; // 聊天窗口
|
||
|
this.chatMiniWindow = !this.chatMiniWindow; // 是否开启聊天窗口
|
||
|
},
|
||
|
// 点击文本消息
|
||
|
submit() {
|
||
|
if (!this.textarea) {
|
||
|
return;
|
||
|
}
|
||
|
var msg = {
|
||
|
text: this.textarea
|
||
|
};
|
||
|
this.sendMsg(msg, 'text');
|
||
|
this.textarea = ''; //清空输入框
|
||
|
},
|
||
|
// 发送图片消息
|
||
|
chatImage(e){
|
||
|
var app = this;
|
||
|
let files = event.target.files[0]; //获取input的图片file值
|
||
|
require(['upload'], function (Upload) {
|
||
|
Upload.api.send(files, function (data, ret) {
|
||
|
// 1.1.2升级
|
||
|
var img = new Image();
|
||
|
img.src = `${data.fullurl}?${Date.parse(new Date())}`;
|
||
|
// 加载完成获取宽高
|
||
|
img.onload = ()=>{
|
||
|
app.sendMsg({
|
||
|
h: img.height,
|
||
|
w: img.width,
|
||
|
url: img.src
|
||
|
}, 'img');
|
||
|
};
|
||
|
return false;
|
||
|
});
|
||
|
});
|
||
|
},
|
||
|
// 发送消息
|
||
|
sendMsg(content, type) {
|
||
|
var data = {
|
||
|
type: 'service',
|
||
|
to_id: this.wanlchat[this.chatSelect].user_id,
|
||
|
form: {
|
||
|
id: this.service.id,
|
||
|
avatar: this.service.avatar,
|
||
|
name: this.service.nickname
|
||
|
},
|
||
|
message: {
|
||
|
type: type,
|
||
|
content: content
|
||
|
},
|
||
|
createtime: parseInt(new Date().getTime() / 1000)
|
||
|
};
|
||
|
// 发送到本地
|
||
|
this.receiveChat(JSON.parse(JSON.stringify(data)));
|
||
|
// 发送消息
|
||
|
this.send(data);
|
||
|
// 更新主列表和 wanlchat列表,如果存在+1,如果不存在追加一个列表
|
||
|
this.updateChatList(data, 'send');
|
||
|
},
|
||
|
// 接受消息
|
||
|
receiveChat(msg) {
|
||
|
if (msg.type == 'service') {
|
||
|
if (msg.message.type == 'text') {
|
||
|
msg.message.content.text = this.replaceEmoji(msg.message.content.text);
|
||
|
}
|
||
|
this.chatContent.push(msg);
|
||
|
}
|
||
|
// 滚动到底
|
||
|
this.latest();
|
||
|
},
|
||
|
// 播放语音
|
||
|
playVoice(url) {
|
||
|
let sound = new Audio();
|
||
|
sound.src = url;
|
||
|
sound.play();
|
||
|
},
|
||
|
//统计数量
|
||
|
chatCount(){
|
||
|
let count = 0;
|
||
|
this.chatlist.forEach((item)=>{
|
||
|
count += item.count;
|
||
|
});
|
||
|
this.count = count;
|
||
|
},
|
||
|
// 消息提示
|
||
|
onMsg(msg, type){
|
||
|
let text = '';
|
||
|
// 文本提示
|
||
|
if(type == 'main'){
|
||
|
text = `新消息:${msg.form.name},${this.typeMsg(msg)}`;
|
||
|
this.msgData = {
|
||
|
avatar: this.cdnurl(msg.form.avatar),
|
||
|
name: msg.form.name,
|
||
|
text: this.typeMsg(msg)
|
||
|
};
|
||
|
this.openMsg();
|
||
|
}
|
||
|
// 语音提示
|
||
|
if(this.isAudio){
|
||
|
this.playAudio(type, text);
|
||
|
}
|
||
|
},
|
||
|
//打开消息弹窗
|
||
|
openMsg(){
|
||
|
this.isMsg = true;
|
||
|
setInterval (()=> {
|
||
|
this.isMsg = false;
|
||
|
}, 5000);
|
||
|
},
|
||
|
// 在线语音合成
|
||
|
playAudio(type, str){
|
||
|
let sound = new Audio();
|
||
|
let url = '';
|
||
|
if(type == 'main'){
|
||
|
// url = str ? ('https://api.oick.cn/txt/apiz.php?spd=3&text=' + encodeURI(str)):''; // 1.1.5升级
|
||
|
url = this.cdnurl('/assets/addons/wanlshop/voice/chat.mp3');
|
||
|
}else if(type == 'openinto'){
|
||
|
url = this.cdnurl('/assets/addons/wanlshop/voice/open.mp3');
|
||
|
}else if(type == 'open'){
|
||
|
url = this.cdnurl('/assets/addons/wanlshop/voice/chat.mp3');
|
||
|
}
|
||
|
sound.src = url;
|
||
|
sound.play();
|
||
|
},
|
||
|
onAudio(){
|
||
|
this.isAudio = !this.isAudio;
|
||
|
this.isAudio ? layer.msg('提示音已开启', {icon: 1}):layer.msg('提示音已关闭', {icon: 2});
|
||
|
},
|
||
|
typeMsg(msg){
|
||
|
let text = '';
|
||
|
if (msg.type == 'system') {
|
||
|
if (msg.msg.type == 'text') {
|
||
|
text = msg.message.content.text;
|
||
|
}
|
||
|
} else if (msg.type == 'service') {
|
||
|
// 用户消息
|
||
|
if (msg.message.type == 'text') {
|
||
|
text = msg.message.content.text;
|
||
|
}else if (msg.message.type == 'voice') {
|
||
|
text = '[语音消息]';
|
||
|
}else if (msg.message.type == 'img') {
|
||
|
text = '[图片消息]';
|
||
|
}else if (msg.message.type == 'goods') {
|
||
|
text = '[商品消息]';
|
||
|
}else if (msg.message.type == 'order') {
|
||
|
text = '[订单消息]';
|
||
|
}else{
|
||
|
text = '[未知类型消息]';
|
||
|
}
|
||
|
}
|
||
|
return text;
|
||
|
},
|
||
|
//替换表情符号为图片
|
||
|
replaceEmoji(text) {
|
||
|
// 这里处理 链接 换行符
|
||
|
let replacedStr = text.replace(/\[([^(\]|\[)]*)\]/g, (item, index) => {
|
||
|
return '<img src="' + this.emojiList.map[item] + '" width="18rpx">';
|
||
|
});
|
||
|
return replacedStr.replace(/(\r\n)|(\n)/g, '<br>');
|
||
|
},
|
||
|
// 表情tab
|
||
|
tabSelect(e) {
|
||
|
this.TabCur = e.currentTarget.dataset.id;
|
||
|
},
|
||
|
//添加表情
|
||
|
addEmoji(em) {
|
||
|
this.textarea += em;
|
||
|
this.toggleBox();
|
||
|
},
|
||
|
// 点击空白区域关闭某个div图层
|
||
|
toggleBox() {
|
||
|
this.showBox = !this.showBox; //通过控制showBox来控制box的显示与隐藏
|
||
|
},
|
||
|
// 滚动底部
|
||
|
latest(){
|
||
|
if(this.chatWindow){
|
||
|
this.$nextTick(() => {
|
||
|
let msg = document.getElementById('talk') // 获取对象
|
||
|
msg.scrollTop = msg.scrollHeight // 滚动高度
|
||
|
})
|
||
|
}
|
||
|
},
|
||
|
cdnurl(url) {
|
||
|
if(url) return Fast.api.cdnurl(url);
|
||
|
},
|
||
|
toFind(type){
|
||
|
var name = '发布';
|
||
|
if(type == 'new'){
|
||
|
name = '发布 上新'
|
||
|
}else if(type == 'want'){
|
||
|
name = '发布 种草'
|
||
|
}else if(type == 'show'){
|
||
|
name = '发布 买家秀'
|
||
|
}
|
||
|
Fast.api.open('/index/wanlshop.find/add.html?type='+type, name);
|
||
|
},
|
||
|
full(){
|
||
|
this.onFull = !this.onFull;
|
||
|
},
|
||
|
// 实现移动端拖拽
|
||
|
down() {
|
||
|
this.flags = true;
|
||
|
var touch;
|
||
|
if (event.touches) {
|
||
|
touch = event.touches[0];
|
||
|
} else {
|
||
|
touch = event;
|
||
|
}
|
||
|
this.position.x = touch.clientX;
|
||
|
this.position.y = touch.clientY;
|
||
|
this.dx = this.moveBtn.offsetLeft;
|
||
|
this.dy = this.moveBtn.offsetTop;
|
||
|
},
|
||
|
move() {
|
||
|
if (this.flags) {
|
||
|
var touch;
|
||
|
if (event.touches) {
|
||
|
touch = event.touches[0];
|
||
|
} else {
|
||
|
touch = event;
|
||
|
}
|
||
|
this.nx = touch.clientX - this.position.x;
|
||
|
this.ny = touch.clientY - this.position.y;
|
||
|
this.xPum = this.dx + this.nx;
|
||
|
this.yPum = this.dy + this.ny;
|
||
|
var clientWidth = document.documentElement.clientWidth;
|
||
|
var clientHeight = document.documentElement.clientHeight;
|
||
|
if (this.xPum > 0 && this.xPum < (clientWidth - this.moveBtn.offsetWidth)) {
|
||
|
this.moveBtn.style.left = this.xPum + "px";
|
||
|
}
|
||
|
if (this.yPum > 0 && this.yPum < (clientHeight - this.moveBtn.offsetHeight)) {
|
||
|
this.moveBtn.style.top = this.yPum + "px";
|
||
|
}
|
||
|
|
||
|
//阻止页面的滑动默认事件
|
||
|
document.addEventListener("touchmove", this.handler, {
|
||
|
passive: false
|
||
|
});
|
||
|
}
|
||
|
},
|
||
|
//鼠标释放时候的函数
|
||
|
end() {
|
||
|
this.flags = false;
|
||
|
document.addEventListener('touchmove', this.handler, {
|
||
|
passive: false
|
||
|
});
|
||
|
},
|
||
|
handler(e) {
|
||
|
if(this.flags){
|
||
|
event.preventDefault();
|
||
|
}else{
|
||
|
return true
|
||
|
}
|
||
|
},
|
||
|
timeFormat(timestamp = null, fmt = 'yyyy-mm-dd'){
|
||
|
// yyyy:mm:dd|yyyy:mm|yyyy年mm月dd日|yyyy年mm月dd日 hh时MM分等,可自定义组合
|
||
|
timestamp = parseInt(timestamp);
|
||
|
// 如果为null,则格式化当前时间
|
||
|
if (!timestamp) timestamp = Number(new Date());
|
||
|
// 判断用户输入的时间戳是秒还是毫秒,一般前端js获取的时间戳是毫秒(13位),后端传过来的为秒(10位)
|
||
|
if (timestamp.toString().length == 10) timestamp *= 1000;
|
||
|
let date = new Date(timestamp);
|
||
|
let ret;
|
||
|
let opt = {
|
||
|
"y+": date.getFullYear().toString(), // 年
|
||
|
"m+": (date.getMonth() + 1).toString(), // 月
|
||
|
"d+": date.getDate().toString(), // 日
|
||
|
"h+": date.getHours().toString(), // 时
|
||
|
"M+": date.getMinutes().toString(), // 分
|
||
|
"s+": date.getSeconds().toString() // 秒
|
||
|
// 有其他格式化字符需求可以继续添加,必须转化成字符串
|
||
|
};
|
||
|
for (let k in opt) {
|
||
|
ret = new RegExp("(" + k + ")").exec(fmt);
|
||
|
if (ret) {
|
||
|
fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0")))
|
||
|
};
|
||
|
};
|
||
|
return fmt;
|
||
|
},
|
||
|
timefriendly(timestamp){
|
||
|
if (timestamp == null) timestamp = Number(new Date());
|
||
|
timestamp = parseInt(timestamp);
|
||
|
// 判断用户输入的时间戳是秒还是毫秒,一般前端js获取的时间戳是毫秒(13位),后端传过来的为秒(10位)
|
||
|
if (timestamp.toString().length == 10) timestamp *= 1000;
|
||
|
var timer = (new Date()).getTime() - timestamp;
|
||
|
timer = parseInt(timer / 1000);
|
||
|
// 如果小于5分钟,则返回"刚刚",其他以此类推
|
||
|
let tips = '';
|
||
|
switch (true) {
|
||
|
case timer < 86400:
|
||
|
tips = this.timeFormat(timestamp, 'hh:MM');
|
||
|
break;
|
||
|
case timer >= 86400 && timer < 86400 * 7:
|
||
|
var now = new Date(timestamp);
|
||
|
var week = ['日', '一', '二', '三', '四', '五', '六'];
|
||
|
switch (new Date().getDate() - now.getDate()) {
|
||
|
case 1:
|
||
|
tips = this.timeFormat(timestamp, '昨天 hh:MM');
|
||
|
break;
|
||
|
case 2:
|
||
|
tips = this.timeFormat(timestamp, '前天 hh:MM');
|
||
|
break;
|
||
|
default:
|
||
|
tips = '星期' + week[now.getDay()] + this.timeFormat(timestamp, 'hh:MM');
|
||
|
}
|
||
|
break;
|
||
|
case timer >= 86400 * 7:
|
||
|
tips = this.timeFormat(timestamp, 'mm-dd hh:MM');
|
||
|
break;
|
||
|
default:
|
||
|
tips = this.timeFormat(timestamp, 'yyyy-mm-dd hh:MM');
|
||
|
}
|
||
|
return tips;
|
||
|
},
|
||
|
// 表情数据
|
||
|
emojiData() {
|
||
|
let emotions = [{"phrase": "[微笑]","type": "face","url": "http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/e3/2018new_weixioa02_org.png","hot": false,"common": true,"category": "","icon": "http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/e3/2018new_weixioa02_org.png","value": "[微笑]","picid": ""}, {"phrase": "[可爱]","type": "face","url": "http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/09/2018new_keai_org.png","hot": false,"common": true,"category": "","icon": "http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/09/2018new_keai_org.png","value": "[可爱]","picid": ""}, {"phrase": "[太开心]","type": "face","url": "http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/1e/2018new_taikaixin_org.png","hot": false,"common": true,"category": "","icon": "http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/1e/2018new_taikaixin_org.png","value": "[太开心]","picid": ""}, {"phrase": "[鼓掌]","type": "face","url": "http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/6e/2018new_guzhang_org.png","hot": false,"common": true,"category": "","icon": "http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/6e/2018new_guzhang_thumb.png","value": "[鼓掌]","picid": ""}, {"phrase": "[嘻嘻]","type": "face","url": "http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/33/2018new_xixi_org.png","hot": false,"common": true,"category": "","icon": "http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/33/2018new_xixi_thumb.png","value": "[嘻嘻]","picid": ""}, {"phrase": "[哈哈]","type": "face","url": "http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/8f/2018new_haha_org.png","hot": false,"common": true,"category": "","icon": "http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/8f/2018new_haha_thumb.png","value": "[哈哈]","picid": ""}, {"phrase": "[笑cry]","type": "face","url": "http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/4a/2018new_xiaoku_thumb.png","hot": false,"common": true,"category": "","icon": "http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/4a/2018new_xiaoku_thumb.png","value": "[笑cry]","picid": ""}, {"phrase": "[挤眼]","type": "face","url": "http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/43/2018new_jiyan_org.png","hot": false,"common": true,"category": "","icon": "http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/43/2018new_jiyan_org.png","value": "[挤眼]","picid": ""}, {"phrase": "[馋嘴]","type": "face","url": "http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/fa/2018new_chanzui_org.png","hot": false,"common": true,"category": "","icon": "http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/fa/2018new_chanzui_org.png","value": "[馋嘴]","picid": ""}, {"phrase": "[黑线]","type": "face","url": "http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/a3/2018new_heixian_org.png","hot": false,"common": true,"category": "","icon": "http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/a3/2018new_heixian_thumb.png","value": "[黑线]","picid": ""}, {"phrase": "[汗]","type": "face","url": "http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/28/2018new_han_org.png","hot": false,"common": true,"category": "","icon": "http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/28/2018new_han_org.png","value": "[汗]","picid": ""}, {"phrase": "[挖鼻]","type": "face","url": "http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/9a/2018new_wabi_thumb.png","hot": false,"common": true,"category": "","icon": "http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/9a/2018new_wabi_thumb.png","value": "[挖鼻]","picid": ""}, {"phrase": "[哼]","type": "face","url": "http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/7c/2018new_heng_org.png","hot": false,"common": true,"category": "","icon": "http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/7c/2018new_heng_thumb.png","value": "[哼]","picid": ""}, {"phrase": "[怒]","type": "face","url": "http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/f6/2018new_nu_org.png","hot": false,"common": true,"category": "","icon": "http://img.
|
||
|
var groups = {},
|
||
|
categories = [],
|
||
|
map = {};
|
||
|
emotions.forEach(emotion => {
|
||
|
var cate = emotion.category.length > 0 ? emotion.category : '默认';
|
||
|
if (!groups[cate]) {
|
||
|
groups[cate] = [];
|
||
|
categories.push(cate);
|
||
|
}
|
||
|
groups[cate].push(emotion);
|
||
|
map[emotion.phrase] = emotion.icon;
|
||
|
});
|
||
|
return {
|
||
|
groups,
|
||
|
categories,
|
||
|
map
|
||
|
};
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
}
|