移动app

This commit is contained in:
2023-09-24 17:55:19 +08:00
parent 736c5376e0
commit 59f7e39791
735 changed files with 80523 additions and 57 deletions

View File

@@ -0,0 +1,76 @@
// #ifdef VUE3
import {
onShow
} from '@dcloudio/uni-app'
import {
onHide
} from '@dcloudio/uni-app'
// #endif
let onAppShowCallback = [],
onAppHideCallback = []
// 监听应用生命周期
const appEvent = {
appShowIndex: 0,
appHideIndex: 0,
onAppShow(callback) {
this.appShowIndex++
if (typeof callback == 'function') {
onAppShowCallback.push(callback)
}
onAppShowCallback.forEach(fun => fun())
},
onAppHide(callback) {
this.appHideIndex++
if (typeof callback == 'function') {
onAppHideCallback.push(callback)
}
onAppHideCallback.forEach(fun => fun())
}
}
setTimeout(() => {
// #ifdef APP
// #ifdef VUE2
getApp().$vm.$on('hook:onShow', function() {
appEvent.onAppShow()
})
getApp().$vm.$on('hook:onHide', function() {
appEvent.onAppHide()
})
// #endif
// #ifdef VUE3
onShow(function() {
appEvent.onAppShow()
}, getApp().$vm.$)
onHide(function() {
appEvent.onAppHide()
}, getApp().$vm.$)
// #endif
// #endif
// #ifdef H5
document.addEventListener("visibilitychange", () => {
if (document.hidden) {
// 页面被挂起
appEvent.onAppHide()
} else {
// 页面呼出
appEvent.onAppShow()
}
})
// #endif
// #ifdef MP
uni.onAppShow(function() {
appEvent.onAppShow()
})
uni.onAppHide(function() {
appEvent.onAppHide()
})
// #endif
}, 0)
export default appEvent

View File

@@ -0,0 +1 @@
export default `😀,😁,😂,🤣,😃,😄,😅,😆,😉,😊,😋,😎,😍,😘,😗,😙,😚,☺️,🙂,🤗,🤩,🤔,🤨,😐,😑,😶,🙄,😏,😣,😥,😮,🤐,😯,😪,😫,😴,😌,😛,😜,😝,🤤,😒,😓,😔,😕,🙃,🤑,😲,☹️,🙁,😖,😞,😟,😤,😢,😭,😦,😧,😨,😩,🤯,😬,😰,😱,😳,🤪,😵,😡,😠,🤬,😷,🤒,🤕,🤢,🤮,🤧,😇,🤠,🤡,🤥,🤫,🤭,🧐,🤓,😈,👿,👹,👺,💀,☠️,👻,👽,🤖,😺,😸,😹,😻,😼,😽,🙀,😿,😾,🙈,🙉,🙊,👶,🧒,👦,👧,🧑,👨,👩,🧓,👴,👵,👨‍⚕️,👩‍⚕️,👨‍🎓,👩‍🎓,👨‍🏫,👩‍🏫,👨‍⚖️,👩‍⚖️,👨‍🌾,👩‍🌾,👨‍🍳,👩‍🍳,👨‍🔧,👩‍🔧,👨‍🏭,👩‍🏭,👨‍💼,👩‍💼,👨‍🔬,👩‍🔬,👨‍💻,👩‍💻,👨‍🎤,👩‍🎤,👨‍🎨,👩‍🎨,👨‍✈️,👩‍✈️,👨‍🚀,👩‍🚀,👨‍🚒,👩‍🚒,👮,👮‍♂️,👮‍♀️,🕵️,🕵️‍♂️,🕵️‍♀️,💂,💂‍♂️,💂‍♀️,👷,👷‍♂️,👷‍♀️,🤴,👸,👳,👳‍♂️,👳‍♀️,👲,🧕,🧔,👱,👱‍♂️,👱‍♀️,🤵,👰,🤰,🤱,👼,🎅,🤶,🧙,🧙‍♀️,🧙‍♂️,🧚,🧚‍♀️,🧚‍♂️,🧛,🧛‍♀️,🧛‍♂️,🧜,🧜‍♀️,🧜‍♂️,🧝,🧝‍♀️,🧝‍♂️,🧞,🧞‍♀️,🧟,🧟‍♀️,🙍,🙍‍♂️,🙍‍♀️,🙎,🙎‍♂️,🙎‍♀️,🙅,🙅‍♂️,🙅‍♀️,🙆,🙆‍♂️,🙆‍♀️,💁,💁‍♂️,💁‍♀️,🙋,🙋‍♂️,🙋‍♀️,🙇,🙇‍♂️,🙇‍♀️,🤦,🤦‍♂️,🤦‍♀️,🤷,🤷‍♂️,🤷‍♀️,💆,💆‍♂️,💆‍♀️,💇,💇‍♂️,💇‍♀️,🚶,🚶‍♂️,🚶‍♀️,🏃,🏃‍♂️,🏃‍♀️,💃,🕺,👯,👯‍♂️,👯‍♀️,🧖,🧖‍♀️,🧖‍♂️,🧗,🧗‍♀️,🧗‍♂️,🧘,🧘‍♀️,🧘‍♂️,🕴️,👤,👥,👫,👬,👭,💏,👨‍❤️‍💋‍👨,👩‍❤️‍💋‍👩,💑,👨‍❤️‍👨,👩‍❤️‍👩,👪,👨‍👩‍👧,👨‍👩‍👧‍👦,👨‍👩‍👦‍👦,👨‍👩‍👧‍👧,👨‍👨‍👦,👨‍👨‍👧,👨‍👨‍👧‍👦,👨‍👨‍👦‍👦,👨‍👨‍👧‍👧,👩‍👩‍👦,👩‍👩‍👧,👩‍👩‍👧‍👦,👩‍👩‍👦‍👦,👩‍👩‍👧‍👧,👨‍👦,👨‍👧,👨‍👧‍👦,👨‍👧‍👧,👩‍👦‍👦,👩‍👧,👩‍👧‍👦,🤳,👃,👅,👄,💋,💘,❤️,💓,💔,💕,💖,💗,💙,💚,💛,🧡,💜,🖤,💝,💞,❣️,💌,💬,🌬️,☃️,⛄,🎎,🗿,👾,💩,🛀,🛌,💅,👂,👣,👀,👁️,🧠,💭,👓,👔,👕,👖,🧣,🧤,🧥,🧦,👗,👘,👙,👚,👛,👜,👝,🎒,👞,👟,👠,👡,👢,👑,👒,🎩,🎓,🧢,📿,💄,💍,💎,🥄,🔪,🏺,🗺️,🗾,🎠,🎡,🎢,💈,🎪,🛰️,🚀,🛸,🛎️,⌛,⏳,⌚,⏰,🕰️,🌡️,🌂,☂️,☔,⛱️,⚡,🎃,🎄,🎆,🎇,🎈,🎉,🎊,🎏,🎐,🎑,🎀,🎁,🎗️,🎟️,🎫,🔮,🎮,🕹️,🎰,🃏,🎴,🎭,🖼️,🎨,🔇,🔈,🔉,🔊,📢,📣,📯,🔔,🔕,🎼,🎵,🎶,🎙️,🎚️,🎛️,🎤,🎧,📻,🎷,🎸,🎹,🎺,🎻,🥁,📱,📲,☎️,📞,📟,📠,🔋,🔌,💻,🖥️,🖨️,⌨️,🖱️,🖲️,💽,💾,💿,📀,🎥,🎞️,📽️,🎬,📺,📷,📸,📹,📼,🔍,🔎,💡,🔦,🏮,📔,📕,📖,📗,📘,📙,📚,📓,📒,📃,📜,📄,📰,📑,🔖,💰,💴,💵,💶,💷,💸,💳,✉️,📧,📨,📩,📤,📥,📦,📫,📪,📬,📭,📮,✏️,✒️,📝,💼,📁,📂,📅,📆,📇,📈,📉,📊,📋,📌,📍,📎,📏,📐,✂️,🔒,🔓,🔏,🔐,🔑,🔨,🔫,🔧,🔩,🔬,🔭,📡,💉,💊,🚪,🚽,🚿,🛁,🛒,🚬,🔅,🔆,⚜️,🔱,📛,🚂,🚃,🚄,🚅,🚆,🚇,🚈,🚉,🚊,🚝,🚞,🚋,🚌,🚍,🚎,🚐,🚑,🚒,🚓,🚔,🚕,🚖,🚗,🚘,🚙,🚚,🚛,🚜,🚲,🛴,🛵,🚏,🛣️,🛤️,🛢️,⛽,🚨,🚥,🚦,🛑,🚧,⛵,🛶,🚤,🛳️,⛴️,🛥️,🚢,✈️,🛩️,🛫,🛬,💺,🚁,🚟,🚠,🚡,⚠️,⛔,🦗,🍇,🍈,🍉,🍊,🍋,🍌,🍍,🍎,🍏,🍐,🍑,🍒,🍓,🥝,🍅,🥥,🥑,🍆,🥔,🥕,🌽,🌶️,🥒,🥦,🥜,🍞,🥐,🥖,🥨,🥞,🧀,🍖,🍗,🥩,🥓,🍔,🍟,🍕,🌭,🥪,🌮,🌯,🥙,🥚,🍳,🥘,🍲,🥣,🥗,🍿,🥫,🍱,🍘,🍙,🍚,🍛,🍜,🍝,🍠,🍢,🍣,🍤,🍥,🍡,🥟,🥠,🥡,🍦,🍧,🍨,🍩,🍪,🎂,🍰,🥧,🍫,🍬,🍭,🍮,🍯,🍼,🥛,☕,🍵,🍶,🍾,🍷,🍸,🍹,🍺,🍻,🥂,🥃,🥤,🥢,🍽️,🍴`.split(',')

View File

@@ -0,0 +1,44 @@
export default function init(callback = ()=>{}){
// #ifdef H5
if (!window.indexedDB) {
return uni.showModal({
content: "Your browser doesn't support a stable version of IndexedDB. Such and such feature will not be available.",
showCancel: false
});
}
let indexedDB = window.indexedDB
let request = indexedDB.open("uni-im", 1)
request.onsuccess = function(event) {
let indexDB = event.target.result // 数据库对象
// console.log('数据库打开成功')
callback(event)
}
request.onerror = function(event) {
console.error("Database error: " + event.target.errorCode);
callback(event)
}
request.onupgradeneeded = function(event) {
// 数据库创建或升级的时候会触发
// console.log('onupgradeneeded')
let indexDB = event.target.result // 数据库对象
if (!indexDB.objectStoreNames.contains("uni-im-msg")) {
let uniImMsgStore = indexDB.createObjectStore("uni-im-msg", {
keyPath: 'unique_id',
// autoIncrement:true
}) // 创建表
uniImMsgStore.createIndex('from_uid', 'from_uid', { unique: false }) // 创建索引 可以让你搜索任意字段
uniImMsgStore.createIndex('to_uid', 'to_uid', { unique: false })
uniImMsgStore.createIndex('unique_id', 'unique_id', { unique: true })
uniImMsgStore.createIndex('conversation_id', 'conversation_id', { unique: false })
uniImMsgStore.createIndex('group_id', 'group_id', { unique: false })
uniImMsgStore.createIndex('body', 'body', { unique: false })
uniImMsgStore.createIndex('is_read', 'is_read', { unique: false })
uniImMsgStore.createIndex('type', 'type', { unique: false })
uniImMsgStore.createIndex('create_time', 'create_time', { unique: false })
uniImMsgStore.createIndex('client_create_time', 'client_create_time', { unique: false })
uniImMsgStore.createIndex('conversation_id-create_time', ['conversation_id','create_time'], { unique: false })
}
}
// #endif
}

View File

@@ -0,0 +1,193 @@
export default function (sMessage) {
function RotateLeft(lValue, iShiftBits) {
return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits));
}
function AddUnsigned(lX, lY) {
var lX4, lY4, lX8, lY8, lResult;
lX8 = (lX & 0x80000000);
lY8 = (lY & 0x80000000);
lX4 = (lX & 0x40000000);
lY4 = (lY & 0x40000000);
lResult = (lX & 0x3FFFFFFF) + (lY & 0x3FFFFFFF);
if (lX4 & lY4) return (lResult ^ 0x80000000 ^ lX8 ^ lY8);
if (lX4 | lY4) {
if (lResult & 0x40000000) return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);
else return (lResult ^ 0x40000000 ^ lX8 ^ lY8);
} else return (lResult ^ lX8 ^ lY8);
}
function F(x, y, z) {
return (x & y) | ((~x) & z);
}
function G(x, y, z) {
return (x & z) | (y & (~z));
}
function H(x, y, z) {
return (x ^ y ^ z);
}
function I(x, y, z) {
return (y ^ (x | (~z)));
}
function FF(a, b, c, d, x, s, ac) {
a = AddUnsigned(a, AddUnsigned(AddUnsigned(F(b, c, d), x), ac));
return AddUnsigned(RotateLeft(a, s), b);
}
function GG(a, b, c, d, x, s, ac) {
a = AddUnsigned(a, AddUnsigned(AddUnsigned(G(b, c, d), x), ac));
return AddUnsigned(RotateLeft(a, s), b);
}
function HH(a, b, c, d, x, s, ac) {
a = AddUnsigned(a, AddUnsigned(AddUnsigned(H(b, c, d), x), ac));
return AddUnsigned(RotateLeft(a, s), b);
}
function II(a, b, c, d, x, s, ac) {
a = AddUnsigned(a, AddUnsigned(AddUnsigned(I(b, c, d), x), ac));
return AddUnsigned(RotateLeft(a, s), b);
}
function ConvertToWordArray(sMessage) {
var lWordCount;
var lMessageLength = sMessage.length;
var lNumberOfWords_temp1 = lMessageLength + 8;
var lNumberOfWords_temp2 = (lNumberOfWords_temp1 - (lNumberOfWords_temp1 % 64)) / 64;
var lNumberOfWords = (lNumberOfWords_temp2 + 1) * 16;
var lWordArray = Array(lNumberOfWords - 1);
var lBytePosition = 0;
var lByteCount = 0;
while (lByteCount < lMessageLength) {
lWordCount = (lByteCount - (lByteCount % 4)) / 4;
lBytePosition = (lByteCount % 4) * 8;
lWordArray[lWordCount] = (lWordArray[lWordCount] | (sMessage.charCodeAt(lByteCount) << lBytePosition));
lByteCount++;
}
lWordCount = (lByteCount - (lByteCount % 4)) / 4;
lBytePosition = (lByteCount % 4) * 8;
lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80 << lBytePosition);
lWordArray[lNumberOfWords - 2] = lMessageLength << 3;
lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29;
return lWordArray;
}
function WordToHex(lValue) {
var WordToHexValue = "",
WordToHexValue_temp = "",
lByte, lCount;
for (lCount = 0; lCount <= 3; lCount++) {
lByte = (lValue >>> (lCount * 8)) & 255;
WordToHexValue_temp = "0" + lByte.toString(16);
WordToHexValue = WordToHexValue + WordToHexValue_temp.substr(WordToHexValue_temp.length - 2, 2);
}
return WordToHexValue;
}
var x = Array();
var k, AA, BB, CC, DD, a, b, c, d
var S11 = 7,
S12 = 12,
S13 = 17,
S14 = 22;
var S21 = 5,
S22 = 9,
S23 = 14,
S24 = 20;
var S31 = 4,
S32 = 11,
S33 = 16,
S34 = 23;
var S41 = 6,
S42 = 10,
S43 = 15,
S44 = 21;
x = ConvertToWordArray(sMessage);
a = 0x67452301;
b = 0xEFCDAB89;
c = 0x98BADCFE;
d = 0x10325476;
for (k = 0; k < x.length; k += 16) {
AA = a;
BB = b;
CC = c;
DD = d;
a = FF(a, b, c, d, x[k + 0], S11, 0xD76AA478);
d = FF(d, a, b, c, x[k + 1], S12, 0xE8C7B756);
c = FF(c, d, a, b, x[k + 2], S13, 0x242070DB);
b = FF(b, c, d, a, x[k + 3], S14, 0xC1BDCEEE);
a = FF(a, b, c, d, x[k + 4], S11, 0xF57C0FAF);
d = FF(d, a, b, c, x[k + 5], S12, 0x4787C62A);
c = FF(c, d, a, b, x[k + 6], S13, 0xA8304613);
b = FF(b, c, d, a, x[k + 7], S14, 0xFD469501);
a = FF(a, b, c, d, x[k + 8], S11, 0x698098D8);
d = FF(d, a, b, c, x[k + 9], S12, 0x8B44F7AF);
c = FF(c, d, a, b, x[k + 10], S13, 0xFFFF5BB1);
b = FF(b, c, d, a, x[k + 11], S14, 0x895CD7BE);
a = FF(a, b, c, d, x[k + 12], S11, 0x6B901122);
d = FF(d, a, b, c, x[k + 13], S12, 0xFD987193);
c = FF(c, d, a, b, x[k + 14], S13, 0xA679438E);
b = FF(b, c, d, a, x[k + 15], S14, 0x49B40821);
a = GG(a, b, c, d, x[k + 1], S21, 0xF61E2562);
d = GG(d, a, b, c, x[k + 6], S22, 0xC040B340);
c = GG(c, d, a, b, x[k + 11], S23, 0x265E5A51);
b = GG(b, c, d, a, x[k + 0], S24, 0xE9B6C7AA);
a = GG(a, b, c, d, x[k + 5], S21, 0xD62F105D);
d = GG(d, a, b, c, x[k + 10], S22, 0x2441453);
c = GG(c, d, a, b, x[k + 15], S23, 0xD8A1E681);
b = GG(b, c, d, a, x[k + 4], S24, 0xE7D3FBC8);
a = GG(a, b, c, d, x[k + 9], S21, 0x21E1CDE6);
d = GG(d, a, b, c, x[k + 14], S22, 0xC33707D6);
c = GG(c, d, a, b, x[k + 3], S23, 0xF4D50D87);
b = GG(b, c, d, a, x[k + 8], S24, 0x455A14ED);
a = GG(a, b, c, d, x[k + 13], S21, 0xA9E3E905);
d = GG(d, a, b, c, x[k + 2], S22, 0xFCEFA3F8);
c = GG(c, d, a, b, x[k + 7], S23, 0x676F02D9);
b = GG(b, c, d, a, x[k + 12], S24, 0x8D2A4C8A);
a = HH(a, b, c, d, x[k + 5], S31, 0xFFFA3942);
d = HH(d, a, b, c, x[k + 8], S32, 0x8771F681);
c = HH(c, d, a, b, x[k + 11], S33, 0x6D9D6122);
b = HH(b, c, d, a, x[k + 14], S34, 0xFDE5380C);
a = HH(a, b, c, d, x[k + 1], S31, 0xA4BEEA44);
d = HH(d, a, b, c, x[k + 4], S32, 0x4BDECFA9);
c = HH(c, d, a, b, x[k + 7], S33, 0xF6BB4B60);
b = HH(b, c, d, a, x[k + 10], S34, 0xBEBFBC70);
a = HH(a, b, c, d, x[k + 13], S31, 0x289B7EC6);
d = HH(d, a, b, c, x[k + 0], S32, 0xEAA127FA);
c = HH(c, d, a, b, x[k + 3], S33, 0xD4EF3085);
b = HH(b, c, d, a, x[k + 6], S34, 0x4881D05);
a = HH(a, b, c, d, x[k + 9], S31, 0xD9D4D039);
d = HH(d, a, b, c, x[k + 12], S32, 0xE6DB99E5);
c = HH(c, d, a, b, x[k + 15], S33, 0x1FA27CF8);
b = HH(b, c, d, a, x[k + 2], S34, 0xC4AC5665);
a = II(a, b, c, d, x[k + 0], S41, 0xF4292244);
d = II(d, a, b, c, x[k + 7], S42, 0x432AFF97);
c = II(c, d, a, b, x[k + 14], S43, 0xAB9423A7);
b = II(b, c, d, a, x[k + 5], S44, 0xFC93A039);
a = II(a, b, c, d, x[k + 12], S41, 0x655B59C3);
d = II(d, a, b, c, x[k + 3], S42, 0x8F0CCC92);
c = II(c, d, a, b, x[k + 10], S43, 0xFFEFF47D);
b = II(b, c, d, a, x[k + 1], S44, 0x85845DD1);
a = II(a, b, c, d, x[k + 8], S41, 0x6FA87E4F);
d = II(d, a, b, c, x[k + 15], S42, 0xFE2CE6E0);
c = II(c, d, a, b, x[k + 6], S43, 0xA3014314);
b = II(b, c, d, a, x[k + 13], S44, 0x4E0811A1);
a = II(a, b, c, d, x[k + 4], S41, 0xF7537E82);
d = II(d, a, b, c, x[k + 11], S42, 0xBD3AF235);
c = II(c, d, a, b, x[k + 2], S43, 0x2AD7D2BB);
b = II(b, c, d, a, x[k + 9], S44, 0xEB86D391);
a = AddUnsigned(a, AA);
b = AddUnsigned(b, BB);
c = AddUnsigned(c, CC);
d = AddUnsigned(d, DD);
}
var temp = WordToHex(a) + WordToHex(b) + WordToHex(c) + WordToHex(d);
return temp.toLowerCase();
}

View File

@@ -0,0 +1,135 @@
let options = {
name: "uni-im",
path: '_doc/uni-im.db'
}
import uniIm from '@/uni_modules/uni-im/lib/main.js';
export default {
async init(callback = ()=>{}){
callback()
},
async checkDataBaseIsOpen(){
if(uniIm.dataBaseIsOpen){
return true
}
let dataBaseIsOpen = plus.sqlite.isOpenDatabase(options)
uniIm.dataBaseIsOpen = dataBaseIsOpen
// console.log('uniIm.dataBaseIsOpen',uniIm.dataBaseIsOpen);
if (!dataBaseIsOpen) {
let res = await new Promise((resolve, reject) => {
plus.sqlite.openDatabase({
...options,
success: function(e) {
// console.log(e, 'openDatabase success!')
resolve(e)
},
fail: function(e) {
console.error(e, 'openDatabase failed: ' + JSON.stringify(e))
reject(e)
}
});
})
let sql = `create table if not exists msg(
"_id" CHAR(32),
"body" TEXT,
"type" CHAR(32),
"from_uid" CHAR(32),
"to_uid" CHAR(32),
"is_read" BOOLEAN,
"friendly_time" DATETIME,
"create_time" DATETIME,
"conversation_id" CHAR(32),
"group_id" CHAR(32),
"client_create_time" DATETIME,
"unique_id" CHAR(32),
"appid" CHAR(32),
"state" INT,
"is_revoke" BOOLEAN,
"is_delete" BOOLEAN,
"action" TEXT
)`
this.executeSql(sql)
return res
}
},
async clearMsgTable(){
let dd = await this.executeSql('drop table msg')
console.log('clearMsgTable',dd);
},
async executeSql(sql) { //执行executeSql
await this.checkDataBaseIsOpen()
// console.log('sql',sql);
return await new Promise((resolve, reject) => {
// console.log('执行executeSql',{
// "name": options.name,
// "sql": sql
// });
try{
plus.sqlite.executeSql({
name: options.name,
sql: sql,
success: function(e) {
// console.log(e, 'executeSql success!')
resolve(e)
},
fail: function(e) {
console.error(e)
console.error({sql})
console.error('executeSql failed: ' + JSON.stringify(e))
console.error('executeSql failed: ' + JSON.stringify(sql))
reject(e)
}
});
}catch(e){
reject(e)
}
})
},
async selectSql(sql) { //执行selectSql
await this.checkDataBaseIsOpen()
return await new Promise( async(resolve, reject) => {
// console.log('执行selectSql',{
// "name": options.name,
// "sql": sql
// });
try{
plus.sqlite.selectSql({
name: options.name,
sql: sql,
success: function(e) {
// console.log(e, 'selectSql success!')
resolve(e)
},
fail: function(e) {
console.error('sql:'+sql,'selectSql failed: ' + JSON.stringify(e))
reject(e)
}
});
}catch(e){
reject(e)
}
})
}
}
// await this.clearMsgTable()
// try{
// await new Promise((resolve, reject) => {
// plus.sqlite.closeDatabase({
// ...options,
// success: function(e) {
// console.log(e, 'closeDatabase success!')
// resolve(e)
// },
// fail: function(e) {
// console.error(e, 'closeDatabase failed: ' + JSON.stringify(e))
// reject(e)
// }
// })
// })
// }catch(e){
// console.error(e)
// //TODO handle the exception
// }

View File

@@ -0,0 +1,70 @@
export default function toFriendlyTime(timestamp) {
const now = new Date();
const date = new Date(timestamp);
const secondsAgo = Math.floor((now - date) / 1000);
// 判断是否在今天
if (date.getDate() === now.getDate() && date.getMonth() === now.getMonth() && date.getFullYear() === now.getFullYear()) {
// 小于1分钟显示刚刚
if (secondsAgo < 60) {
return '刚刚';
}
// 大于1分钟小于60分钟显示具体几分钟前
if (secondsAgo < 60 * 60) {
const minutes = Math.floor(secondsAgo / 60);
return `${minutes}分钟前`;
}
// 大于60分钟小于2小时显示具体几小时+分钟前
if (secondsAgo < 60 * 60 * 2) {
const hours = Math.floor(secondsAgo / (60 * 60));
const minutes = Math.floor((secondsAgo - hours * 60 * 60) / 60);
return `${hours}小时 ${minutes}分钟前`;
}
// 超过2小时显示具体的几点几分
const ampm = date.getHours() >= 12 ? '下午' : '上午';
const hour = date.getHours() % 12 || 12;
const minute = date.getMinutes().toString().padStart(2, '0');
return `${ampm} ${hour}:${minute}`;
}
// 不在今天,判断是否在两天内
const oneDayMs = 24 * 60 * 60 * 1000;
if (now - date < oneDayMs * 2) {
if (date.getDate() === now.getDate() - 1 && date.getMonth() === now.getMonth() && date.getFullYear() === now.getFullYear()) {
// 昨天
const ampm = date.getHours() >= 12 ? '下午' : '上午';
const hour = date.getHours() % 12 || 12;
const minute = date.getMinutes().toString().padStart(2, '0');
return `昨天 ${ampm} ${hour}:${minute}`;
} else {
// 前天
const ampm = date.getHours() >= 12 ? '下午' : '上午';
const hour = date.getHours() % 12 || 12;
const minute = date.getMinutes().toString().padStart(2, '0');
return `前天 ${ampm} ${hour}:${minute}`;
}
}
// 不在两天内,判断是否在同一周
const oneWeekMs = oneDayMs * 7;
const diffMs = now - date;
if (diffMs < oneWeekMs) {
const days = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
const ampm = date.getHours() >= 12 ? '下午' : '上午';
const hour = date.getHours() % 12 || 12;
const minute = date.getMinutes().toString().padStart(2, '0');
return `${days[date.getDay()]} ${ampm} ${hour}:${minute}`;
}
// 不在同一周,显示具体年月日+时间
const year = date.getFullYear();
const month = (date.getMonth() + 1).toString().padStart(2, '0');
const day = date.getDate().toString().padStart(2, '0');
const ampm = date.getHours() >= 12 ? '下午' : '上午';
const hour = date.getHours() % 12 || 12;
const minute = date.getMinutes().toString().padStart(2, '0');
return `${year}-${month}-${day} ${ampm} ${hour}:${minute}`;
}

View File

@@ -0,0 +1,699 @@
// #ifdef VUE2
import Vue from 'vue'
// #endif
import md5 from '@/uni_modules/uni-im/common/md5'
import toFriendlyTime from '@/uni_modules/uni-im/common/toFriendlyTime.js';
import appEvent from '@/uni_modules/uni-im/common/appEvent.js';
import {
store as uniIdStore,
mutations as uniIdMutations
} from '@/uni_modules/uni-id-pages/common/store.js';
import uniIm from '@/uni_modules/uni-im/lib/main.js';
// #ifdef H5
import initIndexDB from '@/uni_modules/uni-im/common/initIndexDB.js';
initIndexDB(event => {
// console.log('event.target.result',event.target.result);
uniIm.indexDB = event.target.result
})
// #endif
// #ifdef APP
import sqlite from '@/uni_modules/uni-im/common/sqlite.js';
sqlite.init()
// #endif
const uniIdCo = uniCloud.importObject("uni-id-co", {
customUI: true
})
const db = uniCloud.database();
let appIsShow = true;
let getCloudMsgIng = false
let socketIsClose = true
export default {
init() {
// #ifdef APP
getApp().globalData.sqlite = sqlite
// #endif
uniIm.socketOpenIndex = 0
uni.onSocketClose(function(res) {
socketIsClose = true
console.log('WebSocket 已关闭!');
});
uni.onSocketOpen(function(res) {
console.log('WebSocket连接已打开');
socketIsClose = false
// 记录socket连接次数
uniIm.socketOpenIndex++
if (uniIm.socketOpenIndex > 1) {
// 获取socket断开后丢失的数据
getCloudMsg()
}
});
appEvent.onAppShow(async () => {
// 获取socket断开后丢失的数据
getCloudMsg()
})
// 获得云端数据适用于socket突然断开丢失或者应用iOS切到后台拿不到透传等场景使用 获取丢失的数据
function getCloudMsg(){
if(getCloudMsgIng){
return // 防止重复发起比如即被切换到后台socket又断开的场景
}
getCloudMsgIng = true
// 下一个事件循环执行
setTimeout(async () => {
// 根据本地会话的最大更新时间,查询云端数据
let maxConversation = (await uniIm.conversation.get())[0]
// console.log({maxConversation});
if (!maxConversation) {
getCloudMsgIng = false
return
}
let res = await db.collection('uni-im-msg')
.where({
to_uid: uniCloud.getCurrentUserInfo().uid,
create_time: db.command.gt(maxConversation.update_time)
})
.get()
console.log('getCloudMsg res',maxConversation.update_time,res.result.data);
let clodMsgData = {}
res.result.data.forEach(item => {
if (clodMsgData[item.conversation_id]) {
clodMsgData[item.conversation_id].push(item)
} else {
clodMsgData[item.conversation_id] = [item]
}
})
for (let conversation_id in clodMsgData) {
let conversation = await uniIm.conversation.get(conversation_id)
let msg = clodMsgData[conversation_id]
if (msg.length) {
conversation.msgList.push(...msg)
conversation.msgManager.localMsg.add(msg)
conversation.unread_count += msg.length
}
}
getCloudMsgIng = false
// console.log('获取切到后台后socket离线丢失的数据 res',data);
},0);
}
//监听im消息
this.listenImMsg()
//时间戳心跳(定时器)用于刷新:消息或会话与当前的时间差
setInterval(() => {
uniIm.heartbeat = Date.now()
}, 1000)
// 监听窗口变化
// #ifdef H5
window.addEventListener('resize', () => {
setIsWidescreen()
})
function setIsWidescreen() {
let oldState = uniIm.isWidescreen
uniIm.isWidescreen = window.innerWidth > 960
if (oldState == false && uniIm.isWidescreen == true) {
// if (!window.location.href.includes('/uni_modules/uni-im/pages/index/index')) {
// console.log('uni-im检测到窗口由小屏切为大屏。')
// uni.showModal({
// content: '检测到你的窗口已改成pc模式是否切换显示模式',
// cancelText: "不用了",
// confirmText: "立即切换",
// complete(e) {
// if (e.confirm) {
// uni.switchTab({
// url: "/uni_modules/uni-im/pages/index/index",
// success() {
// window.location.reload()
// }
// })
// }
// }
// });
// }
}
}
setIsWidescreen()
// #endif
const audioContext = uni.createInnerAudioContext()
let _audioContext = {}
Object.defineProperty(_audioContext,'src',{
set(url) {
audioContext.src = url
},
get() {
return audioContext.src
}
})
uniIm.audioContext = new Proxy(_audioContext,{
get(target,propKey,receiver){
return audioContext[propKey]
}
})
uniIm.systemInfo = uni.getSystemInfoSync()
// 初始化uniIm依赖的全局变量
function initData() {
uniIm.conversation.dataList = []
// let storageConversation = uni.getStorageSync('uni-im-conversation' + '_uid:' + uniCloud.getCurrentUserInfo().uid)
// if(storageConversation && storageConversation.dataList.length){
// uniIm.conversation.add(storageConversation.dataList)
// }
uniIm.notification.dataList = []
uniIm.notification.loadMore()
uniIm.friend.dataList = []
uniIm.friend.loadMore()
uniIm.group.dataList = []
uniIm.group.loadMore()
let userInfo = {}
userInfo[uniIdStore.userInfo._id] = uniIdStore.userInfo
uniIm.mergeUsersInfo(userInfo)
}
// 如果已经登录就直接初始化数据
if (uniCloud.getCurrentUserInfo().tokenExpired > Date.now()) {
setTimeout(initData, 0)
}
// 登录成功后 初始化数据
uni.$on('uni-id-pages-login-success', async () => {
initData()
})
uni.onPushMessage(async res => {
if (res.data.payload.type == 'uni-im-notification') {
console.log('uni-im-notification-res.data', res.data);
res.data.create_time = Date.now()
if (typeof res.data.is_read == 'undefined') {
res.data.is_read = false
}
console.log('res.data notification.add', res.data)
res.data._id = res.data.payload.notificationId
const notificationData = res.data
delete res.data.payload.notificationId
delete res.data.unipush_version
uniIm.notification.add(res.data)
}
});
// 通过拦截器监听路由变化解决在非tabbar页面无法设置TabBarBadge的问题
['navigateTo', 'redirectTo', 'reLaunch', 'switchTab', 'navigateBack'].forEach((item) => {
uni.addInterceptor(item, {
success: event => {
// 更新底部选项卡角标值
updateTabBarBadge()
}
})
})
// #ifdef MP-WEIXIN
// 微信的隐式API 监听路由变化
wx.onAppRoute((res) => {
// console.log('跳转', res)
// 更新底部选项卡角标值
updateTabBarBadge()
})
// #endif
// 更新底部选项卡角标值
function updateTabBarBadge(){
setTimeout(() => {
// console.log('updateTabBarBadge');
/**
* 默认每次路由发生变化都会更新updateTabBarBadge的值
* 你可以根据自己的项目情况优化比如首页就是tabbar的可以判断getCurrentPages().length 的长度决定是否继续
*/
let unread_count = uniIm.notification.unreadCount()
// console.log({unread_count});
set(2,unread_count)
// 获取未读会话消息总数
unread_count = uniIm.conversation.unreadCount()
// console.log({unread_count});
set(0,unread_count)
// 设置底部选项卡角标值
function set(index,number){
if (number == 0) {
uni.removeTabBarBadge({
index,
complete: (e) => {
// console.log(e)
}
})
} else {
uni.setTabBarBadge({
index,
text: number + '',
complete: (e) => {
// console.log(e)
}
})
}
}
}, 300);
}
uni.$on('uni-id-pages-logout', () => {
uniIm.conversation.dataList = []
uniIm.conversation.hasMore = true
uniIm.notification.dataList = []
uniIm.notification.hasMore = true
uniIm.friend.dataList = []
uniIm.friend.hasMore = true
uniIm.group.dataList = []
uniIm.group.hasMore = true
uniIm.currentConversationId = false
})
// #ifdef H5
uni.addInterceptor('switchTab', {
invoke: (e) => {
if (e.url.includes('/uni_modules/uni-im/pages/index/index')) {
if (uniIm.matches) {
let param = getUrlParam(e.url)
// console.log('param----',param);
uni.$emit('uni-im-toChat', param)
}
}
}
})
function getUrlParam(url) {
let u = url.split("?");
if (typeof(u[1]) == "string") {
u = u[1].split("&");
let get = {};
for (let i in u) {
let j = u[i].split("=");
get[j[0]] = j[1];
}
return get;
} else {
return {};
}
};
// #endif
appEvent.onAppHide(async () => {
appIsShow = false
})
appEvent.onAppShow(async () => {
appIsShow = true
// #ifdef APP
//清理系统通知栏消息和app角标
this.clearPushNotify()
// #endif
})
},
getConversationId(id, type = 'single') { //single,group
if (type == 'single') {
let current_uid = uniCloud.getCurrentUserInfo().uid
if (!current_uid) {
console.error('错误current_uid不能为空', current_uid);
}
let param = [id, current_uid]
return 'single_' + md5(param.sort().toString())
} else {
return 'group_' + id
}
},
listenImMsg() {
uni.onPushMessage(async res => {
console.log('收到消息', res);
// console.log('收到消息 onPushMessage===================',res.type, res.data,uniIm.currentConversationId );
const {
payload
} = res.data
if (payload.type == "uni-im") {
const msg = payload.data
// console.log({msg});
// 超长文本传输时的id
if (msg.LongMsg) {
const db = uniCloud.database();
let res = await db.collection('uni-im-msg')
.where({
"_id": msg._id,
"conversation_id": msg.conversation_id // conversation_id 必传否则会被触发器拦截
})
.get()
// console.log(res);
if (res.result.code == 0) {
payload.data.body = res.result.data[0].body
} else {
console.error('超长文本类型消息查库失败', msg._id);
}
}
// console.log('payload------', payload.device_id, uni.getSystemInfoSync().deviceId);
if (payload.device_id == uni.getSystemInfoSync().deviceId) {
return console.log('当前设备发的消息,不用接收;忽略');
}
if (res.type == 'receive') {
// console.log(777);
const {
conversation_id,
group_id
} = msg
// console.log('msgmsgmsgmsgmsg.msg',msg);
// #ifdef APP
let currentPages = getCurrentPages()
let topViewRoute = currentPages[currentPages.length - 1].route
// console.log('topViewRoute',topViewRoute);
let pathList = [
'uni_modules/uni-im/pages/chat/chat',
'uni_modules/uni-im/pages/index/index',
'uni_modules/uni-im/pages/userList/userList',
'uni_modules/uni-im/pages/contacts/contacts'
]
if (!appIsShow || !pathList.includes(topViewRoute)) {
// console.log('payload',payload);
let {
content,
data,
title,
avatar_file
} = payload
let url = avatar_file ? avatar_file.url : ''
let icon = '_www/uni_modules/uni-im/static/avatarUrl.png'
//安卓才有头像功能,再执行下载
if (uni.getSystemInfoSync().platform == "android") {
if (avatar_file) {
let downloadFileRes = await uni.downloadFile({
url: avatar_file.url
});
icon = downloadFileRes[1]?.tempFilePath
}
}
plus.push.createMessage(content, payload, {
title,
icon
})
} else if (conversation_id != uniIm.currentConversationId) {
// uni.showToast({
// title: '收到新消息请注意查看',
// icon: 'none'
// });
}
// #endif
let conversation = await uniIm.conversation.get(conversation_id)
let msgList = conversation.msgList
/**
* 排除会话中已包含此消息的情况
*/
let lastMsg = [...msgList].pop()
if(lastMsg && lastMsg._id != msg._id){
msgList.push(msg)
conversation.unread_count++
}
// 如果socket已经关闭的情况下收到消息说明消息来源浏览器页签之间通讯 不需要重复存库
if(!socketIsClose){
conversation.msgManager.localMsg.add(msg)
}
// console.log(29292929,msg)
//限制群聊才有回复提示
if (msg.group_id && msg.about_msg_id) {
let current_uid = uniCloud.getCurrentUserInfo().uid
let aboutMsg = msgList.find(i => i._id == msg.about_msg_id)
if(aboutMsg && aboutMsg.from_uid == current_uid){
conversation.call_list.push(msg._id)
console.log('conversation.call_list', conversation.call_list);
}
}
// console.log({
// conversation_id,
// action:'push',
// data:msg
// });
if (msg.action == "join-group-notice") {
console.log('"join-group-notice"', msg);
let conversation = await uniIm.conversation.get(msg.conversation_id)
console.log('"join-group-notice"conversation', conversation);
if (conversation) {
let userList = msg.body.user_list
if (userList && Object.keys(conversation.group_member)) {
for (let i = 0; i < userList.length; i++) {
// #ifdef VUE3
conversation.group_member[userList[i]._id] = userList[i]
// #endif
// #ifdef VUE2
Vue.set(conversation.group_member, userList[i]._id, userList[i])
// #endif
}
console.log('add user to group_member', conversation.group_member)
}
// 记录用户数据到内存
// console.log('conversation.group_member',conversation.group_member);
uniIm.mergeUsersInfo(conversation.group_member)
// 如果我的群列表没有这个群,则加上
let hasIsGroup = uniIm.group.dataList.find(i => i.group_info._id == group_id)
if (!hasIsGroup) {
await uniIm.group.loadMore({
group_id
})
}
}
}
} else {
let currentPages = getCurrentPages()
let topViewRoute = currentPages[currentPages.length - 1].route
// console.log('topViewRoute',topViewRoute);
if (topViewRoute == 'uni_modules/uni-im/pages/chat/chat') {
uni.redirectTo({
url: '/uni_modules/uni-im/pages/chat/chat?conversation_id=' + msg.conversation_id,
complete(e) {
console.log(e);
}
})
} else {
uni.navigateTo({
url: '/uni_modules/uni-im/pages/chat/chat?conversation_id=' + msg.conversation_id,
complete(e) {
console.log(e);
}
})
}
}
} else if (payload.type == "uni-im-group-exit" || payload.type == "uni-im-group-expel" ||
payload.subType == 'uni-im-group-expel') {
// 用户退群
// 群聊天记录加上 xxx 退群
let {
timestamp,
group_id
} = payload.data
let conversation_id = 'group_' + group_id
let noticeBody = res.data.content
let conversation = await uniIm.conversation.get(conversation_id)
let msg = {
conversation_id,
group_id,
client_create_time: Date.now(),
create_time: Date.now(),
type: 'system',
body: noticeBody
}
conversation.msgList.push(msg)
// 如果socket已经关闭的情况下收到消息说明消息来源浏览器页签之间通讯 不需要重复存库
if(!socketIsClose){
conversation.msgManager.localMsg.add(msg)
}
// 如果是当前用户退群,就将群会话从列表移除
if (payload.data.user_id == uniCloud.getCurrentUserInfo().uid) {
let currentConversationId = uniIm.currentConversationId
//如果已经打开此群聊,或在此群聊的设置页面
let topPageInfo = getTopPageInfo()
// #ifdef VUE2
let {
route,
options
} = topPageInfo
// #endif
// #ifdef VUE3
let {
route,
options
} = topPageInfo.$page
// #endif
if (route == "uni_modules/uni-im/pages/group/info") {
currentConversationId = options.conversation_id
}
if (currentConversationId == ('group_' + payload.data.group_id)) {
uni.navigateBack({
delta: 2
})
}
setTimeout(() => {
uniIm.conversation.remove(conversation_id)
uniIm.group.remove({
group_id: payload.data.group_id
})
}, 1000);
} else {
let data = await uniIm.conversation.get(conversation_id)
// console.error(11111,data)
// #ifdef VUE3
delete data.group_member[payload.data.user_id]
// #endif
// #ifdef VUE2
Vue.delete(data.group_member, payload.data.user_id)
// #endif
}
} else if (payload.type == "uni-im-group-join-request") {
console.log('有用户申请加入群聊');
// uni.showToast({
// title: '有用户申请加入群聊',
// icon: 'none'
// });
} else if (payload.type == "uni-im-notification" && payload.subType ==
'uni-im-group-cancellation') {
// 群解散
let {
group_id
} = payload.data
let conversationId = 'group_' + group_id
//如果已经打开此群聊,或在此群聊的设置页面
let currentConversationId = uniIm.currentConversationId
//如果已经打开此群聊,或在此群聊的设置页面
let topPageInfo = getTopPageInfo()
// #ifdef VUE2
let {
route,
options
} = topPageInfo
// #endif
// #ifdef VUE3
let {
route,
options
} = topPageInfo.$page
// #endif
if (route == "uni_modules/uni-im/pages/group/info") {
currentConversationId = options.conversation_id
}
if (currentConversationId == conversationId) {
uni.navigateBack({
delta: 2
})
}
setTimeout(() => {
uniIm.conversation.remove(conversationId)
uniIm.group.remove({
group_id
})
}, 1000);
} else if (payload.type == "uni-im-notification" && payload.subType == "uni-im-friend-add") {
// console.log('加好友的申请通过');
let {
from_uid,
to_uid
} = payload.data;
let friend_uid = from_uid == uniCloud.getCurrentUserInfo().uid ? to_uid : from_uid
await uniIm.conversation.get({
friend_uid
})
uniIm.friend.loadMore({
friend_uid
})
} else if (payload.type == "uni-im-notification" && payload.subType == "uni-im-friend-delete") {
let {
from_uid,
to_uid
} = payload.data;
let friend_uid = from_uid == uniCloud.getCurrentUserInfo().uid ? to_uid : from_uid
uniIm.conversation.remove(payload.data.conversationId)
uniIm.friend.remove(friend_uid)
} else if (payload.type == "uni-im-revoke-msg") {
let conversation = await uniIm.conversation.revokeMsg(payload.data)
uni.setStorageSync('uni-im-lastTaskTime', payload.data.taskCreateTime)
}
})
},
toFriendlyTime(timestamp) {
// 加上一个*0的数,用于刷新视图中的时间 并无运算意义
if (timestamp - Date.now() < 3600 * 1000 * 2) {
timestamp += uniIm.heartbeat * 0
}
if (!timestamp) {
return '';
}
// return timestamp
return toFriendlyTime(timestamp)
},
// #ifdef APP
clearPushNotify() {
plus.push.clear()
plus.runtime.setBadgeNumber(0)
},
// #endif
async login({
token,
tokenExpired
}) {
uni.setStorage({
key: "uni_id_token_expired",
data: tokenExpired
})
uni.setStorage({
key: "uni_id_token",
data: token
})
uni.getPushClientId({
success: async function(e) {
// console.log(e)
let pushClientId = e.cid
// console.log(pushClientId);
let res = await uniIdCo.setPushCid({
pushClientId
})
// console.log('getPushClientId', res);
},
fail(e) {
console.log(e)
}
})
await uniIdMutations.updateUserInfo()
uni.$emit('uni-id-pages-login-success')
}
}
function getTopPageInfo() {
let pages = getCurrentPages();
return pages[pages.length - 1];
}