From eb0388c8b0f05ce59a055d3859b3d015f375a9fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B5=85=E5=BF=B5?= Date: Tue, 25 Aug 2026 17:03:19 +0800 Subject: [PATCH] =?UTF-8?q?feat(staffchat):=20=E9=A1=B5=E9=9D=A2=E9=AA=A8?= =?UTF-8?q?=E6=9E=B6+=E5=B7=A6=E4=BE=A7=E8=B5=84=E6=96=99=E5=8D=A1/5?= =?UTF-8?q?=E5=AF=BC=E8=88=AA/=E6=8A=98=E5=8F=A0(=E4=B8=89=E6=A0=8F?= =?UTF-8?q?=E5=B8=83=E5=B1=80=E5=AF=B9=E9=BD=90=E4=BA=91=E5=AE=A2)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - StaffChat.vue: 路由驱动 tab(single/group/moments/contacts/stats)+折叠态, 三栏 flex(左栏240/中列280/右列flex:1,高calc(100vh-120px));资料卡走 getAccounts(channel=wechat) 按 account_id 匹配,失败退 ownerId 兜底 - StaffChatSide.vue: 员工资料卡(头像/昵称/真名·电话/微信号)+竖排5导航+ 底部收起;墨玉主题沿用 ChatSidebar 手法(点阵底/玉绿渐变分隔线/药丸按钮) - 5 占位组件(SessionPane/ChatMain/MomentsPane/ContactsPane/StatsPane), defineProps/defineEmits 签名按 Task 10-14 锁定 - relativeChatTime 签名可空友好(ms?: number|null,null→''),spec+1例 Co-Authored-By: Claude --- yunkes/src/components/staffchat/ChatMain.vue | 13 ++ .../src/components/staffchat/ContactsPane.vue | 8 + .../src/components/staffchat/MomentsPane.vue | 8 + .../src/components/staffchat/SessionPane.vue | 18 +++ .../components/staffchat/StaffChatSide.vue | 149 ++++++++++++++++++ yunkes/src/components/staffchat/StatsPane.vue | 8 + yunkes/src/utils/__tests__/format.spec.ts | 5 + yunkes/src/utils/format.ts | 5 +- yunkes/src/views/StaffChat.vue | 140 ++++++++++++++-- 9 files changed, 344 insertions(+), 10 deletions(-) create mode 100644 yunkes/src/components/staffchat/ChatMain.vue create mode 100644 yunkes/src/components/staffchat/ContactsPane.vue create mode 100644 yunkes/src/components/staffchat/MomentsPane.vue create mode 100644 yunkes/src/components/staffchat/SessionPane.vue create mode 100644 yunkes/src/components/staffchat/StaffChatSide.vue create mode 100644 yunkes/src/components/staffchat/StatsPane.vue diff --git a/yunkes/src/components/staffchat/ChatMain.vue b/yunkes/src/components/staffchat/ChatMain.vue new file mode 100644 index 0000000..936cdbc --- /dev/null +++ b/yunkes/src/components/staffchat/ChatMain.vue @@ -0,0 +1,13 @@ + + + + diff --git a/yunkes/src/components/staffchat/ContactsPane.vue b/yunkes/src/components/staffchat/ContactsPane.vue new file mode 100644 index 0000000..8f24f8c --- /dev/null +++ b/yunkes/src/components/staffchat/ContactsPane.vue @@ -0,0 +1,8 @@ + + + + diff --git a/yunkes/src/components/staffchat/MomentsPane.vue b/yunkes/src/components/staffchat/MomentsPane.vue new file mode 100644 index 0000000..7f83835 --- /dev/null +++ b/yunkes/src/components/staffchat/MomentsPane.vue @@ -0,0 +1,8 @@ + + + + diff --git a/yunkes/src/components/staffchat/SessionPane.vue b/yunkes/src/components/staffchat/SessionPane.vue new file mode 100644 index 0000000..dbe5d9f --- /dev/null +++ b/yunkes/src/components/staffchat/SessionPane.vue @@ -0,0 +1,18 @@ + + + + diff --git a/yunkes/src/components/staffchat/StaffChatSide.vue b/yunkes/src/components/staffchat/StaffChatSide.vue new file mode 100644 index 0000000..cb5be7a --- /dev/null +++ b/yunkes/src/components/staffchat/StaffChatSide.vue @@ -0,0 +1,149 @@ + + + + + diff --git a/yunkes/src/components/staffchat/StatsPane.vue b/yunkes/src/components/staffchat/StatsPane.vue new file mode 100644 index 0000000..81a3337 --- /dev/null +++ b/yunkes/src/components/staffchat/StatsPane.vue @@ -0,0 +1,8 @@ + + + + diff --git a/yunkes/src/utils/__tests__/format.spec.ts b/yunkes/src/utils/__tests__/format.spec.ts index 5f8a87c..f2d34c9 100644 --- a/yunkes/src/utils/__tests__/format.spec.ts +++ b/yunkes/src/utils/__tests__/format.spec.ts @@ -36,4 +36,9 @@ describe('relativeChatTime', () => { const lastYear = new Date().getFullYear() - 1 expect(relativeChatTime(at(lastYear, 5, 10))).toBe(`${lastYear}年6月10日`) }) + + it('null/undefined → 空串(可空友好,免调用方 ?? 0 渲染 1970)', () => { + expect(relativeChatTime(null)).toBe('') + expect(relativeChatTime(undefined)).toBe('') + }) }) diff --git a/yunkes/src/utils/format.ts b/yunkes/src/utils/format.ts index 703841a..90d84ec 100644 --- a/yunkes/src/utils/format.ts +++ b/yunkes/src/utils/format.ts @@ -24,8 +24,11 @@ export function formatTimeShort(ts?: number | null): string { /** * 云客聊天窗口相对时间(会话列表/消息时间轴用): 今天→HH:mm, * 昨天→`昨天`, 今年→`M月D日`, 往年→`YYYY年M月D日`。 + * null/undefined → `''`(与 formatTimeShort 一致,调用方可直接传可空字段, + * 无需 `?? 0` 兜底——那会把缺时间渲染成 1970年1月1日)。 */ -export function relativeChatTime(ms: number): string { +export function relativeChatTime(ms?: number | null): string { + if (ms == null) return '' const d = new Date(ms) const now = new Date() const sameDay = (a: Date, b: Date) => a.toDateString() === b.toDateString() diff --git a/yunkes/src/views/StaffChat.vue b/yunkes/src/views/StaffChat.vue index 91d8e08..a1db081 100644 --- a/yunkes/src/views/StaffChat.vue +++ b/yunkes/src/views/StaffChat.vue @@ -1,14 +1,136 @@ - + + +