提交 06395647 作者: 毛细亚

同步代码

上级 dff3a150
---
description:
globs:
alwaysApply: false
alwaysApply: true
---
# 项目结构说明
这是一个 H5的移动端页面 这是一个 H5的移动端页面 最大宽度是 380px 最小宽度是 360px 样所以需要用到 css 自适应 弹性伸缩
......@@ -46,14 +46,13 @@ alwaysApply: false
- 使用 try/catch 块处理异步操作
- 使用组件化的概念 尽量按照功能切分成多个组件 一个组件的代码不要太多
工程化要求:
- ESLint + Prettier
- 性能优化
- 代码分割
- 懒加载实现
# UI 规范
因为 企业微信侧边栏 宽度有限 而且是一个 H5 移动端的页面 最大宽度是 380px 最小宽度 是 360px 所以尽量使用 自适应的样式来进行开发
因为 企业微信侧边栏 宽度有限 而且是一个 H5 的页面 最大宽度是 360px 用自适应样式来构建页面 不要用超过 360px 的宽度
---
description:
globs:
alwaysApply: false
---
---
description:
globs:
alwaysApply: true
---
---
description:
globs:
alwaysApply: false
---
# 企业微信 SDK 使用指南
## 📋 概述
企业微信初始啊的相关方法已封装到 Vuex `user` 模块中,提供了简洁的 API 和 Promise 支持。
企微微信的发送消息的方法 已封状态 `@/utils/index.js` 的 `sendChatMessage` 方法中 通过 type 参数来区分发送消息的类型
## 1. 企微微信 jssdk 初始化 只有在初始化成功以后才可以调用 企业微信的 jssdk 的相关 api
因为 jssdk 的签名的时候 和 path 有关 path 就是当前页面的 url 地址 所以当路由变化的时候
如果想在当前的路由页面 调用 企微 jssdk 的相关 api 就需要 重新 初始化 企微 jssdk 初始化 方法 在 1.4 中
注意:当前想要调用企微 jssdk 的相关 api 的时候 需要判断企微 jssdk 在当前路由页面 是否已经初始化成功 如果没有 你需要重新初始化
### 1.1 `getWecomSignature` - 获取企业微信签名
```javascript
// 自动获取签名(使用当前页面和缓存的 corp_id)
const signData = await this.getWecomSignature()
// 指定参数获取签名
const signData = await this.getWecomSignature({
corp_id: 'your_corp_id',
path: 'https://your-domain.com/path'
})
```
### 1.2 `registerWecomSDK` - 注册企业微信 SDK
```javascript
// 使用已获取的签名数据注册
const registerResult = await this.registerWecomSDK(signData)
// 或者使用 state 中的签名数据
const registerResult = await this.registerWecomSDK()
```
### 1.3 `initWecom` - 一键初始化(推荐)
```javascript
// 完整初始化(获取签名 + 注册 SDK)
try {
const result = await this.initWecom()
console.log('初始化成功:', result)
// result 包含:{ signData, registerResult, success: true }
} catch (error) {
console.error('初始化失败:', error)
}
```
### 1.4 🚀 使用方法
#### 在组件中使用
```javascript
import { mapActions, mapState } from 'vuex'
export default {
computed: {
...mapState('user', ['isWecomSDKReady', 'signData'])
},
methods: {
// 映射 Vuex actions
...mapActions('user', [
'getWecomSignature',
'registerWecomSDK',
'initWecom'
]),
// 初始化企业微信
async initializeWecom() {
try {
const result = await this.initWecom()
// 注册成功后的操作
this.onWecomReady(result.registerResult)
} catch (error) {
console.error('初始化失败:', error)
this.$message.error('企业微信初始化失败')
}
},
// SDK 准备就绪后的回调
onWecomReady(registerResult) {
console.log('企业微信 SDK 已准备就绪')
// 现在可以安全地使用企业微信 API
this.openEnterpriseChat()
this.getCurExternalContact()
// ... 其他企业微信 API 调用
},
// 检查 SDK 是否已准备就绪
checkSDKReady() {
if (this.isWecomSDKReady) {
console.log('SDK 已准备就绪')
return true
} else {
console.log('SDK 尚未准备就绪')
return false
}
}
},
// 在组件挂载时初始化
async mounted() {
await this.initializeWecom()
}
}
```
#### 在页面中使用
```javascript
// 在 login.vue、quickReply.vue 等页面中
export default {
async created() {
// 替代原有的 getSignature() 调用
await this.initializeWecom()
},
methods: {
...mapActions('user', ['initWecom']),
async initializeWecom() {
try {
const result = await this.initWecom()
console.log('企业微信初始化成功')
// 执行需要在 SDK 注册成功后的操作
this.handleWecomReady()
} catch (error) {
console.error('企业微信初始化失败:', error)
}
},
handleWecomReady() {
// 原来在 onAgentConfigSuccess 中的逻辑
this.getCurExternalContact()
// ... 其他操作
}
}
}
```
## 📊 状态管理
新增的 state:
```javascript
// user store 中的状态
{
signData: {}, // 企业微信签名数据
isWecomSDKReady: false // SDK 是否已准备就绪
}
```
## ✅ 优势
1. **统一管理**:所有企业微信相关逻辑集中在 Vuex 中
2. **Promise 支持**:注册成功/失败都会返回 Promise
3. **状态追踪**:可以通过 `isWecomSDKReady` 检查 SDK 状态
4. **错误处理**:统一的错误处理机制
5. **复用性**:多个组件可以共享同一套初始化逻辑
## 🎉 示例项目
参考 `skillPersonal.vue` 和 `quickReply.vue` 和 `sendGame.vue`中的实现方式。
# 2. 调用 企微微信发送消息接口 `ww.sendChatMessage`
## 2.1 在企业微信 jssdk 初始化成功后 我们就可以使用 jssdk api 了 当使用 `ww.sendChatMessage` api 时 我们简单封装了一下 这个 api的使用方法
```js
import {sendChatMessage} form '@/utils/index,js'
```
直接使用即可 以下是文档的具体说明
### 2.2 企业微信发送消息 API 参数文档
本文档描述了 `sendChatMessage` 函数的使用方法,该函数封装了企业微信 JSSDK 的 `ww.sendChatMessage` API,用于向客户发送各种类型的消息。
### 2.3 函数签名
```javascript
/**
* 向企业微信客户发送消息
* @param {string|object} content - 消息内容,根据消息类型不同而不同
* @param {string} type - 消息类型,支持 'text'、'link'、'image'、'miniprogram'、'video'、'file'
* @return {object} messageInfo - 消息发送相关信息
*/
async function sendChatMessage(content, type) { ... }
```
### 2.4 使用方法
```javascript
import { sendChatMessage } from '@/utils/index.js'
// 发送文本消息
await sendChatMessage('这是一条文本消息', 'text')
// 发送其他类型消息
// ...
```
### 2.5 支持的消息类型
#### 2.5.1 文本消息 (text)
```javascript
// content 参数为字符串
await sendChatMessage('这是一条文本消息', 'text')
```
#### 2.5.2 图文消息 (link)
```javascript
// content 参数为对象数组
await sendChatMessage({
articles: [
{
title: '图文消息标题',
desc: '图文消息描述',
url: 'https://example.com/news',
picurl: 'https://example.com/image.jpg'
}
// 可以有多个图文项
]
}, 'link')
```
#### 2.5.3 图片消息 (image)
```javascript
// content 参数为图片URL
await sendChatMessage('https://example.com/image.jpg', 'image')
```
#### 2.5.4 小程序消息 (miniprogram)
```javascript
// content 参数为对象
await sendChatMessage({
appid: 'wx123456789abcdef', // 小程序的appid
title: '小程序消息标题', // 小程序消息的标题
imgurl: 'https://example.com/image.jpg', // 小程序消息的图片
page: 'pages/index/index' // 小程序的页面路径
}, 'miniprogram')
```
#### 2.5.5 视频消息 (video)
```javascript
// content 参数为视频URL
await sendChatMessage('https://example.com/video.mp4', 'video')
```
### 2.5.6 文件消息 (file)
```javascript
// content 参数为文件URL
await sendChatMessage('https://example.com/document.pdf', 'file')
```
## 返回值说明
函数返回一个包含以下字段的对象:
```javascript
{
frontend_message_id: '唯一消息ID',
session_id: '会话ID',
message: content, // 原始消息内容
message_type: type, // 消息类型
timestamp: 1698123456789, // 发送时间戳
success: true/false, // 是否发送成功
response: {}, // 成功回调的响应数据
error: {} // 失败回调的错误数据
}
```
## 注意事项
1. 对于媒体类型消息(图片、视频、文件),系统会自动获取媒体ID
2. 媒体文件大小有限制,请参考企业微信开发文档
3. 所有消息发送都是异步的,返回值中的 `success` 字段仅表示请求是否成功发出
4. 在调用此函数前,确保企业微信 JSSDK 已经初始化成功
## 错误处理
函数内部会处理常见错误,并通过 Element UI 的 Message 组件显示错误提示。对于媒体ID获取失败等错误,会在返回值的 `error` 字段中提供详细信息。
## 相关依赖
- `@wecom/jssdk`:企业微信官方 JSSDK
- `@/api/works`:用于获取媒体ID的API
- `element-ui`:用于显示错误提示
# 1.侧边栏1.2版本的需求文档
# 1.侧边栏1.2版本的需求文档
需要用到的接口引入地址如下
```javascript
import {getClientStatus,remarkSessionIntelTag,finishRest,client_session_rest,checkSingleAgree,checkUserPermit,sendComment} from '@/api/user.js'
```
`getClientStatus`:获取用户的休息状态
`finishRest`:结束休息
`client_session_rest`:开始休息
`checkSingleAgree`:客户是否同意聊天内容存档
`checkUserPermit`:客服号是否开启会话会话内容存档
`remarkSessionIntelTag`:同步智能标签
页面原型图 是 [原型图片]('./images/侧边栏1.2.png')
## 1.1 新增客服休息状态
`src/views/userInfo/components/Info.vue` 新增一个休息中 和 开始休息的按钮状态
在 Info.vue 初始化的时候 调用以下接口 获取初始数据
1.获取客服的休息状态 通过接口 `getClientStatus` 获取用户的休息状态 不需要传入任何参数 返回 的数据 res.data.client_online_status
`client_online_status:` online上线 offline下线 rest休息中 保存在 vuex 中的 user 模块中 以后会用到的
2.调用 remarkSessionIntelTag 同步智能标签 同步智能标签的接口 `remarkSessionIntelTag` 传入参数 `corp_id` `external_userid` `userid` 从 vuex 中 获取参数 不需要保存 接口返回的值 只同步一下标签接口
3. 调用 `checkSingleAgree` 接口 获取用户 是否同步开启聊天内容 存档 传入参数 `external_userid` `userid` 返回的值在 Info.vue 中保存起来 以后会用到的 返回的值是 res.data.agree_status Agreen同意 Disagree不同意 在页面显示 当前微信用户未(已)开启会话内容存档
4. 调用 `checkUserPermit` 接口 获取客服号是否开启获取会话内容存档 传入参数 `userid` 返回的值在 Info.vue 中保存起来 以后会用到的 返回的值是 res.data.has_permit true 有 权限 false 无权限 在页面显示 当前客服号未(已)授权会话内容存档
上面的接口 中 需要在 created 的时候调用 进入页面的时候 就可以调用
5.获取客服的休息状态后 如果是休息中 显示结束休息 按钮 此时不能下线 必须先结束休息 结束休息 接口 `finishRest`
如果是在线状态 显示开始休息按钮 开始休息按钮 鼠标悬浮 显示 文字 `午休或者临时有事可点击休息` 点击 调用接口 `client_session_rest` 开始休息状态
6. `sendComment` 发送评价接口: 在休息按钮旁边 新增一个发送评价按钮 点击发送评价 调用 sendComment 接口 传入 参数 传入参数 `corp_id` `external_userid` `userid` 从 vuex 中 获取参数 返回的数据中 res.data.news 是发送评价的内容
6.1. 发送评价需要调用 企业微信的 jssdk 中 的 `ww.sendChatMessage` 在调用 企微页面的 jssdk 之前 需要 先签名授权当前的 url 地址 所以需要先进行以下操作
6.2. 先初始化 企业微信的 jssdk 之前已经封装过了 调用代码如下
```javascript
created() {
this.initializeWecom()
},
methods: {
...mapActions('user', ['initWecom']),
async initializeWecom() {
try {
console.log('🚀 开始初始化企业微信 SDK')
const result = await this.initWecom()
console.log('✅ 企业微信 SDK 初始化成功', result)
} catch (error) {
console.error('❌ 企业微信 SDK 初始化失败:', error)
}
},
}
```
6.3. 企业微信的 jssdk 初始化成功后 可以开始 调用 `ww.sendChatMessage` 这个方法的经过二次封载 在 `src/utils/index.js` 中 代码如下
```javascript
improt {sendChatMessage} from '@/utils/index.js'
sendChatMessage(res.data.news , 'news')
```
拿到之前 发送评价接口返回的数据 就可以发送评价了
\ No newline at end of file
# 企业微信发送消息 API 参数文档
本文档描述了 `sendChatMessage` 函数的使用方法,该函数封装了企业微信 JSSDK 的 `ww.sendChatMessage` API,用于向客户发送各种类型的消息。
## 函数签名
```javascript
/**
* 向企业微信客户发送消息
* @param {string|object} content - 消息内容,根据消息类型不同而不同
* @param {string} type - 消息类型,支持 'text'、'link'、'image'、'miniprogram'、'video'、'file'
* @return {object} messageInfo - 消息发送相关信息
*/
async function sendChatMessage(content, type) { ... }
```
## 使用方法
```javascript
import { sendChatMessage } from '@/utils/index.js'
// 发送文本消息
await sendChatMessage('这是一条文本消息', 'text')
// 发送其他类型消息
// ...
```
## 支持的消息类型
### 1. 文本消息 (text)
```javascript
// content 参数为字符串
await sendChatMessage('这是一条文本消息', 'text')
```
### 2. 图文消息 (link)
```javascript
// content 参数为对象数组
await sendChatMessage({
articles: [
{
title: '图文消息标题',
desc: '图文消息描述',
url: 'https://example.com/news',
picurl: 'https://example.com/image.jpg'
}
// 可以有多个图文项
]
}, 'link')
```
### 3. 图片消息 (image)
```javascript
// content 参数为图片URL
await sendChatMessage('https://example.com/image.jpg', 'image')
```
### 4. 小程序消息 (miniprogram)
```javascript
// content 参数为对象
await sendChatMessage({
appid: 'wx123456789abcdef', // 小程序的appid
title: '小程序消息标题', // 小程序消息的标题
imgurl: 'https://example.com/image.jpg', // 小程序消息的图片
page: 'pages/index/index' // 小程序的页面路径
}, 'miniprogram')
```
### 5. 视频消息 (video)
```javascript
// content 参数为视频URL
await sendChatMessage('https://example.com/video.mp4', 'video')
```
### 6. 文件消息 (file)
```javascript
// content 参数为文件URL
await sendChatMessage('https://example.com/document.pdf', 'file')
```
## 返回值说明
函数返回一个包含以下字段的对象:
```javascript
{
frontend_message_id: '唯一消息ID',
session_id: '会话ID',
message: content, // 原始消息内容
message_type: type, // 消息类型
timestamp: 1698123456789, // 发送时间戳
success: true/false, // 是否发送成功
response: {}, // 成功回调的响应数据
error: {} // 失败回调的错误数据
}
```
## 注意事项
1. 对于媒体类型消息(图片、视频、文件),系统会自动获取媒体ID
2. 媒体文件大小有限制,请参考企业微信开发文档
3. 所有消息发送都是异步的,返回值中的 `success` 字段仅表示请求是否成功发出
4. 在调用此函数前,确保企业微信 JSSDK 已经初始化成功
## 错误处理
函数内部会处理常见错误,并通过 Element UI 的 Message 组件显示错误提示。对于媒体ID获取失败等错误,会在返回值的 `error` 字段中提供详细信息。
## 相关依赖
- `@wecom/jssdk`:企业微信官方 JSSDK
- `@/api/works`:用于获取媒体ID的API
- `element-ui`:用于显示错误提示
\ No newline at end of file
# 企业微信客户端侧边栏应用开发
......@@ -43,4 +43,5 @@ import {getParams} from '@/utils/index.js'
获取 url 后面的参数 储存在 vuex 中
本项目中会经历两次页面回调 一次是企微的授权验证回调 一次是 钉钉登录成功的回调 回调页面必须在首页完成 因为这个回调地址已经配置过了 钉钉回调成功后 页面 url 上会带一个 type=ding 的参数 需要根据这个参数来判断 是钉钉回调还是企微回调 如果是钉钉的回调 表明 微信授权的逻辑已经完成了 可以直接去 首页了
\ No newline at end of file
本项目中会经历两次页面回调 一次是企微的授权验证回调 一次是 钉钉登录成功的回调 回调页面必须在首页完成 因为这个回调地址已经配置过了 钉钉回调成功后 页面 url 上会带一个 type=ding 的参数 需要根据这个参数来判断 是钉钉回调还是企微回调 如果是钉钉的回调 表明 微信授权的逻辑已经完成了 可以直接去 首页了
# 企业微信 SDK 使用指南
---
---
description:
globs:
alwaysApply: false
---
# 企业微信 SDK 使用指南
## 📋 概述
企业微信相关方法已封装到 Vuex `user` 模块中,提供了简洁的 API 和 Promise 支持。
企业微信初始啊的相关方法已封装到 Vuex `user` 模块中,提供了简洁的 API 和 Promise 支持。
企微微信的发送消息的方法 已封状态 `@/utils/index.js``sendChatMessage` 方法中 通过 type 参数来区分发送消息的类型
## 🎯 可用的 Actions
## 1. 企微微信 jssdk 初始化 只有在初始化成功以后才可以调用 企业微信的 jssdk 的相关 api
### 1. `getWecomSignature` - 获取企业微信签名
因为 jssdk 的签名的时候 和 path 有关 path 就是当前页面的 url 地址 所以当路由变化的时候
如果想在当前的路由页面 调用 企微 jssdk 的相关 api 就需要 重新 初始化 企微 jssdk 初始化 方法 在 1.4 中
注意:当前想要调用企微 jssdk 的相关 api 的时候 需要判断企微 jssdk 在当前路由页面 是否已经初始化成功 如果没有 你需要重新初始化
### 1.1 `getWecomSignature` - 获取企业微信签名
```javascript
// 自动获取签名(使用当前页面和缓存的 corp_id)
......@@ -19,7 +31,7 @@ const signData = await this.getWecomSignature({
})
```
### 2. `registerWecomSDK` - 注册企业微信 SDK
### 1.2 `registerWecomSDK` - 注册企业微信 SDK
```javascript
// 使用已获取的签名数据注册
......@@ -29,7 +41,7 @@ const registerResult = await this.registerWecomSDK(signData)
const registerResult = await this.registerWecomSDK()
```
### 3. `initWecom` - 一键初始化(推荐)
### 1.3 `initWecom` - 一键初始化(推荐)
```javascript
// 完整初始化(获取签名 + 注册 SDK)
......@@ -42,9 +54,9 @@ try {
}
```
## 🚀 使用方法
### 1.4 🚀 使用方法
### 在组件中使用
#### 在组件中使用
```javascript
import { mapActions, mapState } from 'vuex'
......@@ -105,7 +117,7 @@ export default {
}
```
### 在页面中使用
#### 在页面中使用
```javascript
// 在 login.vue、quickReply.vue 等页面中
......@@ -160,41 +172,13 @@ export default {
4. **错误处理**:统一的错误处理机制
5. **复用性**:多个组件可以共享同一套初始化逻辑
## 🔄 迁移指南
### 原有代码:
```javascript
// 旧的方式
async getSignature() {
const res = await getSignature({ corp_id, path })
this.registerWeComSDK(res.data)
}
registerWeComSDK(signData) {
this.$ww.register({
// ... 配置
onAgentConfigSuccess: (res) => {
console.log('注册成功')
// 执行后续操作
}
})
}
```
## 🎉 示例项目
### 新代码:
```javascript
// 新的方式
async initializeWecom() {
try {
const result = await this.initWecom()
console.log('注册成功')
// 执行后续操作
} catch (error) {
console.error('注册失败')
}
}
```
参考 `skillPersonal.vue``quickReply.vue``sendGame.vue`中的实现方式。
## 🎉 示例项目
参考 `skillPersonal.vue``quickReply.vue` 中的实现方式。
\ No newline at end of file
# 2. 调用 企微微信发送消息接口 `ww.sendChatMessage`
## 2.1 在企业微信 jssdk 初始化成功后
......@@ -47,7 +47,6 @@ export function uploadCos(params) {
params
})
}
// 请求企业配置
export function companyviewConfig(data) {
return request({
......@@ -64,4 +63,68 @@ export function logout(data) {
data
})
}
// 客户是否同意聊天内容存档
export function checkSingleAgree(data) {
return request({
url: '/sidebar/external_user/checkSingleAgree',
method: 'post',
data
})
}
// 客服号是否开启会话会话内容存档
export function checkUserPermit(data) {
return request({
url: '/sidebar/external_user/checkUserPermit',
method: 'post',
data
})
}
// 发送评价
export function sendComment(data) {
return request({
url: '/sidebar/client_session/sendComment',
method: 'post',
data
})
}
// 休息
// 导出一个名为rest的函数,接收一个参数data
export function client_session_rest(data) {
// 发送一个post请求,请求的url为'/sidebar/client_session/rest',请求的数据为data
return request({
url: '/sidebar/client_session/rest',
method: 'post',
data
})
}
// 结束休息
export function finishRest(data) {
return request({
url: '/sidebar/work_wei_xin/finishRest',
method: 'post',
data
})
}
// 客户智能标签打标
export function remarkSessionIntelTag(data) {
return request({
url: '/sidebar/client_session/remarkSessionIntelTag',
method: 'post',
data
})
}
// 获取客户号的休息状态
export function getClientStatus(data) {
return request({
url: '/sidebar/work_wei_xin/getClientStatus',
method: 'post',
data
})
}
......@@ -781,6 +781,82 @@ export async function sendChatMessage(content, type) {
messageInfo.error = err
}
}
} else if (type === 'video') {
// 发送视频消息
if (content) {
try {
const res = await getMediaId({ url: content })
if (res.status_code == 1) {
messageObj = {
msgtype: 'video',
video: {
mediaid: res.data.media_id
},
success: (res) => {
console.log(res, '发送视频成功')
messageInfo.success = true
messageInfo.response = res
},
fail: (err) => {
console.log(err, '发送视频失败')
messageInfo.success = false
messageInfo.error = err
}
}
} else {
throw new Error('获取媒体ID失败')
}
} catch (error) {
console.error('获取视频媒体ID失败:', error)
Message.error('获取视频媒体ID失败')
messageInfo.success = false
messageInfo.error = error
return messageInfo
}
} else {
Message.error('视频链接不存在,无法发送')
messageInfo.success = false
messageInfo.error = new Error('视频链接不存在')
return messageInfo
}
} else if (type === 'file') {
// 发送文件消息
if (content) {
try {
const res = await getMediaId({ url: content })
if (res.status_code == 1) {
messageObj = {
msgtype: 'file',
file: {
mediaid: res.data.media_id
},
success: (res) => {
console.log(res, '发送文件成功')
messageInfo.success = true
messageInfo.response = res
},
fail: (err) => {
console.log(err, '发送文件失败')
messageInfo.success = false
messageInfo.error = err
}
}
} else {
throw new Error('获取媒体ID失败')
}
} catch (error) {
console.error('获取文件媒体ID失败:', error)
Message.error('获取文件媒体ID失败')
messageInfo.success = false
messageInfo.error = error
return messageInfo
}
} else {
Message.error('文件链接不存在,无法发送')
messageInfo.success = false
messageInfo.error = new Error('文件链接不存在')
return messageInfo
}
}
console.log(messageObj, '发送消息对象')
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论