|
|
@@ -22,23 +22,44 @@
|
|
|
<el-button icon="Refresh" @click="resetQuery">重設</el-button>
|
|
|
</el-form-item>
|
|
|
</el-form>
|
|
|
- <el-table v-loading="loading" :data="callList">
|
|
|
+ <el-row :gutter="10" class="mb8">
|
|
|
+ <el-col :span="1.5">
|
|
|
+ <el-button
|
|
|
+ type="info"
|
|
|
+ plain
|
|
|
+ icon="Sort"
|
|
|
+ @click="toggleExpandAll"
|
|
|
+ >展開/折疊</el-button>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ <el-table
|
|
|
+ v-if="refreshTable"
|
|
|
+ v-loading="loading"
|
|
|
+ :data="treeData"
|
|
|
+ :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
|
|
|
+ row-key="id"
|
|
|
+ :default-expand-all="isExpandAll"
|
|
|
+ >
|
|
|
<el-table-column type="selection" width="55" align="center" />
|
|
|
- <el-table-column label="id" align="center" prop="id" />
|
|
|
- <el-table-column label="用戶ID" align="center" prop="userId" />
|
|
|
- <el-table-column label="所屬用戶" align="center" prop="userName" />
|
|
|
- <el-table-column label="電話號碼" align="center" prop="phoneNumber" />
|
|
|
- <el-table-column label="通話類型" align="center" prop="callType">
|
|
|
+ <el-table-column label="所屬用戶" prop="userName" width="200" show-overflow-tooltip>
|
|
|
<template #default="{ row }">
|
|
|
- <span>{{ callTypeText(row.callType) }}</span>
|
|
|
+ <span v-if="row.isParent" class="parent-user-name">{{ row.userName || row.userId || '-' }}</span>
|
|
|
+ <span v-else>{{ row.userName || '-' }}</span>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column label="通話開始時間" align="center" prop="startTime" />
|
|
|
- <el-table-column label="通話時長" align="center" prop="duration" />
|
|
|
- <el-table-column label="通訊錄名稱" align="center" prop="contactName" />
|
|
|
+ <el-table-column label="用戶ID" prop="userId" width="120" align="center"/>
|
|
|
+ <el-table-column label="電話號碼" prop="phoneNumber" align="center" />
|
|
|
+ <el-table-column label="通話類型" prop="callType" align="center">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <span v-if="!row.isParent">{{ callTypeText(row.callType) }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="通話開始時間" prop="startTime" align="center" />
|
|
|
+ <el-table-column label="通話時長" prop="duration" align="center" />
|
|
|
+ <el-table-column label="通訊錄名稱" prop="contactName" align="center" />
|
|
|
<el-table-column label="操作" align="center" width="140" class-name="small-padding fixed-width">
|
|
|
<template #default="{ row }">
|
|
|
- <el-tooltip content="查看" placement="top">
|
|
|
+ <el-tooltip content="查看" placement="top" v-if="!row.isParent">
|
|
|
<el-button link type="primary" icon="View" @click.stop="handleView(row)"></el-button>
|
|
|
</el-tooltip>
|
|
|
</template>
|
|
|
@@ -82,6 +103,7 @@ const { proxy } = getCurrentInstance()
|
|
|
const { sys_show_hide, sys_normal_disable } = proxy.useDict("sys_show_hide", "sys_normal_disable")
|
|
|
|
|
|
const callList = ref([])
|
|
|
+const treeData = ref([])
|
|
|
const total = ref(0)
|
|
|
const title = ref("")
|
|
|
const open = ref(false)
|
|
|
@@ -89,12 +111,50 @@ const form = ref({})
|
|
|
const formRef = ref()
|
|
|
const loading = ref(true)
|
|
|
const queryFormRef = ref()
|
|
|
+const isExpandAll = ref(false)
|
|
|
+const refreshTable = ref(true)
|
|
|
const queryParams = reactive({
|
|
|
pageNum: 1,
|
|
|
pageSize: 10,
|
|
|
username: null,
|
|
|
userId:null,
|
|
|
})
|
|
|
+
|
|
|
+// 将扁平数据转换为树形结构
|
|
|
+const convertToTree = (data) => {
|
|
|
+ if (!data || !Array.isArray(data)) {
|
|
|
+ return []
|
|
|
+ }
|
|
|
+ const treeMap = new Map()
|
|
|
+ const result = []
|
|
|
+
|
|
|
+ // 先按userName和userId分组
|
|
|
+ data.forEach(item => {
|
|
|
+ const key = `${item.userName || ''}_${item.userId || ''}`
|
|
|
+ if (!treeMap.has(key)) {
|
|
|
+ treeMap.set(key, {
|
|
|
+ id: `parent_${key}`,
|
|
|
+ userName: item.userName || item.userId || '未知用户',
|
|
|
+ userId: item.userId,
|
|
|
+ isParent: true,
|
|
|
+ children: []
|
|
|
+ })
|
|
|
+ }
|
|
|
+ // 添加子节点
|
|
|
+ treeMap.get(key).children.push({
|
|
|
+ ...item,
|
|
|
+ id: item.id || `child_${key}_${treeMap.get(key).children.length}`
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ // 转换为数组
|
|
|
+ treeMap.forEach(value => {
|
|
|
+ result.push(value)
|
|
|
+ })
|
|
|
+
|
|
|
+ return result
|
|
|
+}
|
|
|
+
|
|
|
onMounted(()=>{
|
|
|
getList()
|
|
|
})
|
|
|
@@ -154,8 +214,39 @@ const getList = () => {
|
|
|
userId:queryParams.userId,
|
|
|
}
|
|
|
getCallPageList(params).then(response => {
|
|
|
- callList.value = response.data.records
|
|
|
- total.value = response.data.total
|
|
|
+ // 处理不同的API返回格式
|
|
|
+ // response 可能是 { code: 200, msg: "操作成功", data: [...] } 或直接是数组
|
|
|
+ let data = []
|
|
|
+ let totalCount = 0
|
|
|
+
|
|
|
+ if (Array.isArray(response)) {
|
|
|
+ // 如果response直接是数组
|
|
|
+ data = response
|
|
|
+ totalCount = data.length
|
|
|
+ } else if (Array.isArray(response.data)) {
|
|
|
+ // 如果data是数组
|
|
|
+ data = response.data
|
|
|
+ totalCount = data.length
|
|
|
+ } else if (response.data && Array.isArray(response.data.records)) {
|
|
|
+ // 如果是分页格式 { records: [], total: ... }
|
|
|
+ data = response.data.records
|
|
|
+ totalCount = response.data.total || data.length
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果数据已经是树形结构(包含isParent和children),直接使用
|
|
|
+ if (data.length > 0 && (data[0].isParent !== undefined || data[0].children !== undefined)) {
|
|
|
+ treeData.value = data
|
|
|
+ callList.value = data.flatMap(item => item.children || [])
|
|
|
+ total.value = totalCount
|
|
|
+ } else {
|
|
|
+ // 否则转换为树形结构
|
|
|
+ callList.value = data
|
|
|
+ treeData.value = convertToTree(data)
|
|
|
+ total.value = totalCount
|
|
|
+ }
|
|
|
+ loading.value = false
|
|
|
+ }).catch((error) => {
|
|
|
+ console.error('获取通话列表失败:', error)
|
|
|
loading.value = false
|
|
|
})
|
|
|
}
|
|
|
@@ -165,7 +256,7 @@ const handleView = (row) => {
|
|
|
reset()
|
|
|
form.value = {...row}
|
|
|
open.value = true
|
|
|
- title.value = "查看圖片資訊"
|
|
|
+ title.value = "查看通話資訊"
|
|
|
nextTick(() => {
|
|
|
if (formRef.value) formRef.value.clearValidate && formRef.value.clearValidate()
|
|
|
})
|
|
|
@@ -175,7 +266,20 @@ const cancel = () => {
|
|
|
open.value = false
|
|
|
reset()
|
|
|
}
|
|
|
+
|
|
|
+/** 展开/折叠操作 */
|
|
|
+const toggleExpandAll = () => {
|
|
|
+ refreshTable.value = false
|
|
|
+ isExpandAll.value = !isExpandAll.value
|
|
|
+ nextTick(() => {
|
|
|
+ refreshTable.value = true
|
|
|
+ })
|
|
|
+}
|
|
|
</script>
|
|
|
<style scoped lang="scss">
|
|
|
-
|
|
|
+.parent-user-name {
|
|
|
+ color: #409EFF;
|
|
|
+ font-weight: 500;
|
|
|
+ font-size: 14px;
|
|
|
+}
|
|
|
</style>
|