123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243 |
- import { useEffect, useState } from 'react'
- import Taro from '@tarojs/taro'
- import { ScrollView, Input, Image, Button } from '@tarojs/components'
- import withLayout from '@/layout'
- import { API_QUERY_USERINFO_BYID } from '@/constants/api'
- import { ROLE_CODE } from '@/constants/user'
- import { uploadFiles, fetch } from '@/utils/request'
- import { queryChatHistory, setMessageReaded } from '@/services/chat'
- import im from '@/utils/im'
- import { getDateForHumans } from '@/utils/chatDate'
- import '@/assets/css/iconfont.css'
- import Card from './Card'
- import useScrollTop from './useScrollTop'
- import './index.scss'
-
- export default withLayout((props) => {
- const { router, person } = props;
- const { friend } = router.params
-
- const [submitting, setSubmitting] = useState(false)
- const [text, setText] = useState()
- const [receiver, setReceiver] = useState({})
- const [PageList, setPageList] = useState([])
- const [scrollTop, scroll] = useScrollTop('#chat-scroll')
-
- const sendMessage = (msg, type = im.MESSAGETYPE.TEXT) => {
- const message = msg
- const messageType = type
-
- // 用来回调写入消息列表
- const newMessage = {
- chatId: Math.random().toString(36).substring(2),
- message,
- messageType,
- receivePerson: friend,
- sendPerson: person.personId,
- createDate: new Date(),
- }
-
- // 发送消息
- setSubmitting(true)
- im.sendMessage(message, messageType).then(() => {
- // 发送成功
- setText()
- // 立刻回显刚刚发送内容
- setPageList(PageList.concat(newMessage))
- // 滚动到底部
- scroll()
- //
- setSubmitting(false)
- }).catch(() => {
- setSubmitting(false)
- Taro.showToast({
- title: '发送失败, 请重试',
- icon: 'none',
- })
- })
- }
-
- const submitText = () => {
- if (text && text.trim()) {
- sendMessage(text.trim())
- }
- }
-
- const submitImage = () => {
- Taro.chooseImage({
- count: 1,
- sizeType: ['original', 'compressed'],
- sourceType: ['album', 'camera'],
- success: res => {
- uploadFiles(res.tempFilePaths).then(data => {
- sendMessage(data[0], im.MESSAGETYPE.IMAGE)
- })
- }
- })
- }
-
- const getChatHistory = (params) => {
- Taro.showLoading()
- queryChatHistory({
- chatWith: friend,
- pageSize: 20,
- ...params || {},
- }).then((res) => {
- const { records } = res;
- Taro.hideLoading()
-
- const lst = (records || []).reverse()
-
- // 如果聊天对象是有身份的
- if (receiver.personType !== ROLE_CODE.DRIFT && receiver.personType !== ROLE_CODE.CUSTOMER) {
- const mockMessage = {
- chatId: Math.random().toString(36).substring(2),
- message: '',
- messageType: im.MESSAGETYPE.CARD,
- receivePerson: person.personId,
- sendPerson: friend,
- createDate: new Date(),
- }
- lst.push(mockMessage)
- }
-
- setPageList(lst)
- scroll()
- })
- }
-
- // 留电话
- // 实际上是发送一条文本记录
- const leavePhone = () => {
- sendMessage(person.phone)
- }
-
- useEffect(() => {
- if (friend) {
- im.bindReceiver(friend)
- fetch({ url: `${API_QUERY_USERINFO_BYID}/${friend}`, spin: true }).then((res) => {
- setReceiver(res)
- getChatHistory({ pageNumber: 1 })
- })
- } else {
- Taro.showToast({
- title: '无聊天对象,请退出重试',
- icon: 'none',
- })
- }
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [friend])
-
- useEffect(() => {
- return im.listen((message) => {
- const receiveData = JSON.parse(message)
- setPageList(PageList.concat(receiveData))
- // 滚动到底部
- scroll()
- // 更新记录为已读
- setMessageReaded(receiveData.chatId)
- })
- }, [PageList, scroll])
-
- const CheckBigImg = (img) => {
- return () => {
- Taro.previewImage({ current: img, urls: [img] })
- }
- }
-
- return (
- <view className='chatDetail flex-v'>
- <view className='flex-item'>
- <view>
- <ScrollView id='chat-scroll' scrollY enhanced scrollTop={scrollTop}>
- <view className='PageContent'>
- {
- PageList.map((item) => (
- <view key={item.chatId} className='ChatItem'>
-
- <view className='Time'>
- <text>{getDateForHumans(item.createDate, true)}</text>
- </view>
-
- <view className='flex-h'>
- {
- item.sendPerson === friend ? (
- <>
- <view className='Icon'>
- <Image mode='scaleToFill' src={receiver.avatarurl}></Image>
- </view>
-
- <view className='flex-item'>
- { /* 如果是文本 */
- item.messageType === im.MESSAGETYPE.TEXT && (
- <view className='Message Left'>
- <text>{item.message}</text>
- </view>
- )
- }
- { /* 图片消息 */
- item.messageType === im.MESSAGETYPE.IMAGE &&
- <view className='Message Left Img'>
- <view>
- <Image onClick={CheckBigImg(item.message)} mode='scaleToFill' src={item.message}></Image>
- </view>
- </view>
- }
- { /* 如果是卡片 */
- item.messageType === im.MESSAGETYPE.CARD && (
- <Card person={receiver} onLeavePhone={leavePhone} />
- )
- }
- </view>
- </>
- ) : (
- <>
- <view className='flex-item'>
- { /* 如果是文本 */
- item.messageType === im.MESSAGETYPE.TEXT && (
- <view className='Message Right'>
- <text>{item.message}</text>
- </view>
- )
- }
- { /* 图片消息 */
- item.messageType === im.MESSAGETYPE.IMAGE &&
- <view className='Message Right Img'>
- <view>
- <Image onClick={CheckBigImg(item.message)} mode='scaleToFill' src={item.message}></Image>
- </view>
- </view>
- }
- </view>
- <view className='Icon'>
- <Image mode='scaleToFill' src={person.avatarurl}></Image>
- </view>
- </>
- )
- }
-
-
- {/* 系统模板消息(对方消息) */}
- {/* {
- index === 0 &&
- } */}
-
- </view>
-
- </view>
- ))
- }
- </view>
- </ScrollView>
- </view>
- </view>
- <view className='SendContent flex-h'>
- <view className='flex-item'>
- <Input placeholder='发送消息' value={text} onInput={(e) => setText(e.detail.value)} />
- </view>
- <text className='iconfont icon-tianjia' onClick={submitImage}></text>
- <Button loading={submitting} className='Send' onClick={submitText}>发送</Button>
- </view>
- </view>
- )
- })
|