feat(customers): 微信客户操作列加「导出HTML聊天记录」+ 时间选择
对齐云客:先弹「请选择时间」→ 确定后调 /api/export/chat-html 下载。 Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,7 @@ import { computed, onMounted, reactive, ref, watch } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { getCustomers } from '@/api'
|
||||
import { downloadBlob } from '@/api/client'
|
||||
import type { Channel, Customer } from '@/api/types'
|
||||
import { useChannelStore } from '@/stores/channel'
|
||||
import { useOrgStore } from '@/stores/org'
|
||||
@@ -165,6 +166,45 @@ function viewChatFromDrawer(): void {
|
||||
viewChat(row)
|
||||
}
|
||||
|
||||
// ---- 操作列:导出HTML聊天记录 → 弹「请选择时间」→ /api/export/chat-html ----
|
||||
// 对齐云客:先弹时间范围 modal(可选,不选=全部),确定后下载。
|
||||
const exportOpen = ref(false)
|
||||
const exportRow = ref<Customer | null>(null)
|
||||
// el-date-picker value-format="X" 绑定秒级 unix 字符串数组;confirmExport 里 *1000 转毫秒。
|
||||
const exportRange = ref<[string, string] | null>(null)
|
||||
|
||||
function openExport(row: Customer): void {
|
||||
if (!row.owner_account_id || !row.friend_id) {
|
||||
ElMessage.warning('该客户缺少归属账号/客户标识,无法导出')
|
||||
return
|
||||
}
|
||||
exportRow.value = row
|
||||
exportRange.value = null
|
||||
exportOpen.value = true
|
||||
}
|
||||
|
||||
async function confirmExport(): Promise<void> {
|
||||
const row = exportRow.value
|
||||
if (!row) return
|
||||
const params: Record<string, unknown> = {
|
||||
channel: row.channel,
|
||||
owner_account_id: row.owner_account_id,
|
||||
talker_id: row.friend_id,
|
||||
}
|
||||
if (exportRange.value) {
|
||||
// value-format="X" 返回秒级字符串,后端要毫秒
|
||||
params.start = Number(exportRange.value[0]) * 1000
|
||||
params.end = Number(exportRange.value[1]) * 1000
|
||||
}
|
||||
exportOpen.value = false
|
||||
try {
|
||||
await downloadBlob('/export/chat-html', params)
|
||||
ElMessage.success('导出已开始')
|
||||
} catch (e) {
|
||||
ElMessage.error(`导出失败,请稍后重试:${(e as Error).message}`)
|
||||
}
|
||||
}
|
||||
|
||||
/** 清除 owner_account_id query(保留其余 query)。 */
|
||||
function clearOwnerFilter(): void {
|
||||
const { owner_account_id: _drop, ...rest } = route.query
|
||||
@@ -298,11 +338,14 @@ onMounted(() => {
|
||||
<el-table-column label="接收条数" width="100" align="right">
|
||||
<template #default="{ row }">{{ cellNum(row, 'receiveNum') }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="130" fixed="right" align="center">
|
||||
<el-table-column label="操作" width="220" fixed="right" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-button link type="primary" size="small" @click.stop="viewChat(row)">
|
||||
查看聊天记录
|
||||
</el-button>
|
||||
<el-button link type="primary" size="small" @click.stop="openExport(row)">
|
||||
导出HTML聊天记录
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -438,6 +481,28 @@ onMounted(() => {
|
||||
</div>
|
||||
</template>
|
||||
</el-drawer>
|
||||
|
||||
<!-- 导出HTML聊天记录:时间范围选择(不选=导出全部) -->
|
||||
<el-dialog v-model="exportOpen" title="请选择时间" width="420px" @close="exportRow = null">
|
||||
<el-form label-width="90px">
|
||||
<el-form-item label="时间范围">
|
||||
<el-date-picker
|
||||
v-model="exportRange"
|
||||
type="datetimerange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始时间"
|
||||
end-placeholder="结束时间"
|
||||
value-format="X"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="exportOpen = false">取 消</el-button>
|
||||
<el-button type="primary" @click="confirmExport">确 定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user