From a1d7e81859f554f3a53680cc35f0f49bf1f77098 Mon Sep 17 00:00:00 2001
From: wwf <1971391498@qq.com>
Date: 星期四, 14 五月 2026 14:37:02 +0800
Subject: [PATCH] 导入项目

---
 src/views/mall/promotion/kefu/components/member/MemberInfo.vue |  255 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 255 insertions(+), 0 deletions(-)

diff --git a/src/views/mall/promotion/kefu/components/member/MemberInfo.vue b/src/views/mall/promotion/kefu/components/member/MemberInfo.vue
new file mode 100644
index 0000000..3acfece
--- /dev/null
+++ b/src/views/mall/promotion/kefu/components/member/MemberInfo.vue
@@ -0,0 +1,255 @@
+<!-- 鍙充晶淇℃伅锛氫細鍛樹俊鎭� + 鏈�杩戞祻瑙� + 浜ゆ槗璁㈠崟 -->
+<template>
+  <el-container class="kefu">
+    <el-header class="kefu-header">
+      <div
+        :class="{ 'kefu-header-item-activation': tabActivation('浼氬憳淇℃伅') }"
+        class="kefu-header-item cursor-pointer flex items-center justify-center"
+        @click="handleClick('浼氬憳淇℃伅')"
+      >
+        浼氬憳淇℃伅
+      </div>
+      <div
+        :class="{ 'kefu-header-item-activation': tabActivation('鏈�杩戞祻瑙�') }"
+        class="kefu-header-item cursor-pointer flex items-center justify-center"
+        @click="handleClick('鏈�杩戞祻瑙�')"
+      >
+        鏈�杩戞祻瑙�
+      </div>
+      <div
+        :class="{ 'kefu-header-item-activation': tabActivation('浜ゆ槗璁㈠崟') }"
+        class="kefu-header-item cursor-pointer flex items-center justify-center"
+        @click="handleClick('浜ゆ槗璁㈠崟')"
+      >
+        浜ゆ槗璁㈠崟
+      </div>
+    </el-header>
+    <el-main class="kefu-content p-10px!">
+      <div v-if="!isEmpty(conversation)" v-loading="loading">
+        <!-- 鍩烘湰淇℃伅 -->
+        <UserBasicInfo v-if="activeTab === '浼氬憳淇℃伅'" :user="user" mode="kefu">
+          <template #header>
+            <CardTitle title="鍩烘湰淇℃伅" />
+          </template>
+        </UserBasicInfo>
+        <!-- 璐︽埛淇℃伅 -->
+        <el-card v-if="activeTab === '浼氬憳淇℃伅'" class="h-full mt-10px" shadow="never">
+          <template #header>
+            <CardTitle title="璐︽埛淇℃伅" />
+          </template>
+          <UserAccountInfo :column="1" :user="user" :wallet="wallet" />
+        </el-card>
+      </div>
+      <div v-show="!isEmpty(conversation)">
+        <el-scrollbar ref="scrollbarRef" always @scroll="handleScroll">
+          <!-- 鏈�杩戞祻瑙� -->
+          <ProductBrowsingHistory v-if="activeTab === '鏈�杩戞祻瑙�'" ref="productBrowsingHistoryRef" />
+          <!-- 浜ゆ槗璁㈠崟 -->
+          <OrderBrowsingHistory v-if="activeTab === '浜ゆ槗璁㈠崟'" ref="orderBrowsingHistoryRef" />
+        </el-scrollbar>
+      </div>
+      <el-empty v-show="isEmpty(conversation)" description="璇烽�夋嫨宸︿晶鐨勪竴涓細璇濆悗寮�濮�" />
+    </el-main>
+  </el-container>
+</template>
+
+<script lang="ts" setup>
+import ProductBrowsingHistory from './ProductBrowsingHistory.vue'
+import OrderBrowsingHistory from './OrderBrowsingHistory.vue'
+import { KeFuConversationRespVO } from '@/api/mall/promotion/kefu/conversation'
+import { isEmpty } from '@/utils/is'
+import { debounce } from 'lodash-es'
+import { ElScrollbar as ElScrollbarType } from 'element-plus/es/components/scrollbar/index'
+import { CardTitle } from '@/components/Card'
+import UserBasicInfo from '@/views/member/user/detail/UserBasicInfo.vue'
+import UserAccountInfo from '@/views/member/user/detail/UserAccountInfo.vue'
+import * as UserApi from '@/api/member/user'
+import * as WalletApi from '@/api/pay/wallet/balance'
+
+defineOptions({ name: 'MemberBrowsingHistory' })
+
+const activeTab = ref('浼氬憳淇℃伅')
+const tabActivation = computed(() => (tab: string) => activeTab.value === tab)
+
+/** tab 鍒囨崲 */
+const productBrowsingHistoryRef = ref<InstanceType<typeof ProductBrowsingHistory>>()
+const orderBrowsingHistoryRef = ref<InstanceType<typeof OrderBrowsingHistory>>()
+const handleClick = async (tab: string) => {
+  if (isEmpty(conversation)) {
+    return
+  }
+  activeTab.value = tab
+  await nextTick()
+  await getHistoryList()
+}
+
+/** 鑾峰緱鍘嗗彶鏁版嵁 */
+const getHistoryList = async () => {
+  switch (activeTab.value) {
+    case '浼氬憳淇℃伅':
+      await getUserData()
+      await getUserWallet()
+      break
+    case '鏈�杩戞祻瑙�':
+      await productBrowsingHistoryRef.value?.getHistoryList(conversation.value)
+      break
+    case '浜ゆ槗璁㈠崟':
+      await orderBrowsingHistoryRef.value?.getHistoryList(conversation.value)
+      break
+    default:
+      break
+  }
+}
+
+/** 鍔犺浇涓嬩竴椤垫暟鎹� */
+const loadMore = async () => {
+  switch (activeTab.value) {
+    case '浼氬憳淇℃伅':
+      break
+    case '鏈�杩戞祻瑙�':
+      await productBrowsingHistoryRef.value?.loadMore()
+      break
+    case '浜ゆ槗璁㈠崟':
+      await orderBrowsingHistoryRef.value?.loadMore()
+      break
+    default:
+      break
+  }
+}
+
+/** 娴忚鍘嗗彶鍒濆鍖� */
+const conversation = ref<KeFuConversationRespVO>({} as KeFuConversationRespVO) // 鐢ㄦ埛浼氳瘽
+const initHistory = async (val: KeFuConversationRespVO) => {
+  activeTab.value = '浼氬憳淇℃伅'
+  conversation.value = val
+  await nextTick()
+  await getHistoryList()
+}
+defineExpose({ initHistory })
+
+/** 澶勭悊娑堟伅鍒楄〃婊氬姩浜嬩欢(debounce 闄愭祦) */
+const scrollbarRef = ref<InstanceType<typeof ElScrollbarType>>()
+const handleScroll = debounce(() => {
+  const wrap = scrollbarRef.value?.wrapRef
+  // 瑙﹀簳閲嶇疆
+  if (Math.abs(wrap!.scrollHeight - wrap!.clientHeight - wrap!.scrollTop) < 1) {
+    loadMore()
+  }
+}, 200)
+
+/** 鏌ヨ鐢ㄦ埛閽卞寘淇℃伅 */
+const WALLET_INIT_DATA = {
+  balance: 0,
+  totalExpense: 0,
+  totalRecharge: 0
+} as WalletApi.WalletVO // 閽卞寘鍒濆鍖栨暟鎹�
+const wallet = ref<WalletApi.WalletVO>(WALLET_INIT_DATA) // 閽卞寘淇℃伅
+const getUserWallet = async () => {
+  if (!conversation.value.userId) {
+    wallet.value = WALLET_INIT_DATA
+    return
+  }
+  wallet.value =
+    (await WalletApi.getWallet({ userId: conversation.value.userId })) || WALLET_INIT_DATA
+}
+
+/** 鑾峰緱鐢ㄦ埛 */
+const loading = ref(true) // 鍔犺浇涓�
+const user = ref<UserApi.UserVO>({} as UserApi.UserVO)
+const getUserData = async () => {
+  loading.value = true
+  try {
+    user.value = await UserApi.getUser(conversation.value.userId)
+  } finally {
+    loading.value = false
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.kefu {
+  position: relative;
+  width: 300px !important;
+  background-color: var(--app-content-bg-color);
+
+  &::after {
+    content: '';
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 1px; /* 瀹為檯瀹藉害 */
+    height: 100%;
+    background-color: var(--el-border-color);
+    transform: scaleX(0.3); /* 缂╁皬瀹藉害 */
+  }
+
+  &-header {
+    background-color: var(--app-content-bg-color);
+    position: relative;
+    display: flex;
+    align-items: center;
+    justify-content: space-around;
+
+    &::before {
+      content: '';
+      position: absolute;
+      bottom: 0;
+      left: 0;
+      width: 100%;
+      height: 1px; /* 鍒濆瀹藉害 */
+      background-color: var(--el-border-color);
+      transform: scaleY(0.3); /* 缂╁皬瑙嗚楂樺害 */
+    }
+
+    &-title {
+      font-size: 18px;
+      font-weight: bold;
+    }
+
+    &-item {
+      height: 100%;
+      width: 100%;
+      position: relative;
+
+      &-activation::before {
+        content: '';
+        position: absolute; /* 缁濆瀹氫綅 */
+        top: 0;
+        left: 0;
+        right: 0;
+        bottom: 0; /* 瑕嗙洊鏁翠釜鍏冪礌 */
+        border-bottom: 2px solid rgba(128, 128, 128, 0.5); /* 杈规鏍峰紡 */
+        pointer-events: none; /* 纭繚鐐瑰嚮浜嬩欢涓嶄細琚吉鍏冪礌鎷︽埅 */
+      }
+
+      &:hover::before {
+        content: '';
+        position: absolute; /* 缁濆瀹氫綅 */
+        top: 0;
+        left: 0;
+        right: 0;
+        bottom: 0; /* 瑕嗙洊鏁翠釜鍏冪礌 */
+        border-bottom: 2px solid rgba(128, 128, 128, 0.5); /* 杈规鏍峰紡 */
+        pointer-events: none; /* 纭繚鐐瑰嚮浜嬩欢涓嶄細琚吉鍏冪礌鎷︽埅 */
+      }
+    }
+  }
+
+  &-content {
+    margin: 0;
+    padding: 0;
+    position: relative;
+    height: 100%;
+    width: 100%;
+  }
+
+  &-tabs {
+    height: 100%;
+    width: 100%;
+  }
+}
+
+.header-title {
+  border-bottom: #e4e0e0 solid 1px;
+}
+</style>

--
Gitblit v1.8.0