3.0.0-beta.14 • Published 2 years ago

@firesoon/log-sdk v3.0.0-beta.14

Weekly downloads
1
License
ISC
Repository
-
Last release
2 years ago

@firesoon/log-sdk

Usage

安装

yarn add @firesoon/log-sdk
// 使用
import track from '@firesoon/log-sdk';

const autoClickHandle = (e) => {
  const activeTabKey = sessionStorage.getItem('activeTabKey');
  const menuUuid = sessionStorage.getItem('uuid');
  // 获取单击数据
  const log: boolean | object = track.getLogData(e);
  if (log) {
    track.sendBeacon('/beacon', {
      ...log,
      menuNo: activeTabKey,
      menuUuid,
    });
  }
};

// 绑定单击事件监听
track.listener.on(document.body, 'click', autoClickHandle);

在 umi 搭建的项目中使用

global.ts

import track from '@firesoon/log-sdk';

const autoClickHandle = (e) => {
  const activeTabKey = sessionStorage.getItem('activeTabKey');
  const menuUuid = sessionStorage.getItem('uuid');

  // 获取单击数据
  const log = track.getLogData(e);
  try {
    if (log) {
      const logData = {
        ...log,
        menuNo: activeTabKey,
        menuUuid,
      };
      // 上报数据或做缓存
      track.sendBeacon('/beacon', logData);
    }
  } catch (e) {
    // 错误处理
  }
};

// 绑定单击事件监听
track.listener.on(document.body, 'click', autoClickHandle);

app.ts

import { generateUUID } from '@/utils/utils';

// 生成UUID
let uuid = generateUUID();
let lasePathName;
export function onRouteChange(params) {
  const {
    action,
    location: { pathname },
  } = params;

  // query变化时不重新生成
  if (action != null && pathname !== lasePathName) {
    uuid = generateUUID();
    sessionStorage.setItem('uuid', uuid);
    lasePathName = pathname;
  }
}

models/global.ts

import track from '@firesoon/log-sdk';

* queryUserInfo(_, { ... }) {
// 可以在获取用户信息的回调里配置通用埋点属性
    track.config({
      baseInfo: {
        hospitalCode,
        appVersion,
        sid,
        roleType,
        userId,
        departmentName,
        appCode: 'drgsmsfl',
      },
    })
}

utils.ts

export function generateUUID() {
  let d = new Date().getTime();
  if (window.performance && typeof window.performance.now === 'function') {
    d += performance.now(); //use high-precision timer if available
  }
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
    const r = (d + Math.random() * 16) % 16 | 0;
    d = Math.floor(d / 16);
    return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16);
  });
}

采集规则

  • 所有的button点击都会自动采集
  • 采集通过classConfig配置的classname的节点及其子节点

个性化

data-auto-track

是否自动上报的节点(优先级最高)

  • Type: boolean
  • Default: 无值, 全部自动上报

只要点击元素或其父元素包含此属性为 false,则都不会自动埋点。设为 true 没有意义,不会采集无法进入 classname 或者 xpath 的 dom 节点。 该属性存在的意义即对复杂组合做个性化的埋点需求时,关闭自动埋点规则。

data-name

需要记录名称的操作

获取当前节点或其父节点第一个出现的 data-name 的值,保存到 value 中.

  • Type: string
// 普通节点使用
<button data-name="下载科室病例明细">下载</button>
// {..., value: '下载科室病例明细', ... }

// 在下拉框中使用, 组件库需封装一层
// CustomSelect.tsx
<div data-name={props.label}>
  <label>{props.label}</label>
  <Select {...props}></Select>
</div>

// index.tsx
<CustomSelect label="出院科室" />
// { ..., value: '出院科室', content: '妇科' }

select 等浮窗需要设置挂载到 trigger 或 trigger.parentNode 下, 否则 data-name 不在其父元素上无法获取

 <ConfigProvider
-  getPopupContainer={triggerNode => triggerNode.parentNode}
+  getPopupContainer={node => {
+    if (node) {
+      return node.parentNode;
+    }
+    return document.body;
+  }}
 >
   <App />
 </ConfigProvider>

config

全局配置

配置获取

type IConfigName = 'baseInfo' | 'autoTrackCls' | 'useInnerTextCls';
// 获取baseInfo的配置
track.config('baseInfo');
track.config({
  classname: 'my-custom-class',
  canUseInnerTextCls: 'my-custom-inner-text',
  route: {
    api: '/api/track/report',
    onChange: (data) => console.log(data),
    exclude: ['/'],
  },
  baseInfo: {
    app: 'mrbp',
  },
});

classname

允许埋点的节点 classname(对点击元素和其父元素们判断)

  • Type: string[] | string;
  • Default
[
  'ant-input-suffix', // Search的suffix
  'ant-calendar-cell', // DatePicker
  'ant-calendar-footer-btn',
  'ant-calendar-month-panel-cell', // MonthPicker
  'ant-tabs-tab', // Tabs
  'ant-select-dropdown-menu-item', // Select下拉框
  'ant-checkbox-wrapper', // CheckBox
  'ant-radio-wrapper', // Radio
  'ant-radio-button-wrapper', // RadioButton
  'fs-select-dropdown-menu-item', // ant-ui QuarterPicker'
  'auto-track', // 需要自动埋点元素使用
  'auto-track-inner-text', // 需要自动埋点且获取innerText作为value的元素使用
];

建议普通点击元素都使用 button 触发自动采集。若有必要配置 classname, 可配置一个通用的(如'auto-track'), 所有需要自动采集的节点都使用该 classname.

使用 classname 注意事项

1. 使用配置 classname 作为数据自动采集过滤条件时,为避免采集到无效点击,必须保证添加有点击事件的节点 classname,而不是父容器的

2. 普通元素由于数据敏感性,不会获取 innerText,只有 button 获取。所以普通标签配置了 classname 如果不自动埋点,需要配置 data-name(或 title)

// 去掉所有默认的 传入空数组或者空字符串
track.config({
  classname: 'my-custom-xx',
});

canUseInnerTextCls

使用 innerText 作为 value 的元素 class 配置(并不是设置了就一定取 innerText, 有优先级)

  • Type: string[] | string;
  • Default
[
  'ant-tabs-tab', // Tabs
  'track-inner-text', // 获取innerText作为value的元素使用
  'auto-track-inner-text', // 需要自动埋点且获取innerText作为value的元素使用
];
// { value: '兄弟萌埋它' }
<p className="auto-track-inner-text">
兄弟萌埋它
</p>

// 或许会有这种使用场景(有更好的使用方式, 只是为了举例)
<div className="auto-track">
    <p>这个点击不会埋</p>
    <p className="track-inner-text">
     不用auto-track埋不了
    </p>
     <p className="track-inner-text">
      需要搭配auto-track使用
    </p>
</div>

baseInfo

通用的上报数据配置

  • Type: object;
  • Default: { version };

默认不包含操作系统相关信息, 可通过使用{ includePlatform: true }添加相关信息

操作系统相关信息统一使用 Nginx 去获取

route (测试功能)

路由变化时触发, 不使用则不需要配置

apionChange二选一, 没有 onChange 会根据 api 自动上报{pathname, time}

type IData = {
  pathname: string;
  stamp: number;
};

interface IRouteChange {
  api?: string; // 上报地址
  onChange?: (data: IData) => void; // 路由变化回调
  exclude?: string[]; // 不需要采集的pathname
}
track.config({
  route: {
    api: '', // 上报地址
    exclude: ['/'],
  },
});

优先级

自动采集

  1. data-auto-track=false
  2. button, track.classConfig

数据获取

value

  1. data-name, Elememt.getAttribute('placeholder')

  2. Elememt.getAttribute('title')

  3. Element.getInnerText

待改进

  1. 数据采集
  • radio, checkbox 的文字获取采用nextElementSibling.innerText获取,依赖 dom 结构

  • 考虑是够支持data-auto-track=true则自动埋点. (考虑可以通过 classname 配置, 如果支持此功能会有重复)

  1. 数据上报
  • 普通的数据上报采用 Image Beacon, unload 和 beforeUnLoad 使用track.sendBeacon

  • 上报接口服务端返回'204 No Content'作为响应,节省服务器资源

LICENSE

ISC

FAQs

  1. 为什么配置了 classname 不生效?

参见 classname 使用注意事项

3.0.0-beta.13

2 years ago

3.0.0-beta.14

2 years ago

3.0.0-beta.1

2 years ago

3.0.0-beta.3

2 years ago

3.0.0-beta.2

2 years ago

3.0.0-beta.5

2 years ago

3.0.0-beta.4

2 years ago

3.0.0-beta.7

2 years ago

3.0.0-beta.6

2 years ago

3.0.0-beta.9

2 years ago

3.0.0-beta.8

2 years ago

2.1.3-beta

2 years ago

3.0.0-beta

2 years ago

3.0.0-beta.10

2 years ago

3.0.0-beta.11

2 years ago

3.0.0-beta.12

2 years ago

2.1.4

2 years ago

2.1.3

2 years ago

2.1.2

2 years ago

2.1.1-0

3 years ago

2.1.0

3 years ago

2.0.0-beta.5

4 years ago

2.0.0-beta.4

4 years ago

2.0.0-beta.3

4 years ago

2.0.0-beta.2

4 years ago

2.0.0-beta.0

4 years ago

2.0.0-beta.1

4 years ago

1.0.3

4 years ago

1.0.2

4 years ago

1.0.1

4 years ago

1.0.0

4 years ago

0.0.2

4 years ago

0.0.1

4 years ago