im-kf
v4.13.0-beta.14
Published
## 启动
Downloads
1
Readme
客服独立IM工作台
启动
1、git clone
2、yarn
3、yarn build 编译独立工作台,生成lib文件
4、yarn serve 运行工作台的example
im-test文件夹下面,直接引用src,不依赖lib
端口8883
访问后端接口 需要配置nginx 以及 hosts
nginx建议内容
server { listen 80; server_name crm.guazi-cloud.com;
location / {
proxy_pass http://127.0.0.1:8883;
}
}
hosts建议使用whistle配置: crm-test.guazi-cloud.com/ 127.0.0.1:8883
项目文件结构
src
核心功能实现
---- src
---- assets 一些icon资源文件
---- common 公共组件
---- tab 实现了纵向的tab组件(使用方法类似于elementui的tab)
---- style 公共样式(修改了一些elementui的组件样式)
---- net-work 网络请求
---- 一些涉及到会话的数据请求
---- core 核心实现
---- bone.vue 实现整体UI框架(拖拽整体边界等逻辑)
---- chat-status 会话状态(正在输入中等等)
---- chats-box 会话列表
---- input-area 输入区域,包括输入框上面的快捷功能
---- message 消息展示区域
---- toolbar 消息展示区域上方的工具条
---- image 消息图片区域,支持缩放,旋转和下载等功能
---- record-list 消息历史记录区域,滚动加载所有的历史消息,后续扩展支持渲染卡片等消息
---- utils 一些工具方法
---- plugins
----- message-render 消息渲染包
---- common 渲染公共
---- bot-reply.vue 机器人推荐回答
---- layout.vue 消息体外部容器
---- message-status.vue 消息状态成功失败
---- components 各类消息组件
---- card 一些卡片
---- image.vue 图片消息
...
---- formatter.js 消息的formatter(注册)
---- index.js 入口
----- link-card 直达链接卡片包
---- link-card-list
---- net-work 直达链接卡片的network
im-test
项目使用示例实现
lib
项目打包后的资源
build
编译配置
全局API
Matrix
提供插件的注册
Matrix.use
参数: Object
注册插件的方法,会调用对象里面的install方法
Matrix.formatter
参数:Object
注册老通道会话的消息组件的formatter,会extend到消息formatter的默认值上面
示例:
export default {
// 处理消息类型为 c2kf 的消息, 追加 sender
c2kf(m) {
m.sender = 2
return m
},
// 处理消息类型为 kf2c 的消息, 追加 sender
kf2c: (m) => {
m.sender = 1
return m
},
// 处理消息内容为 text 的所有消息, 解析文本
text: (m) => {
m.renderType = 'text'
m.contentShort = m.content
// m.content = this.textParsing(m.content)
return m
},
// 处理消息内容为 image 的所有消息
image: (m) => {
m.renderType = 'image'
m.contentShort = '图片'
return m
},
// 系统消息
system_msg_for_kf: (m) => {
m.sender = 3
m.renderType = 'sysmsg'
m.contentShort = '系统消息'
return m
},
// 富文本
rich_text(m) {
m.renderType = 'richText'
m.contentShort = '富文本'
return m
},
card(m) {
m.renderType = 'text'
m.contentShort = '卡片'
return m
},
// 猜你想问
'card-4'(m) {
m.renderType = 'guessCard'
m.contentShort = '猜你想问'
return m
},
'card-6'(m) {
m.renderType = 'helpCard'
m.contetShort = '帮你选车'
return m
},
'card-7'(m) {
m.renderType = 'linkCard'
m.contetShort = '直达卡片'
return m
},
'card-8'(m) {
m.renderType = 'loginCard'
m.contentShort = '登录卡片'
return m
},
'card-9'(m) {
m.renderType = 'workListCard'
m.contentShort = '工单列表卡片'
return m
},
'card-14'(m) {
m.renderType = 'chatRecordCard'
m.contentShort = '聊天记录卡片'
return m
},
'card-23'(m) {
m.renderType = 'harassmentPreventionCard'
m.contetShort = '防骚扰卡片'
return m
},
}
Matrix.nativeFormatter
因im-kf兼容新通道
native-sdk
,且新老通道的native-sdk
和im-sdk
的 MSG_TYPE(新通道MSG_TYPE 参考文档) 定义有所区别,所以新通道的自定义formatter需要额外方法定义
参数:Object
注册新通道会话的消息组件的formatter,会extend到消息formatter的默认值上面
示例:
// 参考 native-sdk文档上的各类参数:http://im-doc-sdk.guazi-cloud.com/guide/
import { NativeSdk } from 'im-kf'
let { DOMAIN_TYPE, CONTENT_TYPE, CTRL_TYPE, helpers, config } = NativeSdk
const C2GMsgformatter = (m) => {
let { ANONYMOUS, EXTERNAL } = DOMAIN_TYPE
if ([ANONYMOUS, EXTERNAL].includes(m.fromDomain)) {
m.sender = 2
} else {
m.sender = 1
}
let {
TEXT,
IMAGE,
VIDEO,
HTML_CARD,
TEMPLATE_STYLE_CARD,
CUSTOM,
CARD,
RICH_TEXT,
} = CONTENT_TYPE
switch (m.subType) {
case TEXT: {
m.renderType = 'text'
break
}
case IMAGE: {
m.renderType = 'image'
m.contentShort = '图片'
try {
let imgObj = JSON.parse(m.content)
m.contentUrl = imgObj.url
} catch (e) {
m.contentUrl = 'https://image.guazistatic.com/gz01180417/19/53/8f570ee1e498c0c7149077e0e42b262f.png' // 默认失败的图片
}
break
}
case VIDEO: {
m.renderType = 'video'
m.contentShort = '视频'
break
}
case HTML_CARD: {
let contentParsed = helpers.parseCard(m.content, NativeSdk, config)
m.renderType = 'htmlCard'
m.contentParsed = contentParsed
m.contentShort = contentParsed.cardName
break
}
case RICH_TEXT: {
m.renderType = 'richText' // 模板卡片
m.contentShort = '富文本消息'
break
}
case TEMPLATE_STYLE_CARD: {
m.renderType = 'templateStyleCard' // 模板卡片
m.contentShort = '模板卡片'
break
}
case CARD: {
m.renderType = 'card' // 卡片消息
m.contentShort = '卡片消息'
break
}
case CUSTOM: {
m.renderType = 'custom' // 自定义消息
m.contentShort = '自定义卡片'
break
}
default: {
m.renderType = 'hidden'
}
}
return m
}
const CtrlFormatter = (m) => {
m.sender = 3
if (m.subType === CTRL_TYPE.SERVICE_GROUP_CONTENT) {
m.renderType = 'sysmsg'
m.contentShort = '系统消息'
} else {
m.renderType = 'hidden'
}
return m
}
export default {
C2GSEND: m => C2GMsgformatter(m),
C2GPUSH: m => C2GMsgformatter(m),
CTRLPUSH_V1: m => CtrlFormatter(m),
RECEIPT(m) {
m.renderType = 'hidden'
return m
},
RECALL: (m) => {
// if (m.from === Bridge.im.config.uid) {
// m.content = '你撤回了一条消息'
// } else {
// m.content = '对方撤回了一条消息'
// }
m.renderType = 'recall'
m.sender = 3
return m
},
}
Matrix.renderComponent
参数:Object(Vue的Component,需要Component提供name属性)
注册具体用来渲染消息的组件
Matrix.WebImMixin
提供一些便利的方法,可以使用mixin注入
Slot
toolbox
注册到输入框上面的工具箱里面,需要采用im-tab-pane的方式注册
示例
chat-info
会话详细内容,会被注册到会话框右边的空间里面
示例
WebIm
开发中使用到的API挂载的实例
会以$webIm的方式注册到Vue.prototype上面
属性
$im
im实例,IM通信的核心
$root
工作台vue组件实例
方法
sendMessage
参数:message | Object 消息体内容,内容具体查看IM-SDK
描述:发送消息
sendFile
参数:message | Object 消息体内容,内容具体查看IM-SDK
描述:发送文件类型的消息
logout
描述:登出IM
login
描述:登录IM
setFree
描述:设置IM状态为空闲
setBusy
描述:设置IM状态为忙碌
appendChatIcon
参数:
描述:会话上面添加ICON
removeChatIcon
参数:
描述:会话上面清楚ICON
事件
会话事件
ready
im实例注册完成,并且挂载各种方法成功
chat-change
选中会话改变(包括因为点击选中带来的改变,或者因为同步会话状态带来的改变)
chat-end
会话主动结束
消息事件
new-message
新消息事件
paste-input
输入区域的粘贴事件
insert-text
参数:content | string
描述:向输入框插入文本
TODO
1:index.vue 里面的 onMessage 方法
2:chats-box 里面关于会话逻辑的部分要从index.vue分离出来
版本升级
v4.0.0-beta:24
兼容新通道Native-sdk
- 新增变化
- 新版本依赖了vuex 所以初始化配置新增了 store参数,示例如下:
// main.js
import Vue from 'vue';
import Vuex from 'vuex';
import WebIm from 'im-kf';
import plugin from './libs/plugin';
import 'im-kf/lib/im-kf.css';
WebIm.use(plugin);
Vue.use(Vuex);
const store = new Vuex.Store({
modules: {
...
},
});
Vue.use(WebIm, {
isDev: isDev,
config: {
// imBarStatus: 'min'
},
store, // 新增参数store 将vuex生成的store进行赋值
});
- this.$webIm增加监听坐席当前会话状态事件:
change-im-status
。示例如下:
methods: {
setWebImLinkStatus(status) {
}
},
created() {
this.$webIm.on('change-im-status', this.setWebImLinkStatus);
},
change-im-status
事件回调函数的行参status:
| 状态 | 说明 |
| ---- | ---- |
| free | 空闲 |
| busy | 忙碌 |
- IM-KF实例新增
nativeFormatter
函数 用来绑定新通道的自定义formatter数据,使用方式:
- 1 新建native-formatter.js文件,输入如下类似自定义内容:
// webIm 参考 native-sdk文档上的各类参数:http://im-doc-sdk.guazi-cloud.com/guide/
const FromDomainType = {
STAFF: 0, // 内部员工
GROUP: 1, // 群 暂时不用
WORKSPACE: 2, // 工作台
OFFACC: 3, // 公众号 暂时不用
SERVICE: 4, // 客服
ANONYMOUS: 5, // C端匿名用户
ROBOT: 6, // 机器人
EXTERNAL: 7, // C端登录用户
SYSTEM: 8, // 系统
UNKNOWN: 9, // 未知
SALER: 10, // 销售
APPRAISER: 11, // 捡瓜子。评估师
NEWCAR_SALER: 12, // 新车太阳花销售
MERCHANT: 13, // 开放平台车商
}
const C2GMsgformatter = (m) => {
let { ANONYMOUS, EXTERNAL } = FromDomainType
if ([ANONYMOUS, EXTERNAL].includes(m.fromDomain)) {
m.sender = 2
} else {
m.sender = 1
}
let {
TEXT,
IMAGE,
VIDEO,
HTML_CARD,
TEMPLATE_STYLE_CARD,
CUSTOM,
CARD,
RICH_TEXT,
} = WebIM.CONTENT_TYPE
switch (m.subType) {
case TEXT: {
m.renderType = 'text'
break
}
case IMAGE: {
m.renderType = 'image'
m.contentShort = '图片'
try {
let imgObj = JSON.parse(m.content)
m.contentUrl = imgObj.url
} catch (e) {
m.contentUrl = 'https://image.guazistatic.com/gz01180417/19/53/8f570ee1e498c0c7149077e0e42b262f.png' // 默认失败的图片
}
break
}
case VIDEO: {
m.renderType = 'video'
m.contentShort = '视频'
break
}
case HTML_CARD: {
let contentParsed = WebIM.helpers.parseCard(m.content, WebIM, WebIM.config)
m.renderType = 'htmlCard'
m.contentParsed = contentParsed
m.contentShort = contentParsed.cardName
break
}
case RICH_TEXT: {
m.renderType = 'richText' // 模板卡片
m.contentShort = '富文本消息'
break
}
case TEMPLATE_STYLE_CARD: {
m.renderType = 'templateStyleCard' // 模板卡片
m.contentShort = '模板卡片'
break
}
case CARD: {
m.renderType = 'card' // 卡片消息
m.contentShort = '卡片消息'
break
}
case CUSTOM: {
m.renderType = 'custom' // 自定义消息
m.contentShort = '自定义卡片'
break
}
default: {
m.renderType = 'hidden'
}
}
return m
}
const CtrlFormatter = (m) => {
m.sender = 3
if (m.subType === WebIM.CTRL_TYPE.SERVICE_GROUP_CONTENT) {
m.renderType = 'sysmsg'
m.contentShort = '系统消息'
} else {
m.renderType = 'hidden'
}
return m
}
// WebIm是
export default {
C2GSEND: m => C2GMsgformatter(m),
C2GPUSH: m => C2GMsgformatter(m),
CTRLPUSH_V1: m => CtrlFormatter(m),
RECEIPT(m) {
m.renderType = 'hidden'
return m
},
RECALL: (m) => {
// if (m.from === Bridge.im.config.uid) {
// m.content = '你撤回了一条消息'
// } else {
// m.content = '对方撤回了一条消息'
// }
m.renderType = 'recall'
m.sender = 3
return m
},
}
- 2 在plugin中增加如下内容:
import TestRender from './test-render.vue'
import nativeFormat from './native-formatter' // 新通道formatter
import format from './formatter' // 老通道formatter
export default {
install(im) {
im.formatter(format)
// 新增内容
im.nativeFormatter(nativeFormat)
im.renderComponent(TestRender)
},
}
- 废弃
- 废弃 v3.0.2-Beta.6 版本中的
linkStatusHasChanged
事件
v3.0.2-Beta.6
im-kf
组件增加props事件linkStatusHasChanged
表示IM连接状态已经改变
- 修改package.json里 im-kf版本为
git+http://git.guazi-corp.com/blusher/im-kf.git#v3.0.2-Beta.6
- 运行
yarn install
更新yarn.lock文件 - 为im-kf组件增加
linkStatusHasChanged
事件:<im-kf :uid="userInfo.userId + '' " :uname="userInfo.userName + '' " :debug="true" :mainWidth="mainWidth" :mainHeight="mainHeight" :rightSideWidth="rightSideWidth" :leftSideWidth="leftSideWidth" :inputHeight="inputHeight" :left="150" :canResize="canResize" @linkStatusHasChanged="linkStatusHasChanged" custom-class="im-index"> <div slot="chat-info" > //此部分用于扩展自己的业务部分 </div> </im-kf> methods: { changeChat(chat) { //eslint-disable-next-line console.log(chat) }, // im弹框连接状态更换通知事件 linkStatusHasChanged(status) { console.log(status) }, },
linkStatusHasChanged
形参status
枚举值:
| 状态 | 说明 | | ---- | ---- | | online | 上线| |offline | 下线| | free | 空闲 | | busy | 忙碌 |
- 2.4.1-beta.8
快捷输入功能:解决埋点901577070811(旧埋点id为10250126)数据无法发送的bug
- 修改package.json里 im-kf版本为
git+http://git.guazi-corp.com/blusher/im-kf.git#v2.4.1-beta.8
- 运行
yarn install
更新yarn.lock文件