Files
yunke/yunkes/src/views/SmsList.vue
T

218 lines
5.5 KiB
Vue
Raw Normal View History

<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { ElMessage } from 'element-plus'
import { getSms } from '@/api'
import type { Sms } from '@/api/types'
import { formatTime, smsDirectionLabel } from '@/utils/format'
const list = ref<Sms[]>([])
const total = ref(0)
const page = ref(1)
const pageSize = ref(20)
const loading = ref(false)
const errorMsg = ref<string | null>(null)
// Detail dialog state — shows the full SMS body (vs the truncated preview in
// the table).
const detailVisible = ref(false)
const detailRow = ref<Sms | null>(null)
async function load(): Promise<void> {
loading.value = true
errorMsg.value = null
try {
const res = await getSms({
page: page.value,
page_size: pageSize.value,
})
list.value = res.items
total.value = res.total
} catch (e) {
errorMsg.value = (e as Error).message
ElMessage.error(`短信记录加载失败:${(e as Error).message}`)
} finally {
loading.value = false
}
}
function handlePageChange(p: number): void {
page.value = p
load()
}
function handlePageSizeChange(s: number): void {
pageSize.value = s
page.value = 1
load()
}
function openDetail(row: Sms): void {
detailRow.value = row
detailVisible.value = true
}
onMounted(load)
</script>
<template>
<div class="yk-sms">
<div class="yk-sms__header">
<div>
<h2 style="margin: 0 0 4px; font-size: 16px">短信记录</h2>
<span class="yk-sms__sub">共 {{ total }} 条</span>
</div>
</div>
<el-alert
v-if="errorMsg"
:title="errorMsg"
type="error"
show-icon
:closable="false"
style="margin-bottom: 12px"
/>
<el-table
v-loading="loading"
:data="list"
stripe
border
row-key="sms_id"
style="width: 100%"
:row-class-name="() => 'yk-clickable-row'"
empty-text="暂无短信记录"
@row-click="openDetail"
>
<el-table-column label="时间" width="160">
<template #default="{ row }">{{ formatTime(row.create_time) }}</template>
</el-table-column>
<el-table-column label="员工" min-width="130">
<template #default="{ row }">
{{ row.receive_name || row.user_id || '--' }}
</template>
</el-table-column>
<el-table-column label="客户号码" min-width="130">
<template #default="{ row }">
{{ row.customer_phone || row.sender || '--' }}
</template>
</el-table-column>
<el-table-column label="方向" width="80">
<template #default="{ row }">{{ smsDirectionLabel(row.direction) }}</template>
</el-table-column>
<el-table-column label="内容预览" min-width="260">
<template #default="{ row }">
<span v-if="row.content_preview">{{ row.content_preview }}</span>
<span v-else-if="row.content">{{ row.content }}</span>
<span v-else style="color: #c0c4cc">--</span>
</template>
</el-table-column>
</el-table>
<div class="yk-sms__pager">
<el-pagination
:current-page="page"
:page-size="pageSize"
:page-sizes="[20, 50, 100]"
:total="total"
layout="total, sizes, prev, pager, next, jumper"
background
@current-change="handlePageChange"
@size-change="handlePageSizeChange"
/>
</div>
<p class="yk-sms__hint">点击任意一行查看完整短信内容。</p>
<el-dialog
v-model="detailVisible"
title="短信详情"
width="520px"
align-center
>
<div v-if="detailRow" class="yk-sms__detail">
<div class="yk-sms__detail-row">
<span class="yk-sms__detail-label">时间</span>
<span>{{ formatTime(detailRow.create_time) }}</span>
</div>
<div class="yk-sms__detail-row">
<span class="yk-sms__detail-label">员工</span>
<span>{{ detailRow.receive_name || detailRow.user_id || '--' }}</span>
</div>
<div class="yk-sms__detail-row">
<span class="yk-sms__detail-label">客户号码</span>
<span>{{ detailRow.customer_phone || '--' }}</span>
</div>
<div class="yk-sms__detail-row">
<span class="yk-sms__detail-label">发送方</span>
<span>{{ detailRow.sender || '--' }}</span>
</div>
<div class="yk-sms__detail-row">
<span class="yk-sms__detail-label">方向</span>
<span>{{ smsDirectionLabel(detailRow.direction) }}</span>
</div>
<div class="yk-sms__detail-row yk-sms__detail-row--top">
<span class="yk-sms__detail-label">内容</span>
<span class="yk-sms__detail-content">{{
detailRow.content || detailRow.content_preview || '(空)'
}}</span>
</div>
</div>
</el-dialog>
</div>
</template>
<style scoped>
.yk-sms__header {
display: flex;
justify-content: space-between;
align-items: flex-start;
gap: 16px;
flex-wrap: wrap;
margin-bottom: 12px;
}
.yk-sms__sub {
color: #909399;
font-size: 13px;
}
.yk-sms__pager {
margin-top: 12px;
display: flex;
justify-content: flex-end;
}
.yk-sms__hint {
margin: 8px 2px 0;
font-size: 12px;
color: #c0c4cc;
}
.yk-sms__detail {
display: flex;
flex-direction: column;
gap: 10px;
font-size: 13px;
}
.yk-sms__detail-row {
display: flex;
gap: 12px;
align-items: center;
}
.yk-sms__detail-row--top {
align-items: flex-start;
}
.yk-sms__detail-label {
flex: 0 0 64px;
color: #909399;
}
.yk-sms__detail-content {
white-space: pre-wrap;
word-break: break-word;
line-height: 1.6;
}
</style>