chat.jsx 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. import Taro, { Component } from '@tarojs/taro'
  2. import { View, ScrollView } from '@tarojs/components'
  3. import ListMore from '@/c/pageDataList/listMore'
  4. import { strTrim, arrToObj } from '@utils'
  5. import './chat.scss'
  6. class Index extends Component {
  7. constructor (props) {
  8. super(props)
  9. const {id: curId} = this.$router.params
  10. this.state = {
  11. page_size: 10,
  12. page: 1,
  13. isListEnd: false,
  14. isListLoading: false,
  15. isListEmpty: false,
  16. dataList: [],
  17. curId,
  18. curObj: {},
  19. commentVal: '',
  20. msgSocketList: [],
  21. uObj: {},
  22. chatUserObj: {},
  23. viewId: '',
  24. }
  25. }
  26. config = {
  27. navigationBarTitleText: '在线聊天',
  28. }
  29. componentDidMount () {
  30. const that = this
  31. let uObj = Taro.getStorageSync('APP_userInfo')
  32. const { to_user_id } = this.$router.params
  33. this.setState({
  34. uObj
  35. }, () => {
  36. let uArr = [uObj.user_id, to_user_id]
  37. Taro.api.base.apiuserinfolist({
  38. user_ids: uArr.join(',')
  39. }).then(res => {
  40. let chatUserObj = {}
  41. const list = res.list || []
  42. list.forEach(item => {
  43. chatUserObj[item.id] = item
  44. })
  45. that.setState({
  46. chatUserObj
  47. })
  48. })
  49. Taro.$AHU(this)
  50. this.getDataList()
  51. this.initSocket()
  52. })
  53. }
  54. getDataList () {
  55. const { to_user_id } = this.$router.params
  56. let { page_size, page, dataList, isListEmpty } = this.state
  57. Taro.api.room.apiuserchatlist({
  58. page,
  59. page_size,
  60. to_user_id,
  61. }).then(res => {
  62. let curData = res.list || []
  63. curData = curData.reverse()
  64. let isListEnd = false
  65. if (curData.length > 0) {
  66. if (page === 1) {
  67. dataList = curData
  68. } else {
  69. dataList = [].concat(curData, dataList)
  70. }
  71. if (curData.length === page_size && res.total !== curData.length) {
  72. isListEnd = false
  73. } else {
  74. isListEnd = true
  75. }
  76. }
  77. if (curData.length === 0 && page === 1) {
  78. isListEmpty = true
  79. dataList = []
  80. } else {
  81. isListEmpty = false
  82. }
  83. const that = this
  84. this.setState({
  85. dataList,
  86. isListEnd,
  87. isListEmpty,
  88. isListLoading: false
  89. }, () => {
  90. if (page > 1) {
  91. setTimeout(() => {
  92. that.setState({
  93. viewId: `history11`
  94. })
  95. }, 100)
  96. }
  97. })
  98. })
  99. }
  100. onScrollToUpper (e) {
  101. let { isListEnd, isListLoading, page } = this.state
  102. if (!isListEnd && !isListLoading) {
  103. page++
  104. this.setState({
  105. page,
  106. isListLoading: true
  107. }, () => {
  108. this.getDataList()
  109. })
  110. }
  111. }
  112. initSocket () {
  113. const that = this
  114. Taro.connectSocket({
  115. url: 'ws://192.168.101.147:8089/acc',
  116. success: function () {
  117. console.log('connect success')
  118. }
  119. }).then(task => {
  120. task.onOpen(function () {
  121. // console.log('onOpen')
  122. const { to_user_id } = that.$router.params
  123. let token = Taro.getStorageSync('APP_token')
  124. task.send({ data: '{"seq":"' + that.sendId() + '","cmd":"login","data":{"userId":"' + to_user_id + '","appId":101,"serviceToken":"' + token + '"}}' })
  125. setInterval(() => {
  126. task.send({data: '{"seq":"' + that.sendId() + '","cmd":"heartbeat","data":{}}'});
  127. }, 30000)
  128. })
  129. task.onMessage(function (msg) {
  130. // console.log('onMessage: ', msg)
  131. let { msgSocketList } = that.state
  132. const data = JSON.parse(msg.data)
  133. // console.log(data)
  134. if (data.cmd === 'msg' || data.cmd === 'login') {
  135. const res = data.response || {}
  136. if (res.code === 200) {
  137. if (data.cmd === 'login') {
  138. msgSocketList.push({msg: '登录成功~'})
  139. } else {
  140. msgSocketList.push(res.data)
  141. }
  142. that.setState({
  143. msgSocketList
  144. }, () => {
  145. setTimeout(() => {
  146. that.setState({
  147. viewId: `item${msgSocketList.length - 1}`
  148. })
  149. }, 100)
  150. })
  151. }
  152. }
  153. // task.close()
  154. })
  155. task.onError(function () {
  156. console.log('onError')
  157. })
  158. task.onClose(function (e) {
  159. console.log('onClose: ', e)
  160. })
  161. })
  162. }
  163. sendId () {
  164. let timeStamp = +new Date()
  165. let randId = parseInt(Math.random() * 1000000)
  166. return `${timeStamp}-${randId}`
  167. }
  168. componentDidShow () { }
  169. componentDidHide () { }
  170. renderList () {
  171. const { chatUserObj, uObj, viewId } = this.state
  172. const { dataList, isListEnd, isListLoading, isListEmpty } = this.state
  173. const itemList = dataList.map((item, index) => {
  174. return (
  175. <View className="sl-item" key={index} id={`history${index}`}>
  176. <View className={item.user_id === uObj.user_id ? 'sl-wrap' : 'sl-wrap t2'}>
  177. <View className="sl-img">
  178. <Image className="img" src={chatUserObj[item.user_id].avatar}></Image>
  179. </View>
  180. <View className="sl-right">
  181. <View className="sign"></View>
  182. <View className="sl-text">{item.content}</View>
  183. <View className="sl-time">{item.create_at}</View>
  184. </View>
  185. </View>
  186. </View>
  187. )
  188. })
  189. return (
  190. <ScrollView
  191. className='l-scroll-view'
  192. scrollY
  193. scrollWithAnimation
  194. upperThreshold="10"
  195. scrollIntoView={viewId}
  196. onScrollToUpper={this.onScrollToUpper.bind(this)}
  197. >
  198. <ListMore isListEnd={isListEnd} isListLoading={isListLoading} isListEmpty={isListEmpty} text="暂无历史消息" />
  199. <View className="scoped-list">
  200. {itemList}
  201. </View>
  202. {/* {
  203. dataList.length > 0
  204. &&
  205. <AtDivider content="以上为历史消息" fontColor='#ccc' lineColor='#ccc' />
  206. } */}
  207. {this.renderMsgList()}
  208. <View id="msgId"></View>
  209. </ScrollView>
  210. )
  211. }
  212. renderMsgList () {
  213. const { msgSocketList } = this.state
  214. const { chatUserObj, uObj } = this.state
  215. const curItems = msgSocketList.map((item, index) => {
  216. return (
  217. <View className="sl-item" key={index} id={`item${index}`}>
  218. {
  219. item.from
  220. ?
  221. <View className={item.from === uObj.user_id ? 'sl-wrap' : 'sl-wrap t2'}>
  222. <View className="sl-img">
  223. <Image className="img" src={chatUserObj[item.from].avatar}></Image>
  224. </View>
  225. <View className="sl-right">
  226. <View className="sign"></View>
  227. <View className="sl-text">{item.msg}</View>
  228. </View>
  229. </View>
  230. :
  231. <View className="scoped-msg-tips">{item.msg}</View>
  232. }
  233. </View>
  234. )
  235. })
  236. return (
  237. <View className="scoped-list">
  238. {curItems}
  239. </View>
  240. )
  241. }
  242. sendHandle () {
  243. const that = this
  244. const { uObj } = this.state
  245. const { commentVal } = this.state
  246. let { msgSocketList } = this.state
  247. const { to_user_id } = this.$router.params
  248. let apiStr = 'apiusersendmessage'
  249. if (commentVal) {
  250. Taro.api.room[apiStr]({
  251. message: commentVal,
  252. type: 'text',
  253. to_user: to_user_id,
  254. }).then(res => {
  255. msgSocketList.push({
  256. from: uObj.user_id,
  257. msg: commentVal
  258. })
  259. this.setState({
  260. msgSocketList,
  261. commentVal: '',
  262. }, () => {
  263. setTimeout(() => {
  264. that.setState({
  265. viewId: `item${msgSocketList.length - 1}`
  266. })
  267. }, 100)
  268. })
  269. })
  270. } else {
  271. Taro.$msg('请输入')
  272. }
  273. }
  274. changeInput (e) {
  275. const val = strTrim(e.target.value)
  276. this.setState({
  277. commentVal: val
  278. })
  279. }
  280. renderFooter () {
  281. const { commentVal } = this.state
  282. return (
  283. <View className="l-floor-footer">
  284. <View className="scoped-footer">
  285. <View className="sf-input">
  286. <Input className="input" placeholder={`请输入`} value={commentVal} onInput={this.changeInput.bind(this)} />
  287. <View className="btn" onClick={this.sendHandle.bind(this)}>发送</View>
  288. </View>
  289. </View>
  290. </View>
  291. )
  292. }
  293. render () {
  294. return (
  295. <View className="l-box has-footer">
  296. {this.renderList()}
  297. {this.renderFooter()}
  298. </View>
  299. )
  300. }
  301. }
  302. export default Index