merge
This commit is contained in:
4
App.vue
4
App.vue
@@ -4,8 +4,8 @@
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
onLaunch: function() {
|
onLaunch: function() {
|
||||||
// im.initIm('lmxuhwaglu76d')
|
im.initIm('lmxuhwaglu76d')
|
||||||
return
|
// return
|
||||||
//#ifdef APP-PLUS
|
//#ifdef APP-PLUS
|
||||||
// 获取系统版本号
|
// 获取系统版本号
|
||||||
getVersions({
|
getVersions({
|
||||||
|
|||||||
20
pages.json
20
pages.json
@@ -373,26 +373,6 @@
|
|||||||
"navigationStyle": "custom"
|
"navigationStyle": "custom"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"path": "pages/im/private/index",
|
|
||||||
"name": "imPrivate",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "聊天",
|
|
||||||
"navigationBarBackgroundColor": "#F3F6FB",
|
|
||||||
"disableScroll": true,
|
|
||||||
"app-plus": {
|
|
||||||
"titleNView": {
|
|
||||||
"type": "default",
|
|
||||||
"buttons": [{
|
|
||||||
"float": "right",
|
|
||||||
"fontSrc": "/static/iconfont.ttf",
|
|
||||||
"text": "\ue607",
|
|
||||||
"fontSize": "20px"
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"path": "pages/im/private/call",
|
"path": "pages/im/private/call",
|
||||||
"name": "imPrivateCall",
|
"name": "imPrivateCall",
|
||||||
|
|||||||
@@ -47,9 +47,7 @@
|
|||||||
if (!this.disabled) {
|
if (!this.disabled) {
|
||||||
RongIMLib.clearTextMessageDraft(this.conversationType, this.targetId)
|
RongIMLib.clearTextMessageDraft(this.conversationType, this.targetId)
|
||||||
im.sentText(this.conversationType, this.targetId, this.inputTxt, () => {
|
im.sentText(this.conversationType, this.targetId, this.inputTxt, () => {
|
||||||
setTimeout(() => {
|
this.$emit('success')
|
||||||
this.$emit('success')
|
|
||||||
}, 500)
|
|
||||||
this.inputTxt = ''
|
this.inputTxt = ''
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import im from '@/utils/im/index.js'
|
import im from '@/utils/im/index.js'
|
||||||
import permision from "@/js_sdk/wa-permission/permission.js"
|
import permision from "@/utils/permission.js"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
|
|||||||
@@ -43,7 +43,18 @@
|
|||||||
<view class="name">{{ friend(item.targetId).name || '未知用户' }}</view>
|
<view class="name">{{ friend(item.targetId).name || '未知用户' }}</view>
|
||||||
<view class="time">{{ item.sentTime|timeCustomCN }}</view>
|
<view class="time">{{ item.sentTime|timeCustomCN }}</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="preview">{{ item.latestMessage.content || '' }}</view>
|
<view class="preview" v-if="item.objectName=='RC:TxtMsg'">
|
||||||
|
{{ item.latestMessage.content || '' }}
|
||||||
|
</view>
|
||||||
|
<view class="preview" v-if="item.objectName=='RC:HQVCMsg'">
|
||||||
|
[语音]
|
||||||
|
</view>
|
||||||
|
<view class="preview" v-if="item.objectName=='RC:ImgMsg'">
|
||||||
|
[图片]
|
||||||
|
</view>
|
||||||
|
<view class="preview" v-if="item.objectName=='RC:FileMsg'">
|
||||||
|
[文件]
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<!-- TODO 长按的弹出框,怎么点击隐藏,没搞明白 -->
|
<!-- TODO 长按的弹出框,怎么点击隐藏,没搞明白 -->
|
||||||
@@ -130,7 +141,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// 隐藏功能菜单
|
// 隐藏功能菜单
|
||||||
hidePop() {
|
hidePop() {
|
||||||
this.showPop = false
|
this.showPop = false
|
||||||
@@ -138,7 +149,7 @@
|
|||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.showShade = false
|
this.showShade = false
|
||||||
}, 250)
|
}, 250)
|
||||||
},
|
},
|
||||||
// 点击会话功能菜单
|
// 点击会话功能菜单
|
||||||
pickerMenu(e) {
|
pickerMenu(e) {
|
||||||
const index = Number(e.currentTarget.dataset.index)
|
const index = Number(e.currentTarget.dataset.index)
|
||||||
@@ -152,7 +163,7 @@
|
|||||||
im.setNotifyBadge()
|
im.setNotifyBadge()
|
||||||
this.getConversationList()
|
this.getConversationList()
|
||||||
this.hidePop()
|
this.hidePop()
|
||||||
},
|
},
|
||||||
// 长按会话,展示功能菜单
|
// 长按会话,展示功能菜单
|
||||||
onLongPress(e) {
|
onLongPress(e) {
|
||||||
let [touches, style, item] = [e.touches[0], "", e.currentTarget.dataset.item]
|
let [touches, style, item] = [e.touches[0], "", e.currentTarget.dataset.item]
|
||||||
@@ -191,6 +202,7 @@
|
|||||||
const timestamp = 0
|
const timestamp = 0
|
||||||
RongIMLib.getConversationList([RongIMLib.ConversationType.PRIVATE], count, timestamp, (res) => {
|
RongIMLib.getConversationList([RongIMLib.ConversationType.PRIVATE], count, timestamp, (res) => {
|
||||||
if (res.code === 0) {
|
if (res.code === 0) {
|
||||||
|
console.log(res.conversations);
|
||||||
this.conversations = res.conversations
|
this.conversations = res.conversations
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -220,7 +232,7 @@
|
|||||||
params
|
params
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 调起扫码
|
// 调起扫码
|
||||||
scanQrCode() {
|
scanQrCode() {
|
||||||
uni.scanCode({
|
uni.scanCode({
|
||||||
|
|||||||
@@ -55,7 +55,7 @@
|
|||||||
import sentVoice from '../components/sentVoice'
|
import sentVoice from '../components/sentVoice'
|
||||||
import sentPopups from '../components/sentPopups'
|
import sentPopups from '../components/sentPopups'
|
||||||
|
|
||||||
const ChatList = uni.requireNativePlugin('dom')
|
const ChatList = uni.requireNativePlugin('dom')
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
@@ -86,8 +86,8 @@
|
|||||||
this.userInfo = this.$store.getters.userInfo(this.targetId)
|
this.userInfo = this.$store.getters.userInfo(this.targetId)
|
||||||
|
|
||||||
// 获取消息列表
|
// 获取消息列表
|
||||||
this.initMessageList()
|
this.initMessageList()
|
||||||
|
|
||||||
uni.setNavigationBarTitle({
|
uni.setNavigationBarTitle({
|
||||||
title: this.userInfo.name
|
title: this.userInfo.name
|
||||||
})
|
})
|
||||||
@@ -125,11 +125,18 @@
|
|||||||
this.chatType = this.chatType === 1 ? 0 : 1
|
this.chatType = this.chatType === 1 ? 0 : 1
|
||||||
},
|
},
|
||||||
// 获取消息列表
|
// 获取消息列表
|
||||||
getMessageList() {
|
getMessageList() {
|
||||||
im.getMessageList(this.conversationType, this.targetId, (messages) => {
|
im.getMessageList(
|
||||||
this.messages = messages.reverse()
|
this.conversationType,
|
||||||
this.scrollBottom()
|
this.targetId,
|
||||||
})
|
new Date().getTime(),
|
||||||
|
10,
|
||||||
|
true,
|
||||||
|
(messages) => {
|
||||||
|
console.log(messages);
|
||||||
|
this.messages = messages.reverse()
|
||||||
|
this.scrollBottom()
|
||||||
|
})
|
||||||
},
|
},
|
||||||
// 展示好友信息, type 1 是自己, 2 是对方
|
// 展示好友信息, type 1 是自己, 2 是对方
|
||||||
showUser(targetId, type) {
|
showUser(targetId, type) {
|
||||||
|
|||||||
@@ -1,499 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view class="chat-content">
|
|
||||||
<scroll-view class="chat-scrool" :scroll-y="true" :scroll-into-view="scrollIntoID"
|
|
||||||
:scroll-with-animation="false">
|
|
||||||
<!-- 聊天窗口 -->
|
|
||||||
<view class="chat-item" v-for="(item,index) in messages" :key="index">
|
|
||||||
<view class="chat-item-article" :class="item.messageDirection == 1 ? 'right' : 'left'">
|
|
||||||
<view class="chat-msg">
|
|
||||||
<!-- 文字消息 -->
|
|
||||||
<view class="chat-msg-text">{{ item.content.content }}</view>
|
|
||||||
<!-- 语音消息 -->
|
|
||||||
<view class="chat-msg-audio" @click="onPlayMsg()">
|
|
||||||
<image v-if="item.messageDirection == 0" src="@/static/icon/audio_green.png"
|
|
||||||
mode="widthFix"></image>
|
|
||||||
10"
|
|
||||||
<image v-if="item.messageDirection == 1" src="@/static/icon/audio_white.png"
|
|
||||||
mode="widthFix"></image>
|
|
||||||
</view>
|
|
||||||
<!-- 预留一些图片,语音表情包等位置 -->
|
|
||||||
</view>
|
|
||||||
<view class="chat-status" :class="{'hide': item.sentStatus == 50}"
|
|
||||||
v-if="item.messageDirection == 1">{{targetId}}{{ item.sentStatus == 50 ? '已读': '未读'}}</view>
|
|
||||||
<view class="chat-avatar" @click="showFriend(targetId, item.messageDirection)">
|
|
||||||
<u-avatar v-if="item.messageDirection == 2" shape="square" bg-color="#ffffff"
|
|
||||||
:src="userInfo.portraitUrl"></u-avatar>
|
|
||||||
<u-avatar v-else shape="square" bg-color="#ffffff" :src="$store.getters.sender.portraitUrl" />
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="chat-item-time" :id="'chatId_'+index">
|
|
||||||
<text>{{ item.sentTime|timeCustomCN }}</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</scroll-view>
|
|
||||||
|
|
||||||
<view class="chat-footer">
|
|
||||||
<view class="msg-type" @click="msgType">
|
|
||||||
<image src="@/static/icon/key-icon.png" v-if="importTabs === 0" mode="widthFix"></image>
|
|
||||||
<image src="@/static/icon/msg-icon.png" v-if="importTabs === 1" mode="widthFix"></image>
|
|
||||||
</view>
|
|
||||||
<block v-if="importTabs === 0">
|
|
||||||
<button type="default" class="chat-mp3" hover-class="chat-hover" @touchstart="startAudio"
|
|
||||||
@touchend="chendAudio">按住 说话</button>
|
|
||||||
</block>
|
|
||||||
<block v-if="importTabs === 1">
|
|
||||||
<input class="chat-input" type="text" v-model="inputTxt" confirm-type="发送" @confirm="send"
|
|
||||||
cursor-spacing="10" />
|
|
||||||
</block>
|
|
||||||
<button class="chat-push" :disabled="disabled" size="mini" @click="send">发送</button>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 录音中提示 -->
|
|
||||||
<view class="audio-transcribe" v-if="showAudioTranscribe">
|
|
||||||
<image src="@/static/icon/record-icon.png" mode="widthFix"></image>
|
|
||||||
<view class="text">录音中 {{transcribeTime}} s</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import * as RongIMLib from "@/uni_modules/RongCloud-IMWrapper/js_sdk/index"
|
|
||||||
import im from '@/utils/im/index.js'
|
|
||||||
import permision from "@/js_sdk/wa-permission/permission.js"
|
|
||||||
|
|
||||||
var transcribe
|
|
||||||
var recorderManager = uni.getRecorderManager()
|
|
||||||
|
|
||||||
export default {
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
targetId: '',
|
|
||||||
scrollIntoID: 'chatID_0',
|
|
||||||
inputTxt: '',
|
|
||||||
messages: [],
|
|
||||||
conversationType: 1,
|
|
||||||
totalCount: 0,
|
|
||||||
userInfo: {
|
|
||||||
name: '',
|
|
||||||
userId: '',
|
|
||||||
portraitUrl: ''
|
|
||||||
},
|
|
||||||
importTabs: 0,
|
|
||||||
showAudioTranscribe: false,
|
|
||||||
transcribeTime: 60,
|
|
||||||
audioSrc: '',
|
|
||||||
audioContextPaused: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onLoad(e) {
|
|
||||||
this.targetId = e.targetId
|
|
||||||
this.conversationType = e.conversationType // 会话类型
|
|
||||||
// 消息总数量
|
|
||||||
RongIMLib.getMessageCount(this.conversationType, this.targetId, ({
|
|
||||||
code,
|
|
||||||
count
|
|
||||||
}) => {
|
|
||||||
if (code == 0) {
|
|
||||||
this.totalCount = count
|
|
||||||
}
|
|
||||||
})
|
|
||||||
this.userInfo = this.$store.getters.userInfo(this.targetId)
|
|
||||||
uni.setNavigationBarTitle({
|
|
||||||
title: this.$store.getters.userInfo(this.targetId).name
|
|
||||||
})
|
|
||||||
|
|
||||||
RongIMLib.clearMessagesUnreadStatus(this.conversationType, this.targetId, new Date().getTime())
|
|
||||||
im.setNotifyBadge()
|
|
||||||
RongIMLib.sendReadReceiptMessage(this.conversationType, this.targetId, new Date().getTime())
|
|
||||||
|
|
||||||
this.getMessageList()
|
|
||||||
|
|
||||||
// 监听消息回执
|
|
||||||
RongIMLib.addReadReceiptReceivedListener(({
|
|
||||||
data
|
|
||||||
}) => {
|
|
||||||
if (data.targetId == this.targetId) {
|
|
||||||
this.getMessageList()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// 监听录音结束
|
|
||||||
recorderManager.onStop(res => {
|
|
||||||
if (res.tempFilePath) this.audioSrc = res.tempFilePath
|
|
||||||
console.log('------------------获取到了录音的临时路径---------------')
|
|
||||||
console.log(res.tempFilePath)
|
|
||||||
})
|
|
||||||
// 简童收到新消息,判断是否是当前会话,更新会话内容
|
|
||||||
uni.$on('onReceiveMessage', (msg) => {
|
|
||||||
if (msg.targetId == this.targetId) {
|
|
||||||
RongIMLib.clearMessagesUnreadStatus(msg.conversationType, msg.targetId, msg.sentTime)
|
|
||||||
RongIMLib.sendReadReceiptMessage(msg.conversationType, msg.targetId, msg.sentTime)
|
|
||||||
this.getMessageList()
|
|
||||||
im.setNotifyBadge()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
beforeDestroy() {
|
|
||||||
uni.$off('onReceiveMessage')
|
|
||||||
},
|
|
||||||
onUnload() {
|
|
||||||
RongIMLib.clearReadReceiptReceivedListener()
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
disabled() {
|
|
||||||
return this.inputTxt.length == 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onNavigationBarButtonTap(e) {
|
|
||||||
if (e.index == 0) {
|
|
||||||
uni.navigateTo({
|
|
||||||
url: '/pages/im/private/setting?targetId=' + this.targetId +
|
|
||||||
'&conversationType=' + this.conversationType,
|
|
||||||
events: {
|
|
||||||
messageClear: () => {
|
|
||||||
this.getMessageList()
|
|
||||||
console.log('聊天消息被清空');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
// 播放语音消息
|
|
||||||
onPlayMsg() {
|
|
||||||
let innerAudioContext = uni.createInnerAudioContext()
|
|
||||||
innerAudioContext.src = this.audioSrc
|
|
||||||
if (this.audioContextPaused) {
|
|
||||||
innerAudioContext.play()
|
|
||||||
this.audioContextPaused = false
|
|
||||||
return
|
|
||||||
}
|
|
||||||
innerAudioContext.stop()
|
|
||||||
innerAudioContext.onStop(resStop => {
|
|
||||||
this.audioContextPaused = true
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 检查安卓录制权限
|
|
||||||
async getAndroidPermission() {
|
|
||||||
return await permision.requestAndroidPermission('android.permission.RECORD_AUDIO')
|
|
||||||
},
|
|
||||||
// 切换聊天信息
|
|
||||||
msgType() {
|
|
||||||
this.importTabs = this.importTabs === 1 ? 0 : 1
|
|
||||||
},
|
|
||||||
// 录制语音消息
|
|
||||||
startAudio(e) {
|
|
||||||
this.getAndroidPermission().then(code => {
|
|
||||||
switch (code) {
|
|
||||||
case 1:
|
|
||||||
this.showAudioTranscribe = true
|
|
||||||
recorderManager.start()
|
|
||||||
transcribe = setInterval(() => {
|
|
||||||
this.transcribeTime -= 1
|
|
||||||
if (this.transcribeTime === 0) {
|
|
||||||
this.chendAudio()
|
|
||||||
}
|
|
||||||
}, 1000)
|
|
||||||
break;
|
|
||||||
case 0:
|
|
||||||
uni.showToast({
|
|
||||||
title: '暂无麦克风权限,请前往应用设置开启麦克风',
|
|
||||||
icon: 'none'
|
|
||||||
})
|
|
||||||
break;
|
|
||||||
case -1:
|
|
||||||
uni.showToast({
|
|
||||||
title: '应用权限错误',
|
|
||||||
icon: 'none'
|
|
||||||
})
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 结束录音
|
|
||||||
chendAudio(e) {
|
|
||||||
if (!this.showAudioTranscribe) return
|
|
||||||
recorderManager.stop()
|
|
||||||
clearInterval(transcribe)
|
|
||||||
this.transcribeTime = 60
|
|
||||||
this.showAudioTranscribe = false
|
|
||||||
},
|
|
||||||
getMessageList() {
|
|
||||||
// 获取消息列表
|
|
||||||
const objectNames = [
|
|
||||||
'RC:TxtMsg',
|
|
||||||
'RC:VcMsg',
|
|
||||||
'RC:HQVCMsg',
|
|
||||||
'RC:ImgMsg',
|
|
||||||
'RC:GIFMsg',
|
|
||||||
'RC:ImgTextMsg',
|
|
||||||
'RC:FileMsg',
|
|
||||||
'RC:LBSMsg',
|
|
||||||
'RC:SightMsg',
|
|
||||||
'RC:ReferenceMsg',
|
|
||||||
'RC:CombineMsg'
|
|
||||||
]
|
|
||||||
const timeStamp = new Date().getTime()
|
|
||||||
const count = 20 // 获取的消息数量
|
|
||||||
const isForward = true // 是否向前获取
|
|
||||||
RongIMLib.getHistoryMessagesByTimestamp(this.conversationType, this.targetId, objectNames, timeStamp,
|
|
||||||
count,
|
|
||||||
isForward,
|
|
||||||
({
|
|
||||||
code,
|
|
||||||
messages
|
|
||||||
}) => {
|
|
||||||
if (code === 0) {
|
|
||||||
this.messages = messages.reverse()
|
|
||||||
this.scrollBottom()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
},
|
|
||||||
send() {
|
|
||||||
im.sendMsg(this.conversationType, this.targetId, this.inputTxt, () => {
|
|
||||||
this.getMessageList()
|
|
||||||
this.inputTxt = ''
|
|
||||||
})
|
|
||||||
},
|
|
||||||
showFriend(targetId, type) {
|
|
||||||
this.$Router.push({
|
|
||||||
name: type === 1 ? 'imFriendsMine' : 'imFriendsInfo',
|
|
||||||
params: {
|
|
||||||
targetId
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
scrollBottom() {
|
|
||||||
this.$nextTick(function() {
|
|
||||||
setTimeout(() => {
|
|
||||||
let len = this.messages.length
|
|
||||||
if (len) {
|
|
||||||
if (this.scrollIntoID == "chatId_" + (len - 1)) {
|
|
||||||
this.scrollIntoID = "chatId_" + (len - 2)
|
|
||||||
this.scrollBottom()
|
|
||||||
} else if (this.scrollIntoID == "chatId_" + (len - 2)) {
|
|
||||||
this.scrollIntoID = "chatId_" + (len - 1)
|
|
||||||
} else {
|
|
||||||
this.scrollIntoID = "chatId_" + (len - 1)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.scrollIntoID = "chatId_0";
|
|
||||||
}
|
|
||||||
}, 50)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.chat-content {
|
|
||||||
height: 100vh;
|
|
||||||
background: $window-color;
|
|
||||||
|
|
||||||
.audio-transcribe {
|
|
||||||
background: rgba($color: #000000, $alpha: .6);
|
|
||||||
position: fixed;
|
|
||||||
height: 200rpx;
|
|
||||||
width: 300rpx;
|
|
||||||
border-radius: $radius;
|
|
||||||
color: white;
|
|
||||||
z-index: 99;
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
margin-top: -200rpx;
|
|
||||||
margin-left: -150rpx;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
image {
|
|
||||||
width: 88rpx;
|
|
||||||
height: 88rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text {
|
|
||||||
font-size: $title-size-m;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-scrool {
|
|
||||||
height: calc(100vh - 140rpx);
|
|
||||||
box-sizing: border-box;
|
|
||||||
padding-bottom: $padding;
|
|
||||||
|
|
||||||
.chat-item {
|
|
||||||
.chat-item-time {
|
|
||||||
text-align: center;
|
|
||||||
padding: $padding/2 $padding;
|
|
||||||
|
|
||||||
text {
|
|
||||||
background: rgba($color: #000000, $alpha: .2);
|
|
||||||
color: white;
|
|
||||||
font-size: $title-size-sm - 4;
|
|
||||||
line-height: 40rpx;
|
|
||||||
padding: 0 15rpx;
|
|
||||||
display: inline-block;
|
|
||||||
border-radius: $radius-lg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-item-article {
|
|
||||||
position: relative;
|
|
||||||
padding: 10rpx ($padding + 110) 0;
|
|
||||||
overflow: hidden;
|
|
||||||
min-height: 40px;
|
|
||||||
|
|
||||||
.chat-msg {
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
.chat-msg-text {
|
|
||||||
display: inline-block;
|
|
||||||
padding: ($padding - 10) $padding;
|
|
||||||
color: $text-color;
|
|
||||||
box-sizing: border-box;
|
|
||||||
font-size: $title-size-lg;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-msg-audio {
|
|
||||||
@extend .chat-msg-text;
|
|
||||||
width: 50%;
|
|
||||||
|
|
||||||
image {
|
|
||||||
width: 38rpx;
|
|
||||||
height: 38rpx;
|
|
||||||
margin: 0;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-status {
|
|
||||||
color: $text-gray;
|
|
||||||
font-size: $title-size-sm;
|
|
||||||
text-align: right;
|
|
||||||
|
|
||||||
&.hide {
|
|
||||||
color: $text-gray-m;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-avatar {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
background: white;
|
|
||||||
border-radius: $radius-m;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.left {
|
|
||||||
.chat-avatar {
|
|
||||||
left: $margin;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-msg {
|
|
||||||
.chat-msg-text {
|
|
||||||
background-color: white;
|
|
||||||
border-radius: 0 $radius*2 $radius*2 $radius*2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.right {
|
|
||||||
.chat-avatar {
|
|
||||||
right: $margin;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-msg {
|
|
||||||
text-align: right;
|
|
||||||
|
|
||||||
.chat-msg-text {
|
|
||||||
border-radius: $radius*2 0 $radius*2 $radius*2;
|
|
||||||
background: $main-color;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-footer {
|
|
||||||
position: fixed;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
height: 140rpx;
|
|
||||||
padding: 20rpx ($padding + 150rpx) 40rpx ($padding + 94rpx);
|
|
||||||
background: white;
|
|
||||||
box-sizing: border-box;
|
|
||||||
z-index: 99;
|
|
||||||
|
|
||||||
.msg-type {
|
|
||||||
position: absolute;
|
|
||||||
top: 20rpx;
|
|
||||||
left: $padding;
|
|
||||||
line-height: 80rpx;
|
|
||||||
|
|
||||||
image {
|
|
||||||
width: 64rpx;
|
|
||||||
height: 64rpx;
|
|
||||||
vertical-align: middle;
|
|
||||||
margin-bottom: 10rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-input {
|
|
||||||
background: $window-color;
|
|
||||||
height: 80rpx;
|
|
||||||
border-radius: $radius-lg;
|
|
||||||
font-size: $title-size-m;
|
|
||||||
padding: 0 $padding;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-mp3 {
|
|
||||||
background: $window-color;
|
|
||||||
line-height: 80rpx;
|
|
||||||
text-align: center;
|
|
||||||
border-radius: $radius-lg;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #333;
|
|
||||||
font-size: $title-size-m;
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-hover {
|
|
||||||
opacity: .5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-push[size='mini'] {
|
|
||||||
position: absolute;
|
|
||||||
right: $margin;
|
|
||||||
top: 20rpx;
|
|
||||||
height: 80rpx;
|
|
||||||
line-height: 80rpx;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
width: 120rpx;
|
|
||||||
background: $main-color;
|
|
||||||
color: white;
|
|
||||||
border-radius: $radius-lg;
|
|
||||||
font-size: $title-size-m;
|
|
||||||
font-weight: bold;
|
|
||||||
|
|
||||||
&[disabled] {
|
|
||||||
background: rgba($color: $main-color, $alpha: .5);
|
|
||||||
}
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import store from '@/store/index.js'
|
import store from '@/store/index.js'
|
||||||
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
|
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
|
||||||
|
|
||||||
const getMessageList = (conversationType, targetId, callback) => {
|
const getMessageList = (conversationType, targetId, timeStamp, count, isForward, callback) => {
|
||||||
// 获取消息列表
|
// 获取消息列表
|
||||||
const objectNames = [
|
const objectNames = [
|
||||||
'RC:TxtMsg',
|
'RC:TxtMsg',
|
||||||
@@ -16,10 +16,12 @@ const getMessageList = (conversationType, targetId, callback) => {
|
|||||||
'RC:ReferenceMsg',
|
'RC:ReferenceMsg',
|
||||||
'RC:CombineMsg'
|
'RC:CombineMsg'
|
||||||
]
|
]
|
||||||
const timeStamp = new Date().getTime()
|
|
||||||
const count = 10 // 获取的消息数量
|
RongIMLib.getHistoryMessagesByTimestamp(
|
||||||
const isForward = true // 是否向前获取
|
conversationType,
|
||||||
RongIMLib.getHistoryMessagesByTimestamp(conversationType, targetId, objectNames, timeStamp,
|
targetId,
|
||||||
|
objectNames,
|
||||||
|
timeStamp + 1000,
|
||||||
count,
|
count,
|
||||||
isForward,
|
isForward,
|
||||||
({
|
({
|
||||||
|
|||||||
388
utils/index.js
388
utils/index.js
@@ -1,221 +1,183 @@
|
|||||||
import sha1 from './sha1.js'
|
import env from './conf/env.js'
|
||||||
import env from './conf/env.js'
|
|
||||||
import * as RongIMLib from '@rongcloud/imlib-uni'
|
|
||||||
export default {
|
export default {
|
||||||
checkPhone: (phone) => {
|
checkPhone: (phone) => {
|
||||||
let re = /^[0-9]+.?[0-9]*/;
|
let re = /^[0-9]+.?[0-9]*/;
|
||||||
if (phone.length === 11) {
|
if (phone.length === 11) {
|
||||||
return re.test(phone)
|
return re.test(phone)
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
jumpUrl(path) {
|
jumpUrl(path) {
|
||||||
uni.navigateTo({
|
uni.navigateTo({
|
||||||
url: path
|
url: path
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
connectIM() {
|
handleTimeCustom(val) {
|
||||||
if(uni.getStorageSync('userInfo')) {
|
val = this.timeStamp(val, 'Y-m-d H:i:s')
|
||||||
let userInfo = JSON.parse(uni.getStorageSync('userInfo'));
|
let currentDate = new Date();
|
||||||
const im = getApp().globalData.im;
|
let currentD = currentDate.getDate();
|
||||||
im.connect({
|
let currentYear = currentDate.getFullYear();
|
||||||
token: userInfo.rongimToken
|
let currentMonth = currentDate.getMonth() + 1;
|
||||||
}).then(user => {
|
let date = val.substring(0, 19);
|
||||||
console.log('IM链接成功, 链接用户 id 为: ', user.id);
|
date = date.replace(/-/g, '/');
|
||||||
}).catch(error => {
|
let valDate = new Date(date);
|
||||||
uni.hideLoading();
|
let valD = valDate.getDate();
|
||||||
console.log('IM链接失败: ', error.code, error.msg);
|
let valYear = valDate.getFullYear();
|
||||||
});
|
let valMonth = valDate.getMonth() + 1;
|
||||||
}
|
// 判断是否属于今天,计算时分
|
||||||
},
|
let difftime = (currentDate - valDate) / 1000;
|
||||||
handleTimeCustom(val) {
|
let hour = valDate.getHours();
|
||||||
val = this.timeStamp(val, 'Y-m-d H:i:s')
|
hour = hour > 9 ? hour : '0' + hour;
|
||||||
let currentDate = new Date();
|
let minute = valDate.getMinutes();
|
||||||
let currentD = currentDate.getDate();
|
minute = minute > 9 ? minute : '0' + minute;
|
||||||
let currentYear = currentDate.getFullYear();
|
if (currentYear === valYear && currentMonth === valMonth && currentD === valD) {
|
||||||
let currentMonth = currentDate.getMonth() + 1;
|
return hour + ':' + minute;
|
||||||
let date = val.substring(0,19);
|
} else {
|
||||||
date = date.replace(/-/g,'/');
|
// 计算天
|
||||||
let valDate = new Date(date);
|
if (currentYear === valYear && currentMonth === valMonth && currentD !== valD) {
|
||||||
let valD = valDate.getDate();
|
return valMonth + '月' + valD + '日 ' + hour + '时' + minute;
|
||||||
let valYear = valDate.getFullYear();
|
} else {
|
||||||
let valMonth = valDate.getMonth() + 1;
|
return valYear + '年' + valMonth + '月' + valD + '日 ' + hour + ':' + minute;
|
||||||
// 判断是否属于今天,计算时分
|
}
|
||||||
let difftime = (currentDate - valDate) / 1000;
|
|
||||||
let hour = valDate.getHours();
|
|
||||||
hour = hour > 9 ? hour : '0' + hour;
|
|
||||||
let minute = valDate.getMinutes();
|
|
||||||
minute = minute > 9 ? minute : '0' + minute;
|
|
||||||
if(currentYear === valYear && currentMonth === valMonth && currentD === valD) {
|
|
||||||
return hour + ':' + minute;
|
|
||||||
} else {
|
|
||||||
// 计算天
|
|
||||||
if(currentYear === valYear && currentMonth === valMonth && currentD !== valD) {
|
|
||||||
return valMonth + '月' + valD + '日 ' + hour + '时' + minute;
|
|
||||||
} else {
|
|
||||||
return valYear + '年' + valMonth + '月' + valD + '日 ' + hour + ':' + minute;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
},
|
|
||||||
handleTimeCustomCN(val) {
|
|
||||||
val = this.timeStamp(val, 'Y-m-d H:i:s')
|
|
||||||
console.log(val, '时间0000000');
|
|
||||||
let currentDate = new Date();
|
|
||||||
let currentD = currentDate.getDate();
|
|
||||||
let currentYear = currentDate.getFullYear();
|
|
||||||
let currentMonth = currentDate.getMonth() + 1;
|
|
||||||
let date = val.substring(0,19);
|
|
||||||
date = date.replace(/-/g,'/');
|
|
||||||
let valDate = new Date(date);
|
|
||||||
let valD = valDate.getDate();
|
|
||||||
let valYear = valDate.getFullYear();
|
|
||||||
let valMonth = valDate.getMonth() + 1;
|
|
||||||
// 判断是否属于今天,计算时分
|
|
||||||
let difftime = (currentDate - valDate) / 1000;
|
|
||||||
if(currentYear === valYear && currentMonth === valMonth && currentD === valD) {
|
|
||||||
let minute = parseInt(difftime % 3600 / 60);
|
|
||||||
if(minute <= 60) {
|
|
||||||
return minute === 0 ? '刚刚' : minute + '分钟前';
|
|
||||||
} else {
|
|
||||||
return (minute * 60).toFixed(0) + '小时前';
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 计算天
|
|
||||||
if(currentYear === valYear && currentMonth === valMonth && currentD - 1 === valD) {
|
|
||||||
return '昨天';
|
|
||||||
} else {
|
|
||||||
let days = Math.abs(currentDate.getTime() - valDate.getTime())/(1000*60*60*24);
|
|
||||||
return Math.ceil(days) + '天前';
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
},
|
|
||||||
timeStamp(timestamp, formats) {
|
|
||||||
/*
|
|
||||||
** 时间戳转换成指定格式日期
|
|
||||||
** eg.
|
|
||||||
** dateFormat(11111111111111, 'Y年m月d日 H时i分')
|
|
||||||
** → "2322年02月06日 03时45分"
|
|
||||||
*/
|
|
||||||
// formats格式包括
|
|
||||||
// 1. Y-m-d
|
|
||||||
// 2. Y-m-d H:i:s
|
|
||||||
// 3. Y年m月d日
|
|
||||||
// 4. Y年m月d日 H时i分
|
|
||||||
formats = formats || 'Y-m-d';
|
|
||||||
|
|
||||||
var zero = function(value) {
|
}
|
||||||
if (value < 10) {
|
},
|
||||||
return '0' + value;
|
handleTimeCustomCN(val) {
|
||||||
}
|
val = this.timeStamp(val, 'Y-m-d H:i:s')
|
||||||
return value;
|
console.log(val, '时间0000000');
|
||||||
};
|
let currentDate = new Date();
|
||||||
var myDate = timestamp ? new Date(timestamp) : new Date();
|
let currentD = currentDate.getDate();
|
||||||
|
let currentYear = currentDate.getFullYear();
|
||||||
|
let currentMonth = currentDate.getMonth() + 1;
|
||||||
|
let date = val.substring(0, 19);
|
||||||
|
date = date.replace(/-/g, '/');
|
||||||
|
let valDate = new Date(date);
|
||||||
|
let valD = valDate.getDate();
|
||||||
|
let valYear = valDate.getFullYear();
|
||||||
|
let valMonth = valDate.getMonth() + 1;
|
||||||
|
// 判断是否属于今天,计算时分
|
||||||
|
let difftime = (currentDate - valDate) / 1000;
|
||||||
|
if (currentYear === valYear && currentMonth === valMonth && currentD === valD) {
|
||||||
|
let minute = parseInt(difftime % 3600 / 60);
|
||||||
|
if (minute <= 60) {
|
||||||
|
return minute === 0 ? '刚刚' : minute + '分钟前';
|
||||||
|
} else {
|
||||||
|
return (minute * 60).toFixed(0) + '小时前';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 计算天
|
||||||
|
if (currentYear === valYear && currentMonth === valMonth && currentD - 1 === valD) {
|
||||||
|
return '昨天';
|
||||||
|
} else {
|
||||||
|
let days = Math.abs(currentDate.getTime() - valDate.getTime()) / (1000 * 60 * 60 * 24);
|
||||||
|
return Math.ceil(days) + '天前';
|
||||||
|
}
|
||||||
|
|
||||||
var year = myDate.getFullYear();
|
}
|
||||||
var month = zero(myDate.getMonth() + 1);
|
},
|
||||||
var day = zero(myDate.getDate());
|
timeStamp(timestamp, formats) {
|
||||||
|
/*
|
||||||
|
** 时间戳转换成指定格式日期
|
||||||
|
** eg.
|
||||||
|
** dateFormat(11111111111111, 'Y年m月d日 H时i分')
|
||||||
|
** → "2322年02月06日 03时45分"
|
||||||
|
*/
|
||||||
|
// formats格式包括
|
||||||
|
// 1. Y-m-d
|
||||||
|
// 2. Y-m-d H:i:s
|
||||||
|
// 3. Y年m月d日
|
||||||
|
// 4. Y年m月d日 H时i分
|
||||||
|
formats = formats || 'Y-m-d';
|
||||||
|
|
||||||
var hour = zero(myDate.getHours());
|
var zero = function(value) {
|
||||||
var minite = zero(myDate.getMinutes());
|
if (value < 10) {
|
||||||
var second = zero(myDate.getSeconds());
|
return '0' + value;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
};
|
||||||
|
var myDate = timestamp ? new Date(timestamp) : new Date();
|
||||||
|
|
||||||
return formats.replace(/Y|m|d|H|i|s/ig, function(matches) {
|
var year = myDate.getFullYear();
|
||||||
return ({
|
var month = zero(myDate.getMonth() + 1);
|
||||||
Y: year,
|
var day = zero(myDate.getDate());
|
||||||
m: month,
|
|
||||||
d: day,
|
|
||||||
H: hour,
|
|
||||||
i: minite,
|
|
||||||
s: second
|
|
||||||
})[matches];
|
|
||||||
});
|
|
||||||
},
|
|
||||||
// 时间字符串转换中文时间
|
|
||||||
timeToDate(str) {
|
|
||||||
let date = str.substring(0, 19);
|
|
||||||
date = date.replace(/-/g, '/');
|
|
||||||
date = new Date(str);
|
|
||||||
let dateObj = {
|
|
||||||
year: date.getFullYear(),
|
|
||||||
month: date.getMonth() + 1,
|
|
||||||
day: date.getDate(),
|
|
||||||
hour: date.getHours(),
|
|
||||||
minute: date.getMinutes(),
|
|
||||||
second: date.getSeconds()
|
|
||||||
}
|
|
||||||
let string = dateObj.year + '年' + dateObj.month + '月' + dateObj.day + '日 ' + dateObj.hour + '时' + dateObj
|
|
||||||
.minute + '分';
|
|
||||||
return string
|
|
||||||
},
|
|
||||||
getAge(strAge) {
|
|
||||||
let birArr = strAge.split("-");
|
|
||||||
let birYear = birArr[0];
|
|
||||||
let birMonth = birArr[1];
|
|
||||||
let birDay = birArr[2];
|
|
||||||
|
|
||||||
d = new Date();
|
var hour = zero(myDate.getHours());
|
||||||
let nowYear = d.getFullYear();
|
var minite = zero(myDate.getMinutes());
|
||||||
let nowMonth = d.getMonth() + 1; //记得加1
|
var second = zero(myDate.getSeconds());
|
||||||
let nowDay = d.getDate();
|
|
||||||
let returnAge;
|
|
||||||
|
|
||||||
if (birArr == null) {
|
return formats.replace(/Y|m|d|H|i|s/ig, function(matches) {
|
||||||
return false
|
return ({
|
||||||
};
|
Y: year,
|
||||||
let d = new Date(birYear, birMonth - 1, birDay);
|
m: month,
|
||||||
if (d.getFullYear() == birYear && (d.getMonth() + 1) == birMonth && d.getDate() == birDay) {
|
d: day,
|
||||||
if (nowYear == birYear) {
|
H: hour,
|
||||||
returnAge = 0;
|
i: minite,
|
||||||
} else {
|
s: second
|
||||||
let ageDiff = nowYear - birYear;
|
})[matches];
|
||||||
if (ageDiff > 0) {
|
});
|
||||||
if (nowMonth == birMonth) {
|
},
|
||||||
let dayDiff = nowDay - birDay;
|
// 时间字符串转换中文时间
|
||||||
if (dayDiff < 0) {
|
timeToDate(str) {
|
||||||
returnAge = ageDiff - 1;
|
let date = str.substring(0, 19);
|
||||||
} else {
|
date = date.replace(/-/g, '/');
|
||||||
returnAge = ageDiff;
|
date = new Date(str);
|
||||||
}
|
let dateObj = {
|
||||||
} else {
|
year: date.getFullYear(),
|
||||||
let monthDiff = nowMonth - birMonth;
|
month: date.getMonth() + 1,
|
||||||
if (monthDiff < 0) {
|
day: date.getDate(),
|
||||||
returnAge = ageDiff - 1;
|
hour: date.getHours(),
|
||||||
} else {
|
minute: date.getMinutes(),
|
||||||
returnAge = ageDiff;
|
second: date.getSeconds()
|
||||||
}
|
}
|
||||||
}
|
let string = dateObj.year + '年' + dateObj.month + '月' + dateObj.day + '日 ' + dateObj.hour + '时' + dateObj
|
||||||
} else {
|
.minute + '分';
|
||||||
return "出生日期晚于今天,数据有误"; //返回-1 表示出生日期输入错误 晚于今天
|
return string
|
||||||
}
|
},
|
||||||
}
|
getAge(strAge) {
|
||||||
return returnAge;
|
let birArr = strAge.split("-");
|
||||||
} else {
|
let birYear = birArr[0];
|
||||||
return ("输入的日期格式错误!");
|
let birMonth = birArr[1];
|
||||||
}
|
let birDay = birArr[2];
|
||||||
},
|
|
||||||
getImUserInfo(targetId) {
|
d = new Date();
|
||||||
return new Promise((resolve, reject) => {
|
let nowYear = d.getFullYear();
|
||||||
const Nonce = Date.now();
|
let nowMonth = d.getMonth() + 1; //记得加1
|
||||||
const Timestamp = Date.now() * 1000;
|
let nowDay = d.getDate();
|
||||||
uni.request({
|
let returnAge;
|
||||||
url: 'https://api2-cn.ronghub.com/user/info.json', //仅为示例,并非真实接口地址。
|
|
||||||
data: {
|
if (birArr == null) {
|
||||||
userId: targetId
|
return false
|
||||||
},
|
};
|
||||||
method: 'POST',
|
let d = new Date(birYear, birMonth - 1, birDay);
|
||||||
header: {
|
if (d.getFullYear() == birYear && (d.getMonth() + 1) == birMonth && d.getDate() == birDay) {
|
||||||
'Content-Type': 'application/x-www-form-urlencoded',
|
if (nowYear == birYear) {
|
||||||
'App-Key': '你的key',
|
returnAge = 0;
|
||||||
'Nonce': Nonce,
|
} else {
|
||||||
'Timestamp': Timestamp,
|
let ageDiff = nowYear - birYear;
|
||||||
'Signature': sha1(env.IMsecret + Nonce + Timestamp)
|
if (ageDiff > 0) {
|
||||||
},
|
if (nowMonth == birMonth) {
|
||||||
success: (res) => {
|
let dayDiff = nowDay - birDay;
|
||||||
resolve(res.data)
|
if (dayDiff < 0) {
|
||||||
}
|
returnAge = ageDiff - 1;
|
||||||
});
|
} else {
|
||||||
})
|
returnAge = ageDiff;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
let monthDiff = nowMonth - birMonth;
|
||||||
|
if (monthDiff < 0) {
|
||||||
|
returnAge = ageDiff - 1;
|
||||||
|
} else {
|
||||||
|
returnAge = ageDiff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return "出生日期晚于今天,数据有误"; //返回-1 表示出生日期输入错误 晚于今天
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return returnAge;
|
||||||
|
} else {
|
||||||
|
return ("输入的日期格式错误!");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,50 +0,0 @@
|
|||||||
function encodeUTF8(s) {
|
|
||||||
var i, r = [], c, x;
|
|
||||||
for (i = 0; i < s.length; i++)
|
|
||||||
if ((c = s.charCodeAt(i)) < 0x80) r.push(c);
|
|
||||||
else if (c < 0x800) r.push(0xC0 + (c >> 6 & 0x1F), 0x80 + (c & 0x3F));
|
|
||||||
else {
|
|
||||||
if ((x = c ^ 0xD800) >> 10 == 0) //对四字节UTF-16转换为Unicode
|
|
||||||
c = (x << 10) + (s.charCodeAt(++i) ^ 0xDC00) + 0x10000,
|
|
||||||
r.push(0xF0 + (c >> 18 & 0x7), 0x80 + (c >> 12 & 0x3F));
|
|
||||||
else r.push(0xE0 + (c >> 12 & 0xF));
|
|
||||||
r.push(0x80 + (c >> 6 & 0x3F), 0x80 + (c & 0x3F));
|
|
||||||
};
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 字符串加密成 hex 字符串
|
|
||||||
function sha1(s) {
|
|
||||||
var data = new Uint8Array(encodeUTF8(s))
|
|
||||||
var i, j, t;
|
|
||||||
var l = ((data.length + 8) >>> 6 << 4) + 16, s = new Uint8Array(l << 2);
|
|
||||||
s.set(new Uint8Array(data.buffer)), s = new Uint32Array(s.buffer);
|
|
||||||
for (t = new DataView(s.buffer), i = 0; i < l; i++)s[i] = t.getUint32(i << 2);
|
|
||||||
s[data.length >> 2] |= 0x80 << (24 - (data.length & 3) * 8);
|
|
||||||
s[l - 1] = data.length << 3;
|
|
||||||
var w = [], f = [
|
|
||||||
function () { return m[1] & m[2] | ~m[1] & m[3]; },
|
|
||||||
function () { return m[1] ^ m[2] ^ m[3]; },
|
|
||||||
function () { return m[1] & m[2] | m[1] & m[3] | m[2] & m[3]; },
|
|
||||||
function () { return m[1] ^ m[2] ^ m[3]; }
|
|
||||||
], rol = function (n, c) { return n << c | n >>> (32 - c); },
|
|
||||||
k = [1518500249, 1859775393, -1894007588, -899497514],
|
|
||||||
m = [1732584193, -271733879, null, null, -1009589776];
|
|
||||||
m[2] = ~m[0], m[3] = ~m[1];
|
|
||||||
for (i = 0; i < s.length; i += 16) {
|
|
||||||
var o = m.slice(0);
|
|
||||||
for (j = 0; j < 80; j++)
|
|
||||||
w[j] = j < 16 ? s[i + j] : rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1),
|
|
||||||
t = rol(m[0], 5) + f[j / 20 | 0]() + m[4] + w[j] + k[j / 20 | 0] | 0,
|
|
||||||
m[1] = rol(m[1], 30), m.pop(), m.unshift(t);
|
|
||||||
for (j = 0; j < 5; j++)m[j] = m[j] + o[j] | 0;
|
|
||||||
};
|
|
||||||
t = new DataView(new Uint32Array(m).buffer);
|
|
||||||
for (var i = 0; i < 5; i++)m[i] = t.getUint32(i << 2);
|
|
||||||
|
|
||||||
var hex = Array.prototype.map.call(new Uint8Array(new Uint32Array(m).buffer), function (e) {
|
|
||||||
return (e < 16 ? "0" : "") + e.toString(16);
|
|
||||||
}).join("");
|
|
||||||
return hex;
|
|
||||||
}
|
|
||||||
export default sha1
|
|
||||||
Reference in New Issue
Block a user