npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

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-sdkim-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文件