Files
JiaZhiQianYan/src/utils/posthog/device.js
2025-12-04 17:41:33 +08:00

205 lines
4.5 KiB
JavaScript

import storage from './storage'
import { STORAGE_KEYS } from './constants'
/**
* 设备信息采集模块
*/
class Device {
constructor() {
this.info = null
this.deviceId = null
}
/**
* 初始化设备信息
*/
init() {
this._collectDeviceInfo()
this._ensureDeviceId()
}
/**
* 采集设备信息
*/
_collectDeviceInfo() {
try {
const systemInfo = uni.getSystemInfoSync()
this.info = {
// 操作系统
os: systemInfo.osName || systemInfo.platform || 'unknown',
osVersion: systemInfo.osVersion || 'unknown',
// 设备信息
brand: systemInfo.brand || 'unknown',
model: systemInfo.model || 'unknown',
deviceType: this._getDeviceType(systemInfo),
// 屏幕信息
screenWidth: systemInfo.screenWidth || 0,
screenHeight: systemInfo.screenHeight || 0,
windowWidth: systemInfo.windowWidth || 0,
windowHeight: systemInfo.windowHeight || 0,
pixelRatio: systemInfo.pixelRatio || 1,
// 小程序信息
appVersion: systemInfo.appVersion || 'unknown',
appLanguage: systemInfo.appLanguage || systemInfo.language || 'zh-CN',
SDKVersion: systemInfo.SDKVersion || 'unknown',
// 平台信息
platform: systemInfo.uniPlatform || 'mp-weixin',
hostName: systemInfo.hostName || 'unknown',
// 网络类型(初始值,后续会更新)
networkType: 'unknown',
}
// 异步获取网络类型
this._updateNetworkType()
} catch (error) {
console.warn('[PostHog Device] Collect info error:', error)
this.info = this._getDefaultInfo()
}
}
/**
* 获取设备类型
*/
_getDeviceType(systemInfo) {
const model = (systemInfo.model || '').toLowerCase()
if (model.includes('ipad') || model.includes('tablet')) {
return 'tablet'
}
if (model.includes('iphone') || model.includes('android')) {
return 'mobile'
}
return 'unknown'
}
/**
* 获取默认设备信息
*/
_getDefaultInfo() {
return {
os: 'unknown',
osVersion: 'unknown',
brand: 'unknown',
model: 'unknown',
deviceType: 'unknown',
screenWidth: 0,
screenHeight: 0,
windowWidth: 0,
windowHeight: 0,
pixelRatio: 1,
appVersion: 'unknown',
appLanguage: 'zh-CN',
SDKVersion: 'unknown',
platform: 'mp-weixin',
hostName: 'unknown',
networkType: 'unknown',
}
}
/**
* 更新网络类型
*/
_updateNetworkType() {
uni.getNetworkType({
success: (res) => {
if (this.info) {
this.info.networkType = res.networkType || 'unknown'
}
},
})
}
/**
* 确保设备ID存在
*/
_ensureDeviceId() {
let deviceId = storage.get(STORAGE_KEYS.DEVICE_ID)
if (!deviceId) {
deviceId = this._generateDeviceId()
storage.set(STORAGE_KEYS.DEVICE_ID, deviceId)
}
this.deviceId = deviceId
}
/**
* 生成设备ID
*/
_generateDeviceId() {
const timestamp = Date.now().toString(36)
const random = Math.random().toString(36).substring(2, 10)
return `device_${timestamp}_${random}`
}
/**
* 获取设备ID
*/
getDeviceId() {
return this.deviceId
}
/**
* 获取设备信息
*/
getInfo() {
return this.info || this._getDefaultInfo()
}
/**
* 获取PostHog格式的设备属性
*/
getProperties() {
const info = this.getInfo()
return {
$os: info.os,
$os_version: info.osVersion,
$device_type: info.deviceType,
$device_id: this.deviceId,
$screen_width: info.screenWidth,
$screen_height: info.screenHeight,
$viewport_width: info.windowWidth,
$viewport_height: info.windowHeight,
$lib: 'uniapp-posthog',
$lib_version: '1.0.0',
// 扩展属性
mp_platform: info.platform,
mp_sdk_version: info.SDKVersion,
device_brand: info.brand,
device_model: info.model,
network_type: info.networkType,
app_language: info.appLanguage,
}
}
/**
* 监听网络状态变化
*/
onNetworkChange(callback) {
uni.onNetworkStatusChange((res) => {
if (this.info) {
this.info.networkType = res.networkType || 'unknown'
}
if (typeof callback === 'function') {
callback(res)
}
})
}
/**
* 检查是否在线
*/
isOnline() {
const networkType = this.info?.networkType || 'unknown'
return networkType !== 'none' && networkType !== 'unknown'
}
}
// 导出单例
export default new Device()