docs(plan): 复核残留修订——exportListToCsv真实签名落地代码块/调度测试改相对日期

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
浅念
2026-09-04 14:48:45 +08:00
parent 0bc1250476
commit 81af615738
@@ -2625,10 +2625,17 @@ async def sched_engine():
async def test_analytics_tick_runs(sched_engine):
# _analytics_tick 用真实「今天」算滚动窗——seed 的 day 必须相对当日,
# 固定 20260904 会在三天后过期(评审残留#2 修正)
import datetime as dt
from app.storage.summary import day_key
engine, maker = sched_engine
today = day_key(int(dt.datetime.now().timestamp() * 1000))
async with maker() as s:
s.add(MsgDailyStats(channel="wechat", owner_account_id="wx1",
peer_kind="friend", peer_id="t1", day=20260904,
peer_kind="friend", peer_id="t1", day=today,
send_cnt=1, recv_cnt=0, last_ts=1756950000000,
last_is_send=True))
s.add(SensitiveWord(word="私单"))
@@ -3061,7 +3068,7 @@ onMounted(load)
import { onMounted, ref } from 'vue'
import { useRouter } from 'vue-router'
import { getChurn, type Channel, type ChurnRow } from '@/api/analytics'
import { exportRowsCsv } from '@/utils/csvExport' // 路径以项目实际为准(grep csvExport)
import { exportListToCsv } from '@/utils/csvExport'
const router = useRouter()
const channel = ref<Channel>('wechat')
@@ -3105,20 +3112,26 @@ function goChat(row: ChurnRow) {
async function exportCsv() {
exporting.value = true
try {
const all: ChurnRow[] = []
for (let p = 1; ; p++) {
const out = await getChurn({
await exportListToCsv<ChurnRow>({
fetchPage: (page, pageSize) => getChurn({
channel: channel.value, type: kind.value, tier: tier.value,
min_msgs: 5, page: p, page_size: 100,
})
all.push(...out.items)
if (all.length >= out.total || out.items.length === 0) break
}
exportRowsCsv(all.map((r) => ({
客户: r.nickname, 渠道: r.channel, 归属员工: r.owner_account_id ?? '',
最后沟通: r.last_chat_time ? new Date(r.last_chat_time).toLocaleString('zh-CN', { hour12: false }) : '',
历史消息量: r.hist_msgs, 活跃天数: r.active_days,
})), `流失预警_${kind.value}_${channel.value}.csv`)
min_msgs: 5, page, page_size: pageSize,
}),
columns: [
{ key: 'nickname', label: '客户' },
{ key: 'channel', label: '渠道' },
{ key: 'owner_account_id', label: '归属员工' },
{
key: 'last_chat_time', label: '最后沟通',
format: (r) => (r.last_chat_time
? new Date(r.last_chat_time).toLocaleString('zh-CN', { hour12: false })
: '从未沟通'),
},
{ key: 'hist_msgs', label: '历史消息量' },
{ key: 'active_days', label: '活跃天数' },
],
filename: `流失预警_${kind.value}_${channel.value}`,
}) // 工具自带翻页+BOM+10000 行 cap
} finally {
exporting.value = false
}