From d9c9599cb2983179236721cbc7d62ef3f5647459 Mon Sep 17 00:00:00 2001
From: ZF sun <34314687@qq.com>
Date: Tue, 16 Dec 2025 16:54:39 +0800
Subject: [PATCH] =?UTF-8?q?chore:=20=E9=9B=86=E6=88=90=E7=BB=9F=E4=B8=80?=
=?UTF-8?q?=E5=AE=A2=E6=9C=8D=E6=9C=8D=E5=8A=A1?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
App.vue | 5 +
common/js/customer-service.js | 345 ++++++++++++++++++
components/hover-nav/hover-nav.vue | 213 ++++++-----
components/ns-contact/ns-contact.vue | 267 +++++---------
components/wxwork-contact/CHANGELOG.md | 66 ++++
components/wxwork-contact/README.md | 484 +++++++++++++++++++++++++
6 files changed, 1103 insertions(+), 277 deletions(-)
create mode 100644 common/js/customer-service.js
create mode 100644 components/wxwork-contact/CHANGELOG.md
create mode 100644 components/wxwork-contact/README.md
diff --git a/App.vue b/App.vue
index 061c99f..ddc469e 100644
--- a/App.vue
+++ b/App.vue
@@ -98,6 +98,11 @@
if (uni.getStorageSync('servicerConfig')) {
this.$store.commit('setServicerConfig', uni.getStorageSync('servicerConfig'));
}
+
+ // 企业微信配置
+ if (uni.getStorageSync('wxworkConfig')) {
+ this.$store.commit('setWxworkConfig', uni.getStorageSync('wxworkConfig'));
+ }
// 版权信息
if (uni.getStorageSync('copyright')) {
diff --git a/common/js/customer-service.js b/common/js/customer-service.js
new file mode 100644
index 0000000..a24af90
--- /dev/null
+++ b/common/js/customer-service.js
@@ -0,0 +1,345 @@
+/**
+ * 客服统一处理服务
+ * 整合各种客服方式,提供统一的调用接口
+ */
+
+export class CustomerService {
+ constructor(vueInstance) {
+ this.vm = vueInstance;
+ }
+
+ /**
+ * 获取平台配置
+ * @returns {Object} 平台对应的客服配置
+ */
+ getPlatformConfig() {
+ const servicerConfig = this.vm.$store.state.servicerConfig;
+ if (!servicerConfig) return null;
+
+ // #ifdef H5
+ return servicerConfig.h5;
+ // #endif
+
+ // #ifdef MP-WEIXIN
+ return servicerConfig.weapp;
+ // #endif
+
+ // #ifdef MP-ALIPAY
+ return servicerConfig.aliapp;
+ // #endif
+
+ return null;
+ }
+
+ /**
+ * 获取企业微信配置
+ * @returns {Object} 企业微信配置
+ */
+ getWxworkConfig() {
+ return this.vm.$store.state.wxworkConfig;
+ }
+
+ /**
+ * 检查客服配置是否可用
+ * @returns {boolean} 是否有可用配置
+ */
+ isConfigAvailable() {
+ const config = this.getPlatformConfig();
+ return config && typeof config === 'object' && config.type;
+ }
+
+ /**
+ * 验证客服配置完整性
+ * @returns {Object} 验证结果
+ */
+ validateConfig() {
+ const config = this.getPlatformConfig();
+ const wxworkConfig = this.getWxworkConfig();
+
+ const result = {
+ isValid: true,
+ errors: [],
+ warnings: []
+ };
+
+ if (!config) {
+ result.isValid = false;
+ result.errors.push('客服配置不存在');
+ return result;
+ }
+
+ if (!config.type) {
+ result.isValid = false;
+ result.errors.push('客服类型未配置');
+ }
+
+ // 验证企业微信配置
+ if (config.type === 'wxwork') {
+ if (!wxworkConfig) {
+ result.isValid = false;
+ result.errors.push('企业微信配置不存在');
+ } else {
+ if (!wxworkConfig.enable) {
+ result.warnings.push('企业微信功能未启用');
+ }
+ if (!wxworkConfig.contact_url) {
+ result.warnings.push('企业微信活码链接未配置,将使用原有客服方式');
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * 获取客服类型
+ * @returns {string} 客服类型
+ */
+ getServiceType() {
+ const config = this.getPlatformConfig();
+ return config?.type || 'none';
+ }
+
+ /**
+ * 处理客服点击事件
+ * @param {Object} options 选项参数
+ * @param {Object} options.niushop 牛商客服参数
+ * @param {string} options.sendMessageTitle 消息标题
+ * @param {string} options.sendMessagePath 消息路径
+ * @param {string} options.sendMessageImg 消息图片
+ */
+ handleCustomerClick(options = {}) {
+ // 验证配置
+ const validation = this.validateConfig();
+ if (!validation.isValid) {
+ console.error('客服配置验证失败:', validation.errors);
+ this.showConfigErrorPopup(validation.errors);
+ return;
+ }
+
+ // 显示警告(如果有)
+ if (validation.warnings.length > 0) {
+ console.warn('客服配置警告:', validation.warnings);
+ }
+
+ const config = this.getPlatformConfig();
+ const {
+ niushop = {},
+ sendMessageTitle = '',
+ sendMessagePath = '',
+ sendMessageImg = ''
+ } = options;
+
+ // 检查是否为无客服类型
+ if (config.type === 'none') {
+ this.showNoServicePopup();
+ return;
+ }
+
+ // 根据类型处理客服
+ switch (config.type) {
+ case 'wxwork':
+ this.openWxworkService(false, config, options);
+ break;
+ case 'third':
+ this.openThirdService(config);
+ break;
+ case 'niushop':
+ this.openNiushopService(niushop);
+ break;
+ case 'weapp':
+ this.openWeappService(config);
+ break;
+ case 'aliapp':
+ this.openAliappService(config);
+ break;
+ default:
+ this.makePhoneCall();
+ }
+ }
+
+ /**
+ * 打开企业微信客服
+ * @param {boolean} useOriginalService 是否使用原有客服方式
+ * @param {Object} servicerConfig 客服配置
+ */
+ openWxworkService(useOriginalService = false, servicerConfig = null, options = {}) {
+ const config = servicerConfig || this.getPlatformConfig();
+ const wxworkConfig = this.getWxworkConfig();
+
+ const {
+ sendMessageTitle = '',
+ sendMessagePath = '',
+ sendMessageImg = ''
+ } = options;
+
+ // #ifdef MP-WEIXIN
+ if (wxworkConfig?.enable && wxworkConfig?.contact_url && !useOriginalService) {
+ // 使用活码链接跳转到企业微信
+ wx.navigateToMiniProgram({
+ appId: 'wxeb490c6f9b154ef9', // 企业微信官方小程序AppID
+ path: `pages/contacts/externalContactDetail?url=${encodeURIComponent(wxworkConfig.contact_url)}`,
+ success: () => {
+ console.log('跳转企业微信成功');
+ },
+ fail: (err) => {
+ console.error('跳转企业微信失败:', err);
+ this.fallbackToOriginalService();
+ }
+ });
+ } else {
+ // 使用原有的客服会话方式
+ wx.openCustomerServiceChat({
+ extInfo: { url: config.wxwork_url },
+ corpId: config.corpid,
+ showMessageCard: true,
+ sendMessageTitle,
+ sendMessagePath,
+ sendMessageImg
+ });
+ }
+ // #endif
+
+ // #ifdef H5
+ if (wxworkConfig?.enable && wxworkConfig?.contact_url) {
+ window.location.href = wxworkConfig.contact_url;
+ } else {
+ location.href = config.wxwork_url;
+ }
+ // #endif
+ }
+
+ /**
+ * 打开第三方客服
+ * @param {Object} config 客服配置
+ */
+ openThirdService(config) {
+ if (config.third_url) {
+ location.href = config.third_url;
+ }
+ }
+
+ /**
+ * 打开牛商客服
+ * @param {Object} niushop 牛商参数
+ */
+ openNiushopService(niushop) {
+ if (Object.keys(niushop).length > 0) {
+ this.vm.$util.redirectTo('/pages_tool/chat/room', niushop);
+ } else {
+ this.makePhoneCall();
+ }
+ }
+
+ /**
+ * 打开微信小程序客服
+ * @param {Object} config 客服配置
+ */
+ openWeappService(config) {
+ // 微信小程序客服会由 open-type="contact" 自动处理
+ console.log('微信小程序客服');
+ }
+
+ /**
+ * 打开支付宝小程序客服
+ * @param {Object} config 客服配置
+ */
+ openAliappService(config) {
+ // 支付宝小程序客服会由 contact-button 组件自动处理
+ console.log('支付宝小程序客服');
+ }
+
+ /**
+ * 拨打电话
+ */
+ makePhoneCall() {
+ this.vm.$api.sendRequest({
+ url: '/api/site/shopcontact',
+ success: res => {
+ if (res.code === 0 && res.data?.mobile) {
+ uni.makePhoneCall({
+ phoneNumber: res.data.mobile
+ });
+ }
+ }
+ });
+ }
+
+ /**
+ * 显示无客服弹窗
+ */
+ showNoServicePopup() {
+ const siteInfo = this.vm.$store.state.siteInfo;
+ const message = siteInfo?.site_tel
+ ? `请联系客服,客服电话是${siteInfo.site_tel}`
+ : '抱歉,商家暂无客服,请线下联系';
+
+ uni.showModal({
+ title: '联系客服',
+ content: message,
+ showCancel: false
+ });
+ }
+
+ /**
+ * 显示配置错误弹窗
+ * @param {Array} errors 错误列表
+ */
+ showConfigErrorPopup(errors) {
+ const message = errors.join('\n');
+ uni.showModal({
+ title: '配置错误',
+ content: `客服配置有误:\n${message}`,
+ showCancel: false
+ });
+ }
+
+ /**
+ * 降级处理:使用原有客服方式
+ */
+ fallbackToOriginalService() {
+ uni.showModal({
+ title: '提示',
+ content: '无法直接添加企业微信客服,是否使用其他方式联系客服?',
+ success: (res) => {
+ if (res.confirm) {
+ console.log('降级处理:使用原有客服方式');
+ this.openWxworkService(true);
+ }
+ }
+ });
+ }
+
+ /**
+ * 获取客服按钮配置
+ * @returns {Object} 按钮配置
+ */
+ getButtonConfig() {
+ const config = this.getPlatformConfig();
+ if (!config) return { openType: '' };
+
+ let openType = '';
+
+ // #ifdef MP-WEIXIN
+ if (config.type === 'weapp') openType = 'contact';
+ // #endif
+
+ // #ifdef MP-ALIPAY
+ if (config.type === 'aliapp') openType = 'contact';
+ // #endif
+
+ return {
+ ...config,
+ openType
+ };
+ }
+}
+
+/**
+ * 创建客服服务实例
+ * @param {Object} vueInstance Vue实例
+ * @returns {CustomerService} 客服服务实例
+ */
+export function createCustomerService(vueInstance) {
+ return new CustomerService(vueInstance);
+}
\ No newline at end of file
diff --git a/components/hover-nav/hover-nav.vue b/components/hover-nav/hover-nav.vue
index c4f38c3..d5a46bf 100644
--- a/components/hover-nav/hover-nav.vue
+++ b/components/hover-nav/hover-nav.vue
@@ -3,17 +3,20 @@
-
@@ -32,186 +27,98 @@
\ No newline at end of file
diff --git a/components/wxwork-contact/CHANGELOG.md b/components/wxwork-contact/CHANGELOG.md
new file mode 100644
index 0000000..bbd49e1
--- /dev/null
+++ b/components/wxwork-contact/CHANGELOG.md
@@ -0,0 +1,66 @@
+# 企业微信联系客服组件更新日志
+
+## v2.0.0 - 集成全局Store配置
+
+### 新增功能
+- ✅ 企业微信配置集成到全局Store
+- ✅ 从 `/api/config/init` 统一获取配置
+- ✅ 支持props覆盖全局配置
+- ✅ 优化配置获取逻辑
+
+### 变更内容
+1. **Store集成**:
+ - 在 `store/index.js` 中添加 `wxworkConfig` 状态
+ - 添加 `setWxworkConfig` mutation
+ - 在 `init` action 中从 `/api/config/init` 获取企业微信配置
+
+2. **组件优化**:
+ - `wxwork-contact.vue` 组件现在优先从全局Store获取配置
+ - 支持通过props覆盖全局配置
+ - 移除单独的API调用,使用统一配置
+
+3. **页面集成**:
+ - `pages/contact/contact.vue` 页面简化配置获取逻辑
+ - 直接使用全局Store中的企业微信配置
+
+### 配置格式
+后端 `/api/config/init` 需要返回以下格式的企业微信配置:
+
+```json
+{
+ "code": 0,
+ "data": {
+ // ... 其他配置 ...
+ "wxwork": {
+ "corp_id": "企业ID",
+ "agent_id": "应用ID",
+ "contact_id": "客服ID",
+ "contact_url": "活码链接",
+ "timestamp": "时间戳",
+ "nonceStr": "随机字符串",
+ "signature": "签名",
+ "enabled": true
+ }
+ }
+}
+```
+
+### 使用方式
+```vue
+
+
+
+
+
+```
+
+## v1.0.0 - 初始版本
+
+### 功能
+- 企业微信JS-SDK封装
+- 基础联系客服组件
+- 支持小程序和H5环境
+- 活码跳转和SDK两种方式
\ No newline at end of file
diff --git a/components/wxwork-contact/README.md b/components/wxwork-contact/README.md
new file mode 100644
index 0000000..ce09d20
--- /dev/null
+++ b/components/wxwork-contact/README.md
@@ -0,0 +1,484 @@
+# 企业微信联系客服组件
+
+## 功能说明
+
+这个组件实现了在小程序中点击"联系客服"后,自动跳转到企业微信添加对应销售的功能。
+
+## 关键前提条件
+
+### ⚠️ 重要提醒
+微信小程序与企业微信互通有严格的平台限制和权限要求,使用前请确保满足以下所有条件:
+
+### 1. 微信小程序环境要求
+- **平台限制**:功能仅在微信小程序环境中可用
+- **基础库版本**:需要微信小程序基础库 2.3.0 及以上版本
+- **用户环境**:用户需要在微信中打开小程序
+
+### 2. 企业微信配置要求
+- **企业认证**:企业微信账号必须完成企业认证
+- **客户联系功能**:需要开通企业微信"客户联系"功能
+- **应用权限**:企业微信应用需要有客户联系相关权限
+
+### 3. 互通配置要求
+- **关联配置**:小程序必须与企业微信进行关联配置
+- **权限申请**:需要在微信开放平台和企业微信后台分别申请相应权限
+- **域名白名单**:相关域名需要在小程序和企业微信后台都配置白名单
+
+### 4. 跳转权限要求
+- **小程序AppID**:需要在企业微信中配置允许跳转的小程序AppID
+- **企业微信AppID**:需要在微信开放平台配置关联的企业微信AppID
+- **业务域授权**:需要配置业务域授权,允许跨平台跳转
+
+### 5. 开发调试要求
+- **测试环境**:需要在测试环境中验证跳转功能
+- **权限验证**:确保所有必要的API权限已申请并生效
+- **兼容性测试**:在不同微信版本中进行兼容性测试
+
+### 6. 具体配置要求
+
+| 条件 | 说明 |
+|------|------|
+| **小程序与企业微信绑定** | 在企业微信管理后台 → 「应用管理」→「小程序」中关联你的微信小程序AppID |
+| **配置可信域名** | 如果涉及网页跳转或回调,需在企业微信后台配置业务域名 |
+| **使用企业微信服务商 or 自建应用** | 若需高级功能(如获取客户详情),需有企业微信管理员权限或通过服务商代开发 |
+
+## 使用方法
+
+### 1. 基础用法
+
+```vue
+
+
+```
+
+### 组件架构
+
+### 分层设计
+```
+调用方 (页面组件)
+ ↓ 传递配置参数
+wxwork-contact 组件
+ ↓ 调用SDK
+wxwork-jssdk.js
+ ↓ 调用企业微信API
+企业微信服务
+```
+
+### 组件设计原则
+
+- **独立性**:组件不直接依赖全局Store,所有配置通过props传递
+- **职责分离**:组件只负责UI展示和企业微信SDK调用,配置管理由调用方负责
+- **灵活配置**:支持调用者覆盖任何配置参数
+
+## 版本信息
+
+### v3.0.0 - 统一客服服务重构版本
+- 创建 `CustomerService` 统一客服处理服务
+- 重构 `ns-contact.vue` 和 `hover-nav.vue` 消除重复代码
+- 提供统一的客服处理接口和平台适配
+- 完善错误处理和降级机制
+- 支持所有客服类型的统一调用
+
+### v2.0.0 - Store集成版本
+- 企业微信配置集成到全局Store
+- 从 `/api/config/init` 统一获取配置
+- 组件完全独立,通过props接收配置
+- 支持全局配置和局部覆盖
+
+### v1.0.0 - 初始版本
+- 基础企业微信联系功能
+- 支持活码跳转和JS-SDK两种方式
+
+### 2. 属性说明
+
+| 属性 | 类型 | 默认值 | 说明 |
+|------|------|--------|------|
+| btnText | String | '添加企业微信客服' | 按钮文字 |
+| corpId | String | - | 企业ID(必需) |
+| agentId | String | '' | 应用ID |
+| timestamp | String | '' | 时间戳 |
+| nonceStr | String | '' | 随机字符串 |
+| signature | String | '' | 签名 |
+| contactId | String | '' | 客服ID或活码配置ID |
+| contactUrl | String | '' | 活码链接 |
+| showConfirm | Boolean | true | 是否显示确认弹窗 |
+
+### 3. 在联系页面中使用
+
+在 `pages/contact/contact.vue` 中已集成使用示例:
+
+```vue
+
+
+```
+
+## 配置说明
+
+### 后端接口需求
+
+企业微信配置已集成到 `/api/config/init` 接口中,返回以下格式的数据:
+
+```json
+{
+ "code": 0,
+ "data": {
+ // ... 其他配置 ...
+ "wxwork": {
+ "corp_id": "企业ID",
+ "agent_id": "应用ID",
+ "contact_id": "客服ID",
+ "contact_url": "活码链接",
+ "timestamp": "时间戳",
+ "nonceStr": "随机字符串",
+ "signature": "签名",
+ "enabled": true
+ }
+ }
+}
+```
+
+### 全局Store集成
+
+企业微信配置通过以下方式集成到全局状态管理:
+
+1. **Store状态**:在 `store/index.js` 中添加 `wxworkConfig` 状态
+2. **配置获取**:在 `init` action 中从 `/api/config/init` 获取企业微信配置
+3. **状态更新**:使用 `setWxworkConfig` mutation 更新配置
+4. **持久化**:配置自动保存到本地存储
+
+### 企业微信配置步骤
+
+1. **获取企业微信活码**:
+ - 登录企业微信管理后台
+ - 进入"客户联系" -> "配置" -> "联系我"
+ - 创建活码,获取配置ID或直接获取活码链接
+
+2. **配置参数**:
+ - `corp_id`: 企业ID(在企业微信后台获取)
+ - `agent_id`: 企业微信应用ID
+ - `contact_id`: 客服的用户ID
+ - `contact_url`: 企业微信活码链接(推荐使用活码链接)
+ - `timestamp`: 生成签名的时间戳
+ - `nonceStr`: 生成签名的随机字符串
+ - `signature`: JS-SDK签名
+
+## 典型业务流程示例
+
+### 目标
+用户在小程序中点击"联系客服",自动添加对应的企业微信销售。
+
+### 步骤
+1. **后端调用企业微信 API** 创建「联系我」二维码(可带场景值,如 user_id=123)。
+2. **前端在小程序中展示该二维码(或生成跳转链接)**。
+3. **用户长按识别 → 打开企业微信 → 添加客服**。
+4. **企业微信收到添加事件 → 通过 API 获取 external_userid → 关联到原小程序用户**。
+
+## 实现原理
+
+### 方案1:企业微信活码跳转(推荐)
+- 使用企业微信活码链接
+- 通过 `uni.navigateToMiniProgram` 跳转到企业微信小程序
+- 直接添加对应的销售为联系人
+
+### 方案2:JS-SDK方式
+- 使用企业微信JS-SDK
+- 调用 `openUserProfile` 接口打开用户资料
+- 用户手动添加联系人
+
+## 注意事项
+
+### 功能限制
+1. **小程序环境**:需要在微信小程序环境中使用
+2. **权限配置**:确保小程序有跳转企业微信的权限
+3. **降级处理**:当企业微信不可用时,会降级到原有客服方式
+4. **用户体验**:建议添加确认弹窗,避免误操作
+
+### 前提条件验证
+5. **权限检查**:使用前需要验证所有必需权限是否生效
+6. **配置完整性**:确保所有配置参数都已正确设置
+7. **网络环境**:确保用户网络环境允许访问企业微信服务
+8. **版本兼容**:检查微信版本和企业微信版本兼容性
+
+### 调试建议
+9. **错误监控**:添加适当的错误日志和用户反馈机制
+10. **性能优化**:避免频繁的SDK初始化和配置获取
+11. **安全考虑**:敏感配置信息应在服务端处理,前端不暴露
+
+## 兼容性
+
+- 微信小程序:✅ 支持
+- H5环境:✅ 支持跳转活码链接
+- 其他平台:降级处理
+
+## 文件结构
+
+```
+components/wxwork-contact/
+├── wxwork-contact.vue # 主组件
+└── README.md # 说明文档
+
+components/ns-contact/
+└── ns-contact.vue # 统一客服组件(重构后)
+
+components/hover-nav/
+└── hover-nav.vue # 悬浮导航组件(重构后)
+
+common/js/
+├── wxwork-jssdk.js # 企业微信JS-SDK封装
+└── customer-service.js # 客服统一处理服务(新增)
+
+store/
+└── index.js # 全局Store,包含wxworkConfig状态管理
+
+pages/contact/
+└── contact.vue # 联系页面,集成企业微信功能
+```
+
+## 系统梳理与优化 (v3.1.0)
+
+### 🔧 已修复的问题
+
+#### 1. **App.vue 配置恢复**
+- ✅ 修复了企业微信配置 (`wxworkConfig`) 在应用启动时的恢复
+- ✅ 确保所有配置都能正确从本地存储恢复到Store
+
+#### 2. **客服服务参数传递**
+- ✅ 修复了 `openCustomerServiceChat` 参数传递错误
+- ✅ 正确传递 `sendMessageTitle`、`sendMessagePath`、`sendMessageImg`
+
+#### 3. **组件配置访问**
+- ✅ 在 `ns-contact.vue` 和 `hover-nav.vue` 中添加 computed 属性
+- ✅ 确保能够正确访问 `servicerConfig`
+
+#### 4. **企业微信服务优化**
+- ✅ 改进参数传递,支持自定义消息参数
+- ✅ 统一处理函数调用方式
+
+### 🛡️ 新增功能
+
+#### 1. **配置验证机制**
+```javascript
+const validation = this.customerService.validateConfig();
+if (!validation.isValid) {
+ // 处理配置错误
+}
+```
+
+#### 2. **错误处理增强**
+- ✅ 添加配置错误弹窗
+- ✅ 改进错误日志记录
+- ✅ 警告信息提示
+
+#### 3. **类型安全**
+- ✅ 完善参数类型检查
+- ✅ 空值和异常情况处理
+
+### 📋 当前系统状态
+
+| 组件 | 状态 | 功能完整性 |
+|------|------|-----------|
+| **customer-service.js** | ✅ 完成 | 统一客服处理服务 |
+| **ns-contact.vue** | ✅ 修复 | 支持所有客服类型 |
+| **hover-nav.vue** | ✅ 修复 | 集成统一客服服务 |
+| **App.vue** | ✅ 修复 | 配置完整恢复 |
+| **contact.vue** | ⚠️ 待优化 | 仍使用原始方式 |
+
+### 🔄 待优化项
+
+#### 1. **contact.vue 页面重构**
+- 建议集成统一客服服务
+- 添加企业微信客服按钮
+- 统一UI交互体验
+
+#### 2. **加载状态反馈**
+- 客服功能调用时的loading状态
+- 网络请求的进度指示
+
+#### 3. **用户体验优化**
+- 客服按钮的点击反馈
+- 错误状态的友好提示
+
+### 🧪 测试建议
+
+1. **配置验证测试**:
+ - 测试各种配置缺失情况
+ - 验证错误提示准确性
+
+2. **平台兼容测试**:
+ - 微信小程序客服功能
+ - H5环境跳转
+ - 支付宝小程序客服
+
+3. **企业微信功能测试**:
+ - 活码链接跳转
+ - 降级处理机制
+ - 参数传递正确性
+
+### 📖 使用最佳实践
+
+```javascript
+// 推荐使用方式
+const customerService = createCustomerService(this);
+
+// 带配置验证的调用
+if (customerService.isConfigAvailable()) {
+ customerService.handleCustomerClick({
+ sendMessageTitle: '商品咨询',
+ sendMessagePath: '/pages/goods/detail',
+ sendMessageImg: 'product-image.jpg'
+ });
+}
+```
+
+## 重构说明 (v3.0.0)
+
+### 统一客服处理服务
+
+为了解决代码重复问题,我们创建了 `CustomerService` 类来统一处理所有客服逻辑:
+
+#### 主要改进
+1. **代码复用**:消除 `ns-contact.vue` 和 `hover-nav.vue` 中的重复代码
+2. **统一接口**:提供一致的客服处理API
+3. **平台适配**:自动处理不同平台的客服配置
+4. **类型安全**:完善的错误处理和降级机制
+
+#### 使用方式
+
+**1. 在组件中导入**
+```javascript
+import { createCustomerService } from '@/common/js/customer-service.js';
+```
+
+**2. 初始化服务**
+```javascript
+created() {
+ this.customerService = createCustomerService(this);
+ this.buttonConfig = this.customerService.getButtonConfig();
+}
+```
+
+**3. 处理客服点击**
+```javascript
+methods: {
+ contactServicer() {
+ this.customerService.handleCustomerClick({
+ niushop: this.niushop,
+ sendMessageTitle: this.sendMessageTitle,
+ sendMessagePath: this.sendMessagePath,
+ sendMessageImg: this.sendMessageImg
+ });
+ }
+}
+```
+
+#### 核心方法
+
+| 方法名 | 用途 | 参数 |
+|--------|------|------|
+| `handleCustomerClick(options)` | 统一处理客服点击 | 客服配置选项 |
+| `getButtonConfig()` | 获取按钮配置 | - |
+| `getServiceType()` | 获取客服类型 | - |
+| `openWxworkService()` | 打开企业微信客服 | 是否使用原方式 |
+
+#### 支持的客服类型
+
+- `wxwork` - 企业微信客服
+- `third` - 第三方客服
+- `niushop` - 牛商客服
+- `weapp` - 微信小程序客服
+- `aliapp` - 支付宝小程序客服
+- `none` - 无客服(显示提示)
+
+## 常见问题 (FAQ)
+
+### Q: contact_id 是小程序ID吗?
+A: 不是的。`contact_id` 是**企业微信中客服人员的用户ID**,具体说明如下:
+
+- **定义**:企业微信系统内部分配给客服人员的唯一标识符
+- **获取方式**:通过企业微信管理后台的"客户联系" → "配置" → "联系我"功能创建活码时获得
+- **用途**:用于指定具体客服人员,当用户点击"联系客服"时,系统通过这个ID知道应该添加哪个企业微信客服人员
+
+### Q: contact_id 和小程序ID的区别?
+A: 两者的作用完全不同:
+
+| 字段 | 用途 | 获取方式 |
+|------|------|----------|
+| **contact_id** | 指定具体的企业微信客服人员 | 企业微信管理后台获取 |
+| **小程序AppID** | 识别整个微信小程序应用 | 微信开放平台获取 |
+
+在业务流程中:
+1. 用户在小程序中点击"联系客服"
+2. 系统使用 `contact_id` 打开对应的企业微信客服人员资料
+3. 用户添加该企业微信客服为联系人
+
+所以 `contact_id` 是企业微信客服的ID,不是小程序的ID。
+
+### Q: wxwork_contact_url 从哪里来?
+A: `wxwork_contact_url` 应该来自全局Store中的 `wxworkConfig`,而不是 `servicerConfig`:
+
+**正确的配置来源**:
+- ✅ `this.$store.state.wxworkConfig.contact_url` - 企业微信配置
+- ❌ `this.config.wxwork_contact_url` - 错误的配置路径
+
+**配置获取流程**:
+1. **后端接口**:`/api/config/init` 返回 `wxwork_config` 数据
+2. **Store存储**:`setWxworkConfig` 将配置保存到 `wxworkConfig` 状态
+3. **组件使用**:通过 `this.$store.state.wxworkConfig.contact_url` 访问
+
+**代码修正示例**:
+```javascript
+// 错误 ❌
+if (this.config.wxwork_contact_url) { ... }
+
+// 正确 ✅
+const wxworkConfig = this.$store.state?.wxworkConfig;
+if (wxworkConfig?.contact_url) { ... }
+```
+
+**字段对应关系**:
+| 后端字段 | Store字段 | 组件使用 |
+|---------|----------|----------|
+| `contact_url` | `contact_url` | `wxworkConfig.contact_url` |
+
+### Q: navigateToMiniProgram 中的企业微信小程序AppID 是指我的业务小程序ID吗?
+A: 不是的!`appId: 'wxeb490c6f9b154ef9'` 是**企业微信官方小程序的AppID**,不是你的业务小程序ID。
+
+**两者的区别**:
+
+| 小程序类型 | AppID示例 | 用途 | 所有者 |
+|-----------|----------|------|--------|
+| **企业微信官方小程序** | `wxeb490c6f9b154ef9` | 展示企业联系人详情页面 | 腾讯企业微信团队 |
+| **你的业务小程序** | 你的AppID | 你的业务功能(电商、服务等) | 你的企业/组织 |
+
+**业务流程**:
+```
+用户小程序 (你的业务)
+ ↓ 点击"联系客服"
+navigateToMiniProgram 跳转到
+企业微信官方小程序 (wxeb490c6f9b154ef9)
+ ↓ 展示联系人详情
+用户添加客服人员到企业微信
+```
+
+**关键点**:
+- 这个AppID是企业微信官方小程序,通常是固定值
+- 用于跳转到企业微信环境展示联系人详情
+- 不需要替换成你自己的小程序AppID |
\ No newline at end of file