MemberInfo.vue 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. <!-- 目录是不是叫 member 好点。然后这个组件是 MemberInfo,里面有浏览足迹 -->
  2. <template>
  3. <el-container class="kefu">
  4. <el-header class="kefu-header">
  5. <el-tabs v-model="activeName" class="kefu-tabs" @tab-click="handleClick">
  6. <el-tab-pane label="最近浏览" name="a" />
  7. <el-tab-pane label="订单列表" name="b" />
  8. </el-tabs>
  9. </el-header>
  10. <el-main class="kefu-content">
  11. <div v-show="!isEmpty(conversation)">
  12. <el-scrollbar ref="scrollbarRef" always @scroll="handleScroll">
  13. <!-- 最近浏览 -->
  14. <ProductBrowsingHistory v-if="activeName === 'a'" ref="productBrowsingHistoryRef" />
  15. <!-- 订单列表 -->
  16. <OrderBrowsingHistory v-if="activeName === 'b'" ref="orderBrowsingHistoryRef" />
  17. </el-scrollbar>
  18. </div>
  19. <el-empty v-show="isEmpty(conversation)" description="请选择左侧的一个会话后开始" />
  20. </el-main>
  21. </el-container>
  22. </template>
  23. <script lang="ts" setup>
  24. import type { TabsPaneContext } from 'element-plus'
  25. import ProductBrowsingHistory from './ProductBrowsingHistory.vue'
  26. import OrderBrowsingHistory from './OrderBrowsingHistory.vue'
  27. import { KeFuConversationRespVO } from '@/api/mall/promotion/kefu/conversation'
  28. import { isEmpty } from '@/utils/is'
  29. import { debounce } from 'lodash-es'
  30. import { ElScrollbar as ElScrollbarType } from 'element-plus/es/components/scrollbar/index'
  31. defineOptions({ name: 'MemberBrowsingHistory' })
  32. const activeName = ref('a')
  33. /** tab 切换 */
  34. const productBrowsingHistoryRef = ref<InstanceType<typeof ProductBrowsingHistory>>()
  35. const orderBrowsingHistoryRef = ref<InstanceType<typeof OrderBrowsingHistory>>()
  36. const handleClick = async (tab: TabsPaneContext) => {
  37. activeName.value = tab.paneName as string
  38. await nextTick()
  39. await getHistoryList()
  40. }
  41. /** 获得历史数据 */
  42. // TODO @puhui:不要用 a、b 哈。就订单列表、浏览列表这种噶
  43. const getHistoryList = async () => {
  44. switch (activeName.value) {
  45. case 'a':
  46. await productBrowsingHistoryRef.value?.getHistoryList(conversation.value)
  47. break
  48. case 'b':
  49. await orderBrowsingHistoryRef.value?.getHistoryList(conversation.value)
  50. break
  51. default:
  52. break
  53. }
  54. }
  55. /** 加载下一页数据 */
  56. const loadMore = async () => {
  57. switch (activeName.value) {
  58. case 'a':
  59. await productBrowsingHistoryRef.value?.loadMore()
  60. break
  61. case 'b':
  62. await orderBrowsingHistoryRef.value?.loadMore()
  63. break
  64. default:
  65. break
  66. }
  67. }
  68. /** 浏览历史初始化 */
  69. const conversation = ref<KeFuConversationRespVO>({} as KeFuConversationRespVO) // 用户会话
  70. const initHistory = async (val: KeFuConversationRespVO) => {
  71. activeName.value = 'a'
  72. conversation.value = val
  73. await nextTick()
  74. await getHistoryList()
  75. }
  76. defineExpose({ initHistory })
  77. /** 处理消息列表滚动事件(debounce 限流) */
  78. const scrollbarRef = ref<InstanceType<typeof ElScrollbarType>>()
  79. const handleScroll = debounce(() => {
  80. const wrap = scrollbarRef.value?.wrapRef
  81. // 触底重置
  82. if (Math.abs(wrap!.scrollHeight - wrap!.clientHeight - wrap!.scrollTop) < 1) {
  83. loadMore()
  84. }
  85. }, 200)
  86. </script>
  87. <style lang="scss" scoped>
  88. .kefu {
  89. margin: 0;
  90. padding: 0;
  91. height: 100%;
  92. width: 300px !important;
  93. background-color: #fff;
  94. border-left: var(--el-border-color) solid 1px;
  95. &-header {
  96. background: #fbfbfb;
  97. box-shadow: 0 0 0 0 #dcdfe6;
  98. display: flex;
  99. align-items: center;
  100. justify-content: center;
  101. &-title {
  102. font-size: 18px;
  103. font-weight: bold;
  104. }
  105. }
  106. &-content {
  107. margin: 0;
  108. padding: 0;
  109. position: relative;
  110. height: 100%;
  111. width: 100%;
  112. }
  113. &-tabs {
  114. height: 100%;
  115. width: 100%;
  116. }
  117. }
  118. .header-title {
  119. border-bottom: #e4e0e0 solid 1px;
  120. }
  121. </style>