feat(pc-client): 通讯录入口整改 + 添加同事弹窗 + 发送错误提示(视觉规范 v1,B-52 施工 3/3)

- ContactSider:三个功能入口改为 20px 线性图标 + 36x36 浅蓝图标块 + 文字
  (①新的同事②添加同事③我的群聊),行高 44,删掉 48px PNG 大图
- 新增 AddColleague 弹窗:工号 + 可编辑验证消息 + 五态(默认/校验失败/发送中/成功/失败)
- 会话栏搜索框右侧新增「+」入口,两处打开同一个弹窗
- useSendMessage:空接收方明确提示、SDK 错误码映射中文提示
- 申请状态文案对齐规范:等待对方通过/已添加/已拒绝
- global.scss 补 --search-bg / --chat-bg token

Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
编码工程师
2026-08-16 02:19:05 +08:00
co-authored by multica-agent
parent 12b0a1c943
commit 032882dbec
7 changed files with 203 additions and 55 deletions
+40 -39
View File
@@ -1,48 +1,48 @@
import { Badge } from "antd";
import clsx from "clsx";
import { UserAddOutlined, UserOutlined, TeamOutlined } from "@ant-design/icons";
import i18n, { t } from "i18next";
import { useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import group_notifications from "@/assets/images/contact/group_notifications.png";
import my_friends from "@/assets/images/contact/my_friends.png";
import my_groups from "@/assets/images/contact/my_groups.png";
import new_friends from "@/assets/images/contact/new_friends.png";
import FlexibleSider from "@/components/FlexibleSider";
import AddColleague from "@/pages/common/AddColleague";
import { useContactStore } from "@/store";
const Links = [
type LinkItem = {
label: string;
icon: React.ReactNode;
path?: string;
modal?: boolean;
};
// 通讯录功能入口:按视觉规范 v1 固定顺序 ①新的同事 ②添加同事 ③我的群聊,
// 全部用「20px 线性图标 + 36×36 浅蓝图标块 + 文字」,行高 44。
const buildLinks = (): LinkItem[] => [
{
label: t("placeholder.newFriends"),
icon: new_friends,
icon: <UserAddOutlined />,
path: "/contact/newFriends",
},
{
label: t("placeholder.groupNotification"),
icon: group_notifications,
path: "/contact/groupNotifications",
},
{
label: t("placeholder.myFriend"),
icon: my_friends,
path: "/contact",
label: t("placeholder.addColleague"),
icon: <UserOutlined />,
modal: true,
},
{
label: t("placeholder.myGroup"),
icon: my_groups,
icon: <TeamOutlined />,
path: "/contact/myGroups",
},
];
i18n.on("languageChanged", () => {
Links[0].label = t("placeholder.newFriends");
Links[1].label = t("placeholder.groupNotification");
Links[2].label = t("placeholder.myFriend");
Links[3].label = t("placeholder.myGroup");
// buildLinks 每次渲染时都会重新读取文案,无需缓存更新
});
const ContactSider = () => {
const [selectIndex, setSelectIndex] = useState(2);
const [selectIndex, setSelectIndex] = useState(-1);
const [addColleagueOpen, setAddColleagueOpen] = useState(false);
const unHandleFriendApplicationCount = useContactStore(
(state) => state.unHandleFriendApplicationCount,
);
@@ -50,16 +50,14 @@ const ContactSider = () => {
(state) => state.unHandleGroupApplicationCount,
);
const navigate = useNavigate();
const Links = buildLinks();
useEffect(() => {
if (location.hash.includes("/contact/newFriends")) {
setSelectIndex(0);
}
if (location.hash.includes("/contact/groupNotifications")) {
setSelectIndex(1);
}
if (location.hash.includes("/contact/myGroups")) {
setSelectIndex(3);
setSelectIndex(2);
}
}, []);
@@ -67,10 +65,16 @@ const ContactSider = () => {
if (index === 0) {
return unHandleFriendApplicationCount;
}
if (index === 1) {
return unHandleGroupApplicationCount;
return index === 2 ? unHandleGroupApplicationCount : 0;
};
const onClick = (item: LinkItem, index: number) => {
if (item.modal) {
setAddColleagueOpen(true);
return;
}
return 0;
setSelectIndex(index);
if (item.path) navigate(item.path);
};
return (
@@ -86,32 +90,29 @@ const ContactSider = () => {
{Links.map((item, index) => {
return (
<li
key={item.path}
key={item.label}
className={clsx(
"mx-2 flex cursor-pointer items-center rounded-lg px-3 py-2.5 text-sm",
"mx-2 flex h-11 cursor-pointer items-center rounded-lg px-3",
index === selectIndex
? "bg-[var(--primary-active)]"
: "hover:bg-[var(--chat-bg)]",
)}
onClick={() => {
setSelectIndex(index);
navigate(String(item.path));
}}
onClick={() => onClick(item, index)}
>
<Badge size="small" count={getBadge(index)}>
<img
alt={item.label}
src={item.icon}
className="mr-3 h-12 w-12 rounded-lg"
/>
<span className="flex h-9 w-9 items-center justify-center rounded-lg bg-[var(--primary-active)] text-[20px] leading-none text-[var(--primary)]">
{item.icon}
</span>
</Badge>
<div className="text-sm">{item.label}</div>
<div className="ml-3 text-[15px] text-[var(--base-black)]">{item.label}</div>
</li>
);
})}
</ul>
</div>
<AddColleague open={addColleagueOpen} onClose={() => setAddColleagueOpen(false)} />
</FlexibleSider>
);
};
export default ContactSider;