合并代码

This commit is contained in:
sx 2025-01-08 21:01:16 +08:00
parent 5c80ff7a73
commit 16e7531f7d
11 changed files with 229 additions and 189 deletions

View File

@ -45,8 +45,8 @@ export const news = {
deleteFriend(param) {
return util.request({
url: `/user/chat/relation/deleteFriend`,
method: 'POST',
data: param.data,
method: 'DELETE',
query: param.query,
})
},
@ -133,6 +133,7 @@ export const news = {
})
},
//
grabredLog(param) {
return util.request({
url: `/home/grabredLog`,
@ -147,7 +148,45 @@ export const news = {
url: `/user/chat/relation/myFriends`,
method: 'GET'
})
}
},
// 获取私聊聊天记录
getUserMsgHistory(param) {
return util.request({
url: `/user/chat/single/getMsgList`,
query: param.query,
method: 'GET'
})
},
// 获取群聊聊天记录
getGroupMsgHistory(param) {
return util.request({
url: `/user/chat/group/getMsgList`,
query: param.query,
method: 'GET'
})
},
// 私聊发消息
sendUserMsg(param) {
return util.request({
url: `/user/chat/single/sendMsg`,
query: param.query,
data: param.data,
method: 'POST'
})
},
// 群聊发消息
sendGroupMsg(param) {
return util.request({
url: `/user/chat/group/sendMsg`,
query: param.query,
data: param.data,
method: 'POST'
})
},
}
export default news

View File

@ -1731,7 +1731,7 @@ const util = {
* @param {Object} option
* @param {Object} option.name 标题昵称
* @param {Object} option.msgId 聊天对象id
* @param {Object} option.type 聊天类型
* @param {Object} option.type 聊天类型 C2C单聊 GROUP群聊
*/
toChat(option) {
uni.navigateTo({

View File

@ -223,8 +223,9 @@
api.news.getFriendList().then(rs => {
if (rs.code == 200) {
const result = rs.data
userList.data.length = 0
//
userList.data.push(...result.rows.map(item => {
userList.data.push(...result.map(item => {
//
let char = pinyin.getCamelChars(item.remark || item.userNickname);
return {
@ -233,6 +234,7 @@
child: [item]
}
}))
console.log('userList', userList.data)
return
}
util.alert({
@ -312,8 +314,8 @@
})
}).then(rs => {
api.news.deleteFriend({
data: {
toUserId: user.userId,
query: {
toUserIds: user.userId,
},
}).then(rs => {
if (rs.code === 200) {
@ -370,8 +372,8 @@
*/
function handleUser(user) {
util.toChat({
name: user.remark || user.profile.nick,
msgId: user.userID,
name: user.remark || user.userNickname,
msgId: user.userId,
type: 'C2C',
})
}
@ -393,7 +395,7 @@
<!-- 菜单 -->
<view class="menu oh c333 f34">
<view class="rows ptb20 plr30 bfff" @click="link('/pages/news/newFriend')">
<view class="">好友申请</view>
<view class="">新朋友</view>
<uni-icons type="right" color="#999" size="30rpx" />
</view>

View File

@ -10,8 +10,6 @@
nextTick,
onUnmounted,
onMounted,
inject,
provide,
computed,
getCurrentInstance,
watch,
@ -26,18 +24,16 @@
onPageScroll,
onUnload
} from "@dcloudio/uni-app"
import {
getHistoryMsg
} from './fn.js'
import newsTempSystem from './components/news-temp-system'
//
import newsTemplate from './components/news-temp'
import NewsEmoji from '@/static/news-emoji.png'
import NewsPlus from '@/static/news-plus.png'
import NewsVoice from '@/static/news-voice.png'
//
import emoji from './emoji.vue'
//
import JyVoice from './jy-voice.vue'
//
import JyPlus from './jy-plus.vue'
import {
useStore
} from 'vuex'
@ -55,18 +51,22 @@
})
//
const content = ref('')
//
const loading = ref(false)
const isLast = ref(false)
//
const userinfo = computed(() => {
let result = store.state.userinfo
return result
})
//
const list = ref([])
// id im
const nextReqMessageID = ref(undefined)
//
const list = reactive({
//
limit: 20,
//
data: [],
//
total: 0,
})
//
const top = ref(0)
//
@ -95,14 +95,17 @@
//
addListener()
//
getHistory(scrollToBottom)
//
getHistory({
callback: scrollToBottom
})
// #ifdef APP
uni.onKeyboardHeightChange((rs) => {
ghostBox.value.height = rs.height + 'px'
nextTick(() => {
scrollToBottom()
})
})
// #endif
})
onReady(() => {
@ -118,15 +121,21 @@
})
onUnload(() => {
// #ifdef APP
uni.offKeyboardHeightChange(() => {})
// #endif
videoContext.value.stop()
})
//
function addListener() {
let onMessageReceived = function(event) {
console.log('TencentCloudChat.EVENT.MESSAGE_RECEIVED', event)
return
//
getHistory()
//
list.value.push(...event.data)
list.data.push(...event.data)
}
uni.$chat.on(TencentCloudChat.EVENT.MESSAGE_RECEIVED, onMessageReceived);
@ -139,67 +148,76 @@
//
function getMoreHistroy() {
if (nextReqMessageID.value) getHistory()
//
if (list.total <= list.data.length) return
getHistory({
param: list.data[0].id
})
}
//
function getHistory(callback = () => {}) {
/**
* 获取历史记录
* @param {Object} param
*/
function getHistory(param = {}) {
// sdk
let isReady = uni.$chat.isReady();
//
if (!isReady && userinfo.value.userId) {
if (!isReady && userinfo.value.id) {
setTimeout(function() {
getHistory(callback)
getHistory(param)
}, 200);
return
}
// msgId
// if(!param.msgId)
if (loading.value) {
//
util.showToastAndRedirect("加载中")
return
}
if (!isLast.value) {
loading.value = true
//
getHistoryMsg({
msgId: msg.id,
chatType: msg.type,
nextReqMessageID: nextReqMessageID.value,
}).then(res => {
//
loading.value = true
//
let request = api.news.getUserMsgHistory
//
if (msg.type === 'GROUP') api.news.getGroupMsgHistory
//
request({
query: {
msgId: param.msgId || '',
fromId: userinfo.value.id,
toId: msg.id,
limit: param.limit || list.limit,
},
}).then(res => {
if (res.code === 200) {
//
const result = res.data
if (page.value == 1) list.value.length = 0
//
list.value.unshift(...result.messageList.map(item => {
try {
// 1 2
item.messageType = 1
// console.log('check 1', item.type, TencentCloudChat.TYPES.MSG_CUSTOM, item.payload.data)
//
if (item.type === TencentCloudChat.TYPES.MSG_CUSTOM && item.payload.data) {
if (item.payload.data) item.payload.data = JSON.parse(item.payload.data)
if (item.payload.data.data) item.payload.data.data = JSON.parse(item.payload.data.data)
//
if (['1', 'group_create'].includes(item.payload.data.businessID)) {
item.messageType = 2
}
}
} catch (err) {
console.log('map catch', err)
}
//
list.data.unshift(...result.list.map(item => {
item.callbackData = JSON.parse(item.callbackJson)
return item
}))
page.value++
console.log('getHistoryMsg then', result.messageList.length, list.value, res)
//
nextReqMessageID.value = result.nextReqMessageID || undefined;
//
list.total = result.totalCount
console.log('list', list.data)
nextTick(() => {
callback()
param.callback && param.callback()
})
}).finally(() => {
loading.value = false
return
}
util.alert({
content: res.msg,
showCancel: false,
})
}
}).finally(() => {
loading.value = false
})
}
//
@ -236,22 +254,15 @@
//
function handleSend() {
//
let message = uni.$chat.createTextMessage({
to: msg.id,
conversationType: msg.type,
payload: {
text: content.value
},
//
needReadReceipt: true,
//
// cloudCustomData: 'content.value',
});
//
sendMsg({
message,
query: {
toUserId: msg.id,
msgType: TencentCloudChat.TYPES.MSG_TEXT,
},
data: {
text: content.value
},
success: () => {
//
content.value = ''
@ -275,12 +286,27 @@
* @param {Object} param
*/
function sendMsg(param) {
//
const request = api.news.sendUserMsg
//
if (msg.type == 'group') request = api.news.sendGroupMsg
//
uni.$chat.sendMessage(param.message).then((rs) => {
console.log('rs', rs)
param.success ? param.success() : ''
//
getHistory(scrollToBottom())
request({
query: param.query,
data: param.data,
}).then((rs) => {
if (rs.code == 200) {
param.success ? param.success() : ''
//
getHistory({
callback: scrollToBottom,
})
return
}
util.alert({
content: rs.msg,
showCancel: false,
})
}).catch((rs) => {
console.log('sendMsg error:', rs);
})
@ -407,7 +433,6 @@
videoUrl.value = item.payload.videoUrl
//
videoContext.value.requestFullScreen()
videoContext.value.requestFullScreen()
}
//
@ -419,37 +444,29 @@
<template>
<view class="app">
<scroll-view class="scroll-view" scroll-y :scroll-with-animation="true" :scroll-top="top" @scroll="onContentScroll" @scrolltoupper="getMoreHistroy">
<scroll-view class="scroll-view" scroll-y :scroll-with-animation="true" :scroll-top="top"
@scroll="onContentScroll" @scrolltoupper="getMoreHistroy">
<view id="scroll-content" style="padding: 30rpx 30rpx">
<view v-for="(item, index) in list" :key="index">
<!-- 系统消息 -->
<template v-if="item.messageType == 2">
<!-- 创建群聊 -->
<view class="mtb30 tac c999 f22" v-if="item.payload.data.businessID === 'group_create'">群组创建成功</view>
</template>
<view v-for="(item, index) in list.data" :key="index">
<!-- 普通消息 -->
<template v-else-if="item.messageType == 1">
<view class="message" :class="[item.from === userinfo.userId ? 'self' : 'friend']">
<!-- 如果是我自己 -->
<view v-if="item.from === userinfo.userId">
<image :src="util.format_url(userinfo.userPortrait, 'img')" class="avatar" mode="widthFix" />
</view>
<!-- 如果是用户 -->
<view v-else>
<image :src="item.avatar" class="avatar" mode="widthFix" />
</view>
<view class="df fdc mlr20">
<!-- 昵称 -->
<view class="df fdc" v-if="item.from != userinfo.userId">
<view class="name">{{ item.nick }}</view>
</view>
<!-- 消息 -->
<newsTemplate :item="item" :msg="msg" @openRedBag="handleRedPacket" @viewVideo="handleViewVideo" />
</view>
<view class="message" :class="[item.From_Account === userinfo.id ? 'self' : 'friend']">
<!-- 如果是我自己 -->
<view>
<image :src="item.callbackData.from_url" class="avatar" mode="widthFix" />
</view>
</template>
<view class="df fdc mlr20">
<!-- 昵称 -->
<view class="df fdc" v-if="item.from != userinfo.userId">
<view class="name">{{ item.callbackData.from_name }}</view>
</view>
<!-- 消息 -->
<newsTemplate :item="item" :msg="msg" @openRedBag="handleRedPacket"
@viewVideo="handleViewVideo" />
</view>
</view>
</view>
<view v-if="showGhost" :style="{ height: `${ghostBox.height}px`, transition: `${ghostBox.duration}s` }">
</view>
<view v-if="showGhost" :style="{ height: `${ghostBox.height}px`, transition: `${ghostBox.duration}s` }"></view>
<view class="ghost" :style="{height: toolHeight + 'px'}"></view>
</view>
</scroll-view>
@ -458,20 +475,22 @@
<view class="tool" id="tool">
<view class="tool-group" style="background: #F6F6F6;">
<!-- 语音 -->
<image :src="NewsVoice" mode="widthFix" class="thumb" @click="handleTool('voice')"></image>
<image src="/static/news-voice.png" mode="widthFix" class="thumb" @click="handleTool('voice')"></image>
<!-- 摁住说话 -->
<template v-if="toolStatus == 'voice'">
<JyVoice @send="voiceSend" :msg="msg" />
</template>
<!-- 输入框 -->
<template v-if="toolStatus != 'voice'">
<uni-easyinput @focus="onFocus" type="text" v-model="content" :clearable="false" class="input" :adjust-position="false" @keyboardheightchange="keyboardheightchange" placeholder="请输入你的问题" confirmType="发送" />
<uni-easyinput @focus="onFocus" type="text" v-model="content" :clearable="false" class="input"
:adjust-position="false" @keyboardheightchange="keyboardheightchange" placeholder="请输入你的问题"
confirmType="发送" />
</template>
<!-- 表情 -->
<image :src="NewsEmoji" mode="widthFix" class="thumb" @click="handleTool('emoji')"></image>
<image src="/static/news-emoji.png" mode="widthFix" class="thumb" @click="handleTool('emoji')"></image>
<!-- 加号 -->
<template v-if="!content">
<image :src="NewsPlus" mode="widthFix" class="thumb" @click="handleTool('plus')" />
<image src="/static/news-plus.png" mode="widthFix" class="thumb" @click="handleTool('plus')" />
</template>
<!-- 文本发送按钮 -->
<template v-else>

View File

@ -1,24 +0,0 @@
<!-- 系统消息 -->
<template>
<view class="news-temp-system">
<view v-if="item.ext.type === 'time'" class="system"> {{ item.ext.time }}</view>
</view>
</template>
<script setup>
import { ref } from 'vue'
const props = defineProps({
item: {
type: Object,
default: () => { }
}
})
</script>
<style scoped lang="scss">
.system {
padding: 20rpx 0;
color: #858585;
font-size: 28rpx;
text-align: center;
}
</style>

View File

@ -30,13 +30,6 @@
} from 'vuex'
const store = useStore()
const emit = defineEmits(['openRedBag', 'viewVideo'])
// watch(props.item, nV => {
// console.log('watch item', nV.type, nV)
// }, {
// immediate: true
// })
//
const formatData = computed(() => {
let result = props.item.payload.data
@ -85,17 +78,17 @@
<template>
<view class="content pr">
<!-- 图片 -->
<template v-if="item.type === TencentCloudChat.TYPES.MSG_IMAGE">
<template v-if="item.callbackData.MsgType === TencentCloudChat.TYPES.MSG_IMAGE">
<image :src="item.payload.imageInfoArray[0].imageUrl" mode="widthFix" />
</template>
<!-- 文字 -->
<template v-else-if="item.type === TencentCloudChat.TYPES.MSG_TEXT">
<template v-else-if="item.callbackData.MsgType === TencentCloudChat.TYPES.MSG_TEXT">
<view class="p25">
{{ item.payload.text }}
{{ item.callbackData.callback_json.Text }}
</view>
</template>
<!-- 自定义消息 -->
<template v-else-if="item.type === TencentCloudChat.TYPES.MSG_CUSTOM">
<template v-else-if="item.callbackData.MsgType === TencentCloudChat.TYPES.MSG_CUSTOM">
<!-- 判断业务字段 -->
<template v-if="formatData.businessID">
<!-- 音视频通话 -->
@ -104,8 +97,10 @@
<view class="p25" @click="handleCall">
<template v-if="formatData.actionType == TencentCloudChat.TSignaling.ACTION_TYPE_INVITE">
<text>[ </text>
<uni-icons type="videocam" color="#333" size="32rpx" v-if="formatData.data.call_type == 1" />
<uni-icons type="phone" color="#333" size="32rpx" v-else-if="formatData.data.call_type == 2" />
<uni-icons type="videocam" color="#333" size="32rpx"
v-if="formatData.data.call_type == 1" />
<uni-icons type="phone" color="#333" size="32rpx"
v-else-if="formatData.data.call_type == 2" />
<text>发起</text>
<text v-if="formatData.data.call_type == 1">语音</text>
<text v-else-if="formatData.data.call_type == 2">视频</text>
@ -114,27 +109,36 @@
</template>
<template v-if="formatData.actionType == TencentCloudChat.TSignaling.ACTION_TYPE_CANCEL_INVITE">
<text>[</text>
<uni-icons type="videocam" color="#333" size="32rpx" v-if="formatData.data.call_type == 1" />
<uni-icons type="phone" color="#333" size="32rpx" v-else-if="formatData.data.call_type == 2" />
<uni-icons type="videocam" color="#333" size="32rpx"
v-if="formatData.data.call_type == 1" />
<uni-icons type="phone" color="#333" size="32rpx"
v-else-if="formatData.data.call_type == 2" />
<text>已取消通话 ]</text>
</template>
<template v-if="formatData.actionType == TencentCloudChat.TSignaling.ACTION_TYPE_ACCEPT_INVITE">
<text>[ </text>
<uni-icons type="videocam" color="#333" size="32rpx" v-if="formatData.data.call_type == 1" />
<uni-icons type="phone" color="#333" size="32rpx" v-else-if="formatData.data.call_type == 2" />
<uni-icons type="videocam" color="#333" size="32rpx"
v-if="formatData.data.call_type == 1" />
<uni-icons type="phone" color="#333" size="32rpx"
v-else-if="formatData.data.call_type == 2" />
<text>已接通 ]</text>
<!-- <text>[ 通话时长 {{formatData.data.call_end}} ]</text> -->
</template>
<template v-if="formatData.actionType == TencentCloudChat.TSignaling.ACTION_TYPE_REJECT_INVITE">
<text>[ </text>
<uni-icons type="videocam" color="#333" size="32rpx" v-if="formatData.data.call_type == 1" />
<uni-icons type="phone" color="#333" size="32rpx" v-else-if="formatData.data.call_type == 2" />
<uni-icons type="videocam" color="#333" size="32rpx"
v-if="formatData.data.call_type == 1" />
<uni-icons type="phone" color="#333" size="32rpx"
v-else-if="formatData.data.call_type == 2" />
<text>已拒绝通话 ]</text>
</template>
<template v-if="formatData.actionType == TencentCloudChat.TSignaling.ACTION_TYPE_INVITE_TIMEOUT">
<template
v-if="formatData.actionType == TencentCloudChat.TSignaling.ACTION_TYPE_INVITE_TIMEOUT">
<text>[ </text>
<uni-icons type="videocam" color="#333" size="32rpx" v-if="formatData.data.call_type == 1" />
<uni-icons type="phone" color="#333" size="32rpx" v-else-if="formatData.data.call_type == 2" />
<uni-icons type="videocam" color="#333" size="32rpx"
v-if="formatData.data.call_type == 1" />
<uni-icons type="phone" color="#333" size="32rpx"
v-else-if="formatData.data.call_type == 2" />
<text>超时未接听 ]</text>
</template>
</view>
@ -142,7 +146,8 @@
<!-- 红包消息 -->
<template v-else-if="formatData.businessID == 'redPacket'">
<!-- 红包 -->
<view class="redPacket br10" :class="{'disabled': formatData.status != 0 || formatData.receive}" @click="handleOpenRedBag">
<view class="redPacket br10" :class="{'disabled': formatData.status != 0 || formatData.receive}"
@click="handleOpenRedBag">
<view class="df aic">
<image class="img mr10" src="/static/image/red-envelope.png" />
<view class="red-packet-text">{{ formatData.name }}</view>
@ -156,7 +161,7 @@
</template>
<!-- 音频文件 -->
<template v-if="item.type == TencentCloudChat.TYPES.MSG_AUDIO">
<template v-if="item.callbackData.MsgType == TencentCloudChat.TYPES.MSG_AUDIO">
<div class="df aic p25" style="width: 100rpx" @click="payAudio(item)">
<image class="mr20" style="width: 30rpx;height: 30rpx;z-index: 1;" :src="NewsAudio" />
<text>{{ item.payload.downloadFlag }}''</text>
@ -164,7 +169,7 @@
</template>
<!-- 视频消息 -->
<template v-if="item.type == TencentCloudChat.TYPES.MSG_VIDEO">
<template v-if="item.callbackData.MsgType == TencentCloudChat.TYPES.MSG_VIDEO">
<image :src="item.payload.snapshotUrl" mode="widthFix" />
<view class="window pfull" @click="handleViewVideo(item)">
<image class="pause pmid wh40" src="/static/pause.png" mode="aspectFit" />
@ -172,11 +177,11 @@
</template>
<!-- 咨询订单 -->
<template v-if="item.type === 'order'">
<template v-if="item.callbackData.MsgType === 'order'">
<JyCommodityInformation :showType="4" :right="false"></JyCommodityInformation>
</template>
<!-- 咨询商品-->
<template v-if="item.type === 'shop'">
<template v-if="item.callbackData.MsgType === 'shop'">
<JyCommodityInformation :showType="3"></JyCommodityInformation>
</template>
</view>

View File

@ -1,6 +1,7 @@
<!-- 语音 -->
<template>
<view class="voice_box" @touchstart="sv.touchstartVoice" @touchmove.stop.prevent="sv.touchmoveVoice" @touchend="sv.touchendVoice" @touchcancel="sv.touchcancelVoice">
<view class="voice_box" @touchstart="sv.touchstartVoice" @touchmove.stop.prevent="sv.touchmoveVoice"
@touchend="sv.touchendVoice" @touchcancel="sv.touchcancelVoice">
<text class="voice_text c000">{{ voiceText }}</text>
</view>
@ -22,7 +23,9 @@
//
import TencentCloudChat from '@tencentcloud/chat';
const props = defineProps({
msg: Object,
msg: {
type: Object
},
})
const emit = defineEmits(['send'])
//

View File

@ -279,9 +279,10 @@
}
}
//
//
.swiper {
flex: 1;
width: 100%;
}
//

View File

@ -344,6 +344,10 @@
util.alert('正文不能为空')
return
}
if (!labelSelect[0]) {
util.alert('标签不能为空')
return
}
}
//
if (labelSelect[0]) {

View File

@ -175,12 +175,6 @@ register
isShop
1
实名认证
账号唯一
一个实名信息只能绑定一个账号
其他的账号绑定实名提示
即时通讯 发红包
积分 余额
消息添加红包功能
@ -355,12 +349,6 @@ call_type 通话类型 2为视频1是音频
长按二倍速
发布
视频列表
有效读秒
释放榴莲果
钱包
释放
选择视频截帧
@ -388,3 +376,6 @@ call_type 通话类型 2为视频1是音频
"likeStatus": "1" // 1 公开赞 2私有赞 0 没有赞

View File

@ -15,22 +15,22 @@ export default defineConfig({
},
"/user": {
// target: "http://192.168.0.129:8080",
target: "http://192.168.0.133:8080",
target: "http://192.168.1.199:8080",
changeOrigin: true,
},
"/coreplay": {
// target: "http://192.168.0.129:8080",
target: "http://192.168.0.133:8080",
target: "http://192.168.1.199:8080",
changeOrigin: true,
},
"/file": {
// target: "http://192.168.0.129:8080",
target: "http://192.168.0.133:8080",
target: "http://192.168.1.199:8080",
changeOrigin: true,
},
"/video": {
// target: "http://192.168.0.129:8080",
target: "http://192.168.0.133:8080",
target: "http://192.168.1.199:8080",
changeOrigin: true,
},
}