123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357 |
- import Taro, { Component } from '@tarojs/taro'
- import { View, ScrollView } from '@tarojs/components'
- import ListMore from '@/c/pageDataList/listMore'
- import { strTrim, arrToObj } from '@utils'
- import './chat.scss'
- class Index extends Component {
- constructor (props) {
- super(props)
- const {id: curId} = this.$router.params
- this.state = {
- page_size: 10,
- page: 1,
- isListEnd: false,
- isListLoading: false,
- isListEmpty: false,
- dataList: [],
- curId,
- curObj: {},
- commentVal: '',
- msgSocketList: [],
- uObj: {},
- chatUserObj: {},
- viewId: '',
- socketTimer: null
- }
- }
- config = {
- navigationBarTitleText: '在线沟通',
- }
- componentWillUnmount () {
- this.closeSocket()
- let pages = getCurrentPages()
- let prevPage = pages[ pages.length - 2 ]
- if (prevPage.$component.getNotifycount) prevPage.$component.getNotifycount()
- }
- closeSocket () {
- Taro.closeSocket()
- const { socketTimer } = this.state
- clearInterval(socketTimer)
- }
- componentDidMount () {
- const that = this
- let uObj = Taro.getStorageSync('APP_userInfo')
- const { to_user_id } = this.$router.params
- this.setState({
- uObj
- }, () => {
- let uArr = [uObj.user_id, to_user_id]
- Taro.api.base.apiuserinfolist({
- user_ids: uArr.join(',')
- }).then(res => {
- let chatUserObj = {}
- const list = res.list || []
- list.forEach(item => {
- chatUserObj[item.id] = item
- })
- that.setState({
- chatUserObj
- })
- })
- Taro.$AHU(this)
- this.getDataList()
- this.initSocket()
- })
- }
- getDataList () {
- const { to_user_id } = this.$router.params
- let { page_size, page, dataList, isListEmpty } = this.state
- Taro.api.room.apiuserchatlist({
- page,
- page_size,
- to_user_id,
- }).then(res => {
- let curData = res.list || []
- curData = curData.reverse()
- let isListEnd = false
- if (curData.length > 0) {
- if (page === 1) {
- dataList = curData
- } else {
- dataList = [].concat(curData, dataList)
- }
- if (curData.length === page_size && res.total !== curData.length) {
- isListEnd = false
- } else {
- isListEnd = true
- }
- }
- if (curData.length === 0 && page === 1) {
- isListEmpty = true
- dataList = []
- } else {
- isListEmpty = false
- }
- const that = this
- this.setState({
- dataList,
- isListEnd,
- isListEmpty,
- isListLoading: false
- }, () => {
- if (page > 1) {
- setTimeout(() => {
- that.setState({
- viewId: `history11`
- })
- }, 100)
- }
- })
- })
- }
- onScrollToUpper (e) {
- let { isListEnd, isListLoading, page } = this.state
- if (!isListEnd && !isListLoading) {
- page++
- this.setState({
- page,
- isListLoading: true
- }, () => {
- this.getDataList()
- })
- }
- }
- initSocket () {
- const { uObj } = this.state
- const that = this
- Taro.connectSocket({
- url: 'ws://192.168.101.147:8089/acc',
- success: function () {
- console.log('connect success')
- }
- }).then(task => {
- task.onOpen(function () {
- // console.log('onOpen')
- // const { to_user_id } = that.$router.params
- let token = Taro.getStorageSync('APP_token')
- task.send({ data: '{"seq":"' + that.sendId() + '","cmd":"login","data":{"userId":"' + uObj.user_id + '","appId":101,"serviceToken":"' + token + '"}}' })
- const socketTimer = setInterval(() => {
- task.send({data: '{"seq":"' + that.sendId() + '","cmd":"heartbeat","data":{}}'});
- }, 30000)
- that.setState({
- socketTimer
- })
- })
- task.onMessage(function (msg) {
- // console.log('onMessage: ', msg)
- let { msgSocketList } = that.state
- const data = JSON.parse(msg.data)
- // console.log(data)
- if (data.cmd === 'msg' || data.cmd === 'login') {
- const res = data.response || {}
- if (res.code === 200) {
- if (data.cmd === 'login') {
- msgSocketList.push({msg: '登录成功~'})
- } else {
- msgSocketList.push(res.data)
- }
- that.setState({
- msgSocketList
- }, () => {
- setTimeout(() => {
- that.setState({
- viewId: `item${msgSocketList.length - 1}`
- })
- }, 100)
- })
- }
- }
- if (data.cmd === 'heartbeat') {
- const res = data.response || {}
- if (res.code !== 200) {
- msgSocketList.push({msg: res.codeMsg + '|暂无法接收消息,请退出当前页面重新登录~'})
- that.setState({
- msgSocketList
- }, () => {
- setTimeout(() => {
- that.setState({
- viewId: `item${msgSocketList.length - 1}`
- }, () => {
- that.closeSocket()
- })
- }, 100)
- })
- }
- }
- // task.close()
- })
- task.onError(function () {
- console.log('onError')
- })
- task.onClose(function (e) {
- console.log('onClose: ', e)
- })
- })
- }
- sendId () {
- let timeStamp = +new Date()
- let randId = parseInt(Math.random() * 1000000)
- return `${timeStamp}-${randId}`
- }
- componentDidShow () { }
- componentDidHide () { }
- renderList () {
- const { chatUserObj, uObj, viewId } = this.state
- const { dataList, isListEnd, isListLoading, isListEmpty } = this.state
- const itemList = dataList.map((item, index) => {
- return (
- <View className="sl-item" key={index} id={`history${index}`}>
- <View className={item.user_id === uObj.user_id ? 'sl-wrap' : 'sl-wrap t2'}>
- <View className="sl-img">
- <Image className="img" src={chatUserObj[item.user_id].avatar}></Image>
- </View>
- <View className="sl-right">
- <View className="sign"></View>
- <View className="sl-text">{item.content}</View>
- <View className="sl-time">{item.create_at}</View>
- </View>
- </View>
- </View>
- )
- })
- return (
- <ScrollView
- className='l-scroll-view'
- scrollY
- scrollWithAnimation
- upperThreshold="10"
- scrollIntoView={viewId}
- onScrollToUpper={this.onScrollToUpper.bind(this)}
- >
- <ListMore isListEnd={isListEnd} isListLoading={isListLoading} isListEmpty={isListEmpty} text="暂无历史消息" />
- <View className="scoped-list">
- {itemList}
- </View>
- {/* {
- dataList.length > 0
- &&
- <AtDivider content="以上为历史消息" fontColor='#ccc' lineColor='#ccc' />
- } */}
- {this.renderMsgList()}
- <View id="msgId"></View>
- </ScrollView>
- )
- }
- renderMsgList () {
- const { msgSocketList } = this.state
- const { chatUserObj, uObj } = this.state
- const curItems = msgSocketList.map((item, index) => {
- return (
- <View className="sl-item" key={index} id={`item${index}`}>
- {
- item.from
- ?
- <View className={item.from === uObj.user_id ? 'sl-wrap' : 'sl-wrap t2'}>
- <View className="sl-img">
- <Image className="img" src={chatUserObj[item.from].avatar}></Image>
- </View>
- <View className="sl-right">
- <View className="sign"></View>
- <View className="sl-text">{item.msg}</View>
- </View>
- </View>
- :
- <View className="scoped-msg-tips">{item.msg}</View>
- }
- </View>
- )
- })
- return (
- <View className="scoped-list">
- {curItems}
- </View>
- )
- }
- sendHandle () {
- const that = this
- const { uObj } = this.state
- const { commentVal } = this.state
- let { msgSocketList } = this.state
- const { to_user_id } = this.$router.params
- let apiStr = 'apiusersendmessage'
- if (commentVal) {
- Taro.api.room[apiStr]({
- message: commentVal,
- type: 'text',
- to_user: to_user_id,
- }).then(res => {
- msgSocketList.push({
- from: uObj.user_id,
- msg: commentVal
- })
- this.setState({
- msgSocketList,
- commentVal: '',
- }, () => {
- setTimeout(() => {
- that.setState({
- viewId: `item${msgSocketList.length - 1}`
- })
- }, 100)
- })
- })
- } else {
- Taro.$msg('请输入')
- }
- }
- changeInput (e) {
- const val = strTrim(e.target.value)
- this.setState({
- commentVal: val
- })
- }
- renderFooter () {
- const { commentVal } = this.state
- return (
- <View className="l-floor-footer">
- <View className="scoped-footer">
- <View className="sf-input">
- <Input className="input" placeholder={`请输入`} value={commentVal} onInput={this.changeInput.bind(this)} />
- <View className="btn" onClick={this.sendHandle.bind(this)}>发送</View>
- </View>
- </View>
- </View>
- )
- }
- render () {
- return (
- <View className="l-box has-footer">
- {this.renderList()}
- {this.renderFooter()}
- </View>
- )
- }
- }
- export default Index
|