328 lines
8.2 KiB
TypeScript
328 lines
8.2 KiB
TypeScript
/**
|
|
* 模仿thinkingdata-node直接写一个log的写入,而日志直接用pinus-logger实现
|
|
*/
|
|
import { taLogger } from "../../util/logger";
|
|
|
|
const KEY_NAME_MATCH_REGEX = /^[a-zA-Z#][a-zA-Z0-9_]+$/;
|
|
|
|
let util: any = {};
|
|
util.version = '1.2.2';
|
|
util.log = function(message: string) {
|
|
console.log(message);
|
|
}
|
|
util.each = function (obj, iterator, context) {
|
|
if (obj === null) {
|
|
return;
|
|
}
|
|
if (Array.prototype.forEach && obj.forEach === Array.prototype.forEach) {
|
|
obj.forEach(iterator, context);
|
|
} else if (obj.length === +obj.length) {
|
|
for (let i = 0, l = obj.length; i < l; i++) {
|
|
// @ts-ignore
|
|
if (i in obj && iterator.call(context, obj[i], i, obj)) {
|
|
return;
|
|
}
|
|
}
|
|
} else {
|
|
for (let key in obj) {
|
|
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
// @ts-ignore
|
|
if (iterator.call(context, obj[key], key, obj)) {
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
util.formatDate = function (d) {
|
|
function pad(n) {
|
|
return n < 10 ? '0' + n : n;
|
|
}
|
|
|
|
function padMilliseconds(n) {
|
|
if (n < 10) {
|
|
return '00' + n;
|
|
} else if (n < 100) {
|
|
return '0' + n;
|
|
} else {
|
|
return n;
|
|
}
|
|
}
|
|
return d.getFullYear() + '-' +
|
|
pad(d.getMonth() + 1) + '-' +
|
|
pad(d.getDate()) + ' ' +
|
|
pad(d.getHours()) + ':' +
|
|
pad(d.getMinutes()) + ':' +
|
|
pad(d.getSeconds()) + '.' +
|
|
padMilliseconds(d.getMilliseconds());
|
|
};
|
|
|
|
util.formatString = function (format) {
|
|
const args = Array.prototype.slice.call(arguments, 1);
|
|
return format.replace(/{(\d+)}/g, function (match, number) {
|
|
return typeof args[number] !== 'undefined'
|
|
? args[number]
|
|
: match
|
|
;
|
|
});
|
|
};
|
|
util.isArray = Array.isArray;
|
|
util.isObject = function (obj) {
|
|
return obj === Object(obj) && !util.isArray(obj) && typeof obj === 'object';
|
|
};
|
|
util.encodeURIComponent = function (str) {
|
|
return encodeURIComponent(str);
|
|
}
|
|
util.trim = function (str) {
|
|
return str.replace(/^\s+|\s+$/g, '');
|
|
}
|
|
util.toArray = function (iterable) {
|
|
if (!iterable) {
|
|
return [];
|
|
}
|
|
if (iterable.toArray) {
|
|
return iterable.toArray();
|
|
}
|
|
return [].slice.call(iterable);
|
|
}
|
|
util.each(['Function', 'String', 'Object', 'Number', 'Boolean', 'Date', 'RegExp', 'Error'], function (name) {
|
|
util['is' + name] = function (obj) {
|
|
return Object.prototype.toString.call(obj) === '[object ' + name + ']';
|
|
};
|
|
});
|
|
util.getProperty = function (obj, key) {
|
|
return obj == null ? undefined : obj[key];
|
|
};
|
|
util.setProperty = function (obj, key, value) {
|
|
obj[key] = value;
|
|
};
|
|
util.hasProperty = function (obj, key) {
|
|
return obj != null && typeof obj === 'object' && key in obj;
|
|
};
|
|
util.createLog = function (category) {
|
|
const log = function () {
|
|
};
|
|
log.debug = function () {
|
|
};
|
|
log.info = function () {
|
|
};
|
|
log.warn = function () {
|
|
};
|
|
log.error = function () {
|
|
};
|
|
return log;
|
|
};
|
|
const TABLE_NAME = "app_gold_record";
|
|
|
|
const EXTRA_CODE = {
|
|
"#": "_j_",
|
|
"ing": "_deng_",
|
|
"&": "_he_",
|
|
};
|
|
|
|
function encodeKey(key) {
|
|
let result = "";
|
|
for (let i = 0; i < key.length; i++) {
|
|
const c = key.charAt(i);
|
|
result += EXTRA_CODE[c] || c;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
function decodeKey(key) {
|
|
let result = "";
|
|
let i = 0;
|
|
while (i < key.length) {
|
|
const c = key.charAt(i);
|
|
if (c === '_' && i + 2 < key.length) {
|
|
const nextTwo = key.substring(i + 1, i + 3);
|
|
let found = false;
|
|
for (const [encoded, decoded] of Object.entries(EXTRA_CODE)) {
|
|
if (nextTwo === encoded.substring(1)) {
|
|
result += decoded;
|
|
i += 3;
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!found) {
|
|
result += c;
|
|
i++;
|
|
}
|
|
} else {
|
|
result += c;
|
|
i++;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
function encode(data) {
|
|
const str = JSON.stringify(data);
|
|
return new Buffer(str).toString("base64");
|
|
}
|
|
|
|
function decode(str) {
|
|
return JSON.parse(new Buffer(str, "base64").toString());
|
|
}
|
|
|
|
function encodeId(id) {
|
|
return encodeKey(encode({
|
|
"appid": 1,
|
|
"id": id,
|
|
}));
|
|
}
|
|
|
|
function decodeId(id) {
|
|
const decoded = decode(decodeKey(id));
|
|
return decoded["id"];
|
|
}
|
|
|
|
function encodeData(data) {
|
|
return encode({
|
|
"data": data,
|
|
"time": Date.now(),
|
|
});
|
|
}
|
|
|
|
function decodeData(data) {
|
|
const decoded = decode(data);
|
|
return decoded["data"];
|
|
}
|
|
|
|
let instance = null;
|
|
|
|
export class TA {
|
|
private appId: string;
|
|
private worker: any;
|
|
private receiver: any;
|
|
|
|
constructor(appId: string, token: string) {
|
|
this.appId = appId;
|
|
this.worker = null;
|
|
this.receiver = null;
|
|
}
|
|
|
|
userSet(userId: string, properties: any) {
|
|
const data = {
|
|
"#type": "user_set",
|
|
"#time": util.formatDate(new Date()),
|
|
"#account_id": userId,
|
|
};
|
|
util.each(properties, function (val, key) {
|
|
data[key] = val;
|
|
});
|
|
this.upload(data);
|
|
}
|
|
|
|
userSetOnce(userId: string, properties: any) {
|
|
const data = {
|
|
"#type": "user_setOnce",
|
|
"#time": util.formatDate(new Date()),
|
|
"#account_id": userId,
|
|
};
|
|
util.each(properties, function (val, key) {
|
|
data[key] = val;
|
|
});
|
|
this.upload(data);
|
|
}
|
|
|
|
userAdd(userId: string, properties: any) {
|
|
const data = {
|
|
"#type": "user_add",
|
|
"#time": util.formatDate(new Date()),
|
|
"#account_id": userId,
|
|
};
|
|
util.each(properties, function (val, key) {
|
|
data[key] = val;
|
|
});
|
|
this.upload(data);
|
|
}
|
|
|
|
userUnset(userId: string, keys: string[]) {
|
|
const data: any = {
|
|
"#type": "user_unset",
|
|
"#time": util.formatDate(new Date()),
|
|
"#account_id": userId,
|
|
};
|
|
for (let i = 0; i < keys.length; i++) {
|
|
data[keys[i]] = 0;
|
|
}
|
|
this.upload(data);
|
|
}
|
|
|
|
userDelete(userId: string) {
|
|
const data = {
|
|
"#type": "user_del",
|
|
"#time": util.formatDate(new Date()),
|
|
"#account_id": userId,
|
|
};
|
|
this.upload(data);
|
|
}
|
|
|
|
track(userId: string, eventName: string, properties: any) {
|
|
const data = {
|
|
"#type": "track",
|
|
"#time": util.formatDate(new Date()),
|
|
"#account_id": userId,
|
|
"#event_name": eventName,
|
|
};
|
|
util.each(properties, function (val, key) {
|
|
if (!KEY_NAME_MATCH_REGEX.test(key)) {
|
|
return;
|
|
}
|
|
data[key] = val;
|
|
});
|
|
this.upload(data);
|
|
}
|
|
|
|
upload(data) {
|
|
if (!instance) {
|
|
taLogger.info("ta data:", JSON.stringify(data));
|
|
} else {
|
|
taLogger.info("ta data:", JSON.stringify(data));
|
|
}
|
|
}
|
|
}
|
|
|
|
let ta: TA = null;
|
|
let initCount = 0;
|
|
|
|
export function initTa(appId: string, token: string) {
|
|
initCount++;
|
|
if (ta == null || initCount <= 1) {
|
|
ta = new TA(appId, token);
|
|
}
|
|
return ta;
|
|
}
|
|
|
|
export function getTa() {
|
|
if (!ta) {
|
|
console.error("ta未初始化");
|
|
return null;
|
|
}
|
|
return ta;
|
|
}
|
|
|
|
export function reportTAEvent(uid: string, event: string, data: any) {
|
|
const ta = getTa();
|
|
if (ta) {
|
|
ta.track(uid, event, data);
|
|
}
|
|
}
|
|
|
|
export function reportTAUserSet(uid: string, data: any) {
|
|
const ta = getTa();
|
|
if (ta) {
|
|
ta.userSet(uid, data);
|
|
}
|
|
}
|
|
|
|
export function initTaLoggingMode(isInit: boolean) {
|
|
if (isInit) {
|
|
if (!instance) {
|
|
instance = new TA("AABBCC", "");
|
|
}
|
|
}
|
|
}
|