Compare commits
111 Commits
1.0.11
...
d9f379d489
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d9f379d489 | ||
|
|
92d43c50bc | ||
| 013c030963 | |||
| 7b204e4a50 | |||
| 3a28e34c3d | |||
| ab3d5933a8 | |||
| 2a1590172e | |||
| 9bba6e4ef4 | |||
| 9d9c0cdaf8 | |||
| e0185e589d | |||
| 90584f1101 | |||
|
|
31846e54a7 | ||
|
|
75d73e9c87 | ||
|
|
81543cdcdc | ||
|
|
3ea3a2decd | ||
| eae895f181 | |||
| 3cd11c5863 | |||
| f5da4e7a2c | |||
|
|
da6b60131d | ||
|
|
ae0fa1bde3 | ||
|
|
8b888e250f | ||
| 4888cf2ad1 | |||
| 0eb6be37be | |||
| 831776f7dd | |||
| 519caab9e5 | |||
| aead0f5ed1 | |||
| fb6f5697c7 | |||
| 4760adc504 | |||
| b8291a4222 | |||
|
|
33eacb2a5b | ||
|
|
5c5445d630 | ||
| 056224881e | |||
|
|
f77a91eafe | ||
|
|
54cf21f211 | ||
|
|
da78a3ac11 | ||
| 7c4874a5e1 | |||
| 6f508d906d | |||
| 08ffc0fa53 | |||
| e72d6b3a91 | |||
| 8b7a259c00 | |||
| 4a31ba32f7 | |||
| 32e3e0ef30 | |||
| a7dccde63a | |||
| 9c7a8c8ee1 | |||
| 18173995ab | |||
| 07f707f94a | |||
| d1f5f75355 | |||
| 2d97294c9d | |||
| 78d4611fb2 | |||
| 358372cdba | |||
| ef785ab05f | |||
| 8f3c741ad1 | |||
| f4e44de777 | |||
| 853c4611ef | |||
| 1d648f2dc1 | |||
| d9748d0827 | |||
| 103679c372 | |||
|
|
8c32758e37 | ||
|
|
29757fadeb | ||
| 8a8e55600f | |||
| 768edb8e87 | |||
| 2ce4bb827f | |||
| f68e5fa1fd | |||
| 8bb646a520 | |||
| 20317cc1df | |||
| a5bd5a898c | |||
|
|
00836ac209 | ||
| c840e9ee6b | |||
| 18f0ee457c | |||
| a12d8a2c40 | |||
| 1407d677de | |||
| 8b10fd95fe | |||
| 3b3dda18ca | |||
| c7ba7bd426 | |||
| db9f5f6bde | |||
| 2a61a263de | |||
| 31c60bb319 | |||
| 36f70e1b5e | |||
| 6e2414f160 | |||
| 17e443fdeb | |||
|
|
e21d0e928d | ||
| 5a52bdf2dd | |||
| 01627f6794 | |||
|
|
054a84dae7 | ||
|
|
cdcfc95f88 | ||
|
|
91144195cf | ||
|
|
d92fb30648 | ||
|
|
d1c1c6d5ba | ||
| ab35229331 | |||
|
|
b92fc0fc7e | ||
| 66092967cb | |||
| d812ac2862 | |||
| a396f75041 | |||
| f03c3a0989 | |||
| 914f3f9371 | |||
| 7220c3466d | |||
|
|
ca9f7e80ca | ||
|
|
ee3087b320 | ||
| d8b90f97d1 | |||
| fbe1add9cf | |||
| 883f32f54c | |||
| 1be73f5bbb | |||
|
|
ad40d0d4d1 | ||
|
|
936a66a8aa | ||
| da59b2c31d | |||
| 77ed9dd6f9 | |||
|
|
e99ef72050 | ||
|
|
57cba65206 | ||
| 31ff366457 | |||
| f4b06bbf01 | |||
| ce954c5dcc |
8
App.vue
8
App.vue
@@ -5,14 +5,14 @@
|
||||
import im from '@/utils/im/index.js'
|
||||
|
||||
export default {
|
||||
onLaunch: function() {
|
||||
onLaunch: function() {
|
||||
im.initIm('lmxuhwaglu76d')
|
||||
return
|
||||
// return
|
||||
//#ifdef APP-PLUS
|
||||
// 获取系统版本号
|
||||
getVersions({
|
||||
platform: plus.os.name,
|
||||
version: plus.runtime.versionCode
|
||||
version: plus.runtime.version
|
||||
}).then(res => {
|
||||
if (res.update) {
|
||||
uni.showModal({
|
||||
@@ -29,7 +29,7 @@
|
||||
uni.downloadFile({
|
||||
url: res.info.download,
|
||||
success: apkPick => {
|
||||
plus.runtime.install(apkPick
|
||||
plus.runtime.install(apkPick
|
||||
.tempFilePath, '',
|
||||
installRES => {
|
||||
// 安装完成用于提示新版本引导,暂时无用
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# ZhHealth
|
||||
|
||||
ZH健康
|
||||
ZH健康
|
||||
|
||||
## uni-icons图标组件
|
||||
[图标组件](https://hellouniapp.dcloud.net.cn/pages/extUI/icons/icons)
|
||||
@@ -88,9 +88,9 @@ const searchFriend = (value) => {
|
||||
const pedingFriend = (recipient, message) => {
|
||||
return request({
|
||||
method: 'POST',
|
||||
url: 'im/friends/' + recipient,
|
||||
data: {
|
||||
message
|
||||
url: 'im/friends/' + recipient,
|
||||
data: {
|
||||
message
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -120,19 +120,19 @@ const getGroupBase = (groupId) => {
|
||||
})
|
||||
}
|
||||
|
||||
const getGroupUsers = (groupId, limit) => {
|
||||
const getGroupUsers = (groupId, limit) => {
|
||||
limit = limit || 0
|
||||
return request({
|
||||
url: 'im/groups/' + groupId + '/users?limit=' + limit
|
||||
})
|
||||
}
|
||||
|
||||
// 公告列表
|
||||
const getGroupAnnouncements = (groupId) => {
|
||||
return request({
|
||||
url: 'im/groups/' + groupId + '/announcements'
|
||||
})
|
||||
}
|
||||
|
||||
// 创建公告
|
||||
const createGroupAnnouncement = (groupId, content) => {
|
||||
return request({
|
||||
method: 'POST',
|
||||
@@ -142,13 +142,27 @@ const createGroupAnnouncement = (groupId, content) => {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 查看该公告详情
|
||||
const getGroupAnnouncement = (groupId, announcementId) => {
|
||||
return request({
|
||||
method: 'GET',
|
||||
url: 'im/groups/' + groupId + '/announcements/' + announcementId
|
||||
})
|
||||
}
|
||||
// 删除该公告
|
||||
const deleteGroupAnnouncement = (groupId, announcementId) => {
|
||||
return request({
|
||||
method: 'DELETE',
|
||||
url: 'im/groups/' + groupId + '/announcements/' + announcementId
|
||||
})
|
||||
}
|
||||
// 置顶群公告
|
||||
const topGroupAnnouncement = (groupId, announcementId) => {
|
||||
return request({
|
||||
method: 'POST',
|
||||
url: 'im/groups/' + groupId + '/announcements/' + announcementId + '/top',
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建群聊
|
||||
@@ -227,12 +241,13 @@ const removeGroupUser = (groupId, userId) => {
|
||||
/**
|
||||
* 邀请群成员
|
||||
*/
|
||||
const inviteGroupUser = (groupId, userIds) => {
|
||||
const inviteGroupUser = (groupId, userIds, allowIds) => {
|
||||
return request({
|
||||
method: 'POST',
|
||||
url: 'im/groups/' + groupId + '/invite',
|
||||
data: {
|
||||
userIds
|
||||
userIds: userIds,
|
||||
allowIds: allowIds
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -267,19 +282,16 @@ const transferGroupOwner = (groupId, userId) => {
|
||||
})
|
||||
}
|
||||
|
||||
// //群成员待审核表 -- 废弃
|
||||
// const getGroupMakeSure = (groupId) => {
|
||||
// return request({
|
||||
// url:`im/groups/${groupId}/makesure`
|
||||
// })
|
||||
// }
|
||||
// // 群成员审核通过
|
||||
// const getGroupMakeSureAllow = (groupId, userId) => {
|
||||
// return request({
|
||||
// method: 'POST',
|
||||
// url: 'im/groups/' + groupId + '/owner/' + userId
|
||||
// })
|
||||
// }
|
||||
|
||||
// 通过审核验证群成员
|
||||
const groupMakeSure = (groupId, user) => {
|
||||
return request({
|
||||
url: `im/groups/${groupId}/makesure/${user}`,
|
||||
method: 'POST'
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
export {
|
||||
getImToken,
|
||||
@@ -300,17 +312,19 @@ export {
|
||||
getGroupBase,
|
||||
getGroupUsers,
|
||||
getGroupAnnouncements,
|
||||
getGroupAnnouncement,
|
||||
createGroupAnnouncement,
|
||||
deleteGroupAnnouncement,
|
||||
topGroupAnnouncement,
|
||||
searchGroup,
|
||||
joinGroupPre,
|
||||
joinGroup,
|
||||
quitGroup,
|
||||
dismissGroup,
|
||||
dismissGroup,
|
||||
inviteGroupUser,
|
||||
removeGroupUser,
|
||||
removeGroupUser,
|
||||
transferGroupOwner,
|
||||
setGroupAdmin,
|
||||
removeGroupAdmin,
|
||||
// transferGroupOwner, // -废弃待审核列表
|
||||
// getGroupMakeSure // -废弃待审核列表
|
||||
groupMakeSure, // 通过审核
|
||||
}
|
||||
|
||||
33
main.js
33
main.js
@@ -10,15 +10,16 @@ import Vue from 'vue'
|
||||
import store from './store'
|
||||
import uView from 'uview-ui'
|
||||
import filters from './utils/filters.js'
|
||||
import {
|
||||
usqlite
|
||||
} from '@/uni_modules/onemue-USQLite/js_sdk/usqlite.js'
|
||||
import model from '@/utils/im/models.js'
|
||||
|
||||
import {
|
||||
router,
|
||||
RouterMount
|
||||
} from 'router'
|
||||
import {
|
||||
usqlite
|
||||
} from '@/uni_modules/onemue-USQLite/js_sdk/usqlite.js'
|
||||
import {
|
||||
contactModel
|
||||
} from '@/utils/im/models.js'
|
||||
|
||||
Object.keys(filters).forEach(key => {
|
||||
Vue.filter(key, filters[key])
|
||||
@@ -29,14 +30,22 @@ Vue.use(router)
|
||||
|
||||
Vue.config.productionTip = false
|
||||
Vue.prototype.$store = store
|
||||
uni.$sql = usqlite
|
||||
uni.model = model
|
||||
|
||||
uni.$sql.connect({
|
||||
name: 'zh-health',// 数据库名称
|
||||
path:'_doc/health.db', // 路径
|
||||
})
|
||||
|
||||
usqlite.connect({
|
||||
name: 'zh-health', // 数据库名称
|
||||
path: '_doc/health.db', // 路径
|
||||
}, (err, res) => {
|
||||
uni.getStorage({
|
||||
key: 'FIRST_RUN',
|
||||
fail: () => {
|
||||
contactModel.create((err, res) => {
|
||||
console.error('SQLITE 创建表格', err, res)
|
||||
uni.setStorageSync('FIRST_RUN', 'X')
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
App.mpType = 'app'
|
||||
const app = new Vue({
|
||||
store,
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
"name" : "ZH-HEALTH",
|
||||
"appid" : "__UNI__C29473D",
|
||||
"description" : "ZH-HEALTH,您手上的健康管理专家",
|
||||
"versionName" : "1.0.10",
|
||||
"versionCode" : 110,
|
||||
"versionName" : "1.0.20",
|
||||
"versionCode" : 100,
|
||||
"transformPx" : false,
|
||||
/* 5+App特有相关 */
|
||||
"app-plus" : {
|
||||
@@ -24,7 +24,9 @@
|
||||
"SQLite" : {},
|
||||
"VideoPlayer" : {},
|
||||
"Geolocation" : {},
|
||||
"Fingerprint" : {}
|
||||
"Fingerprint" : {},
|
||||
"Maps" : {},
|
||||
"Push" : {}
|
||||
},
|
||||
/* 应用发布信息 */
|
||||
"distribute" : {
|
||||
@@ -80,49 +82,60 @@
|
||||
}
|
||||
},
|
||||
"ad" : {},
|
||||
"push" : {},
|
||||
"push" : {
|
||||
"unipush" : {}
|
||||
},
|
||||
"geolocation" : {
|
||||
"amap" : {
|
||||
"__platform__" : [ "android" ],
|
||||
"appkey_ios" : "",
|
||||
"appkey_android" : "05b7f32ca9c897c8b63c505d92cd654b"
|
||||
"appkey_android" : "1dfbe526a37dcb1f13263e0b5871ca4d"
|
||||
},
|
||||
"system" : {
|
||||
"__platform__" : [ "android" ]
|
||||
}
|
||||
},
|
||||
"maps" : {
|
||||
"amap" : {
|
||||
"appkey_ios" : "",
|
||||
"appkey_android" : "1dfbe526a37dcb1f13263e0b5871ca4d"
|
||||
}
|
||||
}
|
||||
},
|
||||
"icons" : {
|
||||
"android" : {
|
||||
"hdpi" : "unpackage/res/icons/72x72.png",
|
||||
"xhdpi" : "unpackage/res/icons/96x96.png",
|
||||
"xxhdpi" : "unpackage/res/icons/144x144.png",
|
||||
"xxxhdpi" : "unpackage/res/icons/192x192.png"
|
||||
"hdpi" : "",
|
||||
"xhdpi" : "",
|
||||
"xxhdpi" : "",
|
||||
"xxxhdpi" : ""
|
||||
},
|
||||
"ios" : {
|
||||
"appstore" : "unpackage/res/icons/1024x1024.png",
|
||||
"appstore" : "",
|
||||
"ipad" : {
|
||||
"app" : "unpackage/res/icons/76x76.png",
|
||||
"app@2x" : "unpackage/res/icons/152x152.png",
|
||||
"notification" : "unpackage/res/icons/20x20.png",
|
||||
"notification@2x" : "unpackage/res/icons/40x40.png",
|
||||
"proapp@2x" : "unpackage/res/icons/167x167.png",
|
||||
"settings" : "unpackage/res/icons/29x29.png",
|
||||
"settings@2x" : "unpackage/res/icons/58x58.png",
|
||||
"spotlight" : "unpackage/res/icons/40x40.png",
|
||||
"spotlight@2x" : "unpackage/res/icons/80x80.png"
|
||||
"app" : "",
|
||||
"app@2x" : "",
|
||||
"notification" : "",
|
||||
"notification@2x" : "",
|
||||
"proapp@2x" : "",
|
||||
"settings" : "",
|
||||
"settings@2x" : "",
|
||||
"spotlight" : "",
|
||||
"spotlight@2x" : ""
|
||||
},
|
||||
"iphone" : {
|
||||
"app@2x" : "unpackage/res/icons/120x120.png",
|
||||
"app@3x" : "unpackage/res/icons/180x180.png",
|
||||
"notification@2x" : "unpackage/res/icons/40x40.png",
|
||||
"notification@3x" : "unpackage/res/icons/60x60.png",
|
||||
"settings@2x" : "unpackage/res/icons/58x58.png",
|
||||
"settings@3x" : "unpackage/res/icons/87x87.png",
|
||||
"spotlight@2x" : "unpackage/res/icons/80x80.png",
|
||||
"spotlight@3x" : "unpackage/res/icons/120x120.png"
|
||||
"app@2x" : "",
|
||||
"app@3x" : "",
|
||||
"notification@2x" : "",
|
||||
"notification@3x" : "",
|
||||
"settings@2x" : "",
|
||||
"settings@3x" : "",
|
||||
"spotlight@2x" : "",
|
||||
"spotlight@3x" : ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"splashscreen" : {
|
||||
"androidStyle" : "common"
|
||||
}
|
||||
},
|
||||
"nativePlugins" : {
|
||||
|
||||
383
package-lock.json
generated
383
package-lock.json
generated
@@ -9,8 +9,6 @@
|
||||
"version": "1.0.0",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"bitcore-lib": "^8.25.25",
|
||||
"bitcore-mnemonic": "^8.25.25",
|
||||
"moment": "^2.29.1",
|
||||
"uni-read-pages": "^1.0.5",
|
||||
"uni-simple-router": "^2.0.7",
|
||||
@@ -19,171 +17,6 @@
|
||||
},
|
||||
"devDependencies": {}
|
||||
},
|
||||
"node_modules/base-x": {
|
||||
"version": "3.0.9",
|
||||
"resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz",
|
||||
"integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==",
|
||||
"dependencies": {
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/bech32": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/bech32/-/bech32-2.0.0.tgz",
|
||||
"integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg=="
|
||||
},
|
||||
"node_modules/bigi": {
|
||||
"version": "1.4.2",
|
||||
"resolved": "https://registry.npmjs.org/bigi/-/bigi-1.4.2.tgz",
|
||||
"integrity": "sha1-nGZalfiLiwj8Bc/XMfVhhZ1yWCU="
|
||||
},
|
||||
"node_modules/bip-schnorr": {
|
||||
"version": "0.6.4",
|
||||
"resolved": "https://registry.npmjs.org/bip-schnorr/-/bip-schnorr-0.6.4.tgz",
|
||||
"integrity": "sha512-dNKw7Lea8B0wMIN4OjEmOk/Z5qUGqoPDY0P2QttLqGk1hmDPytLWW8PR5Pb6Vxy6CprcdEgfJpOjUu+ONQveyg==",
|
||||
"dependencies": {
|
||||
"bigi": "^1.4.2",
|
||||
"ecurve": "^1.0.6",
|
||||
"js-sha256": "^0.9.0",
|
||||
"randombytes": "^2.1.0",
|
||||
"safe-buffer": "^5.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/bitcore-lib": {
|
||||
"version": "8.25.25",
|
||||
"resolved": "https://registry.npmjs.org/bitcore-lib/-/bitcore-lib-8.25.25.tgz",
|
||||
"integrity": "sha512-H6qNCVl4M8/MglXhvc04mmeus1d6nrmqTJGQ+xezJLvL7hs7R3dyBPtOqSP3YSw0iq/GWspMd8f5OOlyXVipJQ==",
|
||||
"dependencies": {
|
||||
"bech32": "=2.0.0",
|
||||
"bip-schnorr": "=0.6.4",
|
||||
"bn.js": "=4.11.8",
|
||||
"bs58": "^4.0.1",
|
||||
"buffer-compare": "=1.1.1",
|
||||
"elliptic": "^6.5.3",
|
||||
"inherits": "=2.0.1",
|
||||
"lodash": "^4.17.20"
|
||||
}
|
||||
},
|
||||
"node_modules/bitcore-mnemonic": {
|
||||
"version": "8.25.25",
|
||||
"resolved": "https://registry.npmjs.org/bitcore-mnemonic/-/bitcore-mnemonic-8.25.25.tgz",
|
||||
"integrity": "sha512-7HvRxHrmd+Rh0Ohl0SEDMKQBAM+FoevXbCFnxGju6H+uZjtWMOToHA8vUg0+B91pfEMjdt9mQVB/wSA8GMqnCA==",
|
||||
"dependencies": {
|
||||
"bitcore-lib": "^8.25.25",
|
||||
"unorm": "^1.4.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"bitcore-lib": "^8.20.1"
|
||||
}
|
||||
},
|
||||
"node_modules/bn.js": {
|
||||
"version": "4.11.8",
|
||||
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
|
||||
"integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA=="
|
||||
},
|
||||
"node_modules/brorand": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
|
||||
"integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8="
|
||||
},
|
||||
"node_modules/bs58": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz",
|
||||
"integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=",
|
||||
"dependencies": {
|
||||
"base-x": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer-compare": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer-compare/-/buffer-compare-1.1.1.tgz",
|
||||
"integrity": "sha1-W+e+hTr4kZjR9N3AkNHWakiu9ZY="
|
||||
},
|
||||
"node_modules/ecurve": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/ecurve/-/ecurve-1.0.6.tgz",
|
||||
"integrity": "sha512-/BzEjNfiSuB7jIWKcS/z8FK9jNjmEWvUV2YZ4RLSmcDtP7Lq0m6FvDuSnJpBlDpGRpfRQeTLGLBI8H+kEv0r+w==",
|
||||
"dependencies": {
|
||||
"bigi": "^1.1.0",
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/elliptic": {
|
||||
"version": "6.5.4",
|
||||
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz",
|
||||
"integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==",
|
||||
"dependencies": {
|
||||
"bn.js": "^4.11.9",
|
||||
"brorand": "^1.1.0",
|
||||
"hash.js": "^1.0.0",
|
||||
"hmac-drbg": "^1.0.1",
|
||||
"inherits": "^2.0.4",
|
||||
"minimalistic-assert": "^1.0.1",
|
||||
"minimalistic-crypto-utils": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/elliptic/node_modules/bn.js": {
|
||||
"version": "4.12.0",
|
||||
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
|
||||
"integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
|
||||
},
|
||||
"node_modules/elliptic/node_modules/inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
},
|
||||
"node_modules/hash.js": {
|
||||
"version": "1.1.7",
|
||||
"resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
|
||||
"integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
|
||||
"dependencies": {
|
||||
"inherits": "^2.0.3",
|
||||
"minimalistic-assert": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/hash.js/node_modules/inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
},
|
||||
"node_modules/hmac-drbg": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
|
||||
"integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
|
||||
"dependencies": {
|
||||
"hash.js": "^1.0.3",
|
||||
"minimalistic-assert": "^1.0.0",
|
||||
"minimalistic-crypto-utils": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/inherits": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
|
||||
"integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE="
|
||||
},
|
||||
"node_modules/js-sha256": {
|
||||
"version": "0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz",
|
||||
"integrity": "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA=="
|
||||
},
|
||||
"node_modules/lodash": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
||||
},
|
||||
"node_modules/minimalistic-assert": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
|
||||
"integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A=="
|
||||
},
|
||||
"node_modules/minimalistic-crypto-utils": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
|
||||
"integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo="
|
||||
},
|
||||
"node_modules/moment": {
|
||||
"version": "2.29.1",
|
||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
|
||||
@@ -192,33 +25,6 @@
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/randombytes": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
|
||||
"integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
|
||||
"dependencies": {
|
||||
"safe-buffer": "^5.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/safe-buffer": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
]
|
||||
},
|
||||
"node_modules/uni-read-pages": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/uni-read-pages/-/uni-read-pages-1.0.5.tgz",
|
||||
@@ -230,14 +36,6 @@
|
||||
"resolved": "https://registry.npmjs.org/uni-simple-router/-/uni-simple-router-2.0.7.tgz",
|
||||
"integrity": "sha512-8FKv5dw7Eoonm0gkO8udprrxzin0fNUI0+AvIphFkFRH5ZmP5ZWJ2pvnWzb2NiiqQSECTSU5VSB7HhvOSwD5eA=="
|
||||
},
|
||||
"node_modules/unorm": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/unorm/-/unorm-1.6.0.tgz",
|
||||
"integrity": "sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA==",
|
||||
"engines": {
|
||||
"node": ">= 0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/uview-ui": {
|
||||
"version": "2.0.19",
|
||||
"resolved": "https://registry.npmjs.org/uview-ui/-/uview-ui-2.0.19.tgz",
|
||||
@@ -256,187 +54,11 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"base-x": {
|
||||
"version": "3.0.9",
|
||||
"resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz",
|
||||
"integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==",
|
||||
"requires": {
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"bech32": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/bech32/-/bech32-2.0.0.tgz",
|
||||
"integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg=="
|
||||
},
|
||||
"bigi": {
|
||||
"version": "1.4.2",
|
||||
"resolved": "https://registry.npmjs.org/bigi/-/bigi-1.4.2.tgz",
|
||||
"integrity": "sha1-nGZalfiLiwj8Bc/XMfVhhZ1yWCU="
|
||||
},
|
||||
"bip-schnorr": {
|
||||
"version": "0.6.4",
|
||||
"resolved": "https://registry.npmjs.org/bip-schnorr/-/bip-schnorr-0.6.4.tgz",
|
||||
"integrity": "sha512-dNKw7Lea8B0wMIN4OjEmOk/Z5qUGqoPDY0P2QttLqGk1hmDPytLWW8PR5Pb6Vxy6CprcdEgfJpOjUu+ONQveyg==",
|
||||
"requires": {
|
||||
"bigi": "^1.4.2",
|
||||
"ecurve": "^1.0.6",
|
||||
"js-sha256": "^0.9.0",
|
||||
"randombytes": "^2.1.0",
|
||||
"safe-buffer": "^5.2.1"
|
||||
}
|
||||
},
|
||||
"bitcore-lib": {
|
||||
"version": "8.25.25",
|
||||
"resolved": "https://registry.npmjs.org/bitcore-lib/-/bitcore-lib-8.25.25.tgz",
|
||||
"integrity": "sha512-H6qNCVl4M8/MglXhvc04mmeus1d6nrmqTJGQ+xezJLvL7hs7R3dyBPtOqSP3YSw0iq/GWspMd8f5OOlyXVipJQ==",
|
||||
"requires": {
|
||||
"bech32": "=2.0.0",
|
||||
"bip-schnorr": "=0.6.4",
|
||||
"bn.js": "=4.11.8",
|
||||
"bs58": "^4.0.1",
|
||||
"buffer-compare": "=1.1.1",
|
||||
"elliptic": "^6.5.3",
|
||||
"inherits": "=2.0.1",
|
||||
"lodash": "^4.17.20"
|
||||
}
|
||||
},
|
||||
"bitcore-mnemonic": {
|
||||
"version": "8.25.25",
|
||||
"resolved": "https://registry.npmjs.org/bitcore-mnemonic/-/bitcore-mnemonic-8.25.25.tgz",
|
||||
"integrity": "sha512-7HvRxHrmd+Rh0Ohl0SEDMKQBAM+FoevXbCFnxGju6H+uZjtWMOToHA8vUg0+B91pfEMjdt9mQVB/wSA8GMqnCA==",
|
||||
"requires": {
|
||||
"bitcore-lib": "^8.25.25",
|
||||
"unorm": "^1.4.1"
|
||||
}
|
||||
},
|
||||
"bn.js": {
|
||||
"version": "4.11.8",
|
||||
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
|
||||
"integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA=="
|
||||
},
|
||||
"brorand": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
|
||||
"integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8="
|
||||
},
|
||||
"bs58": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz",
|
||||
"integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=",
|
||||
"requires": {
|
||||
"base-x": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"buffer-compare": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer-compare/-/buffer-compare-1.1.1.tgz",
|
||||
"integrity": "sha1-W+e+hTr4kZjR9N3AkNHWakiu9ZY="
|
||||
},
|
||||
"ecurve": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/ecurve/-/ecurve-1.0.6.tgz",
|
||||
"integrity": "sha512-/BzEjNfiSuB7jIWKcS/z8FK9jNjmEWvUV2YZ4RLSmcDtP7Lq0m6FvDuSnJpBlDpGRpfRQeTLGLBI8H+kEv0r+w==",
|
||||
"requires": {
|
||||
"bigi": "^1.1.0",
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"elliptic": {
|
||||
"version": "6.5.4",
|
||||
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz",
|
||||
"integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==",
|
||||
"requires": {
|
||||
"bn.js": "^4.11.9",
|
||||
"brorand": "^1.1.0",
|
||||
"hash.js": "^1.0.0",
|
||||
"hmac-drbg": "^1.0.1",
|
||||
"inherits": "^2.0.4",
|
||||
"minimalistic-assert": "^1.0.1",
|
||||
"minimalistic-crypto-utils": "^1.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"bn.js": {
|
||||
"version": "4.12.0",
|
||||
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
|
||||
"integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"hash.js": {
|
||||
"version": "1.1.7",
|
||||
"resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
|
||||
"integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
|
||||
"requires": {
|
||||
"inherits": "^2.0.3",
|
||||
"minimalistic-assert": "^1.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"hmac-drbg": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
|
||||
"integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
|
||||
"requires": {
|
||||
"hash.js": "^1.0.3",
|
||||
"minimalistic-assert": "^1.0.0",
|
||||
"minimalistic-crypto-utils": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
|
||||
"integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE="
|
||||
},
|
||||
"js-sha256": {
|
||||
"version": "0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz",
|
||||
"integrity": "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA=="
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
||||
},
|
||||
"minimalistic-assert": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
|
||||
"integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A=="
|
||||
},
|
||||
"minimalistic-crypto-utils": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
|
||||
"integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo="
|
||||
},
|
||||
"moment": {
|
||||
"version": "2.29.1",
|
||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
|
||||
"integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ=="
|
||||
},
|
||||
"randombytes": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
|
||||
"integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
|
||||
"requires": {
|
||||
"safe-buffer": "^5.1.0"
|
||||
}
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
|
||||
},
|
||||
"uni-read-pages": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/uni-read-pages/-/uni-read-pages-1.0.5.tgz",
|
||||
@@ -447,11 +69,6 @@
|
||||
"resolved": "https://registry.npmjs.org/uni-simple-router/-/uni-simple-router-2.0.7.tgz",
|
||||
"integrity": "sha512-8FKv5dw7Eoonm0gkO8udprrxzin0fNUI0+AvIphFkFRH5ZmP5ZWJ2pvnWzb2NiiqQSECTSU5VSB7HhvOSwD5eA=="
|
||||
},
|
||||
"unorm": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/unorm/-/unorm-1.6.0.tgz",
|
||||
"integrity": "sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA=="
|
||||
},
|
||||
"uview-ui": {
|
||||
"version": "2.0.19",
|
||||
"resolved": "https://registry.npmjs.org/uview-ui/-/uview-ui-2.0.19.tgz",
|
||||
|
||||
@@ -7,10 +7,8 @@
|
||||
"moment": "^2.29.1",
|
||||
"uni-read-pages": "^1.0.5",
|
||||
"uni-simple-router": "^2.0.7",
|
||||
"uview-ui": "^2.0.19",
|
||||
"vuex": "^3.6.2"
|
||||
"uview-ui": "^2.0.27"
|
||||
},
|
||||
"devDependencies": {},
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
|
||||
15
pages.json
15
pages.json
@@ -373,19 +373,6 @@
|
||||
{
|
||||
"path": "pages/im/private/chat",
|
||||
"style": {
|
||||
"navigationBarBackgroundColor":"#FFFFFF",
|
||||
"disableScroll": false,
|
||||
"app-plus": {
|
||||
"titleNView": {
|
||||
"type": "default",
|
||||
"buttons": [{
|
||||
"float": "right",
|
||||
"fontSrc": "/static/iconfont.ttf",
|
||||
"text": "\ue607",
|
||||
"fontSize": "20px"
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -464,7 +451,7 @@
|
||||
{
|
||||
"path": "pages/im/group/chat",
|
||||
"name": "imGroupChat",
|
||||
"style": {
|
||||
"style": {
|
||||
"navigationBarTitleText": "群聊",
|
||||
"app-plus": {
|
||||
"titleNView": {
|
||||
|
||||
BIN
pages/.DS_Store
vendored
BIN
pages/.DS_Store
vendored
Binary file not shown.
@@ -1,67 +1,67 @@
|
||||
<template>
|
||||
<u-alert type="warning" v-if="connection != 0" :description="description" show-icon />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
connection: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
description() {
|
||||
return this.connectionStatusMap.filter(item => item.index == this.connection)[0].text
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
connectionStatusMap: [{
|
||||
index: -1,
|
||||
text: '网络不可用'
|
||||
},
|
||||
{
|
||||
index: 0,
|
||||
text: '连接成功'
|
||||
},
|
||||
{
|
||||
index: 1,
|
||||
text: '连接中'
|
||||
},
|
||||
{
|
||||
index: 2,
|
||||
text: '未连接'
|
||||
},
|
||||
{
|
||||
index: 3,
|
||||
text: '用户账号在其它设备登录'
|
||||
},
|
||||
{
|
||||
index: 4,
|
||||
text: 'TOKEN过期'
|
||||
},
|
||||
{
|
||||
index: 6,
|
||||
text: '用户被禁用'
|
||||
},
|
||||
{
|
||||
index: 12,
|
||||
text: '退出登录'
|
||||
},
|
||||
{
|
||||
index: 13,
|
||||
text: '连接暂时被挂起'
|
||||
},
|
||||
{
|
||||
index: 14,
|
||||
text: '连接超时'
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
<template>
|
||||
<u-alert type="warning" v-if="connection != 0" :description="description" show-icon />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
connection: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
description() {
|
||||
return this.connectionStatusMap.filter(item => item.index == this.connection)[0].text
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
connectionStatusMap: [{
|
||||
index: -1,
|
||||
text: '网络不可用'
|
||||
},
|
||||
{
|
||||
index: 0,
|
||||
text: '连接成功'
|
||||
},
|
||||
{
|
||||
index: 1,
|
||||
text: '连接中'
|
||||
},
|
||||
{
|
||||
index: 2,
|
||||
text: '未连接'
|
||||
},
|
||||
{
|
||||
index: 3,
|
||||
text: '用户账号在其它设备登录'
|
||||
},
|
||||
{
|
||||
index: 4,
|
||||
text: 'TOKEN过期'
|
||||
},
|
||||
{
|
||||
index: 6,
|
||||
text: '用户被禁用'
|
||||
},
|
||||
{
|
||||
index: 12,
|
||||
text: '退出登录'
|
||||
},
|
||||
{
|
||||
index: 13,
|
||||
text: '连接暂时被挂起'
|
||||
},
|
||||
{
|
||||
index: 14,
|
||||
text: '连接超时'
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
|
||||
@@ -2,12 +2,14 @@
|
||||
<view class="message--cell">
|
||||
<view class="avatar">
|
||||
<u-badge max="99" shape="horn" absolute :offset="[-5, -8]" :value="item.unreadMessageCount" />
|
||||
<u-avatar :src="contact(item.targetId).portraitUrl" shape="square" size="44" />
|
||||
<u-avatar :src="contact(item.targetId).portraitUrl" shape="square" :size="avatarSize" />
|
||||
</view>
|
||||
<view class="content">
|
||||
<view class="header">
|
||||
<view class="name">{{ contact(item.targetId).name }} <text v-if="item.conversationType === 3"
|
||||
class='qun'>[群]</text></view>
|
||||
<view class="name">
|
||||
{{ contact(item.targetId).name }}
|
||||
<text v-if="item.conversationType === 3" class='group'>[群]</text>
|
||||
</view>
|
||||
<view class="time">{{ item.sentTime|timeCustomCN }}</view>
|
||||
</view>
|
||||
<message-preview class="preview" :msg="item.latestMessage" :draft="item.draft"
|
||||
@@ -18,8 +20,13 @@
|
||||
|
||||
<script>
|
||||
import messagePreview from './messagePreview'
|
||||
import utils from '@/utils/index.js'
|
||||
import imBase from '../../mixins/imBase.js'
|
||||
|
||||
export default {
|
||||
mixins: [
|
||||
imBase
|
||||
],
|
||||
props: {
|
||||
item: {
|
||||
type: Object,
|
||||
@@ -27,16 +34,6 @@
|
||||
return {}
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
console.log(this.item);
|
||||
},
|
||||
computed: {
|
||||
contact() {
|
||||
return function(targetId) {
|
||||
return this.$store.getters.contactInfo(targetId)
|
||||
}
|
||||
}
|
||||
},
|
||||
components: {
|
||||
messagePreview
|
||||
@@ -51,6 +48,7 @@
|
||||
|
||||
.avatar {
|
||||
position: relative;
|
||||
padding-top: 5rpx;
|
||||
|
||||
.u-badge {
|
||||
z-index: 998;
|
||||
@@ -62,10 +60,8 @@
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
flex: 1;
|
||||
|
||||
|
||||
border-bottom-width: 0.5px !important;
|
||||
border-color: #f9f9f9 !important;
|
||||
border-color: #eee !important;
|
||||
border-bottom-style: solid;
|
||||
|
||||
.header {
|
||||
@@ -75,10 +71,8 @@
|
||||
.name {
|
||||
font-size: $title-size + 2;
|
||||
color: #454545;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.qun {
|
||||
.group {
|
||||
color: $main-color;
|
||||
font-size: $title-size-m - 4;
|
||||
margin-left: 4px;
|
||||
@@ -22,15 +22,18 @@
|
||||
<view class="preview" v-if="msg.objectName=='RC:LBSMsg'">
|
||||
<text v-if="conversationType == 3">{{ user.name }}:</text>[位置]
|
||||
</view>
|
||||
<view class="preview" v-if="msg.objectName=='RC:AudioMsg'">
|
||||
<view class="preview" v-if="msg.objectName=='RC:InfoNtf' && JSON.parse(msg.message).mediaType==0">
|
||||
<text v-if="conversationType == 3">{{ user.name }}:</text>[语音通话]
|
||||
</view>
|
||||
<view class="preview" v-if="msg.objectName=='RC:VideoMsg'">
|
||||
<view class="preview" v-if="msg.objectName=='RC:InfoNtf' && JSON.parse(msg.message).mediaType==1">
|
||||
<text v-if="conversationType == 3">{{ user.name }}:</text>[视频通话]
|
||||
</view>
|
||||
<view class="preview" v-if="msg.objectName=='RC:GrpNtf'">
|
||||
[{{ msg.message }}]
|
||||
</view>
|
||||
<view class="preview" v-if="msg.objectName=='RC:RcNtf'">
|
||||
<text v-if="conversationType == 3">{{ user.name }}:</text> 撤回了一条消息
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</template>
|
||||
@@ -1,24 +1,24 @@
|
||||
<template>
|
||||
<view>
|
||||
<view v-for="(item, index) in conversations" :key="index" :class="['message', { 'is-top': item.isTop }]"
|
||||
:data-item="item" @longpress="onLongPress" @click="toDetail(item)">
|
||||
<message-cell :item="item" />
|
||||
</view>
|
||||
|
||||
<view class="shade" @click="hidePop" v-show="showPop">
|
||||
<view class="shade" @click="hidePop" @touchmove="hidePop" v-show="showPop">
|
||||
<view class="pop" :style="popStyle" :class="{'show':showPop}">
|
||||
<view v-for="(item, index) in popButton" :key="index" @click="pickerMenu" :data-index="index">
|
||||
{{item}}
|
||||
<view v-for="(item, index) in popButton" :key="index" @click="pickerMenu(index)">
|
||||
{{ item }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-for="(item, index) in conversations" :key="index"
|
||||
:class="['message', { 'is-top': item.isTop, 'is-active': pickedItem.targetId == item.targetId }]"
|
||||
:data-item="item" @longpress="onLongPress" @click="toDetail(item)">
|
||||
<message-cell :item="item" />
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
|
||||
import im from '@/utils/im/index.js'
|
||||
import messageCell from './messageCell'
|
||||
import messageCell from './conversation/messageCell'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
@@ -66,15 +66,13 @@
|
||||
}, 250)
|
||||
},
|
||||
// 点击会话功能菜单
|
||||
pickerMenu(e) {
|
||||
const index = Number(e.currentTarget.dataset.index)
|
||||
|
||||
pickerMenu(index) {
|
||||
if (index == 0) {
|
||||
RongIMLib.setConversationToTop(this.pickedItem.conversationType, this.pickedItem.targetId, !this
|
||||
.pickedItem.isTop)
|
||||
} else if (index == 1) {
|
||||
RongIMLib.clearMessagesUnreadStatus(this.pickedItem.conversationType, this.pickedItem.targetId, this
|
||||
.pickedItem.sentTime)
|
||||
.pickedItem.sentTime)
|
||||
} else {
|
||||
RongIMLib.removeConversation(this.pickedItem.conversationType, this.pickedItem.targetId)
|
||||
RongIMLib.deleteMessages(this.pickedItem.conversationType, this.pickedItem.targetId)
|
||||
@@ -132,6 +130,10 @@
|
||||
&.is-top {
|
||||
background: $window-color;
|
||||
}
|
||||
|
||||
&.is-active {
|
||||
background: #F8FAFF;
|
||||
}
|
||||
}
|
||||
|
||||
/* 遮罩 */
|
||||
@@ -139,8 +141,10 @@
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 999;
|
||||
|
||||
.pop {
|
||||
.pop {
|
||||
border-radius: 10rpx;
|
||||
position: fixed;
|
||||
z-index: 101;
|
||||
width: 200rpx;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<view class="apply--cell">
|
||||
<view class="avatar">
|
||||
<u-avatar :src="user.portraitUrl || require('@/static/user/cover.png')" shape="square" size="46" />
|
||||
<u-avatar :src="user.portraitUrl || require('@/static/user/cover.png')" shape="square" :size="avatarSize" />
|
||||
</view>
|
||||
<view class="info">
|
||||
<view class="name"> {{ user.name }}</view>
|
||||
@@ -20,8 +20,12 @@
|
||||
resolveFriend,
|
||||
rejectFriend
|
||||
} from '@/apis/interfaces/im.js'
|
||||
import imBase from '../mixins/imBase.js'
|
||||
|
||||
export default {
|
||||
mixins: [
|
||||
imBase
|
||||
],
|
||||
props: {
|
||||
message: {
|
||||
type: Object,
|
||||
@@ -36,7 +40,6 @@
|
||||
methods: {
|
||||
resolve() {
|
||||
resolveFriend(this.message.sourceUserId).then(res => {
|
||||
this.clearMessages()
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: '通过好友申请'
|
||||
@@ -47,6 +50,8 @@
|
||||
icon: 'none',
|
||||
title: err.message
|
||||
})
|
||||
}).finally(() => {
|
||||
this.clearMessages()
|
||||
})
|
||||
},
|
||||
reject() {
|
||||
@@ -70,7 +75,9 @@
|
||||
clearMessages() {
|
||||
RongIMLib.deleteMessages(RongIMLib.ConversationType.SYSTEM, this.message.sourceUserId)
|
||||
this.$emit('success')
|
||||
uni.$emit('onContactNotification')
|
||||
uni.$emit('onNewContactConversation')
|
||||
uni.$emit('onNewContactFriends')
|
||||
uni.$emit('onNewContactPendings')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,126 +1,147 @@
|
||||
<template>
|
||||
<view class="friend-apply">
|
||||
<block v-for="(item, index) in lists" v-if="lists.length > 0" :key="index">
|
||||
<view class="lists">
|
||||
<view class="" style="width: 100rpx;height: 100rpx;">
|
||||
<u-avatar :src="JSON.parse(item.latestMessage.extra).portraitUrl" shape="square" size="44" />
|
||||
</view>
|
||||
<view class="right">
|
||||
<view class="title">
|
||||
<view class="name">{{ item.name }}</view>
|
||||
<view class="des">{{ item.latestMessage.message || '--' }}</view>
|
||||
</view>
|
||||
<view class="agress-btn">
|
||||
<span v-if="isAgree" @click="action('agree', item)">通过</span>
|
||||
<span v-if="isAgree" @click="action('reject', item)">拒绝</span>
|
||||
<span v-if="isApply && !item.is_friend" @click="action('apply', item)">查看</span>
|
||||
<span class="isFri" v-if="isApply && item.is_friend" @click="action('isFriend', item)">已是好友</span>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'friend-apply-reject-agree',
|
||||
props: {
|
||||
lists: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
isAgree: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
isReject: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
isApply: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
created() {
|
||||
console.log(this.lists);
|
||||
},
|
||||
methods: {
|
||||
action(type, item) {
|
||||
if (type === 'isFriend') {
|
||||
// ,后期可以跳转到信息介绍页面,先留在这里
|
||||
return uni.showToast({ title: '已是好友,无需重复添加', icon: 'none', duration:2000});
|
||||
}
|
||||
this.$emit('action', { type, item });
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.lists {
|
||||
padding: 0 $padding;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
box-sizing: border-box;
|
||||
font-size: $title-size;
|
||||
color: $text-gray;
|
||||
|
||||
.cover {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
.right {
|
||||
width: 570rpx;
|
||||
margin-left: $margin - 10;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: $padding 0;
|
||||
border-bottom: solid 1rpx #f9f9f9;
|
||||
.title {
|
||||
width: 370rpx;
|
||||
.name {
|
||||
width: 100%;
|
||||
color: $text-color;
|
||||
font-size: $title-size + 2;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.des {
|
||||
width: 100%;
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
font-size: $title-size-m;
|
||||
margin-top: $margin - 10;
|
||||
color: $text-gray-m;
|
||||
}
|
||||
}
|
||||
.agress-btn {
|
||||
display: flex;
|
||||
color: #fff;
|
||||
font-size: $title-size-m;
|
||||
span {
|
||||
display: inline-block;
|
||||
padding: 6rpx 14rpx;
|
||||
background-color: $text-price;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
span:nth-child(1) {
|
||||
background-color: $main-color;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
.isFri {
|
||||
background-color: #f9f9f9 !important;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
<template>
|
||||
<view class="friend-apply">
|
||||
<block v-for="(item, index) in lists" v-if="lists.length > 0" :key="index">
|
||||
<view class="lists">
|
||||
<view class="" style="width: 100rpx;height: 100rpx;">
|
||||
<u-avatar :src="JSON.parse(item.latestMessage.extra).portraitUrl" shape="square" :size="avatarSize" />
|
||||
</view>
|
||||
<view class="right">
|
||||
<view class="title">
|
||||
<view class="name">{{ item.name }}</view>
|
||||
<view class="des">{{ item.latestMessage.message || '--' }}</view>
|
||||
</view>
|
||||
<view class="agress-btn">
|
||||
<span v-if="isAgree" @click="action('agree', item)">通过</span>
|
||||
<span v-if="isAgree" @click="action('reject', item)">拒绝</span>
|
||||
<span v-if="isApply && !item.is_friend" @click="action('apply', item)">查看</span>
|
||||
<span class="isFri" v-if="isApply && item.is_friend"
|
||||
@click="action('isFriend', item)">已是好友</span>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import imBase from '../mixins/imBase.js'
|
||||
|
||||
export default {
|
||||
mixins:[
|
||||
imBase
|
||||
],
|
||||
name: 'friend-apply-reject-agree',
|
||||
props: {
|
||||
lists: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
isAgree: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
isReject: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
isApply: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
created() {
|
||||
console.log(this.lists);
|
||||
},
|
||||
methods: {
|
||||
action(type, item) {
|
||||
if (type === 'isFriend') {
|
||||
// ,后期可以跳转到信息介绍页面,先留在这里
|
||||
return uni.showToast({
|
||||
title: '已是好友,无需重复添加',
|
||||
icon: 'none',
|
||||
duration: 2000
|
||||
});
|
||||
}
|
||||
this.$emit('action', {
|
||||
type,
|
||||
item
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.lists {
|
||||
padding: 0 $padding;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
box-sizing: border-box;
|
||||
font-size: $title-size;
|
||||
color: $text-gray;
|
||||
|
||||
.cover {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.right {
|
||||
width: 570rpx;
|
||||
margin-left: $margin - 10;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: $padding 0;
|
||||
border-bottom: solid 1rpx #f9f9f9;
|
||||
|
||||
.title {
|
||||
width: 370rpx;
|
||||
|
||||
.name {
|
||||
width: 100%;
|
||||
color: $text-color;
|
||||
font-size: $title-size + 2;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.des {
|
||||
width: 100%;
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
font-size: $title-size-m;
|
||||
margin-top: $margin - 10;
|
||||
color: $text-gray-m;
|
||||
}
|
||||
}
|
||||
|
||||
.agress-btn {
|
||||
display: flex;
|
||||
color: #fff;
|
||||
font-size: $title-size-m;
|
||||
|
||||
span {
|
||||
display: inline-block;
|
||||
padding: 6rpx 14rpx;
|
||||
background-color: $text-price;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
|
||||
span:nth-child(1) {
|
||||
background-color: $main-color;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
|
||||
.isFri {
|
||||
background-color: #f9f9f9 !important;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<block v-for="(item, index) in lists" v-if="lists.length > 0" :key="index">
|
||||
<view class="lists">
|
||||
<view class="" style="width: 100rpx;height: 100rpx;">
|
||||
<u-avatar :src="item.portraitUrl || require('@/static/user/cover.png')" shape="square" size="44" />
|
||||
<u-avatar :src="item.portraitUrl || require('@/static/user/cover.png')" shape="square" :size="avatarSize" />
|
||||
</view>
|
||||
<view class="right">
|
||||
<view class="title">
|
||||
@@ -21,7 +21,12 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import imBase from '../mixins/imBase.js'
|
||||
|
||||
export default {
|
||||
mixins: [
|
||||
imBase
|
||||
],
|
||||
name: 'friend-apply-reject-agree',
|
||||
props: {
|
||||
lists: {
|
||||
|
||||
@@ -4,21 +4,22 @@
|
||||
<view :class="['user', {'active': item.targetId === currentUser.targetId}]" @longpress="showAction(item)"
|
||||
v-for="(item, index) in users" :key="index" @click="toUser(item)">
|
||||
<view class="avatar">
|
||||
<u-avatar :size="avatarSize" shape="square" :src="contact(item.targetId).portraitUrl" />
|
||||
<u-avatar :size="avatarSize" shape="square"
|
||||
:src="contact(item.targetId).portraitUrl || require('@/static/user/cover.png')" />
|
||||
<view class="admin" v-if="item.is_admin === 1">管理</view>
|
||||
<view class="owner" v-if="item.is_admin === 2">群主</view>
|
||||
</view>
|
||||
<view class="name">{{ item.name }}</view>
|
||||
</view>
|
||||
<view class="user" v-if="isAdmin">
|
||||
<u-avatar @click="inviteUser" :size="avatarSize" shape="square" icon="plus" bgColor="#f9f9f9" color="#c7c7c7" />
|
||||
<view class="user" v-if="canInvite">
|
||||
<u-avatar @click="inviteUser" :size="avatarSize" shape="square" icon="plus" bgColor="#f9f9f9"
|
||||
color="#c7c7c7" />
|
||||
<view class="name">邀请好友</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="loadmore">
|
||||
<u-icon name="arrow-right" @click="loadMore" v-if="members > users.length" color="#999" labelColor="#999"
|
||||
label="查看更多群成员" labelPos="left" :labelSize="labelSize" :size="iconSize" />
|
||||
<view class="loadmore" @click="loadMore" v-if="members > users.length">
|
||||
查看更多群成员 <uni-icons size="30rpx" type="right"></uni-icons>
|
||||
</view>
|
||||
|
||||
<u-action-sheet :actions="actionMap" :title="actionTitle" cancelText="取消" @close="hideAction"
|
||||
@@ -35,9 +36,13 @@
|
||||
removeGroupAdmin,
|
||||
transferGroupOwner
|
||||
} from '@/apis/interfaces/im.js'
|
||||
import utils from '@/utils/index.js'
|
||||
import utils from '@/utils/index.js'
|
||||
import imBase from '../mixins/imBase.js'
|
||||
|
||||
export default {
|
||||
mixins: [
|
||||
imBase
|
||||
],
|
||||
props: {
|
||||
targetId: {
|
||||
type: String,
|
||||
@@ -53,28 +58,19 @@
|
||||
users: [],
|
||||
isOwner: false,
|
||||
isAdmin: false,
|
||||
canInvite: false, // 是否可以开启邀请
|
||||
adminUid: 0,
|
||||
members: 0,
|
||||
actionShow: false,
|
||||
actionMap: [],
|
||||
actionTitle: '',
|
||||
currentUser: {},
|
||||
avatarSize: 45,
|
||||
labelSize: 14,
|
||||
labelSize: 14,
|
||||
iconSize: 14
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
contact() {
|
||||
return function(targetId) {
|
||||
return this.$store.getters.contactInfo(targetId)
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.avatarSize = utils.rpx2px(90)
|
||||
this.labelSize = utils.rpx2px(24)
|
||||
this.iconSize = utils.rpx2px(26)
|
||||
created() {
|
||||
this.iconSize = utils.rpx2px(26)
|
||||
},
|
||||
mounted() {
|
||||
this.initGroupInfo()
|
||||
@@ -92,6 +88,7 @@
|
||||
this.isAdmin = res.is_admin
|
||||
this.adminUid = res.user_id
|
||||
this.members = res.members
|
||||
this.canInvite = res.can_invite
|
||||
})
|
||||
},
|
||||
initUsers() {
|
||||
@@ -104,6 +101,9 @@
|
||||
this.actionShow = false
|
||||
},
|
||||
showAction(item) {
|
||||
if (item.is_admin == 2) {
|
||||
return
|
||||
}
|
||||
this.currentUser = item
|
||||
this.actionTitle = item.name
|
||||
// 只有管理员以上才会弹窗
|
||||
@@ -271,8 +271,7 @@
|
||||
.avatar {
|
||||
border-radius: 0 8rpx 0 0;
|
||||
position: relative;
|
||||
width: 90rpx;
|
||||
height: 90rpx;
|
||||
width: 84rpx;
|
||||
overflow: hidden;
|
||||
|
||||
.admin {
|
||||
@@ -321,12 +320,16 @@
|
||||
|
||||
.loadmore {
|
||||
font-size: 26rpx;
|
||||
color: $text-gray-m;
|
||||
color: $text-gray-m !important;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-sizing: border-box;
|
||||
|
||||
.uni-icons {
|
||||
color: $text-gray-m !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
79
pages/im/components/sent/sentEmoji.vue
Normal file
79
pages/im/components/sent/sentEmoji.vue
Normal file
@@ -0,0 +1,79 @@
|
||||
<template>
|
||||
<view class="emoji--lay" v-show="show">
|
||||
<scroll-view class="scroll" :scroll-y="true">
|
||||
<view class="emoji-flex">
|
||||
<view class="item" v-for="(item, index) in emojiArr" :key="index" @click="$emit('onEmoji', item)">{{item.emoji}}</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view class="tool">
|
||||
<!-- <view class="item" @click="$emit('delete')">删除</view> -->
|
||||
<view class="item sent" @click="$emit('sent')">发送</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import emoji from '@/static/im/emoji'
|
||||
export default{
|
||||
props:{
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: () => {
|
||||
return false
|
||||
}
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
emojiArr: emoji
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.emoji--lay{
|
||||
height: 600rpx;
|
||||
position: relative;
|
||||
.scroll{
|
||||
height: 600rpx;
|
||||
.emoji-flex{
|
||||
padding: 15rpx 15rpx 120rpx;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
.item{
|
||||
margin: 10rpx 15rpx;
|
||||
font-size: 52rpx;
|
||||
width: calc(12.5% - 30rpx);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
}
|
||||
.tool{
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background-image: linear-gradient(to top, #FFF, rgba(255, 255, 255, .0));
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: 20rpx 30rpx 30rpx;
|
||||
.item{
|
||||
line-height: 70rpx;
|
||||
border-radius: 35rpx;
|
||||
width: 140rpx;
|
||||
text-align: center;
|
||||
font-size: 28rpx;
|
||||
margin-left: 20rpx;
|
||||
background: white;
|
||||
border: solid 1rpx #f5f5f5;
|
||||
box-sizing: border-box;
|
||||
&.sent{
|
||||
border-color: #34CE98;
|
||||
background: #34CE98;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -33,9 +33,12 @@
|
||||
|
||||
<script>
|
||||
import im from '@/utils/im/index.js'
|
||||
import * as CallLib from '@/uni_modules/RongCloud-CallWrapper/lib/index'
|
||||
import imBase from '../../mixins/imBase.js'
|
||||
|
||||
export default {
|
||||
mixins: [
|
||||
imBase
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
callActions: [{
|
||||
@@ -64,15 +67,11 @@
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
sender() {
|
||||
return this.$store.getters.sender
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
singleCall(e) {
|
||||
uni.navigateTo({
|
||||
url: '/pages/im/private/call?targetId=' + this.targetId + '&mediaType=' + e.type
|
||||
url: '/pages/im/private/call?targetId=' + this.targetId + '&mediaType=' + e.type +
|
||||
'&isCall=true'
|
||||
})
|
||||
},
|
||||
onPopupsItem(type) {
|
||||
@@ -104,16 +103,11 @@
|
||||
this.callShow = true
|
||||
break;
|
||||
case 'location':
|
||||
// uni.showToast({
|
||||
// icon: 'none',
|
||||
// title: '功能正在开发中'
|
||||
// })
|
||||
// uni.chooseLocation({
|
||||
// success: res => {
|
||||
// console.log(res);
|
||||
// // this.success()
|
||||
// }
|
||||
// })
|
||||
uni.chooseLocation({
|
||||
success: (c) => {
|
||||
console.log(c);
|
||||
}
|
||||
})
|
||||
break;
|
||||
case 'redpacket':
|
||||
uni.showToast({
|
||||
@@ -140,13 +134,14 @@
|
||||
<style lang="scss" scoped>
|
||||
.sent--popups {
|
||||
background: white;
|
||||
padding: 30rpx 15rpx;
|
||||
display: flex;
|
||||
padding: 30rpx 15rpx;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
flex-direction: row;
|
||||
|
||||
.item {
|
||||
width: 150rpx;
|
||||
margin: 15rpx;
|
||||
margin: 15rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@@ -1,16 +1,29 @@
|
||||
<template>
|
||||
<view class="sent--text">
|
||||
<input class="input" type="text" :auto-blur="true" @focus="focus" @blur="blur" :focus="focusState" v-model="inputTxt" confirm-type="send"
|
||||
@confirm="sent" cursor-spacing="10" />
|
||||
<!-- <button class="button" size="mini" :disabled="disabled" @click="demo">{{focusState ? '失焦': '聚焦'}}</button> -->
|
||||
<input
|
||||
class="input"
|
||||
type="text"
|
||||
:auto-blur="true"
|
||||
:focus="focusState"
|
||||
v-model="inputTxt"
|
||||
confirm-type="send"
|
||||
cursor-spacing="10"
|
||||
@focus="focus"
|
||||
@blur="blur"
|
||||
@confirm="sent"
|
||||
/>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import im from '@/utils/im/index.js'
|
||||
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
|
||||
import imBase from '../../mixins/imBase.js'
|
||||
|
||||
export default {
|
||||
mixins: [
|
||||
imBase
|
||||
],
|
||||
props: {
|
||||
conversationType: {
|
||||
type: Number,
|
||||
@@ -19,21 +32,14 @@
|
||||
targetId: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
inputTxt: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
disabled() {
|
||||
return this.inputTxt.length === 0
|
||||
},
|
||||
sender() {
|
||||
return this.$store.getters.sender
|
||||
}
|
||||
},
|
||||
created() {
|
||||
mounted() {
|
||||
RongIMLib.getTextMessageDraft(this.conversationType, this.targetId, ({
|
||||
draft
|
||||
}) => {
|
||||
@@ -41,38 +47,41 @@
|
||||
})
|
||||
},
|
||||
beforeDestroy() {
|
||||
RongIMLib.saveTextMessageDraft(this.conversationType, this.targetId, this.inputTxt, (res) => {
|
||||
console.log('销毁组件之前,保存草稿信息,但是没有执行', res);
|
||||
})
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
focusState: false,
|
||||
}
|
||||
// 保存草稿
|
||||
RongIMLib.saveTextMessageDraft(this.conversationType, this.targetId, this.inputTxt)
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
focusState: false,
|
||||
inputTxt: ''
|
||||
}
|
||||
},
|
||||
created(){
|
||||
uni.$on('emojiValue', res => {
|
||||
this.inputTxt = res.value
|
||||
})
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 发送文本消息
|
||||
sent() {
|
||||
sent() {
|
||||
if (!this.disabled) {
|
||||
RongIMLib.clearTextMessageDraft(this.conversationType, this.targetId)
|
||||
im.sentText(this.conversationType, this.targetId, this.inputTxt, this.sender, () => {
|
||||
RongIMLib.clearTextMessageDraft(this.conversationType, this.targetId)
|
||||
this.$emit('success')
|
||||
this.inputTxt = ''
|
||||
})
|
||||
}
|
||||
},
|
||||
demo(){
|
||||
console.log(this.focusState)
|
||||
|
||||
this.focusState = !this.focusState
|
||||
},
|
||||
focus() {
|
||||
this.$emit('focus')
|
||||
this.$emit('focus')
|
||||
},
|
||||
blur() {
|
||||
blur(e) {
|
||||
uni.hideKeyboard()
|
||||
this.$emit('blur')
|
||||
this.$emit('blur', e.detail)
|
||||
}
|
||||
},
|
||||
destroyed() {
|
||||
uni.$off('emojiValue')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -82,11 +91,10 @@
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
|
||||
.input {
|
||||
background: #F3F6FB;
|
||||
height: 70rpx;
|
||||
width: 500rpx;
|
||||
width: 400rpx;
|
||||
border-radius: 10rpx;
|
||||
margin-right: 15rpx;
|
||||
padding: 0 20rpx;
|
||||
301
pages/im/components/sent/sentVoice.vue
Normal file
301
pages/im/components/sent/sentVoice.vue
Normal file
@@ -0,0 +1,301 @@
|
||||
<template>
|
||||
<view class="send--voice">
|
||||
<view class="voice" hover-class="chat-hover" @touchstart="startRecord" @touchend="stopRecord" @touchmove="touchmove">
|
||||
<text class="button">按住 说话</text>
|
||||
</view>
|
||||
<!-- 录音层 -->
|
||||
<view class="lay" v-if="showRecordTip">
|
||||
<view class="lay-header">
|
||||
<view class="modal">
|
||||
<image class="icon" src="@/static/icon/record-icon.png" mode="widthFix"></image>
|
||||
<text class="text">录音中 {{recordTime}} s</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="lay-toast">上滑取消</view>
|
||||
<view class="lay-footer">
|
||||
<image class="lay-footer-icon videoFlicker" src="@/static/icon/audio_green.png" mode="widthFix"></image>
|
||||
<view class="lay-footer-text">松开发送</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import im from '@/utils/im/index.js'
|
||||
import permision from '@/utils/permission.js'
|
||||
import imBase from '../../mixins/imBase.js'
|
||||
|
||||
export default {
|
||||
mixins: [
|
||||
imBase
|
||||
],
|
||||
props: {
|
||||
conversationType: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
targetId: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showRecordTip: false,
|
||||
recordTime: 60,
|
||||
interval: 0,
|
||||
maxRecordTime: 60,
|
||||
recorderManager: null,
|
||||
mp3AudioSrc: null,
|
||||
isMoveCancel: false,
|
||||
isBetaPlay: false, // 暂时无用
|
||||
startOffsetTop: 0
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
sender() {
|
||||
return this.$store.getters.sender
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.recorderManager = uni.getRecorderManager()
|
||||
},
|
||||
methods: {
|
||||
// 检查安卓录制权限
|
||||
async getAndroidPermission() {
|
||||
return await permision.requestAndroidPermission('android.permission.RECORD_AUDIO')
|
||||
},
|
||||
// 录制语音消息
|
||||
startRecord(e) {
|
||||
this.getAndroidPermission().then(code => {
|
||||
switch (code) {
|
||||
case 1:
|
||||
this.startOffsetTop = e.target.offsetTop
|
||||
this.showRecordTip = true
|
||||
this.recorderManager.start()
|
||||
this.interval = setInterval(() => {
|
||||
this.recordTime -= 1
|
||||
if (this.recordTime === 0) {
|
||||
this.stopRecord()
|
||||
}
|
||||
}, 1000)
|
||||
break;
|
||||
case 0:
|
||||
uni.showToast({
|
||||
title: '暂无麦克风权限,请前往应用设置开启麦克风',
|
||||
icon: 'none'
|
||||
})
|
||||
break;
|
||||
case -1:
|
||||
uni.showToast({
|
||||
title: '应用权限错误',
|
||||
icon: 'none'
|
||||
})
|
||||
break;
|
||||
}
|
||||
})
|
||||
},
|
||||
// 结束录音
|
||||
stopRecord(e) {
|
||||
if (!this.showRecordTip) return
|
||||
// 延迟500毫秒结束录音
|
||||
setTimeout(()=> {
|
||||
this.recorderManager.stop()
|
||||
clearInterval(this.interval)
|
||||
// 监听录音结束
|
||||
this.recorderManager.onStop(res => {
|
||||
if(this.isMoveCancel) {
|
||||
this.isMoveCancel = false
|
||||
return
|
||||
}
|
||||
if((this.maxRecordTime - this.recordTime) <= 0){
|
||||
uni.showToast({
|
||||
title: '说话时间太短',
|
||||
icon : 'none',
|
||||
})
|
||||
this.showRecordTip = false
|
||||
return
|
||||
}
|
||||
this.mp3AudioSrc = res.tempFilePath
|
||||
this.showRecordTip = false
|
||||
this.senVoice()
|
||||
})
|
||||
},500)
|
||||
},
|
||||
// 发送语音消息
|
||||
senVoice(){
|
||||
if(this.mp3AudioSrc === null) {
|
||||
uni.showToast({
|
||||
title: '发送失败, 暂无音频信息',
|
||||
icon : 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
im.sentVoice(this.conversationType, this.targetId, this.mp3AudioSrc, (this.maxRecordTime -
|
||||
this.recordTime), this.sender, () => {
|
||||
this.recordTime = this.maxRecordTime
|
||||
this.mp3AudioSrc = null
|
||||
setTimeout(() => {
|
||||
this.$emit('success')
|
||||
this.toastAudiMp3()
|
||||
}, 500)
|
||||
})
|
||||
},
|
||||
// 移动按钮
|
||||
touchmove(e){
|
||||
if(this.startOffsetTop - e.changedTouches[0].pageY > 100){
|
||||
if(this.showRecordTip){
|
||||
this.isMoveCancel = true
|
||||
this.showRecordTip = false
|
||||
this.recorderManager.stop()
|
||||
clearInterval(this.interval)
|
||||
this.recordTime = this.maxRecordTime
|
||||
this.mp3AudioSrc = null
|
||||
return
|
||||
}
|
||||
}
|
||||
},
|
||||
// 试听语音
|
||||
startPlay() {
|
||||
let betaAudio = uni.createInnerAudioContext()
|
||||
betaAudio.src = this.mp3AudioSrc;
|
||||
// 在播放中
|
||||
if(this.isBetaPlay){
|
||||
betaAudio.stop()
|
||||
betaAudio.onStop(() => {
|
||||
this.isBetaPlay = false;
|
||||
betaAudio.destroy()
|
||||
})
|
||||
return
|
||||
}
|
||||
// 监听音频播放中
|
||||
betaAudio.play()
|
||||
betaAudio.onPlay(() => {
|
||||
this.isBetaPlay = true;
|
||||
})
|
||||
// 监听音频结束
|
||||
betaAudio.onEnded(() => {
|
||||
this.isBetaPlay = false;
|
||||
betaAudio.destroy()
|
||||
})
|
||||
},
|
||||
// 播放提示音乐
|
||||
toastAudiMp3(){
|
||||
let toastAudio = uni.createInnerAudioContext()
|
||||
toastAudio.src = require('@/static/im/toast/sentVoice.mp3')
|
||||
toastAudio.autoplay = true
|
||||
toastAudio.volume = .1
|
||||
toastAudio.onEnded(() => {
|
||||
toastAudio.destroy()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@keyframes playFlicker {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
50% {
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.videoFlicker {
|
||||
animation: playFlicker 1s infinite;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.send--voice {
|
||||
.voice {
|
||||
display: flex;
|
||||
background: $window-color;
|
||||
height: 70rpx;
|
||||
line-height: 70rpx;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 400rpx;
|
||||
border-radius: 10rpx;
|
||||
margin-right: 15rpx;
|
||||
padding: 0 20rpx;
|
||||
font-weight: bold;
|
||||
.button {
|
||||
font-size: 30rpx;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
.lay{
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 9;
|
||||
background: rgba($color: #000000, $alpha: .5);
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
box-sizing: border-box;
|
||||
.lay-header{
|
||||
height: calc(100vh - 140px);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
.modal {
|
||||
display: flex;
|
||||
background: rgba(0, 0, 0, .6);
|
||||
position: fixed;
|
||||
height: 200rpx;
|
||||
width: 300rpx;
|
||||
border-radius: 10rpx;
|
||||
z-index: 99;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
.icon {
|
||||
width: 88rpx;
|
||||
height: 88rpx;
|
||||
}
|
||||
|
||||
.text {
|
||||
font-size: 28rpx;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
.lay-toast{
|
||||
text-align: center;
|
||||
color: rgba($color: #fff, $alpha: .8);
|
||||
font-size: 28rpx;
|
||||
}
|
||||
.lay-footer{
|
||||
background-color: white;
|
||||
height: 100px;
|
||||
border-radius: 50% 50% 0 0;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
.lay-footer-icon{
|
||||
width: 58rpx;
|
||||
height: 58rpx;
|
||||
}
|
||||
.lay-footer-text{
|
||||
line-height: 40rpx;
|
||||
color: gray;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -7,18 +7,27 @@
|
||||
<image class="icon" src="@/static/icon/msg-icon.png" v-if="chatType === 1" mode="widthFix" />
|
||||
</view>
|
||||
<sent-voice v-if="chatType === 0" :conversationType="conversationType" :targetId="targetId" @success="onSuccess" />
|
||||
<sent-text v-if="chatType === 1" :conversationType="conversationType" :targetId="targetId" @success="onSuccess" />
|
||||
<view class="msg-type msg-popups" @click="showPopups = !showPopups"> <image class="icon" src="@/static/icon/popups-icon.png" /> </view>
|
||||
<sent-text ref="textView" v-if="chatType === 1" :conversationType="conversationType" :targetId="targetId" @success="onSuccess" @blur="onBlur" />
|
||||
<view class="msg-type msg-popups" @click="onShowEmoji">
|
||||
<image class="icon" src="@/static/icon/emoji-icon.png" />
|
||||
<!-- 考虑唤起键盘,暂时保留v-show -->
|
||||
<!-- <image v-show="!showEmoji" class="icon" src="@/static/icon/emoji-icon.png" /> -->
|
||||
<!-- <image v-show="showEmoji" class="icon" src="@/static/icon/key-icon.png" /> -->
|
||||
</view>
|
||||
<view class="msg-type msg-popups" @click="() => {showPopups = !showPopups, showEmoji = false}"> <image class="icon" src="@/static/icon/popups-icon.png" /> </view>
|
||||
</view>
|
||||
<!-- 弹出层 -->
|
||||
<sent-popups :show="showPopups" :conversationType="conversationType" :targetId="targetId" @success="() => {showPopups = false, onSuccess()}" />
|
||||
<sent-popups :show="showPopups" :conversationType="conversationType" :targetId="targetId" @success="() => {showPopups = false, onSuccess()}" />
|
||||
<!-- 表情包 -->
|
||||
<sent-emoji :show="showEmoji" @onEmoji="onEmoji" @delete="onDelete" @sent="onSent"></sent-emoji>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import sentText from '../components/sentText'
|
||||
import sentVoice from '../components/sentVoice'
|
||||
import sentPopups from '../components/sentPopups'
|
||||
import sentText from './sent/sentText'
|
||||
import sentVoice from './sent/sentVoice'
|
||||
import sentPopups from './sent/sentPopups'
|
||||
import sentEmoji from './sent/sentEmoji'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
@@ -34,18 +43,26 @@
|
||||
components: {
|
||||
sentText,
|
||||
sentVoice,
|
||||
sentPopups
|
||||
sentPopups,
|
||||
sentEmoji
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
chatType: 1, // 0 语音,1 文本
|
||||
showPopups: false
|
||||
chatType : 1, // 0 语音,1 文本
|
||||
showPopups : false,
|
||||
showEmoji : false,
|
||||
chatText : {
|
||||
value : "",
|
||||
cursor : 0
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 切换聊天类型,语音/文本
|
||||
changeMessageType() {
|
||||
this.chatType = this.chatType === 1 ? 0 : 1
|
||||
this.chatType = this.chatType === 1 ? 0 : 1
|
||||
if(this.showEmoji) this.showEmoji = false
|
||||
if(this.showPopups) this.showPopups = false
|
||||
},
|
||||
onSuccess() {
|
||||
this.$emit('onSuccess')
|
||||
@@ -55,6 +72,39 @@
|
||||
if(this.showPopups){
|
||||
this.showPopups = false
|
||||
}
|
||||
},
|
||||
// 输入表情
|
||||
onEmoji(e){
|
||||
let atMsg = this.chatText
|
||||
let newMsg = () => {
|
||||
return atMsg.value.slice(0, atMsg.cursor) + e.emoji + atMsg.value.slice(atMsg.cursor)
|
||||
}
|
||||
atMsg.value = newMsg()
|
||||
atMsg.cursor += 2
|
||||
// 全局通讯
|
||||
uni.$emit('emojiValue', atMsg)
|
||||
},
|
||||
// 删除表情
|
||||
onDelete(){
|
||||
console.log('删除')
|
||||
},
|
||||
// 发送消息
|
||||
onSent(){
|
||||
this.$refs.textView.sent()
|
||||
this.chatText = {
|
||||
value : "",
|
||||
cursor : 0
|
||||
}
|
||||
},
|
||||
// 获取输入框文字最新状态
|
||||
onBlur(e){
|
||||
this.chatText = e
|
||||
},
|
||||
// 显示emoji表情
|
||||
onShowEmoji(){
|
||||
this.showEmoji = !this.showEmoji
|
||||
this.chatType = 1
|
||||
if(this.showPopups) this.showPopups = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,143 +0,0 @@
|
||||
<template>
|
||||
<view class="send--voice">
|
||||
<view class="voice" hover-class="chat-hover" @touchstart="startRecord" @touchend="stopRecord">
|
||||
<text class="button">按住说话</text>
|
||||
</view>
|
||||
<!-- 录音中提示 -->
|
||||
<view class="modal" v-if="showRecordTip">
|
||||
<image class="icon" src="@/static/icon/record-icon.png" mode="widthFix"></image>
|
||||
<text class="text">录音中 {{recordTime}} s</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import im from '@/utils/im/index.js'
|
||||
import permision from '@/utils/permission.js'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
conversationType: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
targetId: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showRecordTip: false,
|
||||
recordTime: 60,
|
||||
interval: 0,
|
||||
maxRecordTime: 60,
|
||||
recorderManager: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
sender() {
|
||||
return this.$store.getters.sender
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.recorderManager = uni.getRecorderManager()
|
||||
},
|
||||
methods: {
|
||||
// 检查安卓录制权限
|
||||
async getAndroidPermission() {
|
||||
return await permision.requestAndroidPermission('android.permission.RECORD_AUDIO')
|
||||
},
|
||||
// 录制语音消息
|
||||
startRecord() {
|
||||
this.getAndroidPermission().then(code => {
|
||||
switch (code) {
|
||||
case 1:
|
||||
this.showRecordTip = true
|
||||
this.recorderManager.start()
|
||||
this.interval = setInterval(() => {
|
||||
this.recordTime -= 1
|
||||
if (this.recordTime === 0) {
|
||||
this.stopRecord()
|
||||
}
|
||||
}, 1000)
|
||||
break;
|
||||
case 0:
|
||||
uni.showToast({
|
||||
title: '暂无麦克风权限,请前往应用设置开启麦克风',
|
||||
icon: 'none'
|
||||
})
|
||||
break;
|
||||
case -1:
|
||||
uni.showToast({
|
||||
title: '应用权限错误',
|
||||
icon: 'none'
|
||||
})
|
||||
break;
|
||||
}
|
||||
})
|
||||
},
|
||||
// 结束录音
|
||||
stopRecord(e) {
|
||||
if (!this.showRecordTip) return
|
||||
this.recorderManager.stop()
|
||||
clearInterval(this.interval)
|
||||
// 监听录音结束
|
||||
this.recorderManager.onStop(res => {
|
||||
im.sentVoice(this.conversationType, this.targetId, res.tempFilePath, (this.maxRecordTime -
|
||||
this.recordTime), this.sender, () => {
|
||||
setTimeout(() => {
|
||||
this.$emit('success')
|
||||
}, 500)
|
||||
})
|
||||
this.recordTime = this.maxRecordTime
|
||||
this.showRecordTip = false
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.send--voice {
|
||||
.voice {
|
||||
background: $window-color;
|
||||
height: 70rpx;
|
||||
line-height: 70rpx;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 500rpx;
|
||||
border-radius: 10rpx;
|
||||
margin-right: 15rpx;
|
||||
|
||||
.button {
|
||||
font-size: 30rpx;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.modal {
|
||||
background: rgba(0, 0, 0, .6);
|
||||
position: fixed;
|
||||
height: 200rpx;
|
||||
width: 300rpx;
|
||||
border-radius: 10rpx;
|
||||
z-index: 99;
|
||||
top: 550rpx;
|
||||
left: 225rpx;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.icon {
|
||||
width: 88rpx;
|
||||
height: 88rpx;
|
||||
}
|
||||
|
||||
.text {
|
||||
font-size: 28rpx;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
75
pages/im/components/show/messageState.vue
Normal file
75
pages/im/components/show/messageState.vue
Normal file
@@ -0,0 +1,75 @@
|
||||
<template>
|
||||
<view v-if="!isRemote">
|
||||
<view class="state" v-if="isGroup">
|
||||
<!-- 已发送 -->
|
||||
<uni-icons class="sent" type="checkmarkempty" size="28rpx" :color="message.sentStatus >= 30 ? '#34CE98' : '#999999'" />
|
||||
<text class="readers">{{ readers }}</text>
|
||||
</view>
|
||||
<view class="state" v-else>
|
||||
<uni-icons class="sent" type="checkmarkempty" size="28rpx" :color="message.sentStatus >= 30 ? '#34CE98' : '#999999'" />
|
||||
<uni-icons class="receive" type="checkmarkempty" size="28rpx" :color="message.sentStatus >= 50 ? '#34CE98' : '#999999'" />
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
|
||||
import utils from '@/utils/index.js'
|
||||
|
||||
export default {
|
||||
name: 'showText',
|
||||
props: {
|
||||
message: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
isGroup: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
isRemote: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
iconSize() {
|
||||
return utils.rpx2px(28)
|
||||
},
|
||||
readers() {
|
||||
if (this.message.extra) {
|
||||
return JSON.parse(this.message.extra).readers || 0
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.state {
|
||||
padding: 10rpx;
|
||||
border-radius: 30rpx;
|
||||
background-color: #ddd;
|
||||
display: flex;
|
||||
margin-right: 10rpx;
|
||||
|
||||
.sent {
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.receive {
|
||||
z-index: 1;
|
||||
margin-left: -20rpx;
|
||||
}
|
||||
|
||||
.readers {
|
||||
font-size: 20rpx;
|
||||
margin-left: -6rpx;
|
||||
color: $text-gray-m;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
91
pages/im/components/show/showCall.vue
Normal file
91
pages/im/components/show/showCall.vue
Normal file
@@ -0,0 +1,91 @@
|
||||
<template>
|
||||
<view class="msg--call">
|
||||
<view class="name" v-if="isGroup && isRemote">{{ contact(message.senderUserId).name }}</view>
|
||||
<view class="im--text" :class="isRemote ? 'left': 'right'">
|
||||
<uni-icons type="videocam" size="44rpx" v-if="msg.mediaType == 1" />
|
||||
<uni-icons type="phone" size="40rpx" v-else />
|
||||
{{ label }}
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import utils from '@/utils/index.js'
|
||||
import moment from 'moment'
|
||||
import imBase from '../../mixins/imBase.js'
|
||||
|
||||
export default {
|
||||
mixins: [
|
||||
imBase
|
||||
],
|
||||
name: 'showText',
|
||||
props: {
|
||||
message: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
isGroup: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
},
|
||||
computed: {
|
||||
msg() {
|
||||
return JSON.parse(this.message.content.message)
|
||||
},
|
||||
label() {
|
||||
return this.msg.connected ? '通话时长:' + duration : '未接通'
|
||||
},
|
||||
isRemote() {
|
||||
return this.message.messageDirection == 2
|
||||
},
|
||||
duration() {
|
||||
if (this.message.duration > 3600) {
|
||||
return moment.utc(this.message.duration * 1000).format('HH:mm:ss')
|
||||
} else {
|
||||
return moment.utc(this.message.duration * 1000).format('mm:ss')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.msg--call {
|
||||
.name {
|
||||
font-size: 26rpx;
|
||||
color: $text-gray-m;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.im--text {
|
||||
max-width: 508rpx;
|
||||
padding: 20rpx;
|
||||
line-height: 46rpx;
|
||||
font-size: 32rpx;
|
||||
color: $text-color;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
&.left {
|
||||
border-radius: 0 20rpx 20rpx 20rpx;
|
||||
background: white;
|
||||
}
|
||||
|
||||
&.right {
|
||||
border-radius: 20rpx 0 20rpx 20rpx;
|
||||
background: $main-color;
|
||||
color: white;
|
||||
|
||||
.uni-icons {
|
||||
color: white !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
105
pages/im/components/show/showImage.vue
Normal file
105
pages/im/components/show/showImage.vue
Normal file
@@ -0,0 +1,105 @@
|
||||
<template>
|
||||
<view class="msg--image">
|
||||
<message-state :message="message" :isGroup="isGroup" :isRemote="isRemote" />
|
||||
|
||||
<view class="">
|
||||
<view class="name" v-if="isGroup && isRemote">{{ contact(message.senderUserId).name }}</view>
|
||||
<view class="image" :class="isRemote ? 'left': 'right'">
|
||||
<image class="img" :src="content.thumbnail" @click="previewImage" mode="widthFix"></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
|
||||
import messageState from './messageState'
|
||||
import imBase from '../../mixins/imBase.js'
|
||||
|
||||
export default {
|
||||
mixins: [
|
||||
imBase
|
||||
],
|
||||
name: 'showImage',
|
||||
props: {
|
||||
message: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
isGroup: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
components: {
|
||||
messageState
|
||||
},
|
||||
computed: {
|
||||
isRemote() {
|
||||
return this.message.messageDirection == 2
|
||||
},
|
||||
content() {
|
||||
return this.message.content
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
showImage(path) {
|
||||
uni.previewImage({
|
||||
urls: [
|
||||
path
|
||||
]
|
||||
})
|
||||
},
|
||||
previewImage() {
|
||||
if (this.content.local && this.content.local.indexOf('///data/user/') < 0) {
|
||||
this.showImage(this.content.local)
|
||||
} else {
|
||||
this.showImage(this.content.remote)
|
||||
RongIMLib.downloadMediaMessage(this.message.messageId, {
|
||||
success: (path) => {
|
||||
this.content.local = path
|
||||
},
|
||||
error: (errorCode, messageId) => {
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: errorCode
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.msg--image {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
|
||||
.name {
|
||||
font-size: 24rpx;
|
||||
color: $text-gray-m;
|
||||
}
|
||||
|
||||
.image {
|
||||
.img {
|
||||
width: 180rpx;
|
||||
}
|
||||
|
||||
&.left {
|
||||
.img {
|
||||
border-radius: 0 10rpx 10rpx 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
&.right {
|
||||
.img {
|
||||
border-radius: 10rpx 0 10rpx 10rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
78
pages/im/components/show/showText.vue
Normal file
78
pages/im/components/show/showText.vue
Normal file
@@ -0,0 +1,78 @@
|
||||
<template>
|
||||
<view class="msg--text">
|
||||
<message-state :message="message" :isGroup="isGroup" :isRemote="isRemote" />
|
||||
|
||||
<view class="">
|
||||
<view class="name" v-if="isGroup && isRemote">{{ contact(message.senderUserId).name }}</view>
|
||||
<view :class="['text', isRemote ? 'left': 'right']">{{ content }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import messageState from './messageState'
|
||||
import imBase from '../../mixins/imBase.js'
|
||||
|
||||
export default {
|
||||
name: 'showText',
|
||||
mixins: [
|
||||
imBase,
|
||||
],
|
||||
props: {
|
||||
message: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
isGroup: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
components: {
|
||||
messageState
|
||||
},
|
||||
computed: {
|
||||
isRemote() {
|
||||
return this.message.messageDirection == 2
|
||||
},
|
||||
content() {
|
||||
return this.message.content.content
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.msg--text {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
|
||||
.name {
|
||||
font-size: 24rpx;
|
||||
color: $text-gray-m;
|
||||
}
|
||||
|
||||
.text {
|
||||
box-sizing: border-box;
|
||||
max-width: 502rpx;
|
||||
padding: 20rpx 24rpx;
|
||||
line-height: 46rpx;
|
||||
font-size: 32rpx;
|
||||
color: $text-color;
|
||||
word-break: break-all;
|
||||
|
||||
&.left {
|
||||
border-radius: 0 20rpx 20rpx 20rpx;
|
||||
background: white;
|
||||
}
|
||||
|
||||
&.right {
|
||||
border-radius: 20rpx 0 20rpx 20rpx;
|
||||
background: $main-color;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
247
pages/im/components/show/showVoice.vue
Normal file
247
pages/im/components/show/showVoice.vue
Normal file
@@ -0,0 +1,247 @@
|
||||
<template>
|
||||
<view class="msg--voice">
|
||||
<message-state :message="message" :isGroup="isGroup" :isRemote="isRemote" />
|
||||
|
||||
<view class="">
|
||||
<view class="name" v-if="isGroup && isRemote">{{ contact(message.senderUserId).name }}</view>
|
||||
<view class="msg-voice">
|
||||
<view :class="['voice', isRemote ? 'left': 'right', {'onPlay': onPlay}]" :style="{width: width + 'rpx'}"
|
||||
@click="startPlay">
|
||||
<image v-if="isRemote" class="icon"
|
||||
:class="{ 'videoFlicker' : onPlay && msgId == message.messageId }"
|
||||
src="@/static/icon/audio_green.png" mode="widthFix"></image>
|
||||
<image v-else class="icon" :class="{ 'videoFlicker' : onPlay && msgId == message.messageId }"
|
||||
src="@/static/icon/audio_white.png" mode="widthFix"></image>
|
||||
<text class="duration">{{ duration }}"</text>
|
||||
</view>
|
||||
<u-badge isDot :show="message.content.local =='' && isRemote" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
|
||||
import messageState from './messageState'
|
||||
import imBase from '../../mixins/imBase.js'
|
||||
|
||||
export default {
|
||||
mixins: [
|
||||
imBase
|
||||
],
|
||||
props: {
|
||||
message: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
isGroup: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
components: {
|
||||
messageState
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
onPlay: false,
|
||||
innerAC: null,
|
||||
msgId: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
duration() {
|
||||
return this.message.content.duration
|
||||
},
|
||||
isRemote() {
|
||||
return this.message.messageDirection == 2
|
||||
},
|
||||
width() {
|
||||
if (this.duration > 3) {
|
||||
return (this.duration * 5) + 150
|
||||
} else {
|
||||
return 120
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
// 这样能临时解决,但是会一直监听
|
||||
uni.$on('onVoiceMessagePlay', (messageId) => {
|
||||
if (this.message.messageId != messageId) {
|
||||
this.stopPlay()
|
||||
}
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
// 播放语音消息
|
||||
startPlay() {
|
||||
// 如果是正在播放的,停止当前播放
|
||||
if (this.onPlay) {
|
||||
this.stopPlay()
|
||||
return
|
||||
}
|
||||
this.onPlay = true
|
||||
// 如果下载到了本地,那么直接播放,否则调用下载语音消息接口,下载后再播放
|
||||
if (this.message.content.local && this.message.content.local.indexOf('///data/user/') < 0) {
|
||||
this.playVoice(this.message.content.local)
|
||||
} else {
|
||||
RongIMLib.downloadMediaMessage(this.message.messageId, {
|
||||
success: (path) => {
|
||||
this.message.content.local = path
|
||||
this.playVoice(path)
|
||||
},
|
||||
progress: (progress, messageId) => {},
|
||||
cancel: (messageId) => {},
|
||||
error: (errorCode, messageId) => {
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: '语音播放失败'
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
playVoice(path) {
|
||||
console.log('准备播放', this.message.content);
|
||||
this.innerAC = uni.createInnerAudioContext()
|
||||
this.innerAC.src = path
|
||||
this.innerAC.autoplay = false
|
||||
this.msgId = this.message.messageId
|
||||
this.innerAC.onCanplay(res => {
|
||||
console.log('onCanplay')
|
||||
this.innerAC.play()
|
||||
})
|
||||
this.innerAC.onPlay(res => {
|
||||
console.log('onPlay')
|
||||
uni.$emit('onVoiceMessagePlay', this.message.messageId)
|
||||
})
|
||||
this.innerAC.onEnded(res => {
|
||||
this.innerAC.stop()
|
||||
})
|
||||
this.innerAC.onStop(() => {
|
||||
this.onPlay = false
|
||||
this.innerAC.destroy()
|
||||
this.innerAC = null
|
||||
this.msgId = null
|
||||
uni.$emit('onVoiceMessageStop', this.message.messageId)
|
||||
})
|
||||
this.innerAC.onError(err => {
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: '语音播放失败'
|
||||
})
|
||||
})
|
||||
},
|
||||
stopPlay() {
|
||||
if (this.innerAC) {
|
||||
this.innerAC.stop()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@keyframes playFlicker {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
50% {
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.videoFlicker {
|
||||
animation: playFlicker 1s infinite;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.msg--voice {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
|
||||
.state {
|
||||
padding: 10rpx;
|
||||
border-radius: 30rpx;
|
||||
width: 40rpx;
|
||||
background-color: #ddd;
|
||||
display: flex;
|
||||
margin-right: 10rpx;
|
||||
|
||||
.sent {
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.receive {
|
||||
z-index: 1;
|
||||
margin-left: -20rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.name {
|
||||
font-size: 24rpx;
|
||||
color: $text-gray-m;
|
||||
}
|
||||
|
||||
.msg-voice {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.u-badge {
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
|
||||
.voice {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 84rpx;
|
||||
padding: 0 30rpx;
|
||||
box-sizing: border-box;
|
||||
|
||||
.icon {
|
||||
width: 38rpx;
|
||||
height: 38rpx;
|
||||
}
|
||||
|
||||
&.left {
|
||||
border-radius: 0 20rpx 20rpx 20rpx;
|
||||
background: white;
|
||||
|
||||
&.onPlay {
|
||||
background-color: #EEEEEE;
|
||||
}
|
||||
|
||||
.duration {
|
||||
color: #333;
|
||||
font-size: 30rpx;
|
||||
}
|
||||
}
|
||||
|
||||
&.right {
|
||||
border-radius: 20rpx 0 20rpx 20rpx;
|
||||
background: $main-color;
|
||||
flex-direction: row-reverse;
|
||||
|
||||
&.onPlay {
|
||||
background-color: darken($main-color, 10);
|
||||
}
|
||||
|
||||
.duration {
|
||||
color: white;
|
||||
font-size: 30rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,74 +0,0 @@
|
||||
<template>
|
||||
<view class="">
|
||||
<text class="name" v-if="!guest && name">{{ name }}</text>
|
||||
<view class="msg--image" :class="guest ? 'right': 'left'">
|
||||
<image class="img" :src="msg.thumbnail" @click="previewImage" mode="widthFix"></image>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'showImage',
|
||||
props: {
|
||||
msg: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {
|
||||
local: '',
|
||||
remote: '',
|
||||
objectName: '',
|
||||
thumbnail: '',
|
||||
isFull: false
|
||||
}
|
||||
}
|
||||
},
|
||||
guest: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
name: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
previewImage() {
|
||||
uni.previewImage({
|
||||
urls: [
|
||||
this.msg.remote
|
||||
],
|
||||
current: 1
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.name {
|
||||
font-size: 24rpx;
|
||||
line-height: 34rpx;
|
||||
color: $text-gray-m;
|
||||
padding-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.msg--image {
|
||||
// padding: 20rpx;
|
||||
|
||||
&.left {
|
||||
border-radius: 0 20rpx 20rpx 20rpx;
|
||||
// background: white;
|
||||
}
|
||||
|
||||
&.right {
|
||||
border-radius: 20rpx 0 20rpx 20rpx;
|
||||
// background: #34CE98;
|
||||
}
|
||||
|
||||
.img {
|
||||
width: 150rpx;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
146
pages/im/components/showMessageCell.vue
Normal file
146
pages/im/components/showMessageCell.vue
Normal file
@@ -0,0 +1,146 @@
|
||||
<template>
|
||||
<view class="">
|
||||
<view class="notify" v-if="message.objectName === 'RC:GrpNtf'">
|
||||
{{ message.content.message }}
|
||||
<text class="link" @click="toAnnounce(message)" v-if="message.content.operation == 'ANNOUNCEMENT'">点击查看
|
||||
</text>
|
||||
</view>
|
||||
<view class="notify" v-else-if="message.objectName === 'RC:RcNtf'">
|
||||
{{ contact(message.senderUserId).name }} 撤回了一条消息
|
||||
</view>
|
||||
<view v-else :class="['cell-item', message.messageDirection == 1 ? 'right' : 'left']">
|
||||
<u-avatar class="avatar" @click="toUser(message)" :size="avatarSize" shape="square"
|
||||
:src="contact(message.senderUserId).portraitUrl" />
|
||||
<view class="msg" @longpress="messageAction($event, message)">
|
||||
<show-text v-if="message.objectName === 'RC:TxtMsg'" :message="message" :isGroup="isGroup" />
|
||||
<show-voice v-else-if="message.objectName === 'RC:HQVCMsg'" :message="message" :isGroup="isGroup" />
|
||||
<show-image v-else-if="message.objectName === 'RC:ImgMsg'" :message="message" :isGroup="isGroup" />
|
||||
<show-call v-else-if="message.objectName === 'RC:InfoNtf'" :message="message" :isGroup="isGroup" />
|
||||
<view v-else class="">
|
||||
[未处理的消息类型 {{ message.objectName }}]
|
||||
</view>
|
||||
</view>
|
||||
<!-- <view class="time">{{ item.sentTime|timeCustomCN }}</view> 时间判断,最好是隔一段时间没有消息才展示一个 -->
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getGroupAnnouncement
|
||||
} from '@/apis/interfaces/im.js'
|
||||
import * as IMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
|
||||
import showVoice from './show/showVoice'
|
||||
import showImage from './show/showImage'
|
||||
import showText from './show/showText'
|
||||
import showCall from './show/showCall'
|
||||
import utils from '@/utils/index.js'
|
||||
import imBase from '../mixins/imBase.js'
|
||||
|
||||
export default {
|
||||
mixins: [
|
||||
imBase
|
||||
],
|
||||
components: {
|
||||
showCall,
|
||||
showVoice,
|
||||
showImage,
|
||||
showText
|
||||
},
|
||||
props: {
|
||||
message: {
|
||||
type: Object,
|
||||
default: function() {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
isGroup: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
messageAction(event, message) {
|
||||
this.$emit('messageAction', {
|
||||
event,
|
||||
message
|
||||
})
|
||||
},
|
||||
toUser(item) {
|
||||
if (item.messageDirection == 1) {
|
||||
uni.navigateTo({
|
||||
url: '/pages/im/friends/mine?targetId=' + item.senderUserId
|
||||
})
|
||||
} else {
|
||||
uni.navigateTo({
|
||||
url: '/pages/im/friends/info?targetId=' + item.senderUserId
|
||||
})
|
||||
}
|
||||
},
|
||||
// 跳转群公告
|
||||
toAnnounce(message) {
|
||||
if (message.content.extra) {
|
||||
getGroupAnnouncement(message.targetId, message.content.extra).then(res => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/im/group/announceCreate?type=check&targetId=' + message
|
||||
.targetId + '&aId=' + message.content.extra
|
||||
})
|
||||
}).catch(err => {
|
||||
IMLib.deleteMessagesByIds([message.messageId], ({
|
||||
code
|
||||
}) => {
|
||||
if (code === 0) {
|
||||
uni.$emit('remove_message_' + message.targetId, message.messageId)
|
||||
}
|
||||
})
|
||||
uni.showToast({
|
||||
title: '公告不存在或已删除',
|
||||
icon: 'none',
|
||||
})
|
||||
})
|
||||
} else {
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: '旧版本,无链接'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.notify {
|
||||
text-align: center;
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
|
||||
.link {
|
||||
color: $main-color;
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.cell-item {
|
||||
display: flex;
|
||||
width: 710rpx;
|
||||
justify-content: flex-start;
|
||||
|
||||
&.left {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
&.right {
|
||||
flex-direction: row-reverse;
|
||||
|
||||
.state {
|
||||
flex-direction: row;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
|
||||
.msg {
|
||||
margin: 0 20rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,58 +0,0 @@
|
||||
<template>
|
||||
<view class="msg--text">
|
||||
<text class="name" v-if="!guest && name">{{ name }}</text>
|
||||
<view>
|
||||
<text class="im--text" :class="guest ? 'right': 'left'">{{ msg.content }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'showText',
|
||||
props: {
|
||||
msg: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
name: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
guest: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.msg--text {
|
||||
.name {
|
||||
font-size: 26rpx;
|
||||
color: $text-gray-m;
|
||||
display: inline-block;
|
||||
}
|
||||
.im--text {
|
||||
max-width: 508rpx;
|
||||
padding: 20rpx;
|
||||
line-height: 46rpx;
|
||||
font-size: 32rpx;
|
||||
color: $text-color;
|
||||
display: inline-block;
|
||||
word-break: break-all;
|
||||
&.left {
|
||||
border-radius: 0 20rpx 20rpx 20rpx;
|
||||
background: white;
|
||||
}
|
||||
&.right {
|
||||
border-radius: 20rpx 0 20rpx 20rpx;
|
||||
background: $main-color;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,106 +0,0 @@
|
||||
<template>
|
||||
<view class="">
|
||||
<text class="name" v-if="!guest && name">{{ name }}</text>
|
||||
<view class="msg--voice" :class="guest ? 'right': 'left'" @click="onPlayMsg">
|
||||
<image v-if="!guest" class="icon" src="@/static/icon/audio_green.png" mode="widthFix"></image>
|
||||
<text class="duration">{{msg.duration}}"</text>
|
||||
<image v-if="guest" class="icon" src="@/static/icon/audio_white.png" mode="widthFix"></image>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'showVoice',
|
||||
props: {
|
||||
msg: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {
|
||||
local: '',
|
||||
remote: '',
|
||||
objectName: '',
|
||||
duration: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
name: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
guest: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 播放语音消息
|
||||
onPlayMsg() {
|
||||
uni.downloadFile({
|
||||
url: this.msg.remote,
|
||||
success: (res) => {
|
||||
if (res.statusCode === 200) {
|
||||
let innerAudioContext = uni.createInnerAudioContext()
|
||||
innerAudioContext.src = res.tempFilePath
|
||||
if (this.audioContextPaused) {
|
||||
innerAudioContext.play()
|
||||
this.audioContextPaused = false
|
||||
return
|
||||
}
|
||||
innerAudioContext.stop()
|
||||
innerAudioContext.onStop(resStop => {
|
||||
this.audioContextPaused = true
|
||||
})
|
||||
innerAudioContext.onError(err => {
|
||||
console.log(err);
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.name {
|
||||
font-size: 24rpx;
|
||||
line-height: 34rpx;
|
||||
color: $text-gray-m;
|
||||
}
|
||||
|
||||
.msg--voice {
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 79rpx;
|
||||
width: 170rpx;
|
||||
padding: 0 20rpx;
|
||||
box-sizing: border-box;
|
||||
|
||||
.icon {
|
||||
width: 38rpx;
|
||||
height: 38rpx;
|
||||
}
|
||||
|
||||
&.left {
|
||||
border-radius: 0 20rpx 20rpx 20rpx;
|
||||
background: white;
|
||||
|
||||
.duration {
|
||||
color: #333;
|
||||
font-size: 30rpx;
|
||||
}
|
||||
}
|
||||
|
||||
&.right {
|
||||
border-radius: 20rpx 0 20rpx 20rpx;
|
||||
background: $main-color;
|
||||
|
||||
.duration {
|
||||
color: white;
|
||||
font-size: 30rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -2,32 +2,33 @@
|
||||
<view>
|
||||
<u-index-list :index-list="indexs" inactiveColor="#666" activeColor="#34CE98">
|
||||
<view class="friend-flex" @click="toPending">
|
||||
<u-avatar class="cover" size="40" shape="square" :src="require('@/static/im/im_01.png')"></u-avatar>
|
||||
<u-avatar class="cover" size="40" shape="square" :src="require('@/static/im/im_01.png')" />
|
||||
<u-badge max="99" absolute :offset="[23, 20]" :value="pendingCount" />
|
||||
<view class="info">新的朋友</view>
|
||||
</view>
|
||||
<view class="friend-flex" @click="toGroup">
|
||||
<u-avatar class="cover" size="40" shape="square" :src="require('@/static/im/im_00.png')"></u-avatar>
|
||||
<u-avatar class="cover" size="40" shape="square" :src="require('@/static/im/im_00.png')" />
|
||||
<view class="info">我的群聊</view>
|
||||
</view>
|
||||
<block v-if="friends.length > 0">
|
||||
<u-index-item v-for="(item, fkey) in friends" :key="fkey">
|
||||
<u-index-anchor :text="indexs[fkey]" bgColor="#ededed" height="20" size="12" color="#666"
|
||||
style="padding:10rpx 30rpx" />
|
||||
<u-index-anchor :text="indexs[fkey]" bgColor="#f9f9f9" height="20" size="12" color="#666"
|
||||
class="anchor" />
|
||||
<view v-for="(friendItem, index) in item" :key="index" class="friend-flex"
|
||||
@click="toFriend(friendItem.targetId)">
|
||||
<u-avatar class="avatar-img" size="40" shape="square"
|
||||
:src="contact(friendItem.targetId).portraitUrl" />
|
||||
<view class="info">
|
||||
<view class="name">{{ contact(friendItem.targetId).name }}</view>
|
||||
<!-- <view class="address">地址:{{ friendItem.address }}</view> -->
|
||||
</view>
|
||||
</view>
|
||||
</u-index-item>
|
||||
</block>
|
||||
<block v-else>
|
||||
<u-empty class="pages-null" mode="data" text="暂无好友" />
|
||||
</block>
|
||||
<view class="no-lists" v-else>
|
||||
<u-image class="cover" radius="4" width="400rpx" height="400rpx"
|
||||
:src=" require('@/static/imgs/no-friend.png')" :lazy-load="true" />
|
||||
<span>暂无好友列表~</span>
|
||||
</view>
|
||||
</u-index-list>
|
||||
</view>
|
||||
</template>
|
||||
@@ -37,8 +38,13 @@
|
||||
getFriendsLetter
|
||||
} from '@/apis/interfaces/im';
|
||||
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
|
||||
|
||||
export default {
|
||||
import im from '@/utils/im/index.js'
|
||||
import imBase from '../mixins/imBase.js'
|
||||
|
||||
export default {
|
||||
mixins: [
|
||||
imBase
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
indexs: [],
|
||||
@@ -54,9 +60,14 @@
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
uni.$on('onNewContactFriends', this.checkNewFriendPending)
|
||||
},
|
||||
onShow() {
|
||||
this.getFriendList()
|
||||
this.checkNewFriendPending()
|
||||
uni.$on('onContactNotification', this.checkNewFriendPending)
|
||||
},
|
||||
onUnload() {
|
||||
uni.$off("onNewContactFriends")
|
||||
},
|
||||
methods: {
|
||||
getFriendList() {
|
||||
@@ -72,10 +83,7 @@
|
||||
},
|
||||
toGroup() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/im/group/index',
|
||||
fail(err) {
|
||||
console.log(err);
|
||||
}
|
||||
url: '/pages/im/group/index'
|
||||
})
|
||||
},
|
||||
toFriend(targetId) {
|
||||
@@ -85,24 +93,15 @@
|
||||
},
|
||||
// 新朋友
|
||||
toPending() {
|
||||
// if (this.pendingCount > 0) {
|
||||
uni.navigateTo({
|
||||
url: '/pages/im/friends/pending'
|
||||
});
|
||||
// } else {
|
||||
// uni.showToast({
|
||||
// title: ` 暂无好友申请 ~ `,
|
||||
// icon: "none",
|
||||
// mask: true,
|
||||
// duration: 3000
|
||||
// })
|
||||
// }
|
||||
uni.navigateTo({
|
||||
url: '/pages/im/friends/pending'
|
||||
})
|
||||
}
|
||||
},
|
||||
onNavigationBarButtonTap(e) {
|
||||
uni.navigateTo({
|
||||
url: '/pages/im/friends/search'
|
||||
});
|
||||
})
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -113,6 +112,12 @@
|
||||
height: 70vh;
|
||||
}
|
||||
|
||||
.anchor {
|
||||
background-color: #f9f9f9 !important;
|
||||
padding: 10rpx 30rpx;
|
||||
border-bottom: none !important;
|
||||
}
|
||||
|
||||
// 好友列表
|
||||
.friend-flex {
|
||||
position: relative;
|
||||
@@ -126,6 +131,8 @@
|
||||
box-shadow: 0 0 20rpx rgba($color: $main-color, $alpha: 0.2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
.info {
|
||||
flex: 1;
|
||||
margin-left: $padding;
|
||||
@@ -163,4 +170,19 @@
|
||||
line-height: 24px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.no-lists {
|
||||
padding-top: $padding * 3;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-sizing: border-box;
|
||||
font-size: $title-size-m;
|
||||
color: $text-gray-m;
|
||||
|
||||
span {
|
||||
padding-top: $padding;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
<view class="content">
|
||||
<!-- 用户信息 -->
|
||||
<view class="info-flex">
|
||||
<u-avatar :src="userInfo.portraitUrl || require('@/static/user/cover.png')" shape="square" size="50"
|
||||
bg-color="#fff"></u-avatar>
|
||||
<u-avatar :src="userInfo.portraitUrl || require('@/static/user/cover.png')" shape="square"
|
||||
:size="rpx2px(100)" bg-color="#fff"></u-avatar>
|
||||
<view class="info-text">
|
||||
<view class="nickname">{{ userInfo.name }}</view>
|
||||
<view class="nickname">{{ contact(targetId).name }} ({{ userInfo.name }})</view>
|
||||
<view class="address" @longpress="copyAddress">地址:{{ userInfo.address }}</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -14,23 +14,19 @@
|
||||
<view class="item">
|
||||
<label>性别</label>
|
||||
<view class="text" v-if="userInfo.gender === 0">保密</view>
|
||||
<view class="text" v-if="userInfo.gender === 1">男</view>
|
||||
<view class="text" v-if="userInfo.gender === 2">女</view>
|
||||
<view class="text" v-else-if="userInfo.gender === 1">男</view>
|
||||
<view class="text" v-else>女</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 如果是好友 -->
|
||||
<block v-if="userInfo.friendship ==='accepted'">
|
||||
<view class="info-btns">
|
||||
<view class="item u-border-bottom" @click="setRemark">
|
||||
<label>设置备注</label>
|
||||
<u-icon name="arrow-right" color="#eee" size="16" />
|
||||
</view>
|
||||
<view class="item u-border-bottom" @click="setRemark">
|
||||
<label>设置标签</label>
|
||||
<u-icon name="arrow-right" color="#eee" size="16" />
|
||||
<uni-icons type="right" size="32rpx" />
|
||||
</view>
|
||||
<view class="item u-border-bottom">
|
||||
<label>聊天免打扰</label>
|
||||
<label>消息免打扰</label>
|
||||
<u-switch size="22" v-model="status" activeColor="#34CE98" @change="setStatus"></u-switch>
|
||||
</view>
|
||||
<view class="item">
|
||||
@@ -69,6 +65,14 @@
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<u-modal negativeTop="300" :show="modalShow" title="修改备注" showCancelButton @cancel="onHideModal"
|
||||
@confirm="onChangeRemark">
|
||||
<view class="slot-content">
|
||||
<u--input placeholder="好友备注" border="surround" focus v-model="contactRemark" maxlength="12" />
|
||||
</view>
|
||||
</u-modal>
|
||||
|
||||
<u-action-sheet :actions="callActions" cancelText="取消" @close="callShow = false" @select="singleCall"
|
||||
:show="callShow">
|
||||
</u-action-sheet>
|
||||
@@ -83,12 +87,17 @@
|
||||
} from '@/apis/interfaces/im.js'
|
||||
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
|
||||
import * as CallLib from '@/uni_modules/RongCloud-CallWrapper/lib/index'
|
||||
import imBase from '../mixins/imBase.js'
|
||||
|
||||
// friendship: '' 没有好友关系
|
||||
// accepted 好友
|
||||
// pending 申请中
|
||||
// denied 拒绝
|
||||
// blocked 黑名单
|
||||
export default {
|
||||
mixins: [
|
||||
imBase
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
targetId: '',
|
||||
@@ -107,13 +116,14 @@
|
||||
}
|
||||
],
|
||||
callShow: false,
|
||||
hasPeding: false
|
||||
hasPeding: false,
|
||||
modalShow: false,
|
||||
contactRemark: ''
|
||||
}
|
||||
},
|
||||
onLoad(e) {
|
||||
this.targetId = e.targetId
|
||||
getFriendInfo(e.targetId).then(res => {
|
||||
console.log(res, "获取朋友的信息")
|
||||
this.userInfo = res
|
||||
// 获取到用户信息之后,去检查一下要不要更新
|
||||
this.$store.dispatch('updateContact', res)
|
||||
@@ -148,11 +158,30 @@
|
||||
})
|
||||
},
|
||||
toPrivate() {
|
||||
uni.redirectTo({
|
||||
uni.navigateTo({
|
||||
url: '/pages/im/private/chat?targetId=' + this.targetId
|
||||
});
|
||||
},
|
||||
// 设置好友备注操作
|
||||
setRemark() {
|
||||
this.modalShow = true
|
||||
this.contactRemark = this.$store.getters.contactInfo(this.targetId).name
|
||||
},
|
||||
onHideModal() {
|
||||
this.modalShow = false
|
||||
},
|
||||
onChangeRemark() {
|
||||
this.$store.dispatch('setContactRemark', {
|
||||
targetId: this.targetId,
|
||||
remark: this.contactRemark
|
||||
})
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: '备注设置成功'
|
||||
})
|
||||
this.onHideModal()
|
||||
},
|
||||
setTag() {
|
||||
uni.showToast({
|
||||
title: '开发中',
|
||||
icon: 'none'
|
||||
@@ -209,7 +238,7 @@
|
||||
})
|
||||
return
|
||||
}
|
||||
pedingFriend(this.targetId, 'message').then(res => {
|
||||
pedingFriend(this.targetId, '').then(res => {
|
||||
uni.showToast({
|
||||
title: ` 申请成功,等待审核 `,
|
||||
icon: 'none',
|
||||
@@ -228,8 +257,9 @@
|
||||
})
|
||||
},
|
||||
singleCall(e) {
|
||||
uni.redirectTo({
|
||||
url: '/pages/im/private/call?targetId=' + this.targetId + '&mediaType=' + e.type
|
||||
uni.navigateTo({
|
||||
url: '/pages/im/private/call?targetId=' + this.targetId + '&mediaType=' + e.type +
|
||||
'&isCall=true'
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -344,6 +374,10 @@
|
||||
width: 200rpx;
|
||||
}
|
||||
|
||||
.uni-icons {
|
||||
color: $text-gray-m !important;
|
||||
}
|
||||
|
||||
.text {
|
||||
width: calc(100% - 200rpx);
|
||||
color: $text-gray-m;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<!-- 用户信息 -->
|
||||
<view class="info-flex">
|
||||
<view class="info-flex-item">
|
||||
<u-avatar :src="infoObj.portraitUrl" shape="square" size="210rpx" bg-color="#fff" class="avatar" />
|
||||
<u-avatar :src="infoObj.portraitUrl" @click='previewImg(infoObj.portraitUrl)' shape="square" size="210rpx" bg-color="#fff" class="avatar" />
|
||||
<view class="nickname">{{infoObj.name}}</view>
|
||||
<view class="address">{{infoObj.address}}</view>
|
||||
<view class="info-code">
|
||||
@@ -23,7 +23,8 @@
|
||||
<script>
|
||||
import {
|
||||
getUserInfo
|
||||
} from '@/apis/interfaces/im'
|
||||
} from '@/apis/interfaces/im.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
@@ -46,7 +47,13 @@
|
||||
this.infoObj = res
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
methods: {
|
||||
previewImg(item){
|
||||
console.log(item)
|
||||
uni.previewImage({
|
||||
urls:[item]
|
||||
})
|
||||
},
|
||||
copy() {
|
||||
uni.setClipboardData({
|
||||
data: this.downUrl,
|
||||
@@ -99,7 +106,7 @@
|
||||
|
||||
.avatar {
|
||||
// padding: 14rpx;
|
||||
border-radius: 10rpx;
|
||||
border-radius: 20rpx;
|
||||
background-color: #fff;
|
||||
border: solid 14rpx rgba($color: #fff, $alpha:1);
|
||||
}
|
||||
|
||||
@@ -2,12 +2,19 @@
|
||||
<view class="pending">
|
||||
<u-sticky>
|
||||
<view class="header-search" @click="$Router.push({ name: 'SearchFriend' })">
|
||||
<u-search placeholder="输入手机号码搜索" height="74" searchIcon="search" inputAlign="center" bgColor="white"
|
||||
<u-search placeholder="输入手机号码搜索" searchIcon="search" inputAlign="center" bgColor="white"
|
||||
:disabled="true" :show-action="false" />
|
||||
</view>
|
||||
</u-sticky>
|
||||
<view v-for="(item, index) in pendings" :key="index">
|
||||
<apply-cell :message="item.latestMessage" @success="getPendingList" />
|
||||
<block v-if="pendings.length > 0">
|
||||
<view v-for="(item, index) in pendings" :key="index">
|
||||
<apply-cell :message="item.latestMessage" @success="getPendingList" />
|
||||
</view>
|
||||
</block>
|
||||
<view class="no-lists" v-else>
|
||||
<u-image class="cover" radius="4" width="400rpx" height="400rpx"
|
||||
:src="require('@/static/imgs/no-friend.png')" :lazy-load="true" />
|
||||
<span> 暂无好友申请 ~ </span>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
@@ -15,23 +22,33 @@
|
||||
<script>
|
||||
import applyCell from '../components/friendApplyCell'
|
||||
import im from '@/utils/im/index.js'
|
||||
|
||||
|
||||
export default {
|
||||
components: {
|
||||
applyCell
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pendings: []
|
||||
pendings: [],
|
||||
bg: '#fff'
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
onShow() {
|
||||
this.getPendingList()
|
||||
uni.$on('onContactNotification', this.getPendingList)
|
||||
uni.$on('onNewContactPendings', this.getPendingList)
|
||||
},
|
||||
onUnload() {
|
||||
uni.$off('onNewContactPendings')
|
||||
},
|
||||
methods: {
|
||||
getPendingList() {
|
||||
im.getPendingList((pendings) => {
|
||||
console.log(pendings, 'res......')
|
||||
if (pendings.length > 0) {
|
||||
this.bg = '#f9f9f9'
|
||||
} else {
|
||||
this.bg = '#fff'
|
||||
}
|
||||
this.pendings = pendings
|
||||
})
|
||||
}
|
||||
@@ -46,7 +63,7 @@
|
||||
}
|
||||
|
||||
.no-lists {
|
||||
padding-top: $padding * 3;
|
||||
padding-top: $padding * 5;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
@@ -8,17 +8,19 @@
|
||||
|
||||
<template>
|
||||
<view class="search">
|
||||
<!-- 搜索 、 -->
|
||||
<!-- 搜索 -->
|
||||
<u-sticky>
|
||||
<view class="header-search">
|
||||
<u-search placeholder="输入用户账号、手机号" height="74" searchIcon="search" @custom="search" v-model="searchValue" @search="search" bgColor="#f9f9f9" :focus="focused" />
|
||||
<u-search placeholder="输入用户账号、手机号" searchIcon="search" @custom="search" v-model="searchValue"
|
||||
@search="search" bgColor="#F3F6FB" :focus="focused" />
|
||||
</view>
|
||||
</u-sticky>
|
||||
<block v-if="searchResult.length > 0">
|
||||
<applyFriend :lists="searchResult" :isApply="true" @action="action" />
|
||||
</block>
|
||||
<view class="no-lists" v-else>
|
||||
<u-image class="cover" radius="4" width="400rpx" height="400rpx" :src="require('@/static/imgs/no-search.png')" :lazy-load="true" />
|
||||
<view class="no-lists" v-if="searchResult.length === 0 && searchValue.length > 1">
|
||||
<u-image class="cover" radius="4" width="400rpx" height="400rpx"
|
||||
:src="require('@/static/imgs/no-search.png')" :lazy-load="true" />
|
||||
<span>暂无匹配内容~</span>
|
||||
</view>
|
||||
</view>
|
||||
@@ -30,6 +32,7 @@
|
||||
pedingFriend
|
||||
} from '@/apis/interfaces/im.js';
|
||||
import applyFriend from '../components/friendSearchList.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
applyFriend
|
||||
@@ -41,13 +44,27 @@
|
||||
focused: true
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
searchValue(value) {
|
||||
console.log(value.length, 'length...')
|
||||
if (value.length > 1) {
|
||||
this.searchResult = []
|
||||
this.search()
|
||||
return
|
||||
}
|
||||
if(value.length === 0){
|
||||
this.searchResult = []
|
||||
return
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
search() {
|
||||
// friendship: '' 没有好友关系
|
||||
// accepted 好友
|
||||
// pending 申请中
|
||||
// denied 拒绝
|
||||
// blocked 黑名单
|
||||
// friendship: '' 没有好友关系
|
||||
// accepted 好友
|
||||
// pending 申请中
|
||||
// denied 拒绝
|
||||
// blocked 黑名单
|
||||
searchFriend(this.searchValue)
|
||||
.then(res => {
|
||||
this.searchResult = res;
|
||||
@@ -60,9 +77,9 @@
|
||||
});
|
||||
});
|
||||
},
|
||||
action(e) {
|
||||
uni.navigateTo({
|
||||
url: '/pages/im/friends/info?targetId=' + e.item.targetId
|
||||
action(e) {
|
||||
uni.navigateTo({
|
||||
url: '/pages/im/friends/info?targetId=' + e.item.targetId
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,35 +1,71 @@
|
||||
<template>
|
||||
<view class="create">
|
||||
<view class="create-title">公告内容</view>
|
||||
<u--textarea v-model="content" count height="240" maxlength="240" placeholder="请输入公告内容" />
|
||||
<u-button type="primary" text="发布" :disabled="disabled" @click="onCreate" color="#34CE98" />
|
||||
|
||||
<block v-if="type === 'check'">
|
||||
<view class="content"> {{content}} </view>
|
||||
</block>
|
||||
|
||||
<block v-else>
|
||||
<u--textarea v-model="content" count height="240" maxlength="240" placeholder="请输入公告内容" />
|
||||
<u-button type="primary" text="发布" :disabled="disabled" @click="onCreate" color="#34CE98" />
|
||||
</block>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
createGroupAnnouncement
|
||||
createGroupAnnouncement,
|
||||
getGroupAnnouncement
|
||||
} from '@/apis/interfaces/im.js'
|
||||
import onGroupDismiss from '../mixins/onGroupDismiss.js'
|
||||
|
||||
export default {
|
||||
mixins: [
|
||||
onGroupDismiss
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
targetId: '',
|
||||
content: ''
|
||||
content: '',
|
||||
aId: '',
|
||||
type: '' // cheack ' 查看详情'
|
||||
}
|
||||
},
|
||||
onLoad(e) {
|
||||
this.targetId = e.targetId
|
||||
},
|
||||
computed: {
|
||||
disabled() {
|
||||
return this.content.length == 0 || this.content.length > 200
|
||||
}
|
||||
if (e.aId) {
|
||||
this.type = e.type
|
||||
uni.setNavigationBarTitle({
|
||||
title: '群公告'
|
||||
})
|
||||
this.aId = e.aId
|
||||
getGroupAnnouncement(this.targetId, this.aId).then(res => {
|
||||
this.content = res.content
|
||||
}).catch(err => {
|
||||
if (err.status_code == 404) {
|
||||
this.$nextTick(() => {
|
||||
uni.navigateBack()
|
||||
})
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: err.message,
|
||||
icon: 'none',
|
||||
mask: true
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
disabled() {
|
||||
return this.content.length == 0 || this.content.length > 200
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onCreate() {
|
||||
createGroupAnnouncement(this.targetId, this.content).then(res => {
|
||||
uni.$emit('groupAnnouncementCreated')
|
||||
createGroupAnnouncement(this.targetId, this.content).then(res => {
|
||||
uni.$emit('groupAnnouncementCreated')
|
||||
uni.showToast({
|
||||
title: '发布成功',
|
||||
success: () => {
|
||||
@@ -52,15 +88,16 @@
|
||||
<style lang="scss" scoped>
|
||||
.create {
|
||||
padding: $padding;
|
||||
.create-title{
|
||||
|
||||
.create-title {
|
||||
font-size: $title-size + 4;
|
||||
padding: $padding - 10 0 $padding - 10 $padding - 10 ;
|
||||
padding: $padding - 10 0 $padding - 10 $padding - 10;
|
||||
color: $text-color;
|
||||
font-weight: 800;
|
||||
position: relative;
|
||||
|
||||
&::before{
|
||||
content:"";
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 10rpx;
|
||||
height: 34rpx;
|
||||
@@ -69,6 +106,13 @@
|
||||
top: 26rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
color: $text-color;
|
||||
font-size: $title-size;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.u-button {
|
||||
margin-top: $padding;
|
||||
}
|
||||
|
||||
@@ -1,22 +1,30 @@
|
||||
<template>
|
||||
<view class="announce">
|
||||
<view class="announce" :style="`background-color:${bg};`">
|
||||
<!-- 有列表 -->
|
||||
<u-skeleton rows="2" :loading="loading" avatar :rows="5" v-if="announcements.length>0">
|
||||
<view v-for="(item,index) in announcements" :key="index" class="item" >
|
||||
<view class="header">
|
||||
<u-avatar :src="item.user.portraitUrl" />
|
||||
<view class="user">
|
||||
<view class="name">{{ item.user.name }}</view>
|
||||
<view class="time">{{ item.created_at }}</view>
|
||||
</view>
|
||||
<view class="delete" v-if="isAdmin" @click="onDelete(item.announcement_id)">删除</view>
|
||||
<view v-for="(item,index) in announcements" :key="index" class="item"
|
||||
@longpress="actions(item.announcement_id)" @click="tabA(item.announcement_id)">
|
||||
<view class="content-a"><span v-if="item.is_top">置顶</span>{{ item.content }}</view>
|
||||
<view class="user">
|
||||
<u-avatar :src="item.user.portraitUrl" size="40rpx" />
|
||||
<view class="name">{{ item.user.name }}</view>
|
||||
<view class="time">{{ item.created_at }}</view>
|
||||
</view>
|
||||
<view class="content">{{ item.content }}</view>
|
||||
<!-- <view class="delete" v-if="isAdmin" @click="onDelete(item.announcement_id)">删除</view> -->
|
||||
</view>
|
||||
</u-skeleton>
|
||||
|
||||
<!-- 没有列表 -->
|
||||
<view class="no-lists" v-else>
|
||||
<u-image class="cover" radius="4" width="400rpx" height="400rpx" :src="require('@/static/imgs/no-level-list.png')" :lazy-load="true" />
|
||||
<u-image class="cover" radius="4" width="400rpx" height="400rpx"
|
||||
:src="require('@/static/imgs/no-level-list.png')" :lazy-load="true" />
|
||||
<span>暂无公告内容~</span>
|
||||
</view>
|
||||
|
||||
<!-- 弹出 -->
|
||||
<u-action-sheet :actions="actionMap" :title="actionTitle" :show="actionShow" cancelText="取消"
|
||||
@close="actionShow = false" @select="handleAction" />
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@@ -24,16 +32,36 @@
|
||||
import {
|
||||
getGroupInfo,
|
||||
getGroupAnnouncements,
|
||||
deleteGroupAnnouncement
|
||||
deleteGroupAnnouncement,
|
||||
topGroupAnnouncement
|
||||
} from '@/apis/interfaces/im.js'
|
||||
import onGroupDismiss from '../mixins/onGroupDismiss.js'
|
||||
import imBase from '../mixins/imBase.js'
|
||||
|
||||
export default {
|
||||
mixins: [
|
||||
imBase,
|
||||
onGroupDismiss
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
targetId: '',
|
||||
announcements: [],
|
||||
groupAnnouncementId: '', // 选择公告 id
|
||||
announcements: [], // 公告列表
|
||||
loading: true,
|
||||
isAdmin: false
|
||||
isAdmin: false,
|
||||
actionShow: false,
|
||||
actionMap: [{
|
||||
key: 2,
|
||||
name: ' 删除该公告',
|
||||
disabled: false
|
||||
}, {
|
||||
key: 3,
|
||||
name: '置顶该公告',
|
||||
disabled: false
|
||||
}],
|
||||
actionTitle: '请选择操作',
|
||||
bg: '#fff'
|
||||
}
|
||||
},
|
||||
onLoad(e) {
|
||||
@@ -60,26 +88,63 @@
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 获取公告信息
|
||||
initData() {
|
||||
getGroupAnnouncements(this.targetId).then(res => {
|
||||
if (res.length > 0) {
|
||||
this.bg = '#f9f9f9'
|
||||
} else {
|
||||
this.bg = '#fff'
|
||||
}
|
||||
this.announcements = res
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
// 选择公告 并显示操作弹窗
|
||||
actions(id) {
|
||||
if (this.isAdmin) {
|
||||
this.groupAnnouncementId = id
|
||||
this.actionShow = true
|
||||
}
|
||||
},
|
||||
// 选择了操作出发事件
|
||||
handleAction(e) {
|
||||
console.log(e.key)
|
||||
switch (e.key) {
|
||||
case 2:
|
||||
this.onDelete(this.groupAnnouncementId)
|
||||
break;
|
||||
case 3:
|
||||
this.onTop(this.groupAnnouncementId)
|
||||
break;
|
||||
}
|
||||
},
|
||||
tabA(id) {
|
||||
uni.navigateTo({
|
||||
url: '/pages/im/group/announceCreate?type=check&targetId=' + this.targetId + '&aId=' + id
|
||||
})
|
||||
},
|
||||
onTop(aId) {
|
||||
topGroupAnnouncement(this.targetId, aId).then(res => {
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: ' 置顶成功',
|
||||
mask: true
|
||||
})
|
||||
uni.$emit('updateAnnouncement')
|
||||
this.initData()
|
||||
})
|
||||
},
|
||||
// 删除公告
|
||||
onDelete(aId) {
|
||||
uni.showModal({
|
||||
title: '删除公告',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
deleteGroupAnnouncement(this.targetId, aId).then(res => {
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: '删除成功'
|
||||
})
|
||||
this.initData()
|
||||
})
|
||||
}
|
||||
}
|
||||
deleteGroupAnnouncement(this.targetId, aId).then(res => {
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: '删除成功',
|
||||
mask: true
|
||||
})
|
||||
uni.$emit('updateAnnouncement')
|
||||
this.initData()
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -88,7 +153,8 @@
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.announce {
|
||||
padding: 0 $padding $padding $padding;
|
||||
min-height: 99vh;
|
||||
|
||||
.no-lists {
|
||||
padding-top: $padding * 5;
|
||||
display: flex;
|
||||
@@ -98,46 +164,60 @@
|
||||
box-sizing: border-box;
|
||||
font-size: $title-size-m;
|
||||
color: $text-gray-m;
|
||||
|
||||
|
||||
span {
|
||||
padding-top: $padding;
|
||||
}
|
||||
}
|
||||
.item {
|
||||
border-bottom: solid 1rpx #f9f9f9 !important;
|
||||
padding-top: $padding;
|
||||
|
||||
.header {
|
||||
.item {
|
||||
background-color: #fff;
|
||||
padding: $padding $padding + 10 10rpx $padding + 10;
|
||||
border-bottom: $padding solid #f9f9f9;
|
||||
|
||||
|
||||
.user {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
font-size: $title-size-m;
|
||||
color: $text-gray-m;
|
||||
padding: 20rpx 10rpx 10rpx 10rpx;
|
||||
border-top: solid 1rpx #F9F9F9;
|
||||
|
||||
.user {
|
||||
margin-left: $padding;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
|
||||
.name {}
|
||||
|
||||
.time {
|
||||
font-size: 24rpx;
|
||||
color: $text-gray-m;
|
||||
}
|
||||
.name {
|
||||
padding-left: 10rpx;
|
||||
}
|
||||
|
||||
.delete {
|
||||
color: $text-price;
|
||||
font-size: 28rpx;
|
||||
.time {
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 20rpx $padding;
|
||||
.content-a {
|
||||
font-size: $title-size;
|
||||
color: $text-gray;
|
||||
color: $text-color;
|
||||
max-width: 100%;
|
||||
margin-bottom: 10rpx;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 3;
|
||||
overflow: hidden;
|
||||
line-height: 1.5;
|
||||
|
||||
span {
|
||||
color: #fff;
|
||||
display: inline-block;
|
||||
border-radius: 10rpx;
|
||||
background-color: $main-color;
|
||||
font-size: $title-size-m - 4;
|
||||
padding: 4rpx 10rpx;
|
||||
margin-right: 10rpx;
|
||||
line-height: 1.4;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,8 +20,14 @@
|
||||
joinGroupPre,
|
||||
joinGroup
|
||||
} from '@/apis/interfaces/im.js'
|
||||
|
||||
export default {
|
||||
import onGroupDismiss from '../mixins/onGroupDismiss.js'
|
||||
import imBase from '../mixins/imBase.js'
|
||||
|
||||
export default {
|
||||
mixins: [
|
||||
imBase,
|
||||
onGroupDismiss
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
targetId: '',
|
||||
@@ -45,7 +51,7 @@
|
||||
mask: true,
|
||||
duration: 3000
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
toGroupChat() {
|
||||
|
||||
@@ -2,22 +2,18 @@
|
||||
<view class="chat">
|
||||
<sent-message-bar :conversationType="conversationType" :targetId="targetId" @onSuccess="getNewMessage()" />
|
||||
|
||||
<view class="shade" @click="hidePop" v-show="showPop">
|
||||
<view class="pop" :style="popStyle" :class="{'show':showPop}">
|
||||
<view v-for="(item, index) in popButton" :key="index" @click="pickerMenu(item)">
|
||||
{{ item }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="body">
|
||||
<view class="scroll">
|
||||
<view class="cell" v-for="(item, index) in messages" :key="index">
|
||||
<view class="time" v-if="item.senderUserId === '__system__'">{{ item.content.message }}</view>
|
||||
<view v-else :class="['cell-item', item.messageDirection == 1 ? 'right' : 'left']">
|
||||
<u-avatar class="avatar" @click="toUser(item)" size="36" shape="square"
|
||||
:src="contact(item.senderUserId).portraitUrl" />
|
||||
<view class="msg">
|
||||
<show-voice v-if="item.objectName === 'RC:HQVCMsg'" :guest="item.messageDirection == 1"
|
||||
:msg="item.content" :name="contact(item.senderUserId).name" />
|
||||
<show-image v-if="item.objectName === 'RC:ImgMsg'" :guest="item.messageDirection == 1"
|
||||
:msg="item.content" :name="contact(item.senderUserId).name" />
|
||||
<show-text v-if="item.objectName === 'RC:TxtMsg'" :guest="item.messageDirection == 1"
|
||||
:msg="item.content" :name="contact(item.senderUserId).name" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="cell" v-for="(message, index) in messages" :key="index">
|
||||
<show-message-cell :message="message" isGroup @messageAction="messageAction" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -25,28 +21,31 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
timeCustomCN
|
||||
} from '@/utils/filters.js'
|
||||
import {
|
||||
getGroupBase
|
||||
} from '@/apis/interfaces/im.js'
|
||||
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
|
||||
import im from '@/utils/im/index.js'
|
||||
import showVoice from '../components/showVoice'
|
||||
import showImage from '../components/showImage'
|
||||
import showText from '../components/showText'
|
||||
import sentMessageBar from '../components/sentMessageBar'
|
||||
import showMessageCell from '../components/showMessageCell'
|
||||
import utils from '@/utils/index.js'
|
||||
import onGroupDismiss from '../mixins/onGroupDismiss.js'
|
||||
import imBase from '../mixins/imBase.js'
|
||||
import messageActions from '../mixins/messageActions.js'
|
||||
|
||||
export default {
|
||||
mixins: [
|
||||
imBase,
|
||||
onGroupDismiss,
|
||||
messageActions
|
||||
],
|
||||
components: {
|
||||
showVoice,
|
||||
showImage,
|
||||
showText,
|
||||
sentMessageBar
|
||||
sentMessageBar,
|
||||
showMessageCell
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
avatarRpx: 84,
|
||||
targetId: '',
|
||||
conversationType: RongIMLib.ConversationType.GROUP,
|
||||
messages: [],
|
||||
@@ -64,31 +63,62 @@
|
||||
sentTime: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
contact() {
|
||||
return function(targetId) {
|
||||
return this.$store.getters.contactInfo(targetId)
|
||||
}
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
this.initGroupInfo()
|
||||
},
|
||||
onLoad(e) {
|
||||
this.targetId = e.targetId
|
||||
// 获取群成员数量
|
||||
getGroupBase(this.targetId).then(res => {
|
||||
uni.setNavigationBarTitle({
|
||||
title: this.groupInfo.name + `(${res.members})`
|
||||
})
|
||||
})
|
||||
// 获取历史消息列表
|
||||
this.getMessageList()
|
||||
// 监听收到本群的消息,追加消息
|
||||
uni.$on('onReceiveMessage', (msg) => {
|
||||
// 监听新消息
|
||||
uni.$on('onReceiveMessage_' + this.targetId, (message) => {
|
||||
this.getNewMessage()
|
||||
})
|
||||
uni.$on('onReceiptRequest', (msg) => {
|
||||
if (msg.targetId == this.targetId) {
|
||||
this.getNewMessage()
|
||||
RongIMLib.getMessageByUId(msg.messageUId, (result) => {
|
||||
RongIMLib.sendReadReceiptResponse(3, this.targetId, [result.message], (res) => {
|
||||
console.error('发送群聊已读回执成功', res);
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
// 群已读回执
|
||||
uni.$on('onReceiptResponse', (msg) => {
|
||||
if (msg.targetId == this.targetId) {
|
||||
this.messages = this.messages.map(item => {
|
||||
if (msg.messageId == item.messageId) {
|
||||
return msg
|
||||
} else {
|
||||
return item
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
// 清理聊天记录
|
||||
uni.$once('cleanGroupMessage', this.getMessageList)
|
||||
uni.$on('onRecallMessage_' + this.targetId, (message) => {
|
||||
this.messages = this.messages.map(item => {
|
||||
if (message.messageId == item.messageId) {
|
||||
return message
|
||||
} else {
|
||||
return item
|
||||
}
|
||||
})
|
||||
})
|
||||
uni.$on('onRemoveMessage_' + this.targetId, (messageId) => {
|
||||
this.messages = this.messages.filter(item => item.messageId != messageId)
|
||||
})
|
||||
},
|
||||
onUnload() {
|
||||
uni.$off('onRemoveMessage_' + this.targetId)
|
||||
uni.$off('onReceiveMessage_' + this.targetId)
|
||||
uni.$off('onUpdateProfile_' + this.targetId)
|
||||
uni.$off('onRecallMessage_' + this.targetId)
|
||||
uni.$off('onReceiptRequest')
|
||||
uni.$off('onReceiptResponse')
|
||||
},
|
||||
onNavigationBarButtonTap() {
|
||||
uni.navigateTo({
|
||||
@@ -96,23 +126,17 @@
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
initGroupInfo() {
|
||||
// 获取群信息,成员数量,设置标题
|
||||
getGroupBase(this.targetId).then(res => {
|
||||
uni.setNavigationBarTitle({
|
||||
title: res.name + `(${res.members})`
|
||||
})
|
||||
})
|
||||
},
|
||||
onScroll(e) {
|
||||
this.$refs.messageBar.onHidePopus()
|
||||
},
|
||||
toUser(item) {
|
||||
if (item.senderUserId == '__system__') {
|
||||
return
|
||||
}
|
||||
if (item.messageDirection == 1) {
|
||||
uni.navigateTo({
|
||||
url: '/pages/im/friends/mine?targetId=' + item.senderUserId
|
||||
})
|
||||
} else {
|
||||
uni.navigateTo({
|
||||
url: '/pages/im/friends/info?targetId=' + item.senderUserId
|
||||
})
|
||||
}
|
||||
},
|
||||
getNewMessage() {
|
||||
im.getMessageList(
|
||||
this.conversationType,
|
||||
@@ -134,6 +158,18 @@
|
||||
20,
|
||||
true,
|
||||
(messages) => {
|
||||
console.log('获取消息列表', messages);
|
||||
const msgs = messages.filter(item => item.receivedStatus == 0)
|
||||
console.log('未读消息', msgs);
|
||||
if (msgs.length) {
|
||||
RongIMLib.sendReadReceiptResponse(3, this.targetId, msgs, (res) => {
|
||||
console.error('发送群聊已读回执成功', res);
|
||||
msgs.map(item => {
|
||||
RongIMLib.setMessageReceivedStatus(item.messageId, 1)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
this.messages = messages
|
||||
this.scrollBottom()
|
||||
})
|
||||
@@ -144,12 +180,14 @@
|
||||
// 清理当前会话,未读消息数量
|
||||
RongIMLib.clearMessagesUnreadStatus(this.conversationType, this.targetId, this.latestMessage
|
||||
.sentTime)
|
||||
// // 发送消息已读状态给对方
|
||||
// RongIMLib.sendReadReceiptMessage(this.conversationType, this.targetId, this.latestMessage.sentTime)
|
||||
// 更新badge提醒数量
|
||||
im.setNotifyBadge()
|
||||
}
|
||||
}
|
||||
},
|
||||
onHide() {
|
||||
// console.log(JSON.stringify(this.$refs))
|
||||
// this.$refs.voice.stopPlay()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -175,53 +213,52 @@
|
||||
justify-content: flex-end;
|
||||
|
||||
.cell {
|
||||
padding: 10rpx 30rpx;
|
||||
.time {
|
||||
text-align: center;
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
}
|
||||
padding: 10rpx 20rpx;
|
||||
|
||||
.cell-item {
|
||||
display: flex;
|
||||
width: 690rpx;
|
||||
justify-content: flex-start;
|
||||
|
||||
&.left {
|
||||
flex-direction: row;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.right {
|
||||
flex-direction: row-reverse;
|
||||
/* 遮罩 */
|
||||
.shade {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 999;
|
||||
|
||||
.state {
|
||||
flex-direction: row;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
.pop {
|
||||
border-radius: 10rpx;
|
||||
position: fixed;
|
||||
z-index: 101;
|
||||
width: 200rpx;
|
||||
box-sizing: border-box;
|
||||
font-size: 28rpx;
|
||||
text-align: left;
|
||||
color: #333;
|
||||
background-color: #fff;
|
||||
box-shadow: 0 0 5px rgba(0, 0, 0, 0.5);
|
||||
line-height: 80rpx;
|
||||
transition: transform 0.15s ease-in-out 0s;
|
||||
user-select: none;
|
||||
-webkit-touch-callout: none;
|
||||
transform: scale(0, 0);
|
||||
|
||||
.msg {
|
||||
margin: 0 20rpx;
|
||||
&.show {
|
||||
transform: scale(1, 1);
|
||||
}
|
||||
|
||||
.state {
|
||||
padding-top: 10rpx;
|
||||
&>view {
|
||||
padding: 0 20rpx;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
user-select: none;
|
||||
-webkit-touch-callout: none;
|
||||
|
||||
.state-text {
|
||||
font-size: $title-size-m - 2;
|
||||
color: rgba($color: $main-color, $alpha: 0.3)
|
||||
}
|
||||
|
||||
.state-text-active {
|
||||
font-size: $title-size-m - 2;
|
||||
color: #cecece;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cell-footer {
|
||||
height: 20rpx;
|
||||
}
|
||||
&:active {
|
||||
background-color: #f3f3f3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,19 @@
|
||||
<template>
|
||||
<view class="group">
|
||||
<view class="title"> 群聊 </view>
|
||||
<view v-for="(item, index) in groups" :key="index" class="friend-flex" @click="toGroup(item.targetId)">
|
||||
<u-avatar size="38" shape="square" :src="contact(item.targetId).portraitUrl" />
|
||||
<view class="info">
|
||||
<view class="name">{{ item.name }}</view>
|
||||
<view class="group" :style="`background-color:${bg};`">
|
||||
<block v-if="groups.length > 0">
|
||||
<view class="title"> 群聊 </view>
|
||||
<view v-for="(item, index) in groups" :key="index" class="friend-flex" @click="toGroup(item.targetId)">
|
||||
<u-avatar size="36" shape="square" :src="contact(item.targetId).portraitUrl" />
|
||||
<view class="info">
|
||||
<view class="name">{{ item.name }} <span class="total">共{{ item.members }} 成员</span></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="group-count"> {{ groups.length }}个群聊 </view>
|
||||
</block>
|
||||
<view class="no-lists" v-else>
|
||||
<u-image class="cover" radius="4" width="400rpx" height="400rpx" :src="require('@/static/imgs/no-friend.png')" :lazy-load="true" />
|
||||
<span>空空如也~</span>
|
||||
</view>
|
||||
<view class="group-count"> {{groups.length}}个群聊 </view>
|
||||
<u-modal negativeTop="300" :show="createModal" title="创建群聊" showCancelButton @cancel="onHideModal"
|
||||
@confirm="onCreateGroup">
|
||||
<view class="slot-content">
|
||||
@@ -28,7 +34,8 @@
|
||||
return {
|
||||
groups: [],
|
||||
createModal: false,
|
||||
groupName: ''
|
||||
groupName: '',
|
||||
bg: '#fff'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -41,13 +48,19 @@
|
||||
onNavigationBarButtonTap() {
|
||||
this.createModal = true
|
||||
},
|
||||
onLoad() {
|
||||
onShow() {
|
||||
this.initData()
|
||||
uni.$on('onGroupDismiss', this.initData)
|
||||
},
|
||||
methods: {
|
||||
initData() {
|
||||
getMyGroups().then((res) => {
|
||||
getMyGroups().then((res) => {
|
||||
console.log(res,'res...')
|
||||
if (res.length > 0) {
|
||||
this.bg = '#f9f9f9'
|
||||
} else {
|
||||
this.bg = '#fff'
|
||||
}
|
||||
this.groups = res
|
||||
res.map(item => {
|
||||
this.$store.dispatch('updateContact', item)
|
||||
@@ -88,17 +101,19 @@
|
||||
.group {
|
||||
min-height: 100vh;
|
||||
background-color: $window-color;
|
||||
.title{
|
||||
|
||||
.title {
|
||||
font-size: $title-size-m;
|
||||
color: $text-gray-m;
|
||||
padding: 10rpx $padding;
|
||||
}
|
||||
.group-count{
|
||||
|
||||
.group-count {
|
||||
text-align: center;
|
||||
font-size: $title-size;
|
||||
color: $text-gray;
|
||||
background-color: #fff;
|
||||
padding: 10rpx $padding $padding $padding;
|
||||
padding: 10rpx $padding 20rpx $padding;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
@@ -122,6 +137,11 @@
|
||||
.name {
|
||||
font-size: $title-size + 1;
|
||||
color: #454545 !important;
|
||||
}
|
||||
.total{
|
||||
color: $text-gray-m;
|
||||
font-size: $title-size-m - 5;
|
||||
padding-left: 10rpx;
|
||||
}
|
||||
|
||||
.address {
|
||||
@@ -130,4 +150,19 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.no-lists {
|
||||
padding-top: $padding * 5;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-sizing: border-box;
|
||||
font-size: $title-size-m;
|
||||
color: $text-gray-m;
|
||||
|
||||
span {
|
||||
padding-top: $padding;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -4,23 +4,26 @@
|
||||
<group-user-list ref="userList" :targetId="targetId" :count="14" />
|
||||
</view>
|
||||
|
||||
<u-cell-group class="cells" :border="false" >
|
||||
<u-cell :border="false" class="u-border-bottom" isLink title="群公告" :label="announcement" @click="toAnnouncement" />
|
||||
<u-cell-group class="cells" :border="false">
|
||||
<u-cell :border="false" class="u-border-bottom" isLink title="群公告" @click="toAnnouncement">
|
||||
<view slot="label" class="announcement-label "> {{announcement}} </view>
|
||||
</u-cell>
|
||||
<u-cell :border="false" class="u-border-bottom" isLink title="二维码" @click="showGroupQrCode" />
|
||||
<u-cell :border="false" class="u-border-bottom" v-if="group.can_makesure" isLink title="群聊邀请确认" @click="showGroupsSure" />
|
||||
<u-cell :border="false" class="u-border-bottom" title="聊天置顶">
|
||||
<u-switch slot="value" size="20" v-model="isTop" activeColor="#34CE98" @change="setTop" />
|
||||
</u-cell>
|
||||
<u-cell class="u-border-bottom" :border="false" title="免打扰">
|
||||
<u-cell class="u-border-bottom" :border="false" title="消息免打扰">
|
||||
<u-switch slot="value" size="20" v-model="status" activeColor="#34CE98" @change="setStatus" />
|
||||
</u-cell>
|
||||
</u-cell-group>
|
||||
|
||||
<u-cell-group class="cells" v-if="group.is_admin" :border="false">
|
||||
<u-cell :border="false" class="u-border-bottom" isLink title="修改群聊名称" :value="groupName" @click="onGroupName" />
|
||||
<u-cell :border="false" class="u-border-bottom" isLink title="修改群头像" @click="onGroupAvatar">
|
||||
<u-cell :border="false" class="u-border-bottom" isLink title="修改群聊名称" :value="groupName"
|
||||
@click="onGroupName" />
|
||||
<!-- <u-cell :border="false" class="u-border-bottom" isLink title="修改群头像" @click="onGroupAvatar">
|
||||
<u-avatar slot="value" size="25" shape="square" :src="group.cover" />
|
||||
</u-cell>
|
||||
</u-cell> -->
|
||||
<u-cell :border="false" class="u-border-bottom" isLink v-if="group.is_owner" title="准入方式" :value="joinType" @click="onChangeJoinType" />
|
||||
</u-cell-group>
|
||||
|
||||
@@ -31,15 +34,11 @@
|
||||
</view>
|
||||
|
||||
<u-modal negativeTop="300" :show="modalShow" title="修改群名称" showCancelButton @cancel="onHideModal" @confirm="onChangeGroupName">
|
||||
<view class="slot-content">
|
||||
<u--input placeholder="群名称" border="surround" focus v-model="groupName" />
|
||||
</view>
|
||||
<view class="slot-content"> <u--input placeholder="群名称" border="surround" focus v-model="groupName" maxlength="12" /> </view>
|
||||
</u-modal>
|
||||
|
||||
<u-modal :show="qrCodeShow" :title="group.name" @confirm="qrCodeShow = false">
|
||||
<view class="slot-content">
|
||||
<uqrcode class="info-code-src" :size="198" :text="qrContent" />
|
||||
</view>
|
||||
<view class="slot-content"> <uqrcode class="info-code-src" :size="198" :text="qrContent" /> </view>
|
||||
</u-modal>
|
||||
|
||||
<u-action-sheet @select="doAction" :actions="joinTypeMap" cancelText="取消" :show="showActions" @close="showActions=false" />
|
||||
@@ -57,12 +56,18 @@
|
||||
uploads
|
||||
} from '@/apis/interfaces/uploading'
|
||||
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
|
||||
import groupUserList from '../components/groupUserList'
|
||||
|
||||
import groupUserList from '../components/groupUserList'
|
||||
import onGroupDismiss from '../mixins/onGroupDismiss.js'
|
||||
import imBase from '../mixins/imBase.js'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
groupUserList
|
||||
},
|
||||
},
|
||||
mixins: [
|
||||
imBase,
|
||||
onGroupDismiss
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
targetId: '',
|
||||
@@ -84,10 +89,15 @@
|
||||
onLoad(e) {
|
||||
this.targetId = e.targetId
|
||||
this.qrContent += e.targetId
|
||||
RongIMLib.getConversationNotificationStatus(this.conversationType, this.targetId, ({status}) => {
|
||||
RongIMLib.getConversationNotificationStatus(this.conversationType, this.targetId, ({
|
||||
status
|
||||
}) => {
|
||||
this.status = !Boolean(status)
|
||||
})
|
||||
RongIMLib.getConversation(this.conversationType, this.targetId, ({code,conversation}) => {
|
||||
RongIMLib.getConversation(this.conversationType, this.targetId, ({
|
||||
code,
|
||||
conversation
|
||||
}) => {
|
||||
if (code == 0) {
|
||||
this.isTop = conversation.isTop
|
||||
}
|
||||
@@ -95,9 +105,12 @@
|
||||
this.initData()
|
||||
uni.$on('groupAnnouncementCreated', this.initData)
|
||||
uni.$on('groupInvitedUser', this.updateUserList)
|
||||
uni.$on('updateAnnouncement', this.initData)
|
||||
},
|
||||
onUnload() {
|
||||
uni.$off('groupAnnouncementCreated')
|
||||
uni.$off('groupInvitedUser')
|
||||
uni.$off('updateAnnouncement')
|
||||
},
|
||||
methods: {
|
||||
updateUserList() {
|
||||
@@ -105,7 +118,6 @@
|
||||
},
|
||||
initData() {
|
||||
getGroupInfo(this.targetId).then(res => {
|
||||
console.log(res,'群信息。。。。。')
|
||||
this.group = res.group
|
||||
this.groupName = res.group.name
|
||||
this.announcement = res.announcement
|
||||
@@ -119,7 +131,6 @@
|
||||
return item.key == res.join_type
|
||||
})[0].name
|
||||
}).catch(err => {
|
||||
console.log('getGroupInfo ERR', err);
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: '群不存在'
|
||||
@@ -152,9 +163,9 @@
|
||||
this.qrCodeShow = true
|
||||
},
|
||||
// 群聊邀请待确认
|
||||
showGroupsSure(){
|
||||
showGroupsSure() {
|
||||
uni.navigateTo({
|
||||
url:"/pages/im/group/reviewed?id="+this.targetId
|
||||
url: "/pages/im/group/reviewed?targetId=" + this.targetId
|
||||
})
|
||||
},
|
||||
onGroupName() {
|
||||
@@ -243,8 +254,11 @@
|
||||
}
|
||||
return item
|
||||
})
|
||||
this.initData()
|
||||
this.joinType = e.name
|
||||
this.$nextTick(() => {
|
||||
this.$refs.userList.initGroupInfo()
|
||||
this.initData()
|
||||
})
|
||||
this.showActions = false
|
||||
}).catch(err => {
|
||||
console.log(err);
|
||||
@@ -326,6 +340,20 @@
|
||||
.cells {
|
||||
margin-top: $padding;
|
||||
background-color: white;
|
||||
|
||||
.announcement-label {
|
||||
font-size: $title-size-m + 2;
|
||||
padding-top: 10rpx;
|
||||
color: $text-gray-m;
|
||||
overflow: hidden;
|
||||
width: 620rpx;
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 3;
|
||||
}
|
||||
}
|
||||
|
||||
.members {
|
||||
@@ -347,5 +375,4 @@
|
||||
.u-border-bottom {
|
||||
border-bottom: solid 1rpx #f9f9f9 !important;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
<template>
|
||||
<view class="invite">
|
||||
<view class="search">
|
||||
<u--input class="search-input" placeholder="搜索" border="none" prefixIcon="search" v-model="searchTxt"
|
||||
<view class="search u-border-bottom">
|
||||
<u--input class="search-input" placeholder="搜索好友" border="none" prefixIcon="search" v-model="searchTxt"
|
||||
disabledColor="#Fff" prefixIconStyle="font-size: 22px;color: #909399" @change="onSearch" />
|
||||
</view>
|
||||
<block v-if="friends.length > 0">
|
||||
<u-index-list :index-list="indexs" inactiveColor="#666" activeColor="#34CE98">
|
||||
<u-checkbox-group v-if="friends.length > 0" v-model="checkboxValue" placement="column">
|
||||
<u-index-item v-for="(item, fkey) in friends" :key="fkey">
|
||||
<u-index-anchor :text="indexs[fkey]" v-if="indexs[fkey]" bgColor="#ededed" height="20" size="12"
|
||||
color="#666" style="padding:10rpx 30rpx" />
|
||||
<u-index-anchor :text="indexs[fkey]" v-if="indexs[fkey]" bgColor="#f9f9f9f" height="20"
|
||||
size="12" color="#666"
|
||||
style="border:none !important;padding: 10rpx 30rpx;background-color: #f9f9f9 !important;" />
|
||||
<view v-for="(friendItem, index) in item" :key="index" class="friend-flex"
|
||||
@click="addContact(friendItem.targetId)">
|
||||
<u-checkbox :name="friendItem.targetId" shape="circle" activeColor="#34ce98"
|
||||
@@ -25,7 +26,8 @@
|
||||
</u-checkbox-group>
|
||||
</u-index-list>
|
||||
<view class="bottom">
|
||||
<span class="onInvite" @click="onInvite">完成<span>{{`(${checkboxValue.length})` || ''}}</span></span>
|
||||
<span class="onInvite" v-if="canInvite"> 添加中<span>{{`(${checkboxValue.length})` || ''}}</span></span>
|
||||
<span class="onInvite" v-else @click="onInvite">完成<span>{{`(${checkboxValue.length})` || ''}}</span></span>
|
||||
</view>
|
||||
</block>
|
||||
<view class="no-lists" v-else>
|
||||
@@ -44,10 +46,15 @@
|
||||
getGroupUsers
|
||||
} from '@/apis/interfaces/im';
|
||||
import utils from '@/utils/index.js'
|
||||
|
||||
import onGroupDismiss from '../mixins/onGroupDismiss.js'
|
||||
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
|
||||
import imBase from '../mixins/imBase.js'
|
||||
|
||||
export default {
|
||||
mixins: [
|
||||
imBase,
|
||||
onGroupDismiss
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
searchTxt: '',
|
||||
@@ -57,35 +64,28 @@
|
||||
friends: [],
|
||||
orignalFriends: [],
|
||||
checkboxValue: [],
|
||||
selectValue: []
|
||||
selectValue: [],
|
||||
canInvite:false
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
contact() {
|
||||
return function(targetId) {
|
||||
return this.$store.getters.contactInfo(targetId)
|
||||
}
|
||||
}
|
||||
},
|
||||
onLoad(e) {
|
||||
this.targetId = e.targetId
|
||||
this.getFriendList()
|
||||
},
|
||||
methods: {
|
||||
onSearch(val) {
|
||||
if (val) {
|
||||
var ix = []
|
||||
onSearch() {
|
||||
if (this.searchTxt) {
|
||||
this.friends = this.orignalFriends.map((list, index) => {
|
||||
const resList = list.filter(item => item.name.indexOf(val) > 0)
|
||||
if (resList.length > 0) {
|
||||
this.indexs = this.orignalIndexs.map((t, i) => {})
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
const resList = list.filter(item => {
|
||||
return item.name.indexOf(this.searchTxt) >= 0
|
||||
})
|
||||
return resList
|
||||
})
|
||||
this.friends = this.friends.filter(n => n)
|
||||
|
||||
this.indexs = this.orignalIndexs.map((t, i) => {
|
||||
if (this.friends[i].length > 0) {
|
||||
return t
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.friends = this.orignalFriends
|
||||
this.indexs = this.orignalIndexs
|
||||
@@ -103,6 +103,7 @@
|
||||
})
|
||||
getGroupUsers(this.targetId).then(res => {
|
||||
res.map(res => {
|
||||
console.log(res)
|
||||
this.checkboxValue.push(String(res.targetId))
|
||||
this.selectValue.push(String(res.targetId))
|
||||
})
|
||||
@@ -123,15 +124,26 @@
|
||||
|
||||
},
|
||||
onInvite() {
|
||||
inviteGroupUser(this.targetId, this.checkboxValue).then(res => {
|
||||
console.log(res, 'res')
|
||||
console.log(this.checkboxValue, 'userIds.....')
|
||||
console.log(this.selectValue, 'userIds.....')
|
||||
this.canInvite = true
|
||||
let userIds = []
|
||||
this.checkboxValue.filter(item => {
|
||||
if (!utils.inArray(item, this.selectValue)) {
|
||||
userIds.push(item)
|
||||
}
|
||||
})
|
||||
// console.log(userIds)
|
||||
inviteGroupUser(this.targetId, this.checkboxValue, userIds).then(res => {
|
||||
uni.navigateBack({
|
||||
delta: 1,
|
||||
animationType: 'pop-out',
|
||||
animationDuration: 200
|
||||
});
|
||||
});
|
||||
this.canInvite = false
|
||||
uni.$emit('groupInvitedUser')
|
||||
}).catch(err => {
|
||||
}).catch(err => {
|
||||
this.canInvite = false
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: err.message
|
||||
|
||||
@@ -1,79 +1,175 @@
|
||||
<!-- 群聊邀请确认列表页面 -->
|
||||
<template>
|
||||
<view class="reviewed">
|
||||
<view class="reviewed-item">
|
||||
<u-avatar class="avatar" src="require('@/static/user/cover.png')" shape="square" size="36" />
|
||||
<view style="flex:1;">
|
||||
<view class="nickname"><span>{{`艾米的猫儿 `}}</span>想邀请<span>{{` 用户8066`}}</span>加入群聊</view>
|
||||
<view> 申请原因:{{`呵呵哒。。`}}</view>
|
||||
</view>
|
||||
<view class="sure" @click="sure(2)"> 通过 </view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getGroupMakeSure,
|
||||
getGroupMakeSureAllow
|
||||
} from "@/apis/interfaces/im.js"
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
lists: [],
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
|
||||
sure(id) {
|
||||
console.log(id, '....')
|
||||
uni.navigateTo({
|
||||
url: "/pages/im/group/reviewedInfo?id=" + id
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.reviewed {
|
||||
.reviewed-item {
|
||||
margin: $padding - 10;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: flex-start;
|
||||
justify-content: flex-start;
|
||||
box-sizing: border-box;
|
||||
border-bottom: solid 1rpx #f9f9f9;
|
||||
font-size: $title-size-m - 2;
|
||||
padding-bottom: 20rpx;
|
||||
color: $text-gray-m;
|
||||
|
||||
.avatar {
|
||||
background-color: $main-color;
|
||||
border-radius: 6rpx;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.nickname {
|
||||
font-size: $title-size-m;
|
||||
|
||||
span {
|
||||
color: $text-color;
|
||||
font-size: $title-size-m +1;
|
||||
}
|
||||
}
|
||||
|
||||
.sure {
|
||||
background-color: $main-color;
|
||||
color: #Fff;
|
||||
text-align: center;
|
||||
font-size: $title-size-m;
|
||||
padding: 6rpx 20rpx;
|
||||
border-radius: 10rpx;
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
<!-- 群聊邀请确认列表页面 -->
|
||||
<template>
|
||||
<view class="reviewed">
|
||||
<block v-if="pendings.length > 0">
|
||||
<view class="reviewed-item" v-for="(item, index) in pendings" :key="index">
|
||||
<u-avatar class="avatar"
|
||||
:src="JSON.parse(item.content.extra).portraitUrl || require('@/static/user/cover.png')"
|
||||
shape="square" size="46" />
|
||||
<view style="flex:1;" v-if="item.content.operation == 'GroupPending'">
|
||||
<view class="nickname">{{ JSON.parse(item.content.extra).name }} 申请加入群聊</view>
|
||||
<view> 申请原因:{{ item.content.message }}</view>
|
||||
</view>
|
||||
<view style="flex:1;" v-if="item.content.operation == 'GroupInvite'">
|
||||
<view class="nickname">
|
||||
<text>{{ contact(item.content.sourceUserId).name }}</text>想邀请<span>{{ JSON.parse(item.content.extra).name }}</span>加入群聊
|
||||
</view>
|
||||
</view>
|
||||
<view class="sure" @click="sure(item.content.targetUserId,item.messageId)"> 通过 </view>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<view class="no-lists" v-else>
|
||||
<u-image class="cover" radius="4" width="400rpx" height="400rpx"
|
||||
:src="require('@/static/imgs/no-friend.png')" :lazy-load="true" />
|
||||
<span>暂无群聊申请数据</span>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import {
|
||||
getGroupMakeSure,
|
||||
getGroupMakeSureAllow,
|
||||
groupMakeSure
|
||||
} from "@/apis/interfaces/im.js"
|
||||
import im from '@/utils/im/message.js'
|
||||
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
|
||||
import onGroupDismiss from '../mixins/onGroupDismiss.js'
|
||||
import imBase from '../mixins/imBase.js'
|
||||
|
||||
export default {
|
||||
mixins: [
|
||||
imBase,
|
||||
onGroupDismiss
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
targetId: '',
|
||||
pendings: [],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
contact() {
|
||||
return function(targetId) {
|
||||
return this.$store.getters.contactInfo(targetId)
|
||||
}
|
||||
}
|
||||
},
|
||||
onLoad(e) {
|
||||
this.targetId = e.targetId
|
||||
this.getList()
|
||||
},
|
||||
methods: {
|
||||
getList() {
|
||||
im.getGroupPendinglist(this.targetId, (result) => {
|
||||
console.log(result)
|
||||
this.pendings = result
|
||||
})
|
||||
},
|
||||
sure(userId, latestMessageId) {
|
||||
groupMakeSure(this.targetId, userId).then(res => {
|
||||
// 清除聊天列表
|
||||
RongIMLib.deleteMessagesByIds([latestMessageId], ({
|
||||
code
|
||||
}) => {
|
||||
console.log('code', code)
|
||||
if (code == 0) {
|
||||
uni.showToast({
|
||||
title: ` 通过 `,
|
||||
icon: 'none',
|
||||
mask: true,
|
||||
duration: 2000
|
||||
})
|
||||
this.getList()
|
||||
uni.$emit('groupInvitedUser')
|
||||
}
|
||||
})
|
||||
}).catch(err => {
|
||||
// uni.showToast({
|
||||
// title: err.message,
|
||||
// icon: 'none',
|
||||
// mask: true,
|
||||
// duration: 2000
|
||||
// })
|
||||
RongIMLib.deleteMessagesByIds([latestMessageId], ({
|
||||
code
|
||||
}) => {
|
||||
console.log('code', code)
|
||||
if (code == 0) {
|
||||
uni.showToast({
|
||||
title: err.message,
|
||||
icon: 'none',
|
||||
mask: true,
|
||||
duration: 2000
|
||||
})
|
||||
this.getList()
|
||||
uni.$emit('groupInvitedUser')
|
||||
}
|
||||
})
|
||||
})
|
||||
// 直接调用通过或拒绝的接口
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.reviewed {
|
||||
.reviewed-item {
|
||||
margin: $padding - 10;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: flex-start;
|
||||
justify-content: flex-start;
|
||||
box-sizing: border-box;
|
||||
border-bottom: solid 1rpx #f9f9f9;
|
||||
font-size: $title-size-m;
|
||||
padding-bottom: 20rpx;
|
||||
color: $text-gray-m;
|
||||
|
||||
.avatar {
|
||||
background-color: $main-color;
|
||||
border-radius: 6rpx;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.nickname {
|
||||
font-size: $title-size;
|
||||
color: $text-color;
|
||||
padding-bottom: 6rpx;
|
||||
|
||||
span {
|
||||
color: $text-color;
|
||||
font-size: $title-size-m +1;
|
||||
padding-top: 20rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.sure {
|
||||
background-color: $main-color;
|
||||
color: #Fff;
|
||||
text-align: center;
|
||||
font-size: $title-size-m;
|
||||
padding: 6rpx 20rpx;
|
||||
border-radius: 10rpx;
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.no-lists {
|
||||
padding-top: $padding * 5;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-sizing: border-box;
|
||||
font-size: $title-size-m;
|
||||
color: $text-gray-m;
|
||||
|
||||
span {
|
||||
padding-top: $padding;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
<!-- 群聊邀请确认列表页面 -->
|
||||
<template>
|
||||
<view class="reviewed">
|
||||
确认信息页面
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
lists: [],
|
||||
};
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
sure(id) {
|
||||
uni.navigateTo({
|
||||
url:"/pages/im/group/reviewedInfo?id="+id
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.reviewed {
|
||||
.reviewed-item {
|
||||
margin: $padding;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
box-sizing: border-box;
|
||||
border-bottom: solid 1rpx #f9f9f9;
|
||||
font-size: $title-size-m;
|
||||
padding-bottom: 20rpx;
|
||||
color: $text-gray;
|
||||
|
||||
.add-icon {
|
||||
background-color: $main-color;
|
||||
padding: 10rpx;
|
||||
border-radius: 6rpx;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.sure {
|
||||
// width: 140rpx;
|
||||
// background-color: $main-color;
|
||||
color: $main-color;
|
||||
text-align: center;
|
||||
font-size: $title-size-m;
|
||||
padding: 6rpx 20rpx;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
@@ -4,7 +4,12 @@
|
||||
|
||||
<script>
|
||||
import groupUserList from '../components/groupUserList'
|
||||
import onGroupDismiss from '../mixins/onGroupDismiss.js'
|
||||
|
||||
export default {
|
||||
mixins: [
|
||||
onGroupDismiss
|
||||
],
|
||||
components: {
|
||||
groupUserList
|
||||
},
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
</view>
|
||||
</view>
|
||||
<!-- content -->
|
||||
<view v-if="$store.state.token !== ''">
|
||||
<view v-if="$store.state.token !== ''">
|
||||
<connection-status :connection="connection" />
|
||||
<conversation-list @refresh="getConversationList()" :conversations="conversations" />
|
||||
</view>
|
||||
@@ -46,7 +46,8 @@
|
||||
return {
|
||||
conversations: [], // 会话列表
|
||||
connection: 0,
|
||||
hasNewFriends: 0
|
||||
hasNewFriends: 0,
|
||||
perPage: 200
|
||||
}
|
||||
},
|
||||
components: {
|
||||
@@ -54,35 +55,37 @@
|
||||
connectionStatus
|
||||
},
|
||||
onLoad() {
|
||||
// 好友申请数量
|
||||
this.checkNewFriendPending()
|
||||
// 监听新的好友申请
|
||||
uni.$on('onContactNotification', () => {
|
||||
uni.$on('onNewContactConversation', () => {
|
||||
console.log('更新好友申请数量');
|
||||
// 更新好友申请数量
|
||||
this.checkNewFriendPending()
|
||||
})
|
||||
},
|
||||
onShow() {
|
||||
// 好友申请数量
|
||||
this.checkNewFriendPending()
|
||||
|
||||
if (this.$store.state.token !== '') {
|
||||
this.getConversationList()
|
||||
}
|
||||
uni.$on('onConnectionStatusChange', (status) => {
|
||||
this.connection = status
|
||||
})
|
||||
// 监听新消息
|
||||
uni.$on('onReceiveMessage', (msg) => {
|
||||
this.getConversationList()
|
||||
})
|
||||
// 监听网络状态变化
|
||||
uni.$on('onConnectionStatusChange', (status) => {
|
||||
this.connection = status
|
||||
if (status == 0) {
|
||||
this.getConversationList()
|
||||
}
|
||||
})
|
||||
},
|
||||
onHide() {
|
||||
uni.$off('onReceiveMessage')
|
||||
uni.$off('onConnectionStatusChange')
|
||||
},
|
||||
methods: {
|
||||
onDemo(){
|
||||
console.log('1111')
|
||||
uni.navigateTo({
|
||||
url: '/pages/im/chatDemo'
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
checkNewFriendPending() {
|
||||
im.getPendingList((pendings) => {
|
||||
this.hasNewFriends = pendings.length
|
||||
@@ -97,15 +100,14 @@
|
||||
}
|
||||
return true
|
||||
},
|
||||
// 获取私聊的会话列表
|
||||
// 获取会话列表,最新的一千条
|
||||
getConversationList() {
|
||||
const count = 1000
|
||||
const timestamp = 0
|
||||
RongIMLib.getConversationList([1, 3], count, timestamp, ({
|
||||
RongIMLib.getConversationList([1, 3], this.perPage, 0, ({
|
||||
code,
|
||||
conversations
|
||||
}) => {
|
||||
if (code === 0) {
|
||||
if (code === 0) {
|
||||
console.log(conversations,',,,,,')
|
||||
this.conversations = conversations
|
||||
}
|
||||
})
|
||||
|
||||
22
pages/im/mixins/imBase.js
Normal file
22
pages/im/mixins/imBase.js
Normal file
@@ -0,0 +1,22 @@
|
||||
import utils from '@/utils/index.js'
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
contact() {
|
||||
return function(targetId) {
|
||||
return this.$store.getters.contactInfo(targetId)
|
||||
}
|
||||
},
|
||||
avatarSize() {
|
||||
return utils.rpx2px(84)
|
||||
},
|
||||
sender() {
|
||||
return this.$store.getters.sender
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
rpx2px(size) {
|
||||
return utils.rpx2px(size)
|
||||
}
|
||||
}
|
||||
}
|
||||
133
pages/im/mixins/messageActions.js
Normal file
133
pages/im/mixins/messageActions.js
Normal file
@@ -0,0 +1,133 @@
|
||||
import * as IMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
winSize: {},
|
||||
showPop: false,
|
||||
/* 弹窗按钮列表 */
|
||||
popButton: ['复制', '删除', '撤回'],
|
||||
/* 弹窗定位样式 */
|
||||
popStyle: "",
|
||||
pickedItem: {}
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
uni.getSystemInfo({
|
||||
success: (e) => {
|
||||
this.winSize = {
|
||||
width: e.windowWidth,
|
||||
height: e.windowHeight
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
// 隐藏功能菜单
|
||||
hidePop() {
|
||||
this.showPop = false
|
||||
this.pickedItem = {}
|
||||
setTimeout(() => {
|
||||
this.showShade = false
|
||||
}, 250)
|
||||
},
|
||||
// 点击会话功能菜单
|
||||
pickerMenu(e) {
|
||||
const msg = this.pickedItem
|
||||
console.log(msg);
|
||||
switch (e) {
|
||||
case '复制':
|
||||
uni.setClipboardData({
|
||||
data: msg.content.content
|
||||
})
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: '复制成功'
|
||||
})
|
||||
break;
|
||||
case '删除':
|
||||
IMLib.deleteMessagesByIds([msg.messageId], ({
|
||||
code
|
||||
}) => {
|
||||
if (code === 0) {
|
||||
uni.$emit('onRemoveMessage_' + msg.targetId, msg.messageId)
|
||||
uni.showToast({
|
||||
title: '消息删除成功',
|
||||
icon: 'none',
|
||||
})
|
||||
}
|
||||
})
|
||||
break;
|
||||
case '撤回':
|
||||
const pushContent = this.$store.getters.sender.name + '撤回了一条消息'
|
||||
IMLib.recallMessage(msg.messageId, pushContent,
|
||||
({
|
||||
code,
|
||||
message
|
||||
}) => {
|
||||
if (code === 0) {
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: '消息撤回成功'
|
||||
})
|
||||
msg.objectName = 'RC:RcNtf'
|
||||
uni.$emit('onRecallMessage_' + msg.targetId, msg)
|
||||
} else {
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: '撤回失败' + code
|
||||
})
|
||||
}
|
||||
}
|
||||
)
|
||||
break;
|
||||
}
|
||||
this.hidePop()
|
||||
},
|
||||
messageAction(e) {
|
||||
let [touches, style, item] = [e.event.touches[0], "", e.message]
|
||||
|
||||
if (touches.clientY > (this.winSize.height / 2)) {
|
||||
style = `bottom:${this.winSize.height-touches.clientY}px;`
|
||||
} else {
|
||||
style = `top:${touches.clientY}px;`
|
||||
}
|
||||
|
||||
if (touches.clientX > (this.winSize.width / 2)) {
|
||||
style += `right:${this.winSize.width-touches.clientX}px`
|
||||
} else {
|
||||
style += `left:${touches.clientX}px`
|
||||
}
|
||||
|
||||
if (item.messageDirection == 2) {
|
||||
if (item.objectName == 'RC:TxtMsg') {
|
||||
this.popButton = ['复制', '删除']
|
||||
} else {
|
||||
this.popButton = ['删除']
|
||||
}
|
||||
} else {
|
||||
if ((new Date()).getTime() - item.sentTime > 120 * 1000) {
|
||||
if (item.objectName == 'RC:TxtMsg') {
|
||||
this.popButton = ['复制', '删除']
|
||||
} else {
|
||||
this.popButton = ['删除']
|
||||
}
|
||||
} else {
|
||||
if (item.objectName == 'RC:TxtMsg') {
|
||||
this.popButton = ['复制', '撤回']
|
||||
} else {
|
||||
this.popButton = ['删除']
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.popStyle = style
|
||||
this.pickedItem = item
|
||||
this.$nextTick(() => {
|
||||
setTimeout(() => {
|
||||
this.showPop = true;
|
||||
}, 10)
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
34
pages/im/mixins/onGroupDismiss.js
Normal file
34
pages/im/mixins/onGroupDismiss.js
Normal file
@@ -0,0 +1,34 @@
|
||||
// 监听群解散的消息,直接跳转到会话列表页面
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
currentTargetId: ''
|
||||
}
|
||||
},
|
||||
onLoad(e) {
|
||||
this.currentTargetId = e.targetId
|
||||
|
||||
uni.$once('onGroupDismiss_' + e.targetId, () => {
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: '当前群已解散'
|
||||
})
|
||||
uni.switchTab({
|
||||
url: '/pages/im/index'
|
||||
})
|
||||
})
|
||||
uni.$once('onGroupRemoveYou_' + e.targetId, () => {
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: '您已被移出群聊'
|
||||
})
|
||||
uni.switchTab({
|
||||
url: '/pages/im/index'
|
||||
})
|
||||
})
|
||||
},
|
||||
onUnload() {
|
||||
uni.$off('onGroupDismiss_' + this.currentTargetId)
|
||||
uni.$off('onGroupRemoveYou_' + this.currentTargetId)
|
||||
}
|
||||
}
|
||||
@@ -1,27 +1,30 @@
|
||||
<template>
|
||||
<view class="call">
|
||||
<view class="video">
|
||||
<RongCloud-Call-RCUniCallView ref="bigVideoView" :style="{width:windowWidth+'px',height:windowHeight+'px'}"
|
||||
class="bigVideoView">
|
||||
</RongCloud-Call-RCUniCallView>
|
||||
<RongCloud-Call-RCUniCallView ref="smallVideoView" class="smallVideoView">
|
||||
<RongCloud-Call-RCUniCallView ref="bigVideoView" :style="bigVideoStyle" class="bigVideoView">
|
||||
</RongCloud-Call-RCUniCallView>
|
||||
|
||||
<movable-area class="movableArea" :style="movableAreaStyle">
|
||||
<movable-view class="movableView" direction="all" :x="50" :y="50" v-if="mediaType == 1 && connected">
|
||||
<RongCloud-Call-RCUniCallView ref="smallVideoView" class="smallVideoView" @click="changeMine">
|
||||
</RongCloud-Call-RCUniCallView>
|
||||
</movable-view>
|
||||
</movable-area>
|
||||
</view>
|
||||
|
||||
<view class="status" v-if="!connected || mediaType == 0">
|
||||
<view class="status" v-if="!connected">
|
||||
<view class="remote">
|
||||
<u-avatar :src="contact(targetId).portraitUrl" shape="square" size="96" bgColor="#fff" />
|
||||
<u-avatar :src="contact(targetId).portraitUrl" shape="square" :size="avatarSize" bgColor="#fff" />
|
||||
<view><text class="nickname">{{ contact(targetId).name }}</text></view>
|
||||
<view v-if="remoteRinging"><text class="mediaType">等待对方接听</text></view>
|
||||
<view v-if="connected"><text class="mediaType">已接通</text></view>
|
||||
<view v-else><text class="mediaType">{{ mediaType == 0 ? '邀请您语音通话' : '邀请您视频通话' }}</text></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="buttons">
|
||||
<view class="btn" v-if="connected" @click="changeMicrophone">
|
||||
<view class="icon">
|
||||
<u-icon name="mic" color="#ffffff" size="30" />
|
||||
<u-icon name="mic-off" color="#ffffff" size="30" />
|
||||
<u-icon name="mic-off" color="#ffffff" size="30" v-if="micOff" />
|
||||
<u-icon name="mic" color="#ffffff" size="30" v-else />
|
||||
</view>
|
||||
<text class="text">麦克风</text>
|
||||
</view>
|
||||
@@ -31,7 +34,7 @@
|
||||
</view>
|
||||
<text class="text">挂断</text>
|
||||
</view>
|
||||
<view class="btn" v-if="!connected" @click="accept">
|
||||
<view class="btn" v-if="!connected && this.isCall == false" @click="accept">
|
||||
<view class="icon">
|
||||
<u-icon name="checkmark" color="#ffffff" size="30" />
|
||||
</view>
|
||||
@@ -39,8 +42,8 @@
|
||||
</view>
|
||||
<view class="btn" v-if="connected" @click="changeSpeaker">
|
||||
<view class="icon">
|
||||
<u-icon name="volume-fill" color="#ffffff" size="27" />
|
||||
<u-icon name="volume-off-fill" color="#ffffff" size="27" />
|
||||
<u-icon name="volume-off-fill" color="#ffffff" size="27" v-if="volumeOff" />
|
||||
<u-icon name="volume-fill" color="#ffffff" size="27" v-else />
|
||||
</view>
|
||||
<text class="text">扬声器</text>
|
||||
</view>
|
||||
@@ -51,25 +54,46 @@
|
||||
<script>
|
||||
import * as CallLib from '@/uni_modules/RongCloud-CallWrapper/lib/index'
|
||||
import * as IMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
|
||||
import utils from '@/utils/index.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
targetId: '',
|
||||
mediaType: 0, // 0 语音 1 视频
|
||||
isOut: false,
|
||||
connected: false,
|
||||
micStatus: false,
|
||||
speStatus: false,
|
||||
remoteRinging: false,
|
||||
ring: null
|
||||
ring: null,
|
||||
isCall: false,
|
||||
avatarSize: 96,
|
||||
bigVideoStyle: {},
|
||||
movableAreaStyle: {},
|
||||
// 关闭麦克风
|
||||
micOff: false,
|
||||
// 关闭扬声器
|
||||
volumeOff: false,
|
||||
// 通话时长
|
||||
duration: 0,
|
||||
interval: null
|
||||
}
|
||||
},
|
||||
onLoad(e) {
|
||||
this.avatarSize = utils.rpx2px(200)
|
||||
this.targetId = e.targetId
|
||||
this.mediaType = e.mediaType
|
||||
this.isCall = Boolean(e.isCall)
|
||||
// 进入页面开启外呼
|
||||
CallLib.startSingleCall(this.targetId, this.mediaType, '');
|
||||
if (this.isCall) {
|
||||
CallLib.startSingleCall(this.targetId, this.mediaType, '');
|
||||
if (this.mediaType == 1) {
|
||||
const session = CallLib.getCurrentCallSession()
|
||||
setTimeout(() => {
|
||||
CallLib.setVideoView(session.mine.userId, this.$refs.bigVideoView.ref, 0, false)
|
||||
}, 200)
|
||||
}
|
||||
}
|
||||
// 响铃
|
||||
this.startRing()
|
||||
// 监听通话链接状态
|
||||
@@ -81,6 +105,14 @@
|
||||
uni.$once('onRemoteUserJoined', () => {
|
||||
this.remoteRinging = false
|
||||
})
|
||||
this.bigVideoStyle = {
|
||||
width: this.windowWidth + 'px',
|
||||
height: this.windowHeight + 'px',
|
||||
}
|
||||
this.movableAreaStyle = {
|
||||
width: this.windowWidth + 'px',
|
||||
height: this.windowHeight + 'px',
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
|
||||
@@ -99,11 +131,36 @@
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
afterHangup() {
|
||||
clearInterval(this.interval)
|
||||
const targetId = this.targetId
|
||||
const sentStatus = 30
|
||||
const messageContent = {
|
||||
objectName: 'RC:InfoNtf',
|
||||
userInfo: this.$store.getters.sender,
|
||||
message: JSON.stringify({
|
||||
mediaType: this.mediaType,
|
||||
connected: this.connected,
|
||||
duration: this.duration
|
||||
})
|
||||
}
|
||||
const sentTime = 0
|
||||
if (this.isCall) {
|
||||
IMLib.insertOutgoingMessage(1, targetId, sentStatus, messageContent, sentTime)
|
||||
} else {
|
||||
IMLib.insertIncomingMessage(1, targetId, targetId, sentStatus, messageContent, sentTime)
|
||||
}
|
||||
uni.$emit('onReceiveMessage_' + this.targetId, {
|
||||
targetId: this.targetId
|
||||
})
|
||||
},
|
||||
changeMicrophone() {
|
||||
this.micOff = !this.micOff
|
||||
CallLib.enableMicrophone(this.micStatus)
|
||||
this.micStatus = !this.micStatus
|
||||
},
|
||||
changeSpeaker() {
|
||||
this.volumeOff = !this.volumeOff
|
||||
CallLib.enableSpeaker(this.speStatus)
|
||||
this.speStatus = !this.speStatus
|
||||
},
|
||||
@@ -122,10 +179,31 @@
|
||||
CallLib.setVideoView(session.targetId, this.$refs.bigVideoView.ref, 0, false)
|
||||
CallLib.setVideoView(session.mine.userId, this.$refs.smallVideoView.ref, 0, true)
|
||||
}, 200)
|
||||
}
|
||||
}
|
||||
this.interval = setInterval(() => {
|
||||
this.duration++
|
||||
}, 1000)
|
||||
},
|
||||
// 切换主屏显示人
|
||||
changeMine() {
|
||||
// if (this.isCall) {
|
||||
// const session = CallLib.getCurrentCallSession()
|
||||
// setTimeout(() => {
|
||||
// CallLib.setVideoView(session.targetId, this.$refs.bigVideoView.ref, 0, false)
|
||||
// CallLib.setVideoView(session.mine.userId, this.$refs.smallVideoView.ref, 0, true)
|
||||
// }, 200)
|
||||
// } else {
|
||||
// const session = CallLib.getCurrentCallSession()
|
||||
// setTimeout(() => {
|
||||
// CallLib.setVideoView(session.targetId, this.$refs.smallVideoView.ref, 0, true)
|
||||
// CallLib.setVideoView(session.mine.userId, this.$refs.bigVideoView.ref, 0, false)
|
||||
// }, 200)
|
||||
// }
|
||||
// this.isCall = !this.isCall
|
||||
},
|
||||
hangup() {
|
||||
CallLib.hangup()
|
||||
this.afterHangup()
|
||||
this.stopRing()
|
||||
|
||||
setTimeout(() => {
|
||||
@@ -171,23 +249,33 @@
|
||||
position: relative;
|
||||
|
||||
.video {
|
||||
.bigVideoView {
|
||||
background: #000;
|
||||
.movableArea {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
|
||||
.movableView {
|
||||
width: 180rpx;
|
||||
height: 320rpx;
|
||||
position: relative;
|
||||
|
||||
.smallVideoView {
|
||||
width: 180rpx;
|
||||
height: 320rpx;
|
||||
background-color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.smallVideoView {
|
||||
background: blue;
|
||||
position: absolute;
|
||||
right: 100rpx;
|
||||
top: 100rpx;
|
||||
width: 180rpx;
|
||||
height: 320rpx;
|
||||
.bigVideoView {
|
||||
background-color: #666;
|
||||
}
|
||||
}
|
||||
|
||||
.status {
|
||||
flex: 1;
|
||||
background: #666;
|
||||
width: 750rpx;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
@@ -226,10 +314,6 @@
|
||||
.btn {
|
||||
align-items: center;
|
||||
|
||||
&.hangup {
|
||||
background: $text-price;
|
||||
}
|
||||
|
||||
.icon {
|
||||
background: $main-color;
|
||||
width: 132rpx;
|
||||
@@ -238,6 +322,10 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
&.hangup {
|
||||
background-color: $text-price;
|
||||
}
|
||||
}
|
||||
|
||||
.text {
|
||||
|
||||
@@ -1,46 +1,41 @@
|
||||
<template>
|
||||
<view class="chat">
|
||||
<sent-message-bar :conversationType="conversationType" :targetId="targetId" @onSuccess="getNewMessage()" />
|
||||
<view class="shade" @click="hidePop" v-show="showPop">
|
||||
<view class="pop" :style="popStyle" :class="{'show':showPop}">
|
||||
<view v-for="(item, index) in popButton" :key="index" @click="pickerMenu(item)">
|
||||
{{ item }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- chat -->
|
||||
<view class="body">
|
||||
<view class="scroll">
|
||||
<view class="cell" v-for="(item, index) in messages" :key="index">
|
||||
<view class="time">{{ item.sentTime|timeCustomCN }}</view>
|
||||
<view :class="['cell-item', item.messageDirection == 1 ? 'right' : 'left']">
|
||||
<u-avatar class="avatar" size="40" shape="square"
|
||||
@click="showUser(item.senderUserId, item.messageDirection)"
|
||||
:src="contact(item.senderUserId).portraitUrl" />
|
||||
<view class="msg">
|
||||
<show-voice v-if="item.objectName === 'RC:HQVCMsg'" :guest="item.messageDirection == 1"
|
||||
:msg="item.content" />
|
||||
<show-image v-if="item.objectName === 'RC:ImgMsg'" :guest="item.messageDirection == 1"
|
||||
:msg="item.content" />
|
||||
<show-text v-if="item.objectName === 'RC:TxtMsg'" :guest="item.messageDirection == 1"
|
||||
:msg="item.content" />
|
||||
<view class="state" v-if="item.messageDirection == 1">
|
||||
<text
|
||||
:class="item.sentStatus === 50?'state-text':'state-text-active'">{{ item.sentStatus == 50 ? '已读': '未读'}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="cell" v-for="(message, index) in messages" :key="index">
|
||||
<show-message-cell :message="message" @messageAction="messageAction" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
|
||||
import im from '@/utils/im/index.js'
|
||||
import showVoice from '../components/showVoice'
|
||||
import showImage from '../components/showImage'
|
||||
import showText from '../components/showText'
|
||||
import sentMessageBar from '../components/sentMessageBar'
|
||||
import showMessageCell from '../components/showMessageCell'
|
||||
import utils from '@/utils/index.js'
|
||||
import imBase from '../mixins/imBase.js'
|
||||
import messageActions from '../mixins/messageActions.js'
|
||||
|
||||
export default {
|
||||
mixins: [
|
||||
imBase,
|
||||
messageActions
|
||||
],
|
||||
components: {
|
||||
sentMessageBar,
|
||||
showVoice,
|
||||
showImage,
|
||||
showText
|
||||
showMessageCell
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -63,11 +58,6 @@
|
||||
sentTime: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
contact() {
|
||||
return function(targetId) {
|
||||
return this.$store.getters.contactInfo(targetId)
|
||||
}
|
||||
}
|
||||
},
|
||||
onLoad(e) {
|
||||
@@ -78,6 +68,10 @@
|
||||
})
|
||||
// 获取消息列表
|
||||
this.getMessageList()
|
||||
// 监听新消息
|
||||
uni.$on('onReceiveMessage_' + this.targetId, (message) => {
|
||||
this.getNewMessage()
|
||||
})
|
||||
// 监听消息已读状态
|
||||
uni.$on('onReadReceiptReceived', (data) => {
|
||||
if (data.targetId == this.targetId) {
|
||||
@@ -90,14 +84,30 @@
|
||||
})
|
||||
}
|
||||
})
|
||||
// 监听收到新消息,判断是否是当前会话,更新会话内容
|
||||
uni.$on('onReceiveMessage', (msg) => {
|
||||
if (msg.targetId == this.targetId) {
|
||||
this.getNewMessage()
|
||||
}
|
||||
uni.$on('onRecallMessage_' + this.targetId, (message) => {
|
||||
this.messages = this.messages.map(item => {
|
||||
if (message.messageId == item.messageId) {
|
||||
return message
|
||||
} else {
|
||||
return item
|
||||
}
|
||||
})
|
||||
})
|
||||
uni.$once('onUserDelete_' + this.targetId, () => {
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: '好友关系已解除'
|
||||
})
|
||||
uni.switchTab({
|
||||
url: '/pages/im/index'
|
||||
})
|
||||
})
|
||||
},
|
||||
onUnload() {
|
||||
uni.$off('onUserDelete_' + this.targetId)
|
||||
uni.$off('onReceiveMessage_' + this.targetId)
|
||||
uni.$off('onRecallMessage_' + this.targetId)
|
||||
uni.$off('onRecallMessage')
|
||||
uni.$off('onReadReceiptReceived')
|
||||
},
|
||||
methods: {
|
||||
@@ -126,13 +136,6 @@
|
||||
this.scrollBottom()
|
||||
})
|
||||
},
|
||||
// 展示好友信息, type 1 是自己, 2 是对方
|
||||
showUser(targetId, type) {
|
||||
uni.navigateTo({
|
||||
url: type === 1 ? '/pages/im/friends/mine?targetId=' + targetId :
|
||||
'/pages/im/friends/info?targetId=' + targetId
|
||||
})
|
||||
},
|
||||
// 滚动到底部
|
||||
scrollBottom(type) {
|
||||
if (this.latestMessage) {
|
||||
@@ -147,7 +150,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
/* 窗口 */
|
||||
@@ -170,17 +173,18 @@
|
||||
justify-content: flex-end;
|
||||
|
||||
.cell {
|
||||
padding: 10rpx 30rpx;
|
||||
padding: 10rpx 20rpx;
|
||||
|
||||
.time {
|
||||
text-align: center;
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.cell-item {
|
||||
display: flex;
|
||||
width: 690rpx;
|
||||
width: 710rpx;
|
||||
justify-content: flex-start;
|
||||
|
||||
&.left {
|
||||
@@ -189,23 +193,14 @@
|
||||
|
||||
&.right {
|
||||
flex-direction: row-reverse;
|
||||
|
||||
.state {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
.msg {
|
||||
margin: 0 20rpx;
|
||||
.state {
|
||||
padding-top: 10rpx;
|
||||
.state-text {
|
||||
font-size: $title-size-m - 2;
|
||||
color: rgba($color: $main-color, $alpha: 0.3)
|
||||
}
|
||||
.state-text-active {
|
||||
font-size: $title-size-m - 2;
|
||||
color: #cecece;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -216,4 +211,47 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 遮罩 */
|
||||
.shade {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 999;
|
||||
|
||||
.pop {
|
||||
border-radius: 10rpx;
|
||||
position: fixed;
|
||||
z-index: 101;
|
||||
width: 200rpx;
|
||||
box-sizing: border-box;
|
||||
font-size: 28rpx;
|
||||
text-align: left;
|
||||
color: #333;
|
||||
background-color: #fff;
|
||||
box-shadow: 0 0 5px rgba(0, 0, 0, 0.5);
|
||||
line-height: 80rpx;
|
||||
transition: transform 0.15s ease-in-out 0s;
|
||||
user-select: none;
|
||||
-webkit-touch-callout: none;
|
||||
transform: scale(0, 0);
|
||||
|
||||
&.show {
|
||||
transform: scale(1, 1);
|
||||
}
|
||||
|
||||
&>view {
|
||||
padding: 0 20rpx;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
user-select: none;
|
||||
-webkit-touch-callout: none;
|
||||
|
||||
&:active {
|
||||
background-color: #f3f3f3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<view class="info-box">
|
||||
<image src="@/static/user/user_back.png" mode="aspectFill" />
|
||||
<view class="user-flex">
|
||||
<image class="cover" @click="$Router.push({ name: 'Setting' })"
|
||||
<image class="cover" @click="goSetting"
|
||||
:src="userInfo.avatar || require('@/static/user/cover.png')" mode="aspectFill" />
|
||||
<view class="user-content">
|
||||
<block v-if="$store.state.token != ''">
|
||||
@@ -233,6 +233,11 @@
|
||||
params
|
||||
});
|
||||
}
|
||||
},
|
||||
goSetting(){
|
||||
if (this.isLogin()) {
|
||||
this.$Router.push({ name: 'Setting' })
|
||||
}
|
||||
},
|
||||
// 检查登录
|
||||
isLogin() {
|
||||
|
||||
BIN
static/.DS_Store
vendored
BIN
static/.DS_Store
vendored
Binary file not shown.
BIN
static/icon/emoji-icon.png
Normal file
BIN
static/icon/emoji-icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.5 KiB |
795
static/im/emoji.js
Normal file
795
static/im/emoji.js
Normal file
@@ -0,0 +1,795 @@
|
||||
var EmojiFactory = {
|
||||
"u1F603": {
|
||||
"en": "Smiley Face",
|
||||
"zh": "绗戣劯",
|
||||
"tag": "\uD83D\uDE03",
|
||||
"position": "-75px 0px"
|
||||
},
|
||||
"u1F600": {
|
||||
"en": "Grinning Face",
|
||||
"zh": "绗戝樆鍢<E6A886>",
|
||||
"tag": "\uD83D\uDE00",
|
||||
"position": "0px 0px"
|
||||
},
|
||||
"u1F60A": {
|
||||
"en": "Smiley",
|
||||
"zh": "寰瑧",
|
||||
"tag": "\uD83D\uDE0A",
|
||||
"position": "-1725px 0px"
|
||||
},
|
||||
"u263A": {
|
||||
"en": "Cute",
|
||||
"zh": "钀岃悓鍝<E68293>",
|
||||
"tag": "\u263A",
|
||||
"position": "-2950px 0px"
|
||||
},
|
||||
"u1F609": {
|
||||
"en": "Winking Face",
|
||||
"zh": "鐪ㄧ溂",
|
||||
"tag": "\uD83D\uDE09",
|
||||
"position": "-200px 0px"
|
||||
},
|
||||
"u1F60D": {
|
||||
"en": "Heart Eyes",
|
||||
"zh": "鑹茶糠杩<E7B3A0>",
|
||||
"tag": "\uD83D\uDE0D",
|
||||
"position": "-1800px 0px"
|
||||
},
|
||||
"u1F618": {
|
||||
"en": "Blowing Kiss",
|
||||
"zh": "椋炲惢",
|
||||
"tag": "\uD83D\uDE18",
|
||||
"position": "-375px 0px"
|
||||
},
|
||||
"u1F61A": {
|
||||
"en": "Kiss Face",
|
||||
"zh": "涔堜箞鍝<E7AE9E>",
|
||||
"tag": "\uD83D\uDE1A",
|
||||
"position": "-1875px 0px"
|
||||
},
|
||||
"u1F61C": {
|
||||
"en": "Crazy Face",
|
||||
"zh": "璋冪毊",
|
||||
"tag": "\uD83D\uDE1C",
|
||||
"position": "-1900px 0px"
|
||||
},
|
||||
"u1F61D": {
|
||||
"en": "Tongue Out",
|
||||
"zh": "鍚愯垖澶<E59E96>",
|
||||
"tag": "\uD83D\uDE1D",
|
||||
"position": "-1925px 0px"
|
||||
},
|
||||
"u1F633": {
|
||||
"en": "Flushed Face",
|
||||
"zh": "鑴哥孩",
|
||||
"tag": "\uD83D\uDE33",
|
||||
"position": "-625px 0px"
|
||||
},
|
||||
"u1F601": {
|
||||
"en": "Grinning With Smiling",
|
||||
"zh": "闇查娇鑰岀瑧",
|
||||
"tag": "\uD83D\uDE01",
|
||||
"position": "-25px 0px"
|
||||
},
|
||||
"u1F614": {
|
||||
"en": "Pensive",
|
||||
"zh": "娌夋€<E5A48B>",
|
||||
"tag": "\uD83D\uDE14",
|
||||
"position": "-300px 0px"
|
||||
},
|
||||
"u1F60C": {
|
||||
"en": "Pleased",
|
||||
"zh": "婊℃剰",
|
||||
"tag": "\uD83D\uDE0C",
|
||||
"position": "-1775px 0px"
|
||||
},
|
||||
"u1F612": {
|
||||
"en": "Dissatisfied",
|
||||
"zh": "涓嶆弧",
|
||||
"tag": "\uD83D\uDE12",
|
||||
"position": "-250px 0px"
|
||||
},
|
||||
"u1F61F": {
|
||||
"en": "Worried Face",
|
||||
"zh": "鑻︾摐鑴<E69190>",
|
||||
"tag": "\uD83D\uDE1F",
|
||||
"position": "-1975px 0px"
|
||||
},
|
||||
"u1F61E": {
|
||||
"en": "Disappointed Face",
|
||||
"zh": "澶辨湜",
|
||||
"tag": "\uD83D\uDE1E",
|
||||
"position": "-1950px 0px"
|
||||
},
|
||||
"u1F623": {
|
||||
"en": "Helpless Face",
|
||||
"zh": "鏃犲姪",
|
||||
"tag": "\uD83D\uDE23",
|
||||
"position": "-450px 0px"
|
||||
},
|
||||
"u1F62D": {
|
||||
"en": "Crying",
|
||||
"zh": "浼ゅ績",
|
||||
"tag": "\uD83D\uDE22",
|
||||
"position": "-425px 0px"
|
||||
},
|
||||
"u1F602": {
|
||||
"en": "Laughing Tears",
|
||||
"zh": "鍠滄瀬鑰屾常",
|
||||
"tag": "\uD83D\uDE02",
|
||||
"position": "-50px 0px"
|
||||
},
|
||||
"u1F622": {
|
||||
"en": "Sobbing",
|
||||
"zh": "鍝常",
|
||||
"tag": "\uD83D\uDE2D",
|
||||
"position": "-2075px 0px"
|
||||
},
|
||||
"u1F62A": {
|
||||
"en": "Sleepy Face",
|
||||
"zh": "鍥<>",
|
||||
"tag": "\uD83D\uDE2A",
|
||||
"position": "-2000px 0px"
|
||||
},
|
||||
"u1F630": {
|
||||
"en": "Cold Sweat",
|
||||
"zh": "鍐锋睏",
|
||||
"tag": "\uD83D\uDE30",
|
||||
"position": "-550px 0px"
|
||||
},
|
||||
"u1F605": {
|
||||
"en": "Happy Sweat",
|
||||
"zh": "灏村艾",
|
||||
"tag": "\uD83D\uDE05",
|
||||
"position": "-100px 0px"
|
||||
},
|
||||
"u1F613": {
|
||||
"en": "Sweat",
|
||||
"zh": "姹<>",
|
||||
"tag": "\uD83D\uDE13",
|
||||
"position": "-275px 0px"
|
||||
},
|
||||
"u1F62B": {
|
||||
"en": "Tired Face",
|
||||
"zh": "鎶撶媯",
|
||||
"tag": "\uD83D\uDE2B",
|
||||
"position": "-2025px 0px"
|
||||
},
|
||||
"u1F629": {
|
||||
"en": "Weary Face",
|
||||
"zh": "鐤叉儷",
|
||||
"tag": "\uD83D\uDE29",
|
||||
"position": "-525px 0px"
|
||||
},
|
||||
"u1F628": {
|
||||
"en": "Fearful Face",
|
||||
"zh": "鍙€<EE889B>",
|
||||
"tag": "\uD83D\uDE28",
|
||||
"position": "-500px 0px"
|
||||
},
|
||||
"u1F631": {
|
||||
"en": "Scream",
|
||||
"zh": "灏栧彨",
|
||||
"tag": "\uD83D\uDE31",
|
||||
"position": "-575px 0px"
|
||||
},
|
||||
"u1F621": {
|
||||
"en": "Angry Face",
|
||||
"zh": "鐢熸皵",
|
||||
"tag": "\uD83D\uDE21",
|
||||
"position": "-400px 0px"
|
||||
},
|
||||
"u1F624": {
|
||||
"en": "Mad Face",
|
||||
"zh": "鎬掓皵鍐插啿",
|
||||
"tag": "\uD83D\uDE24",
|
||||
"position": "-475px 0px"
|
||||
},
|
||||
"u1F616": {
|
||||
"en": "Confounded Face",
|
||||
"zh": "钂欑緸",
|
||||
"tag": "\uD83D\uDE16",
|
||||
"position": "-350px 0px"
|
||||
},
|
||||
"u1F606": {
|
||||
"en": "Big Grin",
|
||||
"zh": "澶х瑧",
|
||||
"tag": "\uD83D\uDE06",
|
||||
"position": "-125px 0px"
|
||||
},
|
||||
"u1F60B": {
|
||||
"en": "Hungry",
|
||||
"zh": "棣<>",
|
||||
"tag": "\uD83D\uDE0B",
|
||||
"position": "-1750px 0px"
|
||||
},
|
||||
"u1F637": {
|
||||
"en": "Mask Face",
|
||||
"zh": "鍙g僵",
|
||||
"tag": "\uD83D\uDE37",
|
||||
"position": "-725px 0px"
|
||||
},
|
||||
"u1F60E": {
|
||||
"en": "Sunglasses",
|
||||
"zh": "澧ㄩ暅",
|
||||
"tag": "\uD83D\uDE0E",
|
||||
"position": "-1825px 0px"
|
||||
},
|
||||
"u1F634": {
|
||||
"en": "Sleeping",
|
||||
"zh": "鐫$湢",
|
||||
"tag": "\uD83D\uDE34",
|
||||
"position": "-650px 0px"
|
||||
},
|
||||
"u1F635": {
|
||||
"en": "Dizzy Face",
|
||||
"zh": "澶存檿鐪艰姳",
|
||||
"tag": "\uD83D\uDE35",
|
||||
"position": "-675px 0px"
|
||||
},
|
||||
"u1F632": {
|
||||
"en": "Shocked Face",
|
||||
"zh": "闇囨儕",
|
||||
"tag": "\uD83D\uDE32",
|
||||
"position": "-600px 0px"
|
||||
},
|
||||
"u1F608": {
|
||||
"en": "Purple Devil",
|
||||
"zh": "灏忔伓榄<E4BC93>",
|
||||
"tag": "\uD83D\uDE08",
|
||||
"position": "-175px 0px"
|
||||
},
|
||||
"u1F47F": {
|
||||
"en": "Devil",
|
||||
"zh": "鎭堕瓟",
|
||||
"tag": "\uD83D\uDC7F",
|
||||
"position": "-1600px 0px"
|
||||
},
|
||||
"u1F62F": {
|
||||
"en": "Surprised Face",
|
||||
"zh": "鎯婂憜",
|
||||
"tag": "\uD83D\uDE2F",
|
||||
"position": "-2100px 0px"
|
||||
},
|
||||
"u1F62C": {
|
||||
"en": "Grimacing Face",
|
||||
"zh": "鎵鑴<EE8397>",
|
||||
"tag": "\uD83D\uDE2C",
|
||||
"position": "-2050px 0px"
|
||||
},
|
||||
"u1F615": {
|
||||
"en": "Confused",
|
||||
"zh": "鍥版儜",
|
||||
"tag": "\uD83D\uDE15",
|
||||
"position": "-325px 0px"
|
||||
},
|
||||
"u1F636": {
|
||||
"en": "Mouthless",
|
||||
"zh": "鏃犲彛",
|
||||
"tag": "\uD83D\uDE36",
|
||||
"position": "-700px 0px"
|
||||
},
|
||||
"u1F607": {
|
||||
"en": "Halo",
|
||||
"zh": "澶╀娇鍏夌幆",
|
||||
"tag": "\uD83D\uDE07",
|
||||
"position": "-150px 0px"
|
||||
},
|
||||
"u1F60F": {
|
||||
"en": "Smirking Face",
|
||||
"zh": "鍌荤瑧",
|
||||
"tag": "\uD83D\uDE0F",
|
||||
"position": "-1850px 0px"
|
||||
},
|
||||
"u1F611": {
|
||||
"en": "Expressionless Face",
|
||||
"zh": "闈㈡棤琛ㄦ儏",
|
||||
"tag": "\uD83D\uDE11",
|
||||
"position": "-225px 0px"
|
||||
},
|
||||
"u1F648": {
|
||||
"en": "See No Monkey",
|
||||
"zh": "涓嶇湅",
|
||||
"tag": "\uD83D\uDE48",
|
||||
"position": "-2675px 0px"
|
||||
},
|
||||
"u1F649": {
|
||||
"en": "Hear No Monkey",
|
||||
"zh": "涓嶅惉",
|
||||
"tag": "\uD83D\uDE49",
|
||||
"position": "-2700px 0px"
|
||||
},
|
||||
"u1F64A": {
|
||||
"en": "No Speaking",
|
||||
"zh": "闂槾",
|
||||
"tag": "\uD83D\uDE4A",
|
||||
"position": "-2125px 0px"
|
||||
},
|
||||
"u1F47D": {
|
||||
"en": "Alien",
|
||||
"zh": "澶栨槦浜<E6A7A6>",
|
||||
"tag": "\uD83D\uDC7D",
|
||||
"position": "-1575px 0px"
|
||||
},
|
||||
"u1F4A9": {
|
||||
"en": "Pile Of Poo",
|
||||
"zh": "渚夸究",
|
||||
"tag": "\uD83D\uDCA9",
|
||||
"position": "-1025px 0px"
|
||||
},
|
||||
"u1F494": {
|
||||
"en": "Broken Heart",
|
||||
"zh": "蹇冪",
|
||||
"tag": "\uD83D\uDC94",
|
||||
"position": "-2600px 0px"
|
||||
},
|
||||
"u1F525": {
|
||||
"en": "Fire",
|
||||
"zh": "鐏<>",
|
||||
"tag": "\uD83D\uDD25",
|
||||
"position": "-2625px 0px"
|
||||
},
|
||||
"u1F4A2": {
|
||||
"en": "Anger",
|
||||
"zh": "鎰ゆ€<E38286>",
|
||||
"tag": "\uD83D\uDCA2",
|
||||
"position": "-950px 0px"
|
||||
},
|
||||
"u1F4A4": {
|
||||
"en": "Zzz",
|
||||
"zh": "ZZZ",
|
||||
"tag": "\uD83D\uDCA4",
|
||||
"position": "-1000px 0px"
|
||||
},
|
||||
"u1F6AB": {
|
||||
"en": "Prohibited",
|
||||
"zh": "绂佹",
|
||||
"tag": "\uD83D\uDEAB",
|
||||
"position": "-1175px 0px"
|
||||
},
|
||||
"u2B50": {
|
||||
"en": "Star",
|
||||
"zh": "鏄熸槦",
|
||||
"tag": "\u2B50",
|
||||
"position": "-2750px 0px"
|
||||
},
|
||||
"u26A1": {
|
||||
"en": "Lightning Bolt",
|
||||
"zh": "闂數",
|
||||
"tag": "\u26A1",
|
||||
"position": "-2825px 0px"
|
||||
},
|
||||
"u1F319": {
|
||||
"en": "Drescent Moon",
|
||||
"zh": "寮湀",
|
||||
"tag": "\uD83C\uDF19",
|
||||
"position": "-2175px 0px"
|
||||
},
|
||||
"u2600": {
|
||||
"en": "Sunny",
|
||||
"zh": "鏅存湕",
|
||||
"tag": "\u2600",
|
||||
"position": "-3075px 0px"
|
||||
},
|
||||
"u26C5": {
|
||||
"en": "Cloudy",
|
||||
"zh": "澶氫簯",
|
||||
"tag": "\u26C5",
|
||||
"position": "-2900px 0px"
|
||||
},
|
||||
"u2601": {
|
||||
"en": "Cloud",
|
||||
"zh": "浜戝僵",
|
||||
"tag": "\u2601",
|
||||
"position": "-3100px 0px"
|
||||
},
|
||||
"u2744": {
|
||||
"en": "Snowflake",
|
||||
"zh": "闆姳",
|
||||
"tag": "\u2744",
|
||||
"position": "-3175px 0px"
|
||||
},
|
||||
"u2614": {
|
||||
"en": "Umbrella",
|
||||
"zh": "闆ㄤ紴",
|
||||
"tag": "\u2614",
|
||||
"position": "-3125px 0px"
|
||||
},
|
||||
"u26C4": {
|
||||
"en": "Snowman",
|
||||
"zh": "闆汉",
|
||||
"tag": "\u26C4",
|
||||
"position": "-2875px 0px"
|
||||
},
|
||||
"u1F44D": {
|
||||
"en": "Thumbs Up",
|
||||
"zh": "璧<>",
|
||||
"tag": "\uD83D\uDC4D",
|
||||
"position": "-1400px 0px"
|
||||
},
|
||||
"u1F44E": {
|
||||
"en": "Thumbs Down",
|
||||
"zh": "鍠濆€掑僵",
|
||||
"tag": "\uD83D\uDC4E",
|
||||
"position": "-1425px 0px"
|
||||
},
|
||||
"u1F91D": {
|
||||
"en": "Handshake",
|
||||
"zh": "鎻℃墜",
|
||||
"tag": "\uD83E\uDD1D",
|
||||
"position": "-3200px 0px"
|
||||
},
|
||||
"u1F44C": {
|
||||
"en": "Ok Hand",
|
||||
"zh": "娌¢棶棰<E6A3B6>",
|
||||
"tag": "\uD83D\uDC4C",
|
||||
"position": "-1375px 0px"
|
||||
},
|
||||
"u1F44A": {
|
||||
"en": "Raised Fist",
|
||||
"zh": "涓捐捣鎷冲ご",
|
||||
"tag": "\u270A",
|
||||
"position": "-2975px 0px"
|
||||
},
|
||||
"u270A": {
|
||||
"en": "Oncoming Fist",
|
||||
"zh": "鍑绘嫵",
|
||||
"tag": "\uD83D\uDC4A",
|
||||
"position": "-1350px 0px"
|
||||
},
|
||||
"u270C": {
|
||||
"en": "Victory Hand",
|
||||
"zh": "鑰<>",
|
||||
"tag": "\u270C",
|
||||
"position": "-3025px 0px"
|
||||
},
|
||||
"u270B": {
|
||||
"en": "Raised Hand",
|
||||
"zh": "涓炬墜",
|
||||
"tag": "\u270B",
|
||||
"position": "-3000px 0px"
|
||||
},
|
||||
"u1F64F": {
|
||||
"en": "Folded Hands",
|
||||
"zh": "绁堢シ",
|
||||
"tag": "\uD83D\uDE4F",
|
||||
"position": "-2150px 0px"
|
||||
},
|
||||
"u261D": {
|
||||
"en": "Pointing Up",
|
||||
"zh": "绗竴",
|
||||
"tag": "\u261D",
|
||||
"position": "-2925px 0px"
|
||||
},
|
||||
"u1F44F": {
|
||||
"en": "Clapping Hands",
|
||||
"zh": "榧撴帉",
|
||||
"tag": "\uD83D\uDC4F",
|
||||
"position": "-1450px 0px"
|
||||
},
|
||||
"u1F4AA": {
|
||||
"en": "Flexed Biceps",
|
||||
"zh": "鑲岃倝",
|
||||
"tag": "\uD83D\uDCAA",
|
||||
"position": "-1050px 0px"
|
||||
},
|
||||
"u1F46A": {
|
||||
"en": "Family",
|
||||
"zh": "瀹跺涵",
|
||||
"tag": "\uD83D\uDC6A",
|
||||
"position": "-1475px 0px"
|
||||
},
|
||||
"u1F46B": {
|
||||
"en": "Couple",
|
||||
"zh": "鎯呬荆",
|
||||
"tag": "\uD83D\uDC6B",
|
||||
"position": "-1500px 0px"
|
||||
},
|
||||
"u1F47C": {
|
||||
"en": "Baby Angel",
|
||||
"zh": "瀹濊礉澶╀娇",
|
||||
"tag": "\uD83D\uDC7C",
|
||||
"position": "-1550px 0px"
|
||||
},
|
||||
"u1F434": {
|
||||
"en": "Horse",
|
||||
"zh": "椹<>",
|
||||
"tag": "\uD83D\uDC34",
|
||||
"position": "-2475px 0px"
|
||||
},
|
||||
"u1F436": {
|
||||
"en": "Dog",
|
||||
"zh": "鐙<>",
|
||||
"tag": "\uD83D\uDC36",
|
||||
"position": "-2500px 0px"
|
||||
},
|
||||
"u1F437": {
|
||||
"en": "Pig",
|
||||
"zh": "鐚<>",
|
||||
"tag": "\uD83D\uDC37",
|
||||
"position": "-2525px 0px"
|
||||
},
|
||||
"u1F47B": {
|
||||
"en": "Ghost",
|
||||
"zh": "楝<>",
|
||||
"tag": "\uD83D\uDC7B",
|
||||
"position": "-1525px 0px"
|
||||
},
|
||||
"u1F339": {
|
||||
"en": "Rose",
|
||||
"zh": "鐜懓",
|
||||
"tag": "\uD83C\uDF39",
|
||||
"position": "-2225px 0px"
|
||||
},
|
||||
"u1F33B": {
|
||||
"en": "Sunflower",
|
||||
"zh": "鍚戞棩钁<E6A3A9>",
|
||||
"tag": "\uD83C\uDF3B",
|
||||
"position": "-1250px 0px"
|
||||
},
|
||||
"u1F332": {
|
||||
"en": "Pine Tree",
|
||||
"zh": "鏉炬爲",
|
||||
"tag": "\uD83C\uDF32",
|
||||
"position": "-2200px 0px"
|
||||
},
|
||||
"u1F384": {
|
||||
"en": "Christmas Tree",
|
||||
"zh": "鍦h癁鏍<E79981>",
|
||||
"tag": "\uD83C\uDF84",
|
||||
"position": "-2400px 0px"
|
||||
},
|
||||
"u1F381": {
|
||||
"en": "Wrapped Gift",
|
||||
"zh": "绀肩墿",
|
||||
"tag": "\uD83C\uDF81",
|
||||
"position": "-2350px 0px"
|
||||
},
|
||||
"u1F389": {
|
||||
"en": "Party Popper",
|
||||
"zh": "鑱氫細绀艰姳",
|
||||
"tag": "\uD83C\uDF89",
|
||||
"position": "-2425px 0px"
|
||||
},
|
||||
"u1F4B0": {
|
||||
"en": "Money Bag",
|
||||
"zh": "閽辫",
|
||||
"tag": "\uD83D\uDCB0",
|
||||
"position": "-1075px 0px"
|
||||
},
|
||||
"u1F382": {
|
||||
"en": "Birthday Cake",
|
||||
"zh": "鐢熸棩铔嬬硶",
|
||||
"tag": "\uD83C\uDF82",
|
||||
"position": "-2375px 0px"
|
||||
},
|
||||
"u1F356": {
|
||||
"en": "Barbecue",
|
||||
"zh": "BBQ",
|
||||
"tag": "\uD83C\uDF56",
|
||||
"position": "-2275px 0px"
|
||||
},
|
||||
"u1F35A": {
|
||||
"en": "Cooked Rice",
|
||||
"zh": "绫抽キ",
|
||||
"tag": "\uD83C\uDF5A",
|
||||
"position": "-1275px 0px"
|
||||
},
|
||||
"u1F366": {
|
||||
"en": "Ice Cream",
|
||||
"zh": "鍐版穱娣<E7A9B1>",
|
||||
"tag": "\uD83C\uDF66",
|
||||
"position": "-2300px 0px"
|
||||
},
|
||||
"u1F36B": {
|
||||
"en": "Chocolate Bar",
|
||||
"zh": "宸у厠鍔<E58EA0>",
|
||||
"tag": "\uD83C\uDF6B",
|
||||
"position": "-1300px 0px"
|
||||
},
|
||||
"u1F349": {
|
||||
"en": "Watermelon",
|
||||
"zh": "瑗跨摐",
|
||||
"tag": "\uD83C\uDF49",
|
||||
"position": "-2250px 0px"
|
||||
},
|
||||
"u1F377": {
|
||||
"en": "Wine Glass",
|
||||
"zh": "绾㈤厭",
|
||||
"tag": "\uD83C\uDF77",
|
||||
"position": "-2325px 0px"
|
||||
},
|
||||
"u1F37B": {
|
||||
"en": "Cheers",
|
||||
"zh": "骞叉澂",
|
||||
"tag": "\uD83C\uDF7B",
|
||||
"position": "-1325px 0px"
|
||||
},
|
||||
"u2615": {
|
||||
"en": "Coffee",
|
||||
"zh": "鍜栧暋",
|
||||
"tag": "\u2615",
|
||||
"position": "-3150px 0px"
|
||||
},
|
||||
"u1F3C0": {
|
||||
"en": "Basketball",
|
||||
"zh": "绡悆",
|
||||
"tag": "\uD83C\uDFC0",
|
||||
"position": "-825px 0px"
|
||||
},
|
||||
"u26BD": {
|
||||
"en": "Soccer Ball",
|
||||
"zh": "瓒崇悆",
|
||||
"tag": "\u26BD",
|
||||
"position": "-2850px 0px"
|
||||
},
|
||||
"u1F3C2": {
|
||||
"en": "Snowboarder",
|
||||
"zh": "鍗曟澘婊戦洩",
|
||||
"tag": "\uD83C\uDFC2",
|
||||
"position": "-850px 0px"
|
||||
},
|
||||
"u1F3A4": {
|
||||
"en": "Microphone",
|
||||
"zh": "楹﹀厠椋<E58EA0>",
|
||||
"tag": "\uD83C\uDFA4",
|
||||
"position": "-750px 0px"
|
||||
},
|
||||
"u1F3B5": {
|
||||
"en": "Musical Note",
|
||||
"zh": "闊充箰",
|
||||
"tag": "\uD83C\uDFB5",
|
||||
"position": "-800px 0px"
|
||||
},
|
||||
"u1F3B2": {
|
||||
"en": "Game Die",
|
||||
"zh": "楠板瓙",
|
||||
"tag": "\uD83C\uDFB2",
|
||||
"position": "-775px 0px"
|
||||
},
|
||||
"u1F004": {
|
||||
"en": "Mahjong Red Dragon",
|
||||
"zh": "楹诲皢",
|
||||
"tag": "\uD83C\uDC04",
|
||||
"position": "-900px 0px"
|
||||
},
|
||||
"u1F451": {
|
||||
"en": "Crown",
|
||||
"zh": "鐜嬪啝",
|
||||
"tag": "\uD83D\uDC51",
|
||||
"position": "-2550px 0px"
|
||||
},
|
||||
"u1F484": {
|
||||
"en": "Lipstick",
|
||||
"zh": "鍙g孩",
|
||||
"tag": "\uD83D\uDC84",
|
||||
"position": "-2575px 0px"
|
||||
},
|
||||
"u1F48B": {
|
||||
"en": "Kiss",
|
||||
"zh": "鍚<>",
|
||||
"tag": "\uD83D\uDC8B",
|
||||
"position": "-1650px 0px"
|
||||
},
|
||||
"u1F48D": {
|
||||
"en": "Ring",
|
||||
"zh": "鎴掓寚",
|
||||
"tag": "\uD83D\uDC8D",
|
||||
"position": "-1675px 0px"
|
||||
},
|
||||
"u1F4DA": {
|
||||
"en": "Books",
|
||||
"zh": "涔︾睄",
|
||||
"tag": "\uD83D\uDCDA",
|
||||
"position": "-1100px 0px"
|
||||
},
|
||||
"u1F393": {
|
||||
"en": "Graduation Cap",
|
||||
"zh": "姣曚笟甯<E7AC9F>",
|
||||
"tag": "\uD83C\uDF93",
|
||||
"position": "-2450px 0px"
|
||||
},
|
||||
"u270F": {
|
||||
"en": "Pencil",
|
||||
"zh": "閾呯瑪",
|
||||
"tag": "\u270F",
|
||||
"position": "-3050px 0px"
|
||||
},
|
||||
"u1F3E1": {
|
||||
"en": "House With Garden",
|
||||
"zh": "鎴垮瓙",
|
||||
"tag": "\uD83C\uDFE1",
|
||||
"position": "-875px 0px"
|
||||
},
|
||||
"u1F6BF": {
|
||||
"en": "Shower",
|
||||
"zh": "娣嬫荡",
|
||||
"tag": "\uD83D\uDEBF",
|
||||
"position": "-1200px 0px"
|
||||
},
|
||||
"u1F4A1": {
|
||||
"en": "Light Bulb",
|
||||
"zh": "鐏场",
|
||||
"tag": "\uD83D\uDCA1",
|
||||
"position": "-925px 0px"
|
||||
},
|
||||
"u1F4DE": {
|
||||
"en": "Telephone Receiver",
|
||||
"zh": "鐢佃瘽鍚瓛",
|
||||
"tag": "\uD83D\uDCDE",
|
||||
"position": "-1125px 0px"
|
||||
},
|
||||
"u1F4E2": {
|
||||
"en": "Loudspeaker",
|
||||
"zh": "鎵╅煶鍣<E785B6>",
|
||||
"tag": "\uD83D\uDCE2",
|
||||
"position": "-1150px 0px"
|
||||
},
|
||||
"u1F556": {
|
||||
"en": "Clock",
|
||||
"zh": "琛<>",
|
||||
"tag": "\uD83D\uDD56",
|
||||
"position": "-2650px 0px"
|
||||
},
|
||||
"u23F0": {
|
||||
"en": "Alarm Clock",
|
||||
"zh": "闂归挓",
|
||||
"tag": "\u23F0",
|
||||
"position": "-2775px 0px"
|
||||
},
|
||||
"u23F3": {
|
||||
"en": "Hourglass",
|
||||
"zh": "娌欐紡",
|
||||
"tag": "\u23F3",
|
||||
"position": "-2800px 0px"
|
||||
},
|
||||
"u1F4A3": {
|
||||
"en": "Bomb",
|
||||
"zh": "鐐稿脊",
|
||||
"tag": "\uD83D\uDCA3",
|
||||
"position": "-975px 0px"
|
||||
},
|
||||
"u1F52B": {
|
||||
"en": "Pistol",
|
||||
"zh": "鎵嬫灙",
|
||||
"tag": "\uD83D\uDD2B",
|
||||
"position": "-1700px 0px"
|
||||
},
|
||||
"u1F48A": {
|
||||
"en": "Capsule",
|
||||
"zh": "鑽<>",
|
||||
"tag": "\uD83D\uDC8A",
|
||||
"position": "-1625px 0px"
|
||||
},
|
||||
"u1F680": {
|
||||
"en": "Rocket",
|
||||
"zh": "鐏",
|
||||
"tag": "\uD83D\uDE80",
|
||||
"position": "-2725px 0px"
|
||||
},
|
||||
"u1F30F": {
|
||||
"en": "Globe",
|
||||
"zh": "鍦扮悆",
|
||||
"tag": "\uD83C\uDF0F",
|
||||
"position": "-1225px 0px"
|
||||
}
|
||||
};
|
||||
let EmojiList = []
|
||||
|
||||
function setEmojiList() {
|
||||
EmojiList.length = 0;
|
||||
for (var unicode in EmojiFactory) {
|
||||
var detail = EmojiFactory[unicode];
|
||||
if (detail.tag) {
|
||||
var lang = 'en';
|
||||
var symbol = detail[lang];
|
||||
EmojiList.push({
|
||||
unicode: unicode,
|
||||
symbol: '[' + symbol + ']',
|
||||
emoji: detail.tag,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
setEmojiList()
|
||||
export default EmojiList
|
||||
BIN
static/im/toast/sentVoice.mp3
Executable file
BIN
static/im/toast/sentVoice.mp3
Executable file
Binary file not shown.
BIN
static/user/cover-s.png
Normal file
BIN
static/user/cover-s.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.8 KiB |
@@ -1,20 +1,23 @@
|
||||
import im from "@/utils/im/index.js"
|
||||
import {
|
||||
contactModel
|
||||
} from '@/utils/im/models.js'
|
||||
|
||||
export default {
|
||||
state: {
|
||||
contacts: {},
|
||||
myInfo: {}
|
||||
myInfo: {}
|
||||
},
|
||||
getters: {
|
||||
contacts(state) {
|
||||
return state.contacts
|
||||
},
|
||||
contactInfo: (state) => (targetId) => {
|
||||
contactInfo: (state) => (targetId) => {
|
||||
if (state.contacts[targetId]) {
|
||||
const info = state.contacts[targetId]
|
||||
|
||||
const info = state.contacts[targetId]
|
||||
|
||||
return {
|
||||
name: info.name,
|
||||
name: info.remark ? info.remark : info.name,
|
||||
hash: info.hash,
|
||||
portraitUrl: info.localAvatar ? info.localAvatar : require('@/static/user/cover.png')
|
||||
}
|
||||
@@ -38,19 +41,41 @@ export default {
|
||||
updateContactInfo(state, contactInfo) {
|
||||
Vue.set(state.contacts, contactInfo.targetId, contactInfo)
|
||||
},
|
||||
setSenderInfo(state, contactInfo) {
|
||||
setSenderInfo(state, contactInfo) {
|
||||
state.myInfo = {
|
||||
userId: contactInfo.targetId,
|
||||
name: contactInfo.name,
|
||||
portraitUrl: contactInfo.portraitUrl
|
||||
}
|
||||
<<<<<<< HEAD
|
||||
}
|
||||
=======
|
||||
},
|
||||
setContactRemark(state, contactInfo) {
|
||||
Vue.set(state.contacts, contactInfo.targetId, contactInfo)
|
||||
}
|
||||
>>>>>>> 013c030963aef06a00ac33d5f767cbd97ef2ceac
|
||||
},
|
||||
actions: {
|
||||
setContactRemark({
|
||||
commit
|
||||
}, {
|
||||
targetId,
|
||||
remark
|
||||
}) {
|
||||
contactModel.find('targetId="' + targetId + '"', (err, result) => {
|
||||
if (!err && result.length > 0) {
|
||||
result[0].remark = remark
|
||||
contactModel.update('targetId="' + targetId + '"', result[0], (err, res) => {
|
||||
commit('setContactRemark', result[0])
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
setSenderInfo({
|
||||
commit
|
||||
}, contactInfo) {
|
||||
commit('setSenderInfo', contactInfo)
|
||||
commit('setSenderInfo', contactInfo)
|
||||
},
|
||||
// 载入好友信息
|
||||
launchContact({
|
||||
@@ -63,8 +88,7 @@ export default {
|
||||
commit,
|
||||
dispatch
|
||||
}, contactInfo) {
|
||||
const model = uni.model.contactModel
|
||||
model.find('targetId="' + contactInfo.targetId + '"', (err, result) => {
|
||||
contactModel.find('targetId="' + contactInfo.targetId + '"', (err, result) => {
|
||||
if (result.length == 0) {
|
||||
// 没有数据,直接新增一条
|
||||
dispatch('initContact', contactInfo)
|
||||
@@ -75,12 +99,13 @@ export default {
|
||||
targetId: contactInfo.targetId,
|
||||
name: contactInfo.name,
|
||||
hash: contactInfo.hash,
|
||||
type: contactInfo.type,
|
||||
portraitUrl: contactInfo.portraitUrl,
|
||||
localAvatar: savedFilePath
|
||||
}
|
||||
model.update('targetId="' + contactInfo.targetId + '"', info, (err,
|
||||
contactModel.update('targetId="' + contactInfo.targetId + '"', info, (err,
|
||||
res) => {
|
||||
console.log('UPDATE AVATAR, ERR', err, info);
|
||||
console.log('UPDATE AVATAR, ERR', err, info)
|
||||
})
|
||||
commit('updateContactInfo', info)
|
||||
})
|
||||
@@ -89,16 +114,17 @@ export default {
|
||||
targetId: contactInfo.targetId,
|
||||
name: contactInfo.name,
|
||||
hash: contactInfo.hash,
|
||||
type: contactInfo.type,
|
||||
portraitUrl: contactInfo.portraitUrl,
|
||||
localAvatar: result[0].localAvatar
|
||||
}
|
||||
model.update('targetId="' + contactInfo.targetId + '"', info, (err, res) => {
|
||||
contactModel.update('targetId="' + contactInfo.targetId + '"', info, (err, res) => {
|
||||
console.log('UPDATE NAME, ERR', err, info);
|
||||
})
|
||||
commit('updateContactInfo', info)
|
||||
}
|
||||
} else {
|
||||
console.log('updateContact, 无操作');
|
||||
console.log('updateContact, 无操作')
|
||||
}
|
||||
})
|
||||
},
|
||||
@@ -108,7 +134,6 @@ export default {
|
||||
}, contactInfo) {
|
||||
// 将好友信息保存到vuex的内存中,方便立即使用
|
||||
commit('updateContactInfo', contactInfo)
|
||||
const model = uni.model.contactModel
|
||||
// 用户头像,是否需要下载到本地
|
||||
if (contactInfo.portraitUrl) {
|
||||
saveAvatar(contactInfo, (savedFilePath) => {
|
||||
@@ -116,10 +141,13 @@ export default {
|
||||
targetId: contactInfo.targetId,
|
||||
name: contactInfo.name,
|
||||
hash: contactInfo.hash,
|
||||
type: contactInfo.type,
|
||||
portraitUrl: contactInfo.portraitUrl,
|
||||
localAvatar: savedFilePath
|
||||
}
|
||||
model.insert(info, (err, res) => {})
|
||||
contactModel.insert(info, (err, res) => {
|
||||
console.error('保存头像', err, res)
|
||||
})
|
||||
// 保存头像后,更新信息
|
||||
commit('updateContactInfo', info)
|
||||
})
|
||||
@@ -129,10 +157,13 @@ export default {
|
||||
targetId: contactInfo.targetId,
|
||||
name: contactInfo.name,
|
||||
hash: contactInfo.hash,
|
||||
type: contactInfo.type,
|
||||
portraitUrl: contactInfo.portraitUrl,
|
||||
localAvatar: ''
|
||||
}
|
||||
model.insert(info, (err, res) => {})
|
||||
contactModel.insert(info, (err, res) => {
|
||||
console.error('没保存头像', err, res)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BIN
uni_modules/onemue-USQLite/.DS_Store
vendored
Normal file
BIN
uni_modules/onemue-USQLite/.DS_Store
vendored
Normal file
Binary file not shown.
@@ -1,7 +1,10 @@
|
||||
## 2.1.0(2022-01-14)
|
||||
1. 新增了添加多个数据的事件选项(options, index)(感谢`@风扬`)
|
||||
## 2.1.2(2022-01-14)
|
||||
1. 新增了添加多个数据的事件选项(options, index)(感谢`@风扬`)
|
||||
## 2.2.2(2022-02-18)
|
||||
1. 解决了自增约束的部分bug
|
||||
2. 解决了处理类型的问题
|
||||
## 2.2.0(2022-02-16)
|
||||
1. 重新处理了判断类型的方法
|
||||
2. 解决了`no connect`的问题
|
||||
3. 新增了自增约束,需要为数字类型
|
||||
## 2.1.0(2022-01-14)
|
||||
1. 新增了添加多个数据的事件选项(options, index)(感谢`@风扬`)
|
||||
## 2.0.2(2022-01-05)
|
||||
|
||||
@@ -37,10 +37,13 @@ class Utils {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Utils.log(primaryKeyArr.length);
|
||||
if (primaryKeyArr.length>=1) {
|
||||
sql = `CREATE TABLE '${name}' (${sqlArr.join(', ')}, PRIMARY KEY (${primaryKeyArr.join()}))`;
|
||||
}else{
|
||||
if (primaryKeyArr.length>1) {
|
||||
|
||||
sql = `CREATE TABLE '${name}' (${sqlArr.join(', ').replaceAll(' PRIMARY KEY','')}, PRIMARY KEY (${primaryKeyArr.join()}))`;
|
||||
}
|
||||
else{
|
||||
sql = `CREATE TABLE '${name}' (${sqlArr.join(', ')})`;
|
||||
}
|
||||
Utils.log(`modelSql :${sql}`);
|
||||
@@ -59,6 +62,22 @@ class Utils {
|
||||
}
|
||||
|
||||
restrainArray.push(Utils.toType(options.type));
|
||||
|
||||
// 主键
|
||||
if (options.primaryKey == true) {
|
||||
if(options.autoIncrement != true){
|
||||
restrainArray.push('PRIMARY KEY');
|
||||
}
|
||||
}
|
||||
|
||||
// 自增
|
||||
if (Utils.isNumber(options.type)&&options.autoIncrement == true) {
|
||||
restrainArray.pop();
|
||||
restrainArray.push('INTEGER');
|
||||
restrainArray.push('PRIMARY KEY');
|
||||
restrainArray.push('AUTOINCREMENT');
|
||||
}
|
||||
|
||||
// 非空
|
||||
if (options.notNull == true) {
|
||||
restrainArray.push('NOT NULL');
|
||||
@@ -74,10 +93,6 @@ class Utils {
|
||||
restrainArray.push('UNIQUE');
|
||||
}
|
||||
|
||||
// 主键
|
||||
// if (options.primaryKey === true) {
|
||||
// restrainArray.push('PRIMARY KEY');
|
||||
// }
|
||||
|
||||
// 检查
|
||||
if (options.check) {
|
||||
@@ -87,27 +102,44 @@ class Utils {
|
||||
return restrainArray.join(' ');
|
||||
}
|
||||
|
||||
// 联合主键
|
||||
static getUnionPrimaryKey() {
|
||||
|
||||
}
|
||||
|
||||
static toType(jsType) {
|
||||
let sqliteType = '';
|
||||
if (jsType == Number) {
|
||||
if (Utils.isNumber(jsType)) {
|
||||
sqliteType = 'numeric';
|
||||
} else if (jsType == Date) {
|
||||
} else if (Utils.isDate(jsType)) {
|
||||
sqliteType = 'timestamp';
|
||||
} else {
|
||||
sqliteType = 'varchar';
|
||||
}
|
||||
return sqliteType;
|
||||
}
|
||||
|
||||
static log() {
|
||||
if (config.deBug) {
|
||||
console.log.apply(null, arguments);
|
||||
}
|
||||
}
|
||||
|
||||
static warn() {
|
||||
if (config.deBug) {
|
||||
console.warn.apply(null, arguments);
|
||||
}
|
||||
}
|
||||
|
||||
static error() {
|
||||
console.error.apply(null, arguments);
|
||||
}
|
||||
|
||||
static isArray(value){ return Object.prototype.toString.call(value) === '[object Array]'}
|
||||
static isObject(value){ return Object.prototype.toString.call(value) === '[object Object]'}
|
||||
static isString(value){ return Object.prototype.toString.call(value) === '[object String]'}
|
||||
static isFunction(value){ return (value === Function || Object.prototype.toString.call(value) === '[object Function]')}
|
||||
static isNumber(value){ return (value === Number || Object.prototype.toString.call(value) === '[object Number]')}
|
||||
static isNaN(value){ return (Object.prototype.toString.call(value) === '[object Number]' && isNaN(value))}
|
||||
static isBoolean(value){ return Object.prototype.toString.call(value) === '[object Boolean]'}
|
||||
static isUndefined(value){ return Object.prototype.toString.call(value) === '[object Undefined]'}
|
||||
static isModel(value){ return Object.prototype.toString.call(value) === '[object Model]'}
|
||||
static isDate(value){ return (value === Date||Object.prototype.toString.call(value) === '[object Date]')}
|
||||
}
|
||||
|
||||
|
||||
@@ -118,7 +150,7 @@ class Model {
|
||||
/**
|
||||
* @constructor
|
||||
* @param {String} name 数据库表名
|
||||
* @param {Object} options 数据表列对象
|
||||
* @param {} options 数据表列对象
|
||||
* @returns
|
||||
*/
|
||||
constructor(name, options) {
|
||||
@@ -129,7 +161,10 @@ class Model {
|
||||
if (config.isConnect) {
|
||||
self.repair();
|
||||
} else {
|
||||
console.error('no connect');
|
||||
if(!config.name||!config.path){
|
||||
console.error('"config.name" or "config.path" is empty');
|
||||
}
|
||||
usqlite.connect(config);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,21 +173,27 @@ class Model {
|
||||
* @param {String|Array} options
|
||||
* - String WHERE 内容
|
||||
* - Array 需要查询的列
|
||||
* @param {*} callback
|
||||
* @param {Function} callback
|
||||
* @returns
|
||||
*/
|
||||
find(options, callback) {
|
||||
let sql = '';
|
||||
let self = this;
|
||||
self.repair();
|
||||
if (!callback) {
|
||||
if(!(Utils.isString(options)||Utils.isArray(options)||Utils.isFunction(options))) {
|
||||
Utils.error('The first parameter of Model.find should be "Array", "String" or "Function" (when there is only one parameter).')
|
||||
}
|
||||
if(!callback&&!(Utils.isFunction(options))) {
|
||||
Utils.error('The second parameter of Model.find should be "Function".')
|
||||
}
|
||||
if (!callback&&Utils.isFunction(options)) {
|
||||
sql = `SELECT * FROM '${this.name}'`; // 查找全部
|
||||
callback = options;
|
||||
} else if (options.constructor == Array) {
|
||||
} else if (Utils.isArray(options)) {
|
||||
sql = `SELECT ${options.join()} FROM '${this.name}'`; // 查找制定列
|
||||
} else if (options.constructor == String) {
|
||||
} else if (Utils.isString(options)) {
|
||||
sql = `SELECT * FROM '${this.name}' WHERE ${options}`; // 制定条件查询
|
||||
};
|
||||
}
|
||||
|
||||
Utils.log(`find: ${sql}`);
|
||||
|
||||
@@ -180,7 +221,13 @@ class Model {
|
||||
let sql = '';
|
||||
let self = this;
|
||||
self.repair();
|
||||
|
||||
if(!Utils.isObject(options)){
|
||||
Utils.error('The first parameter of Model.limit should be "Object".')
|
||||
}
|
||||
if(!Utils.isFunction(callback)){
|
||||
Utils.error('The second parameter of Model.limit should be "Function".')
|
||||
}
|
||||
|
||||
if (!options.where) {
|
||||
// 不存在 where
|
||||
sql =
|
||||
@@ -215,12 +262,19 @@ class Model {
|
||||
let self = this;
|
||||
self.repair();
|
||||
|
||||
if(!(Utils.isObject(options)||Util.isArray(options))){
|
||||
Utils.error('The first parameter of Model.insert should be "Object" or "Array".')
|
||||
}
|
||||
if(!Utils.isFunction(callback)){
|
||||
Utils.error('The second parameter of Model.insert should be "Function".')
|
||||
}
|
||||
|
||||
if (config.isConnect) {
|
||||
if (options.constructor == Array) {
|
||||
if (Utils.isArray(options)) {
|
||||
for (var i = 0; i < options.length; i++) {
|
||||
this.insert(options[i], callback, i);
|
||||
}
|
||||
} else if (options.constructor == Object) {
|
||||
} else if (Utils.isObject(options)) {
|
||||
let keys = [];
|
||||
let values = [];
|
||||
let index = arguments[3]??null;
|
||||
@@ -255,7 +309,7 @@ class Model {
|
||||
|
||||
/**
|
||||
* @description 更新数据
|
||||
* @param {Object} options:可选参数 更新条件
|
||||
* @param {String} options:可选参数 更新条件
|
||||
* @param {Object} obj: 修改后的数据
|
||||
* @param {Function} callback :(err,results)=>{}
|
||||
*/
|
||||
@@ -264,7 +318,14 @@ class Model {
|
||||
let self = this;
|
||||
let items = [];
|
||||
self.repair();
|
||||
|
||||
|
||||
if(!(Utils.isObject(options)||Utils.isString(options))){
|
||||
Utils.error('The first parameter of Model.update should be "Object" or "String".')
|
||||
}
|
||||
if(!(Utils.isObject(obj)||Utils.isFunction(obj))){
|
||||
Utils.error('The second parameter of Model.update should be "Objrct" or "Function".')
|
||||
}
|
||||
|
||||
if (!callback) {
|
||||
// 不存在options
|
||||
callback = obj;
|
||||
@@ -298,13 +359,20 @@ class Model {
|
||||
|
||||
/**
|
||||
* @description 删除数据
|
||||
* @param {Object} options :可选参数 删除条件
|
||||
* @param {String} options :可选参数 删除条件
|
||||
* @param {Function} callback :(err,results)=>{}
|
||||
*/
|
||||
delete(options, callback) {
|
||||
var sql = '';
|
||||
let self = this;
|
||||
self.repair();
|
||||
|
||||
if(!(Utils.isString(options)||Utils.isFunction(options))){
|
||||
Utils.error('The first parameter of Model.delete should be "Object" or "Function".')
|
||||
}
|
||||
if(callback&&!Utils.isFunction(callback)){
|
||||
Utils.error('The second parameter of Model.delete should be "Function".')
|
||||
}
|
||||
|
||||
if (!callback) {
|
||||
sql = `DELETE FROM '${this.name}'`;
|
||||
@@ -330,7 +398,7 @@ class Model {
|
||||
|
||||
/**
|
||||
* @description 重命名或者新增列
|
||||
* @param {Object} options 参数 数组为新增多列 对象为新增单列{aa} 字符串重命名
|
||||
* @param {Object|Array|String} options 参数 数组为新增多列 对象为新增单列{aa} 字符串重命名
|
||||
* @param {Function} callback :(err,results)=>{}
|
||||
* @return:
|
||||
*/
|
||||
@@ -338,12 +406,18 @@ class Model {
|
||||
let self = this;
|
||||
let sql = '';
|
||||
self.repair();
|
||||
|
||||
if (options.constructor == Array) { // 新增多列
|
||||
if(!(Utils.isObject(options)||Utils.isArray(options)||Utils.isString(options))){
|
||||
Utils.error('The first parameter of Model.alter should be "Object", "Array" or "String".')
|
||||
}
|
||||
if(!Utils.isFunction(callback)){
|
||||
Utils.error('The second parameter of Model.alter should be "Function".')
|
||||
}
|
||||
|
||||
if (Utils.isArray(options)) { // 新增多列
|
||||
for (let i = 0; i < options.length; i++) {
|
||||
self.alter(options[i], callback);
|
||||
}
|
||||
} else if (options.constructor == Object) { // 新增单列
|
||||
} else if (Utils.isObject(options)) { // 新增单列
|
||||
let column = Utils.restrain(options.name, options.option);
|
||||
sql = `ALTER TABLE '${this.name}' ADD COLUMN ${column}`
|
||||
} else if (options.constructor == String) { // 重命名
|
||||
@@ -374,13 +448,13 @@ class Model {
|
||||
*/
|
||||
join(model, options, callback) {
|
||||
if (!model) {
|
||||
console.error('"model" cannot be empty.');
|
||||
Utils.error('"model" cannot be empty.');
|
||||
}
|
||||
if (options.constructor != Object) {
|
||||
console.error('The type of "options" is wrong, it should be "Object".');
|
||||
if (!Utils.isObject(options)) {
|
||||
Utils.error('The type of "options" is wrong, it should be "Object".');
|
||||
}
|
||||
if (!options.type || !options.predicate) {
|
||||
console.error('Missing required parameters');
|
||||
Utils.error('Missing required parameters');
|
||||
}
|
||||
|
||||
let leftName = this.name;
|
||||
@@ -427,6 +501,13 @@ class Model {
|
||||
* @param {Function} callback :(err,results)=>{}
|
||||
*/
|
||||
sql(sql, callback) {
|
||||
if (!Utils.isString(sql)) {
|
||||
Utils.error('"The type of "sql" is wrong, it should be "String".');
|
||||
}
|
||||
if (callback&&!Utils.isFunction(callback)) {
|
||||
Utils.error('The type of "callback" is wrong, it should be "Function".');
|
||||
}
|
||||
|
||||
let self = this;
|
||||
self.repair();
|
||||
|
||||
@@ -449,6 +530,10 @@ class Model {
|
||||
* @param {Function} callback
|
||||
*/
|
||||
isExist(callback) {
|
||||
if (callback&&!Utils.isFunction(callback)) {
|
||||
Utils.error('The type of "callback" is wrong, it should be "Function".');
|
||||
}
|
||||
|
||||
let sql = `SELECT count(*) AS isExist FROM sqlite_master WHERE type='table' AND name='${this.name}'`;
|
||||
let self = this;
|
||||
Utils.log(`isExist: ${sql}`);
|
||||
@@ -470,6 +555,10 @@ class Model {
|
||||
* @param {Function} callback
|
||||
*/
|
||||
drop(callback) {
|
||||
if (callback&&!Utils.isFunction(callback)) {
|
||||
Utils.error('The type of "callback" is wrong, it should be "Function".');
|
||||
}
|
||||
|
||||
var sql = `DROP TABLE '${this.name}'`;
|
||||
let self = this;
|
||||
self.repair();
|
||||
@@ -493,6 +582,10 @@ class Model {
|
||||
* @param {Function} callback
|
||||
*/
|
||||
create(callback) {
|
||||
if (callback&&!Utils.isFunction(callback)) {
|
||||
Utils.error('The type of "callback" is wrong, it should be "Function".');
|
||||
}
|
||||
|
||||
let self = this;
|
||||
let sql = Utils.modelSql(self.name, self.options);
|
||||
Utils.log(`create: ${sql}`);
|
||||
@@ -574,6 +667,7 @@ export class usqlite {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 断开数据库
|
||||
* @param {*} callback
|
||||
@@ -591,6 +685,19 @@ export class usqlite {
|
||||
}
|
||||
});
|
||||
}
|
||||
static closeAsync(options){
|
||||
plus.sqlite.closeDatabase({
|
||||
name: config.name, //数据库名称
|
||||
path: config.path, //数据库地址
|
||||
success(e) {
|
||||
config.isConnect = false;
|
||||
callback(null, e);
|
||||
},
|
||||
fail(e) {
|
||||
callback(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* @description 创建 Model 对象
|
||||
* @example
|
||||
|
||||
BIN
uni_modules/onemue-USQLite/js_sdk/usqlite.js.zip
Normal file
BIN
uni_modules/onemue-USQLite/js_sdk/usqlite.js.zip
Normal file
Binary file not shown.
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"id": "onemue-USQLite",
|
||||
"displayName": "u-SQLite V2",
|
||||
"version": "2.1.0",
|
||||
"version": "2.2.2",
|
||||
"description": "基于ORM技术,使用对象的方式来操作sqlite数据库,而无需编写任何sql语句.",
|
||||
"keywords": [
|
||||
"USQLite,数据库操作,缓存,大数据缓存,sqlite,sql,orm"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<h2>onemue-USQLite</h2>
|
||||
<h2>onemue-USQLite</h2><h2>onemue-USQLite</h2>
|
||||
|
||||
<h2 style="color:red">没有特别说明,均为异步函数</h2>
|
||||
> u-SQLite 交流群:643867519
|
||||
> 如果觉的当前插件对你有帮助可以前往 [github](https://github.com/onemue/u-sqlite) 点 star!
|
||||
|
||||
@@ -49,6 +50,7 @@ let studentModel = uni.$sql.model('student',{
|
||||
- unique UNIQUE 不重复
|
||||
- default DEFAULT 默认值
|
||||
- notNull NOT NULL 非空
|
||||
- autoIncrement AUTOINCREMENT 非空
|
||||
|
||||
**联合主键**
|
||||
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
## 1.3.5(2022-01-24)
|
||||
- 优化 size 属性可以传入不带单位的字符串数值
|
||||
## 1.3.4(2022-01-24)
|
||||
- 优化 size 支持其他单位
|
||||
## 1.3.3(2022-01-17)
|
||||
- 修复 nvue 有些图标不显示的bug,兼容老版本图标
|
||||
## 1.3.2(2021-12-01)
|
||||
- 优化 示例可复制图标名称
|
||||
## 1.3.1(2021-11-23)
|
||||
|
||||
@@ -173,6 +173,13 @@ export default {
|
||||
"unicode": "e6bb",
|
||||
"unicode_decimal": 59067
|
||||
},
|
||||
{
|
||||
"icon_id": "24923353",
|
||||
"name": "arrowthinright",
|
||||
"font_class": "arrowthinright",
|
||||
"unicode": "e6bb",
|
||||
"unicode_decimal": 59067
|
||||
},
|
||||
{
|
||||
"icon_id": "24923354",
|
||||
"name": "arrowthinleft",
|
||||
@@ -180,6 +187,13 @@ export default {
|
||||
"unicode": "e6bc",
|
||||
"unicode_decimal": 59068
|
||||
},
|
||||
{
|
||||
"icon_id": "24923354",
|
||||
"name": "arrowthinleft",
|
||||
"font_class": "arrowthinleft",
|
||||
"unicode": "e6bc",
|
||||
"unicode_decimal": 59068
|
||||
},
|
||||
{
|
||||
"icon_id": "24923355",
|
||||
"name": "arrowthinup",
|
||||
@@ -187,12 +201,25 @@ export default {
|
||||
"unicode": "e6bd",
|
||||
"unicode_decimal": 59069
|
||||
},
|
||||
{
|
||||
"icon_id": "24923355",
|
||||
"name": "arrowthinup",
|
||||
"font_class": "arrowthinup",
|
||||
"unicode": "e6bd",
|
||||
"unicode_decimal": 59069
|
||||
},
|
||||
{
|
||||
"icon_id": "24923356",
|
||||
"name": "arrowthindown",
|
||||
"font_class": "arrow-down",
|
||||
"unicode": "e6be",
|
||||
"unicode_decimal": 59070
|
||||
},{
|
||||
"icon_id": "24923356",
|
||||
"name": "arrowthindown",
|
||||
"font_class": "arrowthindown",
|
||||
"unicode": "e6be",
|
||||
"unicode_decimal": 59070
|
||||
},
|
||||
{
|
||||
"icon_id": "24923349",
|
||||
@@ -200,6 +227,12 @@ export default {
|
||||
"font_class": "bottom",
|
||||
"unicode": "e6b8",
|
||||
"unicode_decimal": 59064
|
||||
},{
|
||||
"icon_id": "24923349",
|
||||
"name": "arrowdown",
|
||||
"font_class": "arrowdown",
|
||||
"unicode": "e6b8",
|
||||
"unicode_decimal": 59064
|
||||
},
|
||||
{
|
||||
"icon_id": "24923346",
|
||||
@@ -208,6 +241,13 @@ export default {
|
||||
"unicode": "e6b5",
|
||||
"unicode_decimal": 59061
|
||||
},
|
||||
{
|
||||
"icon_id": "24923346",
|
||||
"name": "arrowright",
|
||||
"font_class": "arrowright",
|
||||
"unicode": "e6b5",
|
||||
"unicode_decimal": 59061
|
||||
},
|
||||
{
|
||||
"icon_id": "24923347",
|
||||
"name": "arrowup",
|
||||
@@ -215,6 +255,13 @@ export default {
|
||||
"unicode": "e6b6",
|
||||
"unicode_decimal": 59062
|
||||
},
|
||||
{
|
||||
"icon_id": "24923347",
|
||||
"name": "arrowup",
|
||||
"font_class": "arrowup",
|
||||
"unicode": "e6b6",
|
||||
"unicode_decimal": 59062
|
||||
},
|
||||
{
|
||||
"icon_id": "24923348",
|
||||
"name": "arrowleft",
|
||||
@@ -222,6 +269,13 @@ export default {
|
||||
"unicode": "e6b7",
|
||||
"unicode_decimal": 59063
|
||||
},
|
||||
{
|
||||
"icon_id": "24923348",
|
||||
"name": "arrowleft",
|
||||
"font_class": "arrowleft",
|
||||
"unicode": "e6b7",
|
||||
"unicode_decimal": 59063
|
||||
},
|
||||
{
|
||||
"icon_id": "24923334",
|
||||
"name": "eye",
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
<template>
|
||||
<!-- #ifdef APP-NVUE -->
|
||||
<text :style="{ color: color, 'font-size': size + 'px' }" class="uni-icons" @click="_onClick">{{unicode}}</text>
|
||||
<text :style="{ color: color, 'font-size': iconSize }" class="uni-icons" @click="_onClick">{{unicode}}</text>
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef APP-NVUE -->
|
||||
<text :style="{ color: color, 'font-size': size + 'px' }" class="uni-icons" :class="['uniui-'+type,customPrefix,customPrefix?type:'']" @click="_onClick"></text>
|
||||
<text :style="{ color: color, 'font-size': iconSize }" class="uni-icons" :class="['uniui-'+type,customPrefix,customPrefix?type:'']" @click="_onClick"></text>
|
||||
<!-- #endif -->
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import icons from './icons.js';
|
||||
import icons from './icons.js';
|
||||
const getVal = (val) => {
|
||||
const reg = /^[0-9]*$/g
|
||||
return (typeof val === 'number' || reg.test(val) )? val + 'px' : val;
|
||||
}
|
||||
// #ifdef APP-NVUE
|
||||
var domModule = weex.requireModule('dom');
|
||||
import iconUrl from './uniicons.ttf'
|
||||
@@ -61,6 +65,9 @@
|
||||
return unescape(`%u${code.unicode}`)
|
||||
}
|
||||
return ''
|
||||
},
|
||||
iconSize(){
|
||||
return getVal(this.size)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"id": "uni-icons",
|
||||
"displayName": "uni-icons 图标",
|
||||
"version": "1.3.2",
|
||||
"version": "1.3.5",
|
||||
"description": "图标组件,用于展示移动端常见的图标,可自定义颜色、大小。",
|
||||
"keywords": [
|
||||
"uni-ui",
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
## 3.3.12(2022-01-15)
|
||||
- 新增 preferedAppPlatform 配置用于解决uni-app vue2版本vue3版本获取platform不一致的问题 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=prefered-app-platform)
|
||||
- 修复 checkToken 未返回自定义token内容的Bug
|
||||
## 3.3.11(2022-01-11)
|
||||
- 修复用户名密码登录时多个应用出现重复用户名登录报错的Bug
|
||||
## 3.3.10(2022-01-07)
|
||||
- 新增 自定义国际化语言支持 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=custom-i8n)
|
||||
- 修复 一键登录时未校验重复手机号是否已验证的Bug
|
||||
- 修复 Apple登录时用户邮箱为空时报错的Bug
|
||||
- 修复 登录接口未传username时错误提示不正确的Bug
|
||||
## 3.3.9(2021-11-09)
|
||||
- 去除重复的context.xxx未找到的提示语
|
||||
## 3.3.8(2021-10-28)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"id": "uni-id",
|
||||
"displayName": "uni-id",
|
||||
"version": "3.3.9",
|
||||
"version": "3.3.12",
|
||||
"description": "简单、统一、可扩展的用户中心",
|
||||
"keywords": [
|
||||
"uniid",
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "uni-id",
|
||||
"version": "3.3.5",
|
||||
"version": "3.3.12",
|
||||
"description": "uni-id for uniCloud",
|
||||
"main": "index.js",
|
||||
"homepage": "https://uniapp.dcloud.io/uniCloud/uni-id",
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
## 1.0.3(2022-01-21)
|
||||
- 优化 组件示例
|
||||
## 1.0.2(2021-11-22)
|
||||
- 修复 / 符号在 vue 不同版本兼容问题引起的报错问题
|
||||
## 1.0.1(2021-11-22)
|
||||
- 修复 vue3中scss语法兼容问题
|
||||
## 1.0.0(2021-11-18)
|
||||
- init
|
||||
## 1.0.1(2021-11-22)
|
||||
- 修复 vue3中scss语法兼容问题
|
||||
## 1.0.0(2021-11-18)
|
||||
- init
|
||||
|
||||
@@ -1 +1 @@
|
||||
@import './styles/index.scss';
|
||||
@import './styles/index.scss';
|
||||
|
||||
@@ -1,82 +1,82 @@
|
||||
{
|
||||
"id": "uni-scss",
|
||||
"displayName": "uni-scss 辅助样式",
|
||||
"version": "1.0.2",
|
||||
"description": "uni-sass是uni-ui提供的一套全局样式 ,通过一些简单的类名和sass变量,实现简单的页面布局操作,比如颜色、边距、圆角等。",
|
||||
"keywords": [
|
||||
"uni-scss",
|
||||
"uni-ui",
|
||||
"辅助样式"
|
||||
],
|
||||
"repository": "https://github.com/dcloudio/uni-ui",
|
||||
"engines": {
|
||||
"HBuilderX": "^3.1.0"
|
||||
},
|
||||
"dcloudext": {
|
||||
"category": [
|
||||
"uni-app前端模板",
|
||||
"前端页面模板"
|
||||
],
|
||||
"sale": {
|
||||
"regular": {
|
||||
"price": "0.00"
|
||||
},
|
||||
"sourcecode": {
|
||||
"price": "0.00"
|
||||
}
|
||||
},
|
||||
"contact": {
|
||||
"qq": ""
|
||||
},
|
||||
"declaration": {
|
||||
"ads": "无",
|
||||
"data": "无",
|
||||
"permissions": "无"
|
||||
},
|
||||
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
|
||||
},
|
||||
"uni_modules": {
|
||||
"dependencies": [],
|
||||
"encrypt": [],
|
||||
"platforms": {
|
||||
"cloud": {
|
||||
"tcb": "y",
|
||||
"aliyun": "y"
|
||||
},
|
||||
"client": {
|
||||
"App": {
|
||||
"app-vue": "y",
|
||||
"app-nvue": "u"
|
||||
},
|
||||
"H5-mobile": {
|
||||
"Safari": "y",
|
||||
"Android Browser": "y",
|
||||
"微信浏览器(Android)": "y",
|
||||
"QQ浏览器(Android)": "y"
|
||||
},
|
||||
"H5-pc": {
|
||||
"Chrome": "y",
|
||||
"IE": "y",
|
||||
"Edge": "y",
|
||||
"Firefox": "y",
|
||||
"Safari": "y"
|
||||
},
|
||||
"小程序": {
|
||||
"微信": "y",
|
||||
"阿里": "y",
|
||||
"百度": "y",
|
||||
"字节跳动": "y",
|
||||
"QQ": "y"
|
||||
},
|
||||
"快应用": {
|
||||
"华为": "n",
|
||||
"联盟": "n"
|
||||
},
|
||||
"Vue": {
|
||||
"vue2": "y",
|
||||
"vue3": "y"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
"id": "uni-scss",
|
||||
"displayName": "uni-scss 辅助样式",
|
||||
"version": "1.0.3",
|
||||
"description": "uni-sass是uni-ui提供的一套全局样式 ,通过一些简单的类名和sass变量,实现简单的页面布局操作,比如颜色、边距、圆角等。",
|
||||
"keywords": [
|
||||
"uni-scss",
|
||||
"uni-ui",
|
||||
"辅助样式"
|
||||
],
|
||||
"repository": "https://github.com/dcloudio/uni-ui",
|
||||
"engines": {
|
||||
"HBuilderX": "^3.1.0"
|
||||
},
|
||||
"dcloudext": {
|
||||
"category": [
|
||||
"JS SDK",
|
||||
"通用 SDK"
|
||||
],
|
||||
"sale": {
|
||||
"regular": {
|
||||
"price": "0.00"
|
||||
},
|
||||
"sourcecode": {
|
||||
"price": "0.00"
|
||||
}
|
||||
},
|
||||
"contact": {
|
||||
"qq": ""
|
||||
},
|
||||
"declaration": {
|
||||
"ads": "无",
|
||||
"data": "无",
|
||||
"permissions": "无"
|
||||
},
|
||||
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
|
||||
},
|
||||
"uni_modules": {
|
||||
"dependencies": [],
|
||||
"encrypt": [],
|
||||
"platforms": {
|
||||
"cloud": {
|
||||
"tcb": "y",
|
||||
"aliyun": "y"
|
||||
},
|
||||
"client": {
|
||||
"App": {
|
||||
"app-vue": "y",
|
||||
"app-nvue": "u"
|
||||
},
|
||||
"H5-mobile": {
|
||||
"Safari": "y",
|
||||
"Android Browser": "y",
|
||||
"微信浏览器(Android)": "y",
|
||||
"QQ浏览器(Android)": "y"
|
||||
},
|
||||
"H5-pc": {
|
||||
"Chrome": "y",
|
||||
"IE": "y",
|
||||
"Edge": "y",
|
||||
"Firefox": "y",
|
||||
"Safari": "y"
|
||||
},
|
||||
"小程序": {
|
||||
"微信": "y",
|
||||
"阿里": "y",
|
||||
"百度": "y",
|
||||
"字节跳动": "y",
|
||||
"QQ": "y"
|
||||
},
|
||||
"快应用": {
|
||||
"华为": "n",
|
||||
"联盟": "n"
|
||||
},
|
||||
"Vue": {
|
||||
"vue2": "y",
|
||||
"vue3": "y"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@import './setting/_variables.scss';
|
||||
@import './setting/_border.scss';
|
||||
@import './setting/_color.scss';
|
||||
@import './setting/_space.scss';
|
||||
@import './setting/_radius.scss';
|
||||
@import './setting/_text.scss';
|
||||
@import './setting/_styles.scss';
|
||||
@import './setting/_variables.scss';
|
||||
@import './setting/_border.scss';
|
||||
@import './setting/_color.scss';
|
||||
@import './setting/_space.scss';
|
||||
@import './setting/_radius.scss';
|
||||
@import './setting/_text.scss';
|
||||
@import './setting/_styles.scss';
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
.uni-border {
|
||||
border: 1px $uni-border-1 solid;
|
||||
.uni-border {
|
||||
border: 1px $uni-border-1 solid;
|
||||
}
|
||||
@@ -1,66 +1,66 @@
|
||||
|
||||
// TODO 暂时不需要 class ,需要用户使用变量实现 ,如果使用类名其实并不推荐
|
||||
// @mixin get-styles($k,$c) {
|
||||
// @if $k == size or $k == weight{
|
||||
// font-#{$k}:#{$c}
|
||||
// }@else{
|
||||
// #{$k}:#{$c}
|
||||
// }
|
||||
// }
|
||||
$uni-ui-color:(
|
||||
// 主色
|
||||
primary: $uni-primary,
|
||||
primary-disable: $uni-primary-disable,
|
||||
primary-light: $uni-primary-light,
|
||||
// 辅助色
|
||||
success: $uni-success,
|
||||
success-disable: $uni-success-disable,
|
||||
success-light: $uni-success-light,
|
||||
warning: $uni-warning,
|
||||
warning-disable: $uni-warning-disable,
|
||||
warning-light: $uni-warning-light,
|
||||
error: $uni-error,
|
||||
error-disable: $uni-error-disable,
|
||||
error-light: $uni-error-light,
|
||||
info: $uni-info,
|
||||
info-disable: $uni-info-disable,
|
||||
info-light: $uni-info-light,
|
||||
// 中性色
|
||||
main-color: $uni-main-color,
|
||||
base-color: $uni-base-color,
|
||||
secondary-color: $uni-secondary-color,
|
||||
extra-color: $uni-extra-color,
|
||||
// 背景色
|
||||
bg-color: $uni-bg-color,
|
||||
// 边框颜色
|
||||
border-1: $uni-border-1,
|
||||
border-2: $uni-border-2,
|
||||
border-3: $uni-border-3,
|
||||
border-4: $uni-border-4,
|
||||
// 黑色
|
||||
black:$uni-black,
|
||||
// 白色
|
||||
white:$uni-white,
|
||||
// 透明
|
||||
transparent:$uni-transparent
|
||||
) !default;
|
||||
@each $key, $child in $uni-ui-color {
|
||||
.uni-#{"" + $key} {
|
||||
color: $child;
|
||||
}
|
||||
.uni-#{"" + $key}-bg {
|
||||
background-color: $child;
|
||||
}
|
||||
}
|
||||
.uni-shadow-sm {
|
||||
box-shadow: $uni-shadow-sm;
|
||||
}
|
||||
.uni-shadow-base {
|
||||
box-shadow: $uni-shadow-base;
|
||||
}
|
||||
.uni-shadow-lg {
|
||||
box-shadow: $uni-shadow-lg;
|
||||
}
|
||||
.uni-mask {
|
||||
background-color:$uni-mask;
|
||||
}
|
||||
|
||||
// TODO 暂时不需要 class ,需要用户使用变量实现 ,如果使用类名其实并不推荐
|
||||
// @mixin get-styles($k,$c) {
|
||||
// @if $k == size or $k == weight{
|
||||
// font-#{$k}:#{$c}
|
||||
// }@else{
|
||||
// #{$k}:#{$c}
|
||||
// }
|
||||
// }
|
||||
$uni-ui-color:(
|
||||
// 主色
|
||||
primary: $uni-primary,
|
||||
primary-disable: $uni-primary-disable,
|
||||
primary-light: $uni-primary-light,
|
||||
// 辅助色
|
||||
success: $uni-success,
|
||||
success-disable: $uni-success-disable,
|
||||
success-light: $uni-success-light,
|
||||
warning: $uni-warning,
|
||||
warning-disable: $uni-warning-disable,
|
||||
warning-light: $uni-warning-light,
|
||||
error: $uni-error,
|
||||
error-disable: $uni-error-disable,
|
||||
error-light: $uni-error-light,
|
||||
info: $uni-info,
|
||||
info-disable: $uni-info-disable,
|
||||
info-light: $uni-info-light,
|
||||
// 中性色
|
||||
main-color: $uni-main-color,
|
||||
base-color: $uni-base-color,
|
||||
secondary-color: $uni-secondary-color,
|
||||
extra-color: $uni-extra-color,
|
||||
// 背景色
|
||||
bg-color: $uni-bg-color,
|
||||
// 边框颜色
|
||||
border-1: $uni-border-1,
|
||||
border-2: $uni-border-2,
|
||||
border-3: $uni-border-3,
|
||||
border-4: $uni-border-4,
|
||||
// 黑色
|
||||
black:$uni-black,
|
||||
// 白色
|
||||
white:$uni-white,
|
||||
// 透明
|
||||
transparent:$uni-transparent
|
||||
) !default;
|
||||
@each $key, $child in $uni-ui-color {
|
||||
.uni-#{"" + $key} {
|
||||
color: $child;
|
||||
}
|
||||
.uni-#{"" + $key}-bg {
|
||||
background-color: $child;
|
||||
}
|
||||
}
|
||||
.uni-shadow-sm {
|
||||
box-shadow: $uni-shadow-sm;
|
||||
}
|
||||
.uni-shadow-base {
|
||||
box-shadow: $uni-shadow-base;
|
||||
}
|
||||
.uni-shadow-lg {
|
||||
box-shadow: $uni-shadow-lg;
|
||||
}
|
||||
.uni-mask {
|
||||
background-color:$uni-mask;
|
||||
}
|
||||
|
||||
@@ -1,55 +1,55 @@
|
||||
@mixin radius($r,$d:null ,$important: false){
|
||||
$radius-value:map-get($uni-radius, $r) if($important, !important, null);
|
||||
// Key exists within the $uni-radius variable
|
||||
@if (map-has-key($uni-radius, $r) and $d){
|
||||
@if $d == t {
|
||||
border-top-left-radius:$radius-value;
|
||||
border-top-right-radius:$radius-value;
|
||||
}@else if $d == r {
|
||||
border-top-right-radius:$radius-value;
|
||||
border-bottom-right-radius:$radius-value;
|
||||
}@else if $d == b {
|
||||
border-bottom-left-radius:$radius-value;
|
||||
border-bottom-right-radius:$radius-value;
|
||||
}@else if $d == l {
|
||||
border-top-left-radius:$radius-value;
|
||||
border-bottom-left-radius:$radius-value;
|
||||
}@else if $d == tl {
|
||||
border-top-left-radius:$radius-value;
|
||||
}@else if $d == tr {
|
||||
border-top-right-radius:$radius-value;
|
||||
}@else if $d == br {
|
||||
border-bottom-right-radius:$radius-value;
|
||||
}@else if $d == bl {
|
||||
border-bottom-left-radius:$radius-value;
|
||||
}
|
||||
}@else{
|
||||
border-radius:$radius-value;
|
||||
}
|
||||
}
|
||||
|
||||
@each $key, $child in $uni-radius {
|
||||
@if($key){
|
||||
.uni-radius-#{"" + $key} {
|
||||
@include radius($key)
|
||||
}
|
||||
}@else{
|
||||
.uni-radius {
|
||||
@include radius($key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@each $direction in t, r, b, l,tl, tr, br, bl {
|
||||
@each $key, $child in $uni-radius {
|
||||
@if($key){
|
||||
.uni-radius-#{"" + $direction}-#{"" + $key} {
|
||||
@include radius($key,$direction,false)
|
||||
}
|
||||
}@else{
|
||||
.uni-radius-#{$direction} {
|
||||
@include radius($key,$direction,false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@mixin radius($r,$d:null ,$important: false){
|
||||
$radius-value:map-get($uni-radius, $r) if($important, !important, null);
|
||||
// Key exists within the $uni-radius variable
|
||||
@if (map-has-key($uni-radius, $r) and $d){
|
||||
@if $d == t {
|
||||
border-top-left-radius:$radius-value;
|
||||
border-top-right-radius:$radius-value;
|
||||
}@else if $d == r {
|
||||
border-top-right-radius:$radius-value;
|
||||
border-bottom-right-radius:$radius-value;
|
||||
}@else if $d == b {
|
||||
border-bottom-left-radius:$radius-value;
|
||||
border-bottom-right-radius:$radius-value;
|
||||
}@else if $d == l {
|
||||
border-top-left-radius:$radius-value;
|
||||
border-bottom-left-radius:$radius-value;
|
||||
}@else if $d == tl {
|
||||
border-top-left-radius:$radius-value;
|
||||
}@else if $d == tr {
|
||||
border-top-right-radius:$radius-value;
|
||||
}@else if $d == br {
|
||||
border-bottom-right-radius:$radius-value;
|
||||
}@else if $d == bl {
|
||||
border-bottom-left-radius:$radius-value;
|
||||
}
|
||||
}@else{
|
||||
border-radius:$radius-value;
|
||||
}
|
||||
}
|
||||
|
||||
@each $key, $child in $uni-radius {
|
||||
@if($key){
|
||||
.uni-radius-#{"" + $key} {
|
||||
@include radius($key)
|
||||
}
|
||||
}@else{
|
||||
.uni-radius {
|
||||
@include radius($key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@each $direction in t, r, b, l,tl, tr, br, bl {
|
||||
@each $key, $child in $uni-radius {
|
||||
@if($key){
|
||||
.uni-radius-#{"" + $direction}-#{"" + $key} {
|
||||
@include radius($key,$direction,false)
|
||||
}
|
||||
}@else{
|
||||
.uni-radius-#{$direction} {
|
||||
@include radius($key,$direction,false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,56 +1,56 @@
|
||||
|
||||
@mixin fn($space,$direction,$size,$n) {
|
||||
@if $n {
|
||||
#{$space}-#{$direction}: #{$size*$uni-space-root}px
|
||||
} @else {
|
||||
#{$space}-#{$direction}: #{-$size*$uni-space-root}px
|
||||
}
|
||||
}
|
||||
@mixin get-styles($direction,$i,$space,$n){
|
||||
@if $direction == t {
|
||||
@include fn($space, top,$i,$n);
|
||||
}
|
||||
@if $direction == r {
|
||||
@include fn($space, right,$i,$n);
|
||||
}
|
||||
@if $direction == b {
|
||||
@include fn($space, bottom,$i,$n);
|
||||
}
|
||||
@if $direction == l {
|
||||
@include fn($space, left,$i,$n);
|
||||
}
|
||||
@if $direction == x {
|
||||
@include fn($space, left,$i,$n);
|
||||
@include fn($space, right,$i,$n);
|
||||
}
|
||||
@if $direction == y {
|
||||
@include fn($space, top,$i,$n);
|
||||
@include fn($space, bottom,$i,$n);
|
||||
}
|
||||
@if $direction == a {
|
||||
@if $n {
|
||||
#{$space}:#{$i*$uni-space-root}px;
|
||||
} @else {
|
||||
#{$space}:#{-$i*$uni-space-root}px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@each $orientation in m,p {
|
||||
$space: margin;
|
||||
@if $orientation == m {
|
||||
$space: margin;
|
||||
} @else {
|
||||
$space: padding;
|
||||
}
|
||||
@for $i from 0 through 16 {
|
||||
@each $direction in t, r, b, l, x, y, a {
|
||||
.uni-#{$orientation}#{$direction}-#{$i} {
|
||||
@include get-styles($direction,$i,$space,true);
|
||||
}
|
||||
.uni-#{$orientation}#{$direction}-n#{$i} {
|
||||
@include get-styles($direction,$i,$space,false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin fn($space,$direction,$size,$n) {
|
||||
@if $n {
|
||||
#{$space}-#{$direction}: #{$size*$uni-space-root}px
|
||||
} @else {
|
||||
#{$space}-#{$direction}: #{-$size*$uni-space-root}px
|
||||
}
|
||||
}
|
||||
@mixin get-styles($direction,$i,$space,$n){
|
||||
@if $direction == t {
|
||||
@include fn($space, top,$i,$n);
|
||||
}
|
||||
@if $direction == r {
|
||||
@include fn($space, right,$i,$n);
|
||||
}
|
||||
@if $direction == b {
|
||||
@include fn($space, bottom,$i,$n);
|
||||
}
|
||||
@if $direction == l {
|
||||
@include fn($space, left,$i,$n);
|
||||
}
|
||||
@if $direction == x {
|
||||
@include fn($space, left,$i,$n);
|
||||
@include fn($space, right,$i,$n);
|
||||
}
|
||||
@if $direction == y {
|
||||
@include fn($space, top,$i,$n);
|
||||
@include fn($space, bottom,$i,$n);
|
||||
}
|
||||
@if $direction == a {
|
||||
@if $n {
|
||||
#{$space}:#{$i*$uni-space-root}px;
|
||||
} @else {
|
||||
#{$space}:#{-$i*$uni-space-root}px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@each $orientation in m,p {
|
||||
$space: margin;
|
||||
@if $orientation == m {
|
||||
$space: margin;
|
||||
} @else {
|
||||
$space: padding;
|
||||
}
|
||||
@for $i from 0 through 16 {
|
||||
@each $direction in t, r, b, l, x, y, a {
|
||||
.uni-#{$orientation}#{$direction}-#{$i} {
|
||||
@include get-styles($direction,$i,$space,true);
|
||||
}
|
||||
.uni-#{$orientation}#{$direction}-n#{$i} {
|
||||
@include get-styles($direction,$i,$space,false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,167 +1,167 @@
|
||||
/* #ifndef APP-NVUE */
|
||||
|
||||
$-color-white:#fff;
|
||||
$-color-black:#000;
|
||||
@mixin base-style($color) {
|
||||
color: #fff;
|
||||
background-color: $color;
|
||||
border-color: mix($-color-black, $color, 8%);
|
||||
&:not([hover-class]):active {
|
||||
background: mix($-color-black, $color, 10%);
|
||||
border-color: mix($-color-black, $color, 20%);
|
||||
color: $-color-white;
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
@mixin is-color($color) {
|
||||
@include base-style($color);
|
||||
&[loading] {
|
||||
@include base-style($color);
|
||||
&::before {
|
||||
margin-right:5px;
|
||||
}
|
||||
}
|
||||
&[disabled] {
|
||||
&,
|
||||
&[loading],
|
||||
&:not([hover-class]):active {
|
||||
color: $-color-white;
|
||||
border-color: mix(darken($color,10%), $-color-white);
|
||||
background-color: mix($color, $-color-white);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@mixin base-plain-style($color) {
|
||||
color:$color;
|
||||
background-color: mix($-color-white, $color, 90%);
|
||||
border-color: mix($-color-white, $color, 70%);
|
||||
&:not([hover-class]):active {
|
||||
background: mix($-color-white, $color, 80%);
|
||||
color: $color;
|
||||
outline: none;
|
||||
border-color: mix($-color-white, $color, 50%);
|
||||
}
|
||||
}
|
||||
@mixin is-plain($color){
|
||||
&[plain] {
|
||||
@include base-plain-style($color);
|
||||
&[loading] {
|
||||
@include base-plain-style($color);
|
||||
&::before {
|
||||
margin-right:5px;
|
||||
}
|
||||
}
|
||||
&[disabled] {
|
||||
&,
|
||||
&:active {
|
||||
color: mix($-color-white, $color, 40%);
|
||||
background-color: mix($-color-white, $color, 90%);
|
||||
border-color: mix($-color-white, $color, 80%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.uni-btn {
|
||||
margin: 5px;
|
||||
color: #393939;
|
||||
border:1px solid #ccc;
|
||||
font-size: 16px;
|
||||
font-weight: 200;
|
||||
background-color: #F9F9F9;
|
||||
// TODO 暂时处理边框隐藏一边的问题
|
||||
overflow: visible;
|
||||
&::after{
|
||||
border: none;
|
||||
}
|
||||
|
||||
&:not([type]),&[type=default] {
|
||||
color: #999;
|
||||
&[loading] {
|
||||
background: none;
|
||||
&::before {
|
||||
margin-right:5px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
&[disabled]{
|
||||
color: mix($-color-white, #999, 60%);
|
||||
&,
|
||||
&[loading],
|
||||
&:active {
|
||||
color: mix($-color-white, #999, 60%);
|
||||
background-color: mix($-color-white,$-color-black , 98%);
|
||||
border-color: mix($-color-white, #999, 85%);
|
||||
}
|
||||
}
|
||||
|
||||
&[plain] {
|
||||
color: #999;
|
||||
background: none;
|
||||
border-color: $uni-border-1;
|
||||
&:not([hover-class]):active {
|
||||
background: none;
|
||||
color: mix($-color-white, $-color-black, 80%);
|
||||
border-color: mix($-color-white, $-color-black, 90%);
|
||||
outline: none;
|
||||
}
|
||||
&[disabled]{
|
||||
&,
|
||||
&[loading],
|
||||
&:active {
|
||||
background: none;
|
||||
color: mix($-color-white, #999, 60%);
|
||||
border-color: mix($-color-white, #999, 85%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:not([hover-class]):active {
|
||||
color: mix($-color-white, $-color-black, 50%);
|
||||
}
|
||||
|
||||
&[size=mini] {
|
||||
font-size: 16px;
|
||||
font-weight: 200;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
&.uni-btn-small {
|
||||
font-size: 14px;
|
||||
}
|
||||
&.uni-btn-mini {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
&.uni-btn-radius {
|
||||
border-radius: 999px;
|
||||
}
|
||||
&[type=primary] {
|
||||
@include is-color($uni-primary);
|
||||
@include is-plain($uni-primary)
|
||||
}
|
||||
&[type=success] {
|
||||
@include is-color($uni-success);
|
||||
@include is-plain($uni-success)
|
||||
}
|
||||
&[type=error] {
|
||||
@include is-color($uni-error);
|
||||
@include is-plain($uni-error)
|
||||
}
|
||||
&[type=warning] {
|
||||
@include is-color($uni-warning);
|
||||
@include is-plain($uni-warning)
|
||||
}
|
||||
&[type=info] {
|
||||
@include is-color($uni-info);
|
||||
@include is-plain($uni-info)
|
||||
}
|
||||
}
|
||||
/* #endif */
|
||||
/* #ifndef APP-NVUE */
|
||||
|
||||
$-color-white:#fff;
|
||||
$-color-black:#000;
|
||||
@mixin base-style($color) {
|
||||
color: #fff;
|
||||
background-color: $color;
|
||||
border-color: mix($-color-black, $color, 8%);
|
||||
&:not([hover-class]):active {
|
||||
background: mix($-color-black, $color, 10%);
|
||||
border-color: mix($-color-black, $color, 20%);
|
||||
color: $-color-white;
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
@mixin is-color($color) {
|
||||
@include base-style($color);
|
||||
&[loading] {
|
||||
@include base-style($color);
|
||||
&::before {
|
||||
margin-right:5px;
|
||||
}
|
||||
}
|
||||
&[disabled] {
|
||||
&,
|
||||
&[loading],
|
||||
&:not([hover-class]):active {
|
||||
color: $-color-white;
|
||||
border-color: mix(darken($color,10%), $-color-white);
|
||||
background-color: mix($color, $-color-white);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@mixin base-plain-style($color) {
|
||||
color:$color;
|
||||
background-color: mix($-color-white, $color, 90%);
|
||||
border-color: mix($-color-white, $color, 70%);
|
||||
&:not([hover-class]):active {
|
||||
background: mix($-color-white, $color, 80%);
|
||||
color: $color;
|
||||
outline: none;
|
||||
border-color: mix($-color-white, $color, 50%);
|
||||
}
|
||||
}
|
||||
@mixin is-plain($color){
|
||||
&[plain] {
|
||||
@include base-plain-style($color);
|
||||
&[loading] {
|
||||
@include base-plain-style($color);
|
||||
&::before {
|
||||
margin-right:5px;
|
||||
}
|
||||
}
|
||||
&[disabled] {
|
||||
&,
|
||||
&:active {
|
||||
color: mix($-color-white, $color, 40%);
|
||||
background-color: mix($-color-white, $color, 90%);
|
||||
border-color: mix($-color-white, $color, 80%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.uni-btn {
|
||||
margin: 5px;
|
||||
color: #393939;
|
||||
border:1px solid #ccc;
|
||||
font-size: 16px;
|
||||
font-weight: 200;
|
||||
background-color: #F9F9F9;
|
||||
// TODO 暂时处理边框隐藏一边的问题
|
||||
overflow: visible;
|
||||
&::after{
|
||||
border: none;
|
||||
}
|
||||
|
||||
&:not([type]),&[type=default] {
|
||||
color: #999;
|
||||
&[loading] {
|
||||
background: none;
|
||||
&::before {
|
||||
margin-right:5px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
&[disabled]{
|
||||
color: mix($-color-white, #999, 60%);
|
||||
&,
|
||||
&[loading],
|
||||
&:active {
|
||||
color: mix($-color-white, #999, 60%);
|
||||
background-color: mix($-color-white,$-color-black , 98%);
|
||||
border-color: mix($-color-white, #999, 85%);
|
||||
}
|
||||
}
|
||||
|
||||
&[plain] {
|
||||
color: #999;
|
||||
background: none;
|
||||
border-color: $uni-border-1;
|
||||
&:not([hover-class]):active {
|
||||
background: none;
|
||||
color: mix($-color-white, $-color-black, 80%);
|
||||
border-color: mix($-color-white, $-color-black, 90%);
|
||||
outline: none;
|
||||
}
|
||||
&[disabled]{
|
||||
&,
|
||||
&[loading],
|
||||
&:active {
|
||||
background: none;
|
||||
color: mix($-color-white, #999, 60%);
|
||||
border-color: mix($-color-white, #999, 85%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:not([hover-class]):active {
|
||||
color: mix($-color-white, $-color-black, 50%);
|
||||
}
|
||||
|
||||
&[size=mini] {
|
||||
font-size: 16px;
|
||||
font-weight: 200;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
&.uni-btn-small {
|
||||
font-size: 14px;
|
||||
}
|
||||
&.uni-btn-mini {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
&.uni-btn-radius {
|
||||
border-radius: 999px;
|
||||
}
|
||||
&[type=primary] {
|
||||
@include is-color($uni-primary);
|
||||
@include is-plain($uni-primary)
|
||||
}
|
||||
&[type=success] {
|
||||
@include is-color($uni-success);
|
||||
@include is-plain($uni-success)
|
||||
}
|
||||
&[type=error] {
|
||||
@include is-color($uni-error);
|
||||
@include is-plain($uni-error)
|
||||
}
|
||||
&[type=warning] {
|
||||
@include is-color($uni-warning);
|
||||
@include is-plain($uni-warning)
|
||||
}
|
||||
&[type=info] {
|
||||
@include is-color($uni-info);
|
||||
@include is-plain($uni-info)
|
||||
}
|
||||
}
|
||||
/* #endif */
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
@mixin get-styles($k,$c) {
|
||||
@if $k == size or $k == weight{
|
||||
font-#{$k}:#{$c}
|
||||
}@else{
|
||||
#{$k}:#{$c}
|
||||
}
|
||||
}
|
||||
|
||||
@each $key, $child in $uni-headings {
|
||||
/* #ifndef APP-NVUE */
|
||||
.uni-#{$key} {
|
||||
@each $k, $c in $child {
|
||||
@include get-styles($k,$c)
|
||||
}
|
||||
}
|
||||
/* #endif */
|
||||
/* #ifdef APP-NVUE */
|
||||
.container .uni-#{$key} {
|
||||
@each $k, $c in $child {
|
||||
@include get-styles($k,$c)
|
||||
}
|
||||
}
|
||||
/* #endif */
|
||||
}
|
||||
@mixin get-styles($k,$c) {
|
||||
@if $k == size or $k == weight{
|
||||
font-#{$k}:#{$c}
|
||||
}@else{
|
||||
#{$k}:#{$c}
|
||||
}
|
||||
}
|
||||
|
||||
@each $key, $child in $uni-headings {
|
||||
/* #ifndef APP-NVUE */
|
||||
.uni-#{$key} {
|
||||
@each $k, $c in $child {
|
||||
@include get-styles($k,$c)
|
||||
}
|
||||
}
|
||||
/* #endif */
|
||||
/* #ifdef APP-NVUE */
|
||||
.container .uni-#{$key} {
|
||||
@each $k, $c in $child {
|
||||
@include get-styles($k,$c)
|
||||
}
|
||||
}
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
@@ -1,146 +1,146 @@
|
||||
// @use "sass:math";
|
||||
@import '../tools/functions.scss';
|
||||
// 间距基础倍数
|
||||
$uni-space-root: 2 !default;
|
||||
// 边框半径默认值
|
||||
$uni-radius-root:5px !default;
|
||||
$uni-radius: () !default;
|
||||
// @use "sass:math";
|
||||
@import '../tools/functions.scss';
|
||||
// 间距基础倍数
|
||||
$uni-space-root: 2 !default;
|
||||
// 边框半径默认值
|
||||
$uni-radius-root:5px !default;
|
||||
$uni-radius: () !default;
|
||||
// 边框半径断点
|
||||
$uni-radius: map-deep-merge(
|
||||
(
|
||||
$uni-radius: map-deep-merge(
|
||||
(
|
||||
0: 0,
|
||||
// TODO 当前版本暂时不支持 sm 属性
|
||||
// 'sm': math.div($uni-radius-root, 2),
|
||||
null: $uni-radius-root,
|
||||
'lg': $uni-radius-root * 2,
|
||||
'xl': $uni-radius-root * 6,
|
||||
'pill': 9999px,
|
||||
'circle': 50%
|
||||
),
|
||||
$uni-radius
|
||||
// TODO 当前版本暂时不支持 sm 属性
|
||||
// 'sm': math.div($uni-radius-root, 2),
|
||||
null: $uni-radius-root,
|
||||
'lg': $uni-radius-root * 2,
|
||||
'xl': $uni-radius-root * 6,
|
||||
'pill': 9999px,
|
||||
'circle': 50%
|
||||
),
|
||||
$uni-radius
|
||||
);
|
||||
// 字体家族
|
||||
$body-font-family: 'Roboto', sans-serif !default;
|
||||
// 文本
|
||||
$heading-font-family: $body-font-family !default;
|
||||
$uni-headings: () !default;
|
||||
$letterSpacing: -0.01562em;
|
||||
$uni-headings: map-deep-merge(
|
||||
(
|
||||
'h1': (
|
||||
size: 32px,
|
||||
weight: 300,
|
||||
line-height: 50px,
|
||||
// letter-spacing:-0.01562em
|
||||
),
|
||||
'h2': (
|
||||
size: 28px,
|
||||
weight: 300,
|
||||
line-height: 40px,
|
||||
// letter-spacing: -0.00833em
|
||||
),
|
||||
'h3': (
|
||||
size: 24px,
|
||||
weight: 400,
|
||||
line-height: 32px,
|
||||
// letter-spacing: normal
|
||||
),
|
||||
'h4': (
|
||||
size: 20px,
|
||||
weight: 400,
|
||||
line-height: 30px,
|
||||
// letter-spacing: 0.00735em
|
||||
),
|
||||
'h5': (
|
||||
size: 16px,
|
||||
weight: 400,
|
||||
line-height: 24px,
|
||||
// letter-spacing: normal
|
||||
),
|
||||
'h6': (
|
||||
size: 14px,
|
||||
weight: 500,
|
||||
line-height: 18px,
|
||||
// letter-spacing: 0.0125em
|
||||
),
|
||||
'subtitle': (
|
||||
size: 12px,
|
||||
weight: 400,
|
||||
line-height: 20px,
|
||||
// letter-spacing: 0.00937em
|
||||
),
|
||||
'body': (
|
||||
font-size: 14px,
|
||||
font-weight: 400,
|
||||
line-height: 22px,
|
||||
// letter-spacing: 0.03125em
|
||||
),
|
||||
'caption': (
|
||||
'size': 12px,
|
||||
'weight': 400,
|
||||
'line-height': 20px,
|
||||
// 'letter-spacing': 0.03333em,
|
||||
// 'text-transform': false
|
||||
)
|
||||
),
|
||||
$uni-headings
|
||||
);
|
||||
|
||||
|
||||
|
||||
// 主色
|
||||
$uni-primary: #2979ff !default;
|
||||
$uni-primary-disable:lighten($uni-primary,20%) !default;
|
||||
$uni-primary-light: lighten($uni-primary,25%) !default;
|
||||
|
||||
// 辅助色
|
||||
// 除了主色外的场景色,需要在不同的场景中使用(例如危险色表示危险的操作)。
|
||||
$uni-success: #18bc37 !default;
|
||||
$uni-success-disable:lighten($uni-success,20%) !default;
|
||||
$uni-success-light: lighten($uni-success,25%) !default;
|
||||
|
||||
$uni-warning: #f3a73f !default;
|
||||
$uni-warning-disable:lighten($uni-warning,20%) !default;
|
||||
$uni-warning-light: lighten($uni-warning,25%) !default;
|
||||
|
||||
$uni-error: #e43d33 !default;
|
||||
$uni-error-disable:lighten($uni-error,20%) !default;
|
||||
$uni-error-light: lighten($uni-error,25%) !default;
|
||||
|
||||
$uni-info: #8f939c !default;
|
||||
$uni-info-disable:lighten($uni-info,20%) !default;
|
||||
$uni-info-light: lighten($uni-info,25%) !default;
|
||||
|
||||
// 中性色
|
||||
// 中性色用于文本、背景和边框颜色。通过运用不同的中性色,来表现层次结构。
|
||||
$uni-main-color: #3a3a3a !default; // 主要文字
|
||||
$uni-base-color: #6a6a6a !default; // 常规文字
|
||||
$uni-secondary-color: #909399 !default; // 次要文字
|
||||
$uni-extra-color: #c7c7c7 !default; // 辅助说明
|
||||
|
||||
// 边框颜色
|
||||
$uni-border-1: #F0F0F0 !default;
|
||||
$uni-border-2: #EDEDED !default;
|
||||
$uni-border-3: #DCDCDC !default;
|
||||
$uni-border-4: #B9B9B9 !default;
|
||||
|
||||
// 常规色
|
||||
$uni-black: #000000 !default;
|
||||
$uni-white: #ffffff !default;
|
||||
$uni-transparent: rgba($color: #000000, $alpha: 0) !default;
|
||||
|
||||
// 背景色
|
||||
$uni-bg-color: #f7f7f7 !default;
|
||||
|
||||
/* 水平间距 */
|
||||
$uni-spacing-sm: 8px !default;
|
||||
$uni-spacing-base: 15px !default;
|
||||
$uni-spacing-lg: 30px !default;
|
||||
|
||||
// 阴影
|
||||
$uni-shadow-sm:0 0 5px rgba($color: #d8d8d8, $alpha: 0.5) !default;
|
||||
$uni-shadow-base:0 1px 8px 1px rgba($color: #a5a5a5, $alpha: 0.2) !default;
|
||||
$uni-shadow-lg:0px 1px 10px 2px rgba($color: #a5a4a4, $alpha: 0.5) !default;
|
||||
|
||||
// 蒙版
|
||||
$uni-mask: rgba($color: #000000, $alpha: 0.4) !default;
|
||||
// 字体家族
|
||||
$body-font-family: 'Roboto', sans-serif !default;
|
||||
// 文本
|
||||
$heading-font-family: $body-font-family !default;
|
||||
$uni-headings: () !default;
|
||||
$letterSpacing: -0.01562em;
|
||||
$uni-headings: map-deep-merge(
|
||||
(
|
||||
'h1': (
|
||||
size: 32px,
|
||||
weight: 300,
|
||||
line-height: 50px,
|
||||
// letter-spacing:-0.01562em
|
||||
),
|
||||
'h2': (
|
||||
size: 28px,
|
||||
weight: 300,
|
||||
line-height: 40px,
|
||||
// letter-spacing: -0.00833em
|
||||
),
|
||||
'h3': (
|
||||
size: 24px,
|
||||
weight: 400,
|
||||
line-height: 32px,
|
||||
// letter-spacing: normal
|
||||
),
|
||||
'h4': (
|
||||
size: 20px,
|
||||
weight: 400,
|
||||
line-height: 30px,
|
||||
// letter-spacing: 0.00735em
|
||||
),
|
||||
'h5': (
|
||||
size: 16px,
|
||||
weight: 400,
|
||||
line-height: 24px,
|
||||
// letter-spacing: normal
|
||||
),
|
||||
'h6': (
|
||||
size: 14px,
|
||||
weight: 500,
|
||||
line-height: 18px,
|
||||
// letter-spacing: 0.0125em
|
||||
),
|
||||
'subtitle': (
|
||||
size: 12px,
|
||||
weight: 400,
|
||||
line-height: 20px,
|
||||
// letter-spacing: 0.00937em
|
||||
),
|
||||
'body': (
|
||||
font-size: 14px,
|
||||
font-weight: 400,
|
||||
line-height: 22px,
|
||||
// letter-spacing: 0.03125em
|
||||
),
|
||||
'caption': (
|
||||
'size': 12px,
|
||||
'weight': 400,
|
||||
'line-height': 20px,
|
||||
// 'letter-spacing': 0.03333em,
|
||||
// 'text-transform': false
|
||||
)
|
||||
),
|
||||
$uni-headings
|
||||
);
|
||||
|
||||
|
||||
|
||||
// 主色
|
||||
$uni-primary: #2979ff !default;
|
||||
$uni-primary-disable:lighten($uni-primary,20%) !default;
|
||||
$uni-primary-light: lighten($uni-primary,25%) !default;
|
||||
|
||||
// 辅助色
|
||||
// 除了主色外的场景色,需要在不同的场景中使用(例如危险色表示危险的操作)。
|
||||
$uni-success: #18bc37 !default;
|
||||
$uni-success-disable:lighten($uni-success,20%) !default;
|
||||
$uni-success-light: lighten($uni-success,25%) !default;
|
||||
|
||||
$uni-warning: #f3a73f !default;
|
||||
$uni-warning-disable:lighten($uni-warning,20%) !default;
|
||||
$uni-warning-light: lighten($uni-warning,25%) !default;
|
||||
|
||||
$uni-error: #e43d33 !default;
|
||||
$uni-error-disable:lighten($uni-error,20%) !default;
|
||||
$uni-error-light: lighten($uni-error,25%) !default;
|
||||
|
||||
$uni-info: #8f939c !default;
|
||||
$uni-info-disable:lighten($uni-info,20%) !default;
|
||||
$uni-info-light: lighten($uni-info,25%) !default;
|
||||
|
||||
// 中性色
|
||||
// 中性色用于文本、背景和边框颜色。通过运用不同的中性色,来表现层次结构。
|
||||
$uni-main-color: #3a3a3a !default; // 主要文字
|
||||
$uni-base-color: #6a6a6a !default; // 常规文字
|
||||
$uni-secondary-color: #909399 !default; // 次要文字
|
||||
$uni-extra-color: #c7c7c7 !default; // 辅助说明
|
||||
|
||||
// 边框颜色
|
||||
$uni-border-1: #F0F0F0 !default;
|
||||
$uni-border-2: #EDEDED !default;
|
||||
$uni-border-3: #DCDCDC !default;
|
||||
$uni-border-4: #B9B9B9 !default;
|
||||
|
||||
// 常规色
|
||||
$uni-black: #000000 !default;
|
||||
$uni-white: #ffffff !default;
|
||||
$uni-transparent: rgba($color: #000000, $alpha: 0) !default;
|
||||
|
||||
// 背景色
|
||||
$uni-bg-color: #f7f7f7 !default;
|
||||
|
||||
/* 水平间距 */
|
||||
$uni-spacing-sm: 8px !default;
|
||||
$uni-spacing-base: 15px !default;
|
||||
$uni-spacing-lg: 30px !default;
|
||||
|
||||
// 阴影
|
||||
$uni-shadow-sm:0 0 5px rgba($color: #d8d8d8, $alpha: 0.5) !default;
|
||||
$uni-shadow-base:0 1px 8px 1px rgba($color: #a5a5a5, $alpha: 0.2) !default;
|
||||
$uni-shadow-lg:0px 1px 10px 2px rgba($color: #a5a4a4, $alpha: 0.5) !default;
|
||||
|
||||
// 蒙版
|
||||
$uni-mask: rgba($color: #000000, $alpha: 0.4) !default;
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
// 合并 map
|
||||
@function map-deep-merge($parent-map, $child-map){
|
||||
$result: $parent-map;
|
||||
@each $key, $child in $child-map {
|
||||
$parent-has-key: map-has-key($result, $key);
|
||||
$parent-value: map-get($result, $key);
|
||||
$parent-type: type-of($parent-value);
|
||||
$child-type: type-of($child);
|
||||
$parent-is-map: $parent-type == map;
|
||||
$child-is-map: $child-type == map;
|
||||
|
||||
@if (not $parent-has-key) or ($parent-type != $child-type) or (not ($parent-is-map and $child-is-map)){
|
||||
$result: map-merge($result, ( $key: $child ));
|
||||
}@else {
|
||||
$result: map-merge($result, ( $key: map-deep-merge($parent-value, $child) ));
|
||||
}
|
||||
}
|
||||
@return $result;
|
||||
};
|
||||
// 合并 map
|
||||
@function map-deep-merge($parent-map, $child-map){
|
||||
$result: $parent-map;
|
||||
@each $key, $child in $child-map {
|
||||
$parent-has-key: map-has-key($result, $key);
|
||||
$parent-value: map-get($result, $key);
|
||||
$parent-type: type-of($parent-value);
|
||||
$child-type: type-of($child);
|
||||
$parent-is-map: $parent-type == map;
|
||||
$child-is-map: $child-type == map;
|
||||
|
||||
@if (not $parent-has-key) or ($parent-type != $child-type) or (not ($parent-is-map and $child-is-map)){
|
||||
$result: map-merge($result, ( $key: $child ));
|
||||
}@else {
|
||||
$result: map-merge($result, ( $key: map-deep-merge($parent-value, $child) ));
|
||||
}
|
||||
}
|
||||
@return $result;
|
||||
};
|
||||
|
||||
@@ -1,31 +1,31 @@
|
||||
// 间距基础倍数
|
||||
$uni-space-root: 2;
|
||||
// 边框半径默认值
|
||||
$uni-radius-root:5px;
|
||||
// 主色
|
||||
$uni-primary: #2979ff;
|
||||
// 辅助色
|
||||
$uni-success: #4cd964;
|
||||
// 警告色
|
||||
$uni-warning: #f0ad4e;
|
||||
// 错误色
|
||||
$uni-error: #dd524d;
|
||||
// 描述色
|
||||
$uni-info: #909399;
|
||||
// 中性色
|
||||
$uni-main-color: #303133;
|
||||
$uni-base-color: #606266;
|
||||
$uni-secondary-color: #909399;
|
||||
$uni-extra-color: #C0C4CC;
|
||||
// 背景色
|
||||
$uni-bg-color: #f5f5f5;
|
||||
// 边框颜色
|
||||
$uni-border-1: #DCDFE6;
|
||||
$uni-border-2: #E4E7ED;
|
||||
$uni-border-3: #EBEEF5;
|
||||
$uni-border-4: #F2F6FC;
|
||||
|
||||
// 常规色
|
||||
$uni-black: #000000;
|
||||
$uni-white: #ffffff;
|
||||
$uni-transparent: rgba($color: #000000, $alpha: 0);
|
||||
// 间距基础倍数
|
||||
$uni-space-root: 2;
|
||||
// 边框半径默认值
|
||||
$uni-radius-root:5px;
|
||||
// 主色
|
||||
$uni-primary: #2979ff;
|
||||
// 辅助色
|
||||
$uni-success: #4cd964;
|
||||
// 警告色
|
||||
$uni-warning: #f0ad4e;
|
||||
// 错误色
|
||||
$uni-error: #dd524d;
|
||||
// 描述色
|
||||
$uni-info: #909399;
|
||||
// 中性色
|
||||
$uni-main-color: #303133;
|
||||
$uni-base-color: #606266;
|
||||
$uni-secondary-color: #909399;
|
||||
$uni-extra-color: #C0C4CC;
|
||||
// 背景色
|
||||
$uni-bg-color: #f5f5f5;
|
||||
// 边框颜色
|
||||
$uni-border-1: #DCDFE6;
|
||||
$uni-border-2: #E4E7ED;
|
||||
$uni-border-3: #EBEEF5;
|
||||
$uni-border-4: #F2F6FC;
|
||||
|
||||
// 常规色
|
||||
$uni-black: #000000;
|
||||
$uni-white: #ffffff;
|
||||
$uni-transparent: rgba($color: #000000, $alpha: 0);
|
||||
|
||||
@@ -1,62 +1,62 @@
|
||||
@import './styles/setting/_variables.scss';
|
||||
// 间距基础倍数
|
||||
$uni-space-root: 2;
|
||||
// 边框半径默认值
|
||||
$uni-radius-root:5px;
|
||||
|
||||
// 主色
|
||||
$uni-primary: #2979ff;
|
||||
$uni-primary-disable:mix(#fff,$uni-primary,50%);
|
||||
$uni-primary-light: mix(#fff,$uni-primary,80%);
|
||||
|
||||
// 辅助色
|
||||
// 除了主色外的场景色,需要在不同的场景中使用(例如危险色表示危险的操作)。
|
||||
$uni-success: #18bc37;
|
||||
$uni-success-disable:mix(#fff,$uni-success,50%);
|
||||
$uni-success-light: mix(#fff,$uni-success,80%);
|
||||
|
||||
$uni-warning: #f3a73f;
|
||||
$uni-warning-disable:mix(#fff,$uni-warning,50%);
|
||||
$uni-warning-light: mix(#fff,$uni-warning,80%);
|
||||
|
||||
$uni-error: #e43d33;
|
||||
$uni-error-disable:mix(#fff,$uni-error,50%);
|
||||
$uni-error-light: mix(#fff,$uni-error,80%);
|
||||
|
||||
$uni-info: #8f939c;
|
||||
$uni-info-disable:mix(#fff,$uni-info,50%);
|
||||
$uni-info-light: mix(#fff,$uni-info,80%);
|
||||
|
||||
// 中性色
|
||||
// 中性色用于文本、背景和边框颜色。通过运用不同的中性色,来表现层次结构。
|
||||
$uni-main-color: #3a3a3a; // 主要文字
|
||||
$uni-base-color: #6a6a6a; // 常规文字
|
||||
$uni-secondary-color: #909399; // 次要文字
|
||||
$uni-extra-color: #c7c7c7; // 辅助说明
|
||||
|
||||
// 边框颜色
|
||||
$uni-border-1: #F0F0F0;
|
||||
$uni-border-2: #EDEDED;
|
||||
$uni-border-3: #DCDCDC;
|
||||
$uni-border-4: #B9B9B9;
|
||||
|
||||
// 常规色
|
||||
$uni-black: #000000;
|
||||
$uni-white: #ffffff;
|
||||
$uni-transparent: rgba($color: #000000, $alpha: 0);
|
||||
|
||||
// 背景色
|
||||
$uni-bg-color: #f7f7f7;
|
||||
|
||||
/* 水平间距 */
|
||||
$uni-spacing-sm: 8px;
|
||||
$uni-spacing-base: 15px;
|
||||
$uni-spacing-lg: 30px;
|
||||
|
||||
// 阴影
|
||||
$uni-shadow-sm:0 0 5px rgba($color: #d8d8d8, $alpha: 0.5);
|
||||
$uni-shadow-base:0 1px 8px 1px rgba($color: #a5a5a5, $alpha: 0.2);
|
||||
$uni-shadow-lg:0px 1px 10px 2px rgba($color: #a5a4a4, $alpha: 0.5);
|
||||
|
||||
// 蒙版
|
||||
$uni-mask: rgba($color: #000000, $alpha: 0.4);
|
||||
@import './styles/setting/_variables.scss';
|
||||
// 间距基础倍数
|
||||
$uni-space-root: 2;
|
||||
// 边框半径默认值
|
||||
$uni-radius-root:5px;
|
||||
|
||||
// 主色
|
||||
$uni-primary: #2979ff;
|
||||
$uni-primary-disable:mix(#fff,$uni-primary,50%);
|
||||
$uni-primary-light: mix(#fff,$uni-primary,80%);
|
||||
|
||||
// 辅助色
|
||||
// 除了主色外的场景色,需要在不同的场景中使用(例如危险色表示危险的操作)。
|
||||
$uni-success: #18bc37;
|
||||
$uni-success-disable:mix(#fff,$uni-success,50%);
|
||||
$uni-success-light: mix(#fff,$uni-success,80%);
|
||||
|
||||
$uni-warning: #f3a73f;
|
||||
$uni-warning-disable:mix(#fff,$uni-warning,50%);
|
||||
$uni-warning-light: mix(#fff,$uni-warning,80%);
|
||||
|
||||
$uni-error: #e43d33;
|
||||
$uni-error-disable:mix(#fff,$uni-error,50%);
|
||||
$uni-error-light: mix(#fff,$uni-error,80%);
|
||||
|
||||
$uni-info: #8f939c;
|
||||
$uni-info-disable:mix(#fff,$uni-info,50%);
|
||||
$uni-info-light: mix(#fff,$uni-info,80%);
|
||||
|
||||
// 中性色
|
||||
// 中性色用于文本、背景和边框颜色。通过运用不同的中性色,来表现层次结构。
|
||||
$uni-main-color: #3a3a3a; // 主要文字
|
||||
$uni-base-color: #6a6a6a; // 常规文字
|
||||
$uni-secondary-color: #909399; // 次要文字
|
||||
$uni-extra-color: #c7c7c7; // 辅助说明
|
||||
|
||||
// 边框颜色
|
||||
$uni-border-1: #F0F0F0;
|
||||
$uni-border-2: #EDEDED;
|
||||
$uni-border-3: #DCDCDC;
|
||||
$uni-border-4: #B9B9B9;
|
||||
|
||||
// 常规色
|
||||
$uni-black: #000000;
|
||||
$uni-white: #ffffff;
|
||||
$uni-transparent: rgba($color: #000000, $alpha: 0);
|
||||
|
||||
// 背景色
|
||||
$uni-bg-color: #f7f7f7;
|
||||
|
||||
/* 水平间距 */
|
||||
$uni-spacing-sm: 8px;
|
||||
$uni-spacing-base: 15px;
|
||||
$uni-spacing-lg: 30px;
|
||||
|
||||
// 阴影
|
||||
$uni-shadow-sm:0 0 5px rgba($color: #d8d8d8, $alpha: 0.5);
|
||||
$uni-shadow-base:0 1px 8px 1px rgba($color: #a5a5a5, $alpha: 0.2);
|
||||
$uni-shadow-lg:0px 1px 10px 2px rgba($color: #a5a4a4, $alpha: 0.5);
|
||||
|
||||
// 蒙版
|
||||
$uni-mask: rgba($color: #000000, $alpha: 0.4);
|
||||
|
||||
@@ -9,6 +9,9 @@ import {
|
||||
getImToken,
|
||||
getMyGroups
|
||||
} from '@/apis/interfaces/im.js'
|
||||
import {
|
||||
contactModel
|
||||
} from './models.js'
|
||||
|
||||
const initIm = (KEY) => {
|
||||
RongIMLib.init(KEY)
|
||||
@@ -20,6 +23,8 @@ const initIm = (KEY) => {
|
||||
getImToken().then(res => {
|
||||
connect(res.token, res.userInfo, (res) => {
|
||||
console.log('IM.CONNECT', res);
|
||||
// 发布全局事件,有新消息,刷新会话列表
|
||||
uni.$emit('onReceiveMessage')
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -62,13 +67,12 @@ const connect = (token, userInfo, callback) => {
|
||||
// 设置未读消息数量
|
||||
setNotifyBadge()
|
||||
// 首次运行获取好友列表
|
||||
const FK = 'ZHKD_' + userInfo.targetId
|
||||
const FK = 'ZH_CONTACT_' + userInfo.targetId
|
||||
|
||||
uni.getStorage({
|
||||
key: FK,
|
||||
success: () => {
|
||||
const model = uni.model.contactModel
|
||||
model.find((err, results) => {
|
||||
contactModel.find((err, results) => {
|
||||
results.map(item => {
|
||||
store.dispatch('launchContact', item)
|
||||
})
|
||||
|
||||
@@ -20,7 +20,30 @@ const onReceiveMessage = (message) => {
|
||||
}
|
||||
})
|
||||
im.setNotifyBadge()
|
||||
// 发布全局事件,有新消息,刷新会话列表
|
||||
uni.$emit('onReceiveMessage', message)
|
||||
// 这个是为了更新消息列表页的
|
||||
uni.$emit('onReceiveMessage_' + message.targetId, message)
|
||||
}
|
||||
|
||||
// 检测联系人信息,不存在的时候,从服务端获取
|
||||
const checkContactExists = (message) => {
|
||||
if (!store.getters.contactIsExist(message.targetId)) {
|
||||
getUserInfo(message.targetId).then(res => {
|
||||
console.log('targetId', res);
|
||||
store.dispatch('initContact', res)
|
||||
}).catch(err => {
|
||||
console.error('getUserInfo ERR', err)
|
||||
})
|
||||
}
|
||||
if (!store.getters.contactIsExist(message.senderUserId)) {
|
||||
getUserInfo(message.senderUserId).then(res => {
|
||||
console.log('senderUserId', message.senderUserId, res);
|
||||
store.dispatch('initContact', res)
|
||||
}).catch(err => {
|
||||
console.error('getUserInfo ERR', err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 允许通知的消息类型,触发更新消息列表操作,提示音
|
||||
@@ -32,66 +55,115 @@ const notifyMsgTypes = [
|
||||
IMLib.ObjectName.Location,
|
||||
IMLib.ObjectName.Voice,
|
||||
IMLib.ObjectName.HQVoice,
|
||||
IMLib.ObjectName.Sight,
|
||||
IMLib.ObjectName.Text,
|
||||
IMLib.ObjectName.Text,
|
||||
IMLib.ObjectName.Text
|
||||
IMLib.ObjectName.Sight
|
||||
]
|
||||
|
||||
const imLibListeners = () => {
|
||||
// 添加连接状态监听函数
|
||||
IMLib.addConnectionStatusListener((res) => {
|
||||
console.log('连接状态监听', res.data.status)
|
||||
console.error('连接状态监听', res.data.status)
|
||||
uni.$emit('onConnectionStatusChange', res.data.status)
|
||||
})
|
||||
// 添加消息监听函数
|
||||
IMLib.addReceiveMessageListener((res) => {
|
||||
const message = res.data.message
|
||||
console.error('[收到消息]', message)
|
||||
checkContactExists(message)
|
||||
if (utils.inArray(message.objectName, notifyMsgTypes)) {
|
||||
if (!store.getters.contactIsExist(message.targetId)) {
|
||||
getUserInfo(message.targetId).then(res => {
|
||||
store.dispatch('initContact', res)
|
||||
}).catch(err => {
|
||||
console.error('getUserInfo ERR', err)
|
||||
})
|
||||
}
|
||||
if (!store.getters.contactIsExist(message.senderUserId)) {
|
||||
getUserInfo(message.senderUserId).then(res => {
|
||||
store.dispatch('initContact', res)
|
||||
}).catch(err => {
|
||||
console.error('getUserInfo ERR', err)
|
||||
})
|
||||
}
|
||||
onReceiveMessage(message)
|
||||
} else if (message.objectName === IMLib.ObjectName.ProfileNotification) {
|
||||
// 更新会话信息
|
||||
uni.$emit('onUpdateProfile_' + message.targetId)
|
||||
// 更新联系人信息
|
||||
store.dispatch('updateContact', JSON.parse(message.content.data))
|
||||
// 调用完更新之后,删除这条消息
|
||||
IMLib.deleteMessagesByIds([message.messageId])
|
||||
} else if (message.objectName === IMLib.ObjectName.ContactNotification) {
|
||||
console.error('触发一个新好友的通知事件', message);
|
||||
// 触发一个新好友的通知事件
|
||||
uni.$emit('onContactNotification', message)
|
||||
} else if (message.objectName === IMLib.ObjectName.ContactNotification) {
|
||||
if (message.content.operation === 'Request') {
|
||||
// 触发一个新好友的通知事件,【会话列表,通讯录,新朋友】页面
|
||||
uni.$emit('onNewContactConversation', message)
|
||||
uni.$emit('onNewContactFriends', message)
|
||||
uni.$emit('onNewContactPendings', message)
|
||||
} else if (message.content.operation === 'Delete') {
|
||||
IMLib.cleanHistoryMessages(1, message.targetId, message.sentTime, false)
|
||||
// 解散了就删了吧
|
||||
IMLib.removeConversation(1, message.targetId)
|
||||
// 刷新会话列表
|
||||
uni.$emit('onUserDelete_' + message.targetId)
|
||||
uni.$emit('onReceiveMessage', message)
|
||||
}
|
||||
} else if (message.objectName === IMLib.ObjectName.GroupNotification) {
|
||||
// 解散群
|
||||
if (message.content.operation === 'Dismiss') {
|
||||
IMLib.cleanHistoryMessages(message.conversationType, message.targetId, message.sentTime,
|
||||
IMLib.cleanHistoryMessages(3, message.targetId, message.sentTime,
|
||||
false)
|
||||
// 解散了就删了吧
|
||||
IMLib.removeConversation(message.conversationType, message.targetId)
|
||||
uni.$emit('onGroupDismiss', message.targetId)
|
||||
IMLib.removeConversation(3, message.targetId)
|
||||
// 发布群解散的消息
|
||||
uni.$emit('onGroupDismiss')
|
||||
uni.$emit('onGroupDismiss_' + message.targetId)
|
||||
} else if (message.content.operation === 'REMOVE') {
|
||||
// 要判断是否当前用户,然后把当前用户踢出到主页去, 删除聊天记录,会话列表
|
||||
if (message.content.extra == store.getters.sender.userId) {
|
||||
IMLib.cleanHistoryMessages(3, message.targetId, message.sentTime,
|
||||
false)
|
||||
// 解散了就删了吧
|
||||
IMLib.removeConversation(3, message.targetId)
|
||||
// 为了更新群列表
|
||||
uni.$emit('onGroupDismiss')
|
||||
uni.$emit('onGroupRemoveYou_' + message.targetId)
|
||||
}
|
||||
uni.$emit('onReceiveMessage_' + message.targetId, message)
|
||||
// 这个是为了更新消息列表页的
|
||||
}
|
||||
// 触发刷新会话列表
|
||||
uni.$emit('onReceiveMessage', message)
|
||||
}
|
||||
})
|
||||
|
||||
// 监听消息回执
|
||||
// 监听私聊消息已读回执
|
||||
IMLib.addReadReceiptReceivedListener(({
|
||||
data
|
||||
}) => {
|
||||
console.error("监听私聊消息已读回执: ", data);
|
||||
uni.$emit('onReadReceiptReceived', data)
|
||||
})
|
||||
// 监听消息撤回操作
|
||||
IMLib.addRecallMessageListener(({
|
||||
data
|
||||
}) => {
|
||||
IMLib.getMessage(data.messageId, ({
|
||||
message
|
||||
}) => {
|
||||
console.error("消息撤回: ", message);
|
||||
im.setNotifyBadge()
|
||||
uni.$emit('onReceiveMessage', message)
|
||||
uni.$emit('onRecallMessage_' + message.targetId, message)
|
||||
})
|
||||
})
|
||||
// 监听需要群聊消息回执
|
||||
IMLib.addReceiptRequestListener(({
|
||||
data
|
||||
}) => {
|
||||
uni.$emit('onReceiptRequest', data)
|
||||
})
|
||||
// 群消息已读的回执
|
||||
IMLib.addReceiptResponseListener(({
|
||||
data
|
||||
}) => {
|
||||
// 获取本地消息
|
||||
IMLib.getMessageByUId(data.messageUId, ({
|
||||
message
|
||||
}) => {
|
||||
const readers = Object.keys(data.users).length
|
||||
const extra = JSON.stringify({
|
||||
readers
|
||||
})
|
||||
// 在消息的扩展数据中,设置已读数量
|
||||
IMLib.setMessageExtra(message.messageId, extra, (result) => {
|
||||
message.extra = extra
|
||||
uni.$emit('onReceiptResponse', message)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const callLibListeners = () => {
|
||||
@@ -100,7 +172,7 @@ const callLibListeners = () => {
|
||||
CallLib.onCallReceived(({
|
||||
data
|
||||
}) => {
|
||||
console.log('onCallReceived');
|
||||
console.error('onCallReceived');
|
||||
uni.navigateTo({
|
||||
url: '/pages/im/private/call?targetId=' + data.targetId + '&mediaType=' +
|
||||
data.mediaType
|
||||
@@ -112,27 +184,27 @@ const callLibListeners = () => {
|
||||
})
|
||||
// 外呼
|
||||
CallLib.onCallOutgoing((res) => {
|
||||
console.log('onCallOutgoing', res);
|
||||
console.error('onCallOutgoing', res);
|
||||
uni.$emit('onCallOutgoing')
|
||||
})
|
||||
// 远端响铃
|
||||
CallLib.onRemoteUserRinging((res) => {
|
||||
console.log('onRemoteUserRinging', res);
|
||||
CallLib.onRemoteUserRinging((res) => {
|
||||
console.error('onRemoteUserRinging', res);
|
||||
uni.$emit('onRemoteUserRinging')
|
||||
})
|
||||
// 远端加入
|
||||
CallLib.onRemoteUserJoined((res) => {
|
||||
console.log('远端接听');
|
||||
console.error('远端接听');
|
||||
uni.$emit('onRemoteUserJoined')
|
||||
})
|
||||
// 断开链接
|
||||
CallLib.onCallDisconnected((res) => {
|
||||
console.log('断开链接', res)
|
||||
console.error('断开链接', res)
|
||||
uni.$emit('onCallDisconnected')
|
||||
})
|
||||
// 远端挂断
|
||||
CallLib.onRemoteUserLeft((res) => {
|
||||
console.log('远端离开', res)
|
||||
console.error('远端离开', res)
|
||||
uni.$emit('onRemoteUserLeft')
|
||||
})
|
||||
}
|
||||
|
||||
@@ -16,7 +16,9 @@ const getMessageList = (conversationType, targetId, timeStamp, count, isForward,
|
||||
'RC:SightMsg',
|
||||
'RC:ReferenceMsg',
|
||||
'RC:CombineMsg',
|
||||
'RC:GrpNtf'
|
||||
'RC:GrpNtf',
|
||||
'RC:InfoNtf',
|
||||
'RC:RcNtf'
|
||||
]
|
||||
|
||||
RongIMLib.getHistoryMessagesByTimestamp(
|
||||
@@ -59,18 +61,16 @@ const getPendingList = (callback, total) => {
|
||||
|
||||
// 群组申请列表,邀请列表
|
||||
const getGroupPendinglist = (targetId, callback) => {
|
||||
total = total || 100
|
||||
RongIMLib.getConversationList([RongIMLib.ConversationType.SYSTEM], total, 0, (res) => {
|
||||
if (res.code === 0) {
|
||||
const pendings = res.conversations.filter((item) => {
|
||||
return item.targetId == targetId &&
|
||||
item.objectName == RongIMLib.ObjectName.ContactNotification &&
|
||||
item.latestMessage.operation === 'GroupPending'
|
||||
})
|
||||
const conversationType = RongIMLib.ConversationType.SYSTEM
|
||||
const objectNames = ['RC:ContactNtf']
|
||||
|
||||
callback(pendings)
|
||||
RongIMLib.getHistoryMessagesByTimestamp(conversationType, targetId, objectNames, 0, 1000, true,
|
||||
({
|
||||
messages
|
||||
}) => {
|
||||
callback(messages)
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -96,6 +96,11 @@ const sentText = (conversationType, targetId, content, user, callback) => {
|
||||
messageId
|
||||
}) => {
|
||||
if (code === 0) {
|
||||
if (conversationType == 3) {
|
||||
RongIMLib.sendReadReceiptRequest(messageId, (res) => {
|
||||
console.log('发送回执请求', res);
|
||||
})
|
||||
}
|
||||
callback(messageId)
|
||||
} else {
|
||||
console.log('发送失败', msg);
|
||||
@@ -122,7 +127,7 @@ const sentVoice = (conversationType, targetId, voiceUrl, time, user, callback) =
|
||||
content: {
|
||||
objectName: 'RC:HQVCMsg',
|
||||
local: 'file:///' + plus.io.convertLocalFileSystemURL(voiceUrl),
|
||||
duration: time,
|
||||
duration: time == 0 ? 1 : time,
|
||||
userInfo: user
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +1,27 @@
|
||||
import {
|
||||
usqlite
|
||||
} from '@/uni_modules/onemue-USQLite/js_sdk/usqlite.js'
|
||||
|
||||
|
||||
const contactModel = usqlite.model('contacts', {
|
||||
targetId: {
|
||||
type: String,
|
||||
primaryKey: true,
|
||||
unique: true
|
||||
},
|
||||
name: String,
|
||||
name: String,
|
||||
remark: String,
|
||||
hash: {
|
||||
type: String,
|
||||
unique: true
|
||||
},
|
||||
portraitUrl: String,
|
||||
type: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
portraitUrl: String,
|
||||
localAvatar: String
|
||||
})
|
||||
})
|
||||
|
||||
export default {
|
||||
export {
|
||||
contactModel
|
||||
}
|
||||
|
||||
13
yarn.lock
13
yarn.lock
@@ -17,12 +17,7 @@ uni-simple-router@^2.0.7:
|
||||
resolved "https://registry.npmjs.org/uni-simple-router/-/uni-simple-router-2.0.7.tgz"
|
||||
integrity sha512-8FKv5dw7Eoonm0gkO8udprrxzin0fNUI0+AvIphFkFRH5ZmP5ZWJ2pvnWzb2NiiqQSECTSU5VSB7HhvOSwD5eA==
|
||||
|
||||
uview-ui@^2.0.19:
|
||||
version "2.0.19"
|
||||
resolved "https://registry.npmjs.org/uview-ui/-/uview-ui-2.0.19.tgz"
|
||||
integrity sha512-ddZiaP7R9wsUxMzAuhuXgh5OswgCm2lKuulTqjnRXFr0uUWsgL1iBifU3GbOwpwP0LtTHKJOo9rYv1LP0WXmzA==
|
||||
|
||||
vuex@^3.6.2:
|
||||
version "3.6.2"
|
||||
resolved "https://registry.npmjs.org/vuex/-/vuex-3.6.2.tgz"
|
||||
integrity sha512-ETW44IqCgBpVomy520DT5jf8n0zoCac+sxWnn+hMe/CzaSejb/eVw2YToiXYX+Ex/AuHHia28vWTq4goAexFbw==
|
||||
uview-ui@^2.0.27:
|
||||
version "2.0.27"
|
||||
resolved "https://registry.yarnpkg.com/uview-ui/-/uview-ui-2.0.27.tgz#1a7dde9c6246e851d768f3efd44b5fb26774a2e1"
|
||||
integrity sha512-fl35rlguNPfXnwNoVv0w4zS1blFFxxSPuGR1+9SbpFGC33aiTBaoFWs/4Fppj0foS/kDCqSWcJiymNmQjPBD4g==
|
||||
|
||||
Reference in New Issue
Block a user