205 lines
4.5 KiB
JavaScript
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() |