feat(staff): WhatsApp stat-number click → detail modal

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
浅念
2026-08-05 18:56:27 +08:00
parent 8e79f80925
commit 55578cf299
+68 -3
View File
@@ -2,8 +2,9 @@
import { computed, onMounted, reactive, ref } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import { getAccounts } from '@/api'
import { getAccounts, getCustomers } from '@/api'
import type { Account, Channel } from '@/api/types'
import YkStaffDetailModal from '@/components/YkStaffDetailModal.vue'
import { useChannelStore } from '@/stores/channel'
import { channelLabel, formatTime } from '@/utils/format'
import { buildAccountSections, formatBytes, readField } from '@/utils/accountFields'
@@ -185,6 +186,55 @@ function viewGroups(): void {
router.push('/groups')
}
// ---------------------------------------------------------------------------
// Detail modal (stat-number click → 明细) — reused for 添加人数 / 沟通人数.
// fetcher is set by open*Modal; the modal triggers it on open.
// ---------------------------------------------------------------------------
const detailOpen = ref(false)
const detailTitle = ref('')
// fetcher is set by open*Modal; the modal invokes it on open.
const detailFetcher = ref<(p: number, s: number) => Promise<any>>(
async () => ({ items: [], total: 0 }),
)
const detailCols = ref<any[]>([])
const baseCustomerCols = [
{ prop: 'friend_nickname', label: '客户', minWidth: 140 },
{ prop: 'phone', label: '客户号码', width: 130 },
{ prop: 'last_chat_time', label: '最后沟通', width: 150 },
{ prop: 'add_time', label: '添加时间', width: 150 },
]
function openAddedModal(row: Account) {
// ⚠️ WA customer has no add_time (Task 2 confirmed: WA raw_json lacks
// addTime; createTime is owner-staff). Degrade: do NOT set add_time_since
// (would be empty); show all WA customers for this staff, sorted by
// last_chat_time.
detailTitle.value = `添加人数 · ${row.user_name ?? row.account_id}`
detailCols.value = baseCustomerCols
detailFetcher.value = (p, s) =>
getCustomers({ user_id: row.user_id!, channel: 'whatsapp', page: p, page_size: s })
detailOpen.value = true
}
function openTalkedModal(row: Account) {
// 沟通人数: chatted within the last 7 days (last_chat_time exists on both
// channels).
const since = Date.now() - 7 * 86400000
detailTitle.value = `沟通人数 · ${row.user_name ?? row.account_id}`
detailCols.value = baseCustomerCols
detailFetcher.value = (p, s) =>
getCustomers({
user_id: row.user_id!,
channel: 'whatsapp',
last_chat_since: since,
page: p,
page_size: s,
})
detailOpen.value = true
}
// ---------------------------------------------------------------------------
// Per-tab loading
// ---------------------------------------------------------------------------
@@ -519,12 +569,20 @@ onMounted(() => {
<!-- 添加人数 -->
<el-table-column label="添加人数" width="100" align="right">
<template #default="{ row }">{{ cellNum(row, 'friendAddNum') }}</template>
<template #default="{ row }">
<el-button link type="primary" size="small" @click.stop="openAddedModal(row)">
{{ cellNum(row, 'friendAddNum') }}
</el-button>
</template>
</el-table-column>
<!-- 沟通人数 -->
<el-table-column label="沟通人数" width="100" align="right">
<template #default="{ row }">{{ cellNum(row, 'talkerCount') }}</template>
<template #default="{ row }">
<el-button link type="primary" size="small" @click.stop="openTalkedModal(row)">
{{ cellNum(row, 'talkerCount') }}
</el-button>
</template>
</el-table-column>
<!-- 好友数 -->
@@ -572,6 +630,13 @@ onMounted(() => {
</el-tab-pane>
</el-tabs>
<YkStaffDetailModal
v-model="detailOpen"
:title="detailTitle"
:cols="detailCols"
:fetcher="detailFetcher"
/>
<p class="yk-staff__hint">点击任意一行查看员工账号全部字段。</p>
<!-- All-fields drawer (reused from AccountList.vue / accountFields.ts) -->