feat(staff): 微信 5 数字 modal 换本地数据源(metric 过滤 + 合成分页)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -3,7 +3,7 @@ import { computed, onMounted, reactive, ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { getAccounts, getCustomers, getMessages, getStaffChatStats } from '@/api'
|
||||
import type { Account, Channel, StaffChatStats } from '@/api/types'
|
||||
import type { Account, Channel, Page, StaffChatCustomer, StaffChatStats } from '@/api/types'
|
||||
import YkStaffDetailModal from '@/components/YkStaffDetailModal.vue'
|
||||
import { useChannelStore } from '@/stores/channel'
|
||||
import { channelLabel, formatTime } from '@/utils/format'
|
||||
@@ -347,11 +347,50 @@ function commModalColsFor(metric: ChatMetric): any[] {
|
||||
}
|
||||
return cols
|
||||
}
|
||||
/** 按 metric 过滤客户明细(口径见 spec §4;last_is_send 为 null 时既非最后回复也非未回复)。 */
|
||||
function metricFilter(c: StaffChatCustomer, m: ChatMetric): boolean {
|
||||
switch (m) {
|
||||
case 'chat':
|
||||
return true
|
||||
case 'effective':
|
||||
return c.send_count >= 1 && c.receive_count >= 1
|
||||
case 'follow':
|
||||
return c.interaction_days >= 2
|
||||
case 'last_reply':
|
||||
return c.last_is_send === 1
|
||||
case 'no_reply':
|
||||
return c.last_is_send === 0
|
||||
}
|
||||
}
|
||||
|
||||
/** 微信员工 5 数字 → 明细 modal(数据源:本地 staff-chat-stats,按 metric 过滤 + 合成分页)。 */
|
||||
function openWechatCommModal(row: Account, metric: ChatMetric): void {
|
||||
// Task 3 接真实数据 + metric 过滤 + 合成分页。此处先立标题与列骨架。
|
||||
detailTitle.value = `${METRIC_TITLES[metric]} · ${row.user_name ?? row.account_id}`
|
||||
detailCols.value = commModalColsFor(metric)
|
||||
detailFetcher.value = async () => ({ items: [], total: 0, page: 1, page_size: 10 })
|
||||
detailFetcher.value = async (page: number, page_size: number): Promise<Page<any>> => {
|
||||
// 复用已缓存的 stats;点击早于列表加载完成则按需补拉。
|
||||
let stats = staffStats.value[row.account_id]
|
||||
if (!stats) {
|
||||
try {
|
||||
stats = await getStaffChatStats({
|
||||
owner_account_id: row.account_id,
|
||||
start: statsStart.value,
|
||||
end: statsEnd.value,
|
||||
})
|
||||
staffStats.value[row.account_id] = stats
|
||||
} catch {
|
||||
return { items: [], total: 0, page, page_size }
|
||||
}
|
||||
}
|
||||
const filtered = stats.customers.filter((c) => metricFilter(c, metric))
|
||||
const startIdx = (page - 1) * page_size
|
||||
return {
|
||||
items: filtered.slice(startIdx, startIdx + page_size),
|
||||
total: filtered.length,
|
||||
page,
|
||||
page_size,
|
||||
}
|
||||
}
|
||||
detailOpen.value = true
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user