【博学谷学习记录】超强总结,用心分享 _ 前端开发 优医问诊H5项目(3)


枚举基本语法

作用: 表示一组明确可选的值,和字面量类型配合联合类型类似。
解释: 枚举可以定义一组常量,使用该类型后,约定只能使用这组常量中的其中一个。

// // 一组数据,Up Down Left Right 对应的值分布式 0 1 2 3 你的类型只能在这组数组中使用其中一个
// enum Direction {
//   Up = 0,
//   Down = 1,
//   Left = 2,
//   Right = 3
// }

// // 值从0开始,以此类推(0,1,2,3)
// enum Direction {
//   Up,
//   Down,
//   Left,
//   Right
// }

// // 第一个值5开始,从5开始加
// enum Direction {
//   Up = 5,
//   Down,
//   Left,
//   Right
// }

// 可以是字符串
enum Direction {
  Up = 'Up',
  Down = 'Down',
  Left = 'Left',
  Right = 'Right'
}

const changeDirection = (d: Direction) => {
  console.log('方向值', d)
}
changeDirection(Direction.Left)

枚举的应用场景:

// 男 0  女 1
enum Gender {
  Boy,
  Girl
}
const changeGender = (gender: Gender) => {
  if (gender === Gender.Boy) {
    console.log('男')
  }
}
changeGender(Gender.Boy)

// 待付款 1   已付款 5   已完成 8
enum OrderStatus {
  Unpay = 1,
  Payed = 5,
  Complete = 8
}
const changeStatus = (status: OrderStatus) => {
  if (status === OrderStatus.Complete) {
    console.log('订单已完成')
  }
}
changeStatus(OrderStatus.Complete)

项目中

创建enums/index.ts中,创建类型。并在对象类型文件d.ts中使用。

// 问诊类型
export enum ConsultType {
  Doctor = 1, // 找医生
  Fast = 2, // 快速问诊
  Medication = 3 // 开药问诊
}
// 问诊时间
export enum ConsultTime {
  Week = 1, // 一周内
  Month, // 一月内
  HalfYear, // 半年内
  More // 半年以上
}

d.ts文件中:

export type Consult = {
  type: ConsultType // 问诊类型
  illnessTime: ConsultTime // 问诊时间
}

聊天室

websocket 可以实现双向通信

是一种网络通信协议,和 HTTP 协议 一样。
为什么需要websocket ?
因为 HTTP 协议有一个缺陷:通信只能由客户端发起。

socket.io

socket.io 是一个基于 WebSocket 的 CS(客户端-服务端)的实时通信库
使用它可以在后端提供一个即时通讯服务
它也提供一个 js 库,在前端可以去链接后端的 socket.io 创建的服务
总结: 它是一套基于 websocket 前后端即时通讯解决方案

安装: pnpm add socket.io-client

import { MsgType } from '@/enums/index'
import type { TimeMessages, Message } from '@/types/room'
import { io } from 'socket.io-client'
import type { Socket } from 'socket.io-client'
import { baseURL } from '@/utils/request'
import { useUserStore } from '@/stores'
import { useRoute } from 'vue-router'
const store = useUserStore()
const route = useRoute()

let socket: Socket
onMounted(() => {
  // 1、建立连接 (组件挂载完毕时,建立连接、组件卸载、关闭连接)
  // 参数一:服务器地址 参数二:配置参数
  socket = io(baseURL, {
    // 身份认证
    auth: {
      token: `Bearer ${store.user?.token}` // 格式要求
    },
    // 订单id(从地址栏中取下来)
    query: {
      orderId: route.query.orderId
    }
  })

  // 2、连接成功(可在浏览器network中的WS查看连接情况)
  socket.on('connect', () => {
    console.log('连接成功')
  })

  // 关闭连接
  socket.on('disconnect', () => {
    console.log('断开连接')
  })
  // 发生错误
  socket.on('error', (err) => {
    console.log('发生错误', err)
  })

  // 获取消息记录(默认消息)     (前面是解构的语法,后面是类型(自定义))
  socket.on('chatMsgList', ({ data }: { data: TimeMessages[] }) => {
    const arr: Message[] = []
    data.forEach((item, i) => {
      // 记录消息分组的起始时间,作为下次获取聊天记录的时间
      if (i === 0) time.value = item.createTime
      arr.push({
        id: item.createTime,
        msgType: MsgType.Notify,
        createTime: item.createTime,
        msg: {
          content: item.createTime
        }
      })
	    // 给每一组数据的最后面加上 是否需要滚动(因为图片信息接收的时候会自动滚动到最后)
      item.items.forEach((item) => {
        arr.push({ ...item, notScroll: initialMsg.value === false })
      })
    })
    // 将处理好的数据放入list中(新消息要放到最上方)
    list.value.unshift(...arr)

    // 关闭刷新效果
    loading.value = false
    if (!data.length) {
      showToast('没有更多了')
    }

    // 第一次获取默认消息滚动到最底部
    nextTick(() => {
      if (initialMsg.value) {
        // 把默认加载到的消息全部改为已读 
        socket.emit('updateMsgStatus', arr[arr.length - 1].id)
        window.scrollTo(0, document.body.scrollHeight)
        initialMsg.value = false
      }
    })
  })


  // 通讯状态改变(有多种,比如未接诊,进行中,已结束等,每次变化都获取一次订单详情)
  socket.on('statusChange', async () => {
    const res = await getConsultOrderDetail(route.query.orderId as string)
    consult.value = res.data
  })
  // 接收消息
  socket.on('receiveChatMsg', (msg: Message) => {
    list.value.push(msg)
    await nextTick() // 因为是收信息是异步的,所以要等渲染完再操作

    // 修改消息为已读
    socket.emit('updateMsgStatus', msg.id)

    window.scrollTo(0, document.body.scrollHeight) // 将消息展示区滚动到最底部
  })
})

// 3、关闭连接
onUnmounted(() => {
  socket.close()
})


// 发送文字消息
const sendText = (text: string) => {
  socket.emit('sendChatMsg', {
    from: store.user?.id, // 发送人
    to: consult.value?.docInfo?.id, // 接收人
    msgType: MsgType.MsgText, // 消息类型
    msg: {
      content: text
    } // 消息内容(文字,图片)
  })


// 加载更多聊天记录
// 1. 默认的聊天记录滚动到最底部
// 2. 实现下拉刷新效果
// 3. 下拉刷新后,发送一个获取聊天记录的消息给后台
// 4. 触发聊天记录事件,记录当前时间段最早的时间,作为发送聊天记录消息的参数给后台
// 4.1 判断如果有数据,追加到数组,如果没有数据,轻提示没有数据
// 4.2 之后获取消息不需要滚动到底部
// 5. 再次连接socket的时候,要清空聊天记录,反之有重复出现消息
const initialMsg = ref(true)
const loading = ref(false)
const time = ref(moment().format('YYYY-MM-DD HH:mm:ss'))
const onRefresh = () => {
  // 获取更多消息(下拉刷新) (消息内容实际还是靠chatMsgList获取)
  socket.emit('getChatMsgList', 20, time.value, consult.value?.id) // 后台要求的参数是20条数据,时间和用户id
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值