触客宝右侧功能提交
This commit is contained in:
@@ -30,10 +30,18 @@
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
min-width: 0; // 防止flex子元素溢出
|
min-width: 0; // 防止flex子元素溢出
|
||||||
|
|
||||||
|
:global(.ant-avatar) {
|
||||||
|
flex-shrink: 0;
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
.chatHeaderDetails {
|
.chatHeaderDetails {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
min-width: 0;
|
||||||
|
|
||||||
.chatHeaderName {
|
.chatHeaderName {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
@@ -63,6 +71,28 @@
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.chatHeaderSubInfo {
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
margin-top: 2px;
|
||||||
|
font-size: 12px;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.chatHeaderRemark {
|
||||||
|
color: #1890ff;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chatHeaderWechatId {
|
||||||
|
color: #8c8c8c;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -298,8 +328,16 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
|
|
||||||
|
:global(.ant-avatar) {
|
||||||
|
flex-shrink: 0;
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
}
|
||||||
|
|
||||||
.profileInfo {
|
.profileInfo {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
h4 {
|
h4 {
|
||||||
margin: 0 0 8px 0;
|
margin: 0 0 8px 0;
|
||||||
@@ -308,6 +346,18 @@
|
|||||||
color: #262626;
|
color: #262626;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.profileNickname {
|
||||||
|
margin: 0 0 8px 0;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #262626;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
max-width: 100%;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
.profileStatus {
|
.profileStatus {
|
||||||
margin: 0 0 4px 0;
|
margin: 0 0 4px 0;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
@@ -319,6 +369,31 @@
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: #8c8c8c;
|
color: #8c8c8c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.profileRemark {
|
||||||
|
margin: 0 0 4px 0;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #1890ff;
|
||||||
|
|
||||||
|
:global(.ant-input) {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(.ant-btn) {
|
||||||
|
padding: 0;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.profileWechatId {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #8c8c8c;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ import {
|
|||||||
FileExcelOutlined,
|
FileExcelOutlined,
|
||||||
FilePptOutlined,
|
FilePptOutlined,
|
||||||
PlayCircleFilled,
|
PlayCircleFilled,
|
||||||
|
EditOutlined,
|
||||||
|
CheckOutlined,
|
||||||
} from "@ant-design/icons";
|
} from "@ant-design/icons";
|
||||||
import { ChatRecord, ContractData } from "@/pages/pc/ckbox/data";
|
import { ChatRecord, ContractData } from "@/pages/pc/ckbox/data";
|
||||||
import { clearUnreadCount, getMessages } from "@/pages/pc/ckbox/api";
|
import { clearUnreadCount, getMessages } from "@/pages/pc/ckbox/api";
|
||||||
@@ -72,6 +74,8 @@ const ChatWindow: React.FC<ChatWindowProps> = ({
|
|||||||
const [pendingVideoRequests, setPendingVideoRequests] = useState<
|
const [pendingVideoRequests, setPendingVideoRequests] = useState<
|
||||||
Record<string, string>
|
Record<string, string>
|
||||||
>({});
|
>({});
|
||||||
|
const [isEditingRemark, setIsEditingRemark] = useState(false);
|
||||||
|
const [remarkValue, setRemarkValue] = useState(contract.conRemark || '');
|
||||||
const messagesEndRef = useRef<HTMLDivElement>(null);
|
const messagesEndRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -94,6 +98,12 @@ const ChatWindow: React.FC<ChatWindowProps> = ({
|
|||||||
});
|
});
|
||||||
}, [contract.id]);
|
}, [contract.id]);
|
||||||
|
|
||||||
|
// 当contract变化时更新备注值
|
||||||
|
useEffect(() => {
|
||||||
|
setRemarkValue(contract.conRemark || '');
|
||||||
|
setIsEditingRemark(false);
|
||||||
|
}, [contract.conRemark]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// 只有在非视频加载操作时才自动滚动到底部
|
// 只有在非视频加载操作时才自动滚动到底部
|
||||||
// 检查是否有视频正在加载中
|
// 检查是否有视频正在加载中
|
||||||
@@ -780,6 +790,21 @@ const ChatWindow: React.FC<ChatWindowProps> = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 处理备注保存
|
||||||
|
const handleSaveRemark = () => {
|
||||||
|
// 这里应该调用API保存备注到后端
|
||||||
|
// 暂时只更新本地状态
|
||||||
|
messageApi.success('备注保存成功');
|
||||||
|
setIsEditingRemark(false);
|
||||||
|
// 更新contract对象中的备注(实际项目中应该通过props回调或状态管理)
|
||||||
|
};
|
||||||
|
|
||||||
|
// 处理取消编辑
|
||||||
|
const handleCancelEdit = () => {
|
||||||
|
setRemarkValue(contract.conRemark || '');
|
||||||
|
setIsEditingRemark(false);
|
||||||
|
};
|
||||||
|
|
||||||
const chatMenu = (
|
const chatMenu = (
|
||||||
<Menu>
|
<Menu>
|
||||||
<Menu.Item key="profile" icon={<UserOutlined />}>
|
<Menu.Item key="profile" icon={<UserOutlined />}>
|
||||||
@@ -804,17 +829,21 @@ const ChatWindow: React.FC<ChatWindowProps> = ({
|
|||||||
// 模拟联系人详细信息
|
// 模拟联系人详细信息
|
||||||
const contractInfo = {
|
const contractInfo = {
|
||||||
name: contract.name,
|
name: contract.name,
|
||||||
|
nickname: contract.nickname,
|
||||||
|
conRemark: remarkValue, // 使用当前编辑的备注值
|
||||||
|
alias: contract.alias,
|
||||||
|
wechatId: contract.wechatId,
|
||||||
avatar: contract.avatar,
|
avatar: contract.avatar,
|
||||||
phone: "13800138001",
|
phone: contract.phone || '-',
|
||||||
email: "zhangsan@example.com",
|
email: contract.email || '-',
|
||||||
department: "技术部",
|
department: contract.department || '-',
|
||||||
position: "前端工程师",
|
position: contract.position || '-',
|
||||||
company: "某某科技有限公司",
|
company: contract.company || '-',
|
||||||
location: "北京市朝阳区",
|
location: contract.location || '-',
|
||||||
joinDate: "2023-01-15",
|
joinDate: contract.joinDate || '-',
|
||||||
status: "在线",
|
status: "在线",
|
||||||
tags: ["技术专家", "前端", "React"],
|
tags: contract.labels,
|
||||||
bio: "专注于前端开发,热爱新技术,擅长React、Vue等框架。",
|
bio: contract.bio || '-',
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -832,17 +861,9 @@ const ChatWindow: React.FC<ChatWindowProps> = ({
|
|||||||
contract.type === "group" ? <TeamOutlined /> : <UserOutlined />
|
contract.type === "group" ? <TeamOutlined /> : <UserOutlined />
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<div
|
<div className={styles.chatHeaderDetails}>
|
||||||
className={styles.chatHeaderDetails}
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div className={styles.chatHeaderName}>
|
<div className={styles.chatHeaderName}>
|
||||||
{contract.name}
|
{contract.nickname || contract.name}
|
||||||
{contract.online && (
|
|
||||||
<span className={styles.chatHeaderOnlineStatus}>在线</span>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -1011,7 +1032,7 @@ const ChatWindow: React.FC<ChatWindowProps> = ({
|
|||||||
|
|
||||||
{/* 右侧个人资料卡片 */}
|
{/* 右侧个人资料卡片 */}
|
||||||
{showProfile && (
|
{showProfile && (
|
||||||
<Sider width={280} className={styles.profileSider}>
|
<Sider width={330} className={styles.profileSider}>
|
||||||
<div className={styles.profileSiderContent}>
|
<div className={styles.profileSiderContent}>
|
||||||
<div className={styles.profileHeader}>
|
<div className={styles.profileHeader}>
|
||||||
<h3>个人资料</h3>
|
<h3>个人资料</h3>
|
||||||
@@ -1032,13 +1053,53 @@ const ChatWindow: React.FC<ChatWindowProps> = ({
|
|||||||
icon={<UserOutlined />}
|
icon={<UserOutlined />}
|
||||||
/>
|
/>
|
||||||
<div className={styles.profileInfo}>
|
<div className={styles.profileInfo}>
|
||||||
<h4>{contractInfo.name}</h4>
|
<Tooltip title={contractInfo.nickname || contractInfo.name} placement="top">
|
||||||
<p className={styles.profileStatus}>
|
<h4 className={styles.profileNickname}>{contractInfo.nickname || contractInfo.name}</h4>
|
||||||
<Badge status="success" text={contractInfo.status} />
|
</Tooltip>
|
||||||
</p>
|
|
||||||
<p className={styles.profilePosition}>
|
<div className={styles.profileRemark}>
|
||||||
{contractInfo.position} · {contractInfo.department}
|
{isEditingRemark ? (
|
||||||
</p>
|
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
||||||
|
<Input
|
||||||
|
value={remarkValue}
|
||||||
|
onChange={(e) => setRemarkValue(e.target.value)}
|
||||||
|
placeholder="请输入备注"
|
||||||
|
size="small"
|
||||||
|
style={{ flex: 1 }}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
type="text"
|
||||||
|
size="small"
|
||||||
|
icon={<CheckOutlined />}
|
||||||
|
onClick={handleSaveRemark}
|
||||||
|
style={{ color: '#52c41a' }}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
type="text"
|
||||||
|
size="small"
|
||||||
|
icon={<CloseOutlined />}
|
||||||
|
onClick={handleCancelEdit}
|
||||||
|
style={{ color: '#ff4d4f' }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
||||||
|
<span>备注: {contractInfo.conRemark || '无'}</span>
|
||||||
|
<Button
|
||||||
|
type="text"
|
||||||
|
size="small"
|
||||||
|
icon={<EditOutlined />}
|
||||||
|
onClick={() => setIsEditingRemark(true)}
|
||||||
|
style={{ color: '#1890ff' }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p className={styles.profileWechatId}>
|
||||||
|
微信号: {contractInfo.alias || contractInfo.wechatId}
|
||||||
|
</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
|
|||||||
Reference in New Issue
Block a user