refactor(archive): 优化列表展示体验,补全客户昵称与添加悬浮提示
1. 前端:为发送人、接收人列添加悬浮提示展示完整ID,移除无用的消息动作列 2. 后端:新增企微客户昵称补全逻辑,实时拉取并更新数据库中缺失的客户名称
This commit is contained in:
parent
75c98d04e6
commit
26fadbe307
@ -1,5 +1,6 @@
|
||||
package com.artedu.archive.service;
|
||||
|
||||
import com.artedu.archive.client.WeComApiClient;
|
||||
import com.artedu.archive.entity.ArchiveMessage;
|
||||
import com.artedu.archive.entity.Customer;
|
||||
import com.artedu.archive.entity.Staff;
|
||||
@ -44,6 +45,9 @@ public class ArchiveSessionService {
|
||||
@Autowired
|
||||
private ArchiveMessageMapper archiveMessageMapper;
|
||||
|
||||
@Autowired
|
||||
private WeComApiClient weComApiClient;
|
||||
|
||||
private static final java.time.format.DateTimeFormatter TIME_FORMATTER =
|
||||
java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
@ -80,9 +84,48 @@ public class ArchiveSessionService {
|
||||
|
||||
Page<Customer> pageResult = customerMapper.selectPage(new Page<>(page, size), wrapper);
|
||||
List<CustomerSessionVO> list = pageResult.getRecords().stream().map(this::convertCustomerVO).collect(Collectors.toList());
|
||||
enrichCustomerNames(list);
|
||||
return PageResult.of(page, size, pageResult.getTotal(), list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 补全客户昵称:对名字为空或仍为 ID 的外部客户,实时从企微获取并更新数据库
|
||||
*/
|
||||
private void enrichCustomerNames(List<CustomerSessionVO> list) {
|
||||
if (list == null || list.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
for (CustomerSessionVO vo : list) {
|
||||
String customerId = vo.getCustomerId();
|
||||
String name = vo.getName();
|
||||
if (!isExternalUserId(customerId) || (name != null && !name.trim().isEmpty() && !customerId.equals(name))) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
Map<String, Object> detail = weComApiClient.getExternalContact(customerId);
|
||||
if (detail == null || detail.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
Map<String, Object> contact = (Map<String, Object>) detail.get("external_contact");
|
||||
if (contact == null) {
|
||||
continue;
|
||||
}
|
||||
String fetchedName = (String) contact.get("name");
|
||||
if (fetchedName == null || fetchedName.trim().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
vo.setName(fetchedName);
|
||||
Customer customer = customerMapper.selectByCustomerId(customerId, corpId);
|
||||
if (customer != null) {
|
||||
customer.setName(fetchedName);
|
||||
customerMapper.updateById(customer);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("实时获取客户昵称失败: customerId={}", customerId, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 员工的会话列表
|
||||
*/
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { useState, useEffect } from 'react'
|
||||
import { Table, Input, Select, Tag, Space, Card, Statistic, Row, Col, Button } from 'antd'
|
||||
import { Table, Input, Select, Tag, Space, Card, Statistic, Row, Col, Button, Tooltip } from 'antd'
|
||||
import { MessageOutlined, FileTextOutlined, PictureOutlined, AudioOutlined, VideoCameraOutlined, FileOutlined, LinkOutlined, EnvironmentOutlined, SmileOutlined, AppstoreOutlined, WechatOutlined } from '@ant-design/icons'
|
||||
import request from '../utils/request'
|
||||
|
||||
@ -45,12 +45,6 @@ export default function ArchiveList() {
|
||||
EXTERNAL: '客户',
|
||||
}
|
||||
|
||||
const actionMap: Record<string, string> = {
|
||||
send: '发送消息',
|
||||
recall: '撤回消息',
|
||||
switch: '切换企业',
|
||||
}
|
||||
|
||||
const loadData = async (page = 1, pageSize = 20) => {
|
||||
setLoading(true)
|
||||
try {
|
||||
@ -260,7 +254,9 @@ export default function ArchiveList() {
|
||||
dataIndex: 'fromUser',
|
||||
width: 120,
|
||||
render: (fromUser: string, record: any) => (
|
||||
<span style={{ color: '#333', fontWeight: 500 }}>{record.fromUserName || fromUser}</span>
|
||||
<Tooltip title={fromUser} placement="topLeft">
|
||||
<span style={{ color: '#333', fontWeight: 500 }}>{record.fromUserName || fromUser}</span>
|
||||
</Tooltip>
|
||||
),
|
||||
},
|
||||
{
|
||||
@ -280,23 +276,20 @@ export default function ArchiveList() {
|
||||
width: 160,
|
||||
render: (time: string) => <span style={{ color: '#666', fontSize: 13 }}>{time}</span>,
|
||||
},
|
||||
{
|
||||
title: '消息动作',
|
||||
dataIndex: 'action',
|
||||
width: 90,
|
||||
align: 'center' as const,
|
||||
render: (action: string) => <span style={{ color: '#666' }}>{actionMap[action] || action}</span>,
|
||||
},
|
||||
{
|
||||
title: '接收人',
|
||||
dataIndex: 'toUser',
|
||||
width: 200,
|
||||
ellipsis: true,
|
||||
render: (_: any, record: any) => (
|
||||
<span style={{ color: '#666', fontSize: 13 }} title={parseReceivers(record.toUser, record.tolist)}>
|
||||
{parseReceivers(record.toUser, record.tolist)}
|
||||
</span>
|
||||
),
|
||||
render: (_: any, record: any) => {
|
||||
const ids = parseReceivers(record.toUser, record.tolist)
|
||||
const names = record.toUserName || ids
|
||||
return (
|
||||
<Tooltip title={ids} placement="topLeft">
|
||||
<span style={{ color: '#666', fontSize: 13 }}>{names}</span>
|
||||
</Tooltip>
|
||||
)
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user