feat(wa): WA客户列表加群列表子tab(好友/群两tab对齐云客)+员工列表群聊按钮跳子tab

- CustomerList whatsapp tab 加子tab切换(好友列表|群列表)
- 群列表内嵌 WA 群表格(序号/员工/群名/消息数/查看聊天)
- StaffList WA viewGroups 跳 /customers?tab=groups(不再跳 /groups)
- WA 群数据 317 个(wa-groups 重扫)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
浅念
2026-08-24 15:28:39 +08:00
parent 31d22ddd45
commit dcd1c2d178
2 changed files with 102 additions and 7 deletions
+90 -3
View File
@@ -3,9 +3,9 @@ import { computed, onMounted, reactive, ref, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import { Download } from '@element-plus/icons-vue'
import { getCustomerDeclaredTotal, getCustomers } from '@/api'
import { getCustomerDeclaredTotal, getCustomers, getGroups } from '@/api'
import { downloadBlob } from '@/api/client'
import type { Channel, Customer } from '@/api/types'
import type { Channel, Customer, Group } from '@/api/types'
import { useChannelStore } from '@/stores/channel'
import { useOrgStore } from '@/stores/org'
import { channelLabel, formatTime } from '@/utils/format'
@@ -72,6 +72,40 @@ const tabState = reactive<Record<TabKey, TabState>>({
whatsapp: freshTabState(10), // WA 10 条(2026-08-24 用户指定)
})
// WA 子 tab:好友列表 | 群列表(对齐云客 friendlist 页两 tab)
const waSubTab = ref<'friends' | 'groups'>(
route.query.tab === 'groups' ? 'groups' : 'friends',
)
// WA 群数据(子 tab=groups 时加载)
const waGroups = ref<Group[]>([])
const waGroupsLoading = ref(false)
const waGroupsTotal = ref(0)
const waGroupsPage = ref(1)
const waGroupsPageSize = ref(10)
async function loadWaGroups(): Promise<void> {
if (waGroups.value.length > 0 || waSubTab.value !== 'groups') return
waGroupsLoading.value = true
try {
const res = await getGroups({
channel: 'whatsapp',
owner_account_id: ownerId.value ?? undefined,
page: waGroupsPage.value,
page_size: waGroupsPageSize.value,
})
waGroups.value = res.items
waGroupsTotal.value = res.total
} catch (e) {
ElMessage.error(`WA 群列表加载失败:${(e as Error).message}`)
} finally {
waGroupsLoading.value = false
}
}
function onWaSubTabChange(): void {
if (waSubTab.value === 'groups') loadWaGroups()
}
// 全字段抽屉(两 tab 共享)
const drawerOpen = ref(false)
const drawerCustomer = ref<Customer | null>(null)
@@ -532,9 +566,17 @@ onMounted(() => {
<!-- ============================================================
WhatsApp客户 — 7 列,对齐云客 waBusiness/friendlist.
============================================================ -->
<!-- WA 子 tab:好友列表 | 群列表(对齐云客) -->
<template v-if="activeTab === 'whatsapp'">
<div v-if="waSubTab === 'groups'" class="yk-wa-subtab" style="margin-bottom: 12px">
<el-radio-group v-model="waSubTab" size="small" @change="onWaSubTabChange">
<el-radio-button value="friends">好友列表</el-radio-button>
<el-radio-button value="groups">群列表</el-radio-button>
</el-radio-group>
<span v-if="waSubTab == 'groups'" style="margin-left: 12px; font-size: 13px; color: #909399">{{ waGroupsTotal }} 个群</span>
</div>
<el-alert
v-if="tabState.whatsapp.errorMsg"
v-if="waSubTab === 'friends' && tabState.whatsapp.errorMsg"
:title="tabState.whatsapp.errorMsg"
type="error"
show-icon
@@ -542,6 +584,7 @@ onMounted(() => {
style="margin-bottom: 12px"
/>
<el-table
v-show="waSubTab === 'friends'"
v-loading="tabState.whatsapp.loading"
:data="tabState.whatsapp.items"
stripe
@@ -587,6 +630,50 @@ onMounted(() => {
</template>
</el-table-column>
</el-table>
<!-- WA 群列表(waSubTab=groups 时显示,对齐云客群列表 tab) -->
<el-table
v-if="waSubTab === 'groups'"
v-loading="waGroupsLoading"
:data="waGroups"
stripe
border
row-key="room_id"
style="width: 100%"
empty-text="暂无 WhatsApp 群数据"
>
<el-table-column label="序号" width="70" align="center">
<template #default="{ $index }">{{ (waGroupsPage - 1) * waGroupsPageSize + $index + 1 }}</template>
</el-table-column>
<el-table-column label="员工信息" min-width="140">
<template #default="{ row }">{{ row.owner_account_nickname || row.owner_account_id || '--' }}</template>
</el-table-column>
<el-table-column label="群信息" min-width="180">
<template #default="{ row }">{{ row.room_name || row.room_id || '--' }}</template>
</el-table-column>
<el-table-column label="消息数量" width="100" align="right">
<template #default="{ row }">{{ row.message_count ?? 0 }}</template>
</el-table-column>
<el-table-column label="操作" width="130" align="center">
<template #default="{ row }">
<el-button link type="primary" size="small" @click.stop="router.push({ name: 'group-chat', params: { channel: 'whatsapp', ownerId: row.owner_account_id || '', roomId: row.room_id } })">
查看聊天记录
</el-button>
</template>
</el-table-column>
</el-table>
<div v-if="waSubTab === 'groups'" class="yk-customers__pager">
<el-pagination
:current-page="waGroupsPage"
:page-size="waGroupsPageSize"
:page-sizes="[10, 20, 50]"
:total="waGroupsTotal"
layout="total, prev, pager, next"
background
@current-change="(p: number) => { waGroupsPage = p; waGroups = []; loadWaGroups(); }"
/>
</div>
<div class="yk-customers__pager">
<el-pagination
:current-page="tabState.whatsapp.page"
+12 -4
View File
@@ -248,10 +248,18 @@ function viewCustomers(row: Account): void {
function viewGroups(row: Account): void {
channelStore.setChannel(row.channel)
router.push({
path: '/groups',
query: { owner_account_id: row.account_id },
})
if (row.channel === 'whatsapp') {
// WA:对齐云客,群列表在客户列表页的子 tab(2026-08-24)
router.push({
path: '/customers',
query: { owner_account_id: row.account_id, channel: 'whatsapp', tab: 'groups' },
})
} else {
router.push({
path: '/groups',
query: { owner_account_id: row.account_id },
})
}
}
async function viewChat(row: Account) {