在电脑端使用 localStorage 模拟企微环境,测试会话激活功能的完整流程。
cd yss-project
npm install # 如果还没安装依赖
ng serve
服务器启动后,访问:http://localhost:4200
按 F12 或右键 → 检查,打开开发者工具,切换到 Console 标签页。
在控制台中依次执行以下代码:
// ========== 1. 设置公司ID ==========
localStorage.setItem('company', 'test-company-001');
// ========== 2. 设置当前用户 ==========
const mockUser = {
objectId: 'user-001',
id: 'user-001',
userid: 'wxwork-user-001',
name: '测试技术员',
realName: '张三',
roleName: '技术',
department: {
__type: 'Pointer',
className: 'Department',
objectId: 'dept-001'
},
company: {
__type: 'Pointer',
className: 'Company',
objectId: 'test-company-001'
}
};
localStorage.setItem('currentUser', JSON.stringify(mockUser));
// ========== 3. 设置项目数据 ==========
const mockProject = {
objectId: 'project-001',
id: 'project-001',
title: '测试项目 - 现代简约风格装修',
description: '客厅、卧室、厨房三室一厅装修,预算15-20万',
status: '进行中',
contact: {
__type: 'Pointer',
className: 'ContactInfo',
objectId: 'contact-001'
},
assignee: {
__type: 'Pointer',
className: 'Profile',
objectId: 'user-001'
},
department: {
__type: 'Pointer',
className: 'Department',
objectId: 'dept-001'
}
};
localStorage.setItem('mockProject', JSON.stringify(mockProject));
// ========== 4. 设置客户数据 ==========
const mockContact = {
objectId: 'contact-001',
id: 'contact-001',
name: '李女士',
external_userid: 'external-user-001',
mobile: '138****8888',
company: 'test-company-001',
data: {
avatar: 'https://via.placeholder.com/100',
wechat: 'lixiaojie123',
tags: {
preference: '现代简约',
budget: { min: 150000, max: 200000 },
colorAtmosphere: '暖色调'
}
}
};
localStorage.setItem('mockContact', JSON.stringify(mockContact));
// ========== 5. 设置群聊数据 ==========
const mockGroupChat = {
objectId: 'groupchat-001',
id: 'groupchat-001',
chat_id: 'wrkSFfCgAAXXXXXXXXXXXXXXXXXXXX',
name: '【李女士】现代简约装修项目群',
company: 'test-company-001',
project: {
__type: 'Pointer',
className: 'Project',
objectId: 'project-001'
},
introSent: false,
introSentAt: null,
joinQrcode: {
qr_code: 'https://via.placeholder.com/300?text=QR+Code'
},
joinUrl: {
join_url: 'https://work.weixin.qq.com/ca/cawcde123456'
},
member_list: [
{
userid: 'wxwork-user-001',
type: 1,
name: '张三',
invitor: {
userid: 'admin-001'
}
},
{
userid: 'external-user-001',
type: 2,
name: '李女士',
invitor: {
userid: 'wxwork-user-001'
}
},
{
userid: 'wxwork-user-002',
type: 1,
name: '王组长',
invitor: {
userid: 'admin-001'
}
}
],
messages: [
{
msgid: 'msg-001',
from: 'external-user-001',
msgtime: Math.floor(Date.now() / 1000) - 3600,
msgtype: 'text',
text: {
content: '你好,我想了解一下项目的进度'
}
},
{
msgid: 'msg-002',
from: 'wxwork-user-001',
msgtime: Math.floor(Date.now() / 1000) - 3500,
msgtype: 'text',
text: {
content: '您好李女士,目前我们正在进行方案设计,预计明天可以给您看初稿'
}
},
{
msgid: 'msg-003',
from: 'external-user-001',
msgtime: Math.floor(Date.now() / 1000) - 3400,
msgtype: 'text',
text: {
content: '好的,那我等你们的消息'
}
},
{
msgid: 'msg-004',
from: 'external-user-001',
msgtime: Math.floor(Date.now() / 1000) - 700,
msgtype: 'text',
text: {
content: '对了,我想把客厅的颜色改成浅灰色,可以吗?'
}
},
{
msgid: 'msg-005',
from: 'external-user-001',
msgtime: Math.floor(Date.now() / 1000) - 650,
msgtype: 'text',
text: {
content: '还有厨房的橱柜我想换个品牌'
}
}
]
};
localStorage.setItem('mockGroupChat', JSON.stringify(mockGroupChat));
// ========== 6. 设置部门数据 ==========
const mockDepartment = {
objectId: 'dept-001',
id: 'dept-001',
name: '设计部',
leader: {
__type: 'Pointer',
className: 'Profile',
objectId: 'leader-001'
}
};
localStorage.setItem('mockDepartment', JSON.stringify(mockDepartment));
// ========== 7. 设置组长数据 ==========
const mockLeader = {
objectId: 'leader-001',
id: 'leader-001',
name: '王组长',
userid: 'wxwork-user-002',
roleName: '组长'
};
localStorage.setItem('mockLeader', JSON.stringify(mockLeader));
console.log('✅ 所有模拟数据已设置完成!');
console.log('📝 数据清单:');
console.log('- 公司ID:', localStorage.getItem('company'));
console.log('- 当前用户:', JSON.parse(localStorage.getItem('currentUser')).name);
console.log('- 项目:', JSON.parse(localStorage.getItem('mockProject')).title);
console.log('- 客户:', JSON.parse(localStorage.getItem('mockContact')).name);
console.log('- 群聊:', JSON.parse(localStorage.getItem('mockGroupChat')).name);
console.log('- 消息数量:', JSON.parse(localStorage.getItem('mockGroupChat')).messages.length);
chat-activation.component.ts在组件的 loadData() 方法中添加 localStorage 支持:
async loadData() {
try {
this.loading = true;
// ========== 开发环境:使用 localStorage ==========
if (!this.wxwork && typeof window !== 'undefined') {
console.log('🔧 开发模式:使用 localStorage 模拟数据');
// 1. 加载当前用户
const userStr = localStorage.getItem('currentUser');
if (userStr) {
this.currentUser = JSON.parse(userStr) as any;
console.log('✅ 用户加载成功:', this.currentUser.name);
}
// 2. 加载项目
const projectStr = localStorage.getItem('mockProject');
if (projectStr) {
this.project = JSON.parse(projectStr) as any;
console.log('✅ 项目加载成功:', this.project.title);
}
// 3. 加载客户
const contactStr = localStorage.getItem('mockContact');
if (contactStr) {
this.contact = JSON.parse(contactStr) as any;
console.log('✅ 客户加载成功:', this.contact.name);
}
// 4. 加载群聊
const groupChatStr = localStorage.getItem('mockGroupChat');
if (groupChatStr) {
this.groupChat = JSON.parse(groupChatStr) as any;
this.chatId = this.groupChat.chat_id;
this.introSent = this.groupChat.introSent || false;
console.log('✅ 群聊加载成功:', this.groupChat.name);
// 加载入群方式
this.joinMethods.qrCode = this.groupChat.joinQrcode?.qr_code || '';
this.joinMethods.link = this.groupChat.joinUrl?.join_url || '';
}
// 5. 加载部门和组长
const deptStr = localStorage.getItem('mockDepartment');
const leaderStr = localStorage.getItem('mockLeader');
if (deptStr && leaderStr && this.project) {
const dept = JSON.parse(deptStr);
const leader = JSON.parse(leaderStr);
this.project.department = dept;
this.project.department.leader = leader;
console.log('✅ 部门和组长加载成功');
}
// 6. 生成介绍文案
this.generateIntroTemplate();
// 7. 加载消息(使用 mock 数据)
await this.loadChatMessagesFromLocalStorage();
this.loading = false;
this.cdr.markForCheck();
return;
}
// ========== 生产环境:正常流程 ==========
// ... 原有代码保持不变
} catch (error) {
console.error('❌ 加载数据失败:', error);
this.error = error.message || '加载失败';
} finally {
this.loading = false;
}
}
// 新增:从 localStorage 加载消息
async loadChatMessagesFromLocalStorage() {
try {
this.loadingMessages = true;
if (!this.groupChat) {
this.messages = [];
this.updateStatistics();
return;
}
const messagesData = this.groupChat.messages || [];
const memberList = this.groupChat.member_list || [];
const customerUserId = this.contact?.external_userid || '';
// 转换为 ChatMessage 格式
this.messages = messagesData.map((msg: any, index: number) => {
const isCustomer = msg.from === customerUserId ||
memberList.some((m: any) =>
m.type === 2 && m.userid === msg.from
);
const msgTime = new Date(msg.msgtime * 1000);
const needsReply = isCustomer && this.checkNeedsReply(msg, messagesData, index);
return {
id: msg.msgid || `msg-${index}`,
senderName: this.getSenderName(msg.from, memberList),
senderUserId: msg.from,
content: this.getMessageContent(msg),
time: msgTime,
isCustomer,
needsReply,
msgType: msg.msgtype
};
}).sort((a: ChatMessage, b: ChatMessage) => b.time.getTime() - a.time.getTime());
this.updateStatistics();
this.applyFilters();
console.log('✅ 消息加载完成:', {
总消息数: this.totalMessages,
客户消息: this.customerMessageCount,
未回复: this.unreadCount
});
} catch (error) {
console.error('❌ 加载消息失败:', error);
} finally {
this.loadingMessages = false;
this.cdr.markForCheck();
}
}
async sendGroupIntro() {
try {
if (!this.chatId) {
window?.fmode?.alert('群聊信息不完整');
return;
}
this.sendingIntro = true;
// ========== 开发环境:模拟发送 ==========
if (!this.wecorp) {
console.log('🔧 开发模式:模拟发送群介绍');
console.log('📝 文案内容:', this.introTemplate);
// 模拟延迟
await new Promise(resolve => setTimeout(resolve, 1000));
// 更新 localStorage
if (this.groupChat) {
this.groupChat.introSent = true;
this.groupChat.introSentAt = new Date();
localStorage.setItem('mockGroupChat', JSON.stringify(this.groupChat));
this.introSent = true;
}
alert('✅ 群介绍已发送(模拟)!');
this.sendingIntro = false;
this.cdr.markForCheck();
return;
}
// ========== 生产环境:实际发送 ==========
// @ts-ignore - 企微API类型定义问题
await this.wecorp.message.send({
chatid: this.chatId,
msgtype: 'text',
text: {
content: this.introTemplate
}
});
// 更新数据库标记
if (this.groupChat) {
this.groupChat.set('introSent', true);
this.groupChat.set('introSentAt', new Date());
await this.groupChat.save();
this.introSent = true;
}
window?.fmode?.alert('群介绍已发送!');
} catch (error) {
console.error('发送群介绍失败:', error);
window?.fmode?.alert('发送失败,请重试');
} finally {
this.sendingIntro = false;
this.cdr.markForCheck();
}
}
async sendSuggestedReply(reply: SuggestedReply) {
try {
if (!this.chatId) {
window?.fmode?.alert('无法发送消息');
return;
}
// ========== 开发环境:模拟发送 ==========
if (!this.wecorp) {
console.log('🔧 开发模式:模拟发送回复');
console.log('📝 回复内容:', reply.text);
// 模拟延迟
await new Promise(resolve => setTimeout(resolve, 500));
// 添加新消息到 localStorage
const groupChatStr = localStorage.getItem('mockGroupChat');
if (groupChatStr) {
const groupChat = JSON.parse(groupChatStr);
const newMessage = {
msgid: `msg-${Date.now()}`,
from: this.currentUser?.userid || 'wxwork-user-001',
msgtime: Math.floor(Date.now() / 1000),
msgtype: 'text',
text: {
content: reply.text
}
};
groupChat.messages.push(newMessage);
localStorage.setItem('mockGroupChat', JSON.stringify(groupChat));
this.groupChat = groupChat;
}
alert('✅ 消息已发送(模拟)!');
// 关闭建议面板
this.showSuggestions = false;
this.selectedMessage = null;
// 刷新消息列表
await this.loadChatMessagesFromLocalStorage();
return;
}
// ========== 生产环境:实际发送 ==========
// @ts-ignore - 企微API类型定义问题
await this.wecorp.message.send({
chatid: this.chatId,
msgtype: 'text',
text: {
content: reply.text
}
});
window?.fmode?.alert('消息已发送!');
// 关闭建议面板
this.showSuggestions = false;
this.selectedMessage = null;
// 刷新消息列表
await this.loadChatMessages();
} catch (error) {
console.error('发送消息失败:', error);
window?.fmode?.alert('发送失败,请重试');
}
}
在浏览器中访问:
http://localhost:4200/wxwork/test-company-001/project/project-001/chat-activation
或者如果有查询参数:
http://localhost:4200/wxwork/test-company-001/project/project-001/chat-activation?chatId=wrkSFfCgAAXXXXXXXXXXXXXXXXXXXX
页面加载
入群方式卡片
群介绍文案
消息列表
筛选功能
未回复提醒
F12 打开开发者工具测试过程中,控制台会输出详细日志:
🔧 开发模式:使用 localStorage 模拟数据
✅ 用户加载成功: 张三
✅ 项目加载成功: 测试项目 - 现代简约风格装修
✅ 客户加载成功: 李女士
✅ 群聊加载成功: 【李女士】现代简约装修项目群
✅ 部门和组长加载成功
✅ 消息加载完成: {总消息数: 5, 客户消息: 3, 未回复: 2}
修改消息时间为10分钟前:
const groupChat = JSON.parse(localStorage.getItem('mockGroupChat'));
// 将最后一条客户消息改为15分钟前
groupChat.messages[3].msgtime = Math.floor(Date.now() / 1000) - 900; // 15分钟前
groupChat.messages[4].msgtime = Math.floor(Date.now() / 1000) - 850; // 14分钟前
localStorage.setItem('mockGroupChat', JSON.stringify(groupChat));
// 刷新页面
location.reload();
预期效果:
const groupChat = JSON.parse(localStorage.getItem('mockGroupChat'));
groupChat.introSent = true;
groupChat.introSentAt = new Date().toISOString();
localStorage.setItem('mockGroupChat', JSON.stringify(groupChat));
location.reload();
预期效果:
const groupChat = JSON.parse(localStorage.getItem('mockGroupChat'));
// 添加更多消息
for (let i = 0; i < 10; i++) {
groupChat.messages.push({
msgid: `msg-extra-${i}`,
from: i % 2 === 0 ? 'external-user-001' : 'wxwork-user-001',
msgtime: Math.floor(Date.now() / 1000) - (600 - i * 50),
msgtype: 'text',
text: {
content: i % 2 === 0 ? `客户消息 ${i}` : `技术回复 ${i}`
}
});
}
localStorage.setItem('mockGroupChat', JSON.stringify(groupChat));
location.reload();
预期效果:
解决方法:
// 检查 localStorage 数据
console.log('Company:', localStorage.getItem('company'));
console.log('User:', localStorage.getItem('currentUser'));
console.log('Project:', localStorage.getItem('mockProject'));
console.log('GroupChat:', localStorage.getItem('mockGroupChat'));
// 如果数据不存在,重新执行步骤1.2的代码
解决方法:
// 检查群聊消息
const groupChat = JSON.parse(localStorage.getItem('mockGroupChat'));
console.log('Messages:', groupChat.messages);
console.log('Messages count:', groupChat.messages.length);
// 如果为空,重新设置
groupChat.messages = [/* 复制步骤1.2中的消息数据 */];
localStorage.setItem('mockGroupChat', JSON.stringify(groupChat));
location.reload();
解决方法:
解决方法:
// 检查是否进入开发模式
console.log('wxwork:', this.wxwork);
console.log('wecorp:', this.wecorp);
// 如果为 null,说明进入了开发模式
// 查看控制台是否有 "🔧 开发模式:..." 的日志
测试完成后,清除所有模拟数据:
// 清除所有测试数据
localStorage.removeItem('company');
localStorage.removeItem('currentUser');
localStorage.removeItem('mockProject');
localStorage.removeItem('mockContact');
localStorage.removeItem('mockGroupChat');
localStorage.removeItem('mockDepartment');
localStorage.removeItem('mockLeader');
console.log('✅ 所有测试数据已清除');
或者清除所有 localStorage:
localStorage.clear();
console.log('✅ localStorage 已完全清空');
测试时建议截图保存以下内容:
所有以下项目都通过即为测试完成:
# 会话激活功能测试报告
**测试时间**: 2025-11-01
**测试人员**: [你的名字]
**测试环境**: Chrome 浏览器 + localhost:4200
## 测试结果
### 1. 基础功能
- [ ] 页面加载: ✅ 通过 / ❌ 失败
- [ ] 入群方式: ✅ 通过 / ❌ 失败
- [ ] 群介绍: ✅ 通过 / ❌ 失败
### 2. 消息功能
- [ ] 消息列表: ✅ 通过 / ❌ 失败
- [ ] 筛选功能: ✅ 通过 / ❌ 失败
- [ ] 未回复提醒: ✅ 通过 / ❌ 失败
### 3. 辅助回复
- [ ] 快速回复: ✅ 通过 / ❌ 失败
- [ ] 发送消息: ✅ 通过 / ❌ 失败
### 4. 响应式
- [ ] 移动端布局: ✅ 通过 / ❌ 失败
## 发现的问题
1. [问题描述]
2. [问题描述]
## 改进建议
1. [建议内容]
2. [建议内容]
测试通过后,可以:
祝测试顺利! 🎉
如有问题,请查看控制台日志或联系开发团队。