mirror of
https://gitee.com/beijing_hongye_huicheng/lilishop-ui.git
synced 2025-12-19 01:15:53 +08:00
IM
This commit is contained in:
67
im/src/utils/auth.js
Normal file
67
im/src/utils/auth.js
Normal file
@@ -0,0 +1,67 @@
|
||||
import JsBase64 from 'js-base64'
|
||||
|
||||
const USER_TOKEN = 'LILI-TOKEN'
|
||||
const USER_INFO = 'LILI-USERINFO'
|
||||
const USER_SETTING = 'LILI-SETTING'
|
||||
|
||||
/**
|
||||
* 设置用户授权token
|
||||
*
|
||||
* @param {String} token
|
||||
*/
|
||||
export function setToken(token) {
|
||||
return localStorage.setItem(
|
||||
USER_TOKEN,
|
||||
token
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取授权token
|
||||
*/
|
||||
export function getToken() {
|
||||
return localStorage.getItem(USER_TOKEN)
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置用户信息
|
||||
*
|
||||
* @param {Object} data
|
||||
*/
|
||||
export function setUserInfo(data) {
|
||||
localStorage.setItem(USER_INFO, JsBase64.Base64.encode(JSON.stringify(data)))
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户信息
|
||||
*/
|
||||
export function getUserInfo() {
|
||||
const data = JsBase64.Base64.decode(localStorage.getItem(USER_INFO) || '')
|
||||
return data ? JSON.parse(data) : {}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户本地缓存的设置信息
|
||||
*/
|
||||
export function getUserSettingCache() {
|
||||
const data = localStorage.getItem(USER_SETTING)
|
||||
return data ? JSON.parse(data) : {}
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户设置保存到浏览器缓存中
|
||||
*
|
||||
* @param {Object} state 用户设置相关信息
|
||||
*/
|
||||
export function setUserSettingCache(state) {
|
||||
localStorage.setItem(USER_SETTING, JSON.stringify(state))
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除用户相关缓存信息
|
||||
*/
|
||||
export function removeAll() {
|
||||
localStorage.removeItem(USER_TOKEN)
|
||||
localStorage.removeItem(USER_INFO)
|
||||
localStorage.removeItem(USER_SETTING)
|
||||
}
|
||||
144
im/src/utils/date.js
Normal file
144
im/src/utils/date.js
Normal file
@@ -0,0 +1,144 @@
|
||||
/**
|
||||
* 对Date的扩展,将 Date 转化为指定格式的String。
|
||||
*
|
||||
* 月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符,
|
||||
* 年(y)可以用 1-4 个占位符,毫秒(S)只能用 1 个占位符(是 1-3 位的数字)。
|
||||
*
|
||||
* 【示例】:
|
||||
* formatDate(new Date(), 'yyyy-MM-dd hh:mm:ss.S') ==> 2006-07-02 08:09:04.423
|
||||
* formatDate(new Date(), 'yyyy-M-d h:m:s.S') ==> 2006-7-2 8:9:4.18
|
||||
* formatDate(new Date(), 'hh:mm:ss.S') ==> 08:09:04.423
|
||||
*/
|
||||
export function formatDate(date, fmt) {
|
||||
const o = {
|
||||
'M+': date.getMonth() + 1, //月份
|
||||
'd+': date.getDate(), //日
|
||||
'h+': date.getHours(), //小时
|
||||
'm+': date.getMinutes(), //分
|
||||
's+': date.getSeconds(), //秒
|
||||
'q+': Math.floor((date.getMonth() + 3) / 3), //季度
|
||||
S: date.getMilliseconds(), //毫秒
|
||||
}
|
||||
|
||||
if (/(y+)/.test(fmt)) {
|
||||
fmt = fmt.replace(
|
||||
RegExp.$1,
|
||||
(date.getFullYear() + '').substr(4 - RegExp.$1.length)
|
||||
)
|
||||
}
|
||||
|
||||
for (let k in o) {
|
||||
if (new RegExp('(' + k + ')').test(fmt)) {
|
||||
let value =
|
||||
RegExp.$1.length == 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length)
|
||||
fmt = fmt.replace(RegExp.$1, value)
|
||||
}
|
||||
}
|
||||
|
||||
return fmt
|
||||
}
|
||||
|
||||
/**
|
||||
* 仿照微信中的消息时间显示逻辑,将时间戳(单位:毫秒)转换为友好的显示格式.
|
||||
*
|
||||
* 1)7天之内的日期显示逻辑是:今天、昨天(-1d)、前天(-2d)、星期?(只显示总计7天之内的星期数,即<=-4d);
|
||||
* 2)7天之外(即>7天)的逻辑:直接显示完整日期时间。
|
||||
*
|
||||
* @param {[long]} timestamp 时间戳(单位:毫秒),形如:1550789954260
|
||||
* @param {boolean} mustIncludeTime true表示输出的格式里一定会包含“时间:分钟”
|
||||
* ,否则不包含(参考微信,不包含时分的情况,用于首页“消息”中显示时)
|
||||
*
|
||||
* @return {string} 输出格式形如:“刚刚”、“10:30”、“昨天 12:04”、“前天 20:51”、“星期二”、“2019/2/21 12:09”等形式
|
||||
*/
|
||||
export function formatDateShort(timestamp, mustIncludeTime) {
|
||||
// 当前时间
|
||||
let currentDate = new Date()
|
||||
// 目标判断时间
|
||||
let srcDate = new Date(parseInt(timestamp))
|
||||
|
||||
let currentYear = currentDate.getFullYear()
|
||||
let currentMonth = currentDate.getMonth() + 1
|
||||
let currentDateD = currentDate.getDate()
|
||||
|
||||
let srcYear = srcDate.getFullYear()
|
||||
let srcMonth = srcDate.getMonth() + 1
|
||||
let srcDateD = srcDate.getDate()
|
||||
|
||||
let ret = ''
|
||||
|
||||
// 要额外显示的时间分钟
|
||||
let timeExtraStr = mustIncludeTime ? ' ' + formatDate(srcDate, 'hh:mm') : ''
|
||||
|
||||
// 当年
|
||||
if (currentYear == srcYear) {
|
||||
let currentTimestamp = currentDate.getTime()
|
||||
let srcTimestamp = timestamp
|
||||
// 相差时间(单位:毫秒)
|
||||
let deltaTime = currentTimestamp - srcTimestamp
|
||||
|
||||
// 当天(月份和日期一致才是)
|
||||
if (currentMonth == srcMonth && currentDateD == srcDateD) {
|
||||
// 时间相差60秒以内
|
||||
if (deltaTime < 60 * 1000) ret = '刚刚'
|
||||
// 否则当天其它时间段的,直接显示“时:分”的形式
|
||||
else ret = formatDate(srcDate, 'hh:mm')
|
||||
}
|
||||
// 当年 && 当天之外的时间(即昨天及以前的时间)
|
||||
else {
|
||||
// 昨天(以“现在”的时候为基准-1天)
|
||||
let yesterdayDate = new Date()
|
||||
yesterdayDate.setDate(yesterdayDate.getDate() - 1)
|
||||
|
||||
// 前天(以“现在”的时候为基准-2天)
|
||||
let beforeYesterdayDate = new Date()
|
||||
beforeYesterdayDate.setDate(beforeYesterdayDate.getDate() - 2)
|
||||
|
||||
// 用目标日期的“月”和“天”跟上方计算出来的“昨天”进行比较,是最为准确的(如果用时间戳差值
|
||||
// 的形式,是不准确的,比如:现在时刻是2019年02月22日1:00、而srcDate是2019年02月21日23:00,
|
||||
// 这两者间只相差2小时,直接用“deltaTime/(3600 * 1000)” > 24小时来判断是否昨天,就完全是扯蛋的逻辑了)
|
||||
if (
|
||||
srcMonth == yesterdayDate.getMonth() + 1 &&
|
||||
srcDateD == yesterdayDate.getDate()
|
||||
)
|
||||
ret = '昨天' + timeExtraStr
|
||||
// -1d
|
||||
// “前天”判断逻辑同上
|
||||
else if (
|
||||
srcMonth == beforeYesterdayDate.getMonth() + 1 &&
|
||||
srcDateD == beforeYesterdayDate.getDate()
|
||||
)
|
||||
ret = '前天' + timeExtraStr
|
||||
// -2d
|
||||
else {
|
||||
// 跟当前时间相差的小时数
|
||||
let deltaHour = deltaTime / (3600 * 1000)
|
||||
|
||||
// 如果小于或等 7*24小时就显示星期几
|
||||
if (deltaHour <= 7 * 24) {
|
||||
let weekday = new Array(7)
|
||||
weekday[0] = '星期日'
|
||||
weekday[1] = '星期一'
|
||||
weekday[2] = '星期二'
|
||||
weekday[3] = '星期三'
|
||||
weekday[4] = '星期四'
|
||||
weekday[5] = '星期五'
|
||||
weekday[6] = '星期六'
|
||||
|
||||
// 取出当前是星期几
|
||||
let weedayDesc = weekday[srcDate.getDay()]
|
||||
ret = weedayDesc + timeExtraStr
|
||||
}
|
||||
// 否则直接显示完整日期时间
|
||||
else {
|
||||
ret = formatDate(srcDate, 'yyyy/M/d') + timeExtraStr
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 往年
|
||||
else {
|
||||
ret = formatDate(srcDate, 'yyyy/M/d') + timeExtraStr
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
180
im/src/utils/editor.js
Normal file
180
im/src/utils/editor.js
Normal file
@@ -0,0 +1,180 @@
|
||||
/**
|
||||
* 遍历对象
|
||||
*
|
||||
* @param {Object} obj
|
||||
* @param {Object} fn
|
||||
*/
|
||||
export function objForEach(obj, fn) {
|
||||
let key = void 0,
|
||||
result = void 0
|
||||
for (key in obj) {
|
||||
if (obj.hasOwnProperty(key)) {
|
||||
result = fn.call(obj, key, obj[key])
|
||||
if (result === false) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 遍历类数组
|
||||
*
|
||||
* @param {Object} fakeArr
|
||||
* @param {Object} fn
|
||||
*/
|
||||
export function arrForEach(fakeArr, fn) {
|
||||
let i = void 0,
|
||||
item = void 0,
|
||||
result = void 0
|
||||
let length = fakeArr.length || 0
|
||||
for (i = 0; i < length; i++) {
|
||||
item = fakeArr[i]
|
||||
result = fn.call(fakeArr, item, i)
|
||||
if (result === false) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 替换 html 特殊字符
|
||||
*
|
||||
* @param {Object} html
|
||||
*/
|
||||
export function replaceHtmlSymbol(html) {
|
||||
if (html == null) {
|
||||
return ''
|
||||
}
|
||||
return html
|
||||
.replace(/</gm, '<')
|
||||
.replace(/>/gm, '>')
|
||||
.replace(/"/gm, '"')
|
||||
.replace(/(\r\n|\r|\n)/g, '<br/>')
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取粘贴的纯文本
|
||||
*
|
||||
* @param {Object} e
|
||||
*/
|
||||
export function getPasteText(e) {
|
||||
let clipboardData =
|
||||
e.clipboardData || (e.originalEvent && e.originalEvent.clipboardData)
|
||||
let pasteText = void 0
|
||||
if (clipboardData == null) {
|
||||
pasteText = window.clipboardData && window.clipboardData.getData('text')
|
||||
} else {
|
||||
pasteText = clipboardData.getData('text/plain')
|
||||
}
|
||||
|
||||
return replaceHtmlSymbol(pasteText)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取粘贴的html
|
||||
*
|
||||
* @param {Object} e
|
||||
* @param {Object} filterStyle
|
||||
* @param {Object} ignoreImg
|
||||
*/
|
||||
export function getPasteHtml(e, filterStyle, ignoreImg) {
|
||||
let clipboardData =
|
||||
e.clipboardData || (e.originalEvent && e.originalEvent.clipboardData)
|
||||
let pasteText = void 0,
|
||||
pasteHtml = void 0
|
||||
if (clipboardData == null) {
|
||||
pasteText = window.clipboardData && window.clipboardData.getData('text')
|
||||
} else {
|
||||
pasteText = clipboardData.getData('text/plain')
|
||||
pasteHtml = clipboardData.getData('text/html')
|
||||
}
|
||||
if (!pasteHtml && pasteText) {
|
||||
pasteHtml = '<p>' + replaceHtmlSymbol(pasteText) + '</p>'
|
||||
}
|
||||
if (!pasteHtml) {
|
||||
return
|
||||
}
|
||||
|
||||
// 过滤word中状态过来的无用字符
|
||||
let docSplitHtml = pasteHtml.split('</html>')
|
||||
if (docSplitHtml.length === 2) {
|
||||
pasteHtml = docSplitHtml[0]
|
||||
}
|
||||
|
||||
// 过滤无用标签
|
||||
pasteHtml = pasteHtml.replace(/<(meta|script|link).+?>/gim, '')
|
||||
// 去掉注释
|
||||
pasteHtml = pasteHtml.replace(/<!--.*?-->/gm, '')
|
||||
// 过滤 data-xxx 属性
|
||||
pasteHtml = pasteHtml.replace(/\s?data-.+?=('|").+?('|")/gim, '')
|
||||
|
||||
if (ignoreImg) {
|
||||
// 忽略图片
|
||||
pasteHtml = pasteHtml.replace(/<img.+?>/gim, '')
|
||||
}
|
||||
|
||||
if (filterStyle) {
|
||||
// 过滤样式
|
||||
pasteHtml = pasteHtml.replace(/\s?(class|style)=('|").*?('|")/gim, '')
|
||||
} else {
|
||||
// 保留样式
|
||||
pasteHtml = pasteHtml.replace(/\s?class=('|").*?('|")/gim, '')
|
||||
}
|
||||
|
||||
return pasteHtml
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取粘贴的图片文件
|
||||
*
|
||||
* @param {Object} e
|
||||
*/
|
||||
export function getPasteImgs(e) {
|
||||
let result = []
|
||||
let txt = getPasteText(e)
|
||||
if (txt) {
|
||||
// 有文字,就忽略图片
|
||||
return result
|
||||
}
|
||||
|
||||
let clipboardData =
|
||||
e.clipboardData || (e.originalEvent && e.originalEvent.clipboardData) || {}
|
||||
let items = clipboardData.items
|
||||
if (!items) {
|
||||
return result
|
||||
}
|
||||
|
||||
objForEach(items, function(key, value) {
|
||||
let type = value.type
|
||||
if (/image/i.test(type)) {
|
||||
result.push(value.getAsFile())
|
||||
}
|
||||
})
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取拖拽的图片
|
||||
*
|
||||
* @param {Object} e
|
||||
*/
|
||||
export function getDragPasteImg(e) {
|
||||
let result = []
|
||||
let dataTransfer =
|
||||
e.dataTransfer || (e.originalEvent && e.originalEvent.dataTransfer) || {}
|
||||
let items = dataTransfer.items
|
||||
if (!items) {
|
||||
return result
|
||||
}
|
||||
|
||||
objForEach(items, function(key, value) {
|
||||
let type = value.type
|
||||
if (/image/i.test(type)) {
|
||||
result.push(value.getAsFile())
|
||||
}
|
||||
})
|
||||
|
||||
return result
|
||||
}
|
||||
144
im/src/utils/emojis.js
Normal file
144
im/src/utils/emojis.js
Normal file
@@ -0,0 +1,144 @@
|
||||
/**
|
||||
* 动态表情
|
||||
*/
|
||||
const emojis = {
|
||||
"[微笑]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/0.gif'>",
|
||||
"[撇嘴]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/1.gif'>",
|
||||
"[色]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/2.gif'>",
|
||||
"[发呆]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/3.gif'>",
|
||||
"[得意]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/4.gif'>",
|
||||
"[流泪]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/5.gif'>",
|
||||
"[害羞]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/6.gif'>",
|
||||
"[闭嘴]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/7.gif'>",
|
||||
"[睡]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/8.gif'>",
|
||||
"[大哭]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/9.gif'>",
|
||||
"[尴尬]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/10.gif'>",
|
||||
"[发怒]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/11.gif'>",
|
||||
"[调皮]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/12.gif'>",
|
||||
"[呲牙]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/13.gif'>",
|
||||
"[惊讶]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/14.gif'>",
|
||||
"[难过]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/15.gif'>",
|
||||
"[酷]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/16.gif'>",
|
||||
"[冷汗]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/17.gif'>",
|
||||
"[抓狂]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/18.gif'>",
|
||||
"[吐]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/19.gif'>",
|
||||
"[偷笑]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/20.gif'>",
|
||||
"[可爱]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/21.gif'>",
|
||||
"[白眼]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/22.gif'>",
|
||||
"[傲慢]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/23.gif'>",
|
||||
"[饥饿]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/24.gif'>",
|
||||
"[困]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/25.gif'>",
|
||||
"[惊恐]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/26.gif'>",
|
||||
"[流汗]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/27.gif'>",
|
||||
"[憨笑]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/28.gif'>",
|
||||
"[大兵]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/29.gif'>",
|
||||
"[奋斗]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/30.gif'>",
|
||||
"[咒骂]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/31.gif'>",
|
||||
"[疑问]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/32.gif'>",
|
||||
"[嘘]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/33.gif'>",
|
||||
"[晕]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/34.gif'>",
|
||||
"[折磨]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/35.gif'>",
|
||||
"[衰]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/36.gif'>",
|
||||
"[骷髅]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/37.gif'>",
|
||||
"[敲打]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/38.gif'>",
|
||||
"[再见]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/39.gif'>",
|
||||
"[擦汗]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/40.gif'>",
|
||||
"[抠鼻]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/41.gif'>",
|
||||
"[鼓掌]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/42.gif'>",
|
||||
"[糗大了]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/43.gif'>",
|
||||
"[坏笑]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/44.gif'>",
|
||||
"[左哼哼]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/45.gif'>",
|
||||
"[右哼哼]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/46.gif'>",
|
||||
"[哈欠]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/47.gif'>",
|
||||
"[鄙视]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/48.gif'>",
|
||||
"[委屈]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/49.gif'>",
|
||||
"[快哭了]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/50.gif'>",
|
||||
"[阴险]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/51.gif'>",
|
||||
"[亲亲]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/52.gif'>",
|
||||
"[吓]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/53.gif'>",
|
||||
"[可怜]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/54.gif'>",
|
||||
"[菜刀]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/55.gif'>",
|
||||
"[西瓜]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/56.gif'>",
|
||||
"[啤酒]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/57.gif'>",
|
||||
"[篮球]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/58.gif'>",
|
||||
"[乒乓]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/59.gif'>",
|
||||
"[咖啡]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/60.gif'>",
|
||||
"[饭]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/61.gif'>",
|
||||
"[猪头]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/62.gif'>",
|
||||
"[玫瑰]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/63.gif'>",
|
||||
"[凋谢]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/64.gif'>",
|
||||
"[示爱]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/65.gif'>",
|
||||
"[爱心]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/66.gif'>",
|
||||
"[心碎]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/67.gif'>",
|
||||
"[蛋糕]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/68.gif'>",
|
||||
"[闪电]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/69.gif'>",
|
||||
"[炸弹]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/70.gif'>",
|
||||
"[刀]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/71.gif'>",
|
||||
"[足球]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/72.gif'>",
|
||||
"[瓢虫]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/73.gif'>",
|
||||
"[便便]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/74.gif'>",
|
||||
"[月亮]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/75.gif'>",
|
||||
"[太阳]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/76.gif'>",
|
||||
"[礼物]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/77.gif'>",
|
||||
"[拥抱]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/78.gif'>",
|
||||
"[强]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/79.gif'>",
|
||||
"[弱]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/80.gif'>",
|
||||
"[握手]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/81.gif'>",
|
||||
"[胜利]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/82.gif'>",
|
||||
"[抱拳]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/83.gif'>",
|
||||
"[勾引]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/84.gif'>",
|
||||
"[拳头]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/85.gif'>",
|
||||
"[差劲]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/86.gif'>",
|
||||
"[爱你]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/87.gif'>",
|
||||
"[NO]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/88.gif'>",
|
||||
"[OK]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/89.gif'>",
|
||||
"[爱情]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/90.gif'>",
|
||||
"[飞吻]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/91.gif'>",
|
||||
"[跳跳]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/92.gif'>",
|
||||
"[发抖]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/93.gif'>",
|
||||
"[怄火]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/94.gif'>",
|
||||
"[转圈]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/95.gif'>",
|
||||
"[磕头]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/96.gif'>",
|
||||
"[回头]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/97.gif'>",
|
||||
"[跳绳]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/98.gif'>",
|
||||
"[挥手]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/99.gif'>",
|
||||
"[激动]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/100.gif'>",
|
||||
"[街舞]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/101.gif'>",
|
||||
"[献吻]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/102.gif'>",
|
||||
"[左太极]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/103.gif'>",
|
||||
"[右太极]": "<img src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/104.gif'>",
|
||||
};
|
||||
|
||||
/**
|
||||
* 符号表情
|
||||
*/
|
||||
const symbol = [
|
||||
"😠", "😩", "😲", "😞", "😵", "😰", "😒", "😍", "😤", "😜", "😝", "😋", "😘", "😚", "😷",
|
||||
"😳", "😃", "😅", "😆", "😁", "😂", "😊", "☺", "😄", "😢",
|
||||
"😭", "😨", "😣", "😡", "😌", "😖", "😔", "😱", "😪", "😏", "😓", "😥", "😫", "😉",
|
||||
"✊", "✋", "✌", "👊", "👍", "☝", "👆", "👇", "👈", "👉",
|
||||
"👋", "👏", "👌", "👎"
|
||||
];
|
||||
|
||||
const emojisKeys = Object.keys(emojis);
|
||||
|
||||
export const emojiList = {
|
||||
symbol,
|
||||
emojis
|
||||
}
|
||||
|
||||
const regEmoji = emojisKeys.map((value) => '|\\' + value).join('').replace('|', '')
|
||||
|
||||
/**
|
||||
* 替换表情文字
|
||||
*
|
||||
* @param {String} content 需要替换的字符串
|
||||
*/
|
||||
export function textReplaceEmoji(content) {
|
||||
if(!content){
|
||||
return ""
|
||||
}
|
||||
return content.replace(new RegExp(`(${regEmoji})`, 'gi'), ($0, $1) => {
|
||||
return emojis[$1];
|
||||
});
|
||||
}
|
||||
524
im/src/utils/functions.js
Normal file
524
im/src/utils/functions.js
Normal file
@@ -0,0 +1,524 @@
|
||||
/** 公共方法类 */
|
||||
import { getToken } from "@/utils/auth";
|
||||
import config from "@/config/config";
|
||||
|
||||
/**
|
||||
* 人性化时间显示
|
||||
*
|
||||
* @param {Object} datetime
|
||||
*/
|
||||
export function formatTime(datetime) {
|
||||
if (datetime == null) return "";
|
||||
|
||||
datetime = datetime.replace(/-/g, "/");
|
||||
|
||||
let time = new Date();
|
||||
let outTime = new Date(datetime);
|
||||
if (/^[1-9]\d*$/.test(datetime)) {
|
||||
outTime = new Date(parseInt(datetime) * 1000);
|
||||
}
|
||||
|
||||
if (
|
||||
time.getTime() < outTime.getTime() ||
|
||||
time.getFullYear() != outTime.getFullYear()
|
||||
) {
|
||||
return parseTime(outTime, "{y}-{m}-{d} {h}:{i}");
|
||||
}
|
||||
|
||||
if (time.getMonth() != outTime.getMonth()) {
|
||||
return parseTime(outTime, "{m}-{d} {h}:{i}");
|
||||
}
|
||||
|
||||
if (time.getDate() != outTime.getDate()) {
|
||||
let day = outTime.getDate() - time.getDate();
|
||||
if (day == -1) {
|
||||
return parseTime(outTime, "昨天 {h}:{i}");
|
||||
}
|
||||
|
||||
if (day == -2) {
|
||||
return parseTime(outTime, "前天 {h}:{i}");
|
||||
}
|
||||
|
||||
return parseTime(outTime, "{m}-{d} {h}:{i}");
|
||||
}
|
||||
|
||||
if (time.getHours() != outTime.getHours()) {
|
||||
return parseTime(outTime, "{h}:{i}");
|
||||
}
|
||||
|
||||
let minutes = outTime.getMinutes() - time.getMinutes();
|
||||
if (minutes == 0) {
|
||||
return "刚刚";
|
||||
}
|
||||
|
||||
minutes = Math.abs(minutes);
|
||||
return `${minutes}分钟前`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化文件大小
|
||||
*
|
||||
* @param {String} value 文件大小(字节)
|
||||
*/
|
||||
export function formatSize(value) {
|
||||
if (null == value || value == "") {
|
||||
return "0";
|
||||
}
|
||||
let unitArr = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
|
||||
let index = 0;
|
||||
let srcsize = parseFloat(value);
|
||||
index = Math.floor(Math.log(srcsize) / Math.log(1024));
|
||||
let size = srcsize / Math.pow(1024, index);
|
||||
size = size.toFixed(2); //保留的小数位数
|
||||
return size + unitArr[index];
|
||||
}
|
||||
/**
|
||||
* 获取文件后缀名
|
||||
*
|
||||
* @param {String} fileName
|
||||
*/
|
||||
export function getFileExt(fileName) {
|
||||
let ext = fileName.split(".");
|
||||
ext = ext[ext.length - 1]; // 获取文件后缀名
|
||||
return ext;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据图片url下载图片
|
||||
* @param {String} imgsrc
|
||||
* @param {String} name
|
||||
*/
|
||||
export function downloadIamge(imgsrc, name) {
|
||||
//下载图片地址和图片名
|
||||
let image = new Image();
|
||||
// 解决跨域 Canvas 污染问题
|
||||
image.setAttribute("crossOrigin", "anonymous");
|
||||
image.onload = function () {
|
||||
let canvas = document.createElement("canvas");
|
||||
canvas.width = image.width;
|
||||
canvas.height = image.height;
|
||||
let context = canvas.getContext("2d");
|
||||
context.drawImage(image, 0, 0, image.width, image.height);
|
||||
let url = canvas.toDataURL("image/png"); //得到图片的base64编码数据
|
||||
let a = document.createElement("a"); // 生成一个a元素
|
||||
let event = new MouseEvent("click"); // 创建一个单击事件
|
||||
a.download = name || "photo"; // 设置图片名称
|
||||
a.href = url; // 将生成的URL设置为a.href属性
|
||||
a.dispatchEvent(event); // 触发a的单击事件
|
||||
};
|
||||
image.src = imgsrc;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过图片url获取图片大小
|
||||
*
|
||||
* @param {String} imgsrc 例如图片名: D8x5f13a53dbc4b9_350x345.png
|
||||
*/
|
||||
export function getImageInfo(imgsrc) {
|
||||
let data = {
|
||||
width: 0,
|
||||
height: 0,
|
||||
};
|
||||
|
||||
let arr = imgsrc.split("_");
|
||||
if (arr.length == 1) return data;
|
||||
|
||||
let info = arr[arr.length - 1].match(/\d+x\d+/g);
|
||||
if (info == null) return data;
|
||||
|
||||
info = info[0].split("x");
|
||||
return {
|
||||
width: parseInt(info[0]),
|
||||
height: parseInt(info[1]),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件下载方法
|
||||
*
|
||||
* @param {Number} cr_id
|
||||
*/
|
||||
export function download(cr_id) {
|
||||
let api = config.BASE_API_URL;
|
||||
let token = getToken();
|
||||
try {
|
||||
let link = document.createElement("a");
|
||||
link.href = `${api}/download/user-chat-file?cr_id=${cr_id}&token=${token}`;
|
||||
link.click();
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* 时间格式化方法
|
||||
*
|
||||
* @param {(Object|string|number)} time
|
||||
* @param {String} cFormat
|
||||
* @returns {String | null}
|
||||
*/
|
||||
export function parseTime(time, cFormat) {
|
||||
if (arguments.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let date;
|
||||
const format = cFormat || "{y}-{m}-{d} {h}:{i}:{s}";
|
||||
|
||||
if (typeof time === "object") {
|
||||
date = time;
|
||||
} else {
|
||||
if (typeof time === "string" && /^[0-9]+$/.test(time)) {
|
||||
time = parseInt(time);
|
||||
}
|
||||
if (typeof time === "number" && time.toString().length === 10) {
|
||||
time = time * 1000;
|
||||
console.log("时间判断为number");
|
||||
}
|
||||
|
||||
date = new Date(time.replace(/-/g, "/"));
|
||||
}
|
||||
|
||||
const formatObj = {
|
||||
y: date.getFullYear(),
|
||||
m: date.getMonth() + 1,
|
||||
d: date.getDate(),
|
||||
h: date.getHours(),
|
||||
i: date.getMinutes(),
|
||||
s: date.getSeconds(),
|
||||
a: date.getDay(),
|
||||
};
|
||||
|
||||
const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => {
|
||||
const value = formatObj[key];
|
||||
// Note: getDay() returns 0 on Sunday
|
||||
if (key === "a") {
|
||||
return ["日", "一", "二", "三", "四", "五", "六"][value];
|
||||
}
|
||||
|
||||
return value.toString().padStart(2, "0");
|
||||
});
|
||||
|
||||
return time_str;
|
||||
}
|
||||
|
||||
/**
|
||||
* 去除字符串控制
|
||||
*
|
||||
* @param {String} str
|
||||
*/
|
||||
export function trim(str, type = null) {
|
||||
if (type) {
|
||||
return str.replace(/(^\s*)|(\s*$)/g, "");
|
||||
} else if (type == "l") {
|
||||
return str.replace(/(^\s*)/g, "");
|
||||
} else {
|
||||
return str.replace(/(\s*$)/g, "");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析url中参数
|
||||
*
|
||||
* @param {String} url
|
||||
* @returns {Object}
|
||||
*/
|
||||
export function param2Obj(url) {
|
||||
const search = url.split("?")[1];
|
||||
|
||||
if (!search) return {};
|
||||
|
||||
return JSON.parse(
|
||||
'{"' +
|
||||
decodeURIComponent(search)
|
||||
.replace(/"/g, '\\"')
|
||||
.replace(/&/g, '","')
|
||||
.replace(/=/g, '":"')
|
||||
.replace(/\+/g, " ") +
|
||||
'"}'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} json
|
||||
* @returns {Array}
|
||||
*/
|
||||
export function param(json) {
|
||||
if (!json) return "";
|
||||
return cleanArray(
|
||||
Object.keys(json).map((key) => {
|
||||
if (json[key] === undefined) return "";
|
||||
|
||||
return encodeURIComponent(key) + "=" + encodeURIComponent(json[key]);
|
||||
})
|
||||
).join("&");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Array} actual
|
||||
* @returns {Array}
|
||||
*/
|
||||
export function cleanArray(actual) {
|
||||
const newArray = [];
|
||||
for (let i = 0; i < actual.length; i++) {
|
||||
if (actual[i]) {
|
||||
newArray.push(actual[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return newArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {HTMLElement} element
|
||||
* @param {String} className
|
||||
*/
|
||||
export function toggleClass(element, className) {
|
||||
if (!element || !className) {
|
||||
return;
|
||||
}
|
||||
|
||||
let classString = element.className;
|
||||
let nameIndex = classString.indexOf(className);
|
||||
if (nameIndex === -1) {
|
||||
classString += "" + className;
|
||||
} else {
|
||||
classString =
|
||||
classString.substr(0, nameIndex) +
|
||||
classString.substr(nameIndex + className.length);
|
||||
}
|
||||
element.className = classString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an element has a class
|
||||
*
|
||||
* @param {HTMLElement} elm
|
||||
* @param {String} cls
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
export function hasClass(ele, cls) {
|
||||
return !!ele.className.match(new RegExp("(\\s|^)" + cls + "(\\s|$)"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add class to element
|
||||
*
|
||||
* @param {HTMLElement} elm
|
||||
* @param {String} cls
|
||||
*/
|
||||
export function addClass(ele, cls) {
|
||||
if (!hasClass(ele, cls)) ele.className += " " + cls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove class from element
|
||||
*
|
||||
* @param {HTMLElement} elm
|
||||
* @param {String} cls
|
||||
*/
|
||||
export function removeClass(ele, cls) {
|
||||
if (hasClass(ele, cls)) {
|
||||
const reg = new RegExp("(\\s|^)" + cls + "(\\s|$)");
|
||||
ele.className = ele.className.replace(reg, " ");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过图片Url获取图片等比例缩放的宽度和高度信息
|
||||
*
|
||||
* @param {String} src
|
||||
* @param {Number} width
|
||||
*/
|
||||
export function imgZoom(src, width = 200) {
|
||||
const info = getImageInfo(src);
|
||||
|
||||
if (info.width < width) {
|
||||
return {
|
||||
width: `${info.width}px`,
|
||||
height: `${info.height}px`,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
width: width + "px",
|
||||
height: parseInt(info.height / (info.width / width)) + "px",
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取浏览器光标选中内容
|
||||
*
|
||||
* @export
|
||||
* @returns
|
||||
*/
|
||||
export function getSelection() {
|
||||
return window.getSelection
|
||||
? window.getSelection().toString()
|
||||
: document.selection.createRange().text;
|
||||
}
|
||||
|
||||
/**
|
||||
* 剪贴板复制功能
|
||||
*
|
||||
* @param {String} value 复制内容
|
||||
* @param {Function} callback 复制成功回调方法
|
||||
*/
|
||||
export const copyTextToClipboard = (value, callback) => {
|
||||
let textArea = document.createElement("textarea");
|
||||
textArea.style.background = "transparent";
|
||||
textArea.value = value;
|
||||
|
||||
document.body.appendChild(textArea);
|
||||
|
||||
textArea.select();
|
||||
|
||||
try {
|
||||
document.execCommand("copy");
|
||||
if (callback) callback();
|
||||
} catch (err) {
|
||||
this.$message.error("Oops, unable to copy");
|
||||
}
|
||||
|
||||
document.body.removeChild(textArea);
|
||||
};
|
||||
|
||||
/**
|
||||
* 隐藏用户手机号中间四位
|
||||
*
|
||||
* @param {String} phone 手机号
|
||||
*/
|
||||
export function hidePhone(phone) {
|
||||
return phone.replace(/(\d{3})\d{4}(\d{4})/, "$1****$2");
|
||||
}
|
||||
|
||||
/**
|
||||
* 人性化显示时间
|
||||
*
|
||||
* @param {Object} datetime
|
||||
*/
|
||||
export function beautifyTime(datetime = "") {
|
||||
if (datetime == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
datetime = datetime.replace(/-/g, "/");
|
||||
|
||||
let time = new Date();
|
||||
let outTime = new Date(datetime);
|
||||
if (/^[1-9]\d*$/.test(datetime)) {
|
||||
outTime = new Date(parseInt(datetime) * 1000);
|
||||
}
|
||||
|
||||
if (time.getTime() < outTime.getTime()) {
|
||||
return parseTime(outTime, "{y}/{m}/{d}");
|
||||
}
|
||||
|
||||
if (time.getFullYear() != outTime.getFullYear()) {
|
||||
return parseTime(outTime, "{y}/{m}/{d}");
|
||||
}
|
||||
|
||||
if (time.getMonth() != outTime.getMonth()) {
|
||||
return parseTime(outTime, "{m}/{d}");
|
||||
}
|
||||
|
||||
if (time.getDate() != outTime.getDate()) {
|
||||
let day = outTime.getDate() - time.getDate();
|
||||
if (day == -1) {
|
||||
return parseTime(outTime, "昨天 {h}:{i}");
|
||||
}
|
||||
|
||||
if (day == -2) {
|
||||
return parseTime(outTime, "前天 {h}:{i}");
|
||||
}
|
||||
|
||||
return parseTime(outTime, "{m}-{d}");
|
||||
}
|
||||
|
||||
if (time.getHours() != outTime.getHours()) {
|
||||
return parseTime(outTime, "{h}:{i}");
|
||||
}
|
||||
|
||||
let minutes = outTime.getMinutes() - time.getMinutes();
|
||||
if (minutes == 0) {
|
||||
return "刚刚";
|
||||
}
|
||||
|
||||
minutes = Math.abs(minutes);
|
||||
return `${minutes}分钟前`;
|
||||
}
|
||||
|
||||
export function getSort(fn) {
|
||||
return function (a, b) {
|
||||
let ret = 0;
|
||||
|
||||
if (fn.call(this, a, b)) {
|
||||
ret = -1;
|
||||
} else if (fn.call(this, b, a)) {
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量排序
|
||||
*
|
||||
* @param {*} arr
|
||||
*/
|
||||
export function getMutipSort(arr) {
|
||||
return function (a, b) {
|
||||
let tmp;
|
||||
let i = 0;
|
||||
|
||||
do {
|
||||
tmp = arr[i++](a, b);
|
||||
} while (tmp == 0 && i < arr.length);
|
||||
|
||||
return tmp;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Url 替换超链接
|
||||
*
|
||||
* @param {String} text 文本
|
||||
* @param {String} color 超链接颜色
|
||||
*/
|
||||
export function textReplaceLink(text, color = "#409eff") {
|
||||
let exp =
|
||||
/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gi;
|
||||
return text.replace(
|
||||
exp,
|
||||
`<a href='$1' target="_blank" style="color:${color};text-decoration: revert;">$1</a >`
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 防抖
|
||||
*
|
||||
* @param {*} func
|
||||
* @param {*} wait
|
||||
* @param {*} immediate
|
||||
* @returns
|
||||
*/
|
||||
export function debounce(func, wait, immediate) {
|
||||
let timeout;
|
||||
|
||||
return function () {
|
||||
let context = this;
|
||||
let args = arguments;
|
||||
|
||||
if (timeout) clearTimeout(timeout); // timeout 不为null
|
||||
if (immediate) {
|
||||
let callNow = !timeout; // 第一次会立即执行,以后只有事件执行后才会再次触发
|
||||
timeout = setTimeout(function () {
|
||||
timeout = null;
|
||||
}, wait);
|
||||
if (callNow) func.apply(context, args);
|
||||
} else {
|
||||
timeout = setTimeout(function () {
|
||||
func.apply(context, args);
|
||||
}, wait);
|
||||
}
|
||||
};
|
||||
}
|
||||
120
im/src/utils/request.js
Normal file
120
im/src/utils/request.js
Normal file
@@ -0,0 +1,120 @@
|
||||
import axios from "axios";
|
||||
import config from "@/config/config";
|
||||
import { getToken, removeAll } from "@/utils/auth";
|
||||
|
||||
import { Notification } from "element-ui";
|
||||
import qs from "qs";
|
||||
|
||||
// 创建 axios 实例
|
||||
const request = axios.create({
|
||||
// API 请求的默认前缀
|
||||
baseURL: config.BASE_API_URL,
|
||||
|
||||
// 请求超时时间
|
||||
timeout: 20000,
|
||||
});
|
||||
|
||||
/**
|
||||
* 异常拦截处理器
|
||||
*
|
||||
* @param {*} error
|
||||
*/
|
||||
const errorHandler = (error) => {
|
||||
// 判断是否是响应错误信息
|
||||
if (error.response) {
|
||||
if (error.response.status == 401) {
|
||||
removeAll();
|
||||
location.reload();
|
||||
} else {
|
||||
Notification({
|
||||
message: "网络异常,请稍后再试...",
|
||||
position: "top-right",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.reject(error);
|
||||
};
|
||||
|
||||
// 请求拦截器
|
||||
request.interceptors.request.use((config) => {
|
||||
const token = getToken();
|
||||
if (token) {
|
||||
config.headers["accessToken"] = `${token}`;
|
||||
return config;
|
||||
}
|
||||
}, errorHandler);
|
||||
|
||||
// 响应拦截器
|
||||
request.interceptors.response.use((response) => {
|
||||
return response.data;
|
||||
}, errorHandler);
|
||||
|
||||
/**
|
||||
* GET 请求
|
||||
*
|
||||
* @param {String} url
|
||||
* @param {Object} data
|
||||
* @param {Object} options
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
export const get = (url, data = {}, options = {}) => {
|
||||
return request({
|
||||
url,
|
||||
params: data,
|
||||
method: "get",
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* POST 请求
|
||||
*
|
||||
* @param {String} url
|
||||
* @param {Object} data
|
||||
* @param {Object} options
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
export const post = (url, data = {}, options = {}) => {
|
||||
return request({
|
||||
url,
|
||||
method: "post",
|
||||
data: qs.stringify(data),
|
||||
...options,
|
||||
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* del 请求
|
||||
*
|
||||
* @param {String} url
|
||||
* @param {Object} data
|
||||
* @param {Object} options
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
export const del = (url, data = {}, options = {}) => {
|
||||
return request({
|
||||
url,
|
||||
method: "delete",
|
||||
data: data,
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 上传文件 POST 请求
|
||||
*
|
||||
* @param {String} url
|
||||
* @param {Object} data
|
||||
* @param {Object} options
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
export const upload = (url, data = {}, options = {}) => {
|
||||
return request({
|
||||
url: config.BASE_COMMON + url,
|
||||
method: "post",
|
||||
data: data,
|
||||
...options,
|
||||
});
|
||||
};
|
||||
88
im/src/utils/talk.js
Normal file
88
im/src/utils/talk.js
Normal file
@@ -0,0 +1,88 @@
|
||||
import store from "@/store";
|
||||
import router from "@/router";
|
||||
import { parseTime } from "@/utils/functions";
|
||||
import { ServeCreateTalkList } from "@/api/chat";
|
||||
|
||||
const KEY_INDEX_NAME = "send_message_index_name";
|
||||
|
||||
/**
|
||||
* 通过对话索引查找对话列表下标
|
||||
*
|
||||
* @param {String} index_name
|
||||
*/
|
||||
export function findTalkIndex(index_name) {
|
||||
return store.state.talks.items.findIndex(
|
||||
(item) => item.index_name == index_name
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过对话索引查找对话列表
|
||||
*
|
||||
* @param {String} index_name
|
||||
*/
|
||||
export function findTalk(index_name) {
|
||||
return store.state.talks.items.find((item) => item.index_name == index_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化聊天对话列表数据
|
||||
*
|
||||
* @param {Object} params
|
||||
*/
|
||||
export function formatTalkItem(params) {
|
||||
console.log(params);
|
||||
let options = {
|
||||
id: "",
|
||||
disable: false,
|
||||
face: "",
|
||||
lastTalkTime: "",
|
||||
name: "",
|
||||
top: false,
|
||||
unread: 0, //未读消息
|
||||
is_online: 0, //是否在线
|
||||
draft_text: "", //草稿
|
||||
msg_text: "", //存储的消息
|
||||
userId: "",
|
||||
};
|
||||
|
||||
Object.assign(options, params);
|
||||
options.index_name = `${options.talk_type}_${options.receiver_id}`;
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开指定对话窗口
|
||||
*
|
||||
* @param {Integer} talk_type 对话类型[1:私聊;2:群聊;]
|
||||
* @param {Integer} receiver_id 接收者ID
|
||||
*/
|
||||
export function toTalk(talk_type, receiver_id) {
|
||||
ServeCreateTalkList(receiver_id).then(({ code, data }) => {
|
||||
console.log("ServeCreateTalkList", data);
|
||||
if (code == 200) {
|
||||
sessionStorage.setItem(KEY_INDEX_NAME, `${talk_type}_${receiver_id}`);
|
||||
router.push({
|
||||
path: "/message",
|
||||
query: {
|
||||
v: new Date().getTime(),
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取需要打开的对话索引值
|
||||
*
|
||||
* @returns
|
||||
*/
|
||||
export function getCacheIndexName() {
|
||||
let index_name = sessionStorage.getItem(KEY_INDEX_NAME);
|
||||
if (index_name) {
|
||||
sessionStorage.removeItem(KEY_INDEX_NAME);
|
||||
}
|
||||
|
||||
return index_name;
|
||||
}
|
||||
54
im/src/utils/validate.js
Normal file
54
im/src/utils/validate.js
Normal file
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* 检测是否是字邮箱地址
|
||||
*
|
||||
* @param {String} value
|
||||
*/
|
||||
export const isEmail = value => {
|
||||
return /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((.[a-zA-Z0-9_-]{2,3}){1,2})$/.test(
|
||||
value
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测是否是手机号
|
||||
*
|
||||
* @param {String} value
|
||||
*/
|
||||
export const isMobile = value => {
|
||||
return /^1[0-9]{10}$/.test(value)
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测是否为url
|
||||
*
|
||||
* @param {String} value
|
||||
*/
|
||||
export const isURL = value => {
|
||||
return /^http[s]?:\/\/.*/.test(value)
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测是否为数字类型
|
||||
*
|
||||
* @param {*} value
|
||||
*/
|
||||
export const isNumber = value => {
|
||||
return Object.prototype.toString.call(value).slice(8, -1) === 'Number'
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测是否为 Booleanl 类型
|
||||
*
|
||||
* @param {*} value
|
||||
*/
|
||||
export const isBoolean = value => {
|
||||
return Object.prototype.toString.call(value).slice(8, -1) === 'Boolean'
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测是非是微信浏览器
|
||||
*/
|
||||
export const isWeiXin = () => {
|
||||
let ua = navigator.userAgent.toLowerCase()
|
||||
return ua.match(/microMessenger/i) == 'micromessenger'
|
||||
}
|
||||
Reference in New Issue
Block a user