作者 韩昌

优化im

<template>
<view class="message-bubble" :class="[message.flow === 'in' ? '' : 'reverse']">
<image class="avatar" mode="aspectFill" :src="DialogUserAvatar || 'https://web.sdk.qcloud.com/component/TUIKit/assets/avatar_21.png'" alt=""></image>
<!-- <image class="avatar" mode="aspectFill" :src="DialogUserAvatar || '/static/images/mAvatar.png'" alt=""></image> -->
<view class="message-bubble" :class="[message.flow === 'in' ? '' : 'reverse']" v-if="![types.MSG_CUSTOM].includes(data.type)">
<image class="avatar" mode="aspectFill" :src="'https://web.sdk.qcloud.com/component/TUIKit/assets/avatar_21.png'" alt=""></image>
<view>
<view class="username" :style="{ textAlign: message.flow === 'in' ? 'left' : 'right' }">{{ DialogUserName }}</view>
<view class="message-area">
<label class="name" v-if="message.flow === 'in'">{{ message.nick }}</label>
<div :class="['content content-' + message.flow]">
... ... @@ -11,16 +9,16 @@
</div>
</view>
</view>
<view class="message-label fail" v-if="message.status === 'fail'">!</view>
<view class="message-label" :class="[!message.isPeerRead && 'unRead']" v-if="message.conversationType === 'C2C' && message.flow == 'out' && message.status !== 'fail'">
<!-- <view class="message-label fail" v-if="message.status === 'fail'">!</view> -->
<!-- <view class="message-label" :class="[!message.isPeerRead && 'unRead']" v-if="message.conversationType === 'C2C' && message.flow == 'out' && message.status !== 'fail'">
<span v-if="!message.isPeerRead">未读</span>
<span v-else>已读</span>
</view>
</view> -->
</view>
</template>
<script lang="ts" setup>
import { defineComponent, watchEffect, reactive, toRefs, computed, ref, getCurrentInstance, ComponentPublicInstance } from 'vue'
import { watchEffect, ref } from 'vue'
const props = defineProps({
data: {
... ... @@ -30,17 +28,8 @@ const props = defineProps({
}
}
})
const { proxy } = getCurrentInstance() as { proxy: ComponentPublicInstance }
const types = ref(uni.$TIM.TYPES)
const message = ref()
const UserInfo = uni.getStorageSync('UserInfo')
const InUserInfo = uni.getStorageSync('inUserInfo')
const DialogUserName = computed(() => (message.value.flow === 'in' ? InUserInfo.nickName : UserInfo.nickname))
const DialogUserAvatar = computed(() => (message.value.flow === 'in' ? proxy.$h.downFile(InUserInfo.avatar) : proxy.$h.downFile(UserInfo.avatar)))
watchEffect(() => {
message.value = props.data
})
... ...
... ... @@ -28,7 +28,7 @@
<view v-else class="TUI-message-input-main">
<AudioMessage></AudioMessage>
</view>
<up-button
<!-- <up-button
v-if="[10, '10', 21, '21'].includes(detailData.consultationWay)"
color="#05B8D2"
shape="circle"
... ... @@ -36,10 +36,10 @@
throttleTime="1500"
@click="handleSendTextMessage"
:customStyle="{ width: '122rpx', height: '74rpx', marginRight: '16rpx' }"
></up-button>
></up-button> -->
<view class="TUI-message-input-functions" hover-class="none">
<!-- <image class="TUI-icon" @tap="handleEmoji" src="../../../../assets/icon/emoji.svg"></image> -->
<image class="TUI-icon" @tap="handleEmoji" src="../../../../assets/icon/emoji.svg"></image>
<view @tap="handleExtensions">
<image class="TUI-icon" src="../../../../assets/icon/more.svg"></image>
</view>
... ... @@ -110,7 +110,7 @@ const TUIChatInput = defineComponent({
default: () => ({})
}
},
emits: ['scrollbottomHandler'],
emits: ['scrollbottomHandler', 'sendMessagehandler'],
setup(props, { emit }) {
const { proxy } = getCurrentInstance() as { proxy: ComponentPublicInstance }
... ... @@ -146,11 +146,12 @@ const TUIChatInput = defineComponent({
// 发送消息
const handleSendTextMessage = (e: any) => {
if (data.inputText.trimEnd()) {
uni.$TUIKit.TUIChatServer.sendTextMessage(JSON.parse(JSON.stringify(data.inputText)))
}
data.inputText = ' '
// if (data.inputText.trimEnd()) {
// uni.$TUIKit.TUIChatServer.sendTextMessage(JSON.parse(JSON.stringify(data.inputText)))
// }
emit('sendMessagehandler', data.inputText)
emit('scrollbottomHandler')
data.inputText = ' '
}
// 处理需要合并的数据
... ... @@ -170,7 +171,6 @@ const TUIChatInput = defineComponent({
console.error(image)
TUIServer.sendImageMessage(res, image)
emit('scrollbottomHandler')
}
})
}
... ...
... ... @@ -306,7 +306,7 @@ export default defineComponent({
uni.addInterceptor('navigateBack', {
success() {
// 小程序无效 官网链接:https://uniapp.dcloud.io/api/interceptor.html
uni.$TUIKit.TUIConversationServer.setMessageRead(data.conversation.conversationID)
// uni.$TUIKit.TUIConversationServer.setMessageRead(data.conversation.conversationID)
}
})
})
... ...
... ... @@ -4,12 +4,7 @@
<view class="imtopinfo">
<view class="flexJ">
<view class="flexA">
<image
:src="![null, undefined, ''].includes(detailData?.doctor?.avatar) ? proxy.$h.downFile(detailData?.doctor?.avatar) : '/static/images/mAvatar.png'"
@click="proxy.$h.previewImage(proxy.$h.downFile(detailData?.doctor?.avatar))"
class="imtopinfo-avatar"
mode="aspectFill"
/>
<image :src="![null, undefined, ''].includes(detailData?.doctor?.avatar) ? proxy.$h.downFile(detailData?.doctor?.avatar) : '/static/images/mAvatar.png'" class="imtopinfo-avatar" mode="aspectFill" />
<view class="imtopinfo-username">{{ detailData?.doctor?.nickname }}</view>
<template v-if="history === 'err'">
<u-count-down :time="countdownTime * 1000" format="HH:mm:ss" @finish="finishCountDownHandler"></u-count-down>
... ... @@ -44,7 +39,7 @@
<view class="more-btn" v-if="conversation?.type === 'GROUP'" @click="handleGetProfile">更多</view>
<!-- <view class="more-btn" style="margin-top: 180rpx" @click="handleGetProfile">更多</view> -->
<view class="TUIChat-container">
<scroll-view class="TUIChat-main" scroll-y="true" :scroll-with-animation="true" :refresher-triggered="triggered" :refresher-enabled="true" @refresherrefresh="handleRefresher" :scroll-top="scrollTop">
<scroll-view class="TUIChat-main" scroll-y="true" :refresher-triggered="triggered" :refresher-enabled="true" @refresherrefresh="handleRefresher" :scroll-top="scrollTop">
<view class="TUI-message-list" @touchstart="handleTouchStart" @click="dialogID = ''">
<!-- 用户信息卡片 -->
<!-- <UserInfoCard :detailData="detailData" /> -->
... ... @@ -71,16 +66,12 @@
<MessageVideo :id="item.flow + '-' + item.ID" v-if="item.type === types.MSG_VIDEO" :data="handleVideoMessageShowContext(item)" :messageData="item" @longpress="handleItem($event, item)" />
<MessageAudio :id="item.flow + '-' + item.ID" v-if="item.type === types.MSG_AUDIO" :data="handleAudioMessageShowContext(item)" :messageData="item" @longpress="handleItem($event, item)" />
<MessageFace :id="item.flow + '-' + item.ID" v-if="item.type === types.MSG_FACE" :data="handleFaceMessageShowContext(item)" :messageData="item" @longpress="handleItem($event, item)" />
<!-- <MessageCustom :id="item.flow + '-' + item.ID" v-if="item.type === types.MSG_CUSTOM" :data="handleCustomMessageShowContext(item)" :messageData="item" @longpress="handleItem($event, item)" /> -->
</MessageBubble>
<MessageRevoked v-if="item.isRevoked" :data="item" @edit="handleEdit(item)" />
</view>
</template>
<template v-else>
<view v-for="(item, index) in historyList" :key="item.ID" :id="'view' + item.ID">
<!-- <view class="time-container" v-if="item.showTime">{{ caculateTimeago(item.time * 1000) }}</view> -->
<!-- <MessageTip v-if="!item.isRevoked && item.type === types.MSG_GRP_TIP" :data="handleTipMessageShowContext(item)" /> -->
<!-- <MessageTip v-if="item.type === types.MSG_GRP_SYS_NOTICE" /> -->
<MessageBubble :data="item">
<MessageText :id="item.flow + '-' + item.ID" v-if="item.chatType === 1" :data="item" :messageData="item" @longpress="handleItem($event, item)"></MessageText>
<MessageImage :id="item.flow + '-' + item.ID" v-if="item.chatType === 2" :data="item.payload" :messageData="item" @longpress="handleItem($event, item)"></MessageImage>
... ... @@ -100,7 +91,7 @@
<view @click="sendPrescriptionState = true" v-if="[null, undefined, ''].includes(detailData?.drugId)">发送处方单</view>
<view @click="showPrescriptionDetailState = true">查看处方单</view>
</view>
<TUIChatInput :text="text" :conversationData="conversation" :detailData="detailData" @scrollbottomHandler="scrollbottomHandler"></TUIChatInput>
<TUIChatInput :text="text" :conversationData="conversation" :detailData="detailData" @scrollbottomHandler="scrollbottomHandler" @sendMessagehandler="handleSendTextMessage"></TUIChatInput>
</template>
</view>
<!-- <view class="TUIChat" v-if="conversationType === 'system'">
... ... @@ -156,7 +147,7 @@
<script lang="ts">
import { defineComponent, reactive, toRefs, computed, nextTick, watch, onMounted, shallowRef, getCurrentInstance, ComponentPublicInstance, ref, onUnmounted, onBeforeUnmount } from 'vue'
import { onReady, onLoad, onNavigationBarButtonTap, onUnload } from '@dcloudio/uni-app'
import { updateSend_prescription_form, getConsultation_information_detail, getEndInformation, getReceive_diagnosis, getOrder_chat, getPrescription_detail_information } from '@/api'
import { getConsultation_information_detail, getEndInformation, getReceive_diagnosis, getOrder_chat, getPrescription_detail_information } from '@/api'
// 消息元素组件
import MessageBubble from './components/message-elements/message-bubble.vue'
import MessageText from './components/message-elements/message-text.vue'
... ... @@ -171,7 +162,6 @@ import MessageRevoked from './components/message-elements/message-revoked.vue'
import MessageSystem from './components/message-elements/message-system.vue'
// 底部消息发送组件
import TUIChatInput from './components/message-input'
import UserInfoCard from '@/components/UserInfoCard'
import ConversationEnd from '@/components/ConversationEnd'
import SendPrescription from '@/components/SendPrescription'
import ViewPrescription from '@/components/ViewPrescription'
... ... @@ -180,7 +170,6 @@ import store from '../../TUICore/store'
import type { DiaLogEventType, Consultation_information_detailType, PrescriptionDetailType } from '../../../types'
import { emojiMap } from '../../utils/emojiMap'
import {
handleAvatar,
handleTextMessageShowContext,
handleImageMessageShowContext,
handleVideoMessageShowContext,
... ... @@ -194,7 +183,6 @@ import {
} from '../../utils/untis'
import { caculateTimeago } from '../../utils/date'
import Vuex from 'vuex'
import { TUIChatServer } from '../../TUICore/server'
export default defineComponent({
... ... @@ -212,7 +200,6 @@ export default defineComponent({
MessageSystem,
TUIChatInput,
MessageOperate,
UserInfoCard,
ConversationEnd,
SendPrescription,
ViewPrescription,
... ... @@ -290,8 +277,6 @@ export default defineComponent({
onLoad(async (options: DiaLogEventType) => {
data.history = uni.getStorageSync('history')
data.imUserId = uni.getStorageSync('ImUserId')
console.log(uni.getStorageSync('history'), '聊天界面onload获取是否为历史记录')
console.log(options, '聊天界面onload参数')
data.Event = options
getDetailHandler()
... ... @@ -308,15 +293,7 @@ export default defineComponent({
})
onBeforeUnmount(() => {
console.log(uni.$TUIKit, 'im方法')
uni.$TUIKit
.logout()
.then(res => {
console.log(res, '成功')
})
.catch(err => {
console.log(err, '错误')
})
uni.$TUIKit.logout()
})
onUnmounted(() => {})
onUnload(() => {
... ... @@ -335,8 +312,8 @@ export default defineComponent({
nextTick(() => {
// const newLastMessage = newVal[newVal.length - 1]
// const oldLastMessage = oldVal ? oldVal[oldVal.length - 1] : {}
data.oldMessageTime = messages.value[0].time
handleShowTime()
// data.oldMessageTime = messages.value[0].time
// handleShowTime()
// if (oldVal && newLastMessage.ID !== oldLastMessage.ID) {
// handleScrollBottom() // 非从conversationList 首次进入
// }
... ... @@ -365,7 +342,7 @@ export default defineComponent({
uni.addInterceptor('navigateBack', {
success() {
// 小程序无效 官网链接:https://uniapp.dcloud.io/api/interceptor.html
uni.$TUIKit.TUIConversationServer.setMessageRead(data.conversation.conversationID)
// uni.$TUIKit.TUIConversationServer.setMessageRead(data.conversation.conversationID)
}
})
})
... ... @@ -383,8 +360,8 @@ export default defineComponent({
const scrollbottomHandler = () => {
setTimeout(() => {
data.scrollTop = 1000000
}, 800)
data.scrollTop = Number(String(new Date().getTime()).slice(-5))
}, 500)
}
const imageFormatMap = new Map([
... ... @@ -400,7 +377,7 @@ export default defineComponent({
if (result?.orderState !== 30) proxy.$h.timeCallBack('对方已结束问诊即将返回', 2000)
}
}, 3000)
}, 5000)
const getDetailHandler = async () => {
const { result: timeData }: { result: { countdownTime: number } } = await getReceive_diagnosis({ id: data.Event.orderId })
... ... @@ -473,9 +450,6 @@ export default defineComponent({
if (result.records.length) {
result.records.map((_: any) => data.historyList.unshift(_))
console.log(data.historyList, '历史记录')
return
}
uni.$u.toast('没有更多数据了')
... ... @@ -495,7 +469,6 @@ export default defineComponent({
content: '您确定要结束问诊吗',
success: async function (res: any) {
if (res.confirm) {
console.log('用户点击确定')
try {
await getEndInformation({ id: data.Event.orderId })
proxy.$h.backUrl(1)
... ... @@ -566,7 +539,6 @@ export default defineComponent({
})
}
} else if (data.history === 'success') {
console.log('下拉刷洗执行了')
getOrder_chatHandler(false)
}
setTimeout(() => {
... ... @@ -582,10 +554,10 @@ export default defineComponent({
// 发送消息
const handleSendTextMessage = (e: any) => {
if (data.text.trimEnd()) {
TUIServer.sendTextMessage(JSON.parse(JSON.stringify(data.text)))
if (e.trimEnd()) {
TUIServer.sendTextMessage(JSON.parse(JSON.stringify(e)))
}
data.text = ' '
// data.text = ' '
}
// 右键消息,展示处理功能
const handleItem = (event: any, item: any) => {
... ...
... ... @@ -15,6 +15,7 @@ export const doctorPhoneEasyLogin = (data: doctorPhoneEasyLoginType) => request(
export const outLogin = () => request({ url: '/doctor/outLogin', method: 'GET' }) // 退出登录
export const getOrder_chat = (data: { id: string | number }) => request({ url: '/consultation/order_chat', method: 'GET', data }) // im聊天记录
export const getChangePhonePwdCode = (data: { type: string | number }) => request({ url: '/veterinary/getChangePhonePwdCode', method: 'GET', data }) // 发送修改手机号和密码验证码 type:1-修改手机号,2-修改密码
export const getarticle = (data: { name: string }) => request({ url: '/article/article', method: 'GET', data }) // 协议与文章
// 首页
export const getStart = () => request({ url: '/veterinary/start', method: 'GET' }) // 开屏页
... ...
<template>
<view class="u-content">
<view style="padding: 24rpx">
<u-parse :content="content"></u-parse>
</view>
</template>
... ... @@ -7,6 +7,8 @@
<script setup lang="ts">
import { ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { getarticle } from '../../api'
import { ArticleType } from '../../types'
interface EventType {
title: string
... ... @@ -14,18 +16,12 @@ interface EventType {
}
onLoad(async (e: EventType) => {
console.log(e, 'event')
uni.setNavigationBarTitle({ title: e.title })
content.value = '富文本'
const { result }: { result: ArticleType } = await getarticle({ name: e.title })
uni.setNavigationBarTitle({ title: e.title })
content.value = result.content
})
const content = ref('')
</script>
<style lang="scss" scoped>
.u-content {
padding: 24rpx;
}
</style>
... ...
... ... @@ -9,7 +9,7 @@
我已阅读并同意
<text class="bluetext" @click="proxy.$h.jumpUrl(`/pages/login/agreement?title=用户协议&type=1`)">《用户协议》</text>
<text class="bluetext" @click="proxy.$h.jumpUrl(`/pages/login/agreement?title=隐私协议&type=2`)">《隐私协议》</text>
<text class="bluetext" @click="proxy.$h.jumpUrl(`/pages/login/agreement?title=隐私政策&type=2`)">《隐私政策》</text>
</text>
</view>
</view>
... ...
... ... @@ -21,18 +21,18 @@
<view class="text mb24">处方药:</view>
<view class="list br24">
<view
class="flexJ "
class="flexJ"
v-for="(_, index) in props.isRenew === 'err' ? PrescriptionDetail?.drugList : PrescriptionDetail?.renewDrugList"
:key="index"
:style="index === (props.isRenew === 'err' ? PrescriptionDetail?.drugList : PrescriptionDetail?.renewDrugList)?.length ? 'margin-bottom: 42rpx' : 'margin-bottom: 0'"
:style="index === (props.isRenew === 'err' ? PrescriptionDetail?.drugList : PrescriptionDetail?.renewDrugList)?.length as number - 1 ? 'margin-bottom: 0rpx' : 'margin-bottom: 42rpx'"
>
<view>
<view class="blacktext" style="margin-bottom: 8rpx;">{{ _.name || '' }}</view>
<view class="graytext" style="margin-bottom: 16rpx;">{{ _.des || '' }}</view>
<view class="blacktext" style="margin-bottom: 8rpx">{{ _.name || '' }}</view>
<view class="graytext">{{ _.des || '' }}</view>
</view>
<view>
<view class="blacktext" style="margin-bottom: 8rpx;">¥{{ _.amount || 0 }}</view>
<view class="graytext" style="margin-bottom: 16rpx;">x{{ _.num || 0 }}</view>
<view class="blacktext" style="margin-bottom: 8rpx">¥{{ _.amount || 0 }}</view>
<view class="graytext">x{{ _.num || 0 }}</view>
</view>
</view>
</view>
... ...
... ... @@ -638,3 +638,16 @@ export interface GetUserCardType {
doctorWXRealName?: string
[property: string]: any;
}
export interface ArticleType {
/**
* 文章内容
*/
content: string;
id: string;
/**
* 文章标题
*/
name: string;
[property: string]: any;
}
\ No newline at end of file
... ...